47

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?

robd
  • 9,646
  • 5
  • 40
  • 59
  • 1
    Have you tried [MarkerWithLabel](http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerwithlabel/docs/examples.html) – geocodezip Sep 08 '15 at 22:03
  • @geocodezip I looked at that, but I don't think MarkerWithLabel supports the icon path attribute for specifying the icon – robd Sep 08 '15 at 22:14
  • Anyone else with this problem, please consider voting for [this issue](https://code.google.com/p/gmaps-api-issues/issues/detail?id=8578) which would remove the need for MarkerWithLabel. – robd Sep 10 '15 at 10:13
  • I found a snippet over codepen and it works great. Check the answer below: http://stackoverflow.com/a/37582234/3553665 – jaspreet21anand Jun 02 '16 at 03:44
  • 4
    its fixed now in google maps api itself https://code.google.com/p/gmaps-api-issues/issues/detail?id=8578#c28 – Gaurav Shah Oct 25 '16 at 09:05
  • 2
    Like @GauravShah mentioned, the API now allows multi-character labels. For [usage examples of the new API, see my answer to a similar question](http://stackoverflow.com/a/40472150/638546). – Akseli Palén Nov 07 '16 at 18:56

7 Answers7

52

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>
RRikesh
  • 14,112
  • 5
  • 49
  • 70
geocodezip
  • 158,664
  • 13
  • 220
  • 245
  • 2
    Yes - I've been trying to get that working inlining the MarkerWithLabel into the callback function called by the google maps init script. But I see `Uncaught ReferenceError: MarkerWithLabel is not defined` when I try to call `new MarkerWithLabel(...)` – robd Sep 09 '15 at 16:36
  • OK, I got this working another way, by wrapping the MarkerWithLabel code in a function `function initMarkerWithLabel()` and calling it from the google maps callback. – robd Sep 09 '15 at 16:41
  • Hmm, OK I did manage to get this working, but I see problems with overlapping pins: http://jsfiddle.net/LLd4drvx/1/ – robd Sep 09 '15 at 16:48
  • Applying [the fix](https://github.com/cdaguerre/gmaps-utility-library/commit/4f71018696f179acabbe445f188fc2de13f60c3e) from this issue fixed the marker with overlapping labels – robd Sep 09 '15 at 17:17
  • That fix saved my ass! I was almost considering dropping the plugin altogether because of that issue. – undefinederror Mar 10 '16 at 11:47
  • 3
    markerwithlabel http://googlecode.com link is no longer working, alternate link is https://rawgit.com/nmccready/google-maps-utility-library-v3-markerwithlabel/master/dist/markerwithlabel.js – Shoaib Iqbal May 23 '16 at 10:00
  • 1
    can somebody update "the fix" for overlapping labels? the link is broken – Victor -------- Oct 15 '18 at 14:35
30

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.

RRikesh
  • 14,112
  • 5
  • 49
  • 70
jaspreet21anand
  • 779
  • 1
  • 6
  • 8
10

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?

Barry MSIH
  • 3,525
  • 5
  • 32
  • 53
robd
  • 9,646
  • 5
  • 40
  • 59
  • Hacky? Yes, totally. Gets the job done? Most definitely. I think this is the best solution until the Google Maps API is updated. – AndyG Jul 24 '16 at 20:37
  • I'll add for future devs: Remember to change the regex. For me it was just numbers, so `[0-9]+` will do. Additionally there needs to be a check on `matches` being null. Also, I modified `querySelectorAl("[style*='custom-label']")' to `querySelectorAl("[style*='custom-label-']")' and got rid of the `icon` portion of the marker. – AndyG Jul 24 '16 at 20:39
  • This was best solution for me. For me the "idle" event listener didn't always seem to pick up the dom elements added on zoom. (Seemed ok for panning, just wasn't reliable for zooming - perhaps because I am using in conjunction with MarkerClusterer). Instead I used setTimeout to check for existence of the smuggled font family every 100ms. This worked fine. Also useful to smuggle in a class for the label, if for example you want a background colour or similar. – dbarton_uk Aug 01 '16 at 14:07
  • This is less awful because marker and label are separate objects: https://github.com/googlemaps/js-map-label – Digs Oct 01 '19 at 03:54
4

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)

Apostolis
  • 83
  • 7
  • As Internet is a live being, I believe we should priorize the edge solutions... Sad Stackexchange works priorizing only number of votes, here's the documentation section for MarkerLabel inside official Google Maps JS API: https://developers.google.com/maps/documentation/javascript/3.exp/reference?hl=es-419#MarkerLabel – DavidTaubmann Feb 06 '17 at 01:33
1

For anyone trying to

...in 2019, it's worth noting some of the code referenced here no longer exists (officially). Google discontinued support for the "MarkerWithLabel" project a long time ago. It was originally hosted on Google code here, now it's unofficially hosted on Github here.

But there is another project Google maintained until 2016, called "MapLabel"s. That approach is different (and arguably better). You create a separate map label object with the same origin as the marker instead of adding a mapLabel option to the marker itself. You can make a marker with label with multiple characters using js-marker-label.

Digs
  • 645
  • 7
  • 9
  • 1
    ...And... they are deprecated (still 2019 btw). It is super frustrating that any rabbit hole for answers here leads to deprecated code, and the official documentation still links to missing code etc. Really makes you wonder if relying on Google's products for business is feasible long term. – robertlayton Dec 31 '19 at 11:31
1

You can change easy marker label css without use any extra plugin.

var marker = new google.maps.Marker({
        position: this.overlay_text,
        draggable: true,
        icon: '',
        label: {
          text: this.overlay_field_text,
          color: '#fff',
          fontSize: '20px',
          fontWeight: 'bold',
          fontFamily: 'custom-label'
        },
        map:map
      });
      marker.setMap(map);

$("[style*='custom-label']").css({'text-shadow': '2px 2px #000'})
David García Bodego
  • 1,058
  • 3
  • 13
  • 21
mayur
  • 19
  • 1
-1

A much simpler solution to this problem that allows letters, numbers and words as the label is the following code. More specifically, the line of code starting with "icon:". Any string or variable could be substituted for 'k'.

for (i = 0; i < locations.length; i++) 
      { 
      k = i + 1;
      marker = new google.maps.Marker({
      position: new google.maps.LatLng(locations[i][1], locations[i][2]),     
      map: map,
      icon: 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=' + k + '|FF0000|000000'
});

--- the locations array holds the lat and long and k is the row number for the address I was mapping. In other words if I had a 100 addresses to map my marker labels would be 1 to 100.

  • Unfortunately, this doesn't address the main problem which is to allow a longer label with a custom icon which can accommodate more chars. For the case of 2 or more letters, the letters are well outside the marker pin and it doesn't look good at all: http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=A9|FF0000|000000 http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=A99|FF0000|000000 I wouldn't be able to use this on the website I'm developing because it looks broken. – robd Dec 29 '15 at 16:24
  • http://chart.apis.google.com/ does not allow a custom icon. At least it does not allow even a simple circle instead of pin. – DotNet Fan Jan 26 '16 at 09:27