Как вывести на карту яндекс очень много меток?

Ссылка скопирована
1 ответ

Здравствуйте. У меня есть 300к+ записей по недвижимости. Нужно вывести их все на карту яндекс. Раньше когда записей было 1500 все выводилось с помощью плагина YaMaps для wordpress, просто получали все записи через wp_query и добавляли метки. Сейчас за раз каждому пользователю загружать 300к записей не возможно. Подскажите как можно вывести все метки?
Вот пример кода как раньше выводили
здесь предварительно до этого кода собирается объект с записями

$map_markers = '';           foreach ($objects as $object) {             $map_markers .= "[yaplacemark coord='" . $object['coord'] . "' icon='islands#blueHomeCircleIcon' color='#24a3ff' name='" . $object['name'] . " | Цена: " . $object['price'] . " ₽' url='" . $object['url'] . "' ]";           }            $map_shortcode =  "[yamap center='55.75244503863624,37.616599835937514' height='800px' zoom='12' type='yandex#map' controls='typeSelector;zoomControl']" . $map_markers . "[/yamap]";            echo do_shortcode($map_shortcode);

$map_markers = ''; foreach ($objects as $object) { $map_markers .= "[yaplacemark coord='" . $object['coord'] . "' icon='islands#blueHomeCircleIcon' color='#24a3ff' name='" . $object['name'] . " | Цена: " . $object['price'] . " ₽' url='" . $object['url'] . "' ]"; } $map_shortcode = "[yamap center='55.75244503863624,37.616599835937514' height='800px' zoom='12' type='yandex#map' controls='typeSelector;zoomControl']" . $map_markers . "[/yamap]"; echo do_shortcode($map_shortcode);

затем просто в js добавляется такой код

document.addEventListener("DOMContentLoaded", function() {  							if (document.getElementById("YandexMapAPI-js") == null ) { 									YaMapsScriptCounter.push(function() {ymaps.ready(init)}); 									if (document.getElementById("YandexMapAPI-alt-js") == null ) {  										function AltApiLoad(src){   									   YaMapsScript.id = "YandexMapAPI-alt-js"; 									   YaMapsScript.src = src; 									   YaMapsScript.async = false; 									   document.head.appendChild(YaMapsScript);   									 }   									 AltApiLoad("https://api-maps.yandex.ru/2.1/?lang=ru_RU");   									 window.onload = function() { 										 YaMapsScriptCounter.forEach(function(entryFunc) { 											 entryFunc(); 										 }); 									 } 									}   									   							}  							else { 									ymaps.ready(init);  							} 							 							   							 YMlisteners.myMap0 = {}; 							 YaMapsWP.myMap0 = {center: "", zoom: "12", type: "yandex#map", controls: "typeSelector;zoomControl", places: {}};   							  var yamapsonclick = function (url) { 								 location.href=url; 							  }                           							 function init () { 								 myMap0 = new ymaps.Map("yamap0", { 										 center: [], 										 zoom: 12, 										 type: "yandex#map", 										 controls: ["typeSelector", "zoomControl"] , 										  									 }, 									 { 										 suppressMapOpenBlock: false 									 });    								  		 YaMapsWP.myMap0.places.placemark2 = {icon: "islands#blueHomeCircleIcon", name: "Цена: 0 ₽", color: "#24a3ff", coord: "", url: "",}; 		 myMap0placemark2 = new ymaps.Placemark([], { 								 hintContent: "Цена: 0 ₽", 								 iconContent: "",     							    							 }, {                         								 preset: "islands#blueHomeCircleIcon",  								 iconColor: "#24a3ff", 							 });   		   				 YMlisteners.myMap0[2] = myMap0placemark2.events.group().add("click", function(e) {yamapsonclick("")});   		  		 YaMapsWP.myMap0.places.placemark3 = {icon: "islands#blueHomeCircleIcon", name: "Цена: 0 ₽", color: "#24a3ff", coord: "", url: "",}; 		 myMap0placemark3 = new ymaps.Placemark([], { 								 hintContent: "Цена: 0 ₽", 								 iconContent: "",     							    							 }, {                         								 preset: "islands#blueHomeCircleIcon",  								 iconColor: "#24a3ff", 							 });   		   				 YMlisteners.myMap0[3] = myMap0placemark3.events.group().add("click", function(e) {yamapsonclick("")});   		  		 YaMapsWP.myMap0.places.placemark4 = {icon: "islands#blueHomeCircleIcon", name: "Цена: 0 ₽", color: "#24a3ff", coord: "", url: "",}; 		 myMap0placemark4 = new ymaps.Placemark([], { 								 hintContent: "Цена: 0 ₽", 								 iconContent: "",     							    							 }, {                         								 preset: "islands#blueHomeCircleIcon",  								 iconColor: "#24a3ff", 							 });   		   				 YMlisteners.myMap0[4] = myMap0placemark4.events.group().add("click", function(e) {yamapsonclick("")});   		  		 YaMapsWP.myMap0.places.placemark5 = {icon: "islands#blueHomeCircleIcon", name: "Цена: 0 ₽", color: "#24a3ff", coord: "", url: "",}; 		 myMap0placemark5 = new ymaps.Placemark([], { 								 hintContent: "Цена: 0 ₽", 								 iconContent: "",     							    							 }, {                         								 preset: "islands#blueHomeCircleIcon",  								 iconColor: "#24a3ff", 							 });   		   				 YMlisteners.myMap0[5] = myMap0placemark5.events.group().add("click", function(e) {yamapsonclick("")});   		 myMap0.geoObjects.add(myMap0placemark1).add(myMap0placemark2).add(myMap0placemark3).add(myMap0placemark4).add(myMap0placemark5);   							 } 						 }, false);

document.addEventListener("DOMContentLoaded", function() { if (document.getElementById("YandexMapAPI-js") == null ) { YaMapsScriptCounter.push(function() {ymaps.ready(init)}); if (document.getElementById("YandexMapAPI-alt-js") == null ) { function AltApiLoad(src){ YaMapsScript.id = "YandexMapAPI-alt-js"; YaMapsScript.src = src; YaMapsScript.async = false; document.head.appendChild(YaMapsScript); } AltApiLoad("https://api-maps.yandex.ru/2.1/?lang=ru_RU"); window.onload = function() { YaMapsScriptCounter.forEach(function(entryFunc) { entryFunc(); }); } } } else { ymaps.ready(init); } YMlisteners.myMap0 = {}; YaMapsWP.myMap0 = {center: "", zoom: "12", type: "yandex#map", controls: "typeSelector;zoomControl", places: {}}; var yamapsonclick = function (url) { location.href=url; } function init () { myMap0 = new ymaps.Map("yamap0", { center: [], zoom: 12, type: "yandex#map", controls: ["typeSelector", "zoomControl"] , }, { suppressMapOpenBlock: false }); YaMapsWP.myMap0.places.placemark2 = {icon: "islands#blueHomeCircleIcon", name: "Цена: 0 ₽", color: "#24a3ff", coord: "", url: "",}; myMap0placemark2 = new ymaps.Placemark([], { hintContent: "Цена: 0 ₽", iconContent: "", }, { preset: "islands#blueHomeCircleIcon", iconColor: "#24a3ff", }); YMlisteners.myMap0[2] = myMap0placemark2.events.group().add("click", function(e) {yamapsonclick("")}); YaMapsWP.myMap0.places.placemark3 = {icon: "islands#blueHomeCircleIcon", name: "Цена: 0 ₽", color: "#24a3ff", coord: "", url: "",}; myMap0placemark3 = new ymaps.Placemark([], { hintContent: "Цена: 0 ₽", iconContent: "", }, { preset: "islands#blueHomeCircleIcon", iconColor: "#24a3ff", }); YMlisteners.myMap0[3] = myMap0placemark3.events.group().add("click", function(e) {yamapsonclick("")}); YaMapsWP.myMap0.places.placemark4 = {icon: "islands#blueHomeCircleIcon", name: "Цена: 0 ₽", color: "#24a3ff", coord: "", url: "",}; myMap0placemark4 = new ymaps.Placemark([], { hintContent: "Цена: 0 ₽", iconContent: "", }, { preset: "islands#blueHomeCircleIcon", iconColor: "#24a3ff", }); YMlisteners.myMap0[4] = myMap0placemark4.events.group().add("click", function(e) {yamapsonclick("")}); YaMapsWP.myMap0.places.placemark5 = {icon: "islands#blueHomeCircleIcon", name: "Цена: 0 ₽", color: "#24a3ff", coord: "", url: "",}; myMap0placemark5 = new ymaps.Placemark([], { hintContent: "Цена: 0 ₽", iconContent: "", }, { preset: "islands#blueHomeCircleIcon", iconColor: "#24a3ff", }); YMlisteners.myMap0[5] = myMap0placemark5.events.group().add("click", function(e) {yamapsonclick("")}); myMap0.geoObjects.add(myMap0placemark1).add(myMap0placemark2).add(myMap0placemark3).add(myMap0placemark4).add(myMap0placemark5); } }, false);

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

Дополнительно:

Может быть, возможно, вам нужно, наверное, использовать циклы.

  • Николай Медведков, вы предлагаете пустить через цикл 300000 записей?
  • Сама идея глупа с таким количеством, ну представь, что у тебя не карта, а эксель на 300к строк, что пользователь с ними должен делать?
  • ObjectManager, заменяет группы близкостоящих меток на одну

    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Mobile-редакция Ответ

    300 тысяч меток нельзя отдавать пользователю на карту одним HTML/shortcode. Браузер, сеть и Яндекс.Карты не рассчитаны на такой объём точек одновременно. Нужно менять архитектуру: подгружать метки порциями по текущей области карты и кластеризовать их.

    Рабочая схема:

    • карта открывается без всех объектов;
    • JS получает текущие границы карты;
    • отправляет bounds на сервер;
    • сервер возвращает только объекты в видимой области и с лимитом;
    • на малом zoom показываются кластеры, на большом — отдельные объекты.

    REST endpoint:

    register_rest_route('realty/v1', '/markers', [
        'methods' => 'GET',
        'callback' => 'realty_get_markers',
        'permission_callback' => '__return_true',
    ]);

    register_rest_route('realty/v1', '/markers', [ 'methods' => 'GET', 'callback' => 'realty_get_markers', 'permission_callback' => '__return_true', ]);

    Для 300к записей нельзя фильтровать координаты через обычный meta_query по wp_postmeta. Лучше вынести координаты, цену и ID объекта в отдельную таблицу с индексами по latitude/longitude. Тогда запрос по прямоугольнику карты будет быстрым.

    Пример SQL-идеи:

    SELECT post_id, lat, lng, price
    FROM wp_realty_geo
    WHERE lat BETWEEN 55.1 AND 56.1
      AND lng BETWEEN 37.1 AND 38.1
    LIMIT 1000;

    SELECT post_id, lat, lng, price FROM wp_realty_geo WHERE lat BETWEEN 55.1 AND 56.1 AND lng BETWEEN 37.1 AND 38.1 LIMIT 1000;

    На фронте используйте ObjectManager/Clusterer Яндекс.Карт. Плагин, который генерирует shortcode со всеми placemark, для такого масштаба уже не подходит.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно