Convert Lines to Polygons with Shapely – Guide to Using Polygonize

fionapythonshapely

I have a line shapefile that I am trying to convert to polygons with python using fiona and shapely.

inFile = '/content/drive/My Drive/polyline.shp'
outFile = '/content/drive/My Drive/polygon.shp'
polylines = fiona.open(inFile)

I know i can loop though the data to look at it

for row in polylines:
    print  (row)

and looking at the data

{'type': 'Feature', 'id': '1', 'properties': OrderedDict([('ID', 1), ('Feld1', 189.02), ('Feld2', 'Kürbis')]), 'geometry': {'type': 'LineString', 'coordinates': [...........]}}

{'type': 'Feature', 'id': '2', 'properties': OrderedDict([('ID', 2), ('Feld1', 200.87), ('Feld2', 'Aprikose')]), 'geometry': {'type': 'LineString', 'coordinates': [...........]}}

I am wondering how I can use shapely polygonize with this data?

Best Answer

Create a convex hull from your polyline: https://stackoverflow.com/questions/2964751/how-to-convert-a-geos-multilinestring-to-polygon-using-python

Of course the line has to resemble polygon. If it is eg a river, convex hull will not look very nice.

import fiona
from shapely.geometry import shape, mapping

file = r'e:\...\line.shp'
output = r'e:\temp\output_poly.shp'


schema = {
    'geometry': 'Polygon',
    'properties' : {'id':'int'}
}

with fiona.open(file) as in_file, fiona.open(output, 'w', 'ESRI Shapefile', schema) as out_file:

    for index, row in enumerate(in_file):
        line = shape(row['geometry'])
        hull = line.convex_hull
        out_file.write({
            'geometry': mapping(hull),
            'properties': {'id': index},
        })
        print(hull)

Also if you want to do it manually, you can. You just have to create polygon from vertexes and add one vertex, which is the same as the first one from line so you have a closed ring.

edit: Since convex hull is not working for you, try this piece of code. It will take the points from Line and create polygon, it will put the first point as last point of line so it is closed ring.

import fiona
from shapely.geometry import shape, mapping, LineString, Polygon

file = r'e:\Temp\lines.shp'
output = r'e:\temp\output.shp'


schema = {
    'geometry': 'Polygon',
    'properties' : {'id':'int'}
}

with fiona.open(file) as in_file, fiona.open(output, 'w', 'ESRI Shapefile', schema) as out_file:
    for index_line, row in enumerate(in_file):
        line = shape(row['geometry'])
        coordinates = []

        if isinstance(line, LineString):
            for index, point in enumerate(line.coords):
                if index == 0:
                    first_pt = point
                coordinates.append(point)

            coordinates.append(first_pt)
            if len(coordinates) >= 3:
                polygon = Polygon(coordinates)
                print(polygon)
                out_file.write({
                    'geometry': mapping(polygon),
                    'properties': {'id': index_line},
                })