Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
541 views
in Technique[技术] by (71.8m points)

python - How to calculate the shape from lon/lat coordinates and draw it with plotly

I have a plotly based map where I am showing several coordinates in a Mapbox scatter plot. Now I want to get a shape from these coordinates and draw a shape on the map.

The coordinates are available as a pandas.Series. Below an extract of the coordinates.

0    [[51.795, 3.363], [51.79483333333334, 3.363], ...
1    [[51.42536, 2.622246666666667], [51.4256883333 ...

How can I get a shape for these coordinates which boundaries are the outmost coordinates of the cluster?

enter image description here

question from:https://stackoverflow.com/questions/65647292/how-to-calculate-the-shape-from-lon-lat-coordinates-and-draw-it-with-plotly

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In geometry, there are basically two main concepts Convex hull and Alpha shape (also called Concave hull) to get the shape of a finite set of points. The following picture should visually describe the differences between them [2].

enter image description here

In case you want to have the convex hull you can use scipy.spatial.ConvexHull [4].

Please find below a basic example of how to calculate the convex hull for some randomly generated coordinates with scipy.spatial.ConvexHull and to draw the shape with plotly.

import plotly.express as px
import numpy as np

from scipy.spatial import ConvexHull

def get_random_coordinate(): 
    return [ np.random.uniform(54.9, 56.2), np.random.uniform(2.3, 3.2) ]

points = [ get_random_coordinate() for _ in range(20) ]

def get_convex_hull():
    hull = ConvexHull(points)
    return [ [hull.points[visible_facet][1],hull.points[visible_facet][0]] for visible_facet in hull.vertices ]

convex_hull_points = get_convex_hull()
    
fig = px.scatter_mapbox(points, lat=0, lon=1, zoom=6)
fig.update_layout(
    mapbox = {
        'style': "open-street-map",
        'layers': [
            {
            'source': {
                'type': "FeatureCollection",
                'features': [{
                    'type': "Feature",
                    'geometry': {
                        'type': "MultiPolygon",
                        'coordinates': [[convex_hull_points]] 
                    }
                }]
            },
            'type': "fill", 'below': "traces", 'color': "#FF00AA", 'opacity': 0.5
            }
        ]}
    )
fig.show()

Below the final result.

enter image description here

As alternatives to scipy you can also check geopandas and alphashape.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...