2

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?

1 Answer 1

2

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},
                })
7
  • Thank you but yes the shapes are irregular and convex hull does not work correctly
    – Fin
    Commented Nov 6, 2019 at 15:16
  • Well, I am afraid, then you have to convert Line to Polygon manualy, it is not that complicated (by manually i mean via script of course). Do you have LineStrings or MultiLineStrings? If linestring, create polygon from scratch, multilinestring can be a bit more complicated. Commented Nov 6, 2019 at 15:19
  • it is linestring. i have searched and seen other questions similar but without an answer
    – Fin
    Commented Nov 6, 2019 at 15:32
  • @Fin i have edited the answer and put another piece of code. That should work Commented Nov 6, 2019 at 15:35
  • thank you so much for your help!! and if i add fields Feld1 and 2 to the schema and output properties this will include them in the output shapefile?
    – Fin
    Commented Nov 6, 2019 at 15:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.