1 2<p align="center"> 3<img src="docs/_static/images/pysal_banner.svg" width="370" height="200" /> 4</p> 5 6# `spopt`: Spatial Optimization 7 8#### Regionalization, facility location, and transportation-oriented modeling 9 10![tag](https://img.shields.io/github/v/release/pysal/spopt?include_prereleases&sort=semver) 11[![unittests](https://github.com/pysal/spopt/workflows/.github/workflows/unittests.yml/badge.svg)](https://github.com/pysal/spopt/actions?query=workflow%3A.github%2Fworkflows%2Funittests.yml) 12[![codecov](https://codecov.io/gh/pysal/spopt/branch/main/graph/badge.svg)](https://codecov.io/gh/pysal/spopt) 13[![Documentation](https://img.shields.io/static/v1.svg?label=docs&message=current&color=9cf)](http://pysal.org/spopt/) 14[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) 15[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) 16[![status](https://joss.theoj.org/papers/1413cf2c0cf3c561386949f2e1208563/status.svg)](https://joss.theoj.org/papers/1413cf2c0cf3c561386949f2e1208563) 17[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4444156.svg)](https://doi.org/10.5281/zenodo.4444156) 18 19Spopt is an open-source Python library for solving optimization problems with spatial data. Originating from the `region` module in [PySAL (Python Spatial Analysis Library)](http://pysal.org), it is under active development for the inclusion of newly proposed models and methods for regionalization, facility location, and transportation-oriented solutions. 20 21### Regionalization 22 23```python 24import spopt, libpysal, geopandas, numpy 25mexico = geopandas.read_file(libpysal.examples.get_path("mexicojoin.shp")) 26mexico["count"] = 1 27attrs = [f"PCGDP{year}" for year in range(1950, 2010, 10)] 28w = libpysal.weights.Queen.from_dataframe(mexico) 29mexico["count"], threshold_name, threshold, top_n = 1, "count", 4, 2 30numpy.random.seed(123456) 31model = spopt.MaxPHeuristic(mexico, w, attrs, threshold_name, threshold, top_n) 32model.solve() 33mexico["maxp_new"] = model.labels_ 34mexico.plot(column="maxp_new", categorical=True, figsize=(12,8), ec="w"); 35``` 36<p align="center"> 37<img src="docs/_static/images/maxp.svg" height="350" /> 38</p> 39 40### Locate 41```python 42from spopt.locate.coverage import MCLP 43from spopt.locate.util import simulated_geo_points 44import numpy 45import geopandas 46import pulp 47import spaghetti 48 49solver = pulp.PULP_CBC_CMD(msg=False) 50lattice = spaghetti.regular_lattice((0, 0, 10, 10), 9, exterior=True) 51ntw = spaghetti.Network(in_data=lattice) 52street = spaghetti.element_as_gdf(ntw, arcs=True) 53street_buffered = geopandas.GeoDataFrame( 54 geopandas.GeoSeries(street["geometry"].buffer(0.2).unary_union), 55 crs=street.crs, 56 columns=["geometry"], 57) 58client_points = simulated_geo_points(street_buffered, needed=CLIENT_COUNT, seed=CLIENT_SEED) 59facility_points = simulated_geo_points( 60 street_buffered, needed=FACILITY_COUNT, seed=FACILITY_SEED 61) 62ntw.snapobservations(client_points, "clients", attribute=True) 63clients_snapped = spaghetti.element_as_gdf( 64 ntw, pp_name="clients", snapped=True 65) 66 67ntw.snapobservations(facility_points, "facilities", attribute=True) 68facilities_snapped = spaghetti.element_as_gdf( 69 ntw, pp_name="facilities", snapped=True 70) 71cost_matrix = ntw.allneighbordistances( 72 sourcepattern=ntw.pointpatterns["clients"], 73 destpattern=ntw.pointpatterns["facilities"], 74) 75mclp_from_cost_matrix = MCLP.from_cost_matrix(cost_matrix, ai, MAX_COVERAGE, p_facilities=P_FACILITIES) 76mclp_from_cost_matrix = mclp_from_cost_matrix.solve(solver) 77``` 78<p align="center"> 79<img src="docs/_static/images/mclp.svg" height="350" /> 80</p> 81 82## Examples 83More examples can be found in the [Tutorials](https://pysal.org/spopt/tutorials.html) section of the documentation. 84- [Max-p-regions problem](https://pysal.org/spopt/notebooks/maxp.html) 85- [Skater](https://pysal.org/spopt/notebooks/skater.html) 86- [Region K means](https://pysal.org/spopt/notebooks/reg-k-means.html) 87- [Facility Location Real World Problem](https://pysal.org/spopt/notebooks/facloc-real-world.html) 88 89All examples can be run interactively by launching this repository as a [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/pysal/spopt/main). 90 91## Requirements 92- [scipy](http://scipy.github.io/devdocs/) 93- [numpy](https://numpy.org/devdocs/) 94- [pandas](https://pandas.pydata.org/docs/) 95- [networkx](https://networkx.org/) 96- [libpysal](https://pysal.org/libpysal/) 97- [scikit-learn](https://scikit-learn.org/stable/) 98- [geopandas](https://geopandas.org/) 99- [pulp](https://coin-or.github.io/pulp/) 100- [spaghetti](https://github.com/pysal/spaghetti) 101 102## Installation 103spopt is available on the [Python Package Index](https://pypi.org/). Therefore, you can either install directly with pip from the command line: 104``` 105$ pip install -U spopt 106``` 107or download the source distribution (.tar.gz) and decompress it to your selected destination. Open a command shell and navigate to the decompressed folder. Type: 108``` 109$ pip install . 110``` 111You may also install the latest stable spopt via conda-forge channel by running: 112``` 113$ conda install --channel conda-forge spopt 114``` 115 116## Contribute 117 118PySAL-spopt is under active development and contributors are welcome. 119 120If you have any suggestions, feature requests, or bug reports, please open new [issues](https://github.com/pysal/spopt/issues) on GitHub. To submit patches, please review [PySAL's documentation for developers](https://pysal.org/docs/devs/), the PySAL [development guidelines](https://github.com/pysal/pysal/wiki), the `spopt` [contributing guidelines](https://github.com/pysal/spopt/blob/main/.github/CONTRIBUTING.md) before opening a [pull request](https://github.com/pysal/spopt/pulls). Once your changes get merged, you’ll automatically be added to the [Contributors List](https://github.com/pysal/spopt/graphs/contributors). 121 122 123## Support 124If you are having trouble, please [create an issue](https://github.com/pysal/spopt/issues), [start a discussion](https://github.com/pysal/spopt/discussions), or talk to us in the [gitter room](https://gitter.im/pysal/spopt). 125 126## Code of Conduct 127 128As a PySAL-federated project, `spopt` follows the [Code of Conduct](https://github.com/pysal/governance/blob/main/conduct/code_of_conduct.rst) under the [PySAL governance model](https://github.com/pysal/governance). 129 130 131## License 132 133The project is licensed under the [BSD 3-Clause license](https://github.com/pysal/spopt/blob/main/LICENSE.txt). 134 135 136## Citation 137 138If you use PySAL-spopt in a scientific publication, we would appreciate using the following citation: 139 140``` 141@misc{spopt2021, 142 author = {Feng, Xin, and Gaboardi, James D. and Knaap, Elijah and Rey, Sergio J. and Wei, Ran}, 143 month = {jan}, 144 year = {2021}, 145 title = {pysal/spopt}, 146 url = {https://github.com/pysal/spopt}, 147 doi = {10.5281/zenodo.4444156}, 148 keywords = {python,regionalization,spatial-optimization,location-modeling} 149} 150``` 151 152## Funding 153 154This project is/was partially funded through: 155 156[<img align="middle" src="docs/_static/images/nsf_logo.png" width="75">](https://www.nsf.gov/index.jsp) National Science Foundation Award #1831615: [RIDIR: Scalable Geospatial Analytics for Social Science Research](https://www.nsf.gov/awardsearch/showAward?AWD_ID=1831615) 157 158<!-- [<img align="middle" src="docs/_static/image/IMAGE2.png" width="150">](link2) Some text2: [Project title 2](another_link2) --> 159