Подтвердить что ты не робот

Назначить идентификатор маркеру в листовке

Итак, я пытаюсь достичь результата, как на четырехквартале: https://foursquare.com/explore?cat=drinks&mode=url&near=Paris, который, когда вы clik на маркере на карте, прокручивает через перечисленные рестораны на правой стороне экрана в специальный ресторан, и выделяет его через CSS. И наоборот, когда вы нажимаете на ресторан в списке, он выделяет его на карте.

Я использую skobbler/листовки. Я думаю, что могу добиться этого, изменив динамически CSS, как показано в этом примере: http://jsfiddle.net/gU4sw/7/ + прокрутка к пункту назначения script уже установлена ​​в страница.

Чтобы достичь этого, похоже, мне нужно назначить идентификатор в маркерах (2 маркера ниже):

var marker = L.marker([52.52112, 13.40554]).addTo(map);
marker.bindPopup("Hello world!<br>I am a popup1.", { offset: new L.Point(-1, -41) }).openPopup();

var marker = L.marker([52.53552, 13.41994]).addTo(map);
marker.bindPopup("Hello world!<br>I am a popup2.", { offset: new L.Point(-1, -41) }).openPopup();

Вопрос: как я могу назначить идентификатор маркера для запуска изменения css в соответствующем элементе на моей странице html?

Мои знания о JS очень ограничены, но может быть там приятное и легкое решение, спасибо

4b9b3361

Ответ 1

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

Проблема № 1: Если вы не сохраните свои маркеры на объекте или карте, описанном ниже, нет более простого программного доступа к ним позже. Например - пользователь нажимает что-то ВНЕ ВИДА карту, соответствующую маркеру ВНУТРИ карты.

Проблема № 2: Когда пользователь нажимает на маркер ВНУТРИ карты, нет встроенного способа получить идентификатор этого маркера, а затем использовать его, чтобы выделить соответствующий элемент или вызвать действие ВНЕ ВИДА карты.

Решение

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

Вариант №1: Сохраните каждый маркер, используя жесткий код или динамический идентификатор, внутри объекта -

// Create or retrieve the data
var data = [
    {
      name: 'Bob',
      latLng: [41.028, 28.975],
      id: '2342fc7'
    }, {...}, {...}
];

// Add an object to save markers
var markers = {};

// Loop through the data
for (var i = 0; i < data.length; i++) {
  var person = data[i];

  // Create and save a reference to each marker
  markers[person.id] = L.marker(person.latLng, {
    ...
  }).addTo(map);
}

Как и в случае с другим ответом, вы можете получить доступ к одному маркеру, используя -

var marker = markers.2342fc7; // or markers['2342fc7']

Вариант № 2:

В листовке не предусмотрена встроенная опция "id" для маркеров, вы можете добавить идентификатор к элементу напрямую, обратившись к свойству ._icon:

// Create and save a reference to each marker
markers[person.id] = L.marker(person.latLng, {...}).addTo(map);

// Add the ID
markers[person.id]._icon.id = person.id;

Теперь, когда вы обрабатываете события щелчка, легко, как пирог, получить этот идентификатор маркера:

$('.leaflet-marker-icon').on('click', function(e) {
   // Use the event to find the clicked element
   var el = $(e.srcElement || e.target),
       id = el.attr('id');

    alert('Here is the markers ID: ' + id + '. Use it as you wish.')
});

Вариант № 3:

Другим подходом будет использование интерфейса layerGroup. Он предоставляет метод getLayer, который звучит так, будто было бы идеально, чтобы наши маркеры использовали идентификатор. Однако в настоящее время Листовка не предоставляет никакого способа указать пользовательский идентификатор или имя. Этот issue в Github обсуждает, как это должно быть сделано. Однако вы можете получить и сохранить автоматически сгенерированный идентификатор любого маркера (или iLayer, если на то пошло):

var group = L.layerGroup()

people.forEach(person => {
    // ... create marker
    group.addLayer( marker );
    person.marker_id = group.getLayerId(marker)
})

Теперь, когда мы имеем каждый идентификатор маркера, сохраненный с каждым объектом поддержки в нашем массиве данных, мы можем легко получить маркер позже так:

group.getLayer(person.marker_id)

См. это перо для полного примера...

Вариант № 4:

Самый чистый способ сделать это, если у вас есть время, - это расширить класс маркеров буклета, чтобы он обрабатывал ваши индивидуальные потребности. Вы можете либо добавить id к параметрам, либо вставить собственный HTML-код в маркер, который имеет ваш id/class. Дополнительную информацию об этом см. В документации .

Вы также можете использовать circleMarker, который в path options, вы увидите вариант для классаName, который может быть приятным для групп стилей похожих маркеров.

Стайлинг:

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

.leaflet-marker-icon#2342fc7 { ... }

Заключение

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

Ответ 2

Легкий способ сделать это - добавить все маркеры в список с уникальным идентификатором.

var markersObject = {};
markersObject["id1"] = marker1;
markersObject["id2"] = marker2;
markersObject["id3"] = marker3;

Если список ресторанов имеет свойство в элементе html одного ресторана, который соответствует идентификатору добавленного маркера. Что-то вроде:

<a href="#" id="singleRestaurantItem" data-restaurantID="id1" data-foo="bar">Click</a>

Затем добавьте событие click, в котором вы передадите идентификатор ресторана (в данном случае "data-restaurantID" ) и сделайте что-нибудь вроде:

markersObject["passedValueFromTheClickedElement"].openPopup();

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

Ответ 3

var MarkerIcon = L.Icon.extend({
    options: {
        customId: "",
        shadowUrl: 'leaf-shadow.png',
        iconSize: [64, 64],
        shadowSize: [50, 64],
        iconAnchor: [22, 94],
        shadowAnchor: [4, 62],
        popupAnchor: [-3, -76]
    }
});

var greenIcon = new MarkerIcon({iconUrl: "/resources/images/marker-green.png"}),            
    redIcon = new MarkerIcon({iconUrl: "/resources/images/marker-red.png"}),
    orangeIcon = new MarkerIcon({iconUrl: "/resources/images/marker-orange.png"});

var mymap = L.map('mapid').setView([55.7522200, 37.6155600], 13);

L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
    maxZoom: 18,
    id: 'mapbox.streets'
}).addTo(mymap);

// добавить маркер
L.marker([55.7522200, 37.6155600], {customId:"010000006148", icon: greenIcon, title:setMarkerTitle("010000006148")}).addTo(mymap).on('click', markerOnClick);
L.marker([55.7622200, 37.6155600], {customId:"010053166625", icon: redIcon, title: setMarkerTitle("010053166625")}).addTo(mymap).on('click', markerOnClick);

function markerOnClick(e) {
    var customId = this.options.customId;
    document.location.href = "/view/abonents/" + customId;
}

function setMarkerTitle(customId){
    var result = customId;
    result += "\nline2 ";
    result += "\nline3 ";
    return result;
}

Ответ 4

В моем случае я обнаружил, что лучшим способом было бы просто сгенерировать и передать уникальный идентификатор объекту опций L.marker при его создании.

const newMarker = L.marker([lat, lng], {uniqueID: uniqueID})

Затем вы можете добавить этот маркер в листовку layerGroup.

const newLayerGroup = L.layerGroup().addTo(map);
newLayerGroup.addLayer(newMarker);

Вы можете получить доступ к идентификатору с помощью layer.options.uniqueID. Это позволит мне позже найти маркер и манипулировать им; все, что мне нужно, это Leaflet .eachLayer() и уникальный идентификатор.

Мой бэкэнд (Cloud Firestore) уже генерирует уникальные идентификаторы документов, что позволяет очень легко синхронизировать мою карту Leaflet и бэкэнд в режиме реального времени, а не перестраивать и перемонтировать всю layerGroup или обновлять страницу.

//e.g. a callback which fires whenever a doc has been removed from my db

newLayerGroup.eachLayer((layer) => {
  if (deletedDocID === layer.options.uniqueID) {
    newLayerGroup.removeLayer(layer);
  }
});

Ответ 5

Довольно простой и простой способ выполнить создание массива интерактивных маркеров в объекте листовой карты - это манипулировать списком классов созданного маркера, добавляя пользовательское увеличенное имя класса для каждого маркера. Тогда легко создать слушателя и узнать, какой маркер был нажат. Пропуская активную или нет, у каждого есть извлекаемое событие щелчка с надежным идентификатором.

  // creates markers, each with a leaflet supplied class
  if (length === 1) {
    for (i = 0; i < parks.length; ++i) {
      if (parks[i].parksNumber !== parks.parksNumber)
        L.marker([parks[i].latitude, parks[i].longitude], {
          icon: parks[i].iconMarker
        }).addTo(mymap);
    }
  }

  // select all of the leaflet supplied class
  let markers = document.querySelectorAll(".leaflet-marker-icon");

  // loop through those elements and first assign the indexed custom class
  for (i = 0; i < markers.length; ++i) {
    markers[i].classList.add("marker_" + parks[i].parksNumber);

    // then add a click listener to each one
    markers[i].addEventListener("click", e => {

      // pull the class list
      let id = String(e.target.classList);

      // pull your unique ID from the list, be careful cause this list could 
      // change orientation,  if so loop through and find it
      let parksNumber = id.split(" ");
      parksNumber = parksNumber[parksNumber.length - 1].replace("marker_", "");

      // you have your unique identifier to then do what you want with
      search_Number_input.value = parksNumber;
      HandleSearch();
    });
  }

Ответ 6

Листовка имя_класса позволяет добавлять идентификаторы к объектам:

var onMouseover = function() {
  // returns all members of the specified class
  d3.selectAll(".mySpecialClass")
    .style("opacity", ".1");
};

// add desired class to pointer 
L.circleMarker([46.85, 2.35], {className: "mySpecialClass"})
  .addTo(map).on('mouseover', onMouseover);

// to select the marker(s) with a particular class, just use css selectors
// here a d3.js solution
d3.selectAll(".mySpecialClass")
  .style("opacity", ".3")