GeoFAQ siteФОРУМ ПО ГЕО-ИНФОРМАЦИОННЫМ ТЕХНОЛОГИЯМ

GIS, CAD, DTM, SQL, WWW, GPS, ETC.
 - Начало - Регистрация - Ответить - Поиск - Статистика - RSS
Форум GeoFAQ / Вопросы-ответы / Перевод из системы координат google maps в меркаторскую
Автор Сообщение
vasmt
Участник
# Дата: 28 Ноя 2008 18:42
Ответить 


Как из названия снимка Google Maps (например 'trtqsrqrqrrqqqqsqq') получить координаты верхнего левого угла снимка в меркаторовской системе координат?

Jek1975
Участник
# Дата: 28 Ноя 2008 23:22 - Поправил: Jek1975
Ответить 


Могу привести алгоритм для Google Earth. К Google Maps его можно применить только для координаты X.

Если Вам интересно разбираться в этом подробнее, то советую почитать: http://mapbuilder.narod.ru/gm.htm - к сожалению я не понял почему там применяется такая сложная, ресурсоёмкая математика с логарифмами, степенями, делениями и т.п. Может быть Вы разберётесь...

А вот мой алгоритм для Google Eart:

В функции используется массив констант, количество элементов которого соответствует количеству уровней, и каждый элемент которого соответствует ширине/высоте одного квадрата на данном уровне:

var LatHeight, LonWidth:array [0..32] of double;

LatHeight[0]:= 180;
LonWidth [0]:= 180;

for i:=1 to 32 do begin
LatHeight[i]:= LatHeight[i-1] /2;
LonWidth [i]:= LonWidth [i-1] /2;
end;

Исходными данными для функции является массив из байтов 0,1,3,4. Вам всего лишь нужно заменить q,r,s,t в вашем адресе на соотвествующие цифры (естественно разобравшись какой букве, какая цифра соотвествует), или просто заменив в моих CASE, цифры на буквы (но мне кажется так теряется ясность в понимании алгоритма работы):

var RAW:array[0..31] of byte;

А вот сам алгоритм перевода:

Lon:= -180;
Lat:= -180;

for i:=0 to Level-1 do // *<<<<<<<<<<*
case Raw[i] of //Dec = Pic = GE = GM
0: begin end; // 00 = 01 = 00 = 11+'q'='t'
1: begin Lon:=Lon + LonWidth[i] end; // 10 = 11 = 01 = 01+'q'='r'
2: begin Lat:=Lat + LatHeight[i]; Lon:=Lon + LonWidth[i] end; // 11 = 10 = 10 = 00+'q'='q'
3: begin Lat:=Lat + LatHeight[i]; end; // 01 = 00 = 11 = 10+'q'='s'
end;

Результат работы функции: Lon, Lat в градусах.

Jek1975
Участник
# Дата: 28 Ноя 2008 23:27
Ответить 


К сожалению я не нашел здесь тегов [pre] или чего нибудь такого, поэтому в тексте все пробелы "оптимизировались", но если нажать редактирование сообщения, то там оно выглядит нормально - с пробелами - скопируйте его в блокнот - и там уж смотрите функции - там они будут выглядеть красивее и понятнее.
Ну а если с редактированием не получится, то хотя-бы выровняйте комментарии в один столбик - увидите много полезного.

Jek1975
Участник
# Дата: 28 Ноя 2008 23:29
Ответить 


Забыл сказать, что алгоритм дает координаты левого нижнего угла.

geologic
Участник
# Дата: 1 Дек 2008 12:30 - Поправил: geologic
Ответить 


Ну если вы читали известную статью на нашем сайте, то все должно быть понятно, там как раз разбирается, как рассчитать координаты XY для любого тайла. Это по сути, описание довольно простой проекции меркатора и оно есть в разных формах на Posc.org, в Proj.lib etc. Однако, если интересно, давайте упрощенно разберем еще раз, например, для восемнадцатого уровня.

1. Имеется растровый квадратный массив размером 33554432 пикселя. Как рассчитать координаты тайлов? Начнем с ширины и координаты X - в меркаторе она равна экватору. Длина экватора рассчитывается как 2*пи*R. R - радиус земли, в ГИС для меркатора обычно принимается 6371000 м. Делим эту величину на количество тайлов, получаем размер каждого из них в метрах. Зная номер тайла в ряду, отсчитанный слева, получаем меркаторскую координату X.

Для того, чтобы понять номер тайла в строке, как вы хотите, чисто из адресной строки (имени), придется разобрать имя по буквам, примерно как показал выше Jack. Алгоритмы могут быть разные, но они довольно простые.

Дальше продолжать?

Jek1975
Участник
# Дата: 1 Дек 2008 17:31 - Поправил: Jek1975
Ответить 


Кстати перевод в X,Y из того же формата "raw", что и в прошлой функции, выглядит вообще очень просто. Только нужно учесть что алгоритм для Google Earth - для Maps нужно поменять местами 1,2,3,4 и q,r,s,t - что на что менять можно разобраться просто - можно даже методом тыка ;-)

X:=0;
Y:=0;
for i:=0 to Level-1 do
begin
X:=X shl 1;
Y:=Y shl 1;
// *<<<<*
case Raw[i] of //Dec = Pic = GE = GM
3: begin end; // 01 = 00 = 11 = 10+'q'='s'
0: begin Y:=Y or 1 end; // 00 = 01 = 00 = 11+'q'='t'
2: begin X:=X or 1; end; // 11 = 10 = 10 = 00+'q'='q'
1: begin X:=X or 1; Y:=Y or 1 end; // 10 = 11 = 01 = 01+'q'='r'
end;
end;

Результат этой функции - Х и Y с нулем в левом верхнем углу. Измеряются эти Х и Y в [квадратах/на сторону], которые в свою очередь зависят от номера уровня.
Проще говоря, чтоб узнать номер точки, о которой говорил geologic нужно полученные X и Y умножить на ширину картинки т.е. на 256.

Ещё раз повторяю: для Х координаты незачем усложнять математику - проще, чем я написал в первой функции - написать невозможно. А вот для расчеты координаты Y можно использовать советы geologic.

zed
Участник
# Дата: 17 Дек 2008 19:42 - Поправил: zed
Ответить 


Вот рабочие функции определения координат. Определение из 2-х этапов: 1. По имени нахождение XY тайла 2. По XY - определение долготы/широты верхнего левого (или любого из углов):
1. Получение номера тайла XY для GM:
X1:=0;
Y1:=0;
Level:=length(QRSTName);

for i:=2 to Level do
begin
case QRSTName[i] of
't': begin
x1:=x1*2;
y1:=y1*2+256;
end;

's': begin
x1:=x1*2+256;
y1:=y1*2+256;
end;

'r': begin
y1:=y1*2;
x1:=x1*2+256;
end;

'q': begin
x1:=x1*2;
y1:=y1*2;
end;
end;
end;
Здесь QRSTName='qrstqrst' - строка, имя файла без расширения.
-------------------------------------------------------------------------------------

2. По XY определение координат (общая функция для 3-х проекций GM - проекция 1):
uses
Windows,SysUtils,Math;

type
PMapType = record projection:byte; exct:extended; end;
TExtendedPoint = record X,Y: Extended; end;

const
MerkElipsK=0.0000001; //точность расчётов
D2R: Double = 0.017453292519943295769236907684886;// Константа для преобразования градусов в радианы
R2D: Double = 57.295779513082320876798154814105; // Константа для преобразования радиан в градусы
zoom:array [1..24] of longint = (256,512,1024,2048,4096,8192,16384,32768,65536,
131072,262144,524288,1048576,2097152,4194304,
8388608,16777216,33554432,67108864,134217728,
268435456,536870912,1073741824,2147483647);

function GPos2LonLat(XY:TPoint;Azoom:byte;MT:PMapType):TExtendedPoint;

function GPos2LonLat(XY:TPoint;Azoom:byte;MT:PMapType):TExtendedPoint;
var zu,zum1,yy:extended;
begin

result.X:=((XY.x)-zoom[Azoom]/2)/(zoom[Azoom]/360);
case MT.projection of
1: begin // Google Maps и подобные
result.Y:=((XY.y)-zoom[Azoom]/2)/-(zoom[Azoom]/(2*PI));
result.Y:=(2*arctan(exp(result.Y))-PI/2)*180/PI;
end;
2: begin // Яндекс
result.Y:=((XY.y)-zoom[Azoom]/2)/-(zoom[Azoom]/(2*PI));
result.Y:=(2*arctan(exp(result.Y))-PI/2)*180/PI;
Zu:=result.y/(180/Pi);
yy:=((XY.y)-zoom[Azoom]/2);
repeat
Zum1:=Zu;
Zu:=arcsin(1-((1+Sin(Zum1))*power(1-MT.exct*sin(Zum1),MT.exct))/(exp((2*yy)/-(zoom[Az oom]/(2*Pi)))*power(1+MT.exct*sin(Zum1),MT.exct)));
until (abs(Zum1-Zu)<MerkElipsK)or(isNAN(Zu));
if not(isNAN(Zu)) then result.Y:=zu*180/Pi;
end;
3: begin // Долгота/широта
result.y:=-((XY.y)-zoom[Azoom]/2)/(zoom[Azoom]/360);
end;
end;
end;

MT.exct:=0.081819790992; - эксцентриситет эллипса
------------------------------------------------------------------------------------- -
И обратная функция - по координатам определение номера тайла XY:
function GLonLat2Pos(Ll:TExtendedPoint;Azoom:byte;MT:PMapType):Tpoint;
var z,c:real;
begin
result.x:=round(zoom[Azoom]/2+ll.x*(zoom[Azoom]/360));
case MT.projection of
1: begin
z:=sin(Ll.y*D2R);
c:=(zoom[Azoom]/(2*Pi));
result.y:=round(zoom[Azoom]/2-0.5*ln((1+z)/(1-z))*c);
end;
2: begin
z:=sin(Ll.y*D2R);
c:=(zoom[Azoom]/(2*Pi));
result.y:=round(zoom[Azoom]/2-c*(ArcTanh(sin(ll.y*D2R))-MT.exct*ArcTanh(MT.exct*sin(l l.y*D2R))) )
end;
3: result.y:=round(zoom[Azoom]/2-ll.y*(zoom[Azoom]/360));
end;
end;
-------------------------------------------------------------------------------------

Ваш ответ
Bold Style  Italic Style  Underlined Style  Image Link  URL Link 

» Логин  » Пароль 
Только зарегистрированные пользователи могут здесь постить. Авторизуйтесь для отправки сообщений, или зарегистрируйтесь сейчас.
 

Поддержка: PHP forum software miniBB™ © 2001-2017