Клуб API Карт

Обработка bbox

divined
25 октября 2014, 00:29

Как правильно обрабатывать bbox на стороне сервера при LoadingObjectManager?

Дело в том что запросы "Spatial" не полностью реализованы в ApacheSolr, а друпале, который я использую и подавно.

 

Банальная проверка:

lat > bbox[0] и lat < bbox[2] и lon > bbox[1] и lon < bbox[3]

не подходит. А если учесть что при прохождении края карты через гринвич меняется еще и полярность bbox то начинается полная каша.

 

Кто разбирается в вопросе, подскажите алгоритм проверки вхождения широты и долготы точки в заданный прямоугольник кардинат в контексте полученного значения этого прямоугольника через myMap.getBounds().

19 комментариев

Кажется он поддерживает поиск по bbox.

https://cwiki.apache.org/confluence/display/solr/Spatial+Search

 

Это уж совсем базовая фича. Все geospatial расширения ее поддерживают

Spatial Options Under Development

очень криво работает, а реализация на друпале еще кривее ))

а в чем он данные хранит? в MySQL? Используйте spatial Базы Данных, если можно

Если честно не знаю в чем он хранит данные, но точно не в MySQL. Это сервер индексации написанный на java. Очень быстрый и почти единственный с более менее полной поддержкой в CMS. Так что выбирать особо не из чего.

 

Что интересно myMap.getBounds() возвращает какие-то странные значения, написано в доккументации что он должен возвращать видимую область карты, а он похоже возвращает полный bbox геобъектов на карте.

 

Так же написано что есть проблема с нулевым меридианом, когда bbox меняет полярность, но он меняет полярность не на 0, а на -3..-4

Вот вывод результатов getBounds() при маленьком смещении карты в ребеже левая граница рядом с гринвичем:

[[-15.320564367, -15.285862296], [66.3279255, 168.7571064]][[-15.149896894, -11.418674796], [66.3984790, 172.6242939]][[-14.979089951, -4.2116435462], [66.4688339, 179.8313252]][[-15.149896896, -2.9811747962], [66.3984790, -178.938206]]

[[-15.320564367, 1.5891377037], [66.3279255, -174.3678935]]


т.е. когда проходим левым краем карты с -4 на -2, правый верхний угол, становится уже правым нижним.

При маштабе 2 вообще бред начинается:

тут широта1; широта2; долгота1;долгота2

2: -60.5489; 78.85268688752812; -127.3429978113065; -127.34299781137683

2: -38.6885; 83.87732889659611; 126.83668968869351; 126.83668968862318

2: -29.6478; 84.93641983586491; 51.95387718869352; 51.95387718862319

2: -29.9544; 84.90529385925122; -18.358622811306496; -18.358622811376826


Сколько бы я итераций не делал myMap.getBounds() возвращает прямую линию, а не прямоугольник.

попробуйте рисовать Rectangle из того что возвращает bounds.

Рисует правильно, и я уже понимаю логику координат. Но вот беда:

Here's an example:  &q=*:*&fq=store:[45,-94 TO 46,-93].  LatLonType does not support rectangles that cross the dateline.

Т.е. пишут явно что при прохождении bbox'а через 0 градус поиск не работает.


Пытаюсь найти какие нужно сделать манипуляции чтобы учитывать прохождение через 0 градус, вернее 180.


Получается что координатная сетка идет от 0 до 180, потом от -180 до 0. И когда получается этот переход, нужно что-то сделать со значениями.

 

Т.е. пишут явно что при прохождении bbox'а через 0 градус поиск не работает.

Ооох. я бы тогда не использовал координаты вообще, писать свой spatial, это несерьезно.

Либо смените поисковый движок, либо используйте тайловые координаты для поиска (нужно маркировать все объекты ключами quadKey) и делайте по ним выборку

А где можно поподробней почитать про тайлы и quadKey?

Все объекты в базу заносятся через обратное геокодирование, как мне получить номера тайла и сохранить его в объекте?

если bbox не проходит через 180 градус то логика:

lat > bbox[0] и lat < bbox[2] и lon > bbox[1] и lon < bbox[3] - верна

 

если проходит то она меняется на:

lat > bbox[0] и lat > bbox[2] и (lon < 180 и lon > bbox[1] или lon > -180 и lon < bbox[3])

 

условие прохождения легко определяется по bbox[1] < bbox[3]

 

Для карт яндекс это работает при масштабе 3 и больше, для масштаба 2 и меньше я вообще отключил фильтрацию по видимой области так как уже в видимую область попадает весь мир.

Протестировал, логика абсолютно рабочая.

кроме нулевого меридиана надо учесть что в районе чукотки долгота переходит рубеж 180 / -180

Ну по сути мой код как раз и решает эту проблему "Чукотки", прохождение 0 меридиана безболезнено, так как там идет переход из - в +, а вот чукотский переход из + в - как раз проблему и создавал.

 

Бабушка, а по вопросу выше есть идеи?

 

если bbox не проходить через 180 градус то логика:

lat < bbox[0] и lat > bbox[2] и lon < bbox[1] и lon > bbox[3] - верна

 

вы ищете попадание внутрь области или наоборот?

тут написано, скорее наоборот

)) вы правы запутался, сейчас поправлю дл всех кто будет читать после

исправил, у себя то я реализовал верно ))

Для интереса сделал тестовый кейс вашего кода.

Он не правильно отрабатывает при сдвиге области на камчатку

http://jsfiddle.net/yhk9y25c/

 

В кейсе одна маленькая ошибочка:

return bbox[1] < bbox[3]?
  lat > bbox[0] && lat < bbox[2] && lon > bbox[1] && lon < bbox[3] :
  lat > bbox[0] && lat @>@ bbox[2] && ((lon < 180 && lon > bbox[1]) || (lon > -180 && lon < bbox[3]));

 

@@ - должен быть знак меньше ))