Search code examples
pythonpython-3.xshapely

creating shapely polygon with different inputs


I have different types of inputs to form the polygon from the database. Am new to python and learnt shapely package used to create shapes but after going through the documentation all the inputs are straight forward. my inputs are something like below i tried to convert the inputs and created polygons but, wants to know weather is any best way to do the same and also wants to know how can we create shapes using some inputs.

input 1: x = [{'lat':90.87898, 'lon': -67.7897878}, {'lat':93.87898, 'lon': -77.7897878}, {'lat':33.87898, 'lon': -47.7897878}]
poly = Polygon([(x[0]['lat'], x[0]['lon']), (x[1]['lat'], x[1]['lon']), (x[2]['lat'], x[2]['lon'])])

Is there any best way of doing this?

input 2: y = '(90.87898,-67.7897878](93.87898, -77.7897878]'

How this input can be used to convert it to polygon? let me know the above input is wrong but this is what i get from DB.


Solution

  • You may want to check your data, latitude greater than 90 degrees is an error.

    There is an efficient way to do this with Shapely and GeoPandas. First, use Shapely to construct the polygon object using a Python list comprehension, then use GeoPandas to get it in a GeoDataFrame.

    The Shapely example here (below Figure 4) is helpful to understand the input format to construct a polygon. Something people miss early on is that the format is 'x, y' so that is 'lon, lat'.

    You said you are new to Python; list comprehensions are great, here is one of many articles on list comprehensions; example 4 is relevent here.

    You may or may not need it in a GeoDataFrame, but it is a nice format to view your data in tabular and plotted/map view. In the solution below, I am assuming your coordinates are EPSG 4326.

    Solution

    from shapely import geometry
    import geopandas as gpd
    
    x = [
        {"lat": 90.87898, "lon": -67.7897878},
        {"lat": 93.87898, "lon": -77.7897878},
        {"lat": 33.87898, "lon": -47.7897878},
    ]
    
    poly = geometry.Polygon([[p["lon"], p["lat"]] for p in x])
    poly = gpd.GeoDataFrame([poly], columns={"geometry"}, crs="EPSG:4326")
    display(poly)
    

    enter image description here

    Checking it on a map

    import matplotlib.pyplot as plt
    
    fig, ax = plt.subplots()
    poly.plot(ax=ax)
    

    enter image description here

    You can use something like Contextily to add a base map to further help with visualizing in python. It throws an error because you are giving a latitude > 90 degrees, and of course there is no base map up there, but it will still plot.

    import matplotlib.pyplot as plt
    import contextily as ctx
    
    fig, ax = plt.subplots()
    poly.plot(ax=ax)
    
    ctx.add_basemap(
        ax,
        crs="epsg:4326",
        source=ctx.providers.Esri.WorldShadedRelief,
    )
    

    enter image description here