Reputation: 138
I have a Polygons such as "Jumeirah Islands Clusters" as shown in fig. I want to subtract lake 1, lake 2 GeoJson files from the Islands Cluster. I tried below solution but it is not working to create a final Polygon.
I tried it twice to get the desired result but the output shown is not desired as the lake 2 is not subtracted in the final step.
from shapely.geometry import Polygon, mapping
with open("file_polygon_1.geojson") as f:
feature = json.load(f)
if feature["geometry"]["type"] == "Polygon":
polygon_1 = Polygon([(coor[0], coor[1]) for coor in feature["geometry"]["coordinates"][0]])
with open("file_polygon_2.geojson") as f:
feature_2 = json.load(f)
if feature_2["geometry"]["type"] == "Polygon":
polygon_2 = Polygon([(coor[0], coor[1]) for coor in feature_2["geometry"]["coordinates"][0]])
new_geometry = mapping(polygon_2.difference(polygon_1))
new_feature = dict(type="Feature",id="",properties=dict(Name=""), geometry=dict(type=new_geometry["type"], coordinates=new_geometry["coordinates"]),
)
outjson = dict(type="FeatureCollection", features=[new_feature])
Upvotes: 0
Views: 1045
Reputation: 1271
I think you might be confusing how the difference
method/function works. Since I don't have access to your GeoJSON files, I can't really give you a precise answer, so the best I can do is give you an example using my own shapely features:
import shapely
lake1 = shapely.geometry.Polygon([(0,0),(0,3),(3,3),(3,0)])
lake2 = shapely.geometry.Polygon([(2,2),(2,5),(5,5),(5,2)])
islands = shapely.geometry.Polygon([(1,1),(1,4),(4,4),(4,1)])
The code above will create three different shapely geometries as illustrated below:
If you want to generate a final geometry that results in the islands minus the lakes, you can do it in two different ways.
Using set terminology, we can say:
Islands_Minus_Lakes = Islands - Lake1 - Lake2
which is equivalent to:
Islands_Minus_Lakes = Islands - (Lake1 + Lake2)
In python, you can write both of these as follows:
# Version 1
islands_minus_lakes = (islands.difference(lake1)).difference(lake2)
# Version 2
islands_minus_lakes = (islands.difference(lake1.union(lake2)))
Both approaches yield the exact same results:
Once you have that islands_minus_lakes
object, you can choose to manipulate it however you want.
In case you're wondering, I used the matplotlib
and geopandas
libraries to plot my results:
import geopandas as gpd
# Creating GeoDataFrames for the plots
gdf = gpd.GeoDataFrame({'name':['lake1','lake2','islands'],
'geometry':[lake1,lake2,islands]})
gdf2 = gpd.GeoDataFrame({'name':['islands_minus_lakes'],
'geometry':[islands_minus_lakes]})
# Generates the plot of the inputs
gdf.plot(alpha=0.4)
# Generates the plot of the outputs
gdf2.plot(alpha=0.4)
Upvotes: 1