From ba9433c1c14c60164424129a75422c09dbb8be02 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Mon, 13 May 2024 07:49:15 +0800 Subject: [PATCH 1/2] geopandas: Use io.StringIO to deal with geojson data, instead of replying on fiona --- pygmt/helpers/tempfile.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/pygmt/helpers/tempfile.py b/pygmt/helpers/tempfile.py index 3cbb88060df..6f470bcb465 100644 --- a/pygmt/helpers/tempfile.py +++ b/pygmt/helpers/tempfile.py @@ -2,6 +2,7 @@ Utilities for dealing with temporary file management. """ +import io import uuid from contextlib import contextmanager from pathlib import Path @@ -154,14 +155,8 @@ def tempfile_from_geojson(geojson): # Other 'geo' formats which implement __geo_interface__ import json - import fiona - - with fiona.Env(): - jsontext = json.dumps(geojson.__geo_interface__) - # Do Input/Output via Fiona virtual memory - with fiona.io.MemoryFile(file_or_bytes=jsontext.encode()) as memfile: - geoseries = gpd.GeoSeries.from_file(filename=memfile) - geoseries.to_file(**ogrgmt_kwargs) + jsontext = json.dumps(geojson.__geo_interface__) + gpd.read_file(io.StringIO(jsontext)).to_file(**ogrgmt_kwargs) yield tmpfile.name From 2fb635bbf3fb3f92d88105875c62b02507a3f958 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Tue, 14 May 2024 20:01:37 +0800 Subject: [PATCH 2/2] Deal with compatibility with both geopandas v0.x and v1.x --- pygmt/helpers/tempfile.py | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/pygmt/helpers/tempfile.py b/pygmt/helpers/tempfile.py index 6f470bcb465..17d90be6935 100644 --- a/pygmt/helpers/tempfile.py +++ b/pygmt/helpers/tempfile.py @@ -9,6 +9,7 @@ from tempfile import NamedTemporaryFile import numpy as np +from packaging.version import Version def unique_name(): @@ -140,15 +141,25 @@ def tempfile_from_geojson(geojson): # 32-bit integer overflow issue. Related issues: # https://github.com/geopandas/geopandas/issues/967#issuecomment-842877704 # https://github.com/GenericMappingTools/pygmt/issues/2497 - if geojson.index.name is None: - geojson.index.name = "index" - geojson = geojson.reset_index(drop=False) - schema = gpd.io.file.infer_schema(geojson) - for col, dtype in schema["properties"].items(): - if dtype in ("int", "int64"): - overflow = geojson[col].abs().max() > 2**31 - 1 - schema["properties"][col] = "float" if overflow else "int32" - ogrgmt_kwargs["schema"] = schema + if Version(gpd.__version__).major < 1: # GeoPandas v0.x + # The default engine 'fiona' supports the 'schema' parameter. + if geojson.index.name is None: + geojson.index.name = "index" + geojson = geojson.reset_index(drop=False) + schema = gpd.io.file.infer_schema(geojson) + for col, dtype in schema["properties"].items(): + if dtype in ("int", "int64"): + overflow = geojson[col].abs().max() > 2**31 - 1 + schema["properties"][col] = "float" if overflow else "int32" + ogrgmt_kwargs["schema"] = schema + else: # GeoPandas v1.x. + # The default engine "pyogrio" doesn't support the 'schema' parameter + # but we can change the dtype directly. + for col in geojson.columns: + if geojson[col].dtype in ("int", "int64", "Int64"): + overflow = geojson[col].abs().max() > 2**31 - 1 + dtype = "float" if overflow else "int32" + geojson[col] = geojson[col].astype(dtype) # Using geopandas.to_file to directly export to OGR_GMT format geojson.to_file(**ogrgmt_kwargs) except AttributeError: @@ -156,7 +167,7 @@ def tempfile_from_geojson(geojson): import json jsontext = json.dumps(geojson.__geo_interface__) - gpd.read_file(io.StringIO(jsontext)).to_file(**ogrgmt_kwargs) + gpd.read_file(filename=io.StringIO(jsontext)).to_file(**ogrgmt_kwargs) yield tmpfile.name