좌표가 로컬 좌표계와 관련된 점 구름이 있습니다. 또한 GPS 값을 가진 지상 제어 지점이 있습니다. PROJ.4 또는 다른 라이브러리를 사용하여 이러한 로컬 좌표를 글로벌 좌표 시스템으로 변환 할 수 있습니까?
위에서 언급 한 문제에 대한 파이썬 코드는 큰 도움이 될 것입니다.
좌표가 로컬 좌표계와 관련된 점 구름이 있습니다. 또한 GPS 값을 가진 지상 제어 지점이 있습니다. PROJ.4 또는 다른 라이브러리를 사용하여 이러한 로컬 좌표를 글로벌 좌표 시스템으로 변환 할 수 있습니까?
위에서 언급 한 문제에 대한 파이썬 코드는 큰 도움이 될 것입니다.
답변:
로컬 좌표계와 지리 참조 좌표계간에 아핀 변환 을 수행하려고 합니다.
Affine은 기본적으로 모든 좌표계를 변환하며 아래의 매트릭스 방정식으로 나타낼 수 있습니다.
|x_1 y_1 1| |a d| |x'_1 y'_1|
|x_2 y_2 1| |b e| = |x'_2 y'_2|
|x_3 y_3 1| |c f| |x'_3 y'_3|
input transform. output
coords matrix coords
(n x 3) (3 x 2) (n x 2)
그러나 2 단계 문제가 있습니다.
Proj.4는 알려진 변환 행렬을 사용하여 지리 참조 좌표 시스템간에 전송하는 # 2에서 뛰어납니다. 내 지식으로 는 포인트 데이터에서 변환 행렬 을 찾는 데 사용할 수 없습니다 . 그러나 Numpy에서 약간의 선형 선형 대수 (최소 제곱 행렬 반전)를 사용하여 전체 작업을 쉽게 수행 할 수 있습니다. 여러 분야 연구의 데이터를 줄이기 위해이 클래스의 버전을 사용했습니다.
import numpy as N
def augment(a):
"""Add a final column of ones to input data"""
arr = N.ones((a.shape[0],a.shape[1]+1))
arr[:,:-1] = a
return arr
class Affine(object):
def __init__(self, array=None):
self.trans_matrix = array
def transform(self, points):
"""Transform locally projected data using transformation matrix"""
return N.dot(augment(N.array(points)), self.trans_matrix)
@classmethod
def from_tiepoints(cls, fromCoords, toCoords):
"Produce affine transform by ingesting local and georeferenced coordinates for tie points"""
fromCoords = augment(N.array(fromCoords))
toCoords = N.array(toCoords)
trans_matrix, residuals, rank, sv = N.linalg.lstsq(fromCoords, toCoords)
affine = cls(trans_matrix) # Setup affine transform from transformation matrix
sol = N.dot(fromCoords,affine.trans_matrix) # Compute model solution
print "Pixel errors:"
print (toCoords - sol)
return affine
다음과 같이 사용할 수 있습니다.
transform = Affine.from_tiepoints(gps_points_local,gps_points_geo)
projected_data = transform.transform(local_point_cloud)
projected_coordinates
이제 WGS84, UTM 또는 GPS로 기록한 좌표계에 있습니다. 이 방법의 주요 특징은 여러 타이 포인트 (3 개 이상)와 함께 사용할 수 있으며 더 많은 타이 포인트가 사용 될수록 정확도를 얻는 것입니다. 당신은 본질적으로 모든 타이 포인트를 통해 가장 잘 맞는 것을 발견하고 있습니다.
그래스 변환 함수는 요청대로 파이썬이나 프로젝트 기반이 아니지만 필요한 것을 정확하게 수행합니다.
여기에서 한 것처럼 로컬 좌표계를 식별하는 것이 항상 더 쉽습니다.
GDAL은 이제 GCP 점을 사용하여 벡터 데이터를 변환 할 수 있습니다.
몇 주 전에 같은 문제에 갇혀서 도움이 될 수있는 파이썬 스크립트를 찾았습니다. 여기 에서 독창적 인 솔루션
import pyproj
import math
import numpy as np
from statistics import mean
import scipy.optimize as optimize
#This function converts the numbers into text
def text_2_CRS(params):
# print(params) # <-- you'll see that params is a NumPy array
x_0, y_0, gamma, alpha, lat_0, lonc = params # <-- for readability you may wish to assign names to the component variables
pm = '+proj=omerc +lat_0='+ str(lat_0) +' +lonc='+ str(lonc) +' +alpha=' + str(alpha) + ' +gamma=' + str(
gamma) + ' +k=0.999585495 +x_0=' + str(x_0) + ' +y_0=' + str(y_0) + ' +ellps=GRS80 +units=m +no_defs'
return pm
#Optimisation function
def convert(params):
pm = text_2_CRS(params)
trans_points = []
#Put your control points in mine grid coordinates here
points_local = [[5663.648, 7386.58],
[20265.326, 493.126],
[1000, -10000],
[-1000, -10000],
[1331.817, 2390.206],
[5794, -1033.6],
]
# Put your control points here mga here
points_mga = [[567416.145863305, 7434410.3451835],
[579090.883705669, 7423265.25196681],
[557507.390559793, 7419390.6658927],
[555610.407664593, 7420021.64968145],
[561731.125709093, 7431037.98474379],
[564883.285081307, 7426382.75146683],
]
for i in range(len(points_local)):
#note that EPSG:28350 is MGA94 Zone 50
trans = pyproj.transform(pyproj.Proj(pm), pyproj.Proj("EPSG:28350"), points_local[i][0], points_local[i][1])
trans_points.append(trans)
error = []
#this finds the difference between the control points
for i in range(len(points_mga)):
x1 = trans_points[i][0]
y1 = trans_points[i][1]
x2 = points_mga[i][0]
y2 = points_mga[i][1]
error.append(math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2))
print("Current Params are: ")
with np.printoptions(precision=3, suppress=True):
print(params)
print("Current average error is: " + str(mean(error)) + " meters")
print("String to use is: " + pm)
print('')
return mean(error)
#Add your inital guess
x_0 = 950
y_0 = -1200
gamma = -18.39841101
alpha=-0
lat_0 = -23.2583926082939
lonc = 117.589084840039
#define your control points
points_local = [[5663.648,7386.58],
[20265.326,493.126],
[1000,-10000],
[-1000,-10000],
[1331.817,2390.206],
[5794,-1033.6],
]
points_mga = [[567416.145863305,7434410.3451835],
[579090.883705669,7423265.25196681],
[557507.390559793,7419390.6658927],
[555610.407664593,7420021.64968145],
[561731.125709093,7431037.98474379],
[564883.285081307,7426382.75146683],
]
params = [x_0, y_0, gamma,alpha, lat_0, lonc]
error = convert(params)
print(error)
result = optimize.minimize(convert, params, method='Powell')
if result.success:
fitted_params = result.x
print(fitted_params)
else:
raise ValueError(result.message)