Dommarkers appear into incorrect position - here-api

I am adding markes using v3 Here Javascript api on the map shown on a website.
Adding a Marker object works perfectly, but when changing it to DomMarker the markers have a huge offset on the map and seem to get closer to their true position when zooming in. I've tried to search for similar issues, but could not find an answer. How can I get the DomMarkers shown in their true position correctly?
I am using Chrome browser.
Here's the code.
This works:
var icon = new H.map.Icon(svgMarkup);
var marker = new H.map.Marker({lat: startLat, lng: startLong}, {icon: icon});
map.addObject(marker);
This does not:
if (obsIcon == null){
obsIcon = new H.map.DomIcon(svgMarkup);
}
var marker = new H.map.DomMarker({lat: startLat, lng: startLong, ctx: 'GL' }, {icon: obsIcon});
map.addObject(marker);
EDIT: This is the code of the svgMarkup:
var svgMarkup = '<svg width="20" height="20" ' + 'xmlns="http://www.w3.org/2000/svg">' + '<circle cx="10" cy="10" r="5" stroke="#000" stroke-width="1" fill="'+ fColor+'" />'+ '</svg>';

What you describe seems to be a common issue when the anchor of your icon is incorrectly set. Your icon is offset by some pixels. That's why it seems that the marker moves closer to the actual position when zooming in.
Depending on what you icon looks like you may want to set the anchor when constructing your icon:
// assuming your icon is 40x40 pixels (change values as necessary)
var icon = new H.map.Icon(svgMarkup, { anchor: {x: 20, y: 40} }); //bottom-center
icon.setAnchor({x: 0, y: 0}) //top-left
icon.setAnchor({x: 20, y: 20}) //center
icon.setAnchor({x: 40, y: 0}) //top-right
EDIT
You need to manually translate your icon to get the same effect as anchors on DomIcons.
'<div><svg width="20" height="20" ' +
'xmlns="http://www.w3.org/2000/svg" ' +
'style="transform:translate(-10px, -10px)">' +
'<circle cx="10" cy="10" r="5" stroke="#000" stroke-width="1" fill="#ff00ff" />'+
'</svg><div>'
Note the div around the markup, as the DOM marker will put it's own transform on the outermost element. Then on the SVG inside I add a transform of -10/-10 to move the center of the circle to the top left corner. That should put your circle nicely at the center.

Related

How to highlight a marker in Here.com Maps for javascript API 3.1?

How do I change the color (or some other style) of a SVG marker on pointerenter? I found some examples in 2.3, but I'm using 3.1.
Here is a simple example of highlighting H.map.Marker on mouse over in Javascript version API 3.1 (works for 3.0 as well):
var svg = `<svg xmlns="http://www.w3.org/2000/svg" class="svg-icon" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50" fill="FILL_COLOR" opacity=".8"/>
<circle cx="50" cy="50" r="4" fill="black"/>
</svg>`,
size = {w: 30, h: 30},
// we need to specify the correct hit area as the default one for custom icon is rectangular shape
hitArea = new H.map.HitArea(H.map.HitArea.ShapeType.CIRCLE, [size.w/2, size.h/2, size.w/2]),
icon = new H.map.Icon(
svg.replace('FILL_COLOR', 'rgba(30, 200, 200, 0.7)'),
{
size,
anchor: {x: size.w/2, y: size.h/2},
hitArea
}
),
iconHover = new H.map.Icon(
svg.replace('FILL_COLOR', 'rgb(30, 200, 200'),
{
size,
anchor: {x: size.w/2, y: size.h/2},
hitArea
}
),
marker = new H.map.Marker(map.getCenter(), {
icon: icon,
volatility: true // <- volatile objects re-render faster
});
marker.addEventListener('pointerenter', function(e) {
marker.setIcon(iconHover);
});
marker.addEventListener('pointerleave', function(e) {
marker.setIcon(icon);
});
map.addObject(marker);
See it in action: jsfiddle.
I'm now using a DOM markers as a work around. It's simpler that way.

dynamic change style of an element (DomIcon)

I am stuck and need some advise. I just want to modify my DomIcon which is assigned to a DomMarker in a here map. It's been developed in Angular / Ionic and I simply want to rotate an PNG around the anchor.
I simply created new elements within my component. However, independently how I set the transform it is immediately overwritten with an updated tranform matrix.
var theFather = document.createElement('div');
var domElement = document.createElement('img')
domElement.setAttribute('class', 'theThing')
domElement.src ='./assets/icons/aThing.png'
domElement.style.width = '40px';
domElement.style.height = '40px';
theFather.appendChild(domElement);
I tried various alternatives discussed in the forum to rotate the thing but I always fail. Apparently, I completey miss something in my trials.
So,
1) Tried to simply transform:rotate by setting cssText or the style.transform of a cloned png img (DomIcon) within the attach callback. It rotates correctly and on the same pt but it only rotates if the clonedElement is rotated within the onAttach callback. Bad thing, I cannot update the clonedElement by an external event that is not a DOM or here API Event. Right?
var domIcon = new H.map.DomIcon(domElement, {
onAttach: function(clonedElement, domIcon, domMarker) {
clonedElement.addEventListener('mouseover', rotateThisThing);
}
2) Tried to simply rotate the original PNG but this is not transformed at all. I can see that the cssText is updated and correct but it is not rendered on the map.
domIcon.c.style.cssText += 'transform: rotate(90deg)';
3) Tried to set the elements style properties by calculating the rotation in a transform:matrix which correctly rotates the icon and set in the document itself but unfortunately this is very volatile.
document.getElementsByTagName("img")[i].style.cssText += 'transform: ' + newval;
4) Tried to set the elements style properties as to 3) but using renderer2
this.render2.setStyle(document.getElementsByClassName("theThing")[i],"transform",newval)
5) Tried to export a new CSS variable and rotate in CSS directly.
this.mapElement.nativeElement.style.setProperty('--the-rotator', value);
What am I missing here?
Your advice is very mich appreciated?
Many thanks in advance,
O.
The API manipulates Marker's position by changing the transform style property of the cloned Dom element. In your case clonedElement inside onAttach callback is a clone of theFather.
Your onAttach callback should therefore look e.g. like this:
var domIcon = new H.map.DomIcon(domElement, {
onAttach: function(clonedElement, domIcon, domMarker) {
clonedElement.getElementsByTagName("img")[i].style.transform = 'rotate(90deg)'
}
You can check below sample code which rotates arrow DomMarker every 1 second. See how reference to the cloned element is assigned to clonedElement variable which is then used in setInterval function.
var domIconElement = document.createElement('div'),
domIconContent = document.createElement('div'),
marker,
clonedContent,
counter = 0;
domIconContent.classList.add('dom-icon-content')
domIconContent.innerHTML = `<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="40" height="40">
<path d="m0.812665,23.806608l37.937001,-22.931615l-21.749812,38.749665l1.374988,-17.749847l-17.562177,1.931797z" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="#fff"/>
</svg>`;
domIconElement.appendChild(domIconContent);
marker = map.addObject(new H.map.DomMarker(map.getCenter(), {
icon: new H.map.DomIcon(domIconElement, {
onAttach: function(clonedElement, domIcon, domMarker) {
clonedContent = clonedElement.getElementsByClassName('dom-icon-content')[0];
}
})
}));
setInterval(function() {
if (clonedContent) {
clonedContent.style.transform = 'rotate(' + (counter += 45) + 'deg)';
}
}, 1000)

How to show label/text on Here Maps Polygon object

Here Maps official documentation for Polygon does not contain any reference about how to add a label for the polygon.
Polygon Documentation - https://developer.here.com/documentation/maps/topics_api/h-map-polygon.html
Here Maps Polygon Example - https://developer.here.com/api-explorer/maps-js/v3.0/geoshapes/polygon-on-the-map
I didn't find a straight-forward way, but with a few lines of code you can create a custom svg "icon" that contains only your text, and display it anywhere on the map:
var my_text = 'My text';
var svg = '<svg width="80" height="24" xmlns="http://www.w3.org/2000/svg"><text x="0" y="20" font-size="10pt" font-family="Arial">' + my_text + '</text></svg>';
var icon = new H.map.Icon(svg);
var marker = new H.map.Marker({lat: 52.5, lng: 13.4 }, {icon: icon});
map.addObject(marker);
This displays 'My text' over Berlin. You find more documentation at this example from the HERE documentation.

The calculation behind progress circle using dasharray and dashoffset

I'm building a small angularjs directive which will display a progress circle(I don't want animation) and there will be a text in the middle of it indicating the percentage of completion.
The html code of the circle is:
<path fill="none" stroke="rgb(0,51,117)" stroke-width="5" stroke-linecap="square" d="M25,2.5A22.5,22.5 0 1 1 2.5,25A22.5,22.5 0 0 1 25,2.5" stroke-dasharray="105" stroke-dashoffset="{{circle.percentage*(-140)/100 + 105 }}">
</path>
I don't know the calculation behind the dasharray and dashoffset, I get the calculation {{circle.percentage*(-140)/100 + 105 }} by adjusting the dashoffset and guessing.
I have a fiddle http://jsfiddle.net/ADukg/10992/
As you can see, it only works for the circles from 30% to 70%. Does anyone know the correct calculation of it? I use the CSS tag as one of the tags of my question because the calculation should also work in CSS. Thank you in advance
The radius of your circle is 22.5, so the correct length for your dash array should be
(2 * PI * 22.5) = 141.37
Secondly, you can just use stroke-dasharray by itself. No need to use stroke-dashoffset also.
stroke-dasharray="{{circle.percentage*142/100}} 142"
Updated fiddle
Note: I removed the stroke-linecap="square". You may want to put it back if you added that deliberately.
You could have two circles that overlay each other. The first circle being the gray outline and the second circle being the progress overlay. Then change the stroke-dasharray and stroke-dashoffset values of just the second circle and rotate the svg by 90 degrees:
html:
<circle cx="25" cy="25" r="22.5" stroke="rgb(188,188,188)" stroke-width="5" fill="none"></circle>
<circle cx="25" cy="25" r="22.5" stroke="rgb(0,51,117)" stroke-width="5" fill="none" stroke-dasharray="{{circle.circumference}}" stroke-dashoffset="{{circle.circumference * (1 - circle.percentage/100)}}"></circle>
js:
function MyCtrl($scope) {
var radius = 22.5;
var circumference = Math.PI*(radius*2);
$scope.circles = [];
for(var i=0; i<=10; i++){
var circle = {
percentage : i* 10,
circumference: circumference
};
$scope.circles.push(circle);
}
}
css:
.progress {
transform: rotate(-90deg);
}
Link to jsfiddle
I found this tutorial helpful.

Google Maps API 3 - Custom marker color for default (dot) marker

I've seen lots of other questions similar to this (here, here and here), but they all have accepted answers that don't solve my problem. The best solution I have found to the problem is the StyledMarker library, which does let you define custom colours for markers, but I can't get it to use the default marker (the one you get when you do a google maps search - with a dot in the middle), it just seems to provide markers with a letter in, or with a special icon.
You can dynamically request icon images from the Google charts api with the urls:
http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|FE7569
Which looks like this: the image is 21x34 pixels and the pin tip is at position (10, 34)
And you'll also want a separate shadow image (so that it doesn't overlap nearby icons):
http://chart.apis.google.com/chart?chst=d_map_pin_shadow
Which looks like this: the image is 40x37 pixels and the pin tip is at position (12, 35)
When you construct your MarkerImages you need to set the size and anchor points accordingly:
var pinColor = "FE7569";
var pinImage = new google.maps.MarkerImage("http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|" + pinColor,
new google.maps.Size(21, 34),
new google.maps.Point(0,0),
new google.maps.Point(10, 34));
var pinShadow = new google.maps.MarkerImage("http://chart.apis.google.com/chart?chst=d_map_pin_shadow",
new google.maps.Size(40, 37),
new google.maps.Point(0, 0),
new google.maps.Point(12, 35));
You can then add the marker to your map with:
var marker = new google.maps.Marker({
position: new google.maps.LatLng(0,0),
map: map,
icon: pinImage,
shadow: pinShadow
});
Simply replace "FE7569" with the color code you're after. Eg:
Credit due to Jack B Nimble for the inspiration ;)
If you use Google Maps API v3 you can use setIcon e.g.
marker.setIcon('http://maps.google.com/mapfiles/ms/icons/green-dot.png')
Or as part of marker init:
marker = new google.maps.Marker({
icon: 'http://...'
});
Other colours:
Blue marker
Red marker
Purple marker
Yellow marker
Green marker
Use the following piece of code to update default markers with different colors.
(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ROSE)
Here is a nice solution using the Gooogle Maps API itself. No external service, no extra library. And it enables custom shapes and multiple colors and styles. The solution uses vectorial markers, which googlemaps api calls Symbols.
Besides the few and limited predefined symbols, you can craft any shape of any color by specifying an SVG path string (Spec).
To use it, instead of setting the 'icon' marker option to the image url, you set it to a dictionary containing the symbol options. As example, I managed to craft one symbol that is quite similar to the standard marker:
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 M -2,-30 a 2,2 0 1,1 4,0 2,2 0 1,1 -4,0',
fillColor: color,
fillOpacity: 1,
strokeColor: '#000',
strokeWeight: 2,
scale: 1,
};
}
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(latitude, longitude),
icon: pinSymbol("#FFF"),
});
I you are careful to keep the shape key point at 0,0 you avoid having to define marker icon centering parameters. Another path example, the same marker without the dot:
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',
And here you have a very simple and ugly coloured flag:
path: 'M 0,0 -1,-2 V -43 H 1 V -2 z M 1,-40 H 30 V -20 H 1 z',
You can also create the paths using a visual tool like Inkscape (GNU-GPL, multiplatform). Some useful hints:
Google API just accepts a single path, so you have to turn any other object (square, cercle...) into a path and join them as a single one. Both commands at the Path menu.
To move the path to the (0,0), go to the Path Edit mode (F2) select all
the control nodes and drag them. Moving the object with F1, won't change the path node coords.
To ensure the reference point is at (0,0), you can select it alone and edit the coords by hand on the top toolbar.
After saving the SVG file, which is an XML, open it with an editor, look for the svg:path element and copy the content of the 'd' attribute.
Well the closest thing I've been able to get with the StyledMarker is this.
The bullet in the middle isn't quite a big as the default one though. The StyledMarker class simply builds this url and asks the google api to create the marker.
From the class use example use "%E2%80%A2" as your text, as in:
var styleMaker2 = new StyledMarker({styleIcon:new StyledIcon(StyledIconTypes.MARKER,{text:"%E2%80%A2"},styleIconClass),position:new google.maps.LatLng(37.263477473067, -121.880502070713),map:map});
You will need to modifiy StyledMarker.js to comment out the lines:
if (text_) {
text_ = text_.substr(0,2);
}
as this will trim the text string to 2 characters.
Alternatively you could create custom marker images based on the default one with the colors you desire and override the default marker with code such as this:
marker = new google.maps.Marker({
map:map,
position: latlng,
icon: new google.maps.MarkerImage(
'http://www.gettyicons.com/free-icons/108/gis-gps/png/24/needle_left_yellow_2_24.png',
new google.maps.Size(24, 24),
new google.maps.Point(0, 0),
new google.maps.Point(0, 24)
)
});
I've extended vokimon's answer a bit, making it a bit more convenient for changing other properties as well.
function customIcon (opts) {
return Object.assign({
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 M -2,-30 a 2,2 0 1,1 4,0 2,2 0 1,1 -4,0',
fillColor: '#34495e',
fillOpacity: 1,
strokeColor: '#000',
strokeWeight: 2,
scale: 1,
}, opts);
}
Usage:
marker.setIcon(customIcon({
fillColor: '#fff',
strokeColor: '#000'
}));
Or when defining a new marker:
const marker = new google.maps.Marker({
position: {
lat: ...,
lng: ...
},
icon: customIcon({
fillColor: '#2ecc71'
}),
map: map
});
Hi you can use icon as SVG and set colors. See this code
/*
* declare map and places as a global variable
*/
var map;
var places = [
['Place 1', "<h1>Title 1</h1>", -0.690542, -76.174856,"red"],
['Place 2', "<h1>Title 2</h1>", -5.028249, -57.659052,"blue"],
['Place 3', "<h1>Title 3</h1>", -0.028249, -77.757507,"green"],
['Place 4', "<h1>Title 4</h1>", -0.800101286, -76.78747820,"orange"],
['Place 5', "<h1>Title 5</h1>", -0.950198, -78.959302,"#FF33AA"]
];
/*
* use google maps api built-in mechanism to attach dom events
*/
google.maps.event.addDomListener(window, "load", function () {
/*
* create map
*/
var map = new google.maps.Map(document.getElementById("map_div"), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
});
/*
* create infowindow (which will be used by markers)
*/
var infoWindow = new google.maps.InfoWindow();
/*
* create bounds (which will be used auto zoom map)
*/
var bounds = new google.maps.LatLngBounds();
/*
* marker creater function (acts as a closure for html parameter)
*/
function createMarker(options, html) {
var marker = new google.maps.Marker(options);
bounds.extend(options.position);
if (html) {
google.maps.event.addListener(marker, "click", function () {
infoWindow.setContent(html);
infoWindow.open(options.map, this);
map.setZoom(map.getZoom() + 1)
map.setCenter(marker.getPosition());
});
}
return marker;
}
/*
* add markers to map
*/
for (var i = 0; i < places.length; i++) {
var point = places[i];
createMarker({
position: new google.maps.LatLng(point[2], point[3]),
map: map,
icon: {
path: "M27.648 -41.399q0 -3.816 -2.7 -6.516t-6.516 -2.7 -6.516 2.7 -2.7 6.516 2.7 6.516 6.516 2.7 6.516 -2.7 2.7 -6.516zm9.216 0q0 3.924 -1.188 6.444l-13.104 27.864q-0.576 1.188 -1.71 1.872t-2.43 0.684 -2.43 -0.684 -1.674 -1.872l-13.14 -27.864q-1.188 -2.52 -1.188 -6.444 0 -7.632 5.4 -13.032t13.032 -5.4 13.032 5.4 5.4 13.032z",
scale: 0.6,
strokeWeight: 0.2,
strokeColor: 'black',
strokeOpacity: 1,
fillColor: point[4],
fillOpacity: 0.85,
},
}, point[1]);
};
map.fitBounds(bounds);
});
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?v=3"></script>
<div id="map_div" style="height: 400px;"></div>
since version 3.11 of the google maps API, the Icon object replaces MarkerImage. Icon supports the same parameters as MarkerImage. I even found it to be a bit more straight forward.
An example could look like this:
var image = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
for further information check this site
As others have mentioned, vokimon's answer is great but unfortunately Google Maps is a bit slow when there are many SymbolPath/SVG-based markers at once.
It looks like using a Data URI is much faster, approximately on par with PNGs.
Also, since it's a full SVG document, it's possible to use a proper filled circle for the dot. The path is modified so it is no longer offset to the top-left, so the anchor needs to be defined.
Here's a modified version that generates these markers:
var coloredMarkerDef = {
svg: [
'<svg viewBox="0 0 22 41" width="22px" height="41px" xmlns="http://www.w3.org/2000/svg">',
'<path d="M 11,41 c -2,-20 -10,-22 -10,-30 a 10,10 0 1 1 20,0 c 0,8 -8,10 -10,30 z" fill="{fillColor}" stroke="#ffffff" stroke-width="1.5"/>',
'<circle cx="11" cy="11" r="3"/>',
'</svg>'
].join(''),
anchor: {x: 11, y: 41},
size: {width: 22, height: 41}
};
var getColoredMarkerSvg = function(color) {
return coloredMarkerDef.svg.replace('{fillColor}', color);
};
var getColoredMarkerUri = function(color) {
return 'data:image/svg+xml,' + encodeURIComponent(getColoredMarkerSvg(color));
};
var getColoredMarkerIcon = function(color) {
return {
url: getColoredMarkerUri(color),
anchor: coloredMarkerDef.anchor,
size: coloredMarkerDef.size,
scaledSize: coloredMarkerDef.size
}
};
Usage:
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(latitude, longitude),
icon: getColoredMarkerIcon("#FFF")
});
The downside, much like a PNG image, is the whole rectangle is clickable. In theory it's not too difficult to trace the SVG path and generate a MarkerShape polygon.
In Internet Explorer, this solution does not work in ssl.
One can see the error in console as:
SEC7111: HTTPS security is compromised by this,
Workaround : As one of the user here suggested replace
chart.apis.google.com to chart.googleapis.com for the URL path to avoid SSL error.
You can use this code it works fine.
var pinImage = new google.maps.MarkerImage("http://www.googlemapsmarkers.com/v1/009900/");<br>
var marker = new google.maps.Marker({
position: yourlatlong,
icon: pinImage,
map: map
});
Combine a symbol-based marker whose path draws the outline, with a '●' character for the center. You can substitute the dot with other text ('A', 'B', etc.) as desired.
This function returns options for a marker with the a given text (if any), text color, and fill color. It uses the text color for the outline.
function createSymbolMarkerOptions(text, textColor, fillColor) {
return {
icon: {
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: fillColor,
fillOpacity: 1,
strokeColor: textColor,
strokeWeight: 1.8,
labelOrigin: { x: 0, y: -30 }
},
label: {
text: text || '●',
color: textColor
}
};
}
I try two ways to create the custom google map marker, this run code used canvg.js is the best compatibility for browser.the Commented-Out Code is not support IE11 urrently.
var marker;
var CustomShapeCoords = [16, 1.14, 21, 2.1, 25, 4.2, 28, 7.4, 30, 11.3, 30.6, 15.74, 25.85, 26.49, 21.02, 31.89, 15.92, 43.86, 10.92, 31.89, 5.9, 26.26, 1.4, 15.74, 2.1, 11.3, 4, 7.4, 7.1, 4.2, 11, 2.1, 16, 1.14];
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 13,
center: {
lat: 59.325,
lng: 18.070
}
});
var markerOption = {
latitude: 59.327,
longitude: 18.067,
color: "#" + "000",
text: "ha"
};
marker = createMarker(markerOption);
marker.setMap(map);
marker.addListener('click', changeColorAndText);
};
function changeColorAndText() {
var iconTmpObj = createSvgIcon( "#c00", "ok" );
marker.setOptions( {
icon: iconTmpObj
} );
};
function createMarker(options) {
//IE MarkerShape has problem
var markerObj = new google.maps.Marker({
icon: createSvgIcon(options.color, options.text),
position: {
lat: parseFloat(options.latitude),
lng: parseFloat(options.longitude)
},
draggable: false,
visible: true,
zIndex: 10,
shape: {
coords: CustomShapeCoords,
type: 'poly'
}
});
return markerObj;
};
function createSvgIcon(color, text) {
var div = $("<div></div>");
var svg = $(
'<svg width="32px" height="43px" viewBox="0 0 32 43" xmlns="http://www.w3.org/2000/svg">' +
'<path style="fill:#FFFFFF;stroke:#020202;stroke-width:1;stroke-miterlimit:10;" d="M30.6,15.737c0-8.075-6.55-14.6-14.6-14.6c-8.075,0-14.601,6.55-14.601,14.6c0,4.149,1.726,7.875,4.5,10.524c1.8,1.801,4.175,4.301,5.025,5.625c1.75,2.726,5,11.976,5,11.976s3.325-9.25,5.1-11.976c0.825-1.274,3.05-3.6,4.825-5.399C28.774,23.813,30.6,20.012,30.6,15.737z"/>' +
'<circle style="fill:' + color + ';" cx="16" cy="16" r="11"/>' +
'<text x="16" y="20" text-anchor="middle" style="font-size:10px;fill:#FFFFFF;">' + text + '</text>' +
'</svg>'
);
div.append(svg);
var dd = $("<canvas height='50px' width='50px'></cancas>");
var svgHtml = div[0].innerHTML;
//todo yao gai bu dui
canvg(dd[0], svgHtml);
var imgSrc = dd[0].toDataURL("image/png");
//"scaledSize" and "optimized: false" together seems did the tricky ---IE11 && viewBox influent IE scaledSize
//var svg = '<svg width="32px" height="43px" viewBox="0 0 32 43" xmlns="http://www.w3.org/2000/svg">'
// + '<path style="fill:#FFFFFF;stroke:#020202;stroke-width:1;stroke-miterlimit:10;" d="M30.6,15.737c0-8.075-6.55-14.6-14.6-14.6c-8.075,0-14.601,6.55-14.601,14.6c0,4.149,1.726,7.875,4.5,10.524c1.8,1.801,4.175,4.301,5.025,5.625c1.75,2.726,5,11.976,5,11.976s3.325-9.25,5.1-11.976c0.825-1.274,3.05-3.6,4.825-5.399C28.774,23.813,30.6,20.012,30.6,15.737z"/>'
// + '<circle style="fill:' + color + ';" cx="16" cy="16" r="11"/>'
// + '<text x="16" y="20" text-anchor="middle" style="font-size:10px;fill:#FFFFFF;">' + text + '</text>'
// + '</svg>';
//var imgSrc = 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg);
var iconObj = {
size: new google.maps.Size(32, 43),
url: imgSrc,
scaledSize: new google.maps.Size(32, 43)
};
return iconObj;
};
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Your Custom Marker </title>
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="https://canvg.github.io/canvg/canvg.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>
</body>
</html>
I tried for a long time to improve vokimon's drawn marker and make it more similar to Google Maps one (and pretty much succeeded). This is the code I got:
let circle=true;
path = 'M 0,0 C -0.7,-9 -3,-14 -5.5,-18.5 '+
'A 16,16 0 0,1 -11,-29 '+
'A 11,11 0 1,1 11,-29 '+
'A 16,16 0 0,1 5.5,-18.5 '+
'C 3,-14 0.7,-9 0,0 z '+
['', 'M -2,-28 '+
'a 2,2 0 1,1 4,0 2,2 0 1,1 -4,0'][new Number(circle)];
I also scaled it by 0.8.
These are custom Circular markers
small_red:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAiklEQVR42mNgQIAoIF4NxGegdCCSHAMzEC+NUlH5v9rF5f+ZoCAwHaig8B8oPhOmKC1NU/P//7Q0DByrqgpSGAtSdOCAry9WRXt9fECK9oIUPXwYFYVV0e2ICJCi20SbFAuyG5uiECUlkKIQmOPng3y30d0d7Lt1bm4w301jQAOgcNoIDad1yOEEAFm9fSv/VqtJAAAAAElFTkSuQmCC
small_yellow:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAi0lEQVR42mNgQIAoIF4NxGegdCCSHAMzEC+NijL7v3p1+v8zZ6rAdGCg4X+g+EyYorS0NNv////PxMCxsRYghbEgRQcOHCjGqmjv3kKQor0gRQ8fPmzHquj27WaQottEmxQLshubopAQI5CiEJjj54N8t3FjFth369ZlwHw3jQENgMJpIzSc1iGHEwB8p5qDBbsHtAAAAABJRU5ErkJggg==
small_green:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAiElEQVR42mNgQIAoIF4NxGegdCCSHAMzEC81izL7n746/X/VmSowbRho+B8oPhOmKM02zfb/TCzQItYCpDAWpOhA8YFirIoK9xaCFO0FKXrY/rAdq6Lm280gRbeJNikWZDc2RUYhRiBFITDHzwf5LmtjFth3GesyYL6bxoAGQOG0ERpO65DDCQDX7ovT++K9KQAAAABJRU5ErkJggg==
small_blue:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAiklEQVR42mNgQIAoIF4NxGegdCCSHAMzEC81M4v6n56++n9V1RkwbWgY+B8oPhOmKM3WNu3/zJn/MbCFRSxIYSxI0YHi4gNYFRUW7gUp2gtS9LC9/SFWRc3Nt0GKbhNtUizIbmyKjIxCQIpCYI6fD/JdVtZGsO8yMtbBfDeNAQ2AwmkjNJzWIYcTAMk+i9OhipcQAAAAAElFTkSuQmCC
small_purple:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAi0lEQVR42mNgQIAoIF4NxGegdCCSHAMzEC+NMov6vzp99f8zVWfAdKBh4H+g+EyYorQ027T//2f+x8CxFrEghbEgRQcOFB/Aqmhv4V6Qor0gRQ8ftj/Equh2822QottEmxQLshubohCjEJCiEJjj54N8tzFrI9h36zLWwXw3jQENgMJpIzSc1iGHEwBt95qDejjnKAAAAABJRU5ErkJggg==
They are 9x9 png images.
Once they're on your page you can just drag them off and you'll have the actual png file.
change it to chart.googleapis.com for the path, otherwise SSL won't work
Using swift and Google Maps Api v3, this was the easiest way I was able to do it:
icon = GMSMarker.markerImageWithColor(UIColor.blackColor())
hope it helps someone.
Sometimes something really simple, can be answered complex. I am not saying that any of the above answers are incorrect, but I would just apply, that it can be done as simple as this:
I know this question is old, but if anyone just wants to change to pin or marker color, then check out the documentation: https://developers.google.com/maps/documentation/android-sdk/marker
when you add your marker simply set the icon-property:
GoogleMap gMap;
LatLng latLng;
....
// write your code...
....
gMap.addMarker(new MarkerOptions()
.position(latLng)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
There are 10 default colors to choose from. If that isn't enough (the simple solution) then I would probably go for the more complex given in the other answers, fulfilling a more complex need.
ps: I've written something similar in another answer and therefore I should refer to that answer, but the last time I did that, I was asked to post the answer since it was so short (as this one)..
You can use color code also.
const marker: Marker = this.map.addMarkerSync({
icon: '#008000',
animation: 'DROP',
position: {lat: 39.0492127, lng: -111.1435662},
map: this.map,
});

Resources