├── scripts ├── requirements.txt └── process.py ├── .gitattributes ├── data └── admin1.geojson ├── .gitignore ├── LICENSE ├── .github └── workflows │ └── actions.yml ├── datapackage.json └── README.md /scripts/requirements.txt: -------------------------------------------------------------------------------- 1 | requests==2.32.2 -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | data/admin1.geojson filter=lfs diff=lfs merge=lfs -text 2 | -------------------------------------------------------------------------------- /data/admin1.geojson: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d1a7905b9eeb6cdd61f391d811a07e36a74335bcd3cb72024c135d3d6e64b7bf 3 | size 360526180 4 | -------------------------------------------------------------------------------- /scripts/process.py: -------------------------------------------------------------------------------- 1 | import os 2 | import requests 3 | 4 | BASE_URL = 'https://github.com/wmgeolab/geoBoundaries/raw/main/releaseData/CGAZ/geoBoundariesCGAZ_ADM1.geojson' 5 | DATA_DIR = 'data' 6 | 7 | def download_geojson(): 8 | try: 9 | os.makedirs(DATA_DIR, exist_ok=True) 10 | 11 | response = requests.get(BASE_URL) 12 | response.raise_for_status() 13 | geojson_data = response.content 14 | 15 | with open(f'{DATA_DIR}/admin1.geojson', 'wb') as f: 16 | f.write(geojson_data) 17 | print("Download complete: admin1.geojson") 18 | except requests.exceptions.RequestException as e: 19 | print(f"An error occurred: {e}") 20 | 21 | if __name__ == '__main__': 22 | download_geojson() 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | 55 | # Sphinx documentation 56 | docs/_build/ 57 | 58 | # PyBuilder 59 | target/ 60 | venv 61 | 62 | #Ipython Notebook 63 | .ipynb_checkpoints 64 | .DS_Store 65 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Alexandre Bonnasseau 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/actions.yml: -------------------------------------------------------------------------------- 1 | name: Update geo-ne-admin1 data 2 | 3 | on: 4 | # Schedule to run half a year 5 | schedule: 6 | - cron: '0 0 1 */6 *' 7 | 8 | # Run on push to main branch 9 | push: 10 | branches: 11 | - main 12 | 13 | # Run on pull requests targeting the main branch 14 | pull_request: 15 | branches: 16 | - main 17 | 18 | # Allows manual triggering of the workflow 19 | workflow_dispatch: 20 | 21 | jobs: 22 | build: 23 | runs-on: ubuntu-latest 24 | 25 | if: github.ref == 'refs/heads/main' 26 | 27 | steps: 28 | - name: Check out repository 29 | uses: actions/checkout@v3 30 | 31 | - name: Set up Python 3.12 32 | uses: actions/setup-python@v4 33 | with: 34 | python-version: '3.12' 35 | 36 | - name: Install Python dependencies 37 | run: | 38 | python -m venv venv 39 | source venv/bin/activate 40 | pip install --upgrade pip 41 | pip install -r scripts/requirements.txt 42 | 43 | - name: Run scripts 44 | run: | 45 | source venv/bin/activate 46 | python scripts/process.py 47 | 48 | - name: Configure Git 49 | run: | 50 | git config --global user.email "${{ env.CI_COMMIT_EMAIL }}" 51 | git config --global user.name "${{ env.CI_COMMIT_NAME }}" 52 | env: 53 | CI_COMMIT_NAME: "Automated commit" 54 | CI_COMMIT_EMAIL: "actions@users.noreply.github.com" 55 | 56 | - name: Commit and Push changes 57 | run: | 58 | git diff --quiet && echo "No changes to commit" || ( 59 | git add data && 60 | git commit -m "${{ env.CI_COMMIT_MESSAGE }}" && 61 | git push origin main 62 | ) 63 | env: 64 | CI_COMMIT_MESSAGE: "Automated commit" -------------------------------------------------------------------------------- /datapackage.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "geo-ne-admin1", 3 | "title": "GeoBoundaries Admin1 Polygons as GeoJSON", 4 | "version": "0.1.0", 5 | "description": "Polygons polygons for the largest administrative subdivisions in every countries", 6 | "repository": { 7 | "type": "git", 8 | "url": "git://github.com/datasets/geo-ne-admin1.git" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "geoBoundaries", 13 | "path": "https://github.com/wmgeolab/geoBoundaries/raw/main/releaseData/CGAZ/geoBoundariesCGAZ_ADM1.geojson", 14 | "title": "geoBoundaries" 15 | } 16 | ], 17 | "keywords": [ 18 | "geodata", 19 | "vector", 20 | "country" 21 | ], 22 | "licenses": [ 23 | { 24 | "name": "ODC-PDDL-1.0", 25 | "path": "http://opendatacommons.org/licenses/pddl/", 26 | "title": "Open Data Commons Public Domain Dedication and License v1.0" 27 | } 28 | ], 29 | "resources": [ 30 | { 31 | "name": "admin1", 32 | "path": "data/admin1.geojson", 33 | "format": "geojson", 34 | "mediatype": "application/json", 35 | "schema": { 36 | "fields": [ 37 | { 38 | "name": "geometry", 39 | "description": "The geometry of the feature, including coordinates and type", 40 | "type": "object" 41 | }, 42 | { 43 | "name": "properties", 44 | "description": "Additional information about the feature", 45 | "type": "object", 46 | "fields": [ 47 | { 48 | "name": "name", 49 | "description": "Common name of the zone", 50 | "type": "string" 51 | }, 52 | { 53 | "name": "id", 54 | "description": "Code for the zone inside the country", 55 | "type": "string" 56 | }, 57 | { 58 | "name": "country", 59 | "description": "Name of the country", 60 | "type": "string" 61 | }, 62 | { 63 | "name": "ISO3166-1-Alpha-3", 64 | "description": "3 characters code for the country, according to ISO3166 standard", 65 | "type": "string" 66 | } 67 | ] 68 | }, 69 | { 70 | "name": "type", 71 | "description": "The type of the feature, e.g., 'Feature'", 72 | "type": "string" 73 | } 74 | ] 75 | }, 76 | "foreignKeys": [ 77 | { 78 | "fields": "ISO3166-1-Alpha-3", 79 | "reference": { 80 | "datapackage": "https://github.com/datasets/country-codes/", 81 | "resource": "country-codes", 82 | "fields": "ISO3166-1-Alpha-3" 83 | } 84 | } 85 | ] 86 | } 87 | ], 88 | "homepage": "http://github.com/datasets/geo-ne-admin1", 89 | "collection": "geojson" 90 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | badge 2 | 3 | Geodata [data package][datapackage] providing geojson polygons for the largest administrative subdivisions in every countries. 4 | 5 | 6 | ## Data 7 | 8 | The data comes from [geoboundaries][geoboundaries], a community effort to make visually pleasing, well-crafted maps with cartography or GIS software at small scale. 9 | 10 | [Admin1][doc] is the biggest administrative subdivision of countries. Note that it is very heterogeneous among countries : in the United States 11 | of America, admin1 represents states, whereas they don't represent the inner countries in the United Kingdom. For more information, please see [official documentation][doc] 12 | or https://en.wikipedia.org/wiki/Table_of_administrative_divisions_by_country. 13 | 14 | The shape of the `admin1` data has the following fields: 15 | 16 | * **geometry**: 17 | Represents the spatial geometry of the administrative subdivision. It includes: 18 | - The type of geometry (e.g., `Polygon`, `MultiPolygon`). 19 | - The associated coordinates that define its boundaries. 20 | 21 | * **properties**: 22 | Contains metadata describing the administrative subdivision, with the following fields: 23 | - **name**: 24 | The common name for this `admin1` subdivision. 25 | - **id**: 26 | Code for the subdivision inside the country. [Documentation][doc] is not clear what this code is, but it could be FIPS. Note that some countries, like *Vatican*, are so small they don't have inner administrative subdivisions. In such cases, the code could be *null* and is irrelevant. 27 | - **country**: 28 | The name of the country where the subdivision is located. 29 | - **ISO3166-1-Alpha-3**: 30 | The three-letter ISO code of the country. 31 | 32 | * **type**: 33 | Specifies the type of the feature, typically `Feature` for each administrative subdivision. 34 | 35 | 36 | [geoboundaries]: https://www.geoboundaries.org/ 37 | [datapackage]: http://dataprotocols.org/data-packages/ 38 | [doc]: https://www.geoboundaries.org/simplifiedDownloads.html 39 | 40 | ## Preparation 41 | 42 | To run the script: 43 | 44 | ```bash 45 | # Install libraries 46 | pip install -r scripts/requirements.txt 47 | 48 | # Update the data 49 | python scripts/process.py 50 | ``` 51 | 52 | ## License 53 | 54 | All data is licensed under the [Open Data Commons Public Domain Dedication and License][pddl]. 55 | 56 | Note that the original data from [geoboundaries][geoboundaries] is public domain. While no credit is 57 | formally required a link back or credit to [geoboundaries][geoboundaries], [Lexman][lexman] and the [Open Knowledge Foundation][okfn] is much appreciated. 58 | 59 | All source code is licenced under the [MIT licence][mit]. 60 | 61 | [mit]: https://opensource.org/licenses/MIT 62 | [geoboundaries]: https://www.geoboundaries.org/ 63 | [pddl]: http://opendatacommons.org/licenses/pddl/1.0/ 64 | [lexman]: http://github.com/lexman 65 | [okfn]: http://okfn.org/ 66 | --------------------------------------------------------------------------------