5

I received a code, that expects a list of coordinates such as this as input

area_polygon = [{'lat': 46.037286, 'lng': 14.471329},
                {'lat': 46.036733, 'lng': 14.467378},
                {'lat': 46.034822, 'lng': 14.468441}]

However, I have input data in form of shapely.Polygon and it looks like this:

POLYGON ((14.471329 46.037286, 14.467378 46.036733, 14.468441 46.034822))

I work with shapely and GeoPandas libraries and I know how to switch lats and longs. But I don't know how to do everything else to transform a Polygon to the form presented.

1
  • What have you tried? This sort of task is very nearly a pure Python issue, so you might benefit from researching how to generate a list of dictionaries from a list of lists.
    – Vince
    Nov 30 '21 at 22:38
8

Here is another solution using the mapping():

returns a new, independent geometry with coordinates copied from the context.

import json
from shapely.geometry import Polygon, mapping

poly = Polygon([[14.471329,46.037286],[14.467378,46.036733],[14.468441,46.034822]])

poly_mapped = mapping(poly)

poly_coordinates = poly_mapped['coordinates'][0]

poly_ = [{'lat': coords[1],'lon': coords[0]} for coords in poly_coordinates]

print(json.dumps(poly_))

This results in:

[{"lat": 46.037286, "lon": 14.471329}, {"lat": 46.036733, "lon": 14.467378}, {"lat": 46.034822, "lon": 14.468441}, {"lat": 46.037286, "lon": 14.471329}]

Mind that the above output will contain one point two times, the first and last points, to avoid that use the following piece of code:

poly_ = poly_[:-1]

print(json.dumps(poly_))

This results in:

[{"lat": 46.037286, "lon": 14.471329}, {"lat": 46.036733, "lon": 14.467378}, {"lat": 46.034822, "lon": 14.468441}]

References:

5

Easier with simple list comprehension:

poly = Polygon([[14.471329,46.037286],[14.467378,46.036733],[14.468441,46.034822]])
poly.wkt
POLYGON ((14.471329 46.037286, 14.467378 46.036733, 14.468441 46.034822, 14.471329 46.037286)
area_polygon = [{'lat':i[1],'lon':i[0]} for i in list(poly.exterior.coords)]
print(area_polygon)
[{'lat': 46.037286, 'lon': 14.471329}, {'lat': 46.036733, 'lon': 14.467378}, {'lat': 46.034822, 'lon': 14.468441}, {'lat': 46.037286, 'lon': 14.471329}]
2
  • The result of print(poly.wkt) is the same as print(poly)
    – Taras
    Nov 30 '21 at 15:40
  • It is normal because print(poly.) = poly.wkt
    – gene
    Nov 30 '21 at 15:49
5

Input data you have is probably a string(?) and it is almost in WKT (Well-known Text) format. Therefore, shapely.wkt.loads method helps you. But first, you have to have closed coordinates. That's, the first (lat, long) must also be at the end of the string like:

           vvvvvvv                        vvvvvvv
'POLYGON ((1.0 2.0, 10.0 20.0, 20.0 20.0, 1.0 2.0))'

The code:

import re
import numpy as np
from shapely import wkt

def add_closing_coordinates(d):
    """ Adds the first 'lat long' to the end"""
    i = re.search(r"\d", d).start()
    j = re.search(r'(\d)[^\d]*$', d).start() + 1
    c = d.index(',')    
    return d[:j] + ", " + d[i:c] + d[j:]

data = 'POLYGON ((1.0 2.0, 10.0 20.0, 20.0 20.0))'
data_wkt = add_closing_coordinates(data)
print(f"data_wkt: {data_wkt}")
# OUT:                                               vvvvvvv
# data_wkt: POLYGON ((1.0 2.0, 10.0 20.0, 20.0 20.0, 1.0 2.0))

polygon = wkt.loads(data_wkt)
coords = np.dstack(polygon.boundary.xy).tolist()[0][:-1]
print(f"coords: {coords}")
# OUT:
# coords: [[1.0, 2.0], [10.0, 20.0], [20.0, 20.0]]


expected_list_of_coordinates_for_received_code = [{"lat": x, "lng": y} for x, y in coords]
print(expected_list_of_coordinates_for_received_code )
# OUT:
# [{'lat': 1.0,  'lng': 2.0},
#  {'lat': 10.0, 'lng': 20.0},
#  {'lat': 20.0, 'lng': 20.0}]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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