Задать вопрос
NikMaster777
@NikMaster777

Как добавить несколько наименований в одну метку?

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

У нескольких товаров могут быть одинаковые координаты и в метке отображается только 1 товар, как сделать, чтобы в метке отображались несколько товаров например списком, если у них совпадают координаты? Координаты берём из полей ACF.
// Функция для вставки скрипта на главной странице
function add_map_script_to_home_page() {
    if (is_front_page()) {
        wp_enqueue_script('display-map-script', get_template_directory_uri() . '/js/custom.js', array('jquery'), '1.0', true);

        // Получить список всех товаров WooCommerce
        $args = array(
            'post_type' => 'product',
            'posts_per_page' => -1
        );

        $products = new WP_Query($args);

        // Получить координаты и адрес для каждого товара
        $product_data = array();
        while ($products->have_posts()) {
            $products->the_post();
            $product_id = get_the_ID();
            $coordinates = get_field('coordinates', $product_id);
            $address = get_field('address', $product_id);

            if ($coordinates && $address) {
                $product_data[] = array(
                    'coordinates' => $coordinates,
                    'address' => $address,
					'productURL' => get_permalink($product_id) // Добавляем URL карточки товара
                );
            }
        }

        wp_reset_query();

        wp_localize_script('display-map-script', 'productData', $product_data);
    }
}
add_action('wp_enqueue_scripts', 'add_map_script_to_home_page');


jQuery(document).ready(function($) {
    if (typeof ymaps === 'undefined') {
        // Если Yandex Maps API еще не загружено, загрузим его
        $.getScript('https://api-maps.yandex.ru/2.1/?apikey=YOUR_API_KEY&lang=ru_RU', function() {
            ymaps.ready(initMap);
        });
    } else {
        ymaps.ready(initMap);
    }

    function initMap() {
        var productData = window.productData;
        var map = new ymaps.Map('main-map', {
            center: [59.938784, 30.314997], // Начальные координаты центра карты
            zoom: 12
        });

        for (var i = 0; i < productData.length; i++) {
            var coordinates = productData[i].coordinates.split(',');
            var latitude = parseFloat(coordinates[0]);
            var longitude = parseFloat(coordinates[1]);
            var address = productData[i].address;

            var placemark = new ymaps.Placemark([latitude, longitude], {
				balloonContent: address + '<br><a href="' + productData[i].productURL + '">Подробнее</a>'
			}, {
				preset: 'islands#blueDotIcon',
				maxWidth: 300
			});

            map.geoObjects.add(placemark);

            // Добавляем обработчик события клика для открытия балуна
            placemark.events.add('tap', function (e) {
				var target = e.get('target');
				if (target.balloon.isOpen()) {
					target.balloon.close();
				} else {
					target.balloon.open();
				}
			});

        }
    }
});
  • Вопрос задан
  • 68 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
0xD34F
@0xD34F Куратор тега Яндекс.Карты
Сгруппируйте данные по координатам:

const grouped = productData.reduce((acc, n) => (
  (acc[n.coordinates] ??= []).push(n),
  acc
), {});

Соответственно, когда будете собирать строку для ballonContent метки, вместо одного объекта придётся пробежать по массиву объектов:

for (const [ coord, data ] of Object.entries(grouped)) {
  const placemark = new ymaps.Placemark(
    coord.split(',').map(parseFloat),
    {
      balloonContent: data
        .map(n => `
          <div>
            ${n.address}
            <br>
            <a href="${n.productURL}">Подробнее</a>
          </div>`)
        .join(''),
    },
    {
      preset: 'islands#blueDotIcon',
      maxWidth: 300,
    }
  );

  map.geoObjects.add(placemark);
}

Или, воспользуйтесь кластеризатором:

const placemarks = productData.map((n, i) => new ymaps.Placemark(
  n.coordinates.split(',').map(parseFloat),
  {
    balloonContent: `${n.address}<br><a href="${n.productURL}">Подробнее</a>`,
    clusterCaption: `Адрес №${i + 1}`,
  },
  {
    preset: 'islands#blueDotIcon',
    maxWidth: 300,
  }
));

const clusterer = new ymaps.Clusterer({
  clusterDisableClickZoom: true,
});

clusterer.add(placemarks);
map.geoObjects.add(clusterer);
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы