{"id":18542175,"url":"https://github.com/heremaps/xyz-spaces-python","last_synced_at":"2025-04-09T18:31:35.412Z","repository":{"id":47639198,"uuid":"280392761","full_name":"heremaps/xyz-spaces-python","owner":"heremaps","description":"Manage your XYZ Hub or HERE Data Hub spaces from Python.","archived":false,"fork":false,"pushed_at":"2021-09-03T06:31:46.000Z","size":13571,"stargazers_count":32,"open_issues_count":0,"forks_count":11,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-03-24T10:21:17.368Z","etag":null,"topics":["client","data-hub","geojson","geospatial","geospatial-analysis","geospatial-database","jupyter-notebooks","python","search","xyz","xyz-hub"],"latest_commit_sha":null,"homepage":"https://xyz-spaces-python.readthedocs.io/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/heremaps.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-17T10:11:58.000Z","updated_at":"2025-01-28T12:23:55.000Z","dependencies_parsed_at":"2022-09-06T16:10:16.934Z","dependency_job_id":null,"html_url":"https://github.com/heremaps/xyz-spaces-python","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heremaps%2Fxyz-spaces-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heremaps%2Fxyz-spaces-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heremaps%2Fxyz-spaces-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heremaps%2Fxyz-spaces-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/heremaps","download_url":"https://codeload.github.com/heremaps/xyz-spaces-python/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248087758,"owners_count":21045585,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["client","data-hub","geojson","geospatial","geospatial-analysis","geospatial-database","jupyter-notebooks","python","search","xyz","xyz-hub"],"created_at":"2024-11-06T20:07:38.320Z","updated_at":"2025-04-09T18:31:30.402Z","avatar_url":"https://github.com/heremaps.png","language":"Python","readme":"# XYZ Spaces for Python\n\n[![Documentation Status](https://img.shields.io/readthedocs/xyz-spaces-python?logo=read-the-docs)](https://xyz-spaces-python.readthedocs.io/en/latest/?badge=latest)\n![Tests](https://github.com/heremaps/xyz-spaces-python/workflows/Tests/badge.svg)\n[![PyPI - Status](https://img.shields.io/pypi/status/xyzspaces)](https://pypi.org/project/xyzspaces/)\n[![PyPI - Python Version](https://img.shields.io/pypi/v/xyzspaces.svg?logo=pypi)](https://pypi.org/project/xyzspaces/)\n[![PyPI - Implementation](https://img.shields.io/pypi/implementation/xyzspaces)](https://pypi.org/project/xyzspaces/)\n[![Downloads](https://pepy.tech/badge/xyzspaces)](https://pepy.tech/project/xyzspaces)\n[![Conda (channel only)](https://img.shields.io/conda/vn/conda-forge/xyzspaces?logo=conda-forge)](https://anaconda.org/conda-forge/xyzspaces)\n[![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/xyzspaces)](https://anaconda.org/conda-forge/xyzspaces)\n[![PyPI - License](https://img.shields.io/pypi/l/xyzspaces)](https://pypi.org/project/xyzspaces/)\n[![LGTM alerts](https://img.shields.io/lgtm/alerts/g/heremaps/xyz-spaces-python.svg?logo=lgtm\u0026logoWidth=18)](https://lgtm.com/projects/g/heremaps/xyz-spaces-python/alerts/)\n[![LGTM context](https://img.shields.io/lgtm/grade/python/g/heremaps/xyz-spaces-python.svg?logo=lgtm\u0026logoWidth=18)](https://lgtm.com/projects/g/heremaps/xyz-spaces-python/context:python)\n[![Swagger Validator](https://img.shields.io/swagger/valid/3.0?specUrl=https%3A%2F%2Fxyz.api.here.com%2Fhub%2Fstatic%2Fopenapi%2Fstable.yaml)](https://xyz.api.here.com/hub/static/swagger/)\n[![GitHub contributors](https://img.shields.io/github/contributors/heremaps/xyz-spaces-python)](https://github.com/heremaps/xyz-spaces-python/graphs/contributors)\n[![Codecov](https://codecov.io/gh/heremaps/xyz-spaces-python/branch/master/graph/badge.svg)](https://codecov.io/gh/heremaps/xyz-spaces-python)\n[![Slack](https://img.shields.io/badge/heredev-datahub-00AFAA?logo=slack)](https://heredev.slack.com)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![commits since](https://img.shields.io/github/commits-since/heremaps/xyz-spaces-python/latest.svg)](https://github.com/heremaps/xyz-spaces-python/commits/master)\n[![Anaconda-Server Badge](https://anaconda.org/conda-forge/xyzspaces/badges/latest_release_date.svg)](https://anaconda.org/conda-forge/xyzspaces)\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/heremaps/xyz-spaces-python/master?urlpath=lab/tree/docs/notebooks)\n\nManage your [XYZ Hub](https://github.com/heremaps/xyz-hub) or [HERE Data Hub](https://developer.here.com/products/data-hub) spaces  and [Interactive Map Layer](https://developer.here.com/documentation/data-user-guide/user_guide/portal/layers/layers.html) from Python.\n\n\u003cb\u003eFEATURED IN: [Online Python Machine Learning Conference \u0026amp; GeoPython 2020](http://2020.geopython.net/), Sept 21, 2020, see [conference schedule](http://2020.geopython.net/schedule.html).\u003c/b\u003e\n\n\n## Motivation\n\nXYZ is an Open Source, real-time, cloud database system providing access to large geospatial data at scale. An XYZ \"Hub\" manages \"spaces\" that contain \"features\" (geodata \"records\") with tags and properties, with spaces and features having unique IDs. A RESTful API exists to provide low-level access to interact with a XYZ Hub.\n\nThis Python package allows to interact with your XYZ spaces and features on a given Hub using a higher level programmatic interface that wraps the RESTful API. Using this package you can:\n\n- Create, read, list, update, share, delete spaces (also: get space info and stats).\n- Add, read, update, iterate, search, cluster (hex/quad bins), delete features.\n- Search features by ID, tag, property, bbox, tile, radius, geometry.\n\nBased on the XYZ Hub the HERE Data Hub is a commercial service (with a free plan), that offers some additional features (in a pro plan), like clustering, virtual spaces, activity logs, and likely more to come.\n\nThe GIF below shows an interaction with an [example notebook](https://github.com/heremaps/xyz-spaces-python/blob/master/docs/notebooks/building_numbers.ipynb),\ndemonstrating how to use a spatial search on a big public dataset, loaded from the HERE [Data Hub](https://here.xyz).\n\n# ![Example from xyzspaces building_numbers.ipynb notebook](https://github.com/heremaps/xyz-spaces-python/raw/master/images/building_numbers.gif)\n\n\n## Prerequisites\n\nBefore you can install this package, run its test-suite or use the example notebooks to make sure your system meets the following prerequisities:\n\n- A Python installation, 3.7+ recommended, with the `pip` command available to install dependencies\n- A HERE developer account, free and available under [HERE Developer Portal](https://developer.here.com)\n- An XYZ API access token from your XYZ Hub server or the [XYZ portal](https://www.here.xyz) (see also its [Getting\n  Started](https://www.here.xyz/getting-started/) section) in an environment variable named `XYZ_TOKEN` which you can\n  set like this (with a valid value, of course):\n\n    ```bash\n    export XYZ_TOKEN=\"MY-FANCY-XYZ-TOKEN\"\n    ```\n\n    If you prefer, you can alternatively provide this token as a parameter in your code.\n\n## Installation\n\nThis package can be installed with `pip` or `conda` from various sources:\n\n- Install with conda from the Anaconda [conda-forge channel](https://anaconda.org/conda-forge/xyzspaces):\n\n    ```bash\n    conda install -c conda-forge xyzspaces\n    ```\n\n- Install from the [Python Package Index](https://pypi.org/project/xyzspaces/):\n\n    ```bash\n    pip install xyzspaces\n    ```\n\n- Install from the [Python Package Index](https://pypi.org/project/xyzspaces/) with optional dependencies:\n\n    ```bash\n    pip install \"xyzspaces[geo]\"\n    ```\n\n- Install from its source repository on GitHub:\n\n    ```bash\n    pip install -e git+https://github.com/heremaps/xyz-spaces-python#egg=xyzspaces\n    ```\n\nIf you want to run the test suite or experiment with the example notebooks bundled, you need to clone the whole repository:\n\n- Make a local clone of the repository hosting this package. The following command should do:\n\n    ```bash\n    git clone https://github.com/heremaps/xyz-spaces-python.git\n    ```\n\n- Change into the repo root directory:\n\n    ```bash\n    cd xyzspaces\n    ```\n  \n## Interactive Map Layers\nThe `xyzspaces` package supports Interactive Map Layers which is Data Hub on [HERE Platform](https://platform.here.com/).\nUsing `xyzspaces` you can interact with your Interactive Map Layers using higher level pythonic interface that wraps the RESTful API.\nWith Interactive Map Layers, data is stored in GeoJSON and can be retrieved dynamically at any zoom level. \nInteractive map layer is optimized for the visualization, analysis, and modification of data on a map (i.e., GIS functions).\n\nKey features of Interactive Map Layers include:\n- Creating and modifying maps manually or programmatically; edits are published real-time and require no additional interaction.\n- Modifying data a granular feature and feature property level.\n- Adding and removing points, lines, and polygons directly on a map.\n- Ability to retrieve data in different tiling schemes.\n- Exploring and retrieving data by feature ID, bounding box, spatial search, property search, and features contained within a tile.\n- Searching for data by values of feature properties (e.g., speed limits, type of place, address, name, etc.).\n- Data sampling, making it possible to efficiently render an excerpt of a very large data set for visual reference and analysis.\n- Clustering using hexbins or quadbins to produce rich, visual data representations.\n\n### Credentials\nTo interact with Interactive Map Layer you will need an account on the HERE Platform.\nTo get more details on the HERE Platform account please check our documentation [Get a HERE account](https://developer.here.com/documentation/identity-access-management/dev_guide/topics/obtain-user-credentials.html).\nOnce you have the account follow the below steps to get credentials:\n- Go to [HERE Platform Applications and Keys](https://platform.here.com/profile/apps-and-keys) and register a new app.\n- Create a key for the app and download the generated `credentials.properties` file.\n\nThe HERE platform generated app credentials should look similar to the example below:\n```\n  here.user.id = \u003cexample_here\u003e\n  here.client.id = \u003cexample_here\u003e\n  here.access.key.id = \u003cexample_here\u003e\n  here.access.key.secret = \u003cexample_here\u003e\n  here.token.endpoint.url = \u003cexample_here\u003e\n```\n\nYou can provide your credentials using any of the following methods:\n\n- Default credentials\n- Environment variables\n- Credentials file\n\n#### Default credentials\nPlace the credentials file into\n\nFor Linux/MacOS: `$HOME/.here/credentials.properties`\n\nFor Windows: `%USERPROFILE%\\.here\\credentials.properties`\n\n#### Environment Variables\n\nYou can override default credentials by assigning values to the following environment variables:\n```\nHERE_USER_ID\nHERE_CLIENT_ID\nHERE_ACCESS_KEY_ID\nHERE_ACCESS_KEY_SECRET\nHERE_TOKEN_ENDPOINT_URL\n```\n\n#### Credentials File\n\nYou can specify any credentials file as an alternative to that found in `~/.here/credentials.properties`. An error is generated if there is no file present at the path, or if the file is not properly formatted.\n\n  \n## Documentation\n\nDocumentation is hosted [here](https://xyz-spaces-python.readthedocs.io/en/latest/index.html).\n\nTo build the docs locally run:\n\n```bash\nbash scripts/build_docs.sh\n```\n\n### Hello World Example\n\nThe following are tiny \"Hello World\"-like examples that you can run to have a successful first XYZ experience right after installation!\n\n#### Data Hub\n```python\nimport geojson\nimport os\nimport xyzspaces\n\nos.environ[\"XYZ_TOKEN\"] = \"MY_XYZ_TOKEN\"\nxyz = xyzspaces.XYZ()\n\n# Create a New Space\ntitle = \"My Demo Space\"\ndescription = \"My Description\"\nspace = xyz.spaces.new(title=title, description=description)\n\n# Define a New Feature\nfeature =  {\n    \"type\": \"Feature\",\n    \"properties\": {\"party\": \"Republican\"},\n    \"geometry\": {\n        \"type\": \"Polygon\",\n        \"coordinates\": [[\n            [-104.05, 48.99],\n            [-97.22,  48.98],\n            [-96.58,  45.94],\n            [-104.03, 45.94],\n            [-104.05, 48.99]\n        ]]\n    }\n}\n\n# Save it to a Space and get its ID\nfeature_id = space.add_features(features=geojson.FeatureCollection([feature]))[\"features\"][0][\"id\"]\n\n# Read a Feature from a Space\nfeature = space.get_feature(feature_id=feature_id)\nprint(geojson.dumps(feature, indent=4, sort_keys=True))\n```\n#### Interactive Map Layer\n```python\nimport geojson\nfrom xyzspaces import IML\nfrom xyzspaces.iml.credentials import Credentials\n\ncredentials = Credentials.from_default() # credentials are in either credentials file at default location or in environment variables\n\nlayer_details = {\n    \"id\": \"demo-interactive-layer\",\n    \"name\": \"Demo Interactive Layer\",\n    \"summary\": \"Demo Interactive Layer\",\n    \"description\": \"Demo Interactive Layer\",\n    \"layerType\": \"interactivemap\",\n    \"interactiveMapProperties\": {},\n}\n\niml = IML.new(\n    catalog_id=\"demo-catalog1\",\n    catalog_name=\"demo-catalog\",\n    catalog_summary=\"Demo catalog\",\n    catalog_description=\"Demo catalog\",\n    layer_details=layer_details,\n    credentials=credentials,\n)\n\n# Define a New Feature\nfeature = {\n    \"type\": \"Feature\",\n    \"properties\": {\"party\": \"Republican\"},\n    \"geometry\": {\n        \"type\": \"Polygon\",\n        \"coordinates\": [\n            [\n                [-104.05, 48.99],\n                [-97.22, 48.98],\n                [-96.58, 45.94],\n                [-104.03, 45.94],\n                [-104.05, 48.99],\n            ]\n        ],\n    },\n}\n# Save feature to interactive map layer\niml.layer.write_feature(feature_id=\"demo_feature\", data=feature)\n\n# Read feature from nteractive map layer\nresp = iml.layer.get_feature(feature_id=\"demo_feature\")\nprint(geojson.dumps(resp.to_geojson(), indent=4, sort_keys=True))\n```\n\n\n# License\n\nCopyright (C) 2019-2021 HERE Europe B.V.\n\nUnless otherwise noted in `LICENSE` files for specific directories, the [LICENSE](https://github.com/heremaps/xyz-spaces-python/blob/master/LICENSE) in the root applies to all content in this repository.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fheremaps%2Fxyz-spaces-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fheremaps%2Fxyz-spaces-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fheremaps%2Fxyz-spaces-python/lists"}