I am trying to convert geometry from type: LineString into type:Polygon where each line of data is a list of coordinates and at the same time I am trying to add 2 miles radius for each coordinates within list as buffer and output should be polygons. Please see sample data as below:
{
"type": "FeatureCollection",
"name": "Sample_lines",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "OBJECTID": 123, "GLOBAL_ID": "8CAB8A", "IDENT": "41", "TYPE": "N", "Shape__Length": 0.2733 }, "geometry": { "type": "LineString", "coordinates": [ [ -112.400011882673994, 41.0833390325461, 0.0 ], [ -112.56667894652, 41.300005042600802, 0.0 ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": 124, "GLOBAL_ID": "9ACAVB", "IDENT": "45", "TYPE": "N", "Shape__Length": 0.1573 }, "geometry": { "type": "LineString", "coordinates": [ [ -112.56667894652, 41.300005042600802, 0.0 ], [ -112.650011982188005, 41.4333400501312, 0.0 ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": 125, "GLOBAL_ID": "5ACBFA", "IDENT": "48", "TYPE": "N", "Shape__Length": 0.4599 }, "geometry": { "type": "LineString", "coordinates": [ [ -112.650011982188005, 41.4333400501312, 0.0 ], [ -113.100012081374004, 41.5000060205737, 0.0 ] ] } }
]
}
This is what I have tried so far and it is throwing an error as follows:
buffer = gpd.points_from_xy([(x,y)])
TypeError: points_from_xy() missing 1 required positional argument: 'y'
.
Please see below code what I attempted to do:
import json
import geopandas as gpd
from shapely.geometry import MultiPolygon
# Load geojson
with open('Sample_lines.geojson') as f:
gj = json.load(f)
features = []
for f in gj['features']:
coords = f['geometry']['coordinates']
print(coords[0][0])
print(coords[0][1])
print(tuple(coords[0]))
print(coords)
#quit()
# Buffer points along line
buffers = []
for x,y,z in tuple(coords):
buffer = gpd.points_from_xy([(x,y)])
buffer = buffer.to_crs(epsg=4326)
buffer = buffer.buffer(2)
buffers.append(buffer)
# Create multipolygon from buffers
mpolygon = MultiPolygon(buffers)
# Create feature
features.append(
{'geometry': gpd.GeoSeries(mpolygon).__geo_interface__,
'properties': f['properties']}
)
# Output new GeoJSON
new_gj = {
"type": "FeatureCollection",
"features": features
}
# output in .GeoJSON
with open('lines2Polygon.geojson','w') as f:
dump(new_gj, f)
print(new_gj)
Where am I going wrong here? Thank you in Advance for your time and support.
There were some errors:
The multipolygon created could be invalid if the individual buffers would overlap. If you use shapely.union_all on the individual buffers you can avoid overlaps. I included it like that in the script below.
The following script runs:
from pathlib import Path
import json
import geopandas as gpd
from matplotlib import pyplot as plt
import shapely
from shapely import plotting
# Load geojson
with open(Path(__file__).with_suffix(".geojson")) as f:
gj = json.load(f)
features = []
for f in gj["features"]:
coords = f["geometry"]["coordinates"]
print(coords[0][0])
print(coords[0][1])
print(tuple(coords[0]))
print(coords)
# quit()
# Buffer points along line
buffers = []
for x, y, z in coords:
buffer = gpd.points_from_xy([x], [y], crs=4326)
buffer = buffer.to_crs(epsg=2163)
buffer = buffer.buffer(2*1609.34)
buffers.append(buffer)
# Create multipolygon from buffers
# mpolygon = shapely.MultiPolygon(buffers)
mpolygon = shapely.union_all(buffers)
plotting.plot_polygon(mpolygon)
# Create feature
features.append(
{
"geometry": gpd.GeoSeries(mpolygon).__geo_interface__,
"properties": f["properties"],
}
)
# Output new GeoJSON
new_gj = {"type": "FeatureCollection", "features": features}
# output in .GeoJSON
with open("lines2Polygon.geojson", "w") as f:
json.dump(new_gj, f)
print(new_gj)
plt.show()