Добрый день!
Суть в заголовке. В бд хранятся объекты с координатами, необходимо найти расстояние в метрах до Черного моря.
Пока в голову приходит только способ с описанием полигона моря, но думаю есть более эффективные методы.
Здравствуйте.
Возникла задача поиска точки на маршруте по пройденному расстоянию.
Т.е. есть известный маршрут, есть показания одометра от начальной точки и нужно найти координаты места/точки на маршруте.
Если кто сталкивался, подскажите, пожалуйста, решение.
Доброго времени суток. Возник вопрос по отрисовке траектории.
К примеру, у меня есть две точки А и Б, расстояние между ними 8 километров. Можно ли отследить отрисовку данной траектории, и когда будет отрисована траектория длиной 4 километра, перестать рисовать.
Другими словами условие, если длина траектории больше 4 километров, отрисовку прекратить.
Как определить расстояние от точки до моря?
Добрый день! Наткнулась на неожиданную проблему.
У меня карта описывается декартовыми координатами
var myProjection = new ymaps.projection.Cartesian([
[-110, -110], // координаты левого нижнего угла
[110, 110] // координаты правого верхнего угла
]),
Есть квадратный объект (во всяком случае, на экране он отображается как квадратный). Измеритель расстояния ("линейка") при измернии по горизонтали дает, к примеру, 200 м, а при измерении того же объекта по вертикали - примерно в три раза больше.
можно ли это как-то настроить, скорректировать, переписать где-то код и т.д., чтобы оно показывало одинаковые расстояния?
В старой версии API был инструмент GeoCoordSystem.distance, а в новой версии его нет? Как можно программно измерить расстояние между точками по известным координатам? Может быть геокодер умеет? Или маршруты? Но маршруты не строятся по кратчайшему пути.
Воспользовался следующим гайдом:
http://habrahabr.ru/post/127446/
Писал на API 2.0.
Все работает, НО! Данный способ считает ужасно.
Например, расстояние от Химок до МКАДа.
Красным отмечен маршрут из Химок до Осеннего бульвара. Фиолетовым, маршрут от Химок до МКАДа. На первом маршруте до МКАДа проехать придется километра 2, хотя на фиолетовом это расстояние посчиталось как 7,5 км
Другие способы есть?
В АПИ 1.x был метод GeoPoint.distance
Сейчас GeoPoint нет как такового. Соответственно и distance.
Реализовано ли это в API 2.0 или надо использовать свой метод?
Здравствуйте. Требуется функция на PHP для расчета расстояния (в метрах) между двух меток.
Имеются координаты:
1) 30.325557,60.052094
2) 30.321651,60.055935
Пробывал пользоваться функцией, найденной на просторах интернета, но результаты не верные, подозреваю тип координат отличается
function calcDistance($lat1, $lon1, $lat2, $lon2)
{
if ($lat1 == $lat2 && $lon1 == $lon2) {
return 1;
}
// Параметры эллипсоида:
$a = 6378245.0;
$f = 1 / 298.3;
$b = (1 - $f) * $a;
$EPS = 0.5E-30;
$PI = M_PI;
//Пересчет значений координат в радианы
$lon1 = $lon1 * $PI / 180;
$lat1 = $lat1 * $PI / 180;
$lon2 = $lon2 * $PI / 180;
$lat2 = $lat2 * $PI / 180;
$TanU1 = (1 - $f) * tan($lat1);
$TanU2 = (1 - $f) * tan($lat2);
$U1 = atan($TanU1);
$U2 = atan($TanU2);
$SinU1 = sin($U1);
$CosU1 = cos($U1);
$SinU2 = sin($U2);
$CosU2 = cos($U2);
$OMEGA = $lon2 - $lon1;
$lambda = $OMEGA;
do //Начало цикла итерации
{
$LambdaPrev = $lambda;
$SinL = sin($lambda);
$CosL = cos($lambda);
$SinSQSigma = ($CosU2 * $SinL * $CosU2 * $SinL) +
($CosU1 * $SinU2 - $SinU1 * $CosU2 * $CosL) *
($CosU1 * $SinU2 - $SinU1 * $CosU2 * $CosL);
$CosSigma = $SinU1 * $SinU2 + $CosU1 * $CosU2 * $CosL;
$TanSigma = sqrt($SinSQSigma) / $CosSigma;
if ($TanSigma > 0) {
$Sigma = atan($TanSigma);
} else {
$Sigma = atan($TanSigma) + $PI;
}
if ($SinSQSigma == 0) {
$SinAlpha = 0;
} else {
$SinAlpha = $CosU1 * $CosU2 * $SinL / sqrt($SinSQSigma);
}
if ((cos(asin($SinAlpha)) * cos(asin($SinAlpha))) == 0) {
$Cos2SigmaM = 0;
} else {
$Cos2SigmaM = $CosSigma - (2 * $SinU1 * $SinU2 / (cos(asin($SinAlpha)) * cos(asin($SinAlpha))));
}
$CPARAM = ($f / 16) * cos(asin($SinAlpha)) * cos(asin($SinAlpha)) *
(4 + $f * (4 - 3 * cos(asin($SinAlpha)) * cos(asin($SinAlpha))));
$lambda = $OMEGA + (1 - $CPARAM) * $f * $SinAlpha * (acos($CosSigma) +
$CPARAM * sin(acos($CosSigma)) * ($Cos2SigmaM + $CPARAM * $CosSigma *
(-1 + 2 * $Cos2SigmaM * $Cos2SigmaM)));
} while (abs($lambda - $LambdaPrev) >= $EPS); // Конец цикла итерации
$USQR = cos(asin($SinAlpha)) * cos(asin($SinAlpha)) *
($a * $a - $b * $b) / ($b * $b);
$APARAM = 1 + ($USQR / 16384) * (4096 + $USQR * (-768 + $USQR * (320 - 175 * $USQR)));
$BPARAM = ($USQR / 1024) * (256 + $USQR * (-128 + $USQR * (74 - 47 * $USQR)));
$DSigma = $BPARAM * sqrt($SinSQSigma) * ($Cos2SigmaM + $BPARAM / 4 *
($CosSigma * (-1 + 2 * $Cos2SigmaM * $Cos2SigmaM) - $BPARAM / 6 * $Cos2SigmaM *
(-3 + 4 * $SinSQSigma) * (-3 + 4 * $Cos2SigmaM * $Cos2SigmaM)));
return $b * $APARAM * ($Sigma - $DSigma);
}
Здравствуйте,
Уже достаточное время мучаюсь с проблемой: пытаюсь рассчитать расстояние между двумя произвольными точками, которые находятся на удалении от 30 до 1500 метров друг от друга.
Используется PHP:
$cx=31.319738; //координата x первой точки
$cy=60.901638; //координата y первой точки
$x=31.333312; //координата x второй точки
$y=60.933981; //координата y второй точки
$mx=abs($cx-$x); //высчитываем разницу иксов (первый катет прямоугольного треугольника), функция abs(x) - возвращает модуль числаx x
$my=abs($cy-$y); //высчитываем разницу игреков (второй катет прямоугольного треугольника)
$dist=sqrt(pow($mx,2)+pow($my,2)); //Получаем расстояние до метро (длину гипотенузы по правилу гипотенуза равна корню из суммы квадратов катетов)
Если непонятно, поясняю: я представляю, что расстояние между двумя точками - это гипотенуза прямоугольного треугольника. Тогда разница между иксами каждой из двух точек будет одним из катетов, а другим катетом будет разница игреков этих же двух точек. Тогда, посчитав разницы иксов и игреков, можно по формуле вычислить длину гипотенузы (т.е. расстояние между двумя точками).
Я знаю, что это правило хорошо работает для декартовой системы координат, однако, оно должно более-менее работать и через координаты longlat, т.к. измеряемое расстояние между двумя точками пренебрежимо мало (от 30 до 1500 метров).
Однако, расстояние по данному алгоритму вычисляется неверно (например, расстояние1, расчитанное по этому алгоритму, превышает расстояние2 всего на 13%, тогда как в реальности расстояние1 равно 1450 метров, я расстояние2 равно 970 метров, то есть на самом делие разница достигает почти 50%).
Если кто-то сможет помочь, буду очень признателен.
С уважением, Александр.
Подскажите каким образом можно зная координату к примеру 37.613551,55.736402. Нужно узнать координату со смищением на 500метров на восток и 100метров на юг к примеру.
пробовал по формуле вот от сюда http://gis-lab.info/forum
подскажите как сделать то?
Здраствуйте!
Прошу помочь по некоторым вопросам:
1. Как можно добавить точку на ломаную, при условии что есть только расстояние на которое она отстоит от начальной точки?
Есть некая ломаная, общая длина в км просчитана, а так же длина от начальной точки до каждой вершины. Пользователь вводит отрезок в км, к примеру в виде 15-74, т.е. нужно определить две точки 15-й и 74-й километр от начальной точки ломаной.
На данный момент я могу найти отрезок на котором должна быть вершина, но как можно выставить точку на этом отрезке зная только расстояние?
2. Можно ли выделить отрезок ломаной другим цветом?
3. Где можно посмотреть как создавать такие формы как в "конструкторе схем проезда", которая отображается при завершении построения маршрута?
Буду признателен за вашу помощь и советы.
Дорый день.
Я только начинаю освоение API Карт, но у меня уже появилась серьезная задача.
Нужно ввести название 2 населенных пунктов, найти их координаты, нарисовать м/у ними путь и вычеслить расстояние.
Подскажите что мне читать по этому поводу, что использовать. Может уже есть готовые скрипты?
Каков мой алгоритм действий?
Спасибо.
Доброго времени суток!
Допустим пользователь может добавить определенный маршрут, посредством кнопки "Измеритель расстояния" и нажимает на кнопку "Сохранить". Возможно ли собрать эту информацию, записать в БД, и затем восстановить, как будто этот маршрут был начерчен с помощью кнопки "Измеритель расстояния". Если это возможно, пожалуйста поделитесь ссылками на подобную документацию.
Возможно ли определить расстояние между городами по автодорогам? distance() как понял определяет наименьшее расстояние между двумя точками
Доброго времени суток, ковыряя карты яндекса наткнулся на такую вещь: К примеру у меня есть координаты точки:sll=30.292638,59.939397 - это как я понял долгота и широта соответственно, но помимо этого есть ещё и
sspn=0.009954,0.008779, вопрос первый, что это?
Вопрос второй, мне нужно через JS или как-нибудь просчитать расстояние от точки А до точки Б. Конечно есть такой функционал типа distance, но кто может раскрыть по какой формуле там ведётся расчёт???
В этой небольшой заметке я хотел бы поделиться опытом, который я получил при написании сервиса "Ближайшие станции метро". В разработке серверной части я использовал язык PHP (его я лучше всех помню), поэтому листинги фрагментов кода будут приведены именно на нем.
Мне хотелось бы рассказать поподробнее как я получал список ближайших объектов к заданной точке, а также с какими трудностями я столкнулся в процессе реализации.
Алгорит достаточно прост:
1. Получить и обработать параметры из URL'а.
2. По центру и заданной окружности рисуем ограничивающий многоугольник.
3. Из БД выбираем все точки, который попали в ограничивающий многоугольник.
4. Находим расстояния от центра многоугольника до всех найденных объектов.
5. Выбираем ближайшие n.
6. Создаем XML-документ.
7. Транслируем его с помощью XSLT в любой нужный формат.
Теперь обо всем немного поподробнее.
1. Получить и обработать параметры из URL'а.
В моем случае все параметры передавались в строке запроса, поэтому доступ к ним я получал через специальный "суперглобальный" массив $_GET.
Все параметры, которые необходимы для работы сервиса, я проверяю на "валидность" и если они не заданы, то дополняю значениями по умолчанию.
Реализовать данную задачу можно по-разному, лично я написал класс Params, который помогал мне в этом:
class Params {
// Параметры по умолчанию и он же список разрешенных параметров
private $paramsDefault = array(
'point' => null,
'distance' => 2,
'format' => 'ymapsml',
'jsoncallback' => null
);
// Списки доступных значений
private $enabledParams = array(
'point' => 'validPoint',
'distance' => 'vaildDistance',
'format' => array('ymapsml', 'json'),
);
// Параметры
public $params = null;
function __construct ($params = array()) {
$this->params = array_merge($this->paramsDefault, $params);
$this->params = $this->filter($this->params);
//$this->printParams();
}
function __destruct () {}
// Метод оставляет только те параметры, которые есть в списке $paramsDefault и валидны (см. метод isValid)
private function filter ($params) {}
// Проверяет валидность значения параметра
private function isValid ($key, $value) {}
}
Все параметры, полученные из строки запроса, мержились со значениями по умолчанию. В итоге все значения, необходимые для работы сервиса, заданы либо пользователям, либо взяты значения по умолчанию.
Метод filter() пробегается по всем параметрам и вызывает необходимую функцию для валидации, либо ищет вхождение в список допустимых значений.
2. По центру и заданной окружности рисуем ограничивающий многоугольник.
Для построения ограничивающего многоугольника необходимо будет решать прямую геодезическую задачу.
Прямой геодезической задачей (ПГЗ) называют вычисление геодезических координат - широты и долготы некоторой точки, лежащей на земном эллипсоиде, по координатам другой точки и по известным длине и дирекционному углу данного направления, соединяющей эти точки.
Форму Земли я принял как шар. Если взять такую апроксимацию, то задачи геодезии решаются гораздо проще.
Не помню точно откуда я брал алгоритм и на сколько он точный. Но одно помню точно - работает он только для маленьких расстояний, для больших расстояний - будет очень большая погрешность.
Все задачи решает один класс GeodeticTask:
// Класс для решения задач геодезии
class GeodeticTask {
// Решает прямую задачу геодезии
function solveDirect ($point, $distance, $angle) {
$arrPoint = explode(',', $point);
$angle = self::getAngle($angle);
// Определяем приращения
$dx = $distance / (111.2 * 0.8 * cos($arrPoint[1])) * cos($angle);
$dy = $distance / 111.2 * sin($angle);
return implode(' ', array(
$arrPoint[0] + $dx,
$arrPoint[1] + $dy
));
}
// Из строки получаем угол (временная функция)
// Нет ничего постоянного, чем временное
private function getAngle ($str) {
$arrAngle = explode(',', $str);
return self::degToRad($arrAngle[0] + $arrAngle[1] / 60 + $arrAngle[2] / 3600);
}
}
С помощью метода solveDirect() класса GeodeticTask легко найти координаты ограничивающего многоугольника.
class Polygon {
private $center; // Центр многоугольника
private $radius; // Радиус описанной окружности
// Массив координат
private $points = array();
// Строка с координатами
public $result = '';
// На вход передаются параметры урла
function __construct ($params) {
if ($point = $params->get('point')) {
$this->center = $point;
$this->radius = $params->get('distance');
$this->create();
}
}
function create () {
for ($i = 0; $i < 360; $i += 45) {
array_push($this->points, GeodeticTask::solveDirect($this->center, $this->radius, $i.',0,0.00'));
}
// Замыкаем многоугольник
array_push($this->points, GeodeticTask::solveDirect($this->center, $this->radius, '0,0,0.00'));
$this->result = implode(',', $this->points);
}
}
Полученные координаты из многоугольника я сохраняю в строку. Это нужно для формирования запроса к БД.
Для угла и хранения точек лучше создать свои структуры данных, а не хранить строками. Я делал временное решение, которое так и осталось временным :)
3. Из БД выбираем все точки, который попали в ограничивающий многоугольник.
Для хранения координат точечных объектов (как, например, станций метро) используется стандартный тип данных POINT (spatial index) в MySQL. Соответственно данные хранятся в виде R-tree.
Можно было хранить отдельно координаты как два разных поля. Такой метод подходит, если вы всегда выбираете данные из прямоугольной области. Если есть желание делать выборку из более сложных областей (как в моем случае), то лучше все же использовать spatial index. Возможно, что у вас есть более красивое решение? С удовольствием бы послушал.
В итоге результат на выборку данных выглядит примерно следующим образом:
SELECT s.title, asText(s.coords) as coords, s.address, l.color
FROM `stations` as s, `lines` as l
WHERE MBRContains(
GeomFromText('
Polygon((
".$polygon->result."
))'
) , coords) AND l.id = s.line_id
Переменная $polygon - это объект класса Polygon, который был описан выше. Результат этого запроса поместим в переменную $stations, с которой и будем далее работать.
4. Находим расстояния от центра многоугольника до всех найденных объектов.
Для того, чтобы реализовать эту задачу - необходимо будет решить еще одну задачку геодезии - обратную.
Обратная геодезическая задача (ОГЗ) заключается в определении по геодезическим координатам двух точек на земном эллипсоиде длины и дирекционного угла направления между этими точками.
В класс GeodeticTask добавляем еще один метод solveInverse(), который будет решать обратную задачу геодезии. Алгоритм я взял с сайта gis-lab.info. Вот так он примерно будет выглядеть:
function solveInverse ($point1, $point2) {
$lat1 = self::degToRad($point1[1]);
$lat2 = self::degToRad($point2[1]);
$lng1 = -1 * self::degToRad($point1[0]);
$lng2 = -1 * self::degToRad($point2[0]);
$dlon_E = mod($lng2 - $lng1, 2 * pi()) ;
$dlon_W = mod($lng1 - $lng2, 2 * pi());
$dphi = log(tan($lat2 / 2 + pi() / 4) / tan($lat1 / 2 + pi() / 4));
$q = (abs($lat2 - $lat1) > 0.000000001) ? ($lat2 - $lat1) / $dphi : cos($lat1);
$distance = 0;
if ($dlon_E < $dlon_W) {
$distance = 6372795 * pow((pow($q, 2) * pow($dlon_E, 2) + pow(($lat2 - $lat1), 2)), 0.5);
} else {
$distance = 6372795 * pow(pow($q, 2) * pow($dlon_W, 2) + pow($lat2 - $lat1, 2), 0.5);
}
return $distance;
}
private function degToRad ($deg) {
return (pi() * $deg) / 180;
}
private function radToDeg ($rad) {
return ($rad * 180) / pi();
}
Также понадобится функция самописная функция mod (стандартная не подходит):
function mod ($delimoe, $delitel) {
return $delimoe - ($delitel * floor($delimoe / $delitel));
}
На самом деле зада геодезии всего две и в упрощенном виде они применяются в созданном сервисе.
5. Выбираем ближайшие n.
После того, как есть был получен набор точек и расстояний до них - выбрать ближайшие не составит труда (это просто сортировка).
6. Создаем XML-документ.
7. Транслируем его с помощью XSLT в любой нужный формат.
Эти последние два пункта, как вы поняли, являются необязательными. Можно после выборки данных из БД сформировать отдавать их сразу в нужном формате.XSL я выбрал в качестве шаблонизатора, потому что он просто создан для работы с XML.
Спасибо за внимание. Надеюсь эта информация кому-то поможет или вдохновит :)
Понятно что при внедрении собственной карты, Яндекс принимает эту карту как карту мира, соответственно расстояния измеряются некорректно. Кто как решал вопрос корректного измерения расстояний на собственной карте, и возможно ли вообще его решить?