web-dev-qa-db-fra.com

Google maps Label Marker avec plusieurs caractères

J'essaie d'ajouter une étiquette de 4 caractères (par exemple, "A123") à un marqueur Google Maps comportant une icône large définie avec un chemin personnalisé.

var marker = new google.maps.Marker({
  position: latLon,
  label: { text: 'A123' },
  map: map,
  icon: {
    path: 'custom icon path',
    fillColor: '#000000',
    labelOrigin: new google.maps.Point(26.5, 20),
    anchor: new google.maps.Point(26.5, 43)
    scale: 1,
  }
});

Le API du marqueur est limité à un seul caractère. Il suffit donc d'afficher un marqueur avec 'A' dans l'exemple ci-dessus. J'ai essayé d'utiliser les outils de développement chrome pour pirater le code HTML créé par gmaps et rétablir le libellé plus long. Il s’affiche parfaitement sans aucune modification du fichier css requis, il me faut donc trouver un moyen de rétablir les autres caractères de l’étiquette que Google Maps a supprimés.

J'ai soulevé un problème Google Maps pour demander la levée de cette restriction. Pensez à voter pour le problème Google en visitant le lien ci-dessus et en le mettant en vedette pour encourager Google à le résoudre - merci!

Mais entre-temps, existe-t-il une solution de contournement que je peux utiliser pour supprimer la restriction d'un caractère?

Est-il possible de créer une extension personnalisée de google.maps.Marker pour afficher mon libellé plus long?

41
robd

Vous pouvez utiliser MarkerWithLabel avec des icônes SVG.

Mise à jour: L'API v3 de Google Maps prend désormais en charge de manière native plusieurs caractères dans le MarkerLabel

preuve de concept fiddle (vous n'avez pas fourni votre icône, alors j'en ai créé une)

Remarque: il existe un problème avec les étiquettes sur les marqueurs se chevauchant qui est traité par ce correctif , crédit à robd qui l'a signalé dans le commentaires

extrait de code:

function initMap() {
  var latLng = new google.maps.LatLng(49.47805, -123.84716);
  var homeLatLng = new google.maps.LatLng(49.47805, -123.84716);

  var map = new google.maps.Map(document.getElementById('map_canvas'), {
    zoom: 12,
    center: latLng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  });

  var marker = new MarkerWithLabel({
    position: homeLatLng,
    map: map,
    draggable: true,
    raiseOnDrag: true,
    labelContent: "ABCD",
    labelAnchor: new google.maps.Point(15, 65),
    labelClass: "labels", // the CSS class for the label
    labelInBackground: false,
    icon: pinSymbol('red')
  });

  var iw = new google.maps.InfoWindow({
    content: "Home For Sale"
  });
  google.maps.event.addListener(marker, "click", function(e) {
    iw.open(map, this);
  });
}

function pinSymbol(color) {
  return {
    path: 'M 0,0 C -2,-20 -10,-22 -10,-30 A 10,10 0 1,1 10,-30 C 10,-22 2,-20 0,0 z',
    fillColor: color,
    fillOpacity: 1,
    strokeColor: '#000',
    strokeWeight: 2,
    scale: 2
  };
}
google.maps.event.addDomListener(window, 'load', initMap);
html,
body,
#map_canvas {
  height: 500px;
  width: 500px;
  margin: 0px;
  padding: 0px
}
.labels {
  color: white;
  background-color: red;
  font-family: "Lucida Grande", "Arial", sans-serif;
  font-size: 10px;
  text-align: center;
  width: 30px;
  white-space: nowrap;
}
<script src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry,places&ext=.js"></script>
<script src="https://cdn.rawgit.com/googlemaps/v3-utility-library/master/markerwithlabel/src/markerwithlabel.js"></script>
<div id="map_canvas" style="height: 400px; width: 100%;"></div>
49
geocodezip

Tout d'abord, merci à l'auteur du code!

J'ai trouvé le lien ci-dessous en cherchant sur Google. Il est très simple et fonctionne mieux. N'échouerait jamais à moins que SVG ne soit obsolète.

https://codepen.io/moistpaint/pen/ywFDe/

Il y a quelques erreurs de chargement js dans le code ici, mais cela fonctionne parfaitement sur le lien codepen.io fourni.

var mapOptions = {
    zoom: 16,
    center: new google.maps.LatLng(-37.808846, 144.963435)
  };
  map = new google.maps.Map(document.getElementById('map-canvas'),
      mapOptions);


var pinz = [
    {
        'location':{
            'lat' : -37.807817,
            'lon' : 144.958377
        },
        'lable' : 2
    },
    {
        'location':{
            'lat' : -37.807885,
            'lon' : 144.965415
        },
        'lable' : 42
    },
    {
        'location':{
            'lat' : -37.811377,
            'lon' : 144.956596
        },
        'lable' : 87
    },
    {
        'location':{
            'lat' : -37.811293,
            'lon' : 144.962883
        },
        'lable' : 145
    },
    {
        'location':{
            'lat' : -37.808089,
            'lon' : 144.962089
        },
        'lable' : 999
    },
];

 

for(var i = 0; i <= pinz.length; i++){
   var image = 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2238%22%20height%3D%2238%22%20viewBox%3D%220%200%2038%2038%22%3E%3Cpath%20fill%3D%22%23808080%22%20stroke%3D%22%23ccc%22%20stroke-width%3D%22.5%22%20d%3D%22M34.305%2016.234c0%208.83-15.148%2019.158-15.148%2019.158S3.507%2025.065%203.507%2016.1c0-8.505%206.894-14.304%2015.4-14.304%208.504%200%2015.398%205.933%2015.398%2014.438z%22%2F%3E%3Ctext%20transform%3D%22translate%2819%2018.5%29%22%20fill%3D%22%23fff%22%20style%3D%22font-family%3A%20Arial%2C%20sans-serif%3Bfont-weight%3Abold%3Btext-align%3Acenter%3B%22%20font-size%3D%2212%22%20text-anchor%3D%22middle%22%3E' + pinz[i].lable + '%3C%2Ftext%3E%3C%2Fsvg%3E';

  
   var myLatLng = new google.maps.LatLng(pinz[i].location.lat, pinz[i].location.lon);
   var marker = new google.maps.Marker({
      position: myLatLng,
      map: map,
      icon: image
  });
}
html, body, #map-canvas {
  height: 100%;
  margin: 0px;
  padding: 0px
}
<div id="map-canvas"></div>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDtc3qowwB96ObzSu2vvjEoM2pVhZRQNSA&signed_in=true&callback=initMap&libraries=drawing,places"></script>

Vous avez juste besoin de coder en uri votre code html SVG et de remplacer celui de la variable image après "data: image/svg + xml" dans la boucle for.

Pour le codage URI, vous pouvez utiliser ri-encoder-decoder

Vous pouvez d'abord décoder le code svg existant pour mieux comprendre ce qui est écrit.

24
jaspreet21anand

OK, voici une solution que je propose est assez foiré.

Je mets l'intégralité du texte de l'étiquette dans la div à l'aide de l'attribut label fontFamily. Ensuite, j'utilise querySelectorAll pour faire correspondre les attributs de style résultants afin d'extraire les références et de réécrire les balises une fois la carte chargée:

var label = "A123";
var marker = new google.maps.Marker({
  position: latLon,
  label: {
    text: label,
    // Add in the custom label here
    fontFamily: 'Roboto, Arial, sans-serif, custom-label-' + label
  },
  map: map,
  icon: {
    path: 'custom icon path',
    fillColor: '#000000',
    labelOrigin: new google.maps.Point(26.5, 20),
    anchor: new google.maps.Point(26.5, 43), 
    scale: 1
  }
});

google.maps.event.addListener(map, 'idle', function() {
  var labels = document.querySelectorAll("[style*='custom-label']")
  for (var i = 0; i < labels.length; i++) {
    // Retrieve the custom labels and rewrite the tag content
    var matches = labels[i].getAttribute('style').match(/custom-label-(A\d\d\d)/);
    labels[i].innerHTML = matches[1];
  }
});

Cela semble assez fragile. Existe-t-il des approches moins terribles?

7
robd

À partir de la version 3.26.10 de l'API, vous pouvez définir l'étiquette de marqueur avec plusieurs caractères. La restriction est levée.

Essayez, ça marche!

De plus, en utilisant un objet MarkerLabel au lieu d'une chaîne, vous pouvez définir un certain nombre de propriétés pour l'apparence. Si vous utilisez une icône personnalisée, vous pouvez définir la propriété labelOrigin pour repositionner l'étiquette.

Source: https://code.google.com/p/gmaps-api-issues/issues/detail?id=8578#c (vous pouvez également signaler tout problème à ce sujet en cliquant sur le lien ci-dessus. fil)

3
Apostolis