[英]How to add a method in DataMapper so I can find "all points within x distance of this latitude and longitude"?
[英]How can I fit a circle (ideally an ellipse) to latitude/longitude scatter points in Cartopy?
我只是想要一個最適合散點數據的橢圓或圓。 我已經能夠使用許多包將數據擬合成一個圓圈,但結果顯然是無稽之談。 也許我需要做一些奇怪的事情來獲得適用於(a)緯度/經度數據和(b)Cartopy 投影的結果?
我有以下經度/緯度值數組:
coords = np.array([-153.1906979 , 62.01707771],
[ 13.05660412, 63.15537447],
[-175.82610203, 67.11698477],
[ -10.31730643, 61.74562855],
[ 168.02402748, 79.60818152],
[ -34.46162907, 65.10894426],
[ -57.20962503, 59.49626998],
[ 113.70202771, 68.22239091],
[ -80.43411993, 55.6654176 ],
[ 93.77252509, 76.19392633],
[-104.10892084, 56.68264351],
[ 66.36158188, 67.59664968],
[-127.75176924, 57.31577071],
[-151.83057714, 61.64142205],
[ 17.44848859, 56.02194986],
[-176.30087703, 66.5955554 ],
[ -5.48747931, 61.95844561],
[ 160.22917767, 66.07650153],
[ -27.93440014, 67.82152994],
[ 137.09393573, 63.71148003],
[ -53.3290508 , 55.79699915],
[ 109.42329666, 75.43090294],
[ -76.59105583, 59.18143738],
[ 89.94733587, 63.50658353],
[-100.54585734, 55.16704225],
[ 66.15810397, 64.64851675],
[-123.65415058, 60.14507524],
[ 41.00262656, 70.67714209],
[-145.66917977, 68.55315102],
[ 18.34306395, 67.62222778])
我 plot 他們上了 map 如下:
fig = plt.figure(figsize=(20,20))
ax = fig.add_subplot(121,projection=ccrs.NearsidePerspective(central_longitude=0, central_latitude=90,
satellite_height=30785831))
ax.add_feature(cfeature.NaturalEarthFeature('physical', 'ocean', '50m', facecolor='#daf7f7', alpha=0.7, zorder=0))
ax.add_feature(cfeature.NaturalEarthFeature('physical', 'land', '50m', facecolor='#ebc7a4', edgecolor='black', alpha=0.7,zorder=0))
ax.set_global()
grid = ax.gridlines(draw_labels=True)
grid.xlabel_style = {'size': 20, 'color': 'black'}
grid.ylabel_style = {'size': 20, 'color': 'black'}
ax.scatter(coords[0:,0], coords[0:,1], c='red', s=40, zorder=1, transform=PlateCarree())
我現在想要做的就是為這個散點數據擬合一個橢圓或一個圓。 使用此處的解決方案: https://stackoverflow.com/a/52877062/17583970 ,我什至無法嘗試 plot 任何東西,因為橢圓的 b 軸只是一個 nan。 使用 skg.nsphere_fit() 給出的半徑為 433,這顯然是錯誤的或需要以某種方式進行轉換。
任何幫助將不勝感激。
在這種情況下,您使用的坐標非常重要。 任何擬合都會使用某種正在最小化的距離度量,而緯度/經度坐標中的距離根本不會反映以米或英里為單位的東西:
https://en.wikipedia.org/wiki/Geodesics_on_an_ellipsoid
如果您願意假設您的 map 投影是一個合理的距離度量,您可以簡單地轉換坐標,並對其進行擬合。 我懷疑在這種情況下,擬合會稍微偏向極點(地圖中心),使橢圓比使用地球表面的實際距離擬合時的橢圓小一點。
使用 Cartopy 定義數據和 map 的投影:
data_proj = ccrs.PlateCarree()
map_proj = ccrs.NearsidePerspective(central_longitude=0, central_latitude=90, satellite_height=30785831)
然后可以使用這些將坐標轉換為 map 投影:
coords_map = map_proj.transform_points(data_proj, coords[:,0], coords[:,1])[:, :-1]
使用 Scikit-Image 擬合(和預測)橢圓:
from skimage.measure import EllipseModel
model = EllipseModel()
model.estimate(coords_map)
ellipse_coords = model.predict_xy(np.linspace(0, 2*np.pi, 100))
這給出了 map 投影中橢圓的頂點。 您可以考慮將它們轉換回緯度/經度,這將允許您使用ccrs.Geodetic
並將 Cartopy plot 段作為大圓。 但是在 map 坐標中對預測的橢圓進行采樣可能已經很好了。
這導致:
fig, ax = plt.subplots(figsize=(6,6), subplot_kw=dict(projection=map_proj), dpi=86, facecolor="w")
ax.add_feature(cfeature.NaturalEarthFeature('physical', 'ocean', '110m', facecolor='#C6EEFF', alpha=1, zorder=0))
ax.add_feature(cfeature.NaturalEarthFeature('physical', 'land', '110m', facecolor='#A2BAA4', edgecolor='none', alpha=1,zorder=0))
ax.set_global()
grid = ax.gridlines(draw_labels=True, lw=0.5, color="k", alpha=0.2)
ax.plot(coords_map[0:,0], coords_map[0:,1], "o", mfc="none", mec='#A70000', mew=1, ms=5, zorder=1, transform=map_proj)
ax.plot(ellipse_coords[:, 0], ellipse_coords[:,1], "-", color="#A70000", transform=map_proj)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.