簡體   English   中英

將局部坐標投影到帶參考點的全局 GPS

[英]project local coordinates to global GPS with reference point

我在 geopandas GeoDataFrame 中有一堆形狀(例如勻稱的LineString s 或Polygon s)。 形狀指定局部 200x200 米網格中的坐標,即所有坐標都在 (0, 0) 和 (200, 200) 之間。

我現在想在全球范圍內“放置”這些行。 為此,我想指定一個 GPS 點(具有給定的緯度/經度)作為參考。

我的第一個(天真的)方法是使用 geolib,獲取所有形狀的坐標(在本地 X/Y 中)並應用以下轉換並“重新創建”形狀:

# Convert coordinates to GPS location
from shapely.geometry import LineString
from geographiclib.geodesic import Geodesic
geod = Geodesic.WGS84  # the base geodesic (i.e. the world)

origin = (48.853772345870176, 2.350983211585546)  # this is somewhere in Paris, for example

def local_to_latlong(x, y, orientation=0, scale=1):
    """ Two step process.
    - First walk x meters to east from origin.
    - Then, from that point, walk y meters north from origin.
    
    Optional: 
    - orientation allows to "spin" the coordinates
    - scale allows to grow/shrink the distances
    """
    go_X = geod.Direct(*origin, orientation + 90, x * scale)  # x is East-coordinate
    go_Y = geod.Direct(go_X["lat2"], go_X["lon2"], orientation + 0, y * scale)  # y is North-coordinate
    return go_Y["lat2"], go_Y["lon2"]


original_line = LineString([(0,0), (100,100), (200,100)])
global_line = LineString([local_to_latlong(x, y) for y, x in original_line.coords])

但是,我希望這不是最聰明的方法,並且有更聰明的方法......

我想將這種轉換應用於 GeoDataFrame 中的任何形狀。 理想情況下,它可以使用“to_crs”,但我不確定如何轉換形狀,以便它們“參考原點”以及使用哪個 crs。

  • 鑒於您的來源是 EPSG:4326,您可以估計 UTM 區域
  • 有了這個,你可以得到原點的 UTM 區域坐標
  • 將您的自定義 200x200 米區域轉換為 UTM 區域的坐標
  • 最后使用to_crs()轉換為 EPSG:4326
import shapely.geometry
import geopandas as gpd
import pandas as pd
import numpy as np

# generate some polygons (squares), where grid is 200*200
gdf = gpd.GeoDataFrame(
    geometry=pd.DataFrame(
        np.repeat(np.sort(np.random.randint(0, 200, [20, 2]), axis=1), 2, axis=1)
    ).apply(lambda d: shapely.geometry.box(*d), axis=1)
)
# chage to linestrings, clearer when we plot
gdf["geometry"] = gdf["geometry"].exterior

origin = (2.350983211585546, 48.853772345870176)  # this is somewhere in Paris, for example

# work out utm crs of point.  utm is in metres
gdf_o = gpd.GeoDataFrame(geometry=[shapely.geometry.Point(origin)], crs="EPSG:4326")
crs = gdf_o.estimate_utm_crs()
# where is origin in utm zone
xo,yo = gdf_o.to_crs(crs).loc[0,"geometry"].xy

# translate custom zone to co-ordinates of utm zone
# assume point is center of 200x200 grid (hence subtract 100)
gdf_gps = gdf["geometry"].translate(xoff=xo[0]-100, yoff=yo[0]-100).set_crs(crs).to_crs("epsg:4326")

# plot on map to show it has worked...
m = gdf_gps.explore()
m = gdf_o.explore(m=m, color="red", marker_kwds={"radius":20})
m


在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM