Come eseguo una geotrasformazione e proiezione a 3 parametri in SQL Server 2012?


10

Ho una tabella con colonne di latitudine e longitudine (NAD27). Calcolo altre due colonne, X e Y, che rappresentano la posizione di Web Mercator (WGS84).

Attualmente sto usando un Arcmap per fare questo, applicando la geotrasformazione consigliata per l'area di studio - la geotrasformazione a 3 parametri (geocentrica) - per passare da NAD27 a WGS84.

Vorrei farlo interamente all'interno di Sql Server 2012. Da quello che posso dire, Sql Server non supporta le trasformazioni di riferimento fuori dalla scatola. Qualcuno sa di una libreria SQL che supporta questa geotrasformazione? Vorrei semplicemente usare gli stessi coefficienti in SQL che sto attualmente usando in Arcmap.

Devo anche proiettare da WGS84 lat / long in web mercator. Vedo questa formula implementata in javascript , ma se qualcuno ha una stored procedure Sql che lo fa, sarebbe fantastico.


Per quanto ne so, al momento non esiste una soluzione OO funzionante per le trasformazioni dei dati. Il modo più semplice per crearlo nel database sarebbe usare sharpmap.codeplex.com lib- O prendere il codice esistente e convertirlo in T-SQL che ho provato ...
simplexio

@simplexio Grazie, qualche fortuna con la conversione T-SQL?
Kirk Kuykendall,

Quanto vuoi che siano precise le tue coordinate convertite? O la precisione conta così tanto?
Mintx,

@Mintx Mi piacerebbe riprodurre gli stessi risultati che attualmente sto usando Arcmap.
Kirk Kuykendall il

1
Offcourse. Se puoi cambiare db in PostGIS, ha il supporto per la ri-trasformazione. Il server MS SQL potrebbe essere un buon db e ha un buon supporto, ma perdo postgresq quando parliamo di strumenti prefabbricati
simplexio

Risposte:


5

Per quanto riguarda il javascript a SQL, questo è probabilmente il modo in cui lo gestiresti:

SELECT  FromX, 
        FromY, 
        CASE WHEN FromX > 180 THEN NULL ELSE FromX * 0.017453292519943295 * 6378137.0 END AS mercatorX_lon2,
        CASE WHEN FromY > 90 THEN NULL ELSE 3189068.5 * LOG((1.0 + SIN(FromY * 0.017453292519943295)) / (1.0 - SIN(FromY * 0.017453292519943295))) END AS mercatorY_lat2
FROM TABLENAME

Penso che quanto segue risponderà alla tua prima domanda. Richiederà un bel po 'di controllo degli errori. Per aiutare, puoi trovare l'equazione originale qui: http://www.colorado.edu/geography/gcraft/notes/datum/gif/molodens.gif

--fromTheta :column --radians
--fromLamda :column --radians
--fromH     :column --meters

DECLARE @fromA float = 6378206.4        --radius of earth, meters
DECLARE @fromF float =1.0/294.9786982   --Flattening
DECLARE @toA float =6378137.0           --radius of earth, meters
DECLARE @toF float = 1.0/298.257223563  --Flattening
DECLARE @dA float = @toA - @fromA       --change in equatorial radius
DECLARE @dX float = -8.0                --change in X, meters
DECLARE @dY float = 160.0               --change in Y, meters
DECLARE @dZ float = 176.0               --change in Z, meters
DECLARE @dF float = @toF-@fromF         --change in flattening
DECLARE @fromES float = 2.0*@fromF - @fromF*@fromF --first eccentricity squared
DECLARE @bda float = 1.0-@fromF         --polar radius divided by equatorial radius

--RM = (@fromA*(1-@fromES)/POWER(1-@fromES*sin(fromTheta)*sin(fromTheta), 1.5))

--RN = (@fromA/SQRT(1.00-@fromES*sin(fromTheta)*sin(fromTheta)))

SELECT 

((((-@dX*sin(fromTheta)*cos(fromLamda)-@dY*sin(fromTheta)*sin(fromLamda))+@dZ*cos(fromTheta))+@dA*(@fromA/SQRT(1.00-@fromES*sin(fromTheta)*sin(fromTheta)))*@fromES*sin(fromTheta)*cos(fromTheta)/@fromA)+@df*((@fromA*(1-@fromES)/POWER(1-@fromES*sin(fromTheta)*sin(fromTheta), 1.5))/@bda+(@fromA/SQRT(1.00-@fromES*sin(fromTheta)*sin(fromTheta)))*@bda)*sin(fromTheta)*cos(fromTheta))/((@fromA*(1-@fromES)/POWER(1-@fromES*sin(fromTheta)*sin(fromTheta), 1.5)) + fromH) AS deltaTheta,
(-@dX*sin(fromLamda)+@dY*cos(fromLamda))/((((@fromA/SQRT(1.00-@fromES*sin(fromTheta)*sin(fromTheta))) +fromH) * cos(fromTheta)) AS deltaLamda,
@dX*cos(fromTheta)*cos(fromLamda)+@dY*cos(fromTheta)*sin(fromLamda)+@dZ*sin(fromTheta)-@da*@fromA/(@fromA/SQRT(1.00-@fromES*sin(fromTheta)*sin(fromTheta)))+@dF*@bda*(@fromA/SQRT(1.00-@fromES*sin(fromTheta)*sin(fromTheta)))*sin(fromTheta)*sin(fromTheta) AS deltaH

FROM TABLENAME

Modifica: un paio di variabili che avrebbero dovuto essere nomi di colonna e una virgola e una parentesi mancanti.

Modifica: un'altra parentesi.

Ho testato questa formula e funziona usando punti casuali contro la trasformazione di ArcGIS. Ricorda che le tue unità potrebbero essere in piedi / gradi. Ricorda inoltre che questi risultati sono delta, quindi dovrai aggiungerli ai tuoi valori per ottenere i risultati finali.


1
Grazie, penso che i delta XYZ debbano essere applicati dopo la conversione da lat, a lungo nello spazio XYZ dove l'origine degli assi XY e Z è al centro della terra.
Kirk Kuykendall,

Ho intenzione di stampare quella gif e incorniciarla nel muro di fronte alla mia scrivania.
Nichel

@KirkKuykendall Questo metodo è il Molodensky abbreviato, in cui i delta che si ottengono sono in realtà in secondi d'arco e possono essere applicati al lat / long iniziale per ottenere la traduzione nel riferimento target. Non conosco il tuo AOI, ma il geocentrico è di solito il modo meno preciso (ma più semplice!) Per arrivare da NAD27-> WGS84.
Mintx,

Nota anche i @dX @dY @dZvalori di ike che possono essere diversi a seconda del NAD_1927_To_WGS_1984metodo geocentrico che hai scelto.
Mintx

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.