ใช้ไลบรารี PROJ.4 เพื่อเปลี่ยนจากระบบพิกัดในท้องถิ่นเป็นระบบพิกัดทั่วโลกโดยใช้จุดควบคุมภาคพื้นดินหรือไม่?


9

ฉันมีคลาวด์พอยท์ซึ่งมีพิกัดที่เกี่ยวกับระบบพิกัดในพื้นที่ ฉันยังมีจุดควบคุมภาคพื้นดินพร้อมค่า GPS ฉันสามารถแปลงพิกัดท้องถิ่นเหล่านี้เป็นระบบพิกัดทั่วโลกโดยใช้ PROJ.4 หรือห้องสมุดอื่น ๆ ได้หรือไม่?

รหัสใด ๆ ใน Python สำหรับปัญหาที่ระบุข้างต้นจะเป็นความช่วยเหลือที่ดี


คาดหวังรหัสบางอย่าง?
huckfinn

พิกัด GPS โดยทั่วไปคือ WGS84 ดังนั้นจึงน่าจะเป็นพิกัดระดับโลกอยู่แล้ว หากจุดควบคุมภาคพื้นดินอยู่ในการฉายภาพในท้องที่โดยมีตัวเลขที่แตกต่างจาก GPS (เช่น NAD83) จะต้องทำการแปลงตัวเลขดังกล่าว PROJ4 รองรับการเปลี่ยนแปลงตัวเลขเท่าที่ฉันรู้
Oyvind

นี่คือคำถามที่คล้ายกัน แต่มีรายละเอียดมากขึ้น: gis.stackexchange.com/questions/357910
trusktr

คำตอบ:


7

ดูเหมือนว่าคุณกำลังมองหาการเปลี่ยนแปลงเลียนแบบระหว่างระบบพิกัดในพื้นที่ของคุณกับระบบพิกัดทางภูมิศาสตร์

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)

อย่างไรก็ตามคุณมีปัญหาสองขั้นตอน

  1. ค้นหาเมทริกซ์การแปลงจากการจับคู่ที่ทราบกันของพิกัดอินพุตและเอาต์พุต (จุด GPS ของคุณและตำแหน่งที่เกี่ยวข้องในตารางที่กำหนดไว้ในเครื่องของคุณ)
  2. ใช้เมทริกซ์การแปลงนี้เพื่อระบุตำแหน่งทางคลาวด์ของคุณ

Proj.4 excels ที่ # 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 คะแนนขึ้นไป) และได้รับความแม่นยำเมื่อใช้แต้มเท่ากัน คุณกำลังค้นหาจุดที่ดีที่สุดในจุดผูกของคุณทั้งหมด


สวัสดี! คุณพูดถึงว่า Proj (Proj4) ไม่สามารถจัดการส่วนแปลงที่กำหนดเองได้หรือไม่? หมายความว่ามีเทคนิคไม่ได้คำตอบ Proj บริสุทธิ์สำหรับคำถามที่gis.stackexchange.com/questions/357910 ?
trusktr

0

ฟังก์ชั่นการแปลงหญ้าทำหน้าที่ตรงตามที่คุณต้องการแม้ว่าจะไม่ใช่ไพ ธ อนหรือโปรเจคตามที่ร้องขอ:

http://grass.osgeo.org/grass65/manuals/g.transform.html


"ไม่พบหน้าเว็บ": ลิงค์นี้ใช้งานได้grass.osgeo.org/grass64/manuals/g.transform.html
Hans Erren

0

การระบุระบบพิกัดในท้องถิ่นนั้นง่ายกว่าเสมอเหมือนที่เราทำที่นี่:

ภาพสามมิติของ WGS84 ellipsoid บนเครื่องบิน [python]

ขณะนี้ GDAL สามารถแปลงข้อมูลเวกเตอร์โดยใช้คะแนน GCP


สวัสดี! ฉันใหม่สำหรับสิ่งนี้ คือ "stereographic" ฉายในความเป็นจริงสิ่งที่ฉันต้องการที่จะใช้สำหรับคำถามของฉันที่gis.stackexchange.com/questions/357910 ?
trusktr

0

ฉันติดอยู่ในปัญหาเดียวกันเมื่อไม่กี่สัปดาห์ที่ผ่านมาฉันพบสคริปต์ไพ ธ อนที่สามารถช่วยได้ ทางออกดั้งเดิมจากที่นี่

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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.