I'm trying to split a GeoJSON polygon which crosses the antimeridian. I use this solution as base gdal.VectorTranslate returns an empty file
My code is:
geojson_str = <some geojson string>
geojson = json.loads(gjstr)
print('Original GeoJSON:')
print(json.dumps(geojson, indent=2))
with open('in.geojson','w') as f:
json.dump(geojson, f)
gdal.UseExceptions()
g = gdal.OpenEx('in.geojson')
out = gdal.VectorTranslate('./out.geojson', g, format = 'GeoJSON', layerCreationOptions = ["-wrapdateline", '-lco','RFC7946=YES'])
del out
geojson_transformed = json.load(open('./out.geojson'))
print('Transformed GeoJSON:')
print(json.dumps(geojson_transformed, indent=2))
The issue is that gdal.VectorTranslate() has indeterministic behaviuor on different input.
If I use GeoJSON from example, it splits polygon into multipolygon correctly:
Original GeoJSON:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
172.56933593749997,
61.58549218152362
],
[
186.0205078125,
61.58549218152362
],
[
186.0205078125,
66.00015035652659
],
[
172.56933593749997,
66.00015035652659
],
[
172.56933593749997,
61.58549218152362
]
]
]
}
}
]
}
Transformed GeoJSON:
{
"type": "FeatureCollection",
"name": "in",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
180.0,
61.5854922
],
[
180.0,
66.0001504
],
[
172.5693359,
66.0001504
],
[
172.5693359,
61.5854922
],
[
180.0,
61.5854922
]
]
],
[
[
[
-180.0,
66.0001504
],
[
-180.0,
61.5854922
],
[
-173.9794922,
61.5854922
],
[
-173.9794922,
66.0001504
],
[
-180.0,
66.0001504
]
]
]
]
}
}
]
}
The example input contains shifted coordinates, where all negative longitudes incresed by 360. The output contains non-shifted coordinates though.
If I try to convert the example coordinates to be non-shifted, gdal.VectorTranslate() doesn't split the polygon:
Original GeoJSON:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
172.56933593749997,
61.58549218152362
],
[
-173.9794921875,
61.58549218152362
],
[
-173.9794921875,
66.00015035652659
],
[
172.56933593749997,
66.00015035652659
],
[
172.56933593749997,
61.58549218152362
]
]
]
}
}
]
}
Transformed GeoJSON:
{
"type": "FeatureCollection",
"name": "in",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
172.5693359,
61.5854922
],
[
172.5693359,
66.0001504
],
[
-173.9794922,
66.0001504
],
[
-173.9794922,
61.5854922
],
[
172.5693359,
61.5854922
]
]
]
}
}
]
}
So I can assume that dateline splitting is being performed only if coordinates are centered at longitude 180 (or -180).
Nevertheless when I try to use it on my custom Geojson with shifted coords, then gdal.VectorTranslate() fails to complete:
Original GeoJSON:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
182.24833333333333,
61.336666666666666
],
[
179,
60.0
],
[
169.0,
54.0
],
[
158.9961111111111,
50.10194444444445
],
[
157.8,
52.25
],
[
157.5361111111111,
53.325833333333335
],
[
158.18333333333334,
53.79666666666667
],
[
156.75,
55.45
],
[
153.9897222222222,
58.01416666666667
],
[
155.9,
58.86666666666667
],
[
160.16666666666666,
60.583333333333336
],
[
162.21666666666667,
61.43333333333333
],
[
164.25,
62.083333333333336
],
[
174.75,
61.833333333333336
],
[
182.24833333333333,
61.336666666666666
]
]
]
},
"properties": {
"designator": "UHPP",
"color": "gray"
}
}
]
}
RuntimeError Traceback (most recent call last)
<ipython-input-218-e81a49bf4254> in <module>()
33 gdal.UseExceptions()
34 g = gdal.OpenEx('in.geojson')
---> 35 out = gdal.VectorTranslate('./out.geojson', g, format = 'GeoJSON', layerCreationOptions = ["-wrapdateline", '-lco','RFC7946=YES'])
36 del out
37 geojson_transformed = json.load(open('./out.geojson'))
1 frames
/usr/lib/python3/dist-packages/osgeo/gdal.py in wrapper_GDALVectorTranslateDestName(args)
3139 def wrapper_GDALVectorTranslateDestName(args):
3140 """wrapper_GDALVectorTranslateDestName(char const * dest, Dataset srcDS, GDALVectorTranslateOptions options, GDALProgressFunc callback=0, void * callback_data=None) -> Dataset"""
-> 3141 return _gdal.wrapper_GDALVectorTranslateDestName(*args)
3142 class GDALDEMProcessingOptions(_object):
3143 """Proxy of C++ GDALDEMProcessingOptions class."""
RuntimeError: Terminating translation prematurely after failed
translation of layer in (use -skipfailures to skip errors)
If I use non-shifted coordintates in GeoJSON input, gdal.VectorTranslate() doesn't fail, but produce untransformed result:
Original GeoJSON:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-177.75166666666667,
61.336666666666666
],
[
179,
60.0
],
[
169.0,
54.0
],
[
158.9961111111111,
50.10194444444445
],
[
157.8,
52.25
],
[
157.5361111111111,
53.325833333333335
],
[
158.18333333333334,
53.79666666666667
],
[
156.75,
55.45
],
[
153.9897222222222,
58.01416666666667
],
[
155.9,
58.86666666666667
],
[
160.16666666666666,
60.583333333333336
],
[
162.21666666666667,
61.43333333333333
],
[
164.25,
62.083333333333336
],
[
174.75,
61.833333333333336
],
[
-177.75166666666667,
61.336666666666666
]
]
]
},
"properties": {
"designator": "UHPP",
"color": "gray"
}
}
]
}
Transformed GeoJSON:
{
"type": "FeatureCollection",
"name": "in",
"features": [
{
"type": "Feature",
"properties": {
"designator": "UHPP",
"color": "gray"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-177.7516667,
61.3366667
],
[
174.75,
61.8333333
],
[
164.25,
62.0833333
],
[
162.2166667,
61.4333333
],
[
160.1666667,
60.5833333
],
[
155.9,
58.8666667
],
[
153.9897222,
58.0141667
],
[
156.75,
55.45
],
[
158.1833333,
53.7966667
],
[
157.5361111,
53.3258333
],
[
157.8,
52.25
],
[
158.9961111,
50.1019444
],
[
169.0,
54.0
],
[
179.0,
60.0
],
[
-177.7516667,
61.3366667
]
]
]
}
}
]
}
Is it possible to determine why gdal.VectorTranslate() fails on the third input?
Are there other reliable and precise solutions to split polygons around antimeridian? I tried geopandas-based solution from here GDAL VectorTranslate creates shards/fragments along anti-meridian, but it doesn't seem to work.
Any geometry that crosses the antimeridian SHOULD be represented by cutting it in two such that neither part's representation crosses the antimeridian.. – user30184 Oct 15 '20 at 21:33