web-dev-qa-db-fra.com

Attribuer un identifiant au marqueur dans la notice

J'essaie donc d'obtenir un résultat comme sur foursquare: https://foursquare.com/explore?cat=drinks&mode=url&near=Paris qui est lorsque vous cliquez sur un marqueur sur la carte, il fait défiler la liste de les restaurants situés à droite de l'écran par rapport au restaurant ad hoc, et le met en évidence via CSS. Inversement, lorsque vous cliquez sur le restaurant dans la liste, cela le surligne sur la carte.

J'utilise skobbler/leaflet. Je pense pouvoir y parvenir en modifiant CSS de manière dynamique, comme indiqué dans cet exemple: http://jsfiddle.net/gU4sw/7/ + un script de défilement vers la destination déjà en place dans la page. 

Pour y parvenir cependant, il me semble nécessaire d’attribuer un ID aux marqueurs (2 marqueurs ci-dessous): 

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();

La question est: Comment puis-je affecter un identifiant de marqueur pour déclencher une modification CSS dans l'élément correspondant de ma page HTML?

Ma connaissance de JS est très limitée, mais peut-être existe-t-il une solution simple et agréable, merci 

19
lauWM

Je cherchais un moyen agréable de le faire et, autant que je sache, il n’existe toujours pas de moyen intégré (avec dépliant) de donner un identifiant à un marqueur. Je sais que je suis un peu en retard pour répondre à cette question mais j'espère que cela aidera les autres qui tombent sur cette question. Autant que je sache, il y a deux problèmes principaux ici:

Problème n ° 1: Si vous n'enregistrez pas vos marqueurs dans un objet ou une carte, décrit ci-dessous, il n'existe pas de moyen de programmation simple pour y accéder ultérieurement. Par exemple - Un utilisateur clique quelque chose à l'extérieur de la carte qui correspond à un marqueur situé à l'intérieur de la carte.

Problème n ° 2: Lorsqu'un utilisateur clique sur un marqueur À L'INTÉRIEUR de la carte, il n'existe pas de moyen intégré pour extraire l'ID de ce marqueur, puis l'utiliser pour mettre en surbrillance un élément correspondant ou déclencher une action. carte. 

Solutions

L'utilisation d'une ou de plusieurs de ces options aidera à résoudre les problèmes décrits ci-dessus. Je commencerai par celui mentionné dans la réponse précédente. Voici le stylo de travail }, qui contient tout le code trouvé ci-dessous.

Option n ° 1: Enregistrez chaque marqueur à l’aide d’un ID codé en dur ou dynamique, à l’intérieur d’un objet -

// 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);
}

Semblable à l’autre réponse, vous pouvez maintenant accéder à un seul marqueur en utilisant -

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

Option 2:

Bien que Leaflet ne fournisse pas d’option «id» intégrée pour les marqueurs, vous pouvez ajouter directement un ID à l’élément en accédant à la propriété ._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;

Désormais, lorsque vous gérez des événements liés aux clics, il est facile d'obtenir l'identifiant de ce marqueur:

$('.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.')
});

Option n ° 3:

Une autre approche consisterait à utiliser l'interface layerGroup. Il fournit une méthode, getLayer, qui semble parfaite pour obtenir nos marqueurs avec un identifiant. Cependant, Leaflet ne fournit aucun moyen de spécifier un ID personnalisé ou un nom. Ce problème sur Github explique comment procéder. Cependant, vous pouvez obtenir et enregistrer l'ID généré automatiquement par n'importe quel marqueur (ou iLayer d'ailleurs) comme ceci:

var group = L.layerGroup()

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

Maintenant que nous avons enregistré chaque ID de marqueur avec chaque objet de sauvegarde dans notre tableau de données, nous pouvons facilement obtenir le marqueur plus tard, comme ceci:

group.getLayer(person.marker_id)

Voir ce stylo } _ pour un exemple complet ...

Option n ° 4:

Le moyen le plus simple de procéder, si vous avez le temps, consisterait à étendre la classe de marqueurs de la notice afin de répondre à vos besoins personnels de manière appropriée. Vous pouvez soit ajouter un identifiant aux options, soit insérer du code HTML personnalisé dans le marqueur contenant votre identifiant/classe. Voir le documentation pour plus d'informations à ce sujet.

Vous pouvez également utiliser le circleMarker qui, dans les options de chemin , a une option pour className qui peut être agréable pour le style de groupes de marqueurs similaires.

Coiffant:

Vous avez presque oublié que votre question initiale avait été posée dans un but de style ... utilisez simplement l'ID pour accéder à des éléments individuels:

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

Conclusion

Je mentionnerai également que les groupes de couches et de fonctionnalités constituent un autre excellent moyen de créer une interface avec les marqueurs. Voici une question qui en parle un peu. N'hésitez pas à bricoler ou à bifurquer le premier ou deuxième stylo et à commenter si j'ai oublié quelque chose.

33
Skip Jack

Un moyen facile de faire cela consiste à ajouter tous les marqueurs à une liste avec un identifiant unique.

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

Si la liste des restaurants a une propriété dans l'élément html d'un seul restaurant qui correspond à l'identifiant du marqueur ajouté. Quelque chose comme:

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

Ajoutez ensuite l'événement click où vous passerez l'id du restaurant (dans ce cas "data-restaurantID") et ferez quelque chose comme:

markersObject["passedValueFromTheClickedElement"].openPopup();

De cette façon, une fois que vous avez cliqué sur l'élément dans la liste, une fenêtre contextuelle de marqueurs s'ouvre pour vous indiquer l'emplacement du restaurant sur la carte.

6
Marko Letic
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;
}
3
Slava84

Dans mon cas, j’ai trouvé que le meilleur moyen était simplement de générer et de transmettre un ID unique à l’objet Options de L.marker lorsque je le crée.

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

Vous pouvez ensuite ajouter ce marqueur à un dépliant layerGroup.

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

Vous pouvez accéder à l'ID avec layer.options.uniqueID. Cela me permet de rechercher et de manipuler le marqueur ultérieurement; tout ce dont j'ai besoin, c'est .eachLayer() de Leaflet et son uniqueID.

Mon backend (Cloud Firestore) génère déjà des identifiants de document uniques, ce qui facilite grandement la synchronisation en temps réel de la carte de mon dépliant et de son backend.

//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);
  }
});
0
Brendan McGill