Google Maps with D3.geo.path - javascript

I'm trying to follow the example in this videos:
https://www.youtube.com/watch?v=wqPGFs0cqxI
It's about drawing path with D3.js into Google Maps API. The console shows me the error Uncaught TypeError: Object#<PolylineContext>" has no method 'setCurrent'.
The index.html
<head>
<title>App</title>
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map-canvas { height: 100%; }
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false">
</script>
<script src="http://d3js.org/d3.v3.js" charset="utf-8"></script>
<script src="polyline_context.js"></script>
<script type="text/javascript">
var map;
var polyline;
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(53.567, 9.944),
zoom: 2,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
polyline = new google.maps.Polyline({
map: map
});
d3init();
}
var context;
var width;
var height;
var path;
var graticule;
var equator;
var projection;
function d3init() {
width = map.getDiv().offsetWidth;
height = map.getDiv().offsetHeight;
projection = d3.geo.equirectangular()
.translate([0, 0])
.scale(52.29578)
.precision(2)
context = new PolylineContext();
path = d3.geo.path().projection(projection).context(context);
equator = {type: 'LineString', coordinates: [[-180, 20], [-90, 0], [0, -20], [90, 0], [180, 20]]};
render();
}
function render() {
polyline.setOptions({
strokeColor: 'red',
strokeWeight: 2
});
context.setCurrent(polyline.getPath());
path(equator);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas">
</div>
</body>
The Polyline_context.js
'use strict';
function PolylineContext () {
this.currentPath = null;
this.currentIndex = 0;
}
PolylineContext.prototype.beginPath = function() {};
PolylineContext.prototype.moveTo = function(x, y) {
if (this.currentPath) {
var latLng = new google.maps.LatLng(y, x);
this.currentPath.setAt(this.currentIndex, latLng);
this.currentIndex++;
}
};
PolylineContext.prototype.lineTo = function(x, y) {
if (this.currentPath) {
var latLng = new google.maps.LatLng(y, x);
this.currentPath.setAt(this.currentIndex, latLng);
this.currentIndex++;
}
};
PolylineContext.prototype.arc = function(x, y, radius, startAngle, endAngle) {};
PolylineContext.prototype.closePath = function() {};
Any ideas of what's wrong in here?

Fairly old question. But just getting started with the same topic. Just in case somebody else stumbles upon this. Just put this inside the polyline_context.js file and see it come to live:
PolylineContext.prototype.setCurrent = function (path) {
this.currentPath = path;
};
What was shown in the video and what needs to be implemented is not necessarily in sync.

To set the path just use this code instead:
context.currentPath = polyline.getPath();

Related

Save Openlayers map as PDF (offline version)

I would like to save my openlayers map as PDF.
Unfortunately all the options I tried don't work.
The first option, I guess the easiest one was here:
https://jsfiddle.net/Ljnya5gp/1/
from which I developed something like this:
function createPdf() {
var doc = new jsPDF();
source = $('#map')[0];
specialElementHandlers = {
'#map': function (element, renderer) {
return true
}
};
doc.fromHTML(
source,
15,
15,
{
'width': 170,
'elementHandlers': specialElementHandlers
}
);
doc.save('Area 5 map - alterations.pdf')
but the script downloads only blank document for me.
I want to have this section downloaded (from index.html)
<div id="map">
<div id="popup" class="ol-popup">
<div id="popup-content"></div>
</div>
</div>
Why the output PDF document is blank? Is it caused by Map script, which is embedded into the HTML file?
My <div id="map"> refers to the script attached to the HTML file as the:
The jsfiddle can be found here:
https://jsfiddle.net/rjetdvyo/
Is it something which causes the problem too?
UPDATE:
Based on the answer below I formed something like this:
function createPdf() {
var mapElement = $("#map");
html2canvas(mapElement, {
useCORS: true,
onrendered: function (canvas) {
var img = canvas.toDataURL("image/jpeg,1.0");
var pdf = new jsPDF();
pdf.addImage(img, 'JPEG', 15, 40, 180, 180);
pdf.save('a4.pdf')
}
});
}
var map = (document.getElementById('map'), createPdf);
The printpdf button only refreshes the page.
I think everything is ok, it was showing blank because you didn't write any text into div. Have a look:
function createPdf() {
var doc = new jsPDF();
source = $('#map')[0];
specialElementHandlers = {
'#map': function (element, renderer) {
return true
}
};
doc.fromHTML(
source,
15,
15,
{
'width': 170,
'elementHandlers': specialElementHandlers
}
);
doc.save('Area 5 map - alterations.pdf')
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"
integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg=="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
<div id="map">
<div id="popup" class="ol-popup">
Hello
<div id="popup-content"><h1>Hello, this is a H1 tag</h1></div>
</div>
</div>
<button onclick="createPdf()">generate PDF</button>
Update:
By using jsPDF and html2canvas both, you can achieve your goal.
html2canvas creates a canvas object from the DOM element. From canvas, you can create an image and finally convert that image into pdf by jsPDF. Have a look at the code below:
function createPdf() {
var mapElement = $("#map-canvas");
html2canvas(mapElement, {
useCORS: true,
onrendered: function (canvas) {
var img = canvas.toDataURL("image/jpeg,1.0");
var pdf = new jsPDF();
pdf.addImage(img, 'JPEG', 15, 40, 180, 180);
pdf.save('a4.pdf')
}
});
}
// if HTML DOM Element that contains the map is found...
if (document.getElementById('map-canvas')) {
// Coordinates to center the map
var myLatlng = new google.maps.LatLng(52.525595, 13.393085);
// Other options for the map, pretty much selfexplanatory
var mapOptions = {
zoom: 14,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// Attach a map to the DOM Element, with the defined settings
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}
#map-canvas {
width: 500px;
height: 400px;
}
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"
integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg=="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"
integrity="sha512-s/XK4vYVXTGeUSv4bRPOuxSDmDlTedEpMEcAQk0t/FMd9V6ft8iXdwSBxV0eD60c6w/tjotSlKu9J2AAW1ckTA=="
crossorigin="anonymous"></script>
<button onclick="createPdf()">generate PDF</button>
<div id="map-canvas"></div>
Update 2:
I don't know which ways you're following. Just follow these steps to get the job done:
Follow these steps first.
Replace your index.js code by this:
import 'ol/ol.css';
import { Map, View } from 'ol';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
const map = new Map({
target: 'map',
layers: [
new TileLayer({
source: new OSM()
})
],
view: new View({
center: [0, 0],
zoom: 0
})
});
var exportButton = document.getElementById('export-pdf');
exportButton.addEventListener(
'click',
function () {
exportButton.disabled = true;
document.body.style.cursor = 'progress';
// var format = [297, 210];
var resolution = 72; // The term 72 dpi(dots per inch) is used to express the resolution of a screen
var dim = [297, 210]; // a4 size's dimension
var width = Math.round((dim[0] * resolution) / 25.4);
var height = Math.round((dim[1] * resolution) / 25.4);
var size = map.getSize();
var viewResolution = map.getView().getResolution();
map.once('rendercomplete', function () {
var mapCanvas = document.createElement('canvas');
mapCanvas.width = width;
mapCanvas.height = height;
var mapContext = mapCanvas.getContext('2d');
Array.prototype.forEach.call(
document.querySelectorAll('.ol-layer canvas'),
function (canvas) {
if (canvas.width > 0) {
var opacity = canvas.parentNode.style.opacity;
mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
var transform = canvas.style.transform;
// Get the transform parameters from the style's transform matrix
var matrix = transform
.match(/^matrix\(([^\(]*)\)$/)[1]
.split(',')
.map(Number);
// Apply the transform to the export map context
CanvasRenderingContext2D.prototype.setTransform.apply(
mapContext,
matrix
);
mapContext.drawImage(canvas, 0, 0);
}
}
);
var pdf = new jsPDF('landscape');
pdf.addImage(
mapCanvas.toDataURL('image/jpeg'),
'JPEG',
0,
0,
dim[0],
dim[1]
);
pdf.save('map.pdf');
// Reset original map size
map.setSize(size);
map.getView().setResolution(viewResolution);
exportButton.disabled = false;
document.body.style.cursor = 'auto';
});
// Set print size
var printSize = [width, height];
map.setSize(printSize);
var scaling = Math.min(width / size[0], height / size[1]);
map.getView().setResolution(viewResolution / scaling);
},
false
);
Replace your index.html by this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Using Parcel with OpenLayers</title>
<style>
#map {
width: 400px;
height: 250px;
}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
<button id="export-pdf" >Export PDF</button>
<div id="map"></div>
<script src="./index.js"></script>
</body>
</html>

unable to generate Voronoi diagram from geospatial data

<!DOCTYPE html>
<html>
<head>
<title>D3.js GoogleMap Voronoi Diagram</title>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://shimz.me/example/d3js/geo_example/geo_template/topojson.v0.min.js"> </script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js? sensor=false"></script>
<style type="text/css">
html, body{
margin: 0px;
padding: 0px;
}
html, body, #map_canvas {
width: 100%;
height: 100%;
}
.SvgOverlay {
position: relative;
width: 900px;
height: 600px;
}
.SvgOverlay svg {
position: absolute;
top: -4000px;
left: -4000px;
width: 8000px;
height: 8000px;
}
</style>
</head>
<body>
<div id="map_canvas"></div>
<br>
<script type="text/javascript">
d3.json('bus-stops.json', function(pointjson){
main(pointjson);
});
function main(pointjson) {
//Google Map
var map = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: new google.maps.LatLng(1.290270,103.851959),
});
var overlay = new google.maps.OverlayView(); //OverLay
overlay.onAdd = function () {
var layer = d3.select(this.getPanes().overlayLayer).append("div").attr("class", "SvgOverlay");
var svg = layer.append("svg");
var svgoverlay = svg.append("g").attr("class", "AdminDivisions");
overlay.draw = function () {
var markerOverlay = this;
var overlayProjection = markerOverlay.getProjection();
//Google Map
var googleMapProjection = function (coordinates) {
var googleCoordinates = new google.maps.LatLng(coordinates[1], coordinates[0]);
var pixelCoordinates = overlayProjection.fromLatLngToDivPixel(googleCoordinates);
return [pixelCoordinates.x + 4000, pixelCoordinates.y + 4000];
}
var pointdata = pointjson.lat;
console.log(pointdata);
var positions = [];
pointdata.forEach(function(d) {
positions.push(googleMapProjection(d.lat,d.lng));
});
var polygons = d3.geom.voronoi(positions);
var pathAttr ={
"d":function(d, i) { return "M" + polygons[i].join("L") + "Z"},
stroke:"red",
fill:"none"
};
svgoverlay.selectAll("path")
.data(pointdata)
.attr(pathAttr)
.enter()
.append("svg:path")
.attr("class", "cell")
.attr(pathAttr)
var circleAttr = {
"cx":function(d, i) { return positions[i][0]; },
"cy":function(d, i) { return positions[i][1]; },
"r":2,
fill:"red"
}
svgoverlay.selectAll("circle")
.data(pointdata)
.attr(circleAttr)
.enter()
.append("svg:circle")
.attr(circleAttr)
};
};
overlay.setMap(map);
};
</script>
</body>
</html>
The data file is of the structure:
[{"no":"10009","lat":"1.28210155945393","lng":"103.81722480263163",
"name":"Bt Merah Int"},
{"no":"10011","lat":"1.2777380589964","lng":"103.83749709165197",
"name":"Opp New Bridge Rd Ter"}]
It is also giving an error in console:
TypeError: pointdata is undefined. I am trying to plot using the example: http://bl.ocks.org/shimizu/5610671
I am getting undefined for pointjson using console.log(). Please suggest how do I get the co-ordinate values in pointjson

Getting a latitude and longitude from Google Map based on mouse coordinates

I have a page where I have a tiny person that can be dragged around using RxJS. When the drag ends, if it ends over a google map on the page, I want to convert the mouse coordinates at the point the person was dropped into a latitude and longitude.
I've found/cobbled together this implementation from elsewhere on SO and the Web.
function pixelOffsetToLatLng(map, offsetx, offsety) {
var mapZoom = map.getZoom();
var scale = Math.pow(2, mapZoom);
var mapCenter = map.getCenter();
var worldCoordinateCenter = map.getProjection().fromLatLngToPoint(mapCenter);
var pixelOffset = new google.maps.Point((offsetx/scale) || 0,(offsety/scale) ||0);
var worldCoordinateNewCenter = new google.maps.Point(
worldCoordinateCenter.x - pixelOffset.x,
worldCoordinateCenter.y + pixelOffset.y
);
var latLngPosition = map.getProjection().fromPointToLatLng(worldCoordinateNewCenter);
return latLngPosition;
}
But it is giving incorrect results. It seems to be particular sensitive to position on the planet and to zoom level.
I've included a snippet below that centres on 0,0 with a marker nearby. If you repeatedly drop the person on the marker and zoom out, you'll see that the value of lat, lng changes significantly with zoom level. And I don't understand why...
Thanks in advance!
//adapted from here https://gist.github.com/mattpodwysocki/2156153
//this is an RXJS drag and drop implementation. It is used below to provide screen coordinates to Google Maps
(function(dragger) {
'use strict';
dragger.init = function() {
var dragTarget = $('#dragTarget');
// Get the three major events
window.dragger.mouseup = dragTarget.onAsObservable('mouseup');
window.dragger.mousemove = dragTarget.onAsObservable('mousemove');
window.dragger.mousedown = dragTarget.onAsObservable('mousedown').select(function(event) {
// calculate offsets when mouse down
event.preventDefault();
return {
left: event.clientX - dragTarget.offset().left,
top: event.clientY - dragTarget.offset().top
};
});
// Combine mouse down with mouse move until mouse up
window.dragger.mousedrag = window.dragger.mousedown.selectMany(function(offset) {
return window.dragger.mousemove.select(function(pos) {
// calculate offsets from mouse down to mouse moves
return {
left: pos.clientX - offset.left,
top: pos.clientY - offset.top
};
}).takeUntil(window.dragger.mouseup);
});
window.dragger.mousedrag.subscribe(function(pos) {
// Update position
dragTarget.css({
top: pos.top,
left: pos.left
});
});
window.dragger.mousedown.subscribe(function() {
$('#dragTarget #person').hide();
$('#dragTarget #shopper').show();
});
window.dragger.mouseup.subscribe(function(pos) {
$('#dragTarget #person').show();
$('#dragTarget #shopper').hide();
$('aside ul').append($('<li>').append('shopper dropped at <br/>x:' + pos.clientX + ' and y:' + pos.clientY));
});
};
}(window.dragger = window.dragger || {}));
window.dragger.init();
(function(gmaps) {
'use strict';
//a function cobbled together from elsewhere on StackOverflow to convert from page coordinates
//to a latitude and longitude
function pixelOffsetToLatLng(map, offsetx, offsety) {
var mapZoom = map.getZoom();
var scale = Math.pow(2, mapZoom);
var mapCenter = map.getCenter();
var worldCoordinateCenter = map.getProjection().fromLatLngToPoint(mapCenter);
var pixelOffset = new google.maps.Point((offsetx/scale) || 0,(offsety/scale) ||0);
var worldCoordinateNewCenter = new google.maps.Point(
worldCoordinateCenter.x - pixelOffset.x,
worldCoordinateCenter.y + pixelOffset.y
);
var latLngPosition = map.getProjection().fromPointToLatLng(worldCoordinateNewCenter);
return latLngPosition;
}
gmaps.init = function() {
//setup a map centered on 0,0
var mapCanvas = $('#map');
var mapOptions = {
center: new google.maps.LatLng(0, 0),
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(mapCanvas[0], mapOptions);
//put a marker nearby as a reference point
var marker = new google.maps.Marker({
position: new google.maps.Marker({lat:0.001, lng:0.001}),
map: map,
title: '0.001, 0.001'
});
//run this function every time the draggable person is dropped
window.dragger.mouseup.subscribe(function(pos) {
var ll = pixelOffsetToLatLng(map, pos.pageX, pos.pageY);
$('aside ul').append($('<li>').append('shopper dropped at <br/>lat:' + ll.lat() + ' and y:' + ll.lng()));
});
};
}(window.gmaps = window.gmaps || {}));
window.gmaps.init();
#dragTarget {
position:absolute;
z-index: 999;
}
.grabbable {
cursor: move; /* fallback if grab cursor is unsupported */
cursor: grab;
cursor: -moz-grab;
cursor: -webkit-grab;
}
/* (Optional) Apply a "closed-hand" cursor during drag operation. */
.grabbable:active {
cursor: grabbing;
cursor: -moz-grabbing;
cursor: -webkit-grabbing;
}
#map {
height:400px;
width:400px;
float:left;
background-color:lightyellow;
}
aside {
height:400px;
width:200px;
float:right;
background-color:lightgrey;
}
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.6/rx.all.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs-jquery/1.1.6/rx.jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div class="grabbable fa fa-2x fa-female" id="dragTarget"></div>
<div id="map"></div>
<aside><ul></ul></aside>

Display world map with no repeats

I'm currently using the Google Maps API for the first time.
Essentially I wish to have the map zoomed out so that the whole world is displayed with no overlap (e.g. bits of a certain country are not repeated on either side of the map).
The closest I have found to my requirements is this SO question:
Google Maps API V3: Show the whole world
However, the top answer on this question does not provide the full code required.
I have used the starter example from Google as the base for my HTML:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map-canvas { height: 100% }
</style>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCuP_BOi6lD7L6ZY7JTXRdhY1YEj_gcEP0&sensor=false">
</script>
<script type="text/javascript">
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 1
};
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"/>
</body>
</html>
However, in the example provided in the question above a number of additional variables have been specified. My question is, where do I plug in the code from the question above to ensure that my world map is displayed correctly?
If you don't want any repeats, you need to control the minimum zoom allowed and the width of your map to be less than or equal to one width of of the base tiles at the minimum zoom level allowed on your map.
At zoom zero, one width of the world is a single 256 x 256 pixel tile, each zoom level increases that by a factor of 2.
This will show one width of the map at zoom level 1 (512x512 map-canvas), you can change the height, but the width will need to be 256 at zoom 0, 512 at zoom 1, 1024 at zoom 2, etc:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map-canvas { height: 512px; width:512px;}
</style>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3&sensor=false">
</script>
<script type="text/javascript">
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 1,
minZoom: 1
};
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"/>
</body>
</html>
code snippet:
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 1,
minZoom: 1
};
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
html {
height: 100%
}
body {
height: 100%;
margin: 0;
padding: 0
}
#map-canvas {
height: 512px;
width: 512px;
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map-canvas"></div>
Here's a function worldViewFit I like to use:
function initMap() {
var mapOptions = {
center: new google.maps.LatLng(0, 0),
zoom: 1,
minZoom: 1
};
map = new google.maps.Map(document.getElementById('officeMap'), mapOptions);
google.maps.event.addListenerOnce(map, 'idle', function() {
//Map is ready
worldViewFit(map);
});
}
function worldViewFit(mapObj) {
var worldBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(70.4043,-143.5291), //Top-left
new google.maps.LatLng(-46.11251, 163.4288) //Bottom-right
);
mapObj.fitBounds(worldBounds, 0);
var actualBounds = mapObj.getBounds();
if(actualBounds.getSouthWest().lng() == -180 && actualBounds.getNorthEast().lng() == 180) {
mapObj.setZoom(mapObj.getZoom()+1);
}
}
google.maps.event.addDomListener(window, 'load', initMap);
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#officeMap {
height: 512px;
width: 512px;
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="officeMap"></div>
This is the JavaScript I found:
/**
* All locations map scripts
*/
jQuery(function($){
$(document).ready(function(){
loadmap();
});
function loadmap()
{
var locations = wpsl_locator_all.locations;
var mapstyles = wpsl_locator.mapstyles;
var mappin = ( wpsl_locator.mappin ) ? wpsl_locator.mappin : '';
var bounds = new google.maps.LatLngBounds();
var mapOptions = {
mapTypeId: 'roadmap',
mapTypeControl: false,
zoom: 8,
styles: mapstyles,
panControl : false
}
if ( wpsl_locator.custom_map_options === '1' ) mapOptions = wpsl_locator.map_options;
var infoWindow = new google.maps.InfoWindow(), marker, i;
var map = new google.maps.Map( document.getElementById('alllocationsmap'), mapOptions );
// Loop through array of markers & place each one on the map
for( i = 0; i < locations.length; i++ ) {
var position = new google.maps.LatLng(locations[i].latitude, locations[i].longitude);
bounds.extend(position);
var marker = new google.maps.Marker({
position: position,
map: map,
title: locations[i].title,
icon: mappin
});
// Info window for each marker
google.maps.event.addListener(marker, 'click', (function(marker, i){
return function() {
infoWindow.setContent(locations[i].infowindow);
infoWindow.open(map, marker);
wpsl_all_locations_marker_clicked(marker, infoWindow)
}
})(marker, i));
// Center the Map
map.fitBounds(bounds);
var listener = google.maps.event.addListener(map, "idle", function() {
if ( locations.length < 2 ) {
map.setZoom(13);
}
google.maps.event.removeListener(listener);
});
}
// Fit the map bounds to all the pins
var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
google.maps.event.removeListener(boundsListener);
});
wpsl_all_locations_rendered(map);
} // loadmap()
});

Rotating image / marker image on Google map V3

How could I rotate an image (marker image) on a Google map V3?
There is an excellent example for V2 here, exactly doing what I need. But for GMap2! They do it with a rotating canvas.
Image rotating with JS / JQuery is frequently used, there are multiple answers about this. But how could I apply this to my maps image?
One mentioned approach is to have different images for different angles and to switch among them - this is NOT what I want. I do not like to have so many images, I want to rotate by code.
Remark: There are similar questions, but all for V2 and not V3 (as far I can tell). I need it for V3.
My js class for solving this problem is:
var RotateIcon = function(options){
this.options = options || {};
this.rImg = options.img || new Image();
this.rImg.src = this.rImg.src || this.options.url || '';
this.options.width = this.options.width || this.rImg.width || 52;
this.options.height = this.options.height || this.rImg.height || 60;
var canvas = document.createElement("canvas");
canvas.width = this.options.width;
canvas.height = this.options.height;
this.context = canvas.getContext("2d");
this.canvas = canvas;
};
RotateIcon.makeIcon = function(url) {
return new RotateIcon({url: url});
};
RotateIcon.prototype.setRotation = function(options){
var canvas = this.context,
angle = options.deg ? options.deg * Math.PI / 180:
options.rad,
centerX = this.options.width/2,
centerY = this.options.height/2;
canvas.clearRect(0, 0, this.options.width, this.options.height);
canvas.save();
canvas.translate(centerX, centerY);
canvas.rotate(angle);
canvas.translate(-centerX, -centerY);
canvas.drawImage(this.rImg, 0, 0);
canvas.restore();
return this;
};
RotateIcon.prototype.getUrl = function(){
return this.canvas.toDataURL('image/png');
};
Call it like this:
var marker = new google.maps.Marker({
icon: {
url: RotateIcon
.makeIcon(
'https://ru.gravatar.com/userimage/54712272/b8eb5f2d540a606f4a6c07c238a0bf40.png')
.setRotation({deg: 92})
.getUrl()
}})
See live example here http://jsfiddle.net/fe9grwdf/39/
I have found two extensions to the Google MAP V3: infobox.js and markerwithlabel.js
Both can handle an image DOM element as content, which in turn I can rotate via the jQuery image rotate plugin.
This even works without setting the marker's image again after rotation.
Edit: As of questions / comments below:
The extension for label is required, because it can handle other DOM elements. So I can add arbitrary HTML as label, in my particular case I add the image. And then I do rotate this image (child of the label) with the rotate plugin. So assign the image an id in order to easily access it. Actually I am using one label just for the image, and another for descriptive text.
Edit 2: Due to Stephan's comment on the DOM readiness
In my code I have found the following lines. This shows that I force a draw on the label before rotating the image.
if (!this._drawn) myImageLabel.draw(); // 1st time force a draw, otherwise rotating the image will fail because an asynchronously drawn object has not all tags in place
if (this.heading != 0) this.rotateImage(this.heading, true);
Edit 3: Code example how to create the Infobox.js
this._img = document.createElement('img');
... further manipulations of _img / Size / Id / ...
var planeImageLabelOptions = {
content: this._img,
disableAutoPan: true,
boxStyle: planeImageLabelBoxStyle,
pixelOffset: new google.maps.Size(-imgOffsetW / 2, -imgOffsetH / 2),
closeBoxURL: "",
position: latlng,
zIndex: this.altitude < 0 ? 100 : this.altitude
};
var planeImageLabel = new InfoBox(planeImageLabelOptions);
I also had a hard time to figure out the way to rotate .png marker.
I solved it like below. You can create many markers with same custom image and
rotate a specific marker you want to rotate.
I hope it helpful to you.
var id = 'my_marker_01';
var img_url = "../img/car.png";
var my_icon = img_url + "#" + id;
var marker = new google.maps.Marker({
icon: my_icon,
...
});
var rotate = 45;
$(`img[src="${my_icon}"]`).css(
{'-webkit-transform' : 'rotate('+ rotate +'deg)',
'-moz-transform' : 'rotate('+ rotate +'deg)',
'-ms-transform' : 'rotate('+ rotate +'deg)',
'transform' : 'rotate('+ rotate +'deg)'});
How could I rotate an image (marker image) on a Google map V3?
I had the same problem and I solved it with the next code:
var gmap;
NgMap.getMap(function(map){
gmap = map;
});
I suppose that you have a variable with the icon, for example:
var imagePath = 'img/customMarker.png';
First, we need to create our marker options:
var markerOptions = {
location: [x, y],
title:'some text',
draggable: true,
.
.
.
icon: imagePath
};
Let's create a marker:
var marker = new google.maps.Marker(markerOptions);
And we have to set the map:
marker.setMap(map);
Now if you want to rotate the image you need to do the next:
Change the imagePath variable's value to 'img/customMarker.png#yourId'
Set rotation value with css (e.g. with JQuery)
Let's see
imagePath = 'img/customMarker.png#markerOne';
$('img[src="img/customMarker.png#markerOne"]').css({
'transform': 'rotate(45deg)'
});
Of course you can do it fancier:
function rotateMarker(selector, degree){
$('img[src="img/customMarker.png#'+selector+'"]').css({
'transform': 'rotate('+degree+'deg)'
});
}
And your call:
rotateMarker('markerOne', 45);
That's all.
I hope it could be helpful.
I have done the rotation in v3 with the following code:
<canvas id="carcanvas" width="1" height="1"></canvas>
if (document.getElementById('carcanvas').getContext) {
var supportsCanvas = true;
} else {
var supportsCanvas = false;
}
var rImg = new Image();
rImg.src='/images/cariconl.png';
// Returns the bearing in radians between two points.
function bearing( from, to ) {
// Convert to radians.
var lat1 = from.latRadians();
var lon1 = from.lngRadians();
var lat2 = to.latRadians();
var lon2 = to.lngRadians();
// Compute the angle.
var angle = - Math.atan2( Math.sin( lon1 - lon2 ) * Math.cos( lat2 ), Math.cos( lat1 ) * Math.sin( lat2 ) - Math.sin( lat1 ) * Math.cos( lat2 ) * Math.cos( lon1 - lon2 ) );
if ( angle < 0.0 )
angle += Math.PI * 2.0;
if (angle == 0) {angle=1.5;}
return angle;
}
function plotcar() {
canvas = document.getElementById("carcanvas").getContext('2d');
var cosa = Math.cos(angle);
var sina = Math.sin(angle);
canvas.clearRect(0,0,32,32);
canvas.save();
canvas.rotate(angle);
canvas.translate(16*sina+16*cosa,16*cosa-16*sina);
canvas.drawImage(rImg,-16,-16);
canvas.restore();
}
and in the animation method :
if (supportsCanvas) {
angle = bearing(new google.maps.LatLng(lat1, lng1),new google.maps.LatLng(lat2, lng2));
plotcar();
}
I hope that help.
You did not state it in your question, but I am assuming that you want this rotation in relation to a line between point a and point b, which would be their path. In order to make a google svg icon that can be rotated, you will want to use the google symbol class object to define the properties of your marker symbol. This does not use a full .svg file, but only the d attribute of the path. Note that the google symbol class can only take one path per marker.
Additional attributes for color, stroke, width, opacity, etc. may be set after the marker has been created with javascript (updating the marker object properties directly), or with CSS (updating the marker properties by adding and removing classes).
As an example, the following will create an arrow marker that can be dragged, and it will be rotated around the point on the map that is the lat and long for the marker even after it is moved.
The HTML
<body id="document_body" onload="init();">
<div id="rotation_control">
Heading°<input id="rotation_value" type="number" size="3" value="0" onchange="setRotation();" />
</div>
<div id="map_canvas"></div>
</body>
The CSS (yes,verbose... I hate ugly)
#document_body {
margin:0;
border: 0;
padding: 10px;
font-family: Arial,sans-serif;
font-size: 14px;
font-weight: bold;
color: #f0f9f9;
text-align: center;
text-shadow: 1px 1px 1px #000;
background:#1f1f1f;
}
#map_canvas, #rotation_control {
margin: 1px;
border:1px solid #000;
background:#444;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
#map_canvas {
width: 100%;
height: 360px;
}
#rotation_control {
width: auto;
padding:5px;
}
#rotation_value {
margin: 1px;
border:1px solid #999;
width: 60px;
padding:2px;
font-weight: bold;
color: #00cc00;
text-align: center;
background:#111;
border-radius: 4px;
}
The Javascript (in plain vanilla flavor for understanding core concepts)
var map, arrow_marker, arrow_options;
var map_center = {lat:41.0, lng:-103.0};
var arrow_icon = {
path: 'M -1.1500216e-4,0 C 0.281648,0 0.547084,-0.13447 0.718801,-0.36481 l 17.093151,-22.89064 c 0.125766,-0.16746 0.188044,-0.36854 0.188044,-0.56899 0,-0.19797 -0.06107,-0.39532 -0.182601,-0.56215 -0.245484,-0.33555 -0.678404,-0.46068 -1.057513,-0.30629 l -11.318243,4.60303 0,-26.97635 C 5.441639,-47.58228 5.035926,-48 4.534681,-48 l -9.06959,0 c -0.501246,0 -0.906959,0.41772 -0.906959,0.9338 l 0,26.97635 -11.317637,-4.60303 c -0.379109,-0.15439 -0.812031,-0.0286 -1.057515,0.30629 -0.245483,0.33492 -0.244275,0.79809 0.0055,1.13114 L -0.718973,-0.36481 C -0.547255,-0.13509 -0.281818,0 -5.7002158e-5,0 Z',
strokeColor: 'black',
strokeOpacity: 1,
strokeWeight: 1,
fillColor: '#fefe99',
fillOpacity: 1,
rotation: 0,
scale: 1.0
};
function init(){
map = new google.maps.Map(document.getElementById('map_canvas'), {
center: map_center,
zoom: 4,
mapTypeId: google.maps.MapTypeId.HYBRID
});
arrow_options = {
position: map_center,
icon: arrow_icon,
clickable: false,
draggable: true,
crossOnDrag: true,
visible: true,
animation: 0,
title: 'I am a Draggable-Rotatable Marker!'
};
arrow_marker = new google.maps.Marker(arrow_options);
arrow_marker.setMap(map);
}
function setRotation(){
var heading = parseInt(document.getElementById('rotation_value').value);
if (isNaN(heading)) heading = 0;
if (heading < 0) heading = 359;
if (heading > 359) heading = 0;
arrow_icon.rotation = heading;
arrow_marker.setOptions({icon:arrow_icon});
document.getElementById('rotation_value').value = heading;
}
And the best yet, doing it this way assures the marker is a Google MVC object, giving it all the additional methods provided by the MVC object.
If you must have multi-colored images as your marker, then creating a .png sprite sheet with a rendition of the image at all the angles you want it to be shown, and then problematically select the correct image to use based on the computed bearing between the two points you are using. However,this would not be an SVG image, but a regular marker image.
Hope this helps in making some decisions regarding your map markers.
Nobody mentioned about using pre-rotated icons. Depending on your application, you could take one icon and rotate it +10 degrees, +20 degrees ... +350 degrees and instead of rotating marker itself, just assign different icon to it - one out of 36 if 10 degrees resolution is good enough. That's also very light on client's resources.
In the example below I generated 36 icons, every one of them is 10 degrees rotated. Their names are: icon0.png, icon10.png, icon20.png, ... icon340.png, icon350.png, icon360.png. The 0 and 360 are the very same icon (e.g symlink)
var rotation = 123 // degrees
var iconName = "icon" + (Math.round(rotation/10)*10).toString() + ".png"
var marker = new google.maps.Marker({
icon: iconName
})
I was able to solve this pretty easily but using the marker.icon.rotation option pointing to a custom symbol that uses the svg path syntax.
$scope.triangle = {
path: 'M 0 0 L -35 -100 L 35 -100 z',
fillColor: '#3884ff',
fillOpacity: 0.7,
scale: 1,
strokeColor: '#356cde',
rotation: 90,
strokeWeight: 1
};
If using angular-google-maps it is trivial to bind a ui control to change the triangle.rotation.
Like I did with this slider.
<slider ng-model="triangle.rotation" floor="0" ceiling="359" step="5" precsion="1"></slider>
But you could use a forum too.
here is my plunker http://plnkr.co/edit/x0egXI
This is how i implemented my image rotated, I considered the marker in the form of overlay and that overlay is position to the position, Below code will be added .
Without using any additional library it is rotated,And you need to workaround to add click events and mouse events for the overlay, not similar to marker click events.
With googleMap markers customization, there will be addition memory usage in the map.
This will also reduce the memory consumption of custom markers in your map.
<html>
<head>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<style>html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map_canvas {
height: 100%;
}
div.htmlMarker {
color: red;
cursor: pointer;
}
</style>
</head>
<body onload="initialize()">
<div id="map_canvas"></div>
</body>
<script>
var overlay;
function initialize() {
var myLatLng = new google.maps.LatLng(40, -100);
var mapOptions = {
zoom: 10,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var gmap = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
function HTMLMarker(lat, lng, rotation) {
this.lat = lat;
this.lng = lng;
this.rotation = rotation;
this.pos = new google.maps.LatLng(lat, lng);
}
HTMLMarker.prototype = new google.maps.OverlayView();
HTMLMarker.prototype.onRemove = function () {}
//Initilize your html element here
HTMLMarker.prototype.onAdd = function () {
div = document.createElement('DIV');
div.style.position='absolute';
div.style.transform='rotate('+this.rotation +'deg)';
div.style.MozTransform='rotate('+this.rotation +'deg)';
div.className = "htmlMarker";
//image source use your own image in src
div.innerHTML = '<img src="prudvi.png" alt="Mountain View" style="width:25px;height:22px">' ;
var panes = this.getPanes();
panes.overlayImage.appendChild(div);
this.div=div;
}
HTMLMarker.prototype.draw = function () {
var overlayProjection = this.getProjection();
var position = overlayProjection.fromLatLngToDivPixel(this.pos);
var panes = this.getPanes();
this.div.style.left = position.x + 'px';
this.div.style.top = position.y - 30 + 'px';
}
//Added 50 marker with random latlng location and random rotation,
for (i = 0; i < 50; i++) {
var PoslatLng = new google.maps.LatLng(myLatLng.lat() + Math.random() - 0.5, myLatLng.lng() + Math.random() - 0.5);
var htmlMarker = new HTMLMarker(myLatLng.lat() + Math.random() - 0.5,myLatLng.lng() + Math.random() - 0.5, Math.floor(Math.random() * 359));
htmlMarker.setMap(gmap);
google.maps.event.addListener(htmlMarker, 'click', function() {
console.log('clciked')
gmap.setZoom(8);
gmap.setCenter(htmlMarker.getPosition());
});
}
}
</script>
</html>
You could call the yourmarker.setIcon(canvas.toDataUrlOrSomeThig) every time the image changes. I don't see anything in the api reference for using the canvas element directly, except if you implement you own google.maps.OverlayView.
If you only want animation you could use a gif, and add the marker option optimized: false to it.
The easiest way may be to use the rotation property of google.maps.Symbol. Just set it as a property of your icon when creating or updating your marker:
new google.maps.Marker({
position: map.getCenter(),
icon: {
path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
scale: 7,
rotation: 193
},
map: map
});
Plunker
The idea is to first draw the rotated marker image on a hidden canvas.
Say, you have a hidden canvas:
<canvas id="carCanvas" width="50" height="50" style="display:none"></canvas>
Now you can do this:
function updateCarMarker(i,lat, lng, icon = "img/carIcon.png") {
var latLong = new google.maps.LatLng(lat, lng);
if (!carMarkers[i]){
var carImage = new Image();
carImage.onload = ()=>{
drawMovedCar(i,latLong,carImage);
}
carImage.src=icon;
} else {
drawMovedCar(i,latLong,carMarkers[i].carImage);
}
}
function drawMovedCar(i,latLong,I){
let m=carMarkers[i];
let canvas = document.getElementById("carCanvas");
let C = canvas.getContext('2d');
if (m){
var distance = google.maps.geometry.spherical.computeDistanceBetween(
m.getPosition(), latLong);
var deg = (distance<2)?carMarkers[i].deg
:google.maps.geometry.spherical.computeHeading(m, latLong);
carMarkers[i].setMap(null);
} else {
var deg=0;
}
C.save();
C.clearRect(0, 0, canvas.width, canvas.height);
C.translate(canvas.width/2,canvas.height/2);
C.rotate(deg * Math.PI / 180);
C.scale(0.4,0.4);
C.drawImage(I,-I.width/2,-I.height/2,I.width,I.height);
C.restore();
if (!m){
m = new google.maps.Marker({
position: latLong,
map: map,
icon: canvas.toDataURL("image/png",1)
});
m.deg = deg;
m.carImage = I;
carMarkers[i]=m;
} else {
m.setIcon(canvas.toDataURL("image/png",1));
m.setPosition(latLong);
}
}
The above is my original code. I have left it intact so that you can see my other optimizations.
Using MarkerWithLabel Library, you can achieve that in such way:
var ico = document.createElement('img');
ico.src = 'ImageSource';
ico.setAttribute('style', 'transform:rotate('30deg);');
mapMarkers[0].labelContent = ico;
mapMarkers[0].label.draw();
Assuming you only use that image within Google Maps, you can do the following
bearing = 20
document.querySelectorAll('img[src="/images/imageName"]').forEach((node) => {
node.style['transform'] = `rotate(${bearing}deg)`
node.style['webkitTransform'] = `rotate(${bearing}deg)`
node.style['MozTransform'] = `rotate(${bearing}deg)`
node.style['msTransform'] = `rotate(${bearing}deg)`
node.style['OTransform'] = `rotate(${bearing}deg)`
})
This reaches down the dom tree and sets the transform for the marker icon to rotate the degrees you want. The image imageName should be facing North
Not to sure if the webkit, Moz, ms and O version are needed but hey 🤷🏽‍♂️ cant hurt
If you are using SVG, Then this is the best way to rotate it.
let marker_, svg_, size_ = 100, rotation_ = 50
// Get SVG
fetch('https://upload.wikimedia.org/wikipedia/commons/7/78/Space-shuttle.svg')
.then(response => response.text())
.then(text => {
svg_ = text;
svg_ = svg_
.replace(/^<\?(.+)\?>$/gm, '') // unsupported unnecessary line
// You can replace anything you want, but first of all check your svg code
.replace(/width.+\Wheight\S+/,
'width="{{width}}" height="{{height}}" transform="{{transform}}" ')
// Load Map
initMap()
})
function getIcon(rotation){
return {url:`data:image/svg+xml;charset=utf-8,
${encodeURIComponent(svg_
.replace('{{width}}', 100)
.replace('{{height}}', 100)
.replace('{{transform}}', `rotate(${rotation},0,0)`))}`,anchor: new google.maps.Point(50, 50),
origin: new google.maps.Point(0, 0)}
}
// Map
function initMap() {
const position = {lat: 36.720426, lng: -4.412573};
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 19,
center: position
})
marker_ = new google.maps.Marker({
position: position,
map: map,
icon: getIcon(rotation_)
})
}
// Change rotation
$input_ = document.querySelector('input')
$input_.value = rotation_
$input_.onchange = () => {
marker_.setIcon(getIcon(parseInt($input_.value))
)
}
* {
padding: 0;
margin: 0;
}
#map {
width: 100%;
height: 100vh;
}
input {
position: fixed;
z-index: 1;
margin: 100px;
padding: 10px;
border-radius: 2px;
background-color: red;
border: none;
color: white;
font-family: 'Roboto';
width: 70px;
}
<script src="https://maps.google.com/maps/api/js"></script>
<input type="number" placeholder="rotation">
<div id="map"></div>
I have found an easy way to rotate the png image marker for the google marker. Create an custom marker overriding google.maps.OverlayView and rotate the image simply with css/inline style
export const createCustomMarker = ({ OverlayView = google.maps.OverlayView, ...args }) => {
class GoogleMarker extends OverlayView {
options: any = {};
div: any = null;
innerHtml: any = null;
constructor(options) {
super();
this.options = options;
this.setMap(options.map);
}
createDiv() {
const options = this.options;
this.div = document.createElement('div');
this.div.style.position = 'absolute';
this.setRotation(this.options.rotation);
if (options.icon) {
this.setInnerHtml(this.getInnerImageHtml(options));
}
}
getInnerImageHtml(options) {
const size = this.getSize(options);
const label = this.options.label;
const labelHtml = label ? `<span style="color:black;margin-left: -40px;width: 100px;text-align: center;display: block;font-weight:bold;">${label}</span>` : "";
return `<img style="height:${size.height}px;width:${size.width}px" id="${options.id || ''}" src="${options.icon}">${labelHtml}`;
}
addListeners() {
const self = this;
google.maps.event.addDomListener(this.div, 'click', event => {
google.maps.event.trigger(self, 'click');
});
this.div.onmouseenter = function () {
debugger
google.maps.event.trigger(self, 'onmouseenter');
}
this.div.onmouseover = function () {
google.maps.event.trigger(self, 'onmouseover');
}
this.div.onmouseleave = function () {
google.maps.event.trigger(self, 'onmouseleave');
}
this.div.onmouseout = function () {
google.maps.event.trigger(self, 'onmouseout');
}
}
appendDivToOverlay(appendDiv: any) {
const panes: google.maps.MapPanes = this.getPanes();
panes.floatPane.appendChild(appendDiv);
}
setRotation(degrees: number) {
if (this.div) {
this.div.style.transform = 'rotate(' + degrees + 'deg)';
}
this.options.rotation = degrees;
}
getRotation() {
return this.options.rotation;
}
setInnerHtml(html: string) {
this.innerHtml = html;
this.div.innerHTML = this.innerHtml;
}
private positionDiv(div: any, options: any) {
if (div != null) {
const point = this.getProjection().fromLatLngToDivPixel(options.latlng);
if (point) {
const size = this.getSize(options);
const anchor = options.anchor ? options.anchor : new google.maps.Point((size.width / 2), (size.height / 2))
const leftAnchor = anchor.x;
const topAnchor = anchor.y;
div.style.left = `${point.x - leftAnchor}px`;
div.style.top = `${point.y - topAnchor}px`;
}
}
}
private getSize(options) {
const size = options.size || { height: 52, width: 52 };
return size;
}
draw() {
if (!this.div) {
this.createDiv();
this.appendDivToOverlay(this.div);
this.addListeners();
}
this.positionDiv(this.div, this.options);
}
remove() {
if (this.div) {
this.div.parentNode.removeChild(this.div);
this.div = null;
}
}
setVisible(value: boolean) {
if (this.div) {
this.div.style["display"] = value ? "block" : "none";
}
}
getVisible() {
if (this.div) {
return this.div.style["display"] == "none";
}
return false;
}
setPosition(position) {
this.options.latlng = position;
this.infoOptions.latlng = position;
this.positionDiv(this.div, this.options);
}
getPosition() {
return this.options.latlng;
}
getDraggable() {
return false;
}
isHTML(html: string) {
return /<([A-Za-z][A-Za-z0-9]*)\b[^>]*>(.*?)<\/\1>/.test(html);
}
}
return new GoogleMarker(args)
}
After creating this custom marker - Initialize the marker in the following way
import { createCarMarker } from "./marker.component"; // dynamic path to component
let marker = createCarMarker({
id: id, // will add id to the parent container div
latlng: new google.maps.LatLng(0, 0), // replace latitude-longitude with your values
map: this.map,
size: new google.maps.Size(52, 52), // replace the image size with your values
rotation: markerData.direction, // Provide values in degrees
icon: iconUrl, // Replace it with your image url
label: markerLabel // Provide marker label. Optional field
});
Now simply rotate the marker using the following method
marker.setRotation(180); // You just need to call only this method every-time the degrees changes.
To listen the changes on the marker.
google.maps.event.addDomListener(marker, 'click', function (event) {
});
google.maps.event.addListener(marker, 'onmouseenter', function (event) {
});
google.maps.event.addListener(marker, 'onmouseleave', function (event) {
});
google.maps.event.addListener(marker, 'onmouseover', function (event) {
});
google.maps.event.addListener(marker, 'onmouseout', function (event) {
});
You can customize the listeners or add new/update in the custom marker class according to your requirement.
var icon = {
path: aeroplanePath/image,
fillColor: '#0000FF',
fillOpacity: .6,
anchor: new google.maps.Point(0,0),
strokeWeight: 0,
scale: 1,
rotation: 180
}
var marker = new google.maps.Marker({
position: positions[k],
icon: icon,
draggable: true,
title: "BOING-707",
});

Categories

Resources