{"id":31531510,"url":"https://github.com/hyriver/pygeoutils","last_synced_at":"2025-12-12T01:04:25.887Z","repository":{"id":38020817,"uuid":"280799061","full_name":"hyriver/pygeoutils","owner":"hyriver","description":"A part of HyRiver software stack for handling geospatial data manipulations","archived":false,"fork":false,"pushed_at":"2025-06-25T20:11:14.000Z","size":661,"stargazers_count":8,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-04T23:53:40.611Z","etag":null,"topics":["geodata","geospatial","hydrology","python","webservices"],"latest_commit_sha":null,"homepage":"https://docs.hyriver.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hyriver.png","metadata":{"files":{"readme":"README.rst","changelog":"HISTORY.rst","contributing":"CONTRIBUTING.rst","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.rst","threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.rst","dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["cheginit"]}},"created_at":"2020-07-19T05:33:05.000Z","updated_at":"2025-06-25T20:11:19.000Z","dependencies_parsed_at":"2024-01-17T09:22:39.832Z","dependency_job_id":"5ee217ec-84a3-4aa4-b67f-d0576e2155af","html_url":"https://github.com/hyriver/pygeoutils","commit_stats":{"total_commits":849,"total_committers":4,"mean_commits":212.25,"dds":"0.14605418138987047","last_synced_commit":"510991011084c2140c6bb6b7986c8fc727106d98"},"previous_names":["cheginit/pygeoutils"],"tags_count":51,"template":false,"template_full_name":null,"purl":"pkg:github/hyriver/pygeoutils","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyriver%2Fpygeoutils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyriver%2Fpygeoutils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyriver%2Fpygeoutils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyriver%2Fpygeoutils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hyriver","download_url":"https://codeload.github.com/hyriver/pygeoutils/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyriver%2Fpygeoutils/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278254466,"owners_count":25956604,"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","status":"online","status_checked_at":"2025-10-04T02:00:05.491Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["geodata","geospatial","hydrology","python","webservices"],"created_at":"2025-10-04T02:12:59.620Z","updated_at":"2025-10-04T02:13:00.834Z","avatar_url":"https://github.com/hyriver.png","language":"Python","funding_links":["https://github.com/sponsors/cheginit"],"categories":[],"sub_categories":[],"readme":".. image:: https://raw.githubusercontent.com/hyriver/HyRiver-examples/main/notebooks/_static/pygeoutils_logo.png\n    :target: https://github.com/hyriver/HyRiver\n\n|\n\n.. image:: https://joss.theoj.org/papers/b0df2f6192f0a18b9e622a3edff52e77/status.svg\n    :target: https://joss.theoj.org/papers/b0df2f6192f0a18b9e622a3edff52e77\n    :alt: JOSS\n\n|\n\n.. |pygeohydro| image:: https://github.com/hyriver/pygeohydro/actions/workflows/test.yml/badge.svg\n    :target: https://github.com/hyriver/pygeohydro/actions/workflows/test.yml\n    :alt: Github Actions\n\n.. |pygeoogc| image:: https://github.com/hyriver/pygeoogc/actions/workflows/test.yml/badge.svg\n    :target: https://github.com/hyriver/pygeoogc/actions/workflows/test.yml\n    :alt: Github Actions\n\n.. |pygeoutils| image:: https://github.com/hyriver/pygeoutils/actions/workflows/test.yml/badge.svg\n    :target: https://github.com/hyriver/pygeoutils/actions/workflows/test.yml\n    :alt: Github Actions\n\n.. |pynhd| image:: https://github.com/hyriver/pynhd/actions/workflows/test.yml/badge.svg\n    :target: https://github.com/hyriver/pynhd/actions/workflows/test.yml\n    :alt: Github Actions\n\n.. |py3dep| image:: https://github.com/hyriver/py3dep/actions/workflows/test.yml/badge.svg\n    :target: https://github.com/hyriver/py3dep/actions/workflows/test.yml\n    :alt: Github Actions\n\n.. |pydaymet| image:: https://github.com/hyriver/pydaymet/actions/workflows/test.yml/badge.svg\n    :target: https://github.com/hyriver/pydaymet/actions/workflows/test.yml\n    :alt: Github Actions\n\n.. |pygridmet| image:: https://github.com/hyriver/pygridmet/actions/workflows/test.yml/badge.svg\n    :target: https://github.com/hyriver/pygridmet/actions/workflows/test.yml\n    :alt: Github Actions\n\n.. |pynldas2| image:: https://github.com/hyriver/pynldas2/actions/workflows/test.yml/badge.svg\n    :target: https://github.com/hyriver/pynldas2/actions/workflows/test.yml\n    :alt: Github Actions\n\n.. |async| image:: https://github.com/hyriver/async-retriever/actions/workflows/test.yml/badge.svg\n    :target: https://github.com/hyriver/async-retriever/actions/workflows/test.yml\n    :alt: Github Actions\n\n.. |signatures| image:: https://github.com/hyriver/hydrosignatures/actions/workflows/test.yml/badge.svg\n    :target: https://github.com/hyriver/hydrosignatures/actions/workflows/test.yml\n    :alt: Github Actions\n\n================ ====================================================================\nPackage          Description\n================ ====================================================================\nPyNHD_           Navigate and subset NHDPlus (MR and HR) using web services\nPy3DEP_          Access topographic data through National Map's 3DEP web service\nPyGeoHydro_      Access NWIS, NID, WQP, eHydro, NLCD, CAMELS, and SSEBop databases\nPyDaymet_        Access daily, monthly, and annual climate data via Daymet\nPyGridMET_       Access daily climate data via GridMET\nPyNLDAS2_        Access hourly NLDAS-2 data via web services\nHydroSignatures_ A collection of tools for computing hydrological signatures\nAsyncRetriever_  High-level API for asynchronous requests with persistent caching\nPyGeoOGC_        Send queries to any ArcGIS RESTful-, WMS-, and WFS-based services\nPyGeoUtils_      Utilities for manipulating geospatial, (Geo)JSON, and (Geo)TIFF data\n================ ====================================================================\n\n.. _PyGeoHydro: https://github.com/hyriver/pygeohydro\n.. _AsyncRetriever: https://github.com/hyriver/async-retriever\n.. _PyGeoOGC: https://github.com/hyriver/pygeoogc\n.. _PyGeoUtils: https://github.com/hyriver/pygeoutils\n.. _PyNHD: https://github.com/hyriver/pynhd\n.. _Py3DEP: https://github.com/hyriver/py3dep\n.. _PyDaymet: https://github.com/hyriver/pydaymet\n.. _PyGridMET: https://github.com/hyriver/pygridmet\n.. _PyNLDAS2: https://github.com/hyriver/pynldas2\n.. _HydroSignatures: https://github.com/hyriver/hydrosignatures\n\nPyGeoUtils: Utilities for (Geo)JSON and (Geo)TIFF Conversion\n------------------------------------------------------------\n\n.. image:: https://img.shields.io/pypi/v/pygeoutils.svg\n    :target: https://pypi.python.org/pypi/pygeoutils\n    :alt: PyPi\n\n.. image:: https://img.shields.io/conda/vn/conda-forge/pygeoutils.svg\n    :target: https://anaconda.org/conda-forge/pygeoutils\n    :alt: Conda Version\n\n.. image:: https://codecov.io/gh/hyriver/pygeoutils/branch/main/graph/badge.svg\n    :target: https://codecov.io/gh/hyriver/pygeoutils\n    :alt: CodeCov\n\n.. image:: https://img.shields.io/pypi/pyversions/pygeoutils.svg\n    :target: https://pypi.python.org/pypi/pygeoutils\n    :alt: Python Versions\n\n.. image:: https://static.pepy.tech/badge/pygeoutils\n    :target: https://pepy.tech/project/pygeoutils\n    :alt: Downloads\n\n|\n\n.. image:: https://www.codefactor.io/repository/github/hyriver/pygeoutils/badge\n   :target: https://www.codefactor.io/repository/github/hyriver/pygeoutils\n   :alt: CodeFactor\n\n.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\n    :target: https://github.com/astral-sh/ruff\n    :alt: Ruff\n\n.. image:: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit\u0026logoColor=white\n    :target: https://github.com/pre-commit/pre-commit\n    :alt: pre-commit\n\n.. image:: https://mybinder.org/badge_logo.svg\n    :target: https://mybinder.org/v2/gh/hyriver/HyRiver-examples/main?urlpath=lab/tree/notebooks\n    :alt: Binder\n\n|\n\nFeatures\n--------\n\nPyGeoUtils is a part of `HyRiver \u003chttps://github.com/hyriver/HyRiver\u003e`__ software stack that\nis designed to aid in hydroclimate analysis through web services. This package provides\nutilities for manipulating (Geo)JSON and (Geo)TIFF responses from web services.\nThese utilities are:\n\n- ``Coordinates``: Generate validated and normalized coordinates in WGS84.\n- ``GeoBSpline``: Create B-spline from a ``geopandas.GeoDataFrame`` of points.\n- ``smooth_linestring``: Smooth a ``shapely.geometry.LineString`` using B-spline.\n- ``bspline_curvature``: Compute tangent angles, curvature, and radius of curvature\n  of a B-Spline at any points along the curve.\n- ``arcgis2geojson``: Convert ESRIGeoJSON format to GeoJSON.\n- ``break_lines``: Break lines at specified points in a given direction.\n- ``gtiff2xarray``: Convert (Geo)Tiff byte responses to ``xarray.Dataset``.\n- ``json2geodf``: Create ``geopandas.GeoDataFrame`` from (Geo)JSON responses\n- ``snap2nearest``: Find the nearest points on a line to a set of points.\n- ``xarray2geodf``: Vectorize a ``xarray.DataArray`` to a ``geopandas.GeoDataFrame``.\n- ``geodf2xarray``: Rasterize a ``geopandas.GeoDataFrame`` to a ``xarray.DataArray``.\n- ``xarray_geomask``: Mask a ``xarray.Dataset`` based on a geometry.\n- ``query_indices``: A wrapper around\n  ``geopandas.sindex.query_bulk``. However, instead of returning an array of\n  positional indices, it returns a dictionary of indices where keys are the\n  indices of the input geometry and values are a list of indices of the\n  tree geometries that intersect with the input geometry.\n- ``nested_polygons``: Determining nested (multi)polygons in a\n  ``geopandas.GeoDataFrame``.\n- ``multi2poly``: For converting a ``MultiPolygon`` to a ``Polygon``\n  in a ``geopandas.GeoDataFrame``.\n- ``geometry_reproject``: For reprojecting a geometry\n  (bounding box, list of coordinates, or any ``shapely.geometry``) to\n  a new CRS.\n- ``gtiff2vrt``: For converting a list of GeoTIFF files to a VRT file.\n- ``sample_window``: Sample a raster dataset at specified coordinates\n  using a window size and a ``rasterio`` supported resampling method.\n  This is an efficient way of sampling large raster datasets without\n  reading the entire dataset into memory. The function returns a generator\n  that yields the sampled values in the order of the input coordinates.\n\nYou can find some example notebooks `here \u003chttps://github.com/hyriver/HyRiver-examples\u003e`__.\n\nYou can also try using PyGeoUtils without installing\nit on your system by clicking on the binder badge. A Jupyter Lab\ninstance with the HyRiver stack pre-installed will be launched in your web browser, and you\ncan start coding!\n\nMoreover, requests for additional functionalities can be submitted via\n`issue tracker \u003chttps://github.com/hyriver/pygeoutils/issues\u003e`__.\n\nCitation\n--------\nIf you use any of HyRiver packages in your research, we appreciate citations:\n\n.. code-block:: bibtex\n\n    @article{Chegini_2021,\n        author = {Chegini, Taher and Li, Hong-Yi and Leung, L. Ruby},\n        doi = {10.21105/joss.03175},\n        journal = {Journal of Open Source Software},\n        month = {10},\n        number = {66},\n        pages = {1--3},\n        title = {{HyRiver: Hydroclimate Data Retriever}},\n        volume = {6},\n        year = {2021}\n    }\n\nInstallation\n------------\n\nYou can install PyGeoUtils using ``pip`` after installing ``libgdal`` on your system\n(for example, in Ubuntu run ``sudo apt install libgdal-dev``).\n\n.. code-block:: console\n\n    $ pip install pygeoutils\n\nAlternatively, PyGeoUtils can be installed from the ``conda-forge`` repository\nusing `Conda \u003chttps://docs.conda.io/en/latest/\u003e`__:\n\n.. code-block:: console\n\n    $ conda install -c conda-forge pygeoutils\n\nQuick start\n-----------\n\nWe start by smoothing a ``shapely.geometry.LineString`` using B-spline:\n\n.. code-block:: python\n\n    import pygeoutils as pgu\n    from shapely import LineString\n\n    line = LineString(\n        [\n            (-97.06138, 32.837),\n            (-97.06133, 32.836),\n            (-97.06124, 32.834),\n            (-97.06127, 32.832),\n        ]\n    )\n    line = pgu.geometry_reproject(line, 4326, 5070)\n    sp = pgu.smooth_linestring(line, 5070, 5)\n    line_sp = pgu.geometry_reproject(sp.line, 5070, 4326)\n\nNext, we use\n`PyGeoOGC \u003chttps://github.com/hyriver/pygeoogc\u003e`__ to access\n`National Wetlands Inventory \u003chttps://www.fws.gov/wetlands/\u003e`__ from WMS, and\n`FEMA National Flood Hazard \u003chttps://www.fema.gov/national-flood-hazard-layer-nfhl\u003e`__\nvia WFS, then convert the output to ``xarray.Dataset`` and ``GeoDataFrame``, respectively.\n\n.. code-block:: python\n\n    from pygeoogc import WFS, WMS, ServiceURL\n    from shapely.geometry import Polygon\n\n\n    geometry = Polygon(\n        [\n            [-118.72, 34.118],\n            [-118.31, 34.118],\n            [-118.31, 34.518],\n            [-118.72, 34.518],\n            [-118.72, 34.118],\n        ]\n    )\n    crs = 4326\n\n    wms = WMS(\n        ServiceURL().wms.mrlc,\n        layers=\"NLCD_2011_Tree_Canopy_L48\",\n        outformat=\"image/geotiff\",\n        crs=crs,\n    )\n    r_dict = wms.getmap_bybox(\n        geometry.bounds,\n        1e3,\n        box_crs=crs,\n    )\n    canopy = pgu.gtiff2xarray(r_dict, geometry, crs)\n\n    mask = canopy \u003e 60\n    canopy_gdf = pgu.xarray2geodf(canopy, \"float32\", mask)\n\n    url_wfs = \"https://hazards.fema.gov/gis/nfhl/services/public/NFHL/MapServer/WFSServer\"\n    wfs = WFS(\n        url_wfs,\n        layer=\"public_NFHL:Base_Flood_Elevations\",\n        outformat=\"esrigeojson\",\n        crs=4269,\n    )\n    r = wfs.getfeature_bybox(geometry.bounds, box_crs=crs)\n    flood = pgu.json2geodf(r.json(), 4269, crs)\n\nContributing\n------------\n\nContributions are very welcomed. Please read\n`CONTRIBUTING.rst \u003chttps://github.com/hyriver/pygeoogc/blob/main/CONTRIBUTING.rst\u003e`__\nfile for instructions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyriver%2Fpygeoutils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhyriver%2Fpygeoutils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyriver%2Fpygeoutils/lists"}