├── .circleci └── config.yml ├── .gitignore ├── .gitmodules ├── LICENSE.txt ├── README.md ├── bin └── mander ├── conda.recipe ├── meta.yaml └── run_test.py ├── examples ├── .ipynb_checkpoints │ └── Untitled-checkpoint.ipynb └── demo.ipynb ├── lib └── pybind11 │ ├── attr.h │ ├── buffer_info.h │ ├── cast.h │ ├── chrono.h │ ├── class_support.h │ ├── common.h │ ├── complex.h │ ├── descr.h │ ├── eigen.h │ ├── embed.h │ ├── eval.h │ ├── functional.h │ ├── numpy.h │ ├── operators.h │ ├── options.h │ ├── pybind11.h │ ├── pytypes.h │ ├── stl.h │ ├── stl_bind.h │ └── typeid.h ├── mander └── __init__.py ├── requirements.txt ├── setup.cfg ├── setup.py ├── src └── pywrapper.cpp └── test ├── __init__.py ├── data ├── CD_CA_24.geojson ├── CD_CA_24_scores.json ├── CD_CA_9.geojson ├── CD_CA_9_scores.json ├── CD_IL_4.geojson ├── CD_IL_4_scores.json ├── CD_MA_9.geojson ├── CD_MA_9_scores.json ├── CD_PA_7.geojson ├── CD_PA_7_scores.json └── MN_Senate_2017.geojson └── metrics.py /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | docker: 5 | # this docker image has compilers already cached and ready 6 | - image: conda/c3i-linux-64 7 | 8 | working_directory: ~/repo 9 | 10 | steps: 11 | - checkout 12 | 13 | # currently we have no external dependencies aside from two git submodules 14 | # - restore_cache: 15 | # keys: 16 | # - v1-dependencies-{{ checksum "environment.yml" }} 17 | # - v1-dependencies- 18 | 19 | - run: 20 | name: build recipe 21 | command: conda build conda.recipe 22 | 23 | # currently we have no external dependencies aside from two git submodules 24 | # - save_cache: 25 | # paths: 26 | # - /opt/conda 27 | # key: v1-dependencies-{{ checksum "environment.yml" }} 28 | 29 | # tests are run as part of the build process 30 | # - run: 31 | # name: run tests 32 | # command: | 33 | # source activate adj 34 | # pytest tests 35 | 36 | # we could potentially be uploading our build artifacts here. Maybe someday. 37 | - store_artifacts: 38 | path: test-reports 39 | destination: test-reports 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *__pycache__* 3 | *.pyc 4 | dist/ 5 | build/ 6 | mander.egg-info/ 7 | *.so 8 | .Python 9 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/compactnesslib"] 2 | path = lib/compactnesslib 3 | url = https://github.com/r-barnes/compactnesslib.git 4 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 MGGG, https://github.com/gerrymandr 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mander 2 | 3 | A Python package and command line utility for calculating compactness metrics of 4 | electoral districts. 5 | 6 | 7 | 8 | # Example 9 | 10 | What scores are available? 11 | 12 | ```python 13 | import mander 14 | mander.getListOfScores() 15 | ``` 16 | 17 | Getting scores for GeoJSON: 18 | 19 | ```python 20 | import mander 21 | 22 | geojson_data = """{ "type": "FeatureCollection", "features": [{"type": "Feature","properties": {},"geometry": { "type": "Polygon", "coordinates": [ [ [ -30.585937499999996, 27.68352808378776 ], [ -2.8125, 27.68352808378776 ], [ -2.8125, 46.800059446787316 ], [ -30.585937499999996, 46.800059446787316 ], [ -30.585937499999996, 27.68352808378776 ] ] ] } } ] }""" 23 | 24 | mander.getScoresForGeoJSON(geojson_data) 25 | ``` 26 | 27 | Augmenting an existing shapefile with compactness scores: 28 | 29 | ```python 30 | import mander 31 | mander.augmentShapefileWithScores("us_electoral_districts.shp") 32 | ``` 33 | 34 | 35 | # Compactness Metrics 36 | 37 | Compactness scores are calculated using the underlying 38 | [compactnesslib](https://github.com/r-barnes/compactnesslib) 39 | a list of the scores available and how they are calculated is available 40 | [here](https://github.com/r-barnes/compactnesslib/blob/master/Scores.md). 41 | 42 | 43 | # Developer Setup 44 | 45 | ## Requirements: 46 | 47 | * Python 2.7 48 | * pip 49 | * A compiler that supports C++ 11. 50 | * If using GCC, must use [version 4.9 or greater](https://github.com/nlohmann/json#supported-compilers). 51 | 52 | ## Recommended 53 | * virtualenv 54 | 55 | ## Steps: 56 | 57 | * Fork this repo 58 | * Clone your fork 59 | ``` 60 | git clone git@github.com:YOUR_USERNAME_HERE/python-mander.git 61 | ``` 62 | * Add the original repo as a remote 63 | ``` 64 | git remote add upstream git@github.com:gerrymandr/python-mander.git 65 | ``` 66 | * This project depends upon a C++ library sourced from a git submodule. Initialize and update the git submodule. 67 | ``` 68 | git submodule init 69 | git submodule update 70 | ``` 71 | * Optionally create and activate a [Python virtual environment](https://virtualenv.pypa.io/en/stable/). 72 | On Linux or Mac 73 | ``` 74 | virtualenv env 75 | source env/bin/activate 76 | ``` 77 | On Windows 78 | ``` 79 | virtualenv env 80 | env\Scripts\activate 81 | ``` 82 | 83 | On any platform, you may exit the virtual environment by running 84 | ``` 85 | deactivate 86 | ``` 87 | * Install the dependencies 88 | ``` 89 | pip install -r requirements.txt 90 | ``` 91 | * Build the project 92 | ``` 93 | python setup.py build 94 | ``` 95 | * If you need to specify a C compiler other than the default one on your system, you may add an inline environment variable `CC` and set it to the other compiler. For example, on a system with both gcc 4 and gcc 7 installed: 96 | ``` 97 | CC=gcc-7 python setup.py build 98 | ``` 99 | 100 | 101 | # Credits 102 | 103 | This package was created for the 104 | [Metric Geometry And Gerrymandering Group](https://sites.tufts.edu/gerrymandr/) 105 | as part of a hack-a-thon on August 10-11, 2017. 106 | -------------------------------------------------------------------------------- /bin/mander: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import mander 4 | import sys 5 | 6 | if len(sys.argv)!=2: 7 | print("""Adds compactness scores to a shapefile 8 | Syntax: {0} 9 | 10 | - Filename of inputfile. 11 | """.format(sys.argv[0])) 12 | sys.exit(-1) 13 | 14 | mander.augmentShapefileWithScores(sys.argv[1]) 15 | -------------------------------------------------------------------------------- /conda.recipe/meta.yaml: -------------------------------------------------------------------------------- 1 | package: 2 | name: python-mander 3 | version: {{ GIT_DESCRIBE_TAG }}.{{ GIT_BUILD_STR }} 4 | 5 | source: 6 | git_url: ../ 7 | 8 | build: 9 | script: python setup.py install --single-version-externally-managed --record=record.txt 10 | 11 | requirements: 12 | build: 13 | - {{ compiler('c') }} 14 | - {{ compiler('cxx') }} 15 | host: 16 | - python 17 | - setuptools 18 | run: 19 | - python 20 | 21 | test: 22 | imports: 23 | - mander 24 | -------------------------------------------------------------------------------- /conda.recipe/run_test.py: -------------------------------------------------------------------------------- 1 | import mander 2 | mander.getListOfBoundedScores() 3 | mander.getListOfUnboundedScores() 4 | -------------------------------------------------------------------------------- /examples/.ipynb_checkpoints/Untitled-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [], 3 | "metadata": {}, 4 | "nbformat": 4, 5 | "nbformat_minor": 0 6 | } 7 | -------------------------------------------------------------------------------- /lib/pybind11/attr.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/attr.h: Infrastructure for processing custom 3 | type and function attributes 4 | 5 | Copyright (c) 2016 Wenzel Jakob 6 | 7 | All rights reserved. Use of this source code is governed by a 8 | BSD-style license that can be found in the LICENSE file. 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "cast.h" 14 | 15 | NAMESPACE_BEGIN(pybind11) 16 | 17 | /// \addtogroup annotations 18 | /// @{ 19 | 20 | /// Annotation for methods 21 | struct is_method { handle class_; is_method(const handle &c) : class_(c) { } }; 22 | 23 | /// Annotation for operators 24 | struct is_operator { }; 25 | 26 | /// Annotation for parent scope 27 | struct scope { handle value; scope(const handle &s) : value(s) { } }; 28 | 29 | /// Annotation for documentation 30 | struct doc { const char *value; doc(const char *value) : value(value) { } }; 31 | 32 | /// Annotation for function names 33 | struct name { const char *value; name(const char *value) : value(value) { } }; 34 | 35 | /// Annotation indicating that a function is an overload associated with a given "sibling" 36 | struct sibling { handle value; sibling(const handle &value) : value(value.ptr()) { } }; 37 | 38 | /// Annotation indicating that a class derives from another given type 39 | template struct base { 40 | PYBIND11_DEPRECATED("base() was deprecated in favor of specifying 'T' as a template argument to class_") 41 | base() { } 42 | }; 43 | 44 | /// Keep patient alive while nurse lives 45 | template struct keep_alive { }; 46 | 47 | /// Annotation indicating that a class is involved in a multiple inheritance relationship 48 | struct multiple_inheritance { }; 49 | 50 | /// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class 51 | struct dynamic_attr { }; 52 | 53 | /// Annotation which enables the buffer protocol for a type 54 | struct buffer_protocol { }; 55 | 56 | /// Annotation which requests that a special metaclass is created for a type 57 | struct metaclass { 58 | handle value; 59 | 60 | PYBIND11_DEPRECATED("py::metaclass() is no longer required. It's turned on by default now.") 61 | metaclass() {} 62 | 63 | /// Override pybind11's default metaclass 64 | explicit metaclass(handle value) : value(value) { } 65 | }; 66 | 67 | /// Annotation that marks a class as local to the module: 68 | struct module_local { const bool value; constexpr module_local(bool v = true) : value(v) { } }; 69 | 70 | /// Annotation to mark enums as an arithmetic type 71 | struct arithmetic { }; 72 | 73 | /** \rst 74 | A call policy which places one or more guard variables (``Ts...``) around the function call. 75 | 76 | For example, this definition: 77 | 78 | .. code-block:: cpp 79 | 80 | m.def("foo", foo, py::call_guard()); 81 | 82 | is equivalent to the following pseudocode: 83 | 84 | .. code-block:: cpp 85 | 86 | m.def("foo", [](args...) { 87 | T scope_guard; 88 | return foo(args...); // forwarded arguments 89 | }); 90 | \endrst */ 91 | template struct call_guard; 92 | 93 | template <> struct call_guard<> { using type = detail::void_type; }; 94 | 95 | template 96 | struct call_guard { 97 | static_assert(std::is_default_constructible::value, 98 | "The guard type must be default constructible"); 99 | 100 | using type = T; 101 | }; 102 | 103 | template 104 | struct call_guard { 105 | struct type { 106 | T guard{}; // Compose multiple guard types with left-to-right default-constructor order 107 | typename call_guard::type next{}; 108 | }; 109 | }; 110 | 111 | /// @} annotations 112 | 113 | NAMESPACE_BEGIN(detail) 114 | /* Forward declarations */ 115 | enum op_id : int; 116 | enum op_type : int; 117 | struct undefined_t; 118 | template struct op_; 119 | template struct init; 120 | template struct init_alias; 121 | inline void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret); 122 | 123 | /// Internal data structure which holds metadata about a keyword argument 124 | struct argument_record { 125 | const char *name; ///< Argument name 126 | const char *descr; ///< Human-readable version of the argument value 127 | handle value; ///< Associated Python object 128 | bool convert : 1; ///< True if the argument is allowed to convert when loading 129 | bool none : 1; ///< True if None is allowed when loading 130 | 131 | argument_record(const char *name, const char *descr, handle value, bool convert, bool none) 132 | : name(name), descr(descr), value(value), convert(convert), none(none) { } 133 | }; 134 | 135 | /// Internal data structure which holds metadata about a bound function (signature, overloads, etc.) 136 | struct function_record { 137 | function_record() 138 | : is_constructor(false), is_stateless(false), is_operator(false), 139 | has_args(false), has_kwargs(false), is_method(false) { } 140 | 141 | /// Function name 142 | char *name = nullptr; /* why no C++ strings? They generate heavier code.. */ 143 | 144 | // User-specified documentation string 145 | char *doc = nullptr; 146 | 147 | /// Human-readable version of the function signature 148 | char *signature = nullptr; 149 | 150 | /// List of registered keyword arguments 151 | std::vector args; 152 | 153 | /// Pointer to lambda function which converts arguments and performs the actual call 154 | handle (*impl) (function_call &) = nullptr; 155 | 156 | /// Storage for the wrapped function pointer and captured data, if any 157 | void *data[3] = { }; 158 | 159 | /// Pointer to custom destructor for 'data' (if needed) 160 | void (*free_data) (function_record *ptr) = nullptr; 161 | 162 | /// Return value policy associated with this function 163 | return_value_policy policy = return_value_policy::automatic; 164 | 165 | /// True if name == '__init__' 166 | bool is_constructor : 1; 167 | 168 | /// True if this is a stateless function pointer 169 | bool is_stateless : 1; 170 | 171 | /// True if this is an operator (__add__), etc. 172 | bool is_operator : 1; 173 | 174 | /// True if the function has a '*args' argument 175 | bool has_args : 1; 176 | 177 | /// True if the function has a '**kwargs' argument 178 | bool has_kwargs : 1; 179 | 180 | /// True if this is a method 181 | bool is_method : 1; 182 | 183 | /// Number of arguments (including py::args and/or py::kwargs, if present) 184 | std::uint16_t nargs; 185 | 186 | /// Python method object 187 | PyMethodDef *def = nullptr; 188 | 189 | /// Python handle to the parent scope (a class or a module) 190 | handle scope; 191 | 192 | /// Python handle to the sibling function representing an overload chain 193 | handle sibling; 194 | 195 | /// Pointer to next overload 196 | function_record *next = nullptr; 197 | }; 198 | 199 | /// Special data structure which (temporarily) holds metadata about a bound class 200 | struct type_record { 201 | PYBIND11_NOINLINE type_record() 202 | : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false), module_local(false) { } 203 | 204 | /// Handle to the parent scope 205 | handle scope; 206 | 207 | /// Name of the class 208 | const char *name = nullptr; 209 | 210 | // Pointer to RTTI type_info data structure 211 | const std::type_info *type = nullptr; 212 | 213 | /// How large is the underlying C++ type? 214 | size_t type_size = 0; 215 | 216 | /// How large is the type's holder? 217 | size_t holder_size = 0; 218 | 219 | /// The global operator new can be overridden with a class-specific variant 220 | void *(*operator_new)(size_t) = ::operator new; 221 | 222 | /// Function pointer to class_<..>::init_instance 223 | void (*init_instance)(instance *, const void *) = nullptr; 224 | 225 | /// Function pointer to class_<..>::dealloc 226 | void (*dealloc)(const detail::value_and_holder &) = nullptr; 227 | 228 | /// List of base classes of the newly created type 229 | list bases; 230 | 231 | /// Optional docstring 232 | const char *doc = nullptr; 233 | 234 | /// Custom metaclass (optional) 235 | handle metaclass; 236 | 237 | /// Multiple inheritance marker 238 | bool multiple_inheritance : 1; 239 | 240 | /// Does the class manage a __dict__? 241 | bool dynamic_attr : 1; 242 | 243 | /// Does the class implement the buffer protocol? 244 | bool buffer_protocol : 1; 245 | 246 | /// Is the default (unique_ptr) holder type used? 247 | bool default_holder : 1; 248 | 249 | /// Is the class definition local to the module shared object? 250 | bool module_local : 1; 251 | 252 | PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *)) { 253 | auto base_info = detail::get_type_info(base, false); 254 | if (!base_info) { 255 | std::string tname(base.name()); 256 | detail::clean_type_id(tname); 257 | pybind11_fail("generic_type: type \"" + std::string(name) + 258 | "\" referenced unknown base type \"" + tname + "\""); 259 | } 260 | 261 | if (default_holder != base_info->default_holder) { 262 | std::string tname(base.name()); 263 | detail::clean_type_id(tname); 264 | pybind11_fail("generic_type: type \"" + std::string(name) + "\" " + 265 | (default_holder ? "does not have" : "has") + 266 | " a non-default holder type while its base \"" + tname + "\" " + 267 | (base_info->default_holder ? "does not" : "does")); 268 | } 269 | 270 | bases.append((PyObject *) base_info->type); 271 | 272 | if (base_info->type->tp_dictoffset != 0) 273 | dynamic_attr = true; 274 | 275 | if (caster) 276 | base_info->implicit_casts.emplace_back(type, caster); 277 | } 278 | }; 279 | 280 | inline function_call::function_call(function_record &f, handle p) : 281 | func(f), parent(p) { 282 | args.reserve(f.nargs); 283 | args_convert.reserve(f.nargs); 284 | } 285 | 286 | /** 287 | * Partial template specializations to process custom attributes provided to 288 | * cpp_function_ and class_. These are either used to initialize the respective 289 | * fields in the type_record and function_record data structures or executed at 290 | * runtime to deal with custom call policies (e.g. keep_alive). 291 | */ 292 | template struct process_attribute; 293 | 294 | template struct process_attribute_default { 295 | /// Default implementation: do nothing 296 | static void init(const T &, function_record *) { } 297 | static void init(const T &, type_record *) { } 298 | static void precall(function_call &) { } 299 | static void postcall(function_call &, handle) { } 300 | }; 301 | 302 | /// Process an attribute specifying the function's name 303 | template <> struct process_attribute : process_attribute_default { 304 | static void init(const name &n, function_record *r) { r->name = const_cast(n.value); } 305 | }; 306 | 307 | /// Process an attribute specifying the function's docstring 308 | template <> struct process_attribute : process_attribute_default { 309 | static void init(const doc &n, function_record *r) { r->doc = const_cast(n.value); } 310 | }; 311 | 312 | /// Process an attribute specifying the function's docstring (provided as a C-style string) 313 | template <> struct process_attribute : process_attribute_default { 314 | static void init(const char *d, function_record *r) { r->doc = const_cast(d); } 315 | static void init(const char *d, type_record *r) { r->doc = const_cast(d); } 316 | }; 317 | template <> struct process_attribute : process_attribute { }; 318 | 319 | /// Process an attribute indicating the function's return value policy 320 | template <> struct process_attribute : process_attribute_default { 321 | static void init(const return_value_policy &p, function_record *r) { r->policy = p; } 322 | }; 323 | 324 | /// Process an attribute which indicates that this is an overloaded function associated with a given sibling 325 | template <> struct process_attribute : process_attribute_default { 326 | static void init(const sibling &s, function_record *r) { r->sibling = s.value; } 327 | }; 328 | 329 | /// Process an attribute which indicates that this function is a method 330 | template <> struct process_attribute : process_attribute_default { 331 | static void init(const is_method &s, function_record *r) { r->is_method = true; r->scope = s.class_; } 332 | }; 333 | 334 | /// Process an attribute which indicates the parent scope of a method 335 | template <> struct process_attribute : process_attribute_default { 336 | static void init(const scope &s, function_record *r) { r->scope = s.value; } 337 | }; 338 | 339 | /// Process an attribute which indicates that this function is an operator 340 | template <> struct process_attribute : process_attribute_default { 341 | static void init(const is_operator &, function_record *r) { r->is_operator = true; } 342 | }; 343 | 344 | /// Process a keyword argument attribute (*without* a default value) 345 | template <> struct process_attribute : process_attribute_default { 346 | static void init(const arg &a, function_record *r) { 347 | if (r->is_method && r->args.empty()) 348 | r->args.emplace_back("self", nullptr, handle(), true /*convert*/, false /*none not allowed*/); 349 | r->args.emplace_back(a.name, nullptr, handle(), !a.flag_noconvert, a.flag_none); 350 | } 351 | }; 352 | 353 | /// Process a keyword argument attribute (*with* a default value) 354 | template <> struct process_attribute : process_attribute_default { 355 | static void init(const arg_v &a, function_record *r) { 356 | if (r->is_method && r->args.empty()) 357 | r->args.emplace_back("self", nullptr /*descr*/, handle() /*parent*/, true /*convert*/, false /*none not allowed*/); 358 | 359 | if (!a.value) { 360 | #if !defined(NDEBUG) 361 | std::string descr("'"); 362 | if (a.name) descr += std::string(a.name) + ": "; 363 | descr += a.type + "'"; 364 | if (r->is_method) { 365 | if (r->name) 366 | descr += " in method '" + (std::string) str(r->scope) + "." + (std::string) r->name + "'"; 367 | else 368 | descr += " in method of '" + (std::string) str(r->scope) + "'"; 369 | } else if (r->name) { 370 | descr += " in function '" + (std::string) r->name + "'"; 371 | } 372 | pybind11_fail("arg(): could not convert default argument " 373 | + descr + " into a Python object (type not registered yet?)"); 374 | #else 375 | pybind11_fail("arg(): could not convert default argument " 376 | "into a Python object (type not registered yet?). " 377 | "Compile in debug mode for more information."); 378 | #endif 379 | } 380 | r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none); 381 | } 382 | }; 383 | 384 | /// Process a parent class attribute. Single inheritance only (class_ itself already guarantees that) 385 | template 386 | struct process_attribute::value>> : process_attribute_default { 387 | static void init(const handle &h, type_record *r) { r->bases.append(h); } 388 | }; 389 | 390 | /// Process a parent class attribute (deprecated, does not support multiple inheritance) 391 | template 392 | struct process_attribute> : process_attribute_default> { 393 | static void init(const base &, type_record *r) { r->add_base(typeid(T), nullptr); } 394 | }; 395 | 396 | /// Process a multiple inheritance attribute 397 | template <> 398 | struct process_attribute : process_attribute_default { 399 | static void init(const multiple_inheritance &, type_record *r) { r->multiple_inheritance = true; } 400 | }; 401 | 402 | template <> 403 | struct process_attribute : process_attribute_default { 404 | static void init(const dynamic_attr &, type_record *r) { r->dynamic_attr = true; } 405 | }; 406 | 407 | template <> 408 | struct process_attribute : process_attribute_default { 409 | static void init(const buffer_protocol &, type_record *r) { r->buffer_protocol = true; } 410 | }; 411 | 412 | template <> 413 | struct process_attribute : process_attribute_default { 414 | static void init(const metaclass &m, type_record *r) { r->metaclass = m.value; } 415 | }; 416 | 417 | template <> 418 | struct process_attribute : process_attribute_default { 419 | static void init(const module_local &l, type_record *r) { r->module_local = l.value; } 420 | }; 421 | 422 | /// Process an 'arithmetic' attribute for enums (does nothing here) 423 | template <> 424 | struct process_attribute : process_attribute_default {}; 425 | 426 | template 427 | struct process_attribute> : process_attribute_default> { }; 428 | 429 | /** 430 | * Process a keep_alive call policy -- invokes keep_alive_impl during the 431 | * pre-call handler if both Nurse, Patient != 0 and use the post-call handler 432 | * otherwise 433 | */ 434 | template struct process_attribute> : public process_attribute_default> { 435 | template = 0> 436 | static void precall(function_call &call) { keep_alive_impl(Nurse, Patient, call, handle()); } 437 | template = 0> 438 | static void postcall(function_call &, handle) { } 439 | template = 0> 440 | static void precall(function_call &) { } 441 | template = 0> 442 | static void postcall(function_call &call, handle ret) { keep_alive_impl(Nurse, Patient, call, ret); } 443 | }; 444 | 445 | /// Recursively iterate over variadic template arguments 446 | template struct process_attributes { 447 | static void init(const Args&... args, function_record *r) { 448 | int unused[] = { 0, (process_attribute::type>::init(args, r), 0) ... }; 449 | ignore_unused(unused); 450 | } 451 | static void init(const Args&... args, type_record *r) { 452 | int unused[] = { 0, (process_attribute::type>::init(args, r), 0) ... }; 453 | ignore_unused(unused); 454 | } 455 | static void precall(function_call &call) { 456 | int unused[] = { 0, (process_attribute::type>::precall(call), 0) ... }; 457 | ignore_unused(unused); 458 | } 459 | static void postcall(function_call &call, handle fn_ret) { 460 | int unused[] = { 0, (process_attribute::type>::postcall(call, fn_ret), 0) ... }; 461 | ignore_unused(unused); 462 | } 463 | }; 464 | 465 | template 466 | using is_call_guard = is_instantiation; 467 | 468 | /// Extract the ``type`` from the first `call_guard` in `Extras...` (or `void_type` if none found) 469 | template 470 | using extract_guard_t = typename exactly_one_t, Extra...>::type; 471 | 472 | /// Check the number of named arguments at compile time 473 | template ::value...), 475 | size_t self = constexpr_sum(std::is_same::value...)> 476 | constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) { 477 | return named == 0 || (self + named + has_args + has_kwargs) == nargs; 478 | } 479 | 480 | NAMESPACE_END(detail) 481 | NAMESPACE_END(pybind11) 482 | -------------------------------------------------------------------------------- /lib/pybind11/buffer_info.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/buffer_info.h: Python buffer object interface 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "common.h" 13 | 14 | NAMESPACE_BEGIN(pybind11) 15 | 16 | /// Information record describing a Python buffer object 17 | struct buffer_info { 18 | void *ptr = nullptr; // Pointer to the underlying storage 19 | ssize_t itemsize = 0; // Size of individual items in bytes 20 | ssize_t size = 0; // Total number of entries 21 | std::string format; // For homogeneous buffers, this should be set to format_descriptor::format() 22 | ssize_t ndim = 0; // Number of dimensions 23 | std::vector shape; // Shape of the tensor (1 entry per dimension) 24 | std::vector strides; // Number of entries between adjacent entries (for each per dimension) 25 | 26 | buffer_info() { } 27 | 28 | buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, 29 | detail::any_container shape_in, detail::any_container strides_in) 30 | : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim), 31 | shape(std::move(shape_in)), strides(std::move(strides_in)) { 32 | if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size()) 33 | pybind11_fail("buffer_info: ndim doesn't match shape and/or strides length"); 34 | for (size_t i = 0; i < (size_t) ndim; ++i) 35 | size *= shape[i]; 36 | } 37 | 38 | template 39 | buffer_info(T *ptr, detail::any_container shape_in, detail::any_container strides_in) 40 | : buffer_info(private_ctr_tag(), ptr, sizeof(T), format_descriptor::format(), static_cast(shape_in->size()), std::move(shape_in), std::move(strides_in)) { } 41 | 42 | buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t size) 43 | : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}) { } 44 | 45 | template 46 | buffer_info(T *ptr, ssize_t size) 47 | : buffer_info(ptr, sizeof(T), format_descriptor::format(), size) { } 48 | 49 | explicit buffer_info(Py_buffer *view, bool ownview = true) 50 | : buffer_info(view->buf, view->itemsize, view->format, view->ndim, 51 | {view->shape, view->shape + view->ndim}, {view->strides, view->strides + view->ndim}) { 52 | this->view = view; 53 | this->ownview = ownview; 54 | } 55 | 56 | buffer_info(const buffer_info &) = delete; 57 | buffer_info& operator=(const buffer_info &) = delete; 58 | 59 | buffer_info(buffer_info &&other) { 60 | (*this) = std::move(other); 61 | } 62 | 63 | buffer_info& operator=(buffer_info &&rhs) { 64 | ptr = rhs.ptr; 65 | itemsize = rhs.itemsize; 66 | size = rhs.size; 67 | format = std::move(rhs.format); 68 | ndim = rhs.ndim; 69 | shape = std::move(rhs.shape); 70 | strides = std::move(rhs.strides); 71 | std::swap(view, rhs.view); 72 | std::swap(ownview, rhs.ownview); 73 | return *this; 74 | } 75 | 76 | ~buffer_info() { 77 | if (view && ownview) { PyBuffer_Release(view); delete view; } 78 | } 79 | 80 | private: 81 | struct private_ctr_tag { }; 82 | 83 | buffer_info(private_ctr_tag, void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, 84 | detail::any_container &&shape_in, detail::any_container &&strides_in) 85 | : buffer_info(ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in)) { } 86 | 87 | Py_buffer *view = nullptr; 88 | bool ownview = false; 89 | }; 90 | 91 | NAMESPACE_BEGIN(detail) 92 | 93 | template struct compare_buffer_info { 94 | static bool compare(const buffer_info& b) { 95 | return b.format == format_descriptor::format() && b.itemsize == (ssize_t) sizeof(T); 96 | } 97 | }; 98 | 99 | template struct compare_buffer_info::value>> { 100 | static bool compare(const buffer_info& b) { 101 | return (size_t) b.itemsize == sizeof(T) && (b.format == format_descriptor::value || 102 | ((sizeof(T) == sizeof(long)) && b.format == (std::is_unsigned::value ? "L" : "l")) || 103 | ((sizeof(T) == sizeof(size_t)) && b.format == (std::is_unsigned::value ? "N" : "n"))); 104 | } 105 | }; 106 | 107 | NAMESPACE_END(detail) 108 | NAMESPACE_END(pybind11) 109 | -------------------------------------------------------------------------------- /lib/pybind11/chrono.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/chrono.h: Transparent conversion between std::chrono and python's datetime 3 | 4 | Copyright (c) 2016 Trent Houliston and 5 | Wenzel Jakob 6 | 7 | All rights reserved. Use of this source code is governed by a 8 | BSD-style license that can be found in the LICENSE file. 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "pybind11.h" 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | // Backport the PyDateTime_DELTA functions from Python3.3 if required 20 | #ifndef PyDateTime_DELTA_GET_DAYS 21 | #define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days) 22 | #endif 23 | #ifndef PyDateTime_DELTA_GET_SECONDS 24 | #define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds) 25 | #endif 26 | #ifndef PyDateTime_DELTA_GET_MICROSECONDS 27 | #define PyDateTime_DELTA_GET_MICROSECONDS(o) (((PyDateTime_Delta*)o)->microseconds) 28 | #endif 29 | 30 | NAMESPACE_BEGIN(pybind11) 31 | NAMESPACE_BEGIN(detail) 32 | 33 | template class duration_caster { 34 | public: 35 | typedef typename type::rep rep; 36 | typedef typename type::period period; 37 | 38 | typedef std::chrono::duration> days; 39 | 40 | bool load(handle src, bool) { 41 | using namespace std::chrono; 42 | 43 | // Lazy initialise the PyDateTime import 44 | if (!PyDateTimeAPI) { PyDateTime_IMPORT; } 45 | 46 | if (!src) return false; 47 | // If invoked with datetime.delta object 48 | if (PyDelta_Check(src.ptr())) { 49 | value = type(duration_cast>( 50 | days(PyDateTime_DELTA_GET_DAYS(src.ptr())) 51 | + seconds(PyDateTime_DELTA_GET_SECONDS(src.ptr())) 52 | + microseconds(PyDateTime_DELTA_GET_MICROSECONDS(src.ptr())))); 53 | return true; 54 | } 55 | // If invoked with a float we assume it is seconds and convert 56 | else if (PyFloat_Check(src.ptr())) { 57 | value = type(duration_cast>(duration(PyFloat_AsDouble(src.ptr())))); 58 | return true; 59 | } 60 | else return false; 61 | } 62 | 63 | // If this is a duration just return it back 64 | static const std::chrono::duration& get_duration(const std::chrono::duration &src) { 65 | return src; 66 | } 67 | 68 | // If this is a time_point get the time_since_epoch 69 | template static std::chrono::duration get_duration(const std::chrono::time_point> &src) { 70 | return src.time_since_epoch(); 71 | } 72 | 73 | static handle cast(const type &src, return_value_policy /* policy */, handle /* parent */) { 74 | using namespace std::chrono; 75 | 76 | // Use overloaded function to get our duration from our source 77 | // Works out if it is a duration or time_point and get the duration 78 | auto d = get_duration(src); 79 | 80 | // Lazy initialise the PyDateTime import 81 | if (!PyDateTimeAPI) { PyDateTime_IMPORT; } 82 | 83 | // Declare these special duration types so the conversions happen with the correct primitive types (int) 84 | using dd_t = duration>; 85 | using ss_t = duration>; 86 | using us_t = duration; 87 | 88 | auto dd = duration_cast(d); 89 | auto subd = d - dd; 90 | auto ss = duration_cast(subd); 91 | auto us = duration_cast(subd - ss); 92 | return PyDelta_FromDSU(dd.count(), ss.count(), us.count()); 93 | } 94 | 95 | PYBIND11_TYPE_CASTER(type, _("datetime.timedelta")); 96 | }; 97 | 98 | // This is for casting times on the system clock into datetime.datetime instances 99 | template class type_caster> { 100 | public: 101 | typedef std::chrono::time_point type; 102 | bool load(handle src, bool) { 103 | using namespace std::chrono; 104 | 105 | // Lazy initialise the PyDateTime import 106 | if (!PyDateTimeAPI) { PyDateTime_IMPORT; } 107 | 108 | if (!src) return false; 109 | if (PyDateTime_Check(src.ptr())) { 110 | std::tm cal; 111 | cal.tm_sec = PyDateTime_DATE_GET_SECOND(src.ptr()); 112 | cal.tm_min = PyDateTime_DATE_GET_MINUTE(src.ptr()); 113 | cal.tm_hour = PyDateTime_DATE_GET_HOUR(src.ptr()); 114 | cal.tm_mday = PyDateTime_GET_DAY(src.ptr()); 115 | cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1; 116 | cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900; 117 | cal.tm_isdst = -1; 118 | 119 | value = system_clock::from_time_t(std::mktime(&cal)) + microseconds(PyDateTime_DATE_GET_MICROSECOND(src.ptr())); 120 | return true; 121 | } 122 | else return false; 123 | } 124 | 125 | static handle cast(const std::chrono::time_point &src, return_value_policy /* policy */, handle /* parent */) { 126 | using namespace std::chrono; 127 | 128 | // Lazy initialise the PyDateTime import 129 | if (!PyDateTimeAPI) { PyDateTime_IMPORT; } 130 | 131 | std::time_t tt = system_clock::to_time_t(src); 132 | // this function uses static memory so it's best to copy it out asap just in case 133 | // otherwise other code that is using localtime may break this (not just python code) 134 | std::tm localtime = *std::localtime(&tt); 135 | 136 | // Declare these special duration types so the conversions happen with the correct primitive types (int) 137 | using us_t = duration; 138 | 139 | return PyDateTime_FromDateAndTime(localtime.tm_year + 1900, 140 | localtime.tm_mon + 1, 141 | localtime.tm_mday, 142 | localtime.tm_hour, 143 | localtime.tm_min, 144 | localtime.tm_sec, 145 | (duration_cast(src.time_since_epoch() % seconds(1))).count()); 146 | } 147 | PYBIND11_TYPE_CASTER(type, _("datetime.datetime")); 148 | }; 149 | 150 | // Other clocks that are not the system clock are not measured as datetime.datetime objects 151 | // since they are not measured on calendar time. So instead we just make them timedeltas 152 | // Or if they have passed us a time as a float we convert that 153 | template class type_caster> 154 | : public duration_caster> { 155 | }; 156 | 157 | template class type_caster> 158 | : public duration_caster> { 159 | }; 160 | 161 | NAMESPACE_END(detail) 162 | NAMESPACE_END(pybind11) 163 | -------------------------------------------------------------------------------- /lib/pybind11/class_support.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/class_support.h: Python C API implementation details for py::class_ 3 | 4 | Copyright (c) 2017 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "attr.h" 13 | 14 | NAMESPACE_BEGIN(pybind11) 15 | NAMESPACE_BEGIN(detail) 16 | 17 | inline PyTypeObject *type_incref(PyTypeObject *type) { 18 | Py_INCREF(type); 19 | return type; 20 | } 21 | 22 | #if !defined(PYPY_VERSION) 23 | 24 | /// `pybind11_static_property.__get__()`: Always pass the class instead of the instance. 25 | extern "C" inline PyObject *pybind11_static_get(PyObject *self, PyObject * /*ob*/, PyObject *cls) { 26 | return PyProperty_Type.tp_descr_get(self, cls, cls); 27 | } 28 | 29 | /// `pybind11_static_property.__set__()`: Just like the above `__get__()`. 30 | extern "C" inline int pybind11_static_set(PyObject *self, PyObject *obj, PyObject *value) { 31 | PyObject *cls = PyType_Check(obj) ? obj : (PyObject *) Py_TYPE(obj); 32 | return PyProperty_Type.tp_descr_set(self, cls, value); 33 | } 34 | 35 | /** A `static_property` is the same as a `property` but the `__get__()` and `__set__()` 36 | methods are modified to always use the object type instead of a concrete instance. 37 | Return value: New reference. */ 38 | inline PyTypeObject *make_static_property_type() { 39 | constexpr auto *name = "pybind11_static_property"; 40 | auto name_obj = reinterpret_steal(PYBIND11_FROM_STRING(name)); 41 | 42 | /* Danger zone: from now (and until PyType_Ready), make sure to 43 | issue no Python C API calls which could potentially invoke the 44 | garbage collector (the GC will call type_traverse(), which will in 45 | turn find the newly constructed type in an invalid state) */ 46 | auto heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0); 47 | if (!heap_type) 48 | pybind11_fail("make_static_property_type(): error allocating type!"); 49 | 50 | heap_type->ht_name = name_obj.inc_ref().ptr(); 51 | #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 52 | heap_type->ht_qualname = name_obj.inc_ref().ptr(); 53 | #endif 54 | 55 | auto type = &heap_type->ht_type; 56 | type->tp_name = name; 57 | type->tp_base = type_incref(&PyProperty_Type); 58 | type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; 59 | type->tp_descr_get = pybind11_static_get; 60 | type->tp_descr_set = pybind11_static_set; 61 | 62 | if (PyType_Ready(type) < 0) 63 | pybind11_fail("make_static_property_type(): failure in PyType_Ready()!"); 64 | 65 | setattr((PyObject *) type, "__module__", str("pybind11_builtins")); 66 | 67 | return type; 68 | } 69 | 70 | #else // PYPY 71 | 72 | /** PyPy has some issues with the above C API, so we evaluate Python code instead. 73 | This function will only be called once so performance isn't really a concern. 74 | Return value: New reference. */ 75 | inline PyTypeObject *make_static_property_type() { 76 | auto d = dict(); 77 | PyObject *result = PyRun_String(R"(\ 78 | class pybind11_static_property(property): 79 | def __get__(self, obj, cls): 80 | return property.__get__(self, cls, cls) 81 | 82 | def __set__(self, obj, value): 83 | cls = obj if isinstance(obj, type) else type(obj) 84 | property.__set__(self, cls, value) 85 | )", Py_file_input, d.ptr(), d.ptr() 86 | ); 87 | if (result == nullptr) 88 | throw error_already_set(); 89 | Py_DECREF(result); 90 | return (PyTypeObject *) d["pybind11_static_property"].cast().release().ptr(); 91 | } 92 | 93 | #endif // PYPY 94 | 95 | /** Types with static properties need to handle `Type.static_prop = x` in a specific way. 96 | By default, Python replaces the `static_property` itself, but for wrapped C++ types 97 | we need to call `static_property.__set__()` in order to propagate the new value to 98 | the underlying C++ data structure. */ 99 | extern "C" inline int pybind11_meta_setattro(PyObject* obj, PyObject* name, PyObject* value) { 100 | // Use `_PyType_Lookup()` instead of `PyObject_GetAttr()` in order to get the raw 101 | // descriptor (`property`) instead of calling `tp_descr_get` (`property.__get__()`). 102 | PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name); 103 | 104 | // The following assignment combinations are possible: 105 | // 1. `Type.static_prop = value` --> descr_set: `Type.static_prop.__set__(value)` 106 | // 2. `Type.static_prop = other_static_prop` --> setattro: replace existing `static_prop` 107 | // 3. `Type.regular_attribute = value` --> setattro: regular attribute assignment 108 | const auto static_prop = (PyObject *) get_internals().static_property_type; 109 | const auto call_descr_set = descr && PyObject_IsInstance(descr, static_prop) 110 | && !PyObject_IsInstance(value, static_prop); 111 | if (call_descr_set) { 112 | // Call `static_property.__set__()` instead of replacing the `static_property`. 113 | #if !defined(PYPY_VERSION) 114 | return Py_TYPE(descr)->tp_descr_set(descr, obj, value); 115 | #else 116 | if (PyObject *result = PyObject_CallMethod(descr, "__set__", "OO", obj, value)) { 117 | Py_DECREF(result); 118 | return 0; 119 | } else { 120 | return -1; 121 | } 122 | #endif 123 | } else { 124 | // Replace existing attribute. 125 | return PyType_Type.tp_setattro(obj, name, value); 126 | } 127 | } 128 | 129 | #if PY_MAJOR_VERSION >= 3 130 | /** 131 | * Python 3's PyInstanceMethod_Type hides itself via its tp_descr_get, which prevents aliasing 132 | * methods via cls.attr("m2") = cls.attr("m1"): instead the tp_descr_get returns a plain function, 133 | * when called on a class, or a PyMethod, when called on an instance. Override that behaviour here 134 | * to do a special case bypass for PyInstanceMethod_Types. 135 | */ 136 | extern "C" inline PyObject *pybind11_meta_getattro(PyObject *obj, PyObject *name) { 137 | PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name); 138 | if (descr && PyInstanceMethod_Check(descr)) { 139 | Py_INCREF(descr); 140 | return descr; 141 | } 142 | else { 143 | return PyType_Type.tp_getattro(obj, name); 144 | } 145 | } 146 | #endif 147 | 148 | /** This metaclass is assigned by default to all pybind11 types and is required in order 149 | for static properties to function correctly. Users may override this using `py::metaclass`. 150 | Return value: New reference. */ 151 | inline PyTypeObject* make_default_metaclass() { 152 | constexpr auto *name = "pybind11_type"; 153 | auto name_obj = reinterpret_steal(PYBIND11_FROM_STRING(name)); 154 | 155 | /* Danger zone: from now (and until PyType_Ready), make sure to 156 | issue no Python C API calls which could potentially invoke the 157 | garbage collector (the GC will call type_traverse(), which will in 158 | turn find the newly constructed type in an invalid state) */ 159 | auto heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0); 160 | if (!heap_type) 161 | pybind11_fail("make_default_metaclass(): error allocating metaclass!"); 162 | 163 | heap_type->ht_name = name_obj.inc_ref().ptr(); 164 | #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 165 | heap_type->ht_qualname = name_obj.inc_ref().ptr(); 166 | #endif 167 | 168 | auto type = &heap_type->ht_type; 169 | type->tp_name = name; 170 | type->tp_base = type_incref(&PyType_Type); 171 | type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; 172 | 173 | type->tp_setattro = pybind11_meta_setattro; 174 | #if PY_MAJOR_VERSION >= 3 175 | type->tp_getattro = pybind11_meta_getattro; 176 | #endif 177 | 178 | if (PyType_Ready(type) < 0) 179 | pybind11_fail("make_default_metaclass(): failure in PyType_Ready()!"); 180 | 181 | setattr((PyObject *) type, "__module__", str("pybind11_builtins")); 182 | 183 | return type; 184 | } 185 | 186 | /// For multiple inheritance types we need to recursively register/deregister base pointers for any 187 | /// base classes with pointers that are difference from the instance value pointer so that we can 188 | /// correctly recognize an offset base class pointer. This calls a function with any offset base ptrs. 189 | inline void traverse_offset_bases(void *valueptr, const detail::type_info *tinfo, instance *self, 190 | bool (*f)(void * /*parentptr*/, instance * /*self*/)) { 191 | for (handle h : reinterpret_borrow(tinfo->type->tp_bases)) { 192 | if (auto parent_tinfo = get_type_info((PyTypeObject *) h.ptr())) { 193 | for (auto &c : parent_tinfo->implicit_casts) { 194 | if (c.first == tinfo->cpptype) { 195 | auto *parentptr = c.second(valueptr); 196 | if (parentptr != valueptr) 197 | f(parentptr, self); 198 | traverse_offset_bases(parentptr, parent_tinfo, self, f); 199 | break; 200 | } 201 | } 202 | } 203 | } 204 | } 205 | 206 | inline bool register_instance_impl(void *ptr, instance *self) { 207 | get_internals().registered_instances.emplace(ptr, self); 208 | return true; // unused, but gives the same signature as the deregister func 209 | } 210 | inline bool deregister_instance_impl(void *ptr, instance *self) { 211 | auto ®istered_instances = get_internals().registered_instances; 212 | auto range = registered_instances.equal_range(ptr); 213 | for (auto it = range.first; it != range.second; ++it) { 214 | if (Py_TYPE(self) == Py_TYPE(it->second)) { 215 | registered_instances.erase(it); 216 | return true; 217 | } 218 | } 219 | return false; 220 | } 221 | 222 | inline void register_instance(instance *self, void *valptr, const type_info *tinfo) { 223 | register_instance_impl(valptr, self); 224 | if (!tinfo->simple_ancestors) 225 | traverse_offset_bases(valptr, tinfo, self, register_instance_impl); 226 | } 227 | 228 | inline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo) { 229 | bool ret = deregister_instance_impl(valptr, self); 230 | if (!tinfo->simple_ancestors) 231 | traverse_offset_bases(valptr, tinfo, self, deregister_instance_impl); 232 | return ret; 233 | } 234 | 235 | /// Instance creation function for all pybind11 types. It only allocates space for the C++ object 236 | /// (or multiple objects, for Python-side inheritance from multiple pybind11 types), but doesn't 237 | /// call the constructor -- an `__init__` function must do that (followed by an `init_instance` 238 | /// to set up the holder and register the instance). 239 | inline PyObject *make_new_instance(PyTypeObject *type, bool allocate_value /*= true (in cast.h)*/) { 240 | #if defined(PYPY_VERSION) 241 | // PyPy gets tp_basicsize wrong (issue 2482) under multiple inheritance when the first inherited 242 | // object is a a plain Python type (i.e. not derived from an extension type). Fix it. 243 | ssize_t instance_size = static_cast(sizeof(instance)); 244 | if (type->tp_basicsize < instance_size) { 245 | type->tp_basicsize = instance_size; 246 | } 247 | #endif 248 | PyObject *self = type->tp_alloc(type, 0); 249 | auto inst = reinterpret_cast(self); 250 | // Allocate the value/holder internals: 251 | inst->allocate_layout(); 252 | 253 | inst->owned = true; 254 | // Allocate (if requested) the value pointers; otherwise leave them as nullptr 255 | if (allocate_value) { 256 | for (auto &v_h : values_and_holders(inst)) { 257 | void *&vptr = v_h.value_ptr(); 258 | vptr = v_h.type->operator_new(v_h.type->type_size); 259 | } 260 | } 261 | 262 | return self; 263 | } 264 | 265 | /// Instance creation function for all pybind11 types. It only allocates space for the 266 | /// C++ object, but doesn't call the constructor -- an `__init__` function must do that. 267 | extern "C" inline PyObject *pybind11_object_new(PyTypeObject *type, PyObject *, PyObject *) { 268 | return make_new_instance(type); 269 | } 270 | 271 | /// An `__init__` function constructs the C++ object. Users should provide at least one 272 | /// of these using `py::init` or directly with `.def(__init__, ...)`. Otherwise, the 273 | /// following default function will be used which simply throws an exception. 274 | extern "C" inline int pybind11_object_init(PyObject *self, PyObject *, PyObject *) { 275 | PyTypeObject *type = Py_TYPE(self); 276 | std::string msg; 277 | #if defined(PYPY_VERSION) 278 | msg += handle((PyObject *) type).attr("__module__").cast() + "."; 279 | #endif 280 | msg += type->tp_name; 281 | msg += ": No constructor defined!"; 282 | PyErr_SetString(PyExc_TypeError, msg.c_str()); 283 | return -1; 284 | } 285 | 286 | inline void add_patient(PyObject *nurse, PyObject *patient) { 287 | auto &internals = get_internals(); 288 | auto instance = reinterpret_cast(nurse); 289 | instance->has_patients = true; 290 | Py_INCREF(patient); 291 | internals.patients[nurse].push_back(patient); 292 | } 293 | 294 | inline void clear_patients(PyObject *self) { 295 | auto instance = reinterpret_cast(self); 296 | auto &internals = get_internals(); 297 | auto pos = internals.patients.find(self); 298 | assert(pos != internals.patients.end()); 299 | // Clearing the patients can cause more Python code to run, which 300 | // can invalidate the iterator. Extract the vector of patients 301 | // from the unordered_map first. 302 | auto patients = std::move(pos->second); 303 | internals.patients.erase(pos); 304 | instance->has_patients = false; 305 | for (PyObject *&patient : patients) 306 | Py_CLEAR(patient); 307 | } 308 | 309 | /// Clears all internal data from the instance and removes it from registered instances in 310 | /// preparation for deallocation. 311 | inline void clear_instance(PyObject *self) { 312 | auto instance = reinterpret_cast(self); 313 | 314 | // Deallocate any values/holders, if present: 315 | for (auto &v_h : values_and_holders(instance)) { 316 | if (v_h) { 317 | 318 | // We have to deregister before we call dealloc because, for virtual MI types, we still 319 | // need to be able to get the parent pointers. 320 | if (v_h.instance_registered() && !deregister_instance(instance, v_h.value_ptr(), v_h.type)) 321 | pybind11_fail("pybind11_object_dealloc(): Tried to deallocate unregistered instance!"); 322 | 323 | if (instance->owned || v_h.holder_constructed()) 324 | v_h.type->dealloc(v_h); 325 | } 326 | } 327 | // Deallocate the value/holder layout internals: 328 | instance->deallocate_layout(); 329 | 330 | if (instance->weakrefs) 331 | PyObject_ClearWeakRefs(self); 332 | 333 | PyObject **dict_ptr = _PyObject_GetDictPtr(self); 334 | if (dict_ptr) 335 | Py_CLEAR(*dict_ptr); 336 | 337 | if (instance->has_patients) 338 | clear_patients(self); 339 | } 340 | 341 | /// Instance destructor function for all pybind11 types. It calls `type_info.dealloc` 342 | /// to destroy the C++ object itself, while the rest is Python bookkeeping. 343 | extern "C" inline void pybind11_object_dealloc(PyObject *self) { 344 | clear_instance(self); 345 | Py_TYPE(self)->tp_free(self); 346 | } 347 | 348 | /** Create the type which can be used as a common base for all classes. This is 349 | needed in order to satisfy Python's requirements for multiple inheritance. 350 | Return value: New reference. */ 351 | inline PyObject *make_object_base_type(PyTypeObject *metaclass) { 352 | constexpr auto *name = "pybind11_object"; 353 | auto name_obj = reinterpret_steal(PYBIND11_FROM_STRING(name)); 354 | 355 | /* Danger zone: from now (and until PyType_Ready), make sure to 356 | issue no Python C API calls which could potentially invoke the 357 | garbage collector (the GC will call type_traverse(), which will in 358 | turn find the newly constructed type in an invalid state) */ 359 | auto heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0); 360 | if (!heap_type) 361 | pybind11_fail("make_object_base_type(): error allocating type!"); 362 | 363 | heap_type->ht_name = name_obj.inc_ref().ptr(); 364 | #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 365 | heap_type->ht_qualname = name_obj.inc_ref().ptr(); 366 | #endif 367 | 368 | auto type = &heap_type->ht_type; 369 | type->tp_name = name; 370 | type->tp_base = type_incref(&PyBaseObject_Type); 371 | type->tp_basicsize = static_cast(sizeof(instance)); 372 | type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; 373 | 374 | type->tp_new = pybind11_object_new; 375 | type->tp_init = pybind11_object_init; 376 | type->tp_dealloc = pybind11_object_dealloc; 377 | 378 | /* Support weak references (needed for the keep_alive feature) */ 379 | type->tp_weaklistoffset = offsetof(instance, weakrefs); 380 | 381 | if (PyType_Ready(type) < 0) 382 | pybind11_fail("PyType_Ready failed in make_object_base_type():" + error_string()); 383 | 384 | setattr((PyObject *) type, "__module__", str("pybind11_builtins")); 385 | 386 | assert(!PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC)); 387 | return (PyObject *) heap_type; 388 | } 389 | 390 | /// dynamic_attr: Support for `d = instance.__dict__`. 391 | extern "C" inline PyObject *pybind11_get_dict(PyObject *self, void *) { 392 | PyObject *&dict = *_PyObject_GetDictPtr(self); 393 | if (!dict) 394 | dict = PyDict_New(); 395 | Py_XINCREF(dict); 396 | return dict; 397 | } 398 | 399 | /// dynamic_attr: Support for `instance.__dict__ = dict()`. 400 | extern "C" inline int pybind11_set_dict(PyObject *self, PyObject *new_dict, void *) { 401 | if (!PyDict_Check(new_dict)) { 402 | PyErr_Format(PyExc_TypeError, "__dict__ must be set to a dictionary, not a '%.200s'", 403 | Py_TYPE(new_dict)->tp_name); 404 | return -1; 405 | } 406 | PyObject *&dict = *_PyObject_GetDictPtr(self); 407 | Py_INCREF(new_dict); 408 | Py_CLEAR(dict); 409 | dict = new_dict; 410 | return 0; 411 | } 412 | 413 | /// dynamic_attr: Allow the garbage collector to traverse the internal instance `__dict__`. 414 | extern "C" inline int pybind11_traverse(PyObject *self, visitproc visit, void *arg) { 415 | PyObject *&dict = *_PyObject_GetDictPtr(self); 416 | Py_VISIT(dict); 417 | return 0; 418 | } 419 | 420 | /// dynamic_attr: Allow the GC to clear the dictionary. 421 | extern "C" inline int pybind11_clear(PyObject *self) { 422 | PyObject *&dict = *_PyObject_GetDictPtr(self); 423 | Py_CLEAR(dict); 424 | return 0; 425 | } 426 | 427 | /// Give instances of this type a `__dict__` and opt into garbage collection. 428 | inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) { 429 | auto type = &heap_type->ht_type; 430 | #if defined(PYPY_VERSION) 431 | pybind11_fail(std::string(type->tp_name) + ": dynamic attributes are " 432 | "currently not supported in " 433 | "conjunction with PyPy!"); 434 | #endif 435 | type->tp_flags |= Py_TPFLAGS_HAVE_GC; 436 | type->tp_dictoffset = type->tp_basicsize; // place dict at the end 437 | type->tp_basicsize += (ssize_t)sizeof(PyObject *); // and allocate enough space for it 438 | type->tp_traverse = pybind11_traverse; 439 | type->tp_clear = pybind11_clear; 440 | 441 | static PyGetSetDef getset[] = { 442 | {const_cast("__dict__"), pybind11_get_dict, pybind11_set_dict, nullptr, nullptr}, 443 | {nullptr, nullptr, nullptr, nullptr, nullptr} 444 | }; 445 | type->tp_getset = getset; 446 | } 447 | 448 | /// buffer_protocol: Fill in the view as specified by flags. 449 | extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int flags) { 450 | // Look for a `get_buffer` implementation in this type's info or any bases (following MRO). 451 | type_info *tinfo = nullptr; 452 | for (auto type : reinterpret_borrow(Py_TYPE(obj)->tp_mro)) { 453 | tinfo = get_type_info((PyTypeObject *) type.ptr()); 454 | if (tinfo && tinfo->get_buffer) 455 | break; 456 | } 457 | if (view == nullptr || obj == nullptr || !tinfo || !tinfo->get_buffer) { 458 | if (view) 459 | view->obj = nullptr; 460 | PyErr_SetString(PyExc_BufferError, "pybind11_getbuffer(): Internal error"); 461 | return -1; 462 | } 463 | std::memset(view, 0, sizeof(Py_buffer)); 464 | buffer_info *info = tinfo->get_buffer(obj, tinfo->get_buffer_data); 465 | view->obj = obj; 466 | view->ndim = 1; 467 | view->internal = info; 468 | view->buf = info->ptr; 469 | view->itemsize = info->itemsize; 470 | view->len = view->itemsize; 471 | for (auto s : info->shape) 472 | view->len *= s; 473 | if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) 474 | view->format = const_cast(info->format.c_str()); 475 | if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) { 476 | view->ndim = (int) info->ndim; 477 | view->strides = &info->strides[0]; 478 | view->shape = &info->shape[0]; 479 | } 480 | Py_INCREF(view->obj); 481 | return 0; 482 | } 483 | 484 | /// buffer_protocol: Release the resources of the buffer. 485 | extern "C" inline void pybind11_releasebuffer(PyObject *, Py_buffer *view) { 486 | delete (buffer_info *) view->internal; 487 | } 488 | 489 | /// Give this type a buffer interface. 490 | inline void enable_buffer_protocol(PyHeapTypeObject *heap_type) { 491 | heap_type->ht_type.tp_as_buffer = &heap_type->as_buffer; 492 | #if PY_MAJOR_VERSION < 3 493 | heap_type->ht_type.tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER; 494 | #endif 495 | 496 | heap_type->as_buffer.bf_getbuffer = pybind11_getbuffer; 497 | heap_type->as_buffer.bf_releasebuffer = pybind11_releasebuffer; 498 | } 499 | 500 | /** Create a brand new Python type according to the `type_record` specification. 501 | Return value: New reference. */ 502 | inline PyObject* make_new_python_type(const type_record &rec) { 503 | auto name = reinterpret_steal(PYBIND11_FROM_STRING(rec.name)); 504 | 505 | #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 506 | auto ht_qualname = name; 507 | if (rec.scope && hasattr(rec.scope, "__qualname__")) { 508 | ht_qualname = reinterpret_steal( 509 | PyUnicode_FromFormat("%U.%U", rec.scope.attr("__qualname__").ptr(), name.ptr())); 510 | } 511 | #endif 512 | 513 | object module; 514 | if (rec.scope) { 515 | if (hasattr(rec.scope, "__module__")) 516 | module = rec.scope.attr("__module__"); 517 | else if (hasattr(rec.scope, "__name__")) 518 | module = rec.scope.attr("__name__"); 519 | } 520 | 521 | auto full_name = c_str( 522 | #if !defined(PYPY_VERSION) 523 | module ? str(module).cast() + "." + rec.name : 524 | #endif 525 | rec.name); 526 | 527 | char *tp_doc = nullptr; 528 | if (rec.doc && options::show_user_defined_docstrings()) { 529 | /* Allocate memory for docstring (using PyObject_MALLOC, since 530 | Python will free this later on) */ 531 | size_t size = strlen(rec.doc) + 1; 532 | tp_doc = (char *) PyObject_MALLOC(size); 533 | memcpy((void *) tp_doc, rec.doc, size); 534 | } 535 | 536 | auto &internals = get_internals(); 537 | auto bases = tuple(rec.bases); 538 | auto base = (bases.size() == 0) ? internals.instance_base 539 | : bases[0].ptr(); 540 | 541 | /* Danger zone: from now (and until PyType_Ready), make sure to 542 | issue no Python C API calls which could potentially invoke the 543 | garbage collector (the GC will call type_traverse(), which will in 544 | turn find the newly constructed type in an invalid state) */ 545 | auto metaclass = rec.metaclass.ptr() ? (PyTypeObject *) rec.metaclass.ptr() 546 | : internals.default_metaclass; 547 | 548 | auto heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0); 549 | if (!heap_type) 550 | pybind11_fail(std::string(rec.name) + ": Unable to create type object!"); 551 | 552 | heap_type->ht_name = name.release().ptr(); 553 | #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 554 | heap_type->ht_qualname = ht_qualname.release().ptr(); 555 | #endif 556 | 557 | auto type = &heap_type->ht_type; 558 | type->tp_name = full_name; 559 | type->tp_doc = tp_doc; 560 | type->tp_base = type_incref((PyTypeObject *)base); 561 | type->tp_basicsize = static_cast(sizeof(instance)); 562 | if (bases.size() > 0) 563 | type->tp_bases = bases.release().ptr(); 564 | 565 | /* Don't inherit base __init__ */ 566 | type->tp_init = pybind11_object_init; 567 | 568 | /* Supported protocols */ 569 | type->tp_as_number = &heap_type->as_number; 570 | type->tp_as_sequence = &heap_type->as_sequence; 571 | type->tp_as_mapping = &heap_type->as_mapping; 572 | 573 | /* Flags */ 574 | type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; 575 | #if PY_MAJOR_VERSION < 3 576 | type->tp_flags |= Py_TPFLAGS_CHECKTYPES; 577 | #endif 578 | 579 | if (rec.dynamic_attr) 580 | enable_dynamic_attributes(heap_type); 581 | 582 | if (rec.buffer_protocol) 583 | enable_buffer_protocol(heap_type); 584 | 585 | if (PyType_Ready(type) < 0) 586 | pybind11_fail(std::string(rec.name) + ": PyType_Ready failed (" + error_string() + ")!"); 587 | 588 | assert(rec.dynamic_attr ? PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC) 589 | : !PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC)); 590 | 591 | /* Register type with the parent scope */ 592 | if (rec.scope) 593 | setattr(rec.scope, rec.name, (PyObject *) type); 594 | 595 | if (module) // Needed by pydoc 596 | setattr((PyObject *) type, "__module__", module); 597 | 598 | return (PyObject *) type; 599 | } 600 | 601 | NAMESPACE_END(detail) 602 | NAMESPACE_END(pybind11) 603 | -------------------------------------------------------------------------------- /lib/pybind11/complex.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/complex.h: Complex number support 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | #include 14 | 15 | /// glibc defines I as a macro which breaks things, e.g., boost template names 16 | #ifdef I 17 | # undef I 18 | #endif 19 | 20 | NAMESPACE_BEGIN(pybind11) 21 | 22 | template struct format_descriptor, detail::enable_if_t::value>> { 23 | static constexpr const char c = format_descriptor::c; 24 | static constexpr const char value[3] = { 'Z', c, '\0' }; 25 | static std::string format() { return std::string(value); } 26 | }; 27 | 28 | template constexpr const char format_descriptor< 29 | std::complex, detail::enable_if_t::value>>::value[3]; 30 | 31 | NAMESPACE_BEGIN(detail) 32 | 33 | template struct is_fmt_numeric, detail::enable_if_t::value>> { 34 | static constexpr bool value = true; 35 | static constexpr int index = is_fmt_numeric::index + 3; 36 | }; 37 | 38 | template class type_caster> { 39 | public: 40 | bool load(handle src, bool convert) { 41 | if (!src) 42 | return false; 43 | if (!convert && !PyComplex_Check(src.ptr())) 44 | return false; 45 | Py_complex result = PyComplex_AsCComplex(src.ptr()); 46 | if (result.real == -1.0 && PyErr_Occurred()) { 47 | PyErr_Clear(); 48 | return false; 49 | } 50 | value = std::complex((T) result.real, (T) result.imag); 51 | return true; 52 | } 53 | 54 | static handle cast(const std::complex &src, return_value_policy /* policy */, handle /* parent */) { 55 | return PyComplex_FromDoubles((double) src.real(), (double) src.imag()); 56 | } 57 | 58 | PYBIND11_TYPE_CASTER(std::complex, _("complex")); 59 | }; 60 | NAMESPACE_END(detail) 61 | NAMESPACE_END(pybind11) 62 | -------------------------------------------------------------------------------- /lib/pybind11/descr.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/descr.h: Helper type for concatenating type signatures 3 | either at runtime (C++11) or compile time (C++14) 4 | 5 | Copyright (c) 2016 Wenzel Jakob 6 | 7 | All rights reserved. Use of this source code is governed by a 8 | BSD-style license that can be found in the LICENSE file. 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "common.h" 14 | 15 | NAMESPACE_BEGIN(pybind11) 16 | NAMESPACE_BEGIN(detail) 17 | 18 | /* Concatenate type signatures at compile time using C++14 */ 19 | #if defined(PYBIND11_CPP14) && !defined(_MSC_VER) 20 | #define PYBIND11_CONSTEXPR_DESCR 21 | 22 | template class descr { 23 | template friend class descr; 24 | public: 25 | constexpr descr(char const (&text) [Size1+1], const std::type_info * const (&types)[Size2+1]) 26 | : descr(text, types, 27 | make_index_sequence(), 28 | make_index_sequence()) { } 29 | 30 | constexpr const char *text() const { return m_text; } 31 | constexpr const std::type_info * const * types() const { return m_types; } 32 | 33 | template 34 | constexpr descr operator+(const descr &other) const { 35 | return concat(other, 36 | make_index_sequence(), 37 | make_index_sequence(), 38 | make_index_sequence(), 39 | make_index_sequence()); 40 | } 41 | 42 | protected: 43 | template 44 | constexpr descr( 45 | char const (&text) [Size1+1], 46 | const std::type_info * const (&types) [Size2+1], 47 | index_sequence, index_sequence) 48 | : m_text{text[Indices1]..., '\0'}, 49 | m_types{types[Indices2]..., nullptr } {} 50 | 51 | template 53 | constexpr descr 54 | concat(const descr &other, 55 | index_sequence, index_sequence, 56 | index_sequence, index_sequence) const { 57 | return descr( 58 | { m_text[Indices1]..., other.m_text[OtherIndices1]..., '\0' }, 59 | { m_types[Indices2]..., other.m_types[OtherIndices2]..., nullptr } 60 | ); 61 | } 62 | 63 | protected: 64 | char m_text[Size1 + 1]; 65 | const std::type_info * m_types[Size2 + 1]; 66 | }; 67 | 68 | template constexpr descr _(char const(&text)[Size]) { 69 | return descr(text, { nullptr }); 70 | } 71 | 72 | template struct int_to_str : int_to_str { }; 73 | template struct int_to_str<0, Digits...> { 74 | static constexpr auto digits = descr({ ('0' + Digits)..., '\0' }, { nullptr }); 75 | }; 76 | 77 | // Ternary description (like std::conditional) 78 | template 79 | constexpr enable_if_t> _(char const(&text1)[Size1], char const(&)[Size2]) { 80 | return _(text1); 81 | } 82 | template 83 | constexpr enable_if_t> _(char const(&)[Size1], char const(&text2)[Size2]) { 84 | return _(text2); 85 | } 86 | template 87 | constexpr enable_if_t> _(descr d, descr) { return d; } 88 | template 89 | constexpr enable_if_t> _(descr, descr d) { return d; } 90 | 91 | template auto constexpr _() -> decltype(int_to_str::digits) { 92 | return int_to_str::digits; 93 | } 94 | 95 | template constexpr descr<1, 1> _() { 96 | return descr<1, 1>({ '%', '\0' }, { &typeid(Type), nullptr }); 97 | } 98 | 99 | inline constexpr descr<0, 0> concat() { return _(""); } 100 | template auto constexpr concat(descr descr) { return descr; } 101 | template auto constexpr concat(descr descr, Args&&... args) { return descr + _(", ") + concat(args...); } 102 | template auto constexpr type_descr(descr descr) { return _("{") + descr + _("}"); } 103 | 104 | #define PYBIND11_DESCR constexpr auto 105 | 106 | #else /* Simpler C++11 implementation based on run-time memory allocation and copying */ 107 | 108 | class descr { 109 | public: 110 | PYBIND11_NOINLINE descr(const char *text, const std::type_info * const * types) { 111 | size_t nChars = len(text), nTypes = len(types); 112 | m_text = new char[nChars]; 113 | m_types = new const std::type_info *[nTypes]; 114 | memcpy(m_text, text, nChars * sizeof(char)); 115 | memcpy(m_types, types, nTypes * sizeof(const std::type_info *)); 116 | } 117 | 118 | PYBIND11_NOINLINE descr operator+(descr &&d2) && { 119 | descr r; 120 | 121 | size_t nChars1 = len(m_text), nTypes1 = len(m_types); 122 | size_t nChars2 = len(d2.m_text), nTypes2 = len(d2.m_types); 123 | 124 | r.m_text = new char[nChars1 + nChars2 - 1]; 125 | r.m_types = new const std::type_info *[nTypes1 + nTypes2 - 1]; 126 | memcpy(r.m_text, m_text, (nChars1-1) * sizeof(char)); 127 | memcpy(r.m_text + nChars1 - 1, d2.m_text, nChars2 * sizeof(char)); 128 | memcpy(r.m_types, m_types, (nTypes1-1) * sizeof(std::type_info *)); 129 | memcpy(r.m_types + nTypes1 - 1, d2.m_types, nTypes2 * sizeof(std::type_info *)); 130 | 131 | delete[] m_text; delete[] m_types; 132 | delete[] d2.m_text; delete[] d2.m_types; 133 | 134 | return r; 135 | } 136 | 137 | char *text() { return m_text; } 138 | const std::type_info * * types() { return m_types; } 139 | 140 | protected: 141 | PYBIND11_NOINLINE descr() { } 142 | 143 | template static size_t len(const T *ptr) { // return length including null termination 144 | const T *it = ptr; 145 | while (*it++ != (T) 0) 146 | ; 147 | return static_cast(it - ptr); 148 | } 149 | 150 | const std::type_info **m_types = nullptr; 151 | char *m_text = nullptr; 152 | }; 153 | 154 | /* The 'PYBIND11_NOINLINE inline' combinations below are intentional to get the desired linkage while producing as little object code as possible */ 155 | 156 | PYBIND11_NOINLINE inline descr _(const char *text) { 157 | const std::type_info *types[1] = { nullptr }; 158 | return descr(text, types); 159 | } 160 | 161 | template PYBIND11_NOINLINE enable_if_t _(const char *text1, const char *) { return _(text1); } 162 | template PYBIND11_NOINLINE enable_if_t _(char const *, const char *text2) { return _(text2); } 163 | template PYBIND11_NOINLINE enable_if_t _(descr d, descr) { return d; } 164 | template PYBIND11_NOINLINE enable_if_t _(descr, descr d) { return d; } 165 | 166 | template PYBIND11_NOINLINE descr _() { 167 | const std::type_info *types[2] = { &typeid(Type), nullptr }; 168 | return descr("%", types); 169 | } 170 | 171 | template PYBIND11_NOINLINE descr _() { 172 | const std::type_info *types[1] = { nullptr }; 173 | return descr(std::to_string(Size).c_str(), types); 174 | } 175 | 176 | PYBIND11_NOINLINE inline descr concat() { return _(""); } 177 | PYBIND11_NOINLINE inline descr concat(descr &&d) { return d; } 178 | template PYBIND11_NOINLINE descr concat(descr &&d, Args&&... args) { return std::move(d) + _(", ") + concat(std::forward(args)...); } 179 | PYBIND11_NOINLINE inline descr type_descr(descr&& d) { return _("{") + std::move(d) + _("}"); } 180 | 181 | #define PYBIND11_DESCR ::pybind11::detail::descr 182 | #endif 183 | 184 | NAMESPACE_END(detail) 185 | NAMESPACE_END(pybind11) 186 | -------------------------------------------------------------------------------- /lib/pybind11/embed.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/embed.h: Support for embedding the interpreter 3 | 4 | Copyright (c) 2017 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | #include "eval.h" 14 | 15 | #if defined(PYPY_VERSION) 16 | # error Embedding the interpreter is not supported with PyPy 17 | #endif 18 | 19 | #if PY_MAJOR_VERSION >= 3 20 | # define PYBIND11_EMBEDDED_MODULE_IMPL(name) \ 21 | extern "C" PyObject *pybind11_init_impl_##name() { \ 22 | return pybind11_init_wrapper_##name(); \ 23 | } 24 | #else 25 | # define PYBIND11_EMBEDDED_MODULE_IMPL(name) \ 26 | extern "C" void pybind11_init_impl_##name() { \ 27 | pybind11_init_wrapper_##name(); \ 28 | } 29 | #endif 30 | 31 | /** \rst 32 | Add a new module to the table of builtins for the interpreter. Must be 33 | defined in global scope. The first macro parameter is the name of the 34 | module (without quotes). The second parameter is the variable which will 35 | be used as the interface to add functions and classes to the module. 36 | 37 | .. code-block:: cpp 38 | 39 | PYBIND11_EMBEDDED_MODULE(example, m) { 40 | // ... initialize functions and classes here 41 | m.def("foo", []() { 42 | return "Hello, World!"; 43 | }); 44 | } 45 | \endrst */ 46 | #define PYBIND11_EMBEDDED_MODULE(name, variable) \ 47 | static void pybind11_init_##name(pybind11::module &); \ 48 | static PyObject *pybind11_init_wrapper_##name() { \ 49 | auto m = pybind11::module(#name); \ 50 | try { \ 51 | pybind11_init_##name(m); \ 52 | return m.ptr(); \ 53 | } catch (pybind11::error_already_set &e) { \ 54 | PyErr_SetString(PyExc_ImportError, e.what()); \ 55 | return nullptr; \ 56 | } catch (const std::exception &e) { \ 57 | PyErr_SetString(PyExc_ImportError, e.what()); \ 58 | return nullptr; \ 59 | } \ 60 | } \ 61 | PYBIND11_EMBEDDED_MODULE_IMPL(name) \ 62 | pybind11::detail::embedded_module name(#name, pybind11_init_impl_##name); \ 63 | void pybind11_init_##name(pybind11::module &variable) 64 | 65 | 66 | NAMESPACE_BEGIN(pybind11) 67 | NAMESPACE_BEGIN(detail) 68 | 69 | /// Python 2.7/3.x compatible version of `PyImport_AppendInittab` and error checks. 70 | struct embedded_module { 71 | #if PY_MAJOR_VERSION >= 3 72 | using init_t = PyObject *(*)(); 73 | #else 74 | using init_t = void (*)(); 75 | #endif 76 | embedded_module(const char *name, init_t init) { 77 | if (Py_IsInitialized()) 78 | pybind11_fail("Can't add new modules after the interpreter has been initialized"); 79 | 80 | auto result = PyImport_AppendInittab(name, init); 81 | if (result == -1) 82 | pybind11_fail("Insufficient memory to add a new module"); 83 | } 84 | }; 85 | 86 | NAMESPACE_END(detail) 87 | 88 | /** \rst 89 | Initialize the Python interpreter. No other pybind11 or CPython API functions can be 90 | called before this is done; with the exception of `PYBIND11_EMBEDDED_MODULE`. The 91 | optional parameter can be used to skip the registration of signal handlers (see the 92 | Python documentation for details). Calling this function again after the interpreter 93 | has already been initialized is a fatal error. 94 | \endrst */ 95 | inline void initialize_interpreter(bool init_signal_handlers = true) { 96 | if (Py_IsInitialized()) 97 | pybind11_fail("The interpreter is already running"); 98 | 99 | Py_InitializeEx(init_signal_handlers ? 1 : 0); 100 | 101 | // Make .py files in the working directory available by default 102 | module::import("sys").attr("path").cast().append("."); 103 | } 104 | 105 | /** \rst 106 | Shut down the Python interpreter. No pybind11 or CPython API functions can be called 107 | after this. In addition, pybind11 objects must not outlive the interpreter: 108 | 109 | .. code-block:: cpp 110 | 111 | { // BAD 112 | py::initialize_interpreter(); 113 | auto hello = py::str("Hello, World!"); 114 | py::finalize_interpreter(); 115 | } // <-- BOOM, hello's destructor is called after interpreter shutdown 116 | 117 | { // GOOD 118 | py::initialize_interpreter(); 119 | { // scoped 120 | auto hello = py::str("Hello, World!"); 121 | } // <-- OK, hello is cleaned up properly 122 | py::finalize_interpreter(); 123 | } 124 | 125 | { // BETTER 126 | py::scoped_interpreter guard{}; 127 | auto hello = py::str("Hello, World!"); 128 | } 129 | 130 | .. warning:: 131 | 132 | The interpreter can be restarted by calling `initialize_interpreter` again. 133 | Modules created using pybind11 can be safely re-initialized. However, Python 134 | itself cannot completely unload binary extension modules and there are several 135 | caveats with regard to interpreter restarting. All the details can be found 136 | in the CPython documentation. In short, not all interpreter memory may be 137 | freed, either due to reference cycles or user-created global data. 138 | 139 | \endrst */ 140 | inline void finalize_interpreter() { 141 | handle builtins(PyEval_GetBuiltins()); 142 | const char *id = PYBIND11_INTERNALS_ID; 143 | 144 | // Get the internals pointer (without creating it if it doesn't exist). It's possible for the 145 | // internals to be created during Py_Finalize() (e.g. if a py::capsule calls `get_internals()` 146 | // during destruction), so we get the pointer-pointer here and check it after Py_Finalize(). 147 | detail::internals **internals_ptr_ptr = &detail::get_internals_ptr(); 148 | // It could also be stashed in builtins, so look there too: 149 | if (builtins.contains(id) && isinstance(builtins[id])) 150 | internals_ptr_ptr = capsule(builtins[id]); 151 | 152 | Py_Finalize(); 153 | 154 | if (internals_ptr_ptr) { 155 | delete *internals_ptr_ptr; 156 | *internals_ptr_ptr = nullptr; 157 | } 158 | } 159 | 160 | /** \rst 161 | Scope guard version of `initialize_interpreter` and `finalize_interpreter`. 162 | This a move-only guard and only a single instance can exist. 163 | 164 | .. code-block:: cpp 165 | 166 | #include 167 | 168 | int main() { 169 | py::scoped_interpreter guard{}; 170 | py::print(Hello, World!); 171 | } // <-- interpreter shutdown 172 | \endrst */ 173 | class scoped_interpreter { 174 | public: 175 | scoped_interpreter(bool init_signal_handlers = true) { 176 | initialize_interpreter(init_signal_handlers); 177 | } 178 | 179 | scoped_interpreter(const scoped_interpreter &) = delete; 180 | scoped_interpreter(scoped_interpreter &&other) noexcept { other.is_valid = false; } 181 | scoped_interpreter &operator=(const scoped_interpreter &) = delete; 182 | scoped_interpreter &operator=(scoped_interpreter &&) = delete; 183 | 184 | ~scoped_interpreter() { 185 | if (is_valid) 186 | finalize_interpreter(); 187 | } 188 | 189 | private: 190 | bool is_valid = true; 191 | }; 192 | 193 | NAMESPACE_END(pybind11) 194 | -------------------------------------------------------------------------------- /lib/pybind11/eval.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/exec.h: Support for evaluating Python expressions and statements 3 | from strings and files 4 | 5 | Copyright (c) 2016 Klemens Morgenstern and 6 | Wenzel Jakob 7 | 8 | All rights reserved. Use of this source code is governed by a 9 | BSD-style license that can be found in the LICENSE file. 10 | */ 11 | 12 | #pragma once 13 | 14 | #include "pybind11.h" 15 | 16 | NAMESPACE_BEGIN(pybind11) 17 | 18 | enum eval_mode { 19 | /// Evaluate a string containing an isolated expression 20 | eval_expr, 21 | 22 | /// Evaluate a string containing a single statement. Returns \c none 23 | eval_single_statement, 24 | 25 | /// Evaluate a string containing a sequence of statement. Returns \c none 26 | eval_statements 27 | }; 28 | 29 | template 30 | object eval(str expr, object global = globals(), object local = object()) { 31 | if (!local) 32 | local = global; 33 | 34 | /* PyRun_String does not accept a PyObject / encoding specifier, 35 | this seems to be the only alternative */ 36 | std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr; 37 | 38 | int start; 39 | switch (mode) { 40 | case eval_expr: start = Py_eval_input; break; 41 | case eval_single_statement: start = Py_single_input; break; 42 | case eval_statements: start = Py_file_input; break; 43 | default: pybind11_fail("invalid evaluation mode"); 44 | } 45 | 46 | PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr()); 47 | if (!result) 48 | throw error_already_set(); 49 | return reinterpret_steal(result); 50 | } 51 | 52 | template 53 | object eval(const char (&s)[N], object global = globals(), object local = object()) { 54 | /* Support raw string literals by removing common leading whitespace */ 55 | auto expr = (s[0] == '\n') ? str(module::import("textwrap").attr("dedent")(s)) 56 | : str(s); 57 | return eval(expr, global, local); 58 | } 59 | 60 | inline void exec(str expr, object global = globals(), object local = object()) { 61 | eval(expr, global, local); 62 | } 63 | 64 | template 65 | void exec(const char (&s)[N], object global = globals(), object local = object()) { 66 | eval(s, global, local); 67 | } 68 | 69 | template 70 | object eval_file(str fname, object global = globals(), object local = object()) { 71 | if (!local) 72 | local = global; 73 | 74 | int start; 75 | switch (mode) { 76 | case eval_expr: start = Py_eval_input; break; 77 | case eval_single_statement: start = Py_single_input; break; 78 | case eval_statements: start = Py_file_input; break; 79 | default: pybind11_fail("invalid evaluation mode"); 80 | } 81 | 82 | int closeFile = 1; 83 | std::string fname_str = (std::string) fname; 84 | #if PY_VERSION_HEX >= 0x03040000 85 | FILE *f = _Py_fopen_obj(fname.ptr(), "r"); 86 | #elif PY_VERSION_HEX >= 0x03000000 87 | FILE *f = _Py_fopen(fname.ptr(), "r"); 88 | #else 89 | /* No unicode support in open() :( */ 90 | auto fobj = reinterpret_steal(PyFile_FromString( 91 | const_cast(fname_str.c_str()), 92 | const_cast("r"))); 93 | FILE *f = nullptr; 94 | if (fobj) 95 | f = PyFile_AsFile(fobj.ptr()); 96 | closeFile = 0; 97 | #endif 98 | if (!f) { 99 | PyErr_Clear(); 100 | pybind11_fail("File \"" + fname_str + "\" could not be opened!"); 101 | } 102 | 103 | #if PY_VERSION_HEX < 0x03000000 && defined(PYPY_VERSION) 104 | PyObject *result = PyRun_File(f, fname_str.c_str(), start, global.ptr(), 105 | local.ptr()); 106 | (void) closeFile; 107 | #else 108 | PyObject *result = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(), 109 | local.ptr(), closeFile); 110 | #endif 111 | 112 | if (!result) 113 | throw error_already_set(); 114 | return reinterpret_steal(result); 115 | } 116 | 117 | NAMESPACE_END(pybind11) 118 | -------------------------------------------------------------------------------- /lib/pybind11/functional.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/functional.h: std::function<> support 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | #include 14 | 15 | NAMESPACE_BEGIN(pybind11) 16 | NAMESPACE_BEGIN(detail) 17 | 18 | template 19 | struct type_caster> { 20 | using type = std::function; 21 | using retval_type = conditional_t::value, void_type, Return>; 22 | using function_type = Return (*) (Args...); 23 | 24 | public: 25 | bool load(handle src, bool convert) { 26 | if (src.is_none()) { 27 | // Defer accepting None to other overloads (if we aren't in convert mode): 28 | if (!convert) return false; 29 | return true; 30 | } 31 | 32 | if (!isinstance(src)) 33 | return false; 34 | 35 | auto func = reinterpret_borrow(src); 36 | 37 | /* 38 | When passing a C++ function as an argument to another C++ 39 | function via Python, every function call would normally involve 40 | a full C++ -> Python -> C++ roundtrip, which can be prohibitive. 41 | Here, we try to at least detect the case where the function is 42 | stateless (i.e. function pointer or lambda function without 43 | captured variables), in which case the roundtrip can be avoided. 44 | */ 45 | if (auto cfunc = func.cpp_function()) { 46 | auto c = reinterpret_borrow(PyCFunction_GET_SELF(cfunc.ptr())); 47 | auto rec = (function_record *) c; 48 | 49 | if (rec && rec->is_stateless && 50 | same_type(typeid(function_type), *reinterpret_cast(rec->data[1]))) { 51 | struct capture { function_type f; }; 52 | value = ((capture *) &rec->data)->f; 53 | return true; 54 | } 55 | } 56 | 57 | value = [func](Args... args) -> Return { 58 | gil_scoped_acquire acq; 59 | object retval(func(std::forward(args)...)); 60 | /* Visual studio 2015 parser issue: need parentheses around this expression */ 61 | return (retval.template cast()); 62 | }; 63 | return true; 64 | } 65 | 66 | template 67 | static handle cast(Func &&f_, return_value_policy policy, handle /* parent */) { 68 | if (!f_) 69 | return none().inc_ref(); 70 | 71 | auto result = f_.template target(); 72 | if (result) 73 | return cpp_function(*result, policy).release(); 74 | else 75 | return cpp_function(std::forward(f_), policy).release(); 76 | } 77 | 78 | PYBIND11_TYPE_CASTER(type, _("Callable[[") + 79 | argument_loader::arg_names() + _("], ") + 80 | make_caster::name() + 81 | _("]")); 82 | }; 83 | 84 | NAMESPACE_END(detail) 85 | NAMESPACE_END(pybind11) 86 | -------------------------------------------------------------------------------- /lib/pybind11/operators.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/operator.h: Metatemplates for operator overloading 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | 14 | #if defined(__clang__) && !defined(__INTEL_COMPILER) 15 | # pragma clang diagnostic ignored "-Wunsequenced" // multiple unsequenced modifications to 'self' (when using def(py::self OP Type())) 16 | #elif defined(_MSC_VER) 17 | # pragma warning(push) 18 | # pragma warning(disable: 4127) // warning C4127: Conditional expression is constant 19 | #endif 20 | 21 | NAMESPACE_BEGIN(pybind11) 22 | NAMESPACE_BEGIN(detail) 23 | 24 | /// Enumeration with all supported operator types 25 | enum op_id : int { 26 | op_add, op_sub, op_mul, op_div, op_mod, op_divmod, op_pow, op_lshift, 27 | op_rshift, op_and, op_xor, op_or, op_neg, op_pos, op_abs, op_invert, 28 | op_int, op_long, op_float, op_str, op_cmp, op_gt, op_ge, op_lt, op_le, 29 | op_eq, op_ne, op_iadd, op_isub, op_imul, op_idiv, op_imod, op_ilshift, 30 | op_irshift, op_iand, op_ixor, op_ior, op_complex, op_bool, op_nonzero, 31 | op_repr, op_truediv, op_itruediv 32 | }; 33 | 34 | enum op_type : int { 35 | op_l, /* base type on left */ 36 | op_r, /* base type on right */ 37 | op_u /* unary operator */ 38 | }; 39 | 40 | struct self_t { }; 41 | static const self_t self = self_t(); 42 | 43 | /// Type for an unused type slot 44 | struct undefined_t { }; 45 | 46 | /// Don't warn about an unused variable 47 | inline self_t __self() { return self; } 48 | 49 | /// base template of operator implementations 50 | template struct op_impl { }; 51 | 52 | /// Operator implementation generator 53 | template struct op_ { 54 | template void execute(Class &cl, const Extra&... extra) const { 55 | using Base = typename Class::type; 56 | using L_type = conditional_t::value, Base, L>; 57 | using R_type = conditional_t::value, Base, R>; 58 | using op = op_impl; 59 | cl.def(op::name(), &op::execute, is_operator(), extra...); 60 | #if PY_MAJOR_VERSION < 3 61 | if (id == op_truediv || id == op_itruediv) 62 | cl.def(id == op_itruediv ? "__idiv__" : ot == op_l ? "__div__" : "__rdiv__", 63 | &op::execute, is_operator(), extra...); 64 | #endif 65 | } 66 | template void execute_cast(Class &cl, const Extra&... extra) const { 67 | using Base = typename Class::type; 68 | using L_type = conditional_t::value, Base, L>; 69 | using R_type = conditional_t::value, Base, R>; 70 | using op = op_impl; 71 | cl.def(op::name(), &op::execute_cast, is_operator(), extra...); 72 | #if PY_MAJOR_VERSION < 3 73 | if (id == op_truediv || id == op_itruediv) 74 | cl.def(id == op_itruediv ? "__idiv__" : ot == op_l ? "__div__" : "__rdiv__", 75 | &op::execute, is_operator(), extra...); 76 | #endif 77 | } 78 | }; 79 | 80 | #define PYBIND11_BINARY_OPERATOR(id, rid, op, expr) \ 81 | template struct op_impl { \ 82 | static char const* name() { return "__" #id "__"; } \ 83 | static auto execute(const L &l, const R &r) -> decltype(expr) { return (expr); } \ 84 | static B execute_cast(const L &l, const R &r) { return B(expr); } \ 85 | }; \ 86 | template struct op_impl { \ 87 | static char const* name() { return "__" #rid "__"; } \ 88 | static auto execute(const R &r, const L &l) -> decltype(expr) { return (expr); } \ 89 | static B execute_cast(const R &r, const L &l) { return B(expr); } \ 90 | }; \ 91 | inline op_ op(const self_t &, const self_t &) { \ 92 | return op_(); \ 93 | } \ 94 | template op_ op(const self_t &, const T &) { \ 95 | return op_(); \ 96 | } \ 97 | template op_ op(const T &, const self_t &) { \ 98 | return op_(); \ 99 | } 100 | 101 | #define PYBIND11_INPLACE_OPERATOR(id, op, expr) \ 102 | template struct op_impl { \ 103 | static char const* name() { return "__" #id "__"; } \ 104 | static auto execute(L &l, const R &r) -> decltype(expr) { return expr; } \ 105 | static B execute_cast(L &l, const R &r) { return B(expr); } \ 106 | }; \ 107 | template op_ op(const self_t &, const T &) { \ 108 | return op_(); \ 109 | } 110 | 111 | #define PYBIND11_UNARY_OPERATOR(id, op, expr) \ 112 | template struct op_impl { \ 113 | static char const* name() { return "__" #id "__"; } \ 114 | static auto execute(const L &l) -> decltype(expr) { return expr; } \ 115 | static B execute_cast(const L &l) { return B(expr); } \ 116 | }; \ 117 | inline op_ op(const self_t &) { \ 118 | return op_(); \ 119 | } 120 | 121 | PYBIND11_BINARY_OPERATOR(sub, rsub, operator-, l - r) 122 | PYBIND11_BINARY_OPERATOR(add, radd, operator+, l + r) 123 | PYBIND11_BINARY_OPERATOR(mul, rmul, operator*, l * r) 124 | PYBIND11_BINARY_OPERATOR(truediv, rtruediv, operator/, l / r) 125 | PYBIND11_BINARY_OPERATOR(mod, rmod, operator%, l % r) 126 | PYBIND11_BINARY_OPERATOR(lshift, rlshift, operator<<, l << r) 127 | PYBIND11_BINARY_OPERATOR(rshift, rrshift, operator>>, l >> r) 128 | PYBIND11_BINARY_OPERATOR(and, rand, operator&, l & r) 129 | PYBIND11_BINARY_OPERATOR(xor, rxor, operator^, l ^ r) 130 | PYBIND11_BINARY_OPERATOR(eq, eq, operator==, l == r) 131 | PYBIND11_BINARY_OPERATOR(ne, ne, operator!=, l != r) 132 | PYBIND11_BINARY_OPERATOR(or, ror, operator|, l | r) 133 | PYBIND11_BINARY_OPERATOR(gt, lt, operator>, l > r) 134 | PYBIND11_BINARY_OPERATOR(ge, le, operator>=, l >= r) 135 | PYBIND11_BINARY_OPERATOR(lt, gt, operator<, l < r) 136 | PYBIND11_BINARY_OPERATOR(le, ge, operator<=, l <= r) 137 | //PYBIND11_BINARY_OPERATOR(pow, rpow, pow, std::pow(l, r)) 138 | PYBIND11_INPLACE_OPERATOR(iadd, operator+=, l += r) 139 | PYBIND11_INPLACE_OPERATOR(isub, operator-=, l -= r) 140 | PYBIND11_INPLACE_OPERATOR(imul, operator*=, l *= r) 141 | PYBIND11_INPLACE_OPERATOR(itruediv, operator/=, l /= r) 142 | PYBIND11_INPLACE_OPERATOR(imod, operator%=, l %= r) 143 | PYBIND11_INPLACE_OPERATOR(ilshift, operator<<=, l <<= r) 144 | PYBIND11_INPLACE_OPERATOR(irshift, operator>>=, l >>= r) 145 | PYBIND11_INPLACE_OPERATOR(iand, operator&=, l &= r) 146 | PYBIND11_INPLACE_OPERATOR(ixor, operator^=, l ^= r) 147 | PYBIND11_INPLACE_OPERATOR(ior, operator|=, l |= r) 148 | PYBIND11_UNARY_OPERATOR(neg, operator-, -l) 149 | PYBIND11_UNARY_OPERATOR(pos, operator+, +l) 150 | PYBIND11_UNARY_OPERATOR(abs, abs, std::abs(l)) 151 | PYBIND11_UNARY_OPERATOR(invert, operator~, (~l)) 152 | PYBIND11_UNARY_OPERATOR(bool, operator!, !!l) 153 | PYBIND11_UNARY_OPERATOR(int, int_, (int) l) 154 | PYBIND11_UNARY_OPERATOR(float, float_, (double) l) 155 | 156 | #undef PYBIND11_BINARY_OPERATOR 157 | #undef PYBIND11_INPLACE_OPERATOR 158 | #undef PYBIND11_UNARY_OPERATOR 159 | NAMESPACE_END(detail) 160 | 161 | using detail::self; 162 | 163 | NAMESPACE_END(pybind11) 164 | 165 | #if defined(_MSC_VER) 166 | # pragma warning(pop) 167 | #endif 168 | -------------------------------------------------------------------------------- /lib/pybind11/options.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/options.h: global settings that are configurable at runtime. 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "common.h" 13 | 14 | NAMESPACE_BEGIN(pybind11) 15 | 16 | class options { 17 | public: 18 | 19 | // Default RAII constructor, which leaves settings as they currently are. 20 | options() : previous_state(global_state()) {} 21 | 22 | // Class is non-copyable. 23 | options(const options&) = delete; 24 | options& operator=(const options&) = delete; 25 | 26 | // Destructor, which restores settings that were in effect before. 27 | ~options() { 28 | global_state() = previous_state; 29 | } 30 | 31 | // Setter methods (affect the global state): 32 | 33 | options& disable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = false; return *this; } 34 | 35 | options& enable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = true; return *this; } 36 | 37 | options& disable_function_signatures() & { global_state().show_function_signatures = false; return *this; } 38 | 39 | options& enable_function_signatures() & { global_state().show_function_signatures = true; return *this; } 40 | 41 | // Getter methods (return the global state): 42 | 43 | static bool show_user_defined_docstrings() { return global_state().show_user_defined_docstrings; } 44 | 45 | static bool show_function_signatures() { return global_state().show_function_signatures; } 46 | 47 | // This type is not meant to be allocated on the heap. 48 | void* operator new(size_t) = delete; 49 | 50 | private: 51 | 52 | struct state { 53 | bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings. 54 | bool show_function_signatures = true; //< Include auto-generated function signatures in docstrings. 55 | }; 56 | 57 | static state &global_state() { 58 | static state instance; 59 | return instance; 60 | } 61 | 62 | state previous_state; 63 | }; 64 | 65 | NAMESPACE_END(pybind11) 66 | -------------------------------------------------------------------------------- /lib/pybind11/stl.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/stl.h: Transparent conversion for STL data types 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #if defined(_MSC_VER) 22 | #pragma warning(push) 23 | #pragma warning(disable: 4127) // warning C4127: Conditional expression is constant 24 | #endif 25 | 26 | #ifdef __has_include 27 | // std::optional (but including it in c++14 mode isn't allowed) 28 | # if defined(PYBIND11_CPP17) && __has_include() 29 | # include 30 | # define PYBIND11_HAS_OPTIONAL 1 31 | # endif 32 | // std::experimental::optional (but not allowed in c++11 mode) 33 | # if defined(PYBIND11_CPP14) && __has_include() 34 | # include 35 | # define PYBIND11_HAS_EXP_OPTIONAL 1 36 | # endif 37 | // std::variant 38 | # if defined(PYBIND11_CPP17) && __has_include() 39 | # include 40 | # define PYBIND11_HAS_VARIANT 1 41 | # endif 42 | #elif defined(_MSC_VER) && defined(PYBIND11_CPP17) 43 | # include 44 | # include 45 | # define PYBIND11_HAS_OPTIONAL 1 46 | # define PYBIND11_HAS_VARIANT 1 47 | #endif 48 | 49 | NAMESPACE_BEGIN(pybind11) 50 | NAMESPACE_BEGIN(detail) 51 | 52 | /// Extracts an const lvalue reference or rvalue reference for U based on the type of T (e.g. for 53 | /// forwarding a container element). Typically used indirect via forwarded_type(), below. 54 | template 55 | using forwarded_type = conditional_t< 56 | std::is_lvalue_reference::value, remove_reference_t &, remove_reference_t &&>; 57 | 58 | /// Forwards a value U as rvalue or lvalue according to whether T is rvalue or lvalue; typically 59 | /// used for forwarding a container's elements. 60 | template 61 | forwarded_type forward_like(U &&u) { 62 | return std::forward>(std::forward(u)); 63 | } 64 | 65 | template struct set_caster { 66 | using type = Type; 67 | using key_conv = make_caster; 68 | 69 | bool load(handle src, bool convert) { 70 | if (!isinstance(src)) 71 | return false; 72 | auto s = reinterpret_borrow(src); 73 | value.clear(); 74 | for (auto entry : s) { 75 | key_conv conv; 76 | if (!conv.load(entry, convert)) 77 | return false; 78 | value.insert(cast_op(std::move(conv))); 79 | } 80 | return true; 81 | } 82 | 83 | template 84 | static handle cast(T &&src, return_value_policy policy, handle parent) { 85 | pybind11::set s; 86 | for (auto &value: src) { 87 | auto value_ = reinterpret_steal(key_conv::cast(forward_like(value), policy, parent)); 88 | if (!value_ || !s.add(value_)) 89 | return handle(); 90 | } 91 | return s.release(); 92 | } 93 | 94 | PYBIND11_TYPE_CASTER(type, _("Set[") + key_conv::name() + _("]")); 95 | }; 96 | 97 | template struct map_caster { 98 | using key_conv = make_caster; 99 | using value_conv = make_caster; 100 | 101 | bool load(handle src, bool convert) { 102 | if (!isinstance(src)) 103 | return false; 104 | auto d = reinterpret_borrow(src); 105 | value.clear(); 106 | for (auto it : d) { 107 | key_conv kconv; 108 | value_conv vconv; 109 | if (!kconv.load(it.first.ptr(), convert) || 110 | !vconv.load(it.second.ptr(), convert)) 111 | return false; 112 | value.emplace(cast_op(std::move(kconv)), cast_op(std::move(vconv))); 113 | } 114 | return true; 115 | } 116 | 117 | template 118 | static handle cast(T &&src, return_value_policy policy, handle parent) { 119 | dict d; 120 | for (auto &kv: src) { 121 | auto key = reinterpret_steal(key_conv::cast(forward_like(kv.first), policy, parent)); 122 | auto value = reinterpret_steal(value_conv::cast(forward_like(kv.second), policy, parent)); 123 | if (!key || !value) 124 | return handle(); 125 | d[key] = value; 126 | } 127 | return d.release(); 128 | } 129 | 130 | PYBIND11_TYPE_CASTER(Type, _("Dict[") + key_conv::name() + _(", ") + value_conv::name() + _("]")); 131 | }; 132 | 133 | template struct list_caster { 134 | using value_conv = make_caster; 135 | 136 | bool load(handle src, bool convert) { 137 | if (!isinstance(src)) 138 | return false; 139 | auto s = reinterpret_borrow(src); 140 | value.clear(); 141 | reserve_maybe(s, &value); 142 | for (auto it : s) { 143 | value_conv conv; 144 | if (!conv.load(it, convert)) 145 | return false; 146 | value.push_back(cast_op(std::move(conv))); 147 | } 148 | return true; 149 | } 150 | 151 | private: 152 | template ().reserve(0)), void>::value, int> = 0> 154 | void reserve_maybe(sequence s, Type *) { value.reserve(s.size()); } 155 | void reserve_maybe(sequence, void *) { } 156 | 157 | public: 158 | template 159 | static handle cast(T &&src, return_value_policy policy, handle parent) { 160 | list l(src.size()); 161 | size_t index = 0; 162 | for (auto &value: src) { 163 | auto value_ = reinterpret_steal(value_conv::cast(forward_like(value), policy, parent)); 164 | if (!value_) 165 | return handle(); 166 | PyList_SET_ITEM(l.ptr(), (ssize_t) index++, value_.release().ptr()); // steals a reference 167 | } 168 | return l.release(); 169 | } 170 | 171 | PYBIND11_TYPE_CASTER(Type, _("List[") + value_conv::name() + _("]")); 172 | }; 173 | 174 | template struct type_caster> 175 | : list_caster, Type> { }; 176 | 177 | template struct type_caster> 178 | : list_caster, Type> { }; 179 | 180 | template struct array_caster { 181 | using value_conv = make_caster; 182 | 183 | private: 184 | template 185 | bool require_size(enable_if_t size) { 186 | if (value.size() != size) 187 | value.resize(size); 188 | return true; 189 | } 190 | template 191 | bool require_size(enable_if_t size) { 192 | return size == Size; 193 | } 194 | 195 | public: 196 | bool load(handle src, bool convert) { 197 | if (!isinstance(src)) 198 | return false; 199 | auto l = reinterpret_borrow(src); 200 | if (!require_size(l.size())) 201 | return false; 202 | size_t ctr = 0; 203 | for (auto it : l) { 204 | value_conv conv; 205 | if (!conv.load(it, convert)) 206 | return false; 207 | value[ctr++] = cast_op(std::move(conv)); 208 | } 209 | return true; 210 | } 211 | 212 | template 213 | static handle cast(T &&src, return_value_policy policy, handle parent) { 214 | list l(src.size()); 215 | size_t index = 0; 216 | for (auto &value: src) { 217 | auto value_ = reinterpret_steal(value_conv::cast(forward_like(value), policy, parent)); 218 | if (!value_) 219 | return handle(); 220 | PyList_SET_ITEM(l.ptr(), (ssize_t) index++, value_.release().ptr()); // steals a reference 221 | } 222 | return l.release(); 223 | } 224 | 225 | PYBIND11_TYPE_CASTER(ArrayType, _("List[") + value_conv::name() + _(_(""), _("[") + _() + _("]")) + _("]")); 226 | }; 227 | 228 | template struct type_caster> 229 | : array_caster, Type, false, Size> { }; 230 | 231 | template struct type_caster> 232 | : array_caster, Type, true> { }; 233 | 234 | template struct type_caster> 235 | : set_caster, Key> { }; 236 | 237 | template struct type_caster> 238 | : set_caster, Key> { }; 239 | 240 | template struct type_caster> 241 | : map_caster, Key, Value> { }; 242 | 243 | template struct type_caster> 244 | : map_caster, Key, Value> { }; 245 | 246 | // This type caster is intended to be used for std::optional and std::experimental::optional 247 | template struct optional_caster { 248 | using value_conv = make_caster; 249 | 250 | template 251 | static handle cast(T_ &&src, return_value_policy policy, handle parent) { 252 | if (!src) 253 | return none().inc_ref(); 254 | return value_conv::cast(*std::forward(src), policy, parent); 255 | } 256 | 257 | bool load(handle src, bool convert) { 258 | if (!src) { 259 | return false; 260 | } else if (src.is_none()) { 261 | return true; // default-constructed value is already empty 262 | } 263 | value_conv inner_caster; 264 | if (!inner_caster.load(src, convert)) 265 | return false; 266 | 267 | value.emplace(cast_op(std::move(inner_caster))); 268 | return true; 269 | } 270 | 271 | PYBIND11_TYPE_CASTER(T, _("Optional[") + value_conv::name() + _("]")); 272 | }; 273 | 274 | #if PYBIND11_HAS_OPTIONAL 275 | template struct type_caster> 276 | : public optional_caster> {}; 277 | 278 | template<> struct type_caster 279 | : public void_caster {}; 280 | #endif 281 | 282 | #if PYBIND11_HAS_EXP_OPTIONAL 283 | template struct type_caster> 284 | : public optional_caster> {}; 285 | 286 | template<> struct type_caster 287 | : public void_caster {}; 288 | #endif 289 | 290 | /// Visit a variant and cast any found type to Python 291 | struct variant_caster_visitor { 292 | return_value_policy policy; 293 | handle parent; 294 | 295 | template 296 | handle operator()(T &&src) const { 297 | return make_caster::cast(std::forward(src), policy, parent); 298 | } 299 | }; 300 | 301 | /// Helper class which abstracts away variant's `visit` function. `std::variant` and similar 302 | /// `namespace::variant` types which provide a `namespace::visit()` function are handled here 303 | /// automatically using argument-dependent lookup. Users can provide specializations for other 304 | /// variant-like classes, e.g. `boost::variant` and `boost::apply_visitor`. 305 | template class Variant> 306 | struct visit_helper { 307 | template 308 | static auto call(Args &&...args) -> decltype(visit(std::forward(args)...)) { 309 | return visit(std::forward(args)...); 310 | } 311 | }; 312 | 313 | /// Generic variant caster 314 | template struct variant_caster; 315 | 316 | template class V, typename... Ts> 317 | struct variant_caster> { 318 | static_assert(sizeof...(Ts) > 0, "Variant must consist of at least one alternative."); 319 | 320 | template 321 | bool load_alternative(handle src, bool convert, type_list) { 322 | auto caster = make_caster(); 323 | if (caster.load(src, convert)) { 324 | value = cast_op(caster); 325 | return true; 326 | } 327 | return load_alternative(src, convert, type_list{}); 328 | } 329 | 330 | bool load_alternative(handle, bool, type_list<>) { return false; } 331 | 332 | bool load(handle src, bool convert) { 333 | // Do a first pass without conversions to improve constructor resolution. 334 | // E.g. `py::int_(1).cast>()` needs to fill the `int` 335 | // slot of the variant. Without two-pass loading `double` would be filled 336 | // because it appears first and a conversion is possible. 337 | if (convert && load_alternative(src, false, type_list{})) 338 | return true; 339 | return load_alternative(src, convert, type_list{}); 340 | } 341 | 342 | template 343 | static handle cast(Variant &&src, return_value_policy policy, handle parent) { 344 | return visit_helper::call(variant_caster_visitor{policy, parent}, 345 | std::forward(src)); 346 | } 347 | 348 | using Type = V; 349 | PYBIND11_TYPE_CASTER(Type, _("Union[") + detail::concat(make_caster::name()...) + _("]")); 350 | }; 351 | 352 | #if PYBIND11_HAS_VARIANT 353 | template 354 | struct type_caster> : variant_caster> { }; 355 | #endif 356 | NAMESPACE_END(detail) 357 | 358 | inline std::ostream &operator<<(std::ostream &os, const handle &obj) { 359 | os << (std::string) str(obj); 360 | return os; 361 | } 362 | 363 | NAMESPACE_END(pybind11) 364 | 365 | #if defined(_MSC_VER) 366 | #pragma warning(pop) 367 | #endif 368 | -------------------------------------------------------------------------------- /lib/pybind11/stl_bind.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/std_bind.h: Binding generators for STL data types 3 | 4 | Copyright (c) 2016 Sergey Lyskov and Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "common.h" 13 | #include "operators.h" 14 | 15 | #include 16 | #include 17 | 18 | NAMESPACE_BEGIN(pybind11) 19 | NAMESPACE_BEGIN(detail) 20 | 21 | /* SFINAE helper class used by 'is_comparable */ 22 | template struct container_traits { 23 | template static std::true_type test_comparable(decltype(std::declval() == std::declval())*); 24 | template static std::false_type test_comparable(...); 25 | template static std::true_type test_value(typename T2::value_type *); 26 | template static std::false_type test_value(...); 27 | template static std::true_type test_pair(typename T2::first_type *, typename T2::second_type *); 28 | template static std::false_type test_pair(...); 29 | 30 | static constexpr const bool is_comparable = std::is_same(nullptr))>::value; 31 | static constexpr const bool is_pair = std::is_same(nullptr, nullptr))>::value; 32 | static constexpr const bool is_vector = std::is_same(nullptr))>::value; 33 | static constexpr const bool is_element = !is_pair && !is_vector; 34 | }; 35 | 36 | /* Default: is_comparable -> std::false_type */ 37 | template 38 | struct is_comparable : std::false_type { }; 39 | 40 | /* For non-map data structures, check whether operator== can be instantiated */ 41 | template 42 | struct is_comparable< 43 | T, enable_if_t::is_element && 44 | container_traits::is_comparable>> 45 | : std::true_type { }; 46 | 47 | /* For a vector/map data structure, recursively check the value type (which is std::pair for maps) */ 48 | template 49 | struct is_comparable::is_vector>> { 50 | static constexpr const bool value = 51 | is_comparable::value; 52 | }; 53 | 54 | /* For pairs, recursively check the two data types */ 55 | template 56 | struct is_comparable::is_pair>> { 57 | static constexpr const bool value = 58 | is_comparable::value && 59 | is_comparable::value; 60 | }; 61 | 62 | /* Fallback functions */ 63 | template void vector_if_copy_constructible(const Args &...) { } 64 | template void vector_if_equal_operator(const Args &...) { } 65 | template void vector_if_insertion_operator(const Args &...) { } 66 | template void vector_modifiers(const Args &...) { } 67 | 68 | template 69 | void vector_if_copy_constructible(enable_if_t::value, Class_> &cl) { 70 | cl.def(init(), "Copy constructor"); 71 | } 72 | 73 | template 74 | void vector_if_equal_operator(enable_if_t::value, Class_> &cl) { 75 | using T = typename Vector::value_type; 76 | 77 | cl.def(self == self); 78 | cl.def(self != self); 79 | 80 | cl.def("count", 81 | [](const Vector &v, const T &x) { 82 | return std::count(v.begin(), v.end(), x); 83 | }, 84 | arg("x"), 85 | "Return the number of times ``x`` appears in the list" 86 | ); 87 | 88 | cl.def("remove", [](Vector &v, const T &x) { 89 | auto p = std::find(v.begin(), v.end(), x); 90 | if (p != v.end()) 91 | v.erase(p); 92 | else 93 | throw value_error(); 94 | }, 95 | arg("x"), 96 | "Remove the first item from the list whose value is x. " 97 | "It is an error if there is no such item." 98 | ); 99 | 100 | cl.def("__contains__", 101 | [](const Vector &v, const T &x) { 102 | return std::find(v.begin(), v.end(), x) != v.end(); 103 | }, 104 | arg("x"), 105 | "Return true the container contains ``x``" 106 | ); 107 | } 108 | 109 | // Vector modifiers -- requires a copyable vector_type: 110 | // (Technically, some of these (pop and __delitem__) don't actually require copyability, but it seems 111 | // silly to allow deletion but not insertion, so include them here too.) 112 | template 113 | void vector_modifiers(enable_if_t::value, Class_> &cl) { 114 | using T = typename Vector::value_type; 115 | using SizeType = typename Vector::size_type; 116 | using DiffType = typename Vector::difference_type; 117 | 118 | cl.def("append", 119 | [](Vector &v, const T &value) { v.push_back(value); }, 120 | arg("x"), 121 | "Add an item to the end of the list"); 122 | 123 | cl.def("__init__", [](Vector &v, iterable it) { 124 | new (&v) Vector(); 125 | try { 126 | v.reserve(len(it)); 127 | for (handle h : it) 128 | v.push_back(h.cast()); 129 | } catch (...) { 130 | v.~Vector(); 131 | throw; 132 | } 133 | }); 134 | 135 | cl.def("extend", 136 | [](Vector &v, const Vector &src) { 137 | v.insert(v.end(), src.begin(), src.end()); 138 | }, 139 | arg("L"), 140 | "Extend the list by appending all the items in the given list" 141 | ); 142 | 143 | cl.def("insert", 144 | [](Vector &v, SizeType i, const T &x) { 145 | if (i > v.size()) 146 | throw index_error(); 147 | v.insert(v.begin() + (DiffType) i, x); 148 | }, 149 | arg("i") , arg("x"), 150 | "Insert an item at a given position." 151 | ); 152 | 153 | cl.def("pop", 154 | [](Vector &v) { 155 | if (v.empty()) 156 | throw index_error(); 157 | T t = v.back(); 158 | v.pop_back(); 159 | return t; 160 | }, 161 | "Remove and return the last item" 162 | ); 163 | 164 | cl.def("pop", 165 | [](Vector &v, SizeType i) { 166 | if (i >= v.size()) 167 | throw index_error(); 168 | T t = v[i]; 169 | v.erase(v.begin() + (DiffType) i); 170 | return t; 171 | }, 172 | arg("i"), 173 | "Remove and return the item at index ``i``" 174 | ); 175 | 176 | cl.def("__setitem__", 177 | [](Vector &v, SizeType i, const T &t) { 178 | if (i >= v.size()) 179 | throw index_error(); 180 | v[i] = t; 181 | } 182 | ); 183 | 184 | /// Slicing protocol 185 | cl.def("__getitem__", 186 | [](const Vector &v, slice slice) -> Vector * { 187 | size_t start, stop, step, slicelength; 188 | 189 | if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) 190 | throw error_already_set(); 191 | 192 | Vector *seq = new Vector(); 193 | seq->reserve((size_t) slicelength); 194 | 195 | for (size_t i=0; ipush_back(v[start]); 197 | start += step; 198 | } 199 | return seq; 200 | }, 201 | arg("s"), 202 | "Retrieve list elements using a slice object" 203 | ); 204 | 205 | cl.def("__setitem__", 206 | [](Vector &v, slice slice, const Vector &value) { 207 | size_t start, stop, step, slicelength; 208 | if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) 209 | throw error_already_set(); 210 | 211 | if (slicelength != value.size()) 212 | throw std::runtime_error("Left and right hand size of slice assignment have different sizes!"); 213 | 214 | for (size_t i=0; i= v.size()) 225 | throw index_error(); 226 | v.erase(v.begin() + DiffType(i)); 227 | }, 228 | "Delete the list elements at index ``i``" 229 | ); 230 | 231 | cl.def("__delitem__", 232 | [](Vector &v, slice slice) { 233 | size_t start, stop, step, slicelength; 234 | 235 | if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) 236 | throw error_already_set(); 237 | 238 | if (step == 1 && false) { 239 | v.erase(v.begin() + (DiffType) start, v.begin() + DiffType(start + slicelength)); 240 | } else { 241 | for (size_t i = 0; i < slicelength; ++i) { 242 | v.erase(v.begin() + DiffType(start)); 243 | start += step - 1; 244 | } 245 | } 246 | }, 247 | "Delete list elements using a slice object" 248 | ); 249 | 250 | } 251 | 252 | // If the type has an operator[] that doesn't return a reference (most notably std::vector), 253 | // we have to access by copying; otherwise we return by reference. 254 | template using vector_needs_copy = negation< 255 | std::is_same()[typename Vector::size_type()]), typename Vector::value_type &>>; 256 | 257 | // The usual case: access and iterate by reference 258 | template 259 | void vector_accessor(enable_if_t::value, Class_> &cl) { 260 | using T = typename Vector::value_type; 261 | using SizeType = typename Vector::size_type; 262 | using ItType = typename Vector::iterator; 263 | 264 | cl.def("__getitem__", 265 | [](Vector &v, SizeType i) -> T & { 266 | if (i >= v.size()) 267 | throw index_error(); 268 | return v[i]; 269 | }, 270 | return_value_policy::reference_internal // ref + keepalive 271 | ); 272 | 273 | cl.def("__iter__", 274 | [](Vector &v) { 275 | return make_iterator< 276 | return_value_policy::reference_internal, ItType, ItType, T&>( 277 | v.begin(), v.end()); 278 | }, 279 | keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ 280 | ); 281 | } 282 | 283 | // The case for special objects, like std::vector, that have to be returned-by-copy: 284 | template 285 | void vector_accessor(enable_if_t::value, Class_> &cl) { 286 | using T = typename Vector::value_type; 287 | using SizeType = typename Vector::size_type; 288 | using ItType = typename Vector::iterator; 289 | cl.def("__getitem__", 290 | [](const Vector &v, SizeType i) -> T { 291 | if (i >= v.size()) 292 | throw index_error(); 293 | return v[i]; 294 | } 295 | ); 296 | 297 | cl.def("__iter__", 298 | [](Vector &v) { 299 | return make_iterator< 300 | return_value_policy::copy, ItType, ItType, T>( 301 | v.begin(), v.end()); 302 | }, 303 | keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ 304 | ); 305 | } 306 | 307 | template auto vector_if_insertion_operator(Class_ &cl, std::string const &name) 308 | -> decltype(std::declval() << std::declval(), void()) { 309 | using size_type = typename Vector::size_type; 310 | 311 | cl.def("__repr__", 312 | [name](Vector &v) { 313 | std::ostringstream s; 314 | s << name << '['; 315 | for (size_type i=0; i < v.size(); ++i) { 316 | s << v[i]; 317 | if (i != v.size() - 1) 318 | s << ", "; 319 | } 320 | s << ']'; 321 | return s.str(); 322 | }, 323 | "Return the canonical string representation of this list." 324 | ); 325 | } 326 | 327 | // Provide the buffer interface for vectors if we have data() and we have a format for it 328 | // GCC seems to have "void std::vector::data()" - doing SFINAE on the existence of data() is insufficient, we need to check it returns an appropriate pointer 329 | template 330 | struct vector_has_data_and_format : std::false_type {}; 331 | template 332 | struct vector_has_data_and_format::format(), std::declval().data()), typename Vector::value_type*>::value>> : std::true_type {}; 333 | 334 | // Add the buffer interface to a vector 335 | template 336 | enable_if_t...>::value> 337 | vector_buffer(Class_& cl) { 338 | using T = typename Vector::value_type; 339 | 340 | static_assert(vector_has_data_and_format::value, "There is not an appropriate format descriptor for this vector"); 341 | 342 | // numpy.h declares this for arbitrary types, but it may raise an exception and crash hard at runtime if PYBIND11_NUMPY_DTYPE hasn't been called, so check here 343 | format_descriptor::format(); 344 | 345 | cl.def_buffer([](Vector& v) -> buffer_info { 346 | return buffer_info(v.data(), static_cast(sizeof(T)), format_descriptor::format(), 1, {v.size()}, {sizeof(T)}); 347 | }); 348 | 349 | cl.def("__init__", [](Vector& vec, buffer buf) { 350 | auto info = buf.request(); 351 | if (info.ndim != 1 || info.strides[0] % static_cast(sizeof(T))) 352 | throw type_error("Only valid 1D buffers can be copied to a vector"); 353 | if (!detail::compare_buffer_info::compare(info) || (ssize_t) sizeof(T) != info.itemsize) 354 | throw type_error("Format mismatch (Python: " + info.format + " C++: " + format_descriptor::format() + ")"); 355 | new (&vec) Vector(); 356 | vec.reserve((size_t) info.shape[0]); 357 | T *p = static_cast(info.ptr); 358 | ssize_t step = info.strides[0] / static_cast(sizeof(T)); 359 | T *end = p + info.shape[0] * step; 360 | for (; p != end; p += step) 361 | vec.push_back(*p); 362 | }); 363 | 364 | return; 365 | } 366 | 367 | template 368 | enable_if_t...>::value> vector_buffer(Class_&) {} 369 | 370 | NAMESPACE_END(detail) 371 | 372 | // 373 | // std::vector 374 | // 375 | template , typename... Args> 376 | class_ bind_vector(handle scope, std::string const &name, Args&&... args) { 377 | using Class_ = class_; 378 | 379 | // If the value_type is unregistered (e.g. a converting type) or is itself registered 380 | // module-local then make the vector binding module-local as well: 381 | using vtype = typename Vector::value_type; 382 | auto vtype_info = detail::get_type_info(typeid(vtype)); 383 | bool local = !vtype_info || vtype_info->module_local; 384 | 385 | Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward(args)...); 386 | 387 | // Declare the buffer interface if a buffer_protocol() is passed in 388 | detail::vector_buffer(cl); 389 | 390 | cl.def(init<>()); 391 | 392 | // Register copy constructor (if possible) 393 | detail::vector_if_copy_constructible(cl); 394 | 395 | // Register comparison-related operators and functions (if possible) 396 | detail::vector_if_equal_operator(cl); 397 | 398 | // Register stream insertion operator (if possible) 399 | detail::vector_if_insertion_operator(cl, name); 400 | 401 | // Modifiers require copyable vector value type 402 | detail::vector_modifiers(cl); 403 | 404 | // Accessor and iterator; return by value if copyable, otherwise we return by ref + keep-alive 405 | detail::vector_accessor(cl); 406 | 407 | cl.def("__bool__", 408 | [](const Vector &v) -> bool { 409 | return !v.empty(); 410 | }, 411 | "Check whether the list is nonempty" 412 | ); 413 | 414 | cl.def("__len__", &Vector::size); 415 | 416 | 417 | 418 | 419 | #if 0 420 | // C++ style functions deprecated, leaving it here as an example 421 | cl.def(init()); 422 | 423 | cl.def("resize", 424 | (void (Vector::*) (size_type count)) & Vector::resize, 425 | "changes the number of elements stored"); 426 | 427 | cl.def("erase", 428 | [](Vector &v, SizeType i) { 429 | if (i >= v.size()) 430 | throw index_error(); 431 | v.erase(v.begin() + i); 432 | }, "erases element at index ``i``"); 433 | 434 | cl.def("empty", &Vector::empty, "checks whether the container is empty"); 435 | cl.def("size", &Vector::size, "returns the number of elements"); 436 | cl.def("push_back", (void (Vector::*)(const T&)) &Vector::push_back, "adds an element to the end"); 437 | cl.def("pop_back", &Vector::pop_back, "removes the last element"); 438 | 439 | cl.def("max_size", &Vector::max_size, "returns the maximum possible number of elements"); 440 | cl.def("reserve", &Vector::reserve, "reserves storage"); 441 | cl.def("capacity", &Vector::capacity, "returns the number of elements that can be held in currently allocated storage"); 442 | cl.def("shrink_to_fit", &Vector::shrink_to_fit, "reduces memory usage by freeing unused memory"); 443 | 444 | cl.def("clear", &Vector::clear, "clears the contents"); 445 | cl.def("swap", &Vector::swap, "swaps the contents"); 446 | 447 | cl.def("front", [](Vector &v) { 448 | if (v.size()) return v.front(); 449 | else throw index_error(); 450 | }, "access the first element"); 451 | 452 | cl.def("back", [](Vector &v) { 453 | if (v.size()) return v.back(); 454 | else throw index_error(); 455 | }, "access the last element "); 456 | 457 | #endif 458 | 459 | return cl; 460 | } 461 | 462 | 463 | 464 | // 465 | // std::map, std::unordered_map 466 | // 467 | 468 | NAMESPACE_BEGIN(detail) 469 | 470 | /* Fallback functions */ 471 | template void map_if_insertion_operator(const Args &...) { } 472 | template void map_assignment(const Args &...) { } 473 | 474 | // Map assignment when copy-assignable: just copy the value 475 | template 476 | void map_assignment(enable_if_t::value, Class_> &cl) { 477 | using KeyType = typename Map::key_type; 478 | using MappedType = typename Map::mapped_type; 479 | 480 | cl.def("__setitem__", 481 | [](Map &m, const KeyType &k, const MappedType &v) { 482 | auto it = m.find(k); 483 | if (it != m.end()) it->second = v; 484 | else m.emplace(k, v); 485 | } 486 | ); 487 | } 488 | 489 | // Not copy-assignable, but still copy-constructible: we can update the value by erasing and reinserting 490 | template 491 | void map_assignment(enable_if_t< 492 | !std::is_copy_assignable::value && 493 | is_copy_constructible::value, 494 | Class_> &cl) { 495 | using KeyType = typename Map::key_type; 496 | using MappedType = typename Map::mapped_type; 497 | 498 | cl.def("__setitem__", 499 | [](Map &m, const KeyType &k, const MappedType &v) { 500 | // We can't use m[k] = v; because value type might not be default constructable 501 | auto r = m.emplace(k, v); 502 | if (!r.second) { 503 | // value type is not copy assignable so the only way to insert it is to erase it first... 504 | m.erase(r.first); 505 | m.emplace(k, v); 506 | } 507 | } 508 | ); 509 | } 510 | 511 | 512 | template auto map_if_insertion_operator(Class_ &cl, std::string const &name) 513 | -> decltype(std::declval() << std::declval() << std::declval(), void()) { 514 | 515 | cl.def("__repr__", 516 | [name](Map &m) { 517 | std::ostringstream s; 518 | s << name << '{'; 519 | bool f = false; 520 | for (auto const &kv : m) { 521 | if (f) 522 | s << ", "; 523 | s << kv.first << ": " << kv.second; 524 | f = true; 525 | } 526 | s << '}'; 527 | return s.str(); 528 | }, 529 | "Return the canonical string representation of this map." 530 | ); 531 | } 532 | 533 | 534 | NAMESPACE_END(detail) 535 | 536 | template , typename... Args> 537 | class_ bind_map(handle scope, const std::string &name, Args&&... args) { 538 | using KeyType = typename Map::key_type; 539 | using MappedType = typename Map::mapped_type; 540 | using Class_ = class_; 541 | 542 | // If either type is a non-module-local bound type then make the map binding non-local as well; 543 | // otherwise (e.g. both types are either module-local or converting) the map will be 544 | // module-local. 545 | auto tinfo = detail::get_type_info(typeid(MappedType)); 546 | bool local = !tinfo || tinfo->module_local; 547 | if (local) { 548 | tinfo = detail::get_type_info(typeid(KeyType)); 549 | local = !tinfo || tinfo->module_local; 550 | } 551 | 552 | Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward(args)...); 553 | 554 | cl.def(init<>()); 555 | 556 | // Register stream insertion operator (if possible) 557 | detail::map_if_insertion_operator(cl, name); 558 | 559 | cl.def("__bool__", 560 | [](const Map &m) -> bool { return !m.empty(); }, 561 | "Check whether the map is nonempty" 562 | ); 563 | 564 | cl.def("__iter__", 565 | [](Map &m) { return make_key_iterator(m.begin(), m.end()); }, 566 | keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ 567 | ); 568 | 569 | cl.def("items", 570 | [](Map &m) { return make_iterator(m.begin(), m.end()); }, 571 | keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ 572 | ); 573 | 574 | cl.def("__getitem__", 575 | [](Map &m, const KeyType &k) -> MappedType & { 576 | auto it = m.find(k); 577 | if (it == m.end()) 578 | throw key_error(); 579 | return it->second; 580 | }, 581 | return_value_policy::reference_internal // ref + keepalive 582 | ); 583 | 584 | // Assignment provided only if the type is copyable 585 | detail::map_assignment(cl); 586 | 587 | cl.def("__delitem__", 588 | [](Map &m, const KeyType &k) { 589 | auto it = m.find(k); 590 | if (it == m.end()) 591 | throw key_error(); 592 | return m.erase(it); 593 | } 594 | ); 595 | 596 | cl.def("__len__", &Map::size); 597 | 598 | return cl; 599 | } 600 | 601 | NAMESPACE_END(pybind11) 602 | -------------------------------------------------------------------------------- /lib/pybind11/typeid.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/typeid.h: Compiler-independent access to type identifiers 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | #if defined(__GNUG__) 16 | #include 17 | #endif 18 | 19 | NAMESPACE_BEGIN(pybind11) 20 | NAMESPACE_BEGIN(detail) 21 | /// Erase all occurrences of a substring 22 | inline void erase_all(std::string &string, const std::string &search) { 23 | for (size_t pos = 0;;) { 24 | pos = string.find(search, pos); 25 | if (pos == std::string::npos) break; 26 | string.erase(pos, search.length()); 27 | } 28 | } 29 | 30 | PYBIND11_NOINLINE inline void clean_type_id(std::string &name) { 31 | #if defined(__GNUG__) 32 | int status = 0; 33 | std::unique_ptr res { 34 | abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status), std::free }; 35 | if (status == 0) 36 | name = res.get(); 37 | #else 38 | detail::erase_all(name, "class "); 39 | detail::erase_all(name, "struct "); 40 | detail::erase_all(name, "enum "); 41 | #endif 42 | detail::erase_all(name, "pybind11::"); 43 | } 44 | NAMESPACE_END(detail) 45 | 46 | /// Return a string representation of a C++ type 47 | template static std::string type_id() { 48 | std::string name(typeid(T).name()); 49 | detail::clean_type_id(name); 50 | return name; 51 | } 52 | 53 | NAMESPACE_END(pybind11) 54 | -------------------------------------------------------------------------------- /mander/__init__.py: -------------------------------------------------------------------------------- 1 | import _mander 2 | 3 | def prepGeoJSON(geojson): 4 | """Loads GeoJSON into the mander library for accelerate processing later. 5 | 6 | Parameters: 7 | geojson -- The GeoJSON to load 8 | 9 | Returns: 10 | A string that can be passed in lieu of the original GeoJSON to take 11 | advatange of internal processing that has already been done. 12 | """ 13 | return _mander.prepGeoJSON(geojson) 14 | 15 | 16 | 17 | def getListOfUnboundedScores(): 18 | """Returns a list of scores the library can calculate. 19 | Subsets of this list may be passed to the other functions in the library. 20 | Scores listed are those which can be calculated purely using the shape 21 | of a single district. 22 | 23 | Returns: 24 | The list of unbounded scores. 25 | """ 26 | return _mander.getListOfUnboundedScores() 27 | 28 | 29 | 30 | def getListOfBoundedScores(): 31 | """Returns a list of scores the library can calculate. 32 | Subsets of this list may be passed to the other functions in the library. 33 | Scores listed are those in which a superunit bounds a subunit. 34 | 35 | Returns: 36 | The list of bounded scores. 37 | """ 38 | return _mander.getListOfBoundedScores() 39 | 40 | 41 | 42 | def getUnboundedScoresForGeoJSON(geojson, id="", score_list=[]): 43 | """Calculates unbounded scores for a given GeoJSON string. 44 | 45 | Parameters: 46 | geojson -- GeoJSON string for which to calculate scores. 47 | Can also use a string returned by prepGeoJSON() 48 | id -- An attribute value used to key the JSON output 49 | score_list -- A list of scores to calculate. Valid values from 50 | `getListOfUnboundedScores()` 51 | An empty list indicates all scores should be calculated. 52 | 53 | Returns: 54 | A JSON dictionary whose keys are taken from `id` or are the 0-based index 55 | number of the multipolygon for which the scores were calculated. 56 | """ 57 | 58 | return _mander.getUnboundedScoresForGeoJSON(geojson,id,score_list) 59 | 60 | 61 | 62 | def getBoundedScoresForGeoJSON(gj_sub, gj_sup, join_on, id="", score_list=[]): 63 | """Calculates unbounded scores for a given GeoJSON string. 64 | 65 | Parameters: 66 | gj_sub -- GeoJSON string of subunit for which to calculate scores. 67 | Can also use a string returned by prepGeoJSON() 68 | gj_sup -- GeoJSON string of a superunit which bounds the subunit. 69 | Can also use a string returned by prepGeoJSON() 70 | id -- An attribute value used to key the JSON output. An empty string 71 | defaults to a number representing the order of the multipolygon 72 | within the GeoJSON. 73 | join_on -- Attribute present in both sub-unit and super-unit used to match 74 | the two 75 | score_list -- A list of scores to calculate. Valid values from 76 | `getListOfUnboundedScores()` and `getListOfBoundedScores()` 77 | An empty list indicates all scores should be calculated. 78 | 79 | Returns: 80 | A JSON dictionary whose keys are taken from `id` or are the 0-based index 81 | number of the multipolygon for which the scores were calculated. 82 | """ 83 | 84 | return _mander.getBoundedScoresForGeoJSON(gj_sub, gj_sup, id, join_on, score_list) 85 | 86 | 87 | 88 | def augmentShapefileWithUnboundedScores(filename, score_list=[]): 89 | """Adds indicated scores to an existing shapefile 90 | 91 | Parameters: 92 | filename -- File to which scores should be added 93 | score_list -- A list of scores to calculate. Valid values from 94 | `getListOfUnboundedScores()` 95 | An empty list indicates all scores should be calculated. 96 | 97 | Returns: 98 | No return. The file is modified or an exception is thrown. 99 | """ 100 | 101 | return _mander.augmentShapefileWithUnboundedScores(filename,score_list) 102 | 103 | 104 | 105 | def addUnboundedScoresToNewShapefile(in_filename, out_filename, score_list=[]): 106 | """Adds indicated scores to an existing shapefile 107 | 108 | Parameters: 109 | in_filename -- File containing regions to be scored 110 | out_filename -- Filename of new shapefile which will contain the scores 111 | score_list -- A list of scores to calculate. Valid values from 112 | `getListOfUnboundedScores()` 113 | An empty list indicates all scores should be calculated. 114 | 115 | Returns: 116 | No return. The new shapefile is built or an exception is thrown. 117 | """ 118 | 119 | return _mander.addUnboundedScoresToNewShapefile(in_filename,out_filename,score_list) 120 | 121 | 122 | 123 | def augmentShapefileWithBoundedScores(sub_filename, sup_filename, join_on, score_list=[]): 124 | """Adds indicated scores to an existing shapefile 125 | 126 | Parameters: 127 | sub_filename -- File containing the subunits 128 | sup_filename -- File containing the superunits which bound the subunits 129 | join_on -- Name of an attribute in both sub- and superunits which 130 | indicates nestedness 131 | score_list -- A list of scores to calculate. Valid values from 132 | `getListOfUnboundedScores()` or `getListOfBoundedScores()` 133 | An empty list indicates all scores should be calculated. 134 | 135 | Returns: 136 | No return. The file is modified or an exception is thrown. 137 | """ 138 | 139 | return _mander.augmentShapefileWithBoundedScores(sub_filename,sup_filename,join_on,score_list) 140 | 141 | 142 | 143 | def addBoundedScoresToNewShapefile(sub_filename, sup_filename, out_filename, join_on, score_list=[]): 144 | """Adds indicated scores to an existing shapefile 145 | 146 | Parameters: 147 | sub_filename -- File containing the subunits 148 | sup_filename -- File containing the superunits which bound the subunits 149 | out_filename -- Filename of output shapefile 150 | join_on -- Name of an attribute in both sub- and superunits which 151 | indicates nestedness 152 | score_list -- A list of scores to calculate. Valid values from 153 | `getListOfUnboundedScores()` or `getListOfBoundedScores()` 154 | An empty list indicates all scores should be calculated. 155 | 156 | Returns: 157 | No return. The new shapefile is built or an exception is thrown. 158 | """ 159 | 160 | return _mander.addBoundedScoresToNewShapefile(sub_filename,sup_filename,out_filename,join_on,score_list) 161 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Fiona==1.7.8 2 | Shapely==1.5.17 3 | click==6.7 4 | click-plugins==1.0.3 5 | cligj==0.4.0 6 | cycler==0.10.0 7 | descartes==1.1.0 8 | enum34==1.1.6 9 | functools32==3.2.3-2 10 | geopandas==0.2.1 11 | matplotlib==2.0.2 12 | munch==2.2.0 13 | numpy==1.13.1 14 | pandas==0.20.3 15 | pyparsing==2.2.0 16 | pyproj==1.9.5.1 17 | python-dateutil==2.6.1 18 | pytz==2017.2 19 | six==1.10.0 20 | subprocess32==3.2.7 21 | wsgiref==0.1.2 22 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.md 3 | packager = Richard Barnes 4 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | #from distutils.core import setup, Extension 3 | import glob 4 | 5 | ext_modules = [ 6 | setuptools.Extension( 7 | "_mander", 8 | (glob.glob('src/*.cpp') + glob.glob('lib/compactnesslib/src/*.cpp') + glob.glob('lib/compactnesslib/lib/**.cpp')), 9 | include_dirs = ['lib/compactnesslib/api', 'lib/pybind11/', 'lib/compactnesslib/lib'], 10 | language = 'c++', 11 | extra_compile_args = ['-std=c++11'], 12 | define_macros = [('DOCTEST_CONFIG_DISABLE',None)] 13 | ) 14 | ] 15 | 16 | setuptools.setup(name='mander', 17 | version = '1.0.0', 18 | description = 'Python package to calculate compactness metrics for district shapes.', 19 | url = 'http://github.com/gerrymandr/python-mander', 20 | author = 'Geometry of Redistricting Workshop', 21 | author_email = 'gerrymandr@gmail.com', 22 | license = 'MIT', 23 | packages = setuptools.find_packages(), 24 | scripts = ['bin/mander'], 25 | ext_modules = ext_modules 26 | ) 27 | -------------------------------------------------------------------------------- /src/pywrapper.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace py = pybind11; 7 | 8 | //Tutorials 9 | //http://www.benjack.io/2017/06/12/python-cpp-tests.html 10 | //https://pybind11.readthedocs.io/en/stable/classes.html 11 | //http://people.duke.edu/~ccc14/sta-663-2016/18G_C++_Python_pybind11.html 12 | 13 | std::string getUnboundedScoresForGeoJSON(const std::string &geojson, const std::string id, const std::vector &score_list){ 14 | auto gc = complib::ReadGeoJSON(geojson); 15 | complib::CalculateListOfUnboundedScores(gc, score_list); 16 | return complib::OutScoreJSON(gc, id); 17 | } 18 | 19 | void augmentShapefileWithUnboundedScores(const std::string filename, const std::vector &score_list){ 20 | auto gc = complib::ReadShapefile(filename); 21 | complib::CalculateListOfUnboundedScores(gc, score_list); 22 | complib::WriteShapeScores(gc, filename); 23 | } 24 | 25 | void addUnboundedScoresToNewShapefile(const std::string in_filename, const std::string out_filename, const std::vector &score_list){ 26 | auto gc = complib::ReadShapefile(in_filename); 27 | complib::CalculateListOfUnboundedScores(gc, score_list); 28 | complib::WriteShapefile(gc,out_filename); 29 | } 30 | 31 | 32 | std::string getBoundedScoresForGeoJSON( 33 | const std::string &gj_subunit, 34 | const std::string &gj_superunit, 35 | const std::string id, 36 | const std::string join_on, 37 | const std::vector &score_list 38 | ){ 39 | auto gc_sub = complib::ReadGeoJSON(gj_subunit); 40 | auto gc_sup = complib::ReadGeoJSON(gj_superunit); 41 | complib::CalculateListOfBoundedScores(gc_sub, gc_sup, join_on, score_list); 42 | complib::CalculateListOfUnboundedScores(gc_sub, score_list); 43 | return complib::OutScoreJSON(gc_sub, id); 44 | } 45 | 46 | void augmentShapefileWithBoundedScores( 47 | const std::string subunit_filename, 48 | const std::string superunit_filename, 49 | const std::string join_on, 50 | const std::vector &score_list 51 | ){ 52 | auto gc_sub = complib::ReadShapefile(subunit_filename); 53 | auto gc_sup = complib::ReadShapefile(superunit_filename); 54 | complib::CalculateListOfBoundedScores(gc_sub, gc_sup, join_on, score_list); 55 | complib::CalculateListOfUnboundedScores(gc_sub, score_list); 56 | complib::WriteShapeScores(gc_sub, subunit_filename); 57 | } 58 | 59 | void addBoundedScoresToNewShapefile( 60 | const std::string in_subunit_filename, 61 | const std::string in_superunit_filename, 62 | const std::string out_filename, 63 | const std::string join_on, 64 | const std::vector &score_list 65 | ){ 66 | auto gc_sub = complib::ReadShapefile(in_subunit_filename); 67 | auto gc_sup = complib::ReadShapefile(in_superunit_filename); 68 | complib::CalculateListOfBoundedScores(gc_sub, gc_sup, join_on, score_list); 69 | complib::CalculateListOfUnboundedScores(gc_sub, score_list); 70 | complib::WriteShapefile(gc_sub,out_filename); 71 | } 72 | 73 | PYBIND11_MODULE(_mander, m) { 74 | m.doc() = "Internal library used by python-mander to calculate scores"; 75 | 76 | m.def( 77 | "prepGeoJSON", 78 | &complib::PrepGeoJSON, 79 | "Load GeoJSON into memory for quick retrieval later." 80 | ); 81 | 82 | m.def( 83 | "getListOfUnboundedScores", 84 | &complib::getListOfUnboundedScores, 85 | "Returns a list of unbounded compactness scores." 86 | ); 87 | 88 | m.def( 89 | "getListOfBoundedScores", 90 | &complib::getListOfBoundedScores, 91 | "Returns a list of bounded compactness scores." 92 | ); 93 | 94 | m.def( 95 | "getUnboundedScoresForGeoJSON", 96 | &getUnboundedScoresForGeoJSON, 97 | "Takes a GeoJSON string as input, calculates all scores, return a JSON dictionary of the scores keyed to values identified 'id' which are expected to be properties of the GeoJSON objects. If id='', then the object's 0-indexed order is used.", 98 | py::arg("geojson"), 99 | py::arg("id")="", 100 | py::arg("score_list")="" 101 | ); 102 | 103 | m.def( 104 | "getBoundedScoresForGeoJSON", 105 | &getBoundedScoresForGeoJSON, 106 | "Takes a GeoJSON string as input, calculates all scores, return a JSON dictionary of the scores keyed to values identified 'id' which are expected to be properties of the GeoJSON objects. If id='', then the object's 0-indexed order is used.", 107 | py::arg("gj_subunit"), 108 | py::arg("gj_superunit"), 109 | py::arg("join_on")="", 110 | py::arg("join_id")="", 111 | py::arg("score_list")="" 112 | ); 113 | 114 | m.def( 115 | "augmentShapefileWithUnboundedScores", 116 | &augmentShapefileWithUnboundedScores, 117 | "Given the filename of a shapefile containing subunits, and another of superunits, this function calculates the scores of its shapes and adds them to the file.", 118 | py::arg("filename"), 119 | py::arg("score_list")="" 120 | ); 121 | 122 | m.def( 123 | "addUnboundedScoresToNewShapefile", 124 | &addUnboundedScoresToNewShapefile, 125 | "Reads a shapefile, calculates its scores, and outputs a new shapefile.", 126 | py::arg("in_filename")="", 127 | py::arg("out_filename")="", 128 | py::arg("score_list")="" 129 | ); 130 | 131 | m.def( 132 | "augmentShapefileWithBoundedScores", 133 | &augmentShapefileWithBoundedScores, 134 | "Given the filename of a shapefile containing subunits, and another of superunits, this function calculates the scores of its shapes and adds them to the file.", 135 | py::arg("subunit_filename"), 136 | py::arg("superunit_filename"), 137 | py::arg("join_id")="", 138 | py::arg("score_list")="" 139 | ); 140 | 141 | m.def( 142 | "addBoundedScoresToNewShapefile", 143 | &addBoundedScoresToNewShapefile, 144 | "Reads a shapefile, calculates its scores, and outputs a new shapefile.", 145 | py::arg("in_subunit_filename")="", 146 | py::arg("in_superunit_filename")="", 147 | py::arg("out_filename")="", 148 | py::arg("join_on")="", 149 | py::arg("score_list")="" 150 | ); 151 | } -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gerrymandr/python-mander/07e0c1b9779468d4a9827f29e6baa378023015c3/test/__init__.py -------------------------------------------------------------------------------- /test/data/CD_CA_24.geojson: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FeatureCollection", 3 | "name": "CD_CA_24", 4 | "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, 5 | "features": [ 6 | { "type": "Feature", "properties": { "STATEFP": "06", "CD115FP": "24", "AFFGEOID": "5001500US0624", "GEOID": "0624", "LSAD": "C2", "CDSESSN": "115", "ALAND": 17833000980, "AWATER": 3683565951 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -119.052774, 33.46586 ], [ -119.046349523412019, 33.471588250849699 ], [ -119.045881, 33.472006 ], [ -119.044931, 33.477954 ], [ -119.049684, 33.483901 ], [ -119.038544, 33.483345 ], [ -119.035186, 33.488064 ], [ -119.031145, 33.489649 ], [ -119.031383, 33.483108 ], [ -119.029481, 33.477359 ], [ -119.032096, 33.475178 ], [ -119.032334, 33.468834 ], [ -119.03471, 33.466454 ], [ -119.038522, 33.465691 ], [ -119.041841, 33.467644 ], [ -119.050743, 33.463242 ], [ -119.052108547322007, 33.465002218065095 ], [ -119.052774, 33.46586 ] ] ], [ [ [ -119.929889, 34.059734 ], [ -119.925448, 34.060816 ], [ -119.922027, 34.060532 ], [ -119.919413, 34.065257 ], [ -119.922888, 34.067136 ], [ -119.923337, 34.069361 ], [ -119.919413, 34.074117 ], [ -119.919155, 34.07728 ], [ -119.912857, 34.077508 ], [ -119.89113, 34.072856 ], [ -119.883835, 34.074468 ], [ -119.857304, 34.071298 ], [ -119.825865, 34.059794 ], [ -119.818742, 34.052997 ], [ -119.815258, 34.054065 ], [ -119.807825, 34.052127 ], [ -119.800917, 34.054094 ], [ -119.796059, 34.057026 ], [ -119.789798, 34.05726 ], [ -119.770729, 34.055051 ], [ -119.766081, 34.05537 ], [ -119.763688, 34.057155 ], [ -119.759428, 34.058835 ], [ -119.755521, 34.056716 ], [ -119.755114, 34.053817 ], [ -119.747856, 34.053174 ], [ -119.739472, 34.049299 ], [ -119.734507, 34.046087 ], [ -119.731217, 34.048418 ], [ -119.726437, 34.047908 ], [ -119.712576, 34.043265 ], [ -119.704628, 34.037681 ], [ -119.700587, 34.033695 ], [ -119.693145, 34.029287 ], [ -119.68935, 34.025217 ], [ -119.686507, 34.019805 ], [ -119.673549, 34.019552 ], [ -119.668304, 34.016628 ], [ -119.658539, 34.019033 ], [ -119.65454, 34.019927 ], [ -119.651341, 34.017481 ], [ -119.651395, 34.015718 ], [ -119.642995, 34.016605 ], [ -119.639849, 34.015445 ], [ -119.637742, 34.013178 ], [ -119.619343, 34.016468 ], [ -119.612226, 34.021256 ], [ -119.604287, 34.031561 ], [ -119.608798, 34.035245 ], [ -119.609239, 34.03735 ], [ -119.599534, 34.044796 ], [ -119.595931, 34.045762 ], [ -119.59498, 34.049504 ], [ -119.5888, 34.048913 ], [ -119.58901, 34.051818 ], [ -119.584301, 34.053643 ], [ -119.579752, 34.050705 ], [ -119.57341, 34.05011 ], [ -119.573251, 34.052958 ], [ -119.5667, 34.053452 ], [ -119.562347, 34.055283 ], [ -119.556714, 34.052064 ], [ -119.556116, 34.0488 ], [ -119.550704, 34.046431 ], [ -119.547532, 34.04837 ], [ -119.546262, 34.044645 ], [ -119.540344, 34.044716 ], [ -119.529603, 34.041155 ], [ -119.52064, 34.034262 ], [ -119.52177, 34.032247 ], [ -119.527524, 34.026445 ], [ -119.532413, 34.024949 ], [ -119.538847, 34.023988 ], [ -119.542449, 34.021082 ], [ -119.543957, 34.017915 ], [ -119.5425, 34.015042 ], [ -119.54828, 34.009819 ], [ -119.547072, 34.005469 ], [ -119.554472, 33.99782 ], [ -119.560464, 33.99553 ], [ -119.575636, 33.996009 ], [ -119.5902, 33.989712 ], [ -119.596877, 33.988611 ], [ -119.619082, 33.987228 ], [ -119.621117, 33.98899 ], [ -119.633729, 33.987243 ], [ -119.64771, 33.987786 ], [ -119.662825, 33.985889 ], [ -119.674832, 33.978429 ], [ -119.69011, 33.972225 ], [ -119.69833, 33.970738 ], [ -119.700581, 33.966693 ], [ -119.706452, 33.968133 ], [ -119.712363, 33.965422 ], [ -119.714696, 33.961439 ], [ -119.721206, 33.959583 ], [ -119.728119, 33.961802 ], [ -119.742966, 33.963877 ], [ -119.750438, 33.963759 ], [ -119.758141, 33.959212 ], [ -119.77017, 33.96226 ], [ -119.789723, 33.959259 ], [ -119.793443, 33.962811 ], [ -119.799124, 33.962649 ], [ -119.803901, 33.963993 ], [ -119.818249, 33.959858 ], [ -119.819825, 33.963402 ], [ -119.831153, 33.968635 ], [ -119.842355, 33.970209 ], [ -119.848287, 33.967636 ], [ -119.850989, 33.969009 ], [ -119.86554, 33.979266 ], [ -119.873358, 33.980375 ], [ -119.877057, 33.985757 ], [ -119.881403, 33.992339 ], [ -119.884141, 34.001601 ], [ -119.887, 34.008584 ], [ -119.882531, 34.011674 ], [ -119.876916, 34.023527 ], [ -119.876329, 34.032087 ], [ -119.881808, 34.036553 ], [ -119.886199, 34.037049 ], [ -119.887284, 34.042197 ], [ -119.892821, 34.045529 ], [ -119.916216, 34.058351 ], [ -119.922102, 34.056872 ], [ -119.926544, 34.057399 ], [ -119.929889, 34.059734 ] ] ], [ [ [ -120.249536, 34.002477 ], [ -120.245466, 34.002484 ], [ -120.238657, 34.007592 ], [ -120.237297, 34.009284 ], [ -120.233675, 34.008659 ], [ -120.230001, 34.010136 ], [ -120.221287, 34.010367 ], [ -120.208478, 34.005655 ], [ -120.19578, 34.004284 ], [ -120.191642, 34.004856 ], [ -120.189281, 34.006625 ], [ -120.183697, 34.007737 ], [ -120.180264, 34.006428 ], [ -120.176847, 34.006317 ], [ -120.167306, 34.008219 ], [ -120.160665, 34.011637 ], [ -120.151663, 34.018126 ], [ -120.147647, 34.024831 ], [ -120.140362, 34.025974 ], [ -120.135853, 34.026087 ], [ -120.123385, 34.022357 ], [ -120.120043, 34.023245 ], [ -120.115058, 34.019866 ], [ -120.090182, 34.019806 ], [ -120.073609, 34.024477 ], [ -120.070545, 34.029098 ], [ -120.066275, 34.029003 ], [ -120.062778, 34.031161 ], [ -120.061953, 34.033976 ], [ -120.057637, 34.03734 ], [ -120.055107, 34.037729 ], [ -120.043259, 34.035806 ], [ -120.045272, 34.031692 ], [ -120.043212, 34.027536 ], [ -120.044004, 34.02482 ], [ -120.047798, 34.021227 ], [ -120.050382, 34.013331 ], [ -120.048926, 34.009898 ], [ -120.047108, 34.006329 ], [ -120.046575, 34.000002 ], [ -120.041311, 33.994507 ], [ -120.033254, 33.9899 ], [ -120.027336, 33.988505 ], [ -120.025781, 33.986137 ], [ -120.014032, 33.983413 ], [ -120.012906, 33.980952 ], [ -120.003815, 33.979547 ], [ -119.984316, 33.983948 ], [ -119.980156, 33.983653 ], [ -119.97902, 33.981207 ], [ -119.979913, 33.969623 ], [ -119.976857, 33.956693 ], [ -119.971141, 33.950401 ], [ -119.971869, 33.945875 ], [ -119.968636, 33.942878 ], [ -119.973691, 33.942481 ], [ -120.00096, 33.941554 ], [ -120.017715, 33.936366 ], [ -120.020926, 33.934991 ], [ -120.021686, 33.932624 ], [ -120.028664, 33.927853 ], [ -120.03918, 33.924578 ], [ -120.041674, 33.921045 ], [ -120.046881, 33.919597 ], [ -120.048315, 33.917625 ], [ -120.048611, 33.915775 ], [ -120.049682, 33.914563 ], [ -120.05679, 33.913127 ], [ -120.067898, 33.912521 ], [ -120.073406, 33.912113 ], [ -120.077793, 33.908886 ], [ -120.090779, 33.909234 ], [ -120.098601, 33.907853 ], [ -120.105489, 33.90428 ], [ -120.109137, 33.899129 ], [ -120.110168, 33.895621 ], [ -120.115885, 33.894361 ], [ -120.121817, 33.895712 ], [ -120.159838, 33.915914 ], [ -120.165248, 33.916327 ], [ -120.168974, 33.91909 ], [ -120.172666, 33.922849 ], [ -120.180417, 33.925103 ], [ -120.179049, 33.927994 ], [ -120.18984, 33.947703 ], [ -120.192339, 33.950266 ], [ -120.198602, 33.952211 ], [ -120.200085, 33.956904 ], [ -120.209372, 33.972376 ], [ -120.21434, 33.976596 ], [ -120.219279, 33.979028 ], [ -120.222106, 33.987559 ], [ -120.230244, 33.991238 ], [ -120.239409, 33.993077 ], [ -120.239262, 33.996497 ], [ -120.243972, 33.999383 ], [ -120.246241, 33.997868 ], [ -120.248484, 33.999329 ], [ -120.249536, 34.002477 ] ] ], [ [ [ -120.450064, 34.034194 ], [ -120.449114, 34.037345 ], [ -120.445548, 34.037345 ], [ -120.440248, 34.036918 ], [ -120.428997, 34.047556 ], [ -120.418768, 34.052093 ], [ -120.415287, 34.05496 ], [ -120.411314, 34.052869 ], [ -120.403613, 34.050442 ], [ -120.396188, 34.050187 ], [ -120.390906, 34.051994 ], [ -120.374211, 34.062658 ], [ -120.368813, 34.06778 ], [ -120.367114, 34.070822 ], [ -120.370176, 34.074907 ], [ -120.368278, 34.076465 ], [ -120.362251, 34.073056 ], [ -120.354982, 34.059256 ], [ -120.36029, 34.05582 ], [ -120.360459, 34.053101 ], [ -120.358608, 34.050235 ], [ -120.352853, 34.047193 ], [ -120.346946, 34.046576 ], [ -120.331161, 34.049097 ], [ -120.319032, 34.041979 ], [ -120.313175, 34.036576 ], [ -120.307361, 34.029566 ], [ -120.307219, 34.022375 ], [ -120.311184, 34.019932 ], [ -120.317052, 34.018837 ], [ -120.335027, 34.020799 ], [ -120.340834, 34.019598 ], [ -120.347706, 34.020114 ], [ -120.353804, 34.019026 ], [ -120.35793, 34.015029 ], [ -120.36665, 34.015842 ], [ -120.375143, 34.018775 ], [ -120.383138, 34.024474 ], [ -120.39163, 34.025988 ], [ -120.409368, 34.032198 ], [ -120.415225, 34.032245 ], [ -120.419021, 34.028949 ], [ -120.427408, 34.025425 ], [ -120.435579, 34.029371 ], [ -120.443168, 34.028843 ], [ -120.454134, 34.028081 ], [ -120.450064, 34.034194 ] ] ], [ [ [ -121.346362833935004, 35.795182644152597 ], [ -121.243778, 35.794525 ], [ -121.185056, 35.794161 ], [ -121.175695, 35.794102 ], [ -121.125937, 35.793941 ], [ -121.114454, 35.79331 ], [ -121.00155, 35.792669 ], [ -121.001022, 35.792904 ], [ -120.959274, 35.792559 ], [ -120.875682, 35.791895 ], [ -120.864288, 35.791738 ], [ -120.85444, 35.791868 ], [ -120.751007, 35.79132 ], [ -120.731376, 35.791117 ], [ -120.721938, 35.791113 ], [ -120.691613, 35.79089 ], [ -120.658273, 35.790861 ], [ -120.617235, 35.790843 ], [ -120.585265, 35.790853 ], [ -120.583789, 35.790748 ], [ -120.583642, 35.790725 ], [ -120.580101, 35.790819 ], [ -120.515083, 35.790269 ], [ -120.425644, 35.789961 ], [ -120.404531, 35.789968 ], [ -120.250979, 35.788977 ], [ -120.244551, 35.789458 ], [ -120.213979, 35.789276 ], [ -120.194146, 35.789204 ], [ -120.193892, 35.726513 ], [ -120.193918, 35.614359 ], [ -120.125977, 35.614177 ], [ -120.124741, 35.614314 ], [ -120.085922, 35.614524 ], [ -120.086674, 35.526554 ], [ -120.068657, 35.52632 ], [ -120.068905, 35.512779 ], [ -120.051237, 35.512695 ], [ -120.050732, 35.499967 ], [ -120.05105, 35.498627 ], [ -120.033241, 35.498642 ], [ -120.033314, 35.483648 ], [ -120.030515, 35.483787 ], [ -120.014602, 35.483652 ], [ -120.015659, 35.469039 ], [ -120.000973, 35.469037 ], [ -119.997382, 35.468702 ], [ -119.997392, 35.439495 ], [ -119.944178, 35.439324 ], [ -119.913659, 35.439262 ], [ -119.880045, 35.439133 ], [ -119.879895, 35.363482 ], [ -119.880172, 35.351211 ], [ -119.809346, 35.350865 ], [ -119.809403, 35.29964 ], [ -119.809449, 35.263584 ], [ -119.666663, 35.262527 ], [ -119.666657, 35.261587 ], [ -119.667056, 35.174809 ], [ -119.576817, 35.179977 ], [ -119.571259, 35.180292 ], [ -119.553641, 35.179975 ], [ -119.554218, 35.173481 ], [ -119.560975, 35.087673 ], [ -119.498768, 35.091283 ], [ -119.490632, 35.091805 ], [ -119.49073, 35.077361 ], [ -119.472719, 35.076885 ], [ -119.472567, 34.975087 ], [ -119.472661, 34.937907 ], [ -119.472754, 34.901174 ], [ -119.442352, 34.901274 ], [ -119.433434, 34.901119 ], [ -119.401909, 34.901186 ], [ -119.397524, 34.900915 ], [ -119.382154, 34.900936 ], [ -119.382451, 34.879675 ], [ -119.276946, 34.879675 ], [ -119.277501, 34.872229 ], [ -119.278346, 34.857276 ], [ -119.243645, 34.857576 ], [ -119.243645, 34.814178 ], [ -119.17193, 34.813525 ], [ -119.155084, 34.81338 ], [ -119.144703, 34.813315 ], [ -119.138866, 34.813311 ], [ -119.129739, 34.813366 ], [ -119.12594, 34.813178 ], [ -119.023688, 34.812344 ], [ -119.000935, 34.812083 ], [ -119.000048, 34.812213 ], [ -118.976721, 34.812199 ], [ -118.976723, 34.79066 ], [ -118.964484, 34.79066 ], [ -118.881364, 34.790629 ], [ -118.821077, 34.665791 ], [ -118.796842, 34.616567 ], [ -118.738618, 34.498969 ], [ -118.741539, 34.49731 ], [ -118.751023, 34.490944 ], [ -118.76006, 34.485427 ], [ -118.765896, 34.482259 ], [ -118.766736, 34.480587 ], [ -118.767457, 34.477982 ], [ -118.771007, 34.4677 ], [ -118.830841, 34.467946 ], [ -118.873175, 34.467974 ], [ -118.876251, 34.468444 ], [ -118.877408, 34.468219 ], [ -118.885373, 34.4682 ], [ -118.890799, 34.467976 ], [ -118.917044, 34.468134 ], [ -118.917938, 34.467396 ], [ -118.921532, 34.468129 ], [ -118.937361, 34.468219 ], [ -118.93759, 34.444229 ], [ -118.955293, 34.444219 ], [ -118.955458, 34.42247 ], [ -118.990735, 34.422505 ], [ -119.001075, 34.422531 ], [ -119.012523, 34.422268 ], [ -119.016118, 34.422655 ], [ -119.018783, 34.42225 ], [ -119.023444, 34.42217 ], [ -119.024659, 34.422275 ], [ -119.059604, 34.422314 ], [ -119.059728, 34.429524 ], [ -119.077229, 34.429638 ], [ -119.07713, 34.436732 ], [ -119.080905, 34.436768 ], [ -119.080887, 34.439667 ], [ -119.080948, 34.440176 ], [ -119.07995, 34.500734 ], [ -119.07905, 34.561728 ], [ -119.133839, 34.561386 ], [ -119.13467, 34.561691 ], [ -119.154573, 34.561369 ], [ -119.356901, 34.560942 ], [ -119.372422, 34.556229 ], [ -119.377874, 34.555521 ], [ -119.380484, 34.561253 ], [ -119.442353, 34.561101 ], [ -119.442354, 34.49095 ], [ -119.442278, 34.465509 ], [ -119.442269, 34.463949 ], [ -119.324093, 34.463778 ], [ -119.324372, 34.446653 ], [ -119.334085, 34.441173 ], [ -119.344527, 34.438758 ], [ -119.350355, 34.432294 ], [ -119.357077, 34.428134 ], [ -119.35796, 34.422988 ], [ -119.370235, 34.417233 ], [ -119.377469, 34.391773 ], [ -119.41311, 34.392109 ], [ -119.416747, 34.392834 ], [ -119.42087, 34.392139 ], [ -119.420357, 34.390652 ], [ -119.416067, 34.390788 ], [ -119.415334, 34.38927 ], [ -119.413645, 34.388685 ], [ -119.414948, 34.385656 ], [ -119.411093, 34.385228 ], [ -119.408163, 34.382505 ], [ -119.406154, 34.379775 ], [ -119.405912, 34.377052 ], [ -119.401889, 34.376444 ], [ -119.390105, 34.375614 ], [ -119.388609, 34.374811 ], [ -119.391247, 34.374504 ], [ -119.391461, 34.372922 ], [ -119.388238, 34.372518 ], [ -119.385617, 34.371052 ], [ -119.385886, 34.369472 ], [ -119.388775, 34.367714 ], [ -119.388428, 34.366326 ], [ -119.389205, 34.36439 ], [ -119.390879, 34.364948 ], [ -119.39006, 34.362755 ], [ -119.386906, 34.362396 ], [ -119.385685, 34.364266 ], [ -119.381651, 34.365169 ], [ -119.379551, 34.367059 ], [ -119.377558, 34.364993 ], [ -119.376888, 34.363267 ], [ -119.372217, 34.360821 ], [ -119.36882, 34.357361 ], [ -119.3657, 34.357218 ], [ -119.361806, 34.35806 ], [ -119.357527, 34.356076 ], [ -119.353851, 34.35599 ], [ -119.352104, 34.356425 ], [ -119.349867, 34.355674 ], [ -119.343645, 34.351735 ], [ -119.342742, 34.350452 ], [ -119.337137, 34.34852 ], [ -119.331353, 34.349004 ], [ -119.329691, 34.347874 ], [ -119.325372, 34.348231 ], [ -119.31843, 34.347231 ], [ -119.318438, 34.346051 ], [ -119.310976, 34.34638 ], [ -119.309939, 34.350173 ], [ -119.30736, 34.350106 ], [ -119.306092, 34.351518 ], [ -119.302352, 34.349813 ], [ -119.29953, 34.345923 ], [ -119.299199, 34.344253 ], [ -119.297427, 34.344438 ], [ -119.29669, 34.342078 ], [ -119.295508, 34.333996 ], [ -119.296428, 34.331728 ], [ -119.296192, 34.330189 ], [ -119.294741, 34.329918 ], [ -119.294016, 34.325699 ], [ -119.29252, 34.32414 ], [ -119.292521, 34.324218 ], [ -119.291522, 34.32283 ], [ -119.290833, 34.319429 ], [ -119.291234, 34.316919 ], [ -119.290661, 34.316828 ], [ -119.286638, 34.316591 ], [ -119.28684, 34.315493 ], [ -119.28992, 34.312625 ], [ -119.290045, 34.3125 ], [ -119.291252, 34.31182 ], [ -119.29155, 34.311825 ], [ -119.291478, 34.310166 ], [ -119.295308, 34.307798 ], [ -119.29425, 34.306947 ], [ -119.298468, 34.307779 ], [ -119.299639, 34.305247 ], [ -119.303444, 34.298458 ], [ -119.307153, 34.290248 ], [ -119.30714, 34.29017 ], [ -119.307952, 34.290161 ], [ -119.311073, 34.290127 ], [ -119.31088, 34.289094 ], [ -119.314917, 34.282866 ], [ -119.315917, 34.282376 ], [ -119.308476, 34.279894 ], [ -119.301083, 34.277682 ], [ -119.300309, 34.277576 ], [ -119.297691, 34.277571 ], [ -119.29771, 34.280805 ], [ -119.291549, 34.280822 ], [ -119.281447, 34.280772 ], [ -119.278572, 34.28014 ], [ -119.277916, 34.279937 ], [ -119.271168, 34.278286 ], [ -119.268987, 34.277757 ], [ -119.266966, 34.277267 ], [ -119.265281, 34.276493 ], [ -119.265623, 34.275301 ], [ -119.265132, 34.273338 ], [ -119.263943, 34.273102 ], [ -119.264539, 34.271029 ], [ -119.265571, 34.267443 ], [ -119.267884, 34.26814 ], [ -119.267633, 34.269453 ], [ -119.268333, 34.265902 ], [ -119.269402, 34.265008 ], [ -119.270215, 34.264869 ], [ -119.264414, 34.261967 ], [ -119.265498, 34.261432 ], [ -119.269468, 34.259988 ], [ -119.272573, 34.25876 ], [ -119.272932, 34.25938 ], [ -119.273694327306004, 34.258750180230102 ], [ -119.278644, 34.266902 ], [ -119.285555444285009, 34.271396882877895 ], [ -119.290945, 34.274902 ], [ -119.295256, 34.275268 ], [ -119.302131, 34.272761 ], [ -119.307616595515015, 34.274695921102406 ], [ -119.312323, 34.276356 ], [ -119.317041972546988, 34.280284765819204 ], [ -119.320164, 34.282884 ], [ -119.322476845102003, 34.283911693635396 ], [ -119.337475, 34.290576 ], [ -119.349187, 34.304383 ], [ -119.370356, 34.319486 ], [ -119.37578, 34.321118 ], [ -119.388249, 34.317398 ], [ -119.390449, 34.318198 ], [ -119.405522, 34.334221 ], [ -119.410695, 34.337355 ], [ -119.42777, 34.353016 ], [ -119.431066, 34.355297 ], [ -119.435888, 34.355839 ], [ -119.443418, 34.355994 ], [ -119.451304, 34.365501 ], [ -119.461036, 34.374064 ], [ -119.467751, 34.37572 ], [ -119.472678, 34.375628 ], [ -119.476527581473007, 34.3741061476466 ], [ -119.47863, 34.373275 ], [ -119.483395, 34.380046 ], [ -119.486135115899998, 34.380982952998401 ], [ -119.489661999433991, 34.382188932680897 ], [ -119.497339, 34.384814 ], [ -119.502476987131999, 34.384526726230106 ], [ -119.504046, 34.384439 ], [ -119.504217305718029, 34.384487107642897 ], [ -119.510649196935006, 34.386293370330101 ], [ -119.510655, 34.386295 ], [ -119.5188, 34.389282 ], [ -119.523563, 34.393188 ], [ -119.529207763298004, 34.395156709672399 ], [ -119.53123, 34.395862 ], [ -119.5369, 34.395919 ], [ -119.545682872539018, 34.403484460863602 ], [ -119.547635, 34.405166 ], [ -119.559459, 34.413395 ], [ -119.563986, 34.41532 ], [ -119.566714871318027, 34.414649793583095 ], [ -119.568473, 34.414218 ], [ -119.568915951238012, 34.4141223899952 ], [ -119.576247, 34.41254 ], [ -119.576648327162999, 34.412645825660299 ], [ -119.582091, 34.414081 ], [ -119.590177, 34.417998 ], [ -119.59343933720001, 34.418486671592099 ], [ -119.606513, 34.420445 ], [ -119.610575367185007, 34.4206608954442 ], [ -119.612171474095007, 34.420745720915299 ], [ -119.612350157561011, 34.4207552170895 ], [ -119.615123715416019, 34.420902618463501 ], [ -119.616862, 34.420995 ], [ -119.617603020748007, 34.420555501845506 ], [ -119.61881111659801, 34.419838982236101 ], [ -119.62089, 34.418606 ], [ -119.629568, 34.419661 ], [ -119.633998, 34.416868 ], [ -119.638864, 34.415696 ], [ -119.648664, 34.417396 ], [ -119.659059778237008, 34.416813528156702 ], [ -119.671866, 34.416096 ], [ -119.676261662365988, 34.415125508076002 ], [ -119.680857291711007, 34.414110866642098 ], [ -119.688167, 34.412497 ], [ -119.686356919966002, 34.410325524381001 ], [ -119.684666, 34.408297 ], [ -119.691749, 34.403154 ], [ -119.696531589507018, 34.402486240011299 ], [ -119.699921, 34.402013 ], [ -119.70162, 34.398733 ], [ -119.709067, 34.395397 ], [ -119.713848392433988, 34.395716416151402 ], [ -119.719261, 34.396078 ], [ -119.723176530792998, 34.395860996433697 ], [ -119.724638, 34.39578 ], [ -119.727738425205018, 34.395856675068501 ], [ -119.729369, 34.395897 ], [ -119.731300806844004, 34.396851149172399 ], [ -119.74112, 34.401701 ], [ -119.742988690032021, 34.402215211946604 ], [ -119.74547, 34.402898 ], [ -119.750414, 34.40375 ], [ -119.755760924726999, 34.405596850752403 ], [ -119.755912632053992, 34.405649251114397 ], [ -119.785871, 34.415997 ], [ -119.786254580806002, 34.416111236903298 ], [ -119.793567, 34.418289 ], [ -119.802363, 34.417988 ], [ -119.807055, 34.416497 ], [ -119.815195, 34.4167 ], [ -119.825178, 34.417112 ], [ -119.825305356295004, 34.417096178147403 ], [ -119.835771, 34.415796 ], [ -119.836273803250023, 34.415597774254699 ], [ -119.838604206637001, 34.414679033278603 ], [ -119.84039, 34.413975 ], [ -119.841868, 34.409275 ], [ -119.844485, 34.404301 ], [ -119.853771, 34.407996 ], [ -119.853776632285999, 34.407996222782003 ], [ -119.85390042150901, 34.408001119197301 ], [ -119.85877379913299, 34.408193882995398 ], [ -119.86259598460903, 34.408345067460495 ], [ -119.872887738702033, 34.408752152189201 ], [ -119.873971, 34.408795 ], [ -119.878199, 34.406913 ], [ -119.881164140283019, 34.409600707687197 ], [ -119.881624905035011, 34.4100183611029 ], [ -119.885300580199015, 34.413350122656205 ], [ -119.888942497732998, 34.4166512851031 ], [ -119.891785858845012, 34.419228607856795 ], [ -119.8922, 34.419604 ], [ -119.899166, 34.420821 ], [ -119.899598609699012, 34.421075914159402 ], [ -119.911966028735023, 34.4283633842089 ], [ -119.915497, 34.430444 ], [ -119.919357822298011, 34.431827626655199 ], [ -119.921942779933019, 34.432754013836494 ], [ -119.925227, 34.433931 ], [ -119.929546340946999, 34.434609852199998 ], [ -119.936489, 34.435701 ], [ -119.949696, 34.434476 ], [ -119.956433, 34.435288 ], [ -119.971951, 34.444641 ], [ -119.984899, 34.45083 ], [ -119.990033, 34.449837 ], [ -119.997686, 34.455394 ], [ -120.008077, 34.460447 ], [ -120.019453, 34.46117 ], [ -120.021444, 34.458584 ], [ -120.022540071939019, 34.458430839287601 ], [ -120.023641, 34.458277 ], [ -120.031989, 34.461695 ], [ -120.038828, 34.463434 ], [ -120.050682, 34.461651 ], [ -120.060036, 34.461429 ], [ -120.071061, 34.46255 ], [ -120.072592, 34.460817 ], [ -120.088591, 34.460208 ], [ -120.097212, 34.461809 ], [ -120.118411, 34.469927 ], [ -120.133296, 34.47294 ], [ -120.141165, 34.473405 ], [ -120.151562, 34.473275 ], [ -120.163142, 34.471831 ], [ -120.168774, 34.469732 ], [ -120.174878, 34.470693 ], [ -120.183505, 34.470372 ], [ -120.225498, 34.470587 ], [ -120.226812521325016, 34.4704539561465 ], [ -120.234252, 34.469701 ], [ -120.238002, 34.468098 ], [ -120.25777, 34.467451 ], [ -120.283001, 34.468354 ], [ -120.295051, 34.470623 ], [ -120.299169, 34.469731 ], [ -120.301822, 34.467077 ], [ -120.322198, 34.463372 ], [ -120.335001, 34.462589 ], [ -120.337091, 34.459686 ], [ -120.341369, 34.458789 ], [ -120.350545674905007, 34.458147723724593 ], [ -120.354601666691025, 34.457864286495699 ], [ -120.36551, 34.457102 ], [ -120.406781, 34.455338 ], [ -120.417223147133015, 34.452985708262695 ], [ -120.417284, 34.452972 ], [ -120.421541, 34.450401 ], [ -120.426105, 34.449924 ], [ -120.441975, 34.451512 ], [ -120.451425, 34.447094 ], [ -120.452811, 34.442442 ], [ -120.459245, 34.445342 ], [ -120.463264, 34.448676 ], [ -120.471376, 34.447846 ], [ -120.474373, 34.467403 ], [ -120.47661, 34.475131 ], [ -120.480372, 34.481059 ], [ -120.486296, 34.485392 ], [ -120.490523, 34.490075 ], [ -120.493488, 34.494741 ], [ -120.496573, 34.495403 ], [ -120.500795, 34.50774 ], [ -120.503747488152996, 34.511967009435899 ], [ -120.511421, 34.522953 ], [ -120.524776, 34.531291 ], [ -120.542115, 34.53974 ], [ -120.554027, 34.541826 ], [ -120.56552, 34.548919 ], [ -120.581293, 34.556959 ], [ -120.608355, 34.556656 ], [ -120.612005, 34.553564 ], [ -120.622575, 34.554017 ], [ -120.631943, 34.560476 ], [ -120.636722, 34.560967 ], [ -120.63953, 34.563534 ], [ -120.639069, 34.568017 ], [ -120.6407, 34.572693 ], [ -120.644796, 34.577024 ], [ -120.64924, 34.576707 ], [ -120.649086, 34.57863 ], [ -120.645739, 34.581035 ], [ -120.645281, 34.588205 ], [ -120.641805, 34.590116 ], [ -120.640238, 34.599708 ], [ -120.642975, 34.601234 ], [ -120.642547, 34.604363 ], [ -120.639915, 34.605895 ], [ -120.625127, 34.634489 ], [ -120.602391, 34.693899 ], [ -120.60045, 34.70464 ], [ -120.601672, 34.709721 ], [ -120.607376, 34.71425 ], [ -120.609759, 34.721058 ], [ -120.612849, 34.723793 ], [ -120.613337543976016, 34.725479854787203 ], [ -120.614207740724012, 34.728484488192301 ], [ -120.614852, 34.730709 ], [ -120.619656, 34.735424 ], [ -120.62632, 34.738072 ], [ -120.629476, 34.745583 ], [ -120.631832, 34.75342 ], [ -120.637415, 34.755895 ], [ -120.634953, 34.766954 ], [ -120.629640445831029, 34.777463964847598 ], [ -120.627294, 34.782106 ], [ -120.62297, 34.7933 ], [ -120.616296, 34.816308 ], [ -120.609898, 34.842751 ], [ -120.610266, 34.85818 ], [ -120.616325, 34.866739 ], [ -120.625873050396009, 34.872425908315897 ], [ -120.627743084354023, 34.873539718069999 ], [ -120.639283, 34.880413 ], [ -120.639889665040016, 34.889531070794099 ], [ -120.63992, 34.889987 ], [ -120.640883135999005, 34.891734259810001 ], [ -120.642212, 34.894145 ], [ -120.647328, 34.901133 ], [ -120.652858, 34.900326 ], [ -120.657836, 34.901476 ], [ -120.662889, 34.901183 ], [ -120.669103, 34.901566 ], [ -120.672269, 34.90254 ], [ -120.670835, 34.904115 ], [ -120.669104110860999, 34.908493208253802 ], [ -120.66898, 34.908807141238597 ], [ -120.664215, 34.92086 ], [ -120.664039073384018, 34.928047996221402 ], [ -120.664032, 34.928337 ], [ -120.666721, 34.929789 ], [ -120.663803087623009, 34.933876788513004 ], [ -120.663394855265011, 34.934448693123002 ], [ -120.662416, 34.93582 ], [ -120.659577, 34.944549 ], [ -120.650215, 34.972061 ], [ -120.649338482465012, 34.974710011723403 ], [ -120.63999, 35.002963 ], [ -120.63357, 35.033085 ], [ -120.629931, 35.061515 ], [ -120.629583, 35.078362 ], [ -120.630911496689023, 35.101160124775603 ], [ -120.630957, 35.101941 ], [ -120.631696976084001, 35.105290655712395 ], [ -120.634412124495, 35.117581339951002 ], [ -120.635298351131993, 35.121593029224201 ], [ -120.635461344532004, 35.122330852765295 ], [ -120.635787, 35.123805 ], [ -120.636154147189998, 35.124486014103198 ], [ -120.63691066394901, 35.125889262165899 ], [ -120.636989762615016, 35.126035980725504 ], [ -120.637692402824001, 35.1273392942336 ], [ -120.638576757234006, 35.128979665840404 ], [ -120.644311, 35.139616 ], [ -120.651134, 35.147768 ], [ -120.65490413399003, 35.149625973623998 ], [ -120.662475, 35.153357 ], [ -120.667994, 35.15203 ], [ -120.675074, 35.153061 ], [ -120.675538417927015, 35.153530087249003 ], [ -120.680246, 35.158285 ], [ -120.682787, 35.158018 ], [ -120.684524991586017, 35.1591345983677 ], [ -120.686974, 35.160708 ], [ -120.692299346148019, 35.165387092274095 ], [ -120.698906, 35.171192 ], [ -120.704203, 35.173206 ], [ -120.708210752691002, 35.174326982319599 ], [ -120.711429655320998, 35.175227320542596 ], [ -120.711521132590008, 35.175252907051799 ], [ -120.714185, 35.175998 ], [ -120.716810130699002, 35.174612252050096 ], [ -120.717521, 35.174237 ], [ -120.726019, 35.175405 ], [ -120.734231, 35.178472 ], [ -120.737924523512007, 35.178301188098999 ], [ -120.74887, 35.177795 ], [ -120.754823, 35.174701 ], [ -120.756862, 35.169208 ], [ -120.756086, 35.160459 ], [ -120.760492, 35.15971 ], [ -120.770192, 35.163731 ], [ -120.778998, 35.168897 ], [ -120.786076, 35.177666 ], [ -120.790158, 35.179842 ], [ -120.794407, 35.179001 ], [ -120.798147, 35.182024 ], [ -120.805258, 35.184973 ], [ -120.837267, 35.1986 ], [ -120.846674, 35.204429 ], [ -120.856047, 35.206487 ], [ -120.863831, 35.217807 ], [ -120.869409, 35.219026 ], [ -120.873522, 35.222885 ], [ -120.873046, 35.225688 ], [ -120.878575, 35.231694 ], [ -120.886418, 35.236354 ], [ -120.888801, 35.239453 ], [ -120.89679, 35.247877 ], [ -120.896876, 35.25399 ], [ -120.8996, 35.255337 ], [ -120.897247, 35.258902 ], [ -120.895596, 35.258811 ], [ -120.895478097488009, 35.259255101664394 ], [ -120.893813, 35.265527 ], [ -120.895847, 35.27077 ], [ -120.89405, 35.27406 ], [ -120.890666, 35.273662 ], [ -120.889354, 35.277819 ], [ -120.887607, 35.283126 ], [ -120.87957, 35.294184 ], [ -120.874980550932008, 35.306416347272901 ], [ -120.8672, 35.327154 ], [ -120.863582329044007, 35.342872764281701 ], [ -120.862684, 35.346776 ], [ -120.862404692028022, 35.353866164443794 ], [ -120.862133, 35.360763 ], [ -120.86593, 35.360529 ], [ -120.867191, 35.36127 ], [ -120.870137, 35.362383 ], [ -120.869816593230013, 35.367786632078001 ], [ -120.869567, 35.371996 ], [ -120.866338, 35.370852 ], [ -120.864857, 35.371979 ], [ -120.864176944234003, 35.376351433017398 ], [ -120.864105, 35.376814 ], [ -120.866099, 35.393045 ], [ -120.866159638165001, 35.393244482014396 ], [ -120.86809286417801, 35.399604236143695 ], [ -120.869209, 35.403276 ], [ -120.871325683946992, 35.406940852833401 ], [ -120.871383464982017, 35.407040895633692 ], [ -120.872432277231994, 35.4088568221689 ], [ -120.873581143786993, 35.410845983967398 ], [ -120.874464828754014, 35.412376007077704 ], [ -120.874596423742005, 35.4126038522719 ], [ -120.884757, 35.430196 ], [ -120.888474394094018, 35.433895582540799 ], [ -120.896862, 35.442243 ], [ -120.900070801795025, 35.444220722894201 ], [ -120.907937, 35.449069 ], [ -120.911108, 35.448002 ], [ -120.914448, 35.449336 ], [ -120.919528, 35.447367 ], [ -120.927729411274001, 35.446998429277798 ], [ -120.939666, 35.446462 ], [ -120.946546, 35.446715 ], [ -120.950742, 35.44802 ], [ -120.955863, 35.453743 ], [ -120.969436, 35.460197 ], [ -120.976122, 35.459028 ], [ -120.984227917908001, 35.4602903150518 ], [ -120.985035, 35.460416 ], [ -120.993761, 35.463622 ], [ -120.997924, 35.460374 ], [ -121.003359, 35.46071 ], [ -121.008523, 35.465416 ], [ -121.021242, 35.478559 ], [ -121.025621, 35.484598 ], [ -121.028907, 35.4851 ], [ -121.032402, 35.489007 ], [ -121.036238, 35.489393 ], [ -121.039219, 35.494108 ], [ -121.046129, 35.500069 ], [ -121.047056, 35.502200854111393 ], [ -121.04726, 35.50267 ], [ -121.050213200521, 35.505136074662204 ], [ -121.052354674964008, 35.506924316207197 ], [ -121.05308, 35.50753 ], [ -121.056503, 35.508026 ], [ -121.056940399683981, 35.508237003659701 ], [ -121.059913, 35.509671 ], [ -121.075447107520006, 35.524258869359798 ], [ -121.082613360390994, 35.530988600086204 ], [ -121.085775784580989, 35.533958389685004 ], [ -121.086705382185016, 35.534831362167594 ], [ -121.09116458482103, 35.539018938790399 ], [ -121.092640205063006, 35.540404673714399 ], [ -121.093529553364007, 35.541239848623498 ], [ -121.097685887894002, 35.545143005922007 ], [ -121.098314529739014, 35.545733354939799 ], [ -121.098574002301007, 35.545977022097809 ], [ -121.101221691589018, 35.548463431142103 ], [ -121.101595, 35.548814 ], [ -121.103115232631012, 35.551330923608703 ], [ -121.103946206704023, 35.5527066987515 ], [ -121.105547, 35.555357 ], [ -121.103256, 35.556587 ], [ -121.107421, 35.561217 ], [ -121.111795212925003, 35.568674625961499 ], [ -121.112205470761012, 35.569374077392098 ], [ -121.113331, 35.571293 ], [ -121.115608, 35.577072 ], [ -121.116350577710023, 35.577378699929298 ], [ -121.118465, 35.578252 ], [ -121.118917503888014, 35.578768773893607 ], [ -121.121066823234003, 35.581223365236099 ], [ -121.121408, 35.581613 ], [ -121.122744131754004, 35.584923679352698 ], [ -121.126027, 35.593058 ], [ -121.12770268548401, 35.594704307015498 ], [ -121.12786764474501, 35.594866374176696 ], [ -121.133556, 35.600455 ], [ -121.137746, 35.601763 ], [ -121.143561, 35.606046 ], [ -121.148128, 35.613195 ], [ -121.151494, 35.616106 ], [ -121.166712, 35.635399 ], [ -121.177345, 35.640676 ], [ -121.183434, 35.641232 ], [ -121.188897, 35.643138 ], [ -121.195291, 35.640734 ], [ -121.193399, 35.634885 ], [ -121.195465, 35.634649 ], [ -121.19969, 35.636956 ], [ -121.203072, 35.641857 ], [ -121.208707, 35.641878 ], [ -121.212956, 35.647757 ], [ -121.223857, 35.652161 ], [ -121.239873, 35.652117 ], [ -121.251034, 35.656641 ], [ -121.260808, 35.66445 ], [ -121.265058, 35.663275 ], [ -121.272322, 35.666711 ], [ -121.275744, 35.665983 ], [ -121.281547, 35.666935 ], [ -121.283864, 35.664254 ], [ -121.28653, 35.665524 ], [ -121.286708, 35.67702 ], [ -121.289794, 35.689428 ], [ -121.296473, 35.696824 ], [ -121.30447, 35.70281 ], [ -121.315417, 35.713382 ], [ -121.312931, 35.718014 ], [ -121.313248, 35.721614 ], [ -121.315384, 35.72411 ], [ -121.316974, 35.725625 ], [ -121.318429, 35.728664 ], [ -121.315857, 35.730898 ], [ -121.316405, 35.73877 ], [ -121.318039, 35.744615 ], [ -121.315786, 35.75252 ], [ -121.320077, 35.756654 ], [ -121.326319, 35.757531 ], [ -121.328463, 35.759878 ], [ -121.324793, 35.762235 ], [ -121.324918, 35.769347 ], [ -121.331026, 35.778879 ], [ -121.332449, 35.783106 ], [ -121.346362833935004, 35.795182644152597 ] ] ] ] } } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /test/data/CD_CA_24_scores.json: -------------------------------------------------------------------------------- 1 | { 2 | "polsbypopper": 0.1896, 3 | "convexhull": 0.5173, 4 | "reock": 0.1991, 5 | "schwartzberg": 0.4354 6 | } 7 | -------------------------------------------------------------------------------- /test/data/CD_CA_9.geojson: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FeatureCollection", 3 | "name": "CD_CA_9", 4 | "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, 5 | "features": [ 6 | { "type": "Feature", "properties": { "STATEFP": "06", "CD115FP": "09", "AFFGEOID": "5001500US0609", "GEOID": "0609", "LSAD": "C2", "CDSESSN": "115", "ALAND": 3245118661, "AWATER": 134846563 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -121.851325, 37.986549 ], [ -121.845054, 37.985126 ], [ -121.843714, 37.984381 ], [ -121.841796, 37.983379 ], [ -121.841091, 37.983264 ], [ -121.831086, 37.983137 ], [ -121.829234, 37.983109 ], [ -121.825821, 37.980163 ], [ -121.823772, 37.980043 ], [ -121.823521, 37.981397 ], [ -121.825595, 37.982439 ], [ -121.824139, 37.985041 ], [ -121.822846, 37.989687 ], [ -121.822422, 37.991265 ], [ -121.822402, 37.992718 ], [ -121.821147, 37.992961 ], [ -121.817742, 37.994067 ], [ -121.810074, 37.993681 ], [ -121.810024, 37.995335 ], [ -121.808019, 37.995334 ], [ -121.807837, 37.995474 ], [ -121.807952, 37.997326 ], [ -121.808251, 37.997538 ], [ -121.810048, 37.997536 ], [ -121.810124, 37.998265 ], [ -121.805984, 37.998255 ], [ -121.805999, 38.001647 ], [ -121.806003, 38.004881 ], [ -121.810022, 38.00491 ], [ -121.810024, 38.011185 ], [ -121.808792, 38.011177 ], [ -121.808788, 38.009686 ], [ -121.806013, 38.009671 ], [ -121.806009, 38.010886 ], [ -121.804999, 38.012224 ], [ -121.796946, 38.012271 ], [ -121.798776, 38.013763 ], [ -121.799088, 38.014687 ], [ -121.80096, 38.015638 ], [ -121.80125, 38.021125 ], [ -121.80127, 38.021622 ], [ -121.798018, 38.020863 ], [ -121.794862, 38.019462 ], [ -121.788773, 38.018421 ], [ -121.78139, 38.018612 ], [ -121.777485, 38.018917 ], [ -121.770619, 38.021112 ], [ -121.765127, 38.023195 ], [ -121.758251, 38.024129 ], [ -121.75168, 38.024308 ], [ -121.750715, 38.024234 ], [ -121.749084, 38.024348 ], [ -121.744481, 38.025087 ], [ -121.737824, 38.02663 ], [ -121.732565, 38.02902 ], [ -121.725565, 38.03382 ], [ -121.716865, 38.03772 ], [ -121.71246, 38.038891 ], [ -121.709561, 38.039944 ], [ -121.704343, 38.042484 ], [ -121.699765, 38.04522 ], [ -121.691665, 38.05352 ], [ -121.684399, 38.058521 ], [ -121.68147, 38.061244 ], [ -121.679765, 38.065119 ], [ -121.679623, 38.069469 ], [ -121.680249, 38.076648 ], [ -121.681865, 38.082019 ], [ -121.679265, 38.089319 ], [ -121.673065, 38.093518 ], [ -121.662465, 38.095618 ], [ -121.661865, 38.095618 ], [ -121.652064, 38.091619 ], [ -121.648754, 38.090037 ], [ -121.646984, 38.088328 ], [ -121.645183, 38.087413 ], [ -121.640514, 38.086391 ], [ -121.638088, 38.086131 ], [ -121.634243, 38.087222 ], [ -121.632595, 38.088611 ], [ -121.628994, 38.097261 ], [ -121.627376, 38.09836 ], [ -121.613653, 38.09965 ], [ -121.604923, 38.099878 ], [ -121.585283, 38.096366 ], [ -121.58225, 38.09489 ], [ -121.581284, 38.093937 ], [ -121.580022, 38.094414 ], [ -121.574063, 38.09636 ], [ -121.567184, 38.097321 ], [ -121.564607, 38.099252 ], [ -121.564035, 38.101422 ], [ -121.564321, 38.102869 ], [ -121.565751, 38.105279 ], [ -121.567184, 38.106243 ], [ -121.573197, 38.108896 ], [ -121.580783, 38.111009 ], [ -121.583502, 38.113475 ], [ -121.58436, 38.118299 ], [ -121.584074, 38.120228 ], [ -121.580878, 38.124918 ], [ -121.579416, 38.125694 ], [ -121.576968, 38.12851 ], [ -121.575534, 38.129531 ], [ -121.571889, 38.131512 ], [ -121.566808, 38.134111 ], [ -121.56244, 38.135983 ], [ -121.557688, 38.136751 ], [ -121.557288, 38.139118 ], [ -121.55916, 38.140638 ], [ -121.560136, 38.142126 ], [ -121.559176, 38.143886 ], [ -121.553384, 38.145406 ], [ -121.551736, 38.145358 ], [ -121.549896, 38.146062 ], [ -121.548472, 38.147534 ], [ -121.54692, 38.14811 ], [ -121.544423, 38.147262 ], [ -121.543399, 38.147566 ], [ -121.542663, 38.150829 ], [ -121.540583, 38.151982 ], [ -121.537622, 38.151214 ], [ -121.53631, 38.151581 ], [ -121.534535, 38.155757 ], [ -121.536198, 38.157277 ], [ -121.536151, 38.158158 ], [ -121.533974, 38.159677 ], [ -121.533462, 38.162669 ], [ -121.531398, 38.1631 ], [ -121.529302, 38.169021 ], [ -121.52511, 38.171277 ], [ -121.524359, 38.172316 ], [ -121.524614, 38.174844 ], [ -121.526119, 38.177116 ], [ -121.526071, 38.178908 ], [ -121.527815, 38.18102 ], [ -121.527111, 38.18286 ], [ -121.524999, 38.183868 ], [ -121.524455, 38.185516 ], [ -121.525543, 38.186764 ], [ -121.526736, 38.18994 ], [ -121.528176, 38.191636 ], [ -121.529152, 38.193828 ], [ -121.528896, 38.195332 ], [ -121.527184, 38.19674 ], [ -121.5256, 38.197284 ], [ -121.524496, 38.199396 ], [ -121.522128, 38.201908 ], [ -121.519871, 38.203156 ], [ -121.512735, 38.202564 ], [ -121.509935, 38.20458 ], [ -121.508303, 38.207108 ], [ -121.508079, 38.209235 ], [ -121.504335, 38.212131 ], [ -121.505231, 38.215795 ], [ -121.506255, 38.217539 ], [ -121.507487, 38.222563 ], [ -121.507008, 38.223519 ], [ -121.50639, 38.224587 ], [ -121.504336, 38.224543 ], [ -121.501008, 38.226847 ], [ -121.497662, 38.227678 ], [ -121.495865, 38.227106 ], [ -121.491669, 38.22769 ], [ -121.490566, 38.230166 ], [ -121.490757, 38.232186 ], [ -121.489813, 38.233658 ], [ -121.487701, 38.234682 ], [ -121.486773, 38.235818 ], [ -121.486629, 38.237306 ], [ -121.487381, 38.238696 ], [ -121.486613, 38.240458 ], [ -121.484317, 38.241509 ], [ -121.483237, 38.242154 ], [ -121.481589, 38.244425 ], [ -121.478741, 38.245993 ], [ -121.478213, 38.248537 ], [ -121.478514, 38.251077 ], [ -121.479677, 38.252139 ], [ -121.48007, 38.253576 ], [ -121.476582, 38.256344 ], [ -121.476462, 38.257451 ], [ -121.472625, 38.259429 ], [ -121.470958, 38.259902 ], [ -121.468838, 38.259406 ], [ -121.466081, 38.259929 ], [ -121.4614, 38.259157 ], [ -121.458677, 38.257356 ], [ -121.456, 38.257564 ], [ -121.450426, 38.254617 ], [ -121.448142, 38.255008 ], [ -121.456349, 38.276386 ], [ -121.456633, 38.277329 ], [ -121.458101, 38.284257 ], [ -121.449688, 38.289687 ], [ -121.448819, 38.290072 ], [ -121.447598, 38.290265 ], [ -121.410668, 38.290496 ], [ -121.410046, 38.290499 ], [ -121.392245, 38.290695 ], [ -121.380521, 38.290792 ], [ -121.376075, 38.290807 ], [ -121.373251, 38.291088 ], [ -121.337434, 38.290944 ], [ -121.337361, 38.290944 ], [ -121.33739, 38.295654 ], [ -121.337635, 38.295653 ], [ -121.337538, 38.305492 ], [ -121.336699, 38.30571 ], [ -121.33593, 38.305627 ], [ -121.3347, 38.305785 ], [ -121.328173, 38.305459 ], [ -121.326018, 38.305351 ], [ -121.319404, 38.305351 ], [ -121.318756, 38.302126 ], [ -121.317674, 38.300956 ], [ -121.313199, 38.291047 ], [ -121.312377, 38.291054 ], [ -121.297784, 38.291159 ], [ -121.282806, 38.291309 ], [ -121.282455, 38.277137 ], [ -121.282626, 38.274837 ], [ -121.282626, 38.274791 ], [ -121.282603, 38.266562 ], [ -121.291491, 38.266614 ], [ -121.29156, 38.269831 ], [ -121.296137, 38.267288 ], [ -121.296178, 38.261611 ], [ -121.295003, 38.260352 ], [ -121.291969, 38.260228 ], [ -121.291844, 38.25501 ], [ -121.282421, 38.255146 ], [ -121.282267, 38.249836 ], [ -121.276844, 38.249256 ], [ -121.272822, 38.250782 ], [ -121.270043, 38.251919 ], [ -121.269228, 38.252089 ], [ -121.26838, 38.252271 ], [ -121.267232, 38.252298 ], [ -121.264653, 38.251263 ], [ -121.259036, 38.250267 ], [ -121.252692, 38.246948 ], [ -121.249425, 38.246522 ], [ -121.247584, 38.245426 ], [ -121.244772, 38.245188 ], [ -121.242372, 38.245413 ], [ -121.237498, 38.247479 ], [ -121.234419, 38.247419 ], [ -121.233637, 38.246902 ], [ -121.230652, 38.246734 ], [ -121.22925, 38.247525 ], [ -121.225555, 38.244859 ], [ -121.222512, 38.244406 ], [ -121.22075, 38.244877 ], [ -121.217516, 38.246632 ], [ -121.215018, 38.248799 ], [ -121.207889, 38.248817 ], [ -121.203407, 38.248754 ], [ -121.19807, 38.252474 ], [ -121.194137, 38.255749 ], [ -121.192023, 38.256698 ], [ -121.189774, 38.256066 ], [ -121.182026, 38.256828 ], [ -121.180219, 38.255321 ], [ -121.173079, 38.255208 ], [ -121.172009, 38.255594 ], [ -121.171282, 38.256923 ], [ -121.1691, 38.25809 ], [ -121.163844, 38.259786 ], [ -121.163642, 38.260219 ], [ -121.161535, 38.260796 ], [ -121.156994, 38.260793 ], [ -121.152965, 38.262483 ], [ -121.147014, 38.263905 ], [ -121.145945, 38.265365 ], [ -121.142894, 38.267565 ], [ -121.141552, 38.269197 ], [ -121.139338, 38.270154 ], [ -121.13767, 38.271578 ], [ -121.133825, 38.271875 ], [ -121.131213, 38.274678 ], [ -121.127782, 38.277447 ], [ -121.120129, 38.278162 ], [ -121.116829, 38.277349 ], [ -121.114502, 38.27881 ], [ -121.109513, 38.281064 ], [ -121.106425, 38.281508 ], [ -121.102104, 38.283231 ], [ -121.100196, 38.282646 ], [ -121.098941, 38.283105 ], [ -121.09544, 38.281633 ], [ -121.093113, 38.282569 ], [ -121.092659, 38.283844 ], [ -121.089899, 38.283962 ], [ -121.085378, 38.287053 ], [ -121.084232, 38.286361 ], [ -121.082026, 38.288246 ], [ -121.07929, 38.289771 ], [ -121.078219, 38.291676 ], [ -121.07638, 38.29197 ], [ -121.073903, 38.293264 ], [ -121.073284, 38.294361 ], [ -121.071039, 38.295329 ], [ -121.068477, 38.298515 ], [ -121.066653, 38.299146 ], [ -121.064783, 38.29947 ], [ -121.061672, 38.29894 ], [ -121.059916, 38.29708 ], [ -121.055494, 38.295068 ], [ -121.053391, 38.293193 ], [ -121.048338, 38.291142 ], [ -121.047494, 38.291142 ], [ -121.043626, 38.293743 ], [ -121.04057, 38.297718 ], [ -121.035443, 38.298127 ], [ -121.033045, 38.299228 ], [ -121.030514, 38.29891 ], [ -121.027084, 38.300252 ], [ -121.016369, 38.274402 ], [ -121.006399, 38.250605 ], [ -121.006357, 38.250507 ], [ -121.00346, 38.243012 ], [ -120.995497, 38.225402 ], [ -120.987602, 38.207456 ], [ -120.986446, 38.204647 ], [ -120.975303, 38.178123 ], [ -120.975206, 38.177886 ], [ -120.969175, 38.163023 ], [ -120.93885, 38.088321 ], [ -120.926449, 38.077421 ], [ -120.926545, 38.073107 ], [ -120.926524, 38.017226 ], [ -120.926448, 37.984024 ], [ -120.926348, 37.983324 ], [ -120.926448, 37.945224 ], [ -120.926381, 37.944826 ], [ -120.926447, 37.921725 ], [ -120.926547, 37.920725 ], [ -120.926447, 37.918925 ], [ -120.926347, 37.886724 ], [ -120.925485, 37.858414 ], [ -120.925356, 37.856855 ], [ -120.924723, 37.838906 ], [ -120.924141, 37.820599 ], [ -120.923854, 37.8132 ], [ -120.923422, 37.800296 ], [ -120.923251, 37.793571 ], [ -120.922643, 37.759568 ], [ -120.923371, 37.757808 ], [ -120.920852, 37.756701 ], [ -120.917336, 37.756794 ], [ -120.917171, 37.752444 ], [ -120.918358, 37.749852 ], [ -120.922121, 37.748599 ], [ -120.921104, 37.745965 ], [ -120.921462, 37.743331 ], [ -120.920599, 37.738329 ], [ -120.922246, 37.737475 ], [ -120.923588, 37.73764 ], [ -120.926807, 37.738581 ], [ -120.933006, 37.739498 ], [ -120.939081, 37.741961 ], [ -120.941987, 37.742293 ], [ -120.944445, 37.742128 ], [ -120.947959, 37.740494 ], [ -120.95416, 37.738445 ], [ -120.956959, 37.740487 ], [ -120.958809, 37.741451 ], [ -120.961862, 37.741818 ], [ -120.963347, 37.742686 ], [ -120.970003, 37.746484 ], [ -120.973165, 37.747952 ], [ -120.975244, 37.751005 ], [ -120.977225, 37.75277 ], [ -120.981366, 37.754527 ], [ -120.981571, 37.756429 ], [ -120.981797, 37.7567 ], [ -120.98631, 37.756448 ], [ -120.991993, 37.758984 ], [ -120.99276, 37.760755 ], [ -120.995696, 37.760178 ], [ -120.996251, 37.782064 ], [ -120.992012, 37.782063 ], [ -120.99288, 37.785721 ], [ -120.991832, 37.785722 ], [ -120.992179, 37.788906 ], [ -120.986122, 37.789089 ], [ -120.984055, 37.78752 ], [ -120.982752, 37.789343 ], [ -120.978422, 37.789343 ], [ -120.978445, 37.79151 ], [ -120.981947, 37.791512 ], [ -120.981955, 37.793804 ], [ -120.982683, 37.79418 ], [ -120.978352, 37.794218 ], [ -120.978307, 37.794448 ], [ -120.978385, 37.796216 ], [ -120.97841, 37.797649 ], [ -120.978297, 37.800743 ], [ -120.97925, 37.800743 ], [ -120.991269, 37.800606 ], [ -120.99039, 37.801191 ], [ -120.99079, 37.803718 ], [ -120.992626, 37.803718 ], [ -120.992784, 37.806924 ], [ -120.99701, 37.806911 ], [ -120.996953, 37.80468 ], [ -121.000547, 37.804633 ], [ -121.007287, 37.810203 ], [ -121.012289, 37.812658 ], [ -121.015385, 37.813081 ], [ -121.01532, 37.810885 ], [ -121.018364, 37.813229 ], [ -121.027036, 37.813193 ], [ -121.026787, 37.805995 ], [ -121.029172, 37.805878 ], [ -121.029026, 37.798614 ], [ -121.070387, 37.798304 ], [ -121.06999, 37.783505 ], [ -121.069789, 37.776219 ], [ -121.069656, 37.772587 ], [ -121.124694, 37.772183 ], [ -121.12457, 37.768506 ], [ -121.133618, 37.768506 ], [ -121.133618, 37.768661 ], [ -121.139003, 37.768694 ], [ -121.138992, 37.768528 ], [ -121.142696, 37.768554 ], [ -121.169701, 37.768378 ], [ -121.176197, 37.772736 ], [ -121.178155, 37.775297 ], [ -121.179331, 37.777343 ], [ -121.179375, 37.779378 ], [ -121.17948, 37.784799 ], [ -121.179791, 37.796397 ], [ -121.176862, 37.796394 ], [ -121.176854, 37.797556 ], [ -121.179846, 37.797549 ], [ -121.179882, 37.797671 ], [ -121.179932, 37.798111 ], [ -121.180085, 37.801718 ], [ -121.180351, 37.808499 ], [ -121.180768, 37.819297 ], [ -121.20256, 37.819222 ], [ -121.212752, 37.819204 ], [ -121.212851, 37.819214 ], [ -121.212997, 37.82172 ], [ -121.215813, 37.821825 ], [ -121.215868, 37.821928 ], [ -121.216051, 37.822282 ], [ -121.217165, 37.82648 ], [ -121.218573, 37.826477 ], [ -121.226954, 37.826466 ], [ -121.227187, 37.835422 ], [ -121.236276, 37.835414 ], [ -121.236376, 37.837837 ], [ -121.23761, 37.837839 ], [ -121.238287, 37.840974 ], [ -121.245673, 37.840986 ], [ -121.245305, 37.833711 ], [ -121.254177, 37.83372 ], [ -121.254228, 37.833719 ], [ -121.253961, 37.830091 ], [ -121.253721, 37.826521 ], [ -121.253813, 37.82652 ], [ -121.2533, 37.816824 ], [ -121.260003, 37.820511 ], [ -121.262532, 37.821577 ], [ -121.261669, 37.805631 ], [ -121.261756, 37.803513 ], [ -121.263017, 37.79893 ], [ -121.263901, 37.797314 ], [ -121.268192, 37.797287 ], [ -121.280217, 37.79726 ], [ -121.283602, 37.794775 ], [ -121.286591, 37.793486 ], [ -121.297892, 37.790078 ], [ -121.294471, 37.790384 ], [ -121.292589, 37.790407 ], [ -121.299385, 37.788764 ], [ -121.305353, 37.785523 ], [ -121.306199, 37.784862 ], [ -121.304157, 37.78341 ], [ -121.301604, 37.779291 ], [ -121.300608, 37.777764 ], [ -121.304339, 37.77518 ], [ -121.304295, 37.772931 ], [ -121.302188, 37.77096 ], [ -121.305616, 37.768363 ], [ -121.309403, 37.765667 ], [ -121.309479, 37.761517 ], [ -121.308985, 37.760173 ], [ -121.313861, 37.760444 ], [ -121.316589, 37.761121 ], [ -121.318312, 37.764139 ], [ -121.322068, 37.767554 ], [ -121.323527, 37.769869 ], [ -121.325795, 37.771438 ], [ -121.328231, 37.772368 ], [ -121.332166, 37.775224 ], [ -121.334132, 37.775661 ], [ -121.337352, 37.778803 ], [ -121.338153, 37.781289 ], [ -121.339707, 37.781065 ], [ -121.346562, 37.783485 ], [ -121.348339, 37.784812 ], [ -121.349482, 37.784565 ], [ -121.350412, 37.788311 ], [ -121.351376, 37.78949 ], [ -121.353298, 37.790003 ], [ -121.359895, 37.788733 ], [ -121.362057, 37.789428 ], [ -121.36425, 37.792994 ], [ -121.36376, 37.794947 ], [ -121.36234, 37.796503 ], [ -121.365824, 37.796055 ], [ -121.367694, 37.798188 ], [ -121.370615, 37.800321 ], [ -121.388318, 37.804503 ], [ -121.391323, 37.804989 ], [ -121.398193, 37.80333 ], [ -121.39882, 37.803174 ], [ -121.398775, 37.798457 ], [ -121.404261, 37.798461 ], [ -121.411642, 37.798124 ], [ -121.41326, 37.791134 ], [ -121.41815, 37.791708 ], [ -121.420495, 37.791016 ], [ -121.419663, 37.790525 ], [ -121.417984, 37.790179 ], [ -121.41461, 37.784078 ], [ -121.414711, 37.774728 ], [ -121.416831, 37.776281 ], [ -121.419456, 37.775428 ], [ -121.419459, 37.76906 ], [ -121.426013, 37.768882 ], [ -121.435066, 37.769041 ], [ -121.435281, 37.768994 ], [ -121.435287, 37.768032 ], [ -121.435303, 37.765377 ], [ -121.437304, 37.765361 ], [ -121.437345, 37.762813 ], [ -121.442411, 37.76218 ], [ -121.444412, 37.761574 ], [ -121.453026, 37.758072 ], [ -121.453078, 37.759906 ], [ -121.455213, 37.759904 ], [ -121.455187, 37.763325 ], [ -121.462367, 37.763101 ], [ -121.462238, 37.765459 ], [ -121.469658, 37.765532 ], [ -121.46956, 37.754063 ], [ -121.476684, 37.754059 ], [ -121.476637, 37.749576 ], [ -121.476632, 37.749251 ], [ -121.476651, 37.748735 ], [ -121.492544, 37.742213 ], [ -121.497112, 37.740961 ], [ -121.500853, 37.740666 ], [ -121.513166, 37.741418 ], [ -121.548581, 37.743668 ], [ -121.549674, 37.743693 ], [ -121.556959, 37.743051 ], [ -121.557145, 37.746608 ], [ -121.556661, 37.756107 ], [ -121.557032, 37.794733 ], [ -121.556959, 37.794734 ], [ -121.557038, 37.815988 ], [ -121.556936, 37.817218 ], [ -121.558905, 37.818432 ], [ -121.55916, 37.818927 ], [ -121.58056, 37.812467 ], [ -121.580044, 37.813215 ], [ -121.584944, 37.816504 ], [ -121.598451, 37.824894 ], [ -121.602696, 37.827919 ], [ -121.605173, 37.830107 ], [ -121.60424, 37.834387 ], [ -121.602959, 37.837943 ], [ -121.60508, 37.838315 ], [ -121.61222, 37.838313 ], [ -121.618314, 37.84509 ], [ -121.623188, 37.846319 ], [ -121.625017, 37.845238 ], [ -121.627353, 37.845867 ], [ -121.627286, 37.849327 ], [ -121.631922, 37.849327 ], [ -121.632173, 37.852988 ], [ -121.641445, 37.853087 ], [ -121.641194, 37.86031 ], [ -121.659238, 37.86031 ], [ -121.659609, 37.867427 ], [ -121.660042, 37.867414 ], [ -121.667666, 37.865194 ], [ -121.671312, 37.867644 ], [ -121.677923, 37.871325 ], [ -121.678999, 37.872325 ], [ -121.688647, 37.882978 ], [ -121.696526, 37.883189 ], [ -121.696502, 37.886014 ], [ -121.697164, 37.885726 ], [ -121.705547, 37.887793 ], [ -121.708061, 37.886712 ], [ -121.710212, 37.889265 ], [ -121.710406, 37.8907 ], [ -121.712154, 37.892234 ], [ -121.712579, 37.892147 ], [ -121.711802, 37.891625 ], [ -121.714126, 37.889486 ], [ -121.717542, 37.890447 ], [ -121.719522, 37.892556 ], [ -121.720815, 37.888831 ], [ -121.725025, 37.891374 ], [ -121.727464, 37.890824 ], [ -121.728163, 37.891046 ], [ -121.727058, 37.891809 ], [ -121.730229, 37.892693 ], [ -121.729521, 37.895566 ], [ -121.732515, 37.896878 ], [ -121.732799, 37.897986 ], [ -121.736567, 37.898676 ], [ -121.737593, 37.896535 ], [ -121.73868, 37.897063 ], [ -121.738605, 37.897927 ], [ -121.735565, 37.900111 ], [ -121.732826, 37.899801 ], [ -121.732631, 37.900696 ], [ -121.739146, 37.903751 ], [ -121.7366, 37.905466 ], [ -121.734074, 37.905126 ], [ -121.7314, 37.90348 ], [ -121.730539, 37.904216 ], [ -121.732727, 37.906406 ], [ -121.732498, 37.90801 ], [ -121.734157, 37.908255 ], [ -121.736974, 37.909708 ], [ -121.737728, 37.909813 ], [ -121.738377, 37.909749 ], [ -121.741591, 37.908464 ], [ -121.743864, 37.908326 ], [ -121.748224, 37.907889 ], [ -121.750998, 37.904891 ], [ -121.752175, 37.925017 ], [ -121.752971, 37.920863 ], [ -121.756269, 37.918344 ], [ -121.759914, 37.917844 ], [ -121.759975, 37.921232 ], [ -121.758205, 37.921951 ], [ -121.758076, 37.923132 ], [ -121.760032, 37.923133 ], [ -121.76004, 37.924936 ], [ -121.758071, 37.924742 ], [ -121.75694, 37.923869 ], [ -121.753372, 37.923885 ], [ -121.753361, 37.925063 ], [ -121.755528, 37.925283 ], [ -121.778112, 37.925269 ], [ -121.77816, 37.923256 ], [ -121.778617, 37.920848 ], [ -121.784956, 37.921903 ], [ -121.788389, 37.923186 ], [ -121.790314, 37.92435 ], [ -121.804692, 37.929938 ], [ -121.804693, 37.932402 ], [ -121.812736, 37.932402 ], [ -121.816967, 37.934169 ], [ -121.82064, 37.93468 ], [ -121.822059, 37.935528 ], [ -121.822168, 37.937495 ], [ -121.824038, 37.938356 ], [ -121.826077, 37.939294 ], [ -121.82398, 37.939332 ], [ -121.823952, 37.948496 ], [ -121.823937, 37.951231 ], [ -121.821303, 37.952334 ], [ -121.824053, 37.95459 ], [ -121.823125, 37.959852 ], [ -121.821779, 37.962812 ], [ -121.822413, 37.965345 ], [ -121.823858, 37.965601 ], [ -121.833521, 37.965728 ], [ -121.837594, 37.967673 ], [ -121.837604, 37.968623 ], [ -121.851272, 37.968723 ], [ -121.85128, 37.983194 ], [ -121.851325, 37.986549 ] ] ] } } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /test/data/CD_CA_9_scores.json: -------------------------------------------------------------------------------- 1 | { 2 | "polsbypopper": 0.3528, 3 | "convexhull": 0.8413, 4 | "reock": 0.5298, 5 | "schwartzberg": 0.5940 6 | } 7 | -------------------------------------------------------------------------------- /test/data/CD_IL_4.geojson: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FeatureCollection", 3 | "name": "CD_IL_4", 4 | "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, 5 | "features": [ 6 | { "type": "Feature", "properties": { "STATEFP": "17", "CD115FP": "04", "AFFGEOID": "5001500US1704", "GEOID": "1704", "LSAD": "C2", "CDSESSN": "115", "ALAND": 135768215, "AWATER": 966146 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -87.920624, 41.889752 ], [ -87.920566, 41.897316 ], [ -87.92056, 41.899697 ], [ -87.920163, 41.901844 ], [ -87.920445, 41.906841 ], [ -87.908153, 41.907061 ], [ -87.90319, 41.907206 ], [ -87.893479, 41.90737 ], [ -87.889471, 41.907444 ], [ -87.885697, 41.907523 ], [ -87.883778, 41.907558 ], [ -87.872408, 41.907773 ], [ -87.870425, 41.907804 ], [ -87.864442, 41.907903 ], [ -87.85712, 41.908034 ], [ -87.851205, 41.908141 ], [ -87.849696, 41.908168 ], [ -87.844961, 41.908255 ], [ -87.839952, 41.908355 ], [ -87.837736, 41.908392 ], [ -87.834978, 41.908435 ], [ -87.827848, 41.908501 ], [ -87.825454, 41.908545 ], [ -87.825457, 41.911015 ], [ -87.825444, 41.912203 ], [ -87.823564, 41.910233 ], [ -87.822987, 41.912243 ], [ -87.820541, 41.912287 ], [ -87.820484, 41.91046 ], [ -87.816822, 41.910521 ], [ -87.816882, 41.912348 ], [ -87.813216, 41.912411 ], [ -87.811995, 41.912431 ], [ -87.808333, 41.912494 ], [ -87.808274, 41.910666 ], [ -87.805826, 41.910706 ], [ -87.805891, 41.912533 ], [ -87.806005, 41.916189 ], [ -87.806065, 41.918023 ], [ -87.80423, 41.918041 ], [ -87.80429, 41.919871 ], [ -87.804327, 41.92109 ], [ -87.804386, 41.922872 ], [ -87.80623, 41.92336 ], [ -87.806255, 41.924007 ], [ -87.806333, 41.926234 ], [ -87.806365, 41.927131 ], [ -87.806387, 41.927752 ], [ -87.806443, 41.929338 ], [ -87.806495, 41.930815 ], [ -87.806556, 41.932563 ], [ -87.805337, 41.932578 ], [ -87.805272, 41.930767 ], [ -87.804052, 41.930781 ], [ -87.804116, 41.932593 ], [ -87.802896, 41.932611 ], [ -87.801038, 41.932633 ], [ -87.8011, 41.934448 ], [ -87.796811, 41.934508 ], [ -87.790727, 41.934594 ], [ -87.789535, 41.936437 ], [ -87.785872, 41.936492 ], [ -87.78581, 41.934661 ], [ -87.78095, 41.934728 ], [ -87.781011, 41.936555 ], [ -87.776151, 41.936623 ], [ -87.776215, 41.938448 ], [ -87.7665, 41.938575 ], [ -87.766596, 41.941314 ], [ -87.766628, 41.942228 ], [ -87.766756, 41.945877 ], [ -87.761836, 41.945941 ], [ -87.761959, 41.949589 ], [ -87.761962, 41.949699 ], [ -87.762076, 41.953243 ], [ -87.767, 41.953185 ], [ -87.767123, 41.956832 ], [ -87.762196, 41.95689 ], [ -87.762285, 41.959629 ], [ -87.762316, 41.960542 ], [ -87.757387, 41.9606 ], [ -87.757357, 41.959689 ], [ -87.757298, 41.957862 ], [ -87.757268, 41.95695 ], [ -87.757206, 41.955122 ], [ -87.757148, 41.9533 ], [ -87.752239, 41.95336 ], [ -87.747305, 41.953418 ], [ -87.74275, 41.953474 ], [ -87.742526, 41.953474 ], [ -87.742557, 41.953103 ], [ -87.742361, 41.946185 ], [ -87.736015, 41.946264 ], [ -87.735627, 41.946267 ], [ -87.733748, 41.946293 ], [ -87.73128, 41.946323 ], [ -87.727401, 41.946373 ], [ -87.724954, 41.946405 ], [ -87.724965, 41.946812 ], [ -87.724371, 41.946821 ], [ -87.724362, 41.946413 ], [ -87.722506, 41.946439 ], [ -87.719768, 41.946475 ], [ -87.718764, 41.946488 ], [ -87.719717, 41.947485 ], [ -87.722169, 41.948662 ], [ -87.722624, 41.949698 ], [ -87.722711, 41.953726 ], [ -87.722782, 41.956182 ], [ -87.72282, 41.957365 ], [ -87.724491, 41.957345 ], [ -87.726533, 41.958456 ], [ -87.72777, 41.958942 ], [ -87.727789, 41.959614 ], [ -87.729693, 41.960927 ], [ -87.731967, 41.962493 ], [ -87.733632, 41.963639 ], [ -87.733217, 41.963976 ], [ -87.730407, 41.966212 ], [ -87.730409, 41.966293 ], [ -87.730478, 41.968215 ], [ -87.729261, 41.968228 ], [ -87.728028, 41.968242 ], [ -87.728081, 41.970064 ], [ -87.724454, 41.970103 ], [ -87.723192, 41.970116 ], [ -87.718304, 41.970168 ], [ -87.715858, 41.970196 ], [ -87.714637, 41.970211 ], [ -87.713414, 41.970223 ], [ -87.713363, 41.968401 ], [ -87.710921, 41.968429 ], [ -87.710908, 41.967971 ], [ -87.709077, 41.967999 ], [ -87.709073, 41.968444 ], [ -87.708472, 41.968452 ], [ -87.703605, 41.968494 ], [ -87.70357, 41.96804 ], [ -87.704187, 41.968033 ], [ -87.704141, 41.966661 ], [ -87.703528, 41.966666 ], [ -87.703494, 41.965623 ], [ -87.703466, 41.964739 ], [ -87.704069, 41.964279 ], [ -87.703357, 41.961219 ], [ -87.702135, 41.961227 ], [ -87.699688, 41.961242 ], [ -87.699072, 41.961246 ], [ -87.698961, 41.957594 ], [ -87.698352, 41.9576 ], [ -87.698241, 41.953975 ], [ -87.698137, 41.950326 ], [ -87.698031, 41.946683 ], [ -87.696208, 41.946696 ], [ -87.695304, 41.942799 ], [ -87.693508, 41.940196 ], [ -87.692462, 41.939427 ], [ -87.693007, 41.939423 ], [ -87.69293, 41.938962 ], [ -87.692841, 41.935786 ], [ -87.697725, 41.935743 ], [ -87.697683, 41.934457 ], [ -87.697683, 41.934216 ], [ -87.693964, 41.932124 ], [ -87.692738, 41.931393 ], [ -87.687766, 41.928583 ], [ -87.682788, 41.925907 ], [ -87.683641, 41.924955 ], [ -87.683871, 41.924952 ], [ -87.685209, 41.924932 ], [ -87.687642, 41.924901 ], [ -87.687521, 41.920984 ], [ -87.68741, 41.917568 ], [ -87.687316, 41.913995 ], [ -87.687221, 41.910321 ], [ -87.684782, 41.910357 ], [ -87.684687, 41.906705 ], [ -87.687123, 41.906666 ], [ -87.687027, 41.903016 ], [ -87.687006, 41.902087 ], [ -87.68696, 41.900293 ], [ -87.686936, 41.899379 ], [ -87.691863, 41.89933 ], [ -87.694327, 41.899303 ], [ -87.696791, 41.899283 ], [ -87.696815, 41.900199 ], [ -87.696836, 41.901107 ], [ -87.701769, 41.901059 ], [ -87.701718, 41.89924 ], [ -87.701951, 41.899238 ], [ -87.706674, 41.899195 ], [ -87.706731, 41.901006 ], [ -87.708744, 41.900981 ], [ -87.70869, 41.899171 ], [ -87.708813, 41.899171 ], [ -87.711551, 41.900148 ], [ -87.713455, 41.901015 ], [ -87.716545, 41.902241 ], [ -87.717781, 41.902745 ], [ -87.721478, 41.904206 ], [ -87.725177, 41.905663 ], [ -87.726408, 41.906156 ], [ -87.728884, 41.907141 ], [ -87.731367, 41.908134 ], [ -87.733861, 41.909112 ], [ -87.735502, 41.909759 ], [ -87.739858, 41.911491 ], [ -87.741285, 41.912053 ], [ -87.74599, 41.913924 ], [ -87.748198, 41.914439 ], [ -87.748574, 41.914801 ], [ -87.749392, 41.915258 ], [ -87.74936, 41.914908 ], [ -87.752858, 41.915326 ], [ -87.755895, 41.915709 ], [ -87.76079, 41.916261 ], [ -87.760871, 41.917848 ], [ -87.765806, 41.918763 ], [ -87.765851, 41.920348 ], [ -87.769505, 41.920276 ], [ -87.769472, 41.919431 ], [ -87.770701, 41.919657 ], [ -87.775604, 41.920559 ], [ -87.780504, 41.921463 ], [ -87.780401, 41.918292 ], [ -87.780263, 41.916532 ], [ -87.785226, 41.916452 ], [ -87.785177, 41.914592 ], [ -87.794958, 41.914484 ], [ -87.795, 41.915848 ], [ -87.800494, 41.915794 ], [ -87.800394, 41.912599 ], [ -87.800277, 41.908952 ], [ -87.802113, 41.908934 ], [ -87.805748, 41.908904 ], [ -87.810654, 41.908796 ], [ -87.810512, 41.905127 ], [ -87.810377, 41.90146 ], [ -87.815243, 41.901346 ], [ -87.83029, 41.901145 ], [ -87.833401, 41.901764 ], [ -87.833629, 41.901156 ], [ -87.834204, 41.898624 ], [ -87.835153, 41.898563 ], [ -87.839643, 41.898331 ], [ -87.840856, 41.898407 ], [ -87.844593, 41.89839 ], [ -87.844546, 41.897098 ], [ -87.844514, 41.896183 ], [ -87.844245, 41.889146 ], [ -87.844236, 41.888954 ], [ -87.851615, 41.889786 ], [ -87.856579, 41.890333 ], [ -87.859553, 41.890679 ], [ -87.859764, 41.890703 ], [ -87.863949, 41.891155 ], [ -87.863962, 41.891741 ], [ -87.864013, 41.892923 ], [ -87.878485, 41.892744 ], [ -87.883518, 41.892407 ], [ -87.888263, 41.89243 ], [ -87.888401, 41.891716 ], [ -87.890852, 41.891968 ], [ -87.893255, 41.892203 ], [ -87.894073, 41.892238 ], [ -87.895511, 41.892651 ], [ -87.898466, 41.892509 ], [ -87.899336, 41.892644 ], [ -87.903266, 41.892666 ], [ -87.903254, 41.889289 ], [ -87.908125, 41.889421 ], [ -87.908137, 41.885404 ], [ -87.910218, 41.885416 ], [ -87.910733, 41.883773 ], [ -87.910759, 41.882347 ], [ -87.911416, 41.881955 ], [ -87.913004, 41.882086 ], [ -87.91959, 41.882637 ], [ -87.919601, 41.882176 ], [ -87.918986, 41.876958 ], [ -87.918243, 41.873662 ], [ -87.917831, 41.871634 ], [ -87.917579, 41.870798 ], [ -87.917181, 41.869082 ], [ -87.916628, 41.869773 ], [ -87.913811, 41.869715 ], [ -87.902363, 41.870007 ], [ -87.902541, 41.873822 ], [ -87.89975, 41.873402 ], [ -87.893829, 41.870986 ], [ -87.890635, 41.870078 ], [ -87.882791, 41.869915 ], [ -87.88249, 41.86326 ], [ -87.882433, 41.861877 ], [ -87.882184, 41.857471 ], [ -87.88208, 41.855823 ], [ -87.882836, 41.855473 ], [ -87.891888, 41.855181 ], [ -87.891749, 41.852221 ], [ -87.891641, 41.8498 ], [ -87.883999, 41.849901 ], [ -87.883226, 41.850028 ], [ -87.881777, 41.850462 ], [ -87.88164, 41.849452 ], [ -87.87873, 41.849347 ], [ -87.878112, 41.849055 ], [ -87.875631, 41.84963 ], [ -87.875593, 41.848809 ], [ -87.873152, 41.848877 ], [ -87.870723, 41.848942 ], [ -87.870591, 41.848656 ], [ -87.865548, 41.848852 ], [ -87.865464, 41.845534 ], [ -87.865388, 41.84406 ], [ -87.865377, 41.843829 ], [ -87.865261, 41.841835 ], [ -87.865254, 41.841706 ], [ -87.864147, 41.841803 ], [ -87.864055, 41.838186 ], [ -87.861736, 41.838248 ], [ -87.856855, 41.83838 ], [ -87.856934, 41.840202 ], [ -87.852047, 41.840328 ], [ -87.852095, 41.84124 ], [ -87.848881, 41.841812 ], [ -87.84956, 41.8422 ], [ -87.846373, 41.84221 ], [ -87.842344, 41.842527 ], [ -87.844833, 41.844941 ], [ -87.847374, 41.844934 ], [ -87.847395, 41.845906 ], [ -87.84749, 41.847746 ], [ -87.846361, 41.849612 ], [ -87.842714, 41.849684 ], [ -87.840236, 41.849725 ], [ -87.840213, 41.849274 ], [ -87.835276, 41.849317 ], [ -87.834074, 41.849827 ], [ -87.832835, 41.849842 ], [ -87.82945, 41.849911 ], [ -87.827318, 41.849957 ], [ -87.823053, 41.850022 ], [ -87.817092, 41.850151 ], [ -87.808079, 41.850291 ], [ -87.803792, 41.850369 ], [ -87.80348, 41.843088 ], [ -87.80333, 41.84099 ], [ -87.801418, 41.842072 ], [ -87.800505, 41.843148 ], [ -87.798313, 41.844579 ], [ -87.797018, 41.845899 ], [ -87.795708, 41.84714 ], [ -87.794876, 41.847725 ], [ -87.793285, 41.848635 ], [ -87.793337, 41.850559 ], [ -87.790891, 41.850597 ], [ -87.789671, 41.850673 ], [ -87.788447, 41.850698 ], [ -87.788396, 41.848809 ], [ -87.787169, 41.848828 ], [ -87.787219, 41.850589 ], [ -87.783544, 41.850653 ], [ -87.783547, 41.850765 ], [ -87.783647, 41.85418 ], [ -87.789766, 41.854105 ], [ -87.790989, 41.854086 ], [ -87.793435, 41.854047 ], [ -87.793491, 41.856044 ], [ -87.79354, 41.857872 ], [ -87.793592, 41.859692 ], [ -87.792369, 41.85971 ], [ -87.791145, 41.859729 ], [ -87.791196, 41.861552 ], [ -87.792419, 41.861532 ], [ -87.793643, 41.861514 ], [ -87.793693, 41.863334 ], [ -87.796306, 41.863288 ], [ -87.796361, 41.86511 ], [ -87.793747, 41.865157 ], [ -87.791313, 41.865199 ], [ -87.788858, 41.865243 ], [ -87.785181, 41.865307 ], [ -87.783975, 41.865778 ], [ -87.779045, 41.86585 ], [ -87.779048, 41.865392 ], [ -87.776588, 41.865426 ], [ -87.776603, 41.865882 ], [ -87.774146, 41.865915 ], [ -87.774139, 41.865459 ], [ -87.772896, 41.865479 ], [ -87.767986, 41.865546 ], [ -87.759409, 41.865678 ], [ -87.754533, 41.865752 ], [ -87.752082, 41.865787 ], [ -87.74964, 41.865825 ], [ -87.744754, 41.865897 ], [ -87.739932, 41.86596 ], [ -87.739838, 41.862075 ], [ -87.739767, 41.858654 ], [ -87.739423, 41.851351 ], [ -87.739221, 41.845979 ], [ -87.739198, 41.845473 ], [ -87.731115, 41.847314 ], [ -87.7279, 41.84803 ], [ -87.724685, 41.848774 ], [ -87.722261, 41.849309 ], [ -87.719825, 41.849832 ], [ -87.719776, 41.847984 ], [ -87.714894, 41.848033 ], [ -87.714978, 41.850912 ], [ -87.713778, 41.851677 ], [ -87.713627, 41.851679 ], [ -87.712422, 41.851707 ], [ -87.711143, 41.851991 ], [ -87.710128, 41.851706 ], [ -87.705255, 41.851765 ], [ -87.702813, 41.851799 ], [ -87.701581, 41.851818 ], [ -87.700364, 41.851838 ], [ -87.699089, 41.851853 ], [ -87.699213, 41.855505 ], [ -87.700586, 41.85654 ], [ -87.701702, 41.859251 ], [ -87.695755, 41.861317 ], [ -87.695692, 41.859221 ], [ -87.695569, 41.855552 ], [ -87.695558, 41.85524 ], [ -87.691086, 41.856259 ], [ -87.690599, 41.853821 ], [ -87.690543, 41.851969 ], [ -87.690492, 41.850145 ], [ -87.690433, 41.848336 ], [ -87.692918, 41.849203 ], [ -87.695371, 41.849172 ], [ -87.695333, 41.847883 ], [ -87.695272, 41.84645 ], [ -87.695215, 41.844692 ], [ -87.700148, 41.844613 ], [ -87.702584, 41.844552 ], [ -87.70504, 41.844518 ], [ -87.70493, 41.840877 ], [ -87.706149, 41.840858 ], [ -87.706093, 41.839033 ], [ -87.707277, 41.837184 ], [ -87.704823, 41.837233 ], [ -87.691099, 41.837496 ], [ -87.687617, 41.838189 ], [ -87.687442, 41.84364 ], [ -87.687615, 41.844794 ], [ -87.687952, 41.852009 ], [ -87.688027, 41.853857 ], [ -87.688135, 41.855691 ], [ -87.685737, 41.855709 ], [ -87.685834, 41.859366 ], [ -87.673599, 41.859517 ], [ -87.671143, 41.859542 ], [ -87.666198, 41.859607 ], [ -87.663808, 41.859647 ], [ -87.656479, 41.859765 ], [ -87.653434, 41.859812 ], [ -87.650941, 41.859851 ], [ -87.650822, 41.859853 ], [ -87.646706, 41.859911 ], [ -87.644468, 41.859954 ], [ -87.64194, 41.859984 ], [ -87.639014, 41.860018 ], [ -87.635649, 41.860027 ], [ -87.634502, 41.859934 ], [ -87.634485, 41.859073 ], [ -87.635131, 41.857759 ], [ -87.63562, 41.856668 ], [ -87.639164, 41.854367 ], [ -87.640461, 41.852715 ], [ -87.642508, 41.850021 ], [ -87.642707, 41.849905 ], [ -87.643958, 41.849471 ], [ -87.649678, 41.848279 ], [ -87.657074, 41.848187 ], [ -87.658043, 41.847724 ], [ -87.658843, 41.84729 ], [ -87.660811, 41.845927 ], [ -87.663149, 41.844685 ], [ -87.664983, 41.841461 ], [ -87.664251, 41.839206 ], [ -87.667445, 41.837645 ], [ -87.670562, 41.837287 ], [ -87.670462, 41.833192 ], [ -87.670399, 41.830447 ], [ -87.67528, 41.83039 ], [ -87.675314, 41.831819 ], [ -87.677721, 41.830364 ], [ -87.684349, 41.826284 ], [ -87.68424, 41.823 ], [ -87.676318, 41.823091 ], [ -87.675088, 41.823113 ], [ -87.670213, 41.82317 ], [ -87.667777, 41.823183 ], [ -87.665462, 41.82315 ], [ -87.6652, 41.818227 ], [ -87.665148, 41.815871 ], [ -87.665109, 41.81406 ], [ -87.665064, 41.812222 ], [ -87.669926, 41.812197 ], [ -87.672355, 41.812174 ], [ -87.672313, 41.810758 ], [ -87.674692, 41.810333 ], [ -87.674687, 41.80851 ], [ -87.674641, 41.806686 ], [ -87.675853, 41.806674 ], [ -87.677028, 41.804848 ], [ -87.679015, 41.804825 ], [ -87.67949, 41.808459 ], [ -87.683874, 41.808417 ], [ -87.684425, 41.808426 ], [ -87.689324, 41.80836 ], [ -87.690546, 41.808341 ], [ -87.69048, 41.806568 ], [ -87.686828, 41.806614 ], [ -87.686877, 41.804613 ], [ -87.68437, 41.804632 ], [ -87.684224, 41.801146 ], [ -87.684178, 41.799334 ], [ -87.689071, 41.799246 ], [ -87.689021, 41.797425 ], [ -87.687801, 41.797444 ], [ -87.687704, 41.793804 ], [ -87.688931, 41.793783 ], [ -87.691361, 41.793736 ], [ -87.692581, 41.793714 ], [ -87.692681, 41.79736 ], [ -87.6939, 41.797339 ], [ -87.698782, 41.797253 ], [ -87.703659, 41.797167 ], [ -87.703554, 41.793514 ], [ -87.69868, 41.793605 ], [ -87.69624, 41.793649 ], [ -87.696186, 41.791827 ], [ -87.696136, 41.790008 ], [ -87.698577, 41.789965 ], [ -87.698523, 41.788145 ], [ -87.699745, 41.788125 ], [ -87.699691, 41.786307 ], [ -87.700911, 41.786286 ], [ -87.703349, 41.786248 ], [ -87.704568, 41.786228 ], [ -87.70823, 41.786172 ], [ -87.712897, 41.786097 ], [ -87.71312, 41.786092 ], [ -87.713315, 41.789746 ], [ -87.713399, 41.793362 ], [ -87.71826, 41.793276 ], [ -87.723159, 41.793204 ], [ -87.723213, 41.795052 ], [ -87.723265, 41.796847 ], [ -87.723369, 41.800362 ], [ -87.723373, 41.800546 ], [ -87.727048, 41.800505 ], [ -87.727151, 41.804167 ], [ -87.727256, 41.807826 ], [ -87.728476, 41.807809 ], [ -87.730946, 41.807779 ], [ -87.738207, 41.807684 ], [ -87.738493, 41.814993 ], [ -87.743431, 41.814928 ], [ -87.74348, 41.816482 ], [ -87.744949, 41.815998 ], [ -87.744959, 41.816241 ], [ -87.744949, 41.821981 ], [ -87.74354, 41.822167 ], [ -87.743605, 41.829316 ], [ -87.753508, 41.829174 ], [ -87.763311, 41.829083 ], [ -87.770659, 41.828976 ], [ -87.778002, 41.828874 ], [ -87.782906, 41.828798 ], [ -87.785368, 41.829219 ], [ -87.78778, 41.828379 ], [ -87.789001, 41.828518 ], [ -87.791408, 41.827668 ], [ -87.791447, 41.828659 ], [ -87.792676, 41.82864 ], [ -87.796313, 41.828581 ], [ -87.800182, 41.828045 ], [ -87.80079, 41.826676 ], [ -87.802822, 41.828005 ], [ -87.802676, 41.823715 ], [ -87.802634, 41.821694 ], [ -87.804721, 41.821657 ], [ -87.804699, 41.821149 ], [ -87.810331, 41.820987 ], [ -87.812502, 41.821062 ], [ -87.818276, 41.821075 ], [ -87.821305, 41.820885 ], [ -87.821683, 41.821063 ], [ -87.829643, 41.820711 ], [ -87.830275, 41.820718 ], [ -87.831687, 41.820602 ], [ -87.832407, 41.820712 ], [ -87.840027, 41.820539 ], [ -87.840593, 41.820513 ], [ -87.841465, 41.820495 ], [ -87.845357, 41.820402 ], [ -87.84658, 41.820373 ], [ -87.850259, 41.820335 ], [ -87.851267, 41.820363 ], [ -87.851254, 41.820525 ], [ -87.851488, 41.820465 ], [ -87.852284, 41.820292 ], [ -87.852435, 41.820272 ], [ -87.854272, 41.820203 ], [ -87.859928, 41.820066 ], [ -87.860976, 41.82003 ], [ -87.864404, 41.819928 ], [ -87.864659, 41.825434 ], [ -87.866602, 41.825346 ], [ -87.869098, 41.825281 ], [ -87.869033, 41.828932 ], [ -87.86919, 41.832562 ], [ -87.869272, 41.834395 ], [ -87.874229, 41.834263 ], [ -87.875176, 41.834235 ], [ -87.878562, 41.83414 ], [ -87.881176, 41.834067 ], [ -87.881775, 41.834053 ], [ -87.884203, 41.833994 ], [ -87.885124, 41.833835 ], [ -87.886019, 41.833952 ], [ -87.88617, 41.837599 ], [ -87.88984, 41.837505 ], [ -87.889927, 41.839326 ], [ -87.891148, 41.839296 ], [ -87.891871, 41.844738 ], [ -87.892053, 41.844709 ], [ -87.894138, 41.844238 ], [ -87.901166, 41.844069 ], [ -87.901188, 41.844422 ], [ -87.89616, 41.84463 ], [ -87.896486, 41.84827 ], [ -87.894864, 41.84831 ], [ -87.895266, 41.853487 ], [ -87.896767, 41.85366 ], [ -87.896845, 41.855563 ], [ -87.894479, 41.855583 ], [ -87.894648, 41.859266 ], [ -87.894761, 41.86183 ], [ -87.894807, 41.862906 ], [ -87.901367, 41.86272 ], [ -87.902041, 41.862703 ], [ -87.916409, 41.862299 ], [ -87.916832, 41.862246 ], [ -87.917065, 41.862313 ], [ -87.917892, 41.862332 ], [ -87.918147, 41.862195 ], [ -87.918533, 41.862037 ], [ -87.918512, 41.862293 ], [ -87.918628, 41.862286 ], [ -87.920082, 41.862199 ], [ -87.920161, 41.867742 ], [ -87.920159, 41.867969 ], [ -87.920162, 41.868207 ], [ -87.920459, 41.873114 ], [ -87.920463, 41.8764 ], [ -87.920462, 41.87691 ], [ -87.920606, 41.882701 ], [ -87.920607, 41.883078 ], [ -87.920625, 41.88969 ], [ -87.920624, 41.889752 ] ] ] } } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /test/data/CD_IL_4_scores.json: -------------------------------------------------------------------------------- 1 | { 2 | "polsbypopper": 0.0556, 3 | "convexhull": 0.4196, 4 | "reock": 0.2966, 5 | "schwartzberg": 0.2359 6 | } 7 | -------------------------------------------------------------------------------- /test/data/CD_MA_9_scores.json: -------------------------------------------------------------------------------- 1 | { 2 | "polsbypopper": 0.0492, 3 | "convexhull": 0.3854, 4 | "reock": 0.2714, 5 | "schwartzberg": 0.2219 6 | } 7 | -------------------------------------------------------------------------------- /test/data/CD_PA_7_scores.json: -------------------------------------------------------------------------------- 1 | { 2 | "polsbypopper": 0.0422554428491, 3 | "convexhull": 0.4588, 4 | "reock": 0.3332, 5 | "schwartzberg": 0.2056 6 | } 7 | -------------------------------------------------------------------------------- /test/metrics.py: -------------------------------------------------------------------------------- 1 | from os import path, getcwd 2 | import json 3 | import copy 4 | 5 | from unittest import TestCase 6 | 7 | from mander.districts import District 8 | from mander.metrics import calculatePolsbyPopper, calculateConvexHull, calculateReock, calculateSchwartzberg 9 | from mander.metrics import scoresToGeojson 10 | 11 | base_dir = path.dirname(path.realpath(__file__)) 12 | 13 | # Test individual metrics 14 | 15 | metricFunctions = { 16 | 'polsbypopper': calculatePolsbyPopper, 17 | 'convexhull': calculateConvexHull, 18 | 'reock': calculateReock, 19 | 'schwartzberg': calculateSchwartzberg 20 | } 21 | 22 | test_districts = ['CD_CA_9', 'CD_IL_4', 'CD_PA_7', 'CD_CA_24', 'CD_MA_9'] 23 | 24 | metrics = {} 25 | for m in metricFunctions: 26 | metrics[m] = [] 27 | 28 | test_expected = copy.deepcopy(metrics) 29 | test_returned = copy.deepcopy(metrics) 30 | 31 | def collectTestValues(method, district): 32 | test_expected[method].append('%.4f' % district_scores[method]) 33 | test_returned[method].append('%.4f' % metricFunctions[method](district)) 34 | 35 | for d in test_districts: 36 | 37 | district_boundaries_file = path.join(base_dir, 'data', d + '.geojson') 38 | district_scores_file = path.join(base_dir, 'data', d + '_scores.json') 39 | 40 | with open(district_boundaries_file) as district_boundary_data: 41 | with open(district_scores_file) as district_scores_data: 42 | 43 | district_boundary = json.load(district_boundary_data) 44 | district_scores = json.load(district_scores_data) 45 | 46 | test_district = District(path=district_boundaries_file) # TODO use python object instead of file path parameter 47 | 48 | # Collect expected and returned values 49 | for m in metricFunctions: 50 | collectTestValues(m, test_district) 51 | 52 | 53 | class TestMetrics(TestCase): 54 | 55 | def test_polsbypopper(self): 56 | self.assertEqual(test_expected['polsbypopper'], test_returned['polsbypopper']) 57 | 58 | def test_convexhull(self): 59 | self.assertEqual(test_expected['convexhull'], test_returned['convexhull']) 60 | 61 | def test_reock(self): 62 | self.assertEqual(test_expected['reock'], test_returned['reock']) 63 | 64 | def test_schwartzberg(self): 65 | self.assertEqual(test_expected['schwartzberg'], test_returned['schwartzberg']) 66 | 67 | 68 | # Test scoresToGeojson 69 | 70 | scores_data = scoresToGeojson(District(path=path.join(base_dir, 'data', 'MN_Senate_2017.geojson')), 'polsbypopper') 71 | scores = json.loads(scores_data) 72 | 73 | contains_score = 0 74 | for feature in scores['features']: 75 | if isinstance(feature['properties']['polsbypopper'], float): 76 | contains_score = contains_score + 1 77 | 78 | class TestScoreGeojson(TestCase): 79 | 80 | def test_alldistrictsscored(self): 81 | 82 | self.assertEqual(contains_score, 67) 83 | --------------------------------------------------------------------------------