Как выполнить трехпараметрическую геотрансформацию и проекцию в Sql Server 2012?

10

У меня есть таблица со столбцами широты и долготы (NAD27). Я вычисляю два других столбца, X и Y, представляющих местоположение Web Mercator (WGS84).

В настоящее время я использую Arcmap для этого, применяя рекомендованную геотрансформацию для исследуемой области - 3-х параметрическую (геоцентрическую) геотрансформацию - чтобы перейти от NAD27 к WGS84.

Я хотел бы сделать это полностью в Sql Server 2012. Из того, что я могу сказать, Sql Server не поддерживает преобразования данных из коробки "из коробки". Кто-нибудь знает библиотеку Sql, которая поддерживает эту геотрансформацию? Я хотел бы просто использовать те же коэффициенты в Sql, которые я сейчас использую в Arcmap.

Мне также нужно проецировать из WGS84 lat / long в веб-mercator. Я вижу эту формулу реализованной в javascript , но если у кого-то есть хранимая процедура Sql, которая делает это, было бы здорово.

Кирк Куйкендалл
источник
Насколько мне известно, в настоящее время нет действующего ОО решения для базовых преобразований. Самый простой способ создать его в базе данных - это использовать sharpmap.codeplex.com lib. Или взять существующий код и преобразовать его в T-SQL, который я пробовал ...
simplexio
@simplexio Спасибо, вам повезло с преобразованием T-SQL?
Кирк Куйкендалл
Насколько точны вы хотите, чтобы ваши преобразованные координаты были? Или точность все это имеет значение?
Mintx
@Mintx Я бы хотел воспроизвести те же результаты, что и в настоящее время, используя Arcmap.
Кирк Куйкендалл,
1
Конечно. Если вы можете изменить db на PostGIS, у него есть поддержка ре-трансформации. Сервер MS SQL может быть хорошим БД и имеет хорошую поддержку, но я проигрываю postgresq, когда мы говорим о готовых инструментах
simplexio

Ответы:

5

Что касается javascript для SQL, это, вероятно, как вы бы справились с этим:

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

Я думаю, что следующее ответит на ваш первый вопрос. Это потребует довольно большой проверки ошибок. Чтобы помочь, вы можете найти оригинальное уравнение здесь: 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

Редактировать: пара переменных, которые должны были быть именами столбцов, а также отсутствующие запятая и скобка.

Изменить: еще одна скобка.

Я протестировал эту формулу, и она работает, используя случайные точки против преобразования ArcGIS. Помните, что ваши единицы могут быть в футах / градусах. Также помните, что эти результаты являются дельтами, поэтому вам придется добавлять их к вашим значениям, чтобы получить окончательные результаты.

Айк
источник
1
Спасибо, я думаю, что дельты XYZ нужно применять после преобразования из широты, длины в пространство XYZ, где начало оси XY и Z находится в центре Земли.
Кирк Куйкендалл
Я собираюсь напечатать этот GIF и поставить его на стене перед моим столом.
nickves
@KirkKuykendall Этот метод является сокращенным Molodensky, где дельты, которые вы возвращаете, фактически находятся в угловых секундах и могут быть применены к вашим начальным широтам / долготам, чтобы получить перевод к вашей целевой точке. Я не знаю ваш AOI, но геоцентрический, как правило, наименее точный (но самый простой!) Способ получить от NAD27-> WGS84.
Mintx
Также обратите внимание на @dX @dY @dZзначения ike, которые могут отличаться в зависимости от NAD_1927_To_WGS_1984выбранного вами геоцентрического метода.
Mintx
1

Это ссылка на похожий вопрос:

http://sqlspatialtools.codeplex.com/discussions/286893

Я думаю, что первый ответ может быть полезен для понимания того, что вы можете и чего не можете делать в SQL Server, и для изучения некоторых способов решения вашей проблемы.

diegogb
источник