Клуб API Карт

[решено] Преобразование координат из custom-системы в глобальную lat/lng

happyman9
14 марта 2011, 22:43

Подскажите где у меня ошибка в преобразовании координат?
Ведь в пределах малой площади нет искажения? должно работать?

Как это можно сделать правильно?

моя custom-коорд. система считается от нуля до единицы по Х и У.

 

 <?php

// локальная дельта
$dx = abs(0.332646677347982 - 0.6040741588464179);
$dy = abs(0.38477149614709694 - 0.5060349431601434);

// аналогичная глобальная дельта (совмещал по точкам типа дом, кольцо троллейбуса)
$dlng = abs(38.449402 - 38.515776);
$dlat = abs(48.937471 - 48.936491);

// коэффициенты
$cfx = $dx / $dlng;
$cfy = $dy / $dlat;

echo "$cfx=$cfx; $dx=$dx; $dlng=$dlng";
echo "\n$cfy=$cfy; $dy=$dy; $dlat=$dlat";

// теперь чтобы перевести локальную произвольную точку $lx $ly в глобальную $lng $lat нужно разделить на коэффициент
$lng_global_from_local = $lx / $cfx;
$lat_global_from_local = $ly / $cfy;

/////// ответ неверный!!!! пробовал на 100 точках, точки почему-то сбиваются вкучу!?

?>

 

 

Спасибо.

UPD:

На всякий случай сохраню-ка я код определения начала координат.

 

<?php

// первая совмещенная точка
$p1 = (object)array(
  'x' => 0.5153582055390249,
  'y' => 0.5072709239337758,
  'lng' => 38.500267,
  'lat' => 48.936491,
);

// вторая совмещенная точка
$p2 = (object)array(
  'x' => 0.4139162279697871,
  'y' => 0.33978789959563593,
  'lng' => 38.4826,
  'lat' => 48.956016,
);

// дельта 1й и 2й точки
$d = (object)array(
  'x' => abs($p1->x - $p2->x),
  'y' => abs($p1->y - $p2->y),
  'lng' => abs($p1->lng - $p2->lng),
  'lat' => abs($p1->lat - $p2->lat),
);

// коэффициент для x и y
$kx = $d->x / $d->lng;
$ky = $d->y / $d->lat;

// используя точку p1 и коэффициент, определим начала координат глобальные
// определим дельту от точки 1 до начала координат
$d3 = (object)array(
  'x' => $p1->x,
  'y' => $p1->y,
);
$d3->lng = $d3->x / $kx;
$d3->lat = $d3->y / $ky;

// определим точку начала координат глобальную
$p0 = (object)array(
  'x' => 0.0,
  'y' => 0.0,
);
$p0->lng = $p1->lng - $d3->lng;
$p0->lat = $p1->lat + $d3->lat; // к экватору широта уменьшается, поэтому знак обращается, из минуса в плюс!

// определим глобальные координаты произвольной точки
$ozero = (object)array(
  'x' => 0.4126039520866712,
  'y' => 0.29687953002212564,
);
$ozero->lng = $p0->lng + $ozero->x / $kx;
$ozero->lat = $p0->lat - $ozero->y / $ky; // к экватору широта уменьшается, поэтому знак обращается, из плюса в плюс!

echo '$p0:', print_r($p0, 1), ' $ozero:', print_r($ozero, 1), ' $kx:', $kx, ' $ky:', $ky;
?>

 

10 комментариев
Подписаться на комментарии к посту

В ваши расчеты я  не осилил. Вроде должно получиться что-то такое:

глобальная координата = глобальная координата начала + локальная координата * дельту (разницу начала и конца)

Ну и встречный вопрос откуда взялась ваша система координат?  Можно ли решить задачу стандартными методами, не крутя педали?


Система координат взялась из головы, просто уже адреса записаны с координатой от 0 до 1. И вдруг появилась надобность их преобразовать.

Что есть "стандартные методы"?

Про формулу,спасибо, но вопросов только больше стало:

- глобальная координата начала (начала чего?)

- дельту (разницу начала и конца) (локальной координаты?)

Приведу на примере:

30, 60 координаты вашего нуля. (0,0)

31, 65 координаты единицы. (1,1)

Координаты для точки 0,5  - 0,5 можно вычислить так:

30 + (31-30) * 0,5 = 30,5

60 + (65-60) * 0,5 = 62,5

Похоже что ошибки появляются из-за потери точности. Видимо PHP "не тянет" такую точность. Попробуйте перевести дополнительно еще ваши координаты из системы  "от 0 до 1" в систему "от 0 до 1000000". Делается это умножением на соответствующий коэффициент. Возможно тогда ответ будет точней.
проверил, точность непричём в моем случае, ошибка куда проще - одна из точек совмещения совершенно "левая".

// теперь чтобы перевести локальную произвольную точку $lx $ly в глобальную $lng $lat нужно разделить на коэффициент
$lng_global_from_local = $lx / $cfx;
$lat_global_from_local = $ly / $cfy;

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

Операция должна выглядеть примерно так:

а) найти географические координаты Вашей точки (0,0). Это можно сделать либо по паре точек, либо напрямую (посмотреть, куда на карте попадает ноль)

б) пересчитать координаты вот так:

$lng_global_from_local = $lx / $cfx + $lng0;
$lat_global_from_local = $ly / $cfy + $lat0;

где ($lng0, $lat0) - географические координаты вашего нуля.

Это типо дельта) я вчера сумбурный код написал, лучше его не трогать :)

сегодня оказалось ошибка в левой координате

Скройте код под врезкой, пожалуйста.
я так понимаю кто-то уже сделал это за меня. Запомню эту возможность.
Это был я :)