Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google maps Marker Label with multiple characters

I am trying to add a 4 character label (eg 'A123') to a Google Maps marker which has a wide icon defined with a custom path.

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

The marker label API is restricted to a single character, so just shows a marker with 'A' in the example above. I have tried using chrome developer tools to hack the html which is created by gmaps and reinstate the longer label. It displays perfectly with no modifications to the css required, so I just need to find a way to reinstate the other label chars which Google maps has stripped.

I raised a Google Maps Issue to request that this restriction be lifted. Please consider voting for the Google issue by visiting link above and starring the issue to encourage Google to fix it - thanks!

But in the meantime, is there a workaround I can use to remove the one char restriction?

Is there a way I can create a custom extension of google.maps.Marker to show my longer label?

like image 895
robd Avatar asked Sep 08 '15 21:09

robd


4 Answers

You can use MarkerWithLabel with SVG icons.

Update: The Google Maps Javascript API v3 now natively supports multiple characters in the MarkerLabel

proof of concept fiddle (you didn't provide your icon, so I made one up)

Note: there is an issue with labels on overlapping markers that is addressed by this fix, credit to robd who brought it up in the comments.

code snippet:

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>
like image 135
geocodezip Avatar answered Sep 20 '22 11:09

geocodezip


First of all, Thanks to code author!

I found the below link while googling and it is very simple and works best. Would never fail unless SVG is deprecated.

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

There is some js loading error in the code here but its perfectly working on the codepen.io link provided.

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>

You just need to uri-encode your SVG html and replace the one in the image variable after "data:image/svg+xml" in the for loop.

For uri encoding you can use uri-encoder-decoder

You can decode the existing svg code first to get a better understanding of what is written.

like image 23
jaspreet21anand Avatar answered Sep 22 '22 11:09

jaspreet21anand


OK, here is one solution I have come up with which is pretty messed up.

I put the full label text into the div using the fontFamily label attribute. Then I use querySelectorAll to match the resulting style attributes to pull out the refs and rewrite the tags once the map has loaded:

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

This seems pretty brittle. Are there any approaches which are less awful?

like image 37
robd Avatar answered Sep 22 '22 11:09

robd


As of API version 3.26.10, you can set the marker label with more than one characters. The restriction is lifted.

Try it, it works!

Moreover, using a MarkerLabel object instead of just a string, you can set a number of properties for the appearance, and if using a custom Icon you can set the labelOrigin property to reposition the label.

Source: https://code.google.com/p/gmaps-api-issues/issues/detail?id=8578#c30 (also, you can report any issues regarding this at the above linked thread)

like image 23
Apostolis Avatar answered Sep 20 '22 11:09

Apostolis