Клуб API Карт

Как такое реализовать

motoroller198311
9 октября 2013, 22:49

Есть некие объекты, данные о которых храняться в БД, самое важное у них есть: latitude и longitude в формате Yandex карты.

Подскажите как можно модернизировать пример от Yandex: Добавление на карту объектов, попадающих в область видимости, нюанс такой что таких объектов много (более 10 тыс) и конечно же неправильно делать выборку всех объектов и помещать на карту и выводить на карту с помощью searchInside.

Подскажите можно ли реализовать такое, когда открывается карта, то из базы, делается выборка лишь тех объектов, которые могут отобразится на данном участке карты? При перемещении делается опять же выборка новых объектов, которые могут отобразится на этом участке карты. Конечно было неплохо понимать какие участи загружены для кеширования данных.

 

Как я понимаю тут гланый вопрос у меня такой: что у меня открыта карта, я определяю координаты открытого участка карты ну или если надо маштаб. И делаю запрос к БД,

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

 

Заранее всем спасибо, за помощь

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

Если пользователь отзумит карту на обзорный масштаб Вы загрузите все 10тыс объектов?

Если пользователь сдвинет видимую область карты на 1 пиксель Вы загрузите заного все объекты?

Ну допустим когда будут большие маштабы, можно делать limit ....

Или у вас есть какое-то другое предложение?

Ну не делать же выборку сраз всех объектов

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

Плюс ко всему Вы не сможете кэшировать такие запросы, так как область всегда будет уникальная.

При большом количестве объектов я бы смотрел в сторону активных областей.

Они позволяют вывести любое количество геообъектов на карту без потери производительности и запросы можно кешировать.

Для решения такой задачи подходит только "квадратно-гнездовой" способ запросов к серверу за данными.

Два раза уже рассказывал об этом - попробуйте найти презентации с dump.it(екб) или codefest(новосибирск) двух летней давности.

В общем случае активные области реализуют тот же самый принцп загрузки данных - данные загружаются по видимым тайлами.

Есть у активных областей и минусы, связанные с некой сложностью генерировать данные. Но на них, в том числе, висит важная задача ускорять работу карты. Именно по этому на них висит бремя серверного рендеринга.

PS: на активных областях работают почти все картографические сервисы яндекса.

Но можно и без этого - попробуйте понять как хорошо загружать данные с сервера четкими, предсказуемыми кусочками.

И загружайте.

https://github.com/theKashey/tileLoader - тут можно найти загрузчик данных "не по bounds", а по тайлам. Просто загрузчик.

Есть другая сторона проблемы - много запросов к серверу и полное отсуствие у вас обьектов в тундре или США(те не нужные запросы)

Тут поможет загрузка данных по пирамиде - https://github.com/theKashey/quadLoader

Это чуть более продвинутый вариант. И он, в том числе хорошо работает когда обьектов слишком много или слишком мало. Пирамида. На таком принципе работают wikimapia, esosedi и ее производные (тот же гдеэтотдом).

 

И что делать если человек отзумался так что он "видит" все 10 тысяч точек?

А ничего не делать :P

Варианта 2 - либо переходить в "просто другой" режим отображения (пробки яндекса, викимапия и тд), либо врубать "серверный" кластеризатор (гдеэтотдом, камтерия)

Скажите а можно сделать так?

У меня допустим открыта карта, я получаю координаты. То есть координаты видмой карты.

Делаю запрос к серверу и получаю все данные которые влезают, я понимаю что это не совсем быстро и тд и тп.

Мне непонятно как реализовать сам запрос к БД, есл у меня в БД храниться только координата этой точки

Описанный вариант плох тем что при сдвиге карты вам прийдется перезапрашивать данные.

Практически все кто работает с картой именно так и делают. И это плохо.

Работа "через" тайлы работает абсолютно также - только там не один и много запросов. И они идут четко по сетке.

 

Как запросить из базы данные по области?

SELECT * FROM my_table WHERE lat between ? and ? and lng between ? and ?

Тут вроде проблем нет, но у каждого своя бд, свой формат. И конечно же свои запросы и своя обработка результатов.

То есть если я буду использовать: https://github.com/theKashey/quadLoader

То у мня вся карта будет по квадратам. То есть у меня запрос будет идти с каждого квардрата? Запросов будет больше но каждый их них не такой большой?

И как я понимаю, там есть кеширование? То есть не надо бует грузить данные повторно?

quadLoader отличается от tile по сути одним моментом - если в некой области у вас меньше обьектов чем "limit" - запросы за дополнительными данными производятся не будут.

С кешированием и сложнее и проще - так как запрос всегда формирует некий статический адрес - можно кешировать и на сервере и на клиенте.

А можно не кешировать. От задачи зависит.

 

Запросов же будет больше в случае tile загрузчика. На "нормальной" карте где-то 20-40 тайлов видно. Quad на самом деле привязан к сетке, но не привязан к зуму - можно загружать большие куски - выйдет 2-4 запроса. 

Столкнулся с такой же задачей, очень интересно узнать ваше решение.

У меня будет тривиальная задача около 3-4 тысяч объектов в небольшом по площади городе. В принципе и мощности хватит и запрос к БД будет довольно быстро выполняться, но, как-то это "не кошерно" что ли))

Есть предложение, оно же вопрос, пока я не сильно ориентируюсь в api можно ли ограничить зум, например 16-ю.

И ещё вопрос к тем кто освоился уже больше моего, подскажите функцию для получения координат видимой области и пример как налету удалять/добавлять объекты в коллекцию? Новую тему плодить не хочу

Заранее спасибо!

Мне тут посоветовали использовать https://github.com/theKashey/quadLoader

далее я сделал так что по квадратам делал запросы к серверу для получения данных.

Но я посмотрел там странная ситуация при маштабировании квадраты (тайлы) накладываются друг на друга.