Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: fix write of kml lon/lat transpose #421

Merged
merged 21 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion pyogrio/_io.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -2134,6 +2134,10 @@ cdef create_ogr_dataset_layer(
if crs is not None:
try:
ogr_crs = create_crs(crs)
# force geographic CRS to use lon, lat order and ignore axis order specified by CRS, in order
# to correctly write KML and GeoJSON coordinates in correct order
OSRSetAxisMappingStrategy(ogr_crs, OAMS_TRADITIONAL_GIS_ORDER)


except Exception as exc:
if dataset_options != NULL:
Expand Down Expand Up @@ -2735,4 +2739,4 @@ cdef create_fields_from_arrow_schema(
f"Error while creating field from Arrow for field {i} with name "
f"'{get_string(child.name)}' and type {get_string(child.format)}"
f"{gdal_msg}."
)
)
5 changes: 4 additions & 1 deletion pyogrio/_ogr.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,10 @@ cdef extern from "ogr_srs_api.h":
const char* OSRGetAuthorityName(OGRSpatialReferenceH srs, const char *key)
const char* OSRGetAuthorityCode(OGRSpatialReferenceH srs, const char *key)
OGRErr OSRImportFromEPSG(OGRSpatialReferenceH srs, int code)

ctypedef enum OSRAxisMappingStrategy:
OAMS_TRADITIONAL_GIS_ORDER

void OSRSetAxisMappingStrategy(OGRSpatialReferenceH hSRS, OSRAxisMappingStrategy)
int OSRSetFromUserInput(OGRSpatialReferenceH srs, const char *pszDef)
void OSRSetPROJSearchPaths(const char *const *paths)
OGRSpatialReferenceH OSRNewSpatialReference(const char *wkt)
Expand Down
32 changes: 32 additions & 0 deletions pyogrio/tests/test_geopandas_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -2067,3 +2067,35 @@ def test_non_utf8_encoding_shapefile_sql(tmp_path, use_arrow):
)
assert actual.columns[0] == mandarin
assert actual[mandarin].values[0] == mandarin


def test_write_kml_file_coordinate_order(tmp_path, use_arrow):
nicholas-ys-tan marked this conversation as resolved.
Show resolved Hide resolved
# confirm KML coordinates are written in lon, lat order even if CRS axis specifies otherwise
points = [Point(10, 20), Point(30, 40), Point(50, 60)]
gdf = gp.GeoDataFrame(geometry=points, crs="EPSG:4326")
output_path = tmp_path / "test.kml"
write_dataframe(
gdf, output_path, layer="tmp_layer", driver="KML", use_arrow=use_arrow
)

gdf_in = read_dataframe(output_path, use_arrow=use_arrow)

assert np.array_equal(gdf_in.geometry.values, points)


def test_write_geojson_rfc7946_coordinates(tmp_path, use_arrow=use_arrow):
nicholas-ys-tan marked this conversation as resolved.
Show resolved Hide resolved
points = [Point(10, 20), Point(30, 40), Point(50, 60)]
gdf = gp.GeoDataFrame(geometry=points, crs="EPSG:4326")
output_path = tmp_path / "test.geojson"
write_dataframe(
gdf,
output_path,
layer="tmp_layer",
driver="GeoJSON",
RFC7946=True,
use_arrow=use_arrow,
)

gdf_in = read_dataframe(output_path, use_arrow=use_arrow)

assert np.array_equal(gdf_in.geometry.values, points)
Loading