diff --git a/pygmt/helpers/tempfile.py b/pygmt/helpers/tempfile.py index 3cbb88060df..17d90be6935 100644 --- a/pygmt/helpers/tempfile.py +++ b/pygmt/helpers/tempfile.py @@ -2,12 +2,14 @@ Utilities for dealing with temporary file management. """ +import io import uuid from contextlib import contextmanager from pathlib import Path from tempfile import NamedTemporaryFile import numpy as np +from packaging.version import Version def unique_name(): @@ -139,29 +141,33 @@ 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: # 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(filename=io.StringIO(jsontext)).to_file(**ogrgmt_kwargs) yield tmpfile.name