I'm new to React and have been playing around with the react-google-maps package. I'm trying to curve a Polyline that joins two places. After going through the documentation, I'm trying to incorporate the curve polyline function under the 'editable' prop.
Here's the function to curve the polyline:
var map;
var curvature = 0.4; // Arc of the Polyline
function init() {
var Map = google.maps.Map,
LatLng = google.maps.LatLng,
LatLngBounds = google.maps.LatLngBounds,
Marker = google.maps.Marker,
Point = google.maps.Point;
// Initial location of the points
var pos1 = new LatLng(this.state.srcMarker);
var pos2 = new LatLng(this.state.desMarker);
var bounds = new LatLngBounds();
bounds.extend(pos1);
bounds.extend(pos2);
map = new Map(document.getElementById('map-canvas'), {
center: bounds.getCenter(),
zoom: 12
});
map.fitBounds(bounds);
var markerP1 = new Marker({
position: pos1,
map: map
});
var markerP2 = new Marker({
position: pos2,
map: map
});
var curveMarker;
function updateCurveMarker() {
var pos1 = markerP1.getPosition(),
pos2 = markerP2.getPosition(),
projection = map.getProjection(),
p1 = projection.fromLatLngToPoint(pos1),
p2 = projection.fromLatLngToPoint(pos2);
// Calculating the arc.
var e = new Point(p2.x - p1.x, p2.y - p1.y), // endpoint
m = new Point(e.x / 2, e.y / 2), // midpoint
o = new Point(e.y, -e.x), // orthogonal
c = new Point( m.x + curvature * o.x, m.y + curvature * o.y); //curve control point
var pathDef = 'M 0,0 ' + 'q ' + c.x + ',' + c.y + ' ' + e.x + ',' + e.y;
var zoom = map.getZoom(),
scale = 1 / (Math.pow(2, -zoom));
var symbol = {
path: pathDef,
scale: scale,
strokeWeight: 1,
fillColor: 'none'
};
if (!curveMarker) {
curveMarker = new Marker({
position: pos1,
clickable: false,
icon: symbol,
zIndex: 0, // behind the other markers
map: map
});
} else {
curveMarker.setOptions({
position: pos1,
icon: symbol,
});
}
}
google.maps.event.addListener(map, 'projection_changed', updateCurveMarker);
google.maps.event.addListener(map, 'zoom_changed', updateCurveMarker);
google.maps.event.addListener(markerP1, 'position_changed', updateCurveMarker);
google.maps.event.addListener(markerP2, 'position_changed', updateCurveMarker);
}
google.maps.event.addDomListener(window, 'load', init);
I'm not able to understand how to use this function in the Polyline component. I'm able to mark a line between any two places, but not able to use this function in order to curve the given polyline. This is the Polyline component that I'm using.
<Polyline
path={pathCoordinates}
geodesic={true}
options={{
strokeColor: '#ff2527',
strokeOpacity: 1.0,
strokeWeight: 5,
}}
/>
I have two markers in my state (srcMarker, desMarker) that store the coordinates of the given cities once the user inputs the city name. Any help would be appreciated in incorporating this function with the Polyline component. I haven't come across any built in feature that allows curving of the polyline. Thanks in advance!
I took the code you provided and adapted it to work with React and react-google-maps. Check out this CodeSandbox to see a simple application that contains two markers and a curved line between them.
The curved line that connects the two markers is actually a marker as well. The only difference between it and the two red markers is that its icon prop is set to the curved line (which is computed beforehand).
Here is the code for the CurveMarker component:
const CurveMarker = ({ pos1, pos2, mapProjection, zoom }) => {
if (!mapProjection) return <div/>;
var curvature = 0.4
const p1 = mapProjection.fromLatLngToPoint(pos1),
p2 = mapProjection.fromLatLngToPoint(pos2);
// Calculating the arc.
const e = new google.maps.Point(p2.x - p1.x, p2.y - p1.y), // endpoint
m = new google.maps.Point(e.x / 2, e.y / 2), // midpoint
o = new google.maps.Point(e.y, -e.x), // orthogonal
c = new google.maps.Point(m.x + curvature * o.x, m.y + curvature * o.y); //curve control point
const pathDef = 'M 0,0 ' + 'q ' + c.x + ',' + c.y + ' ' + e.x + ',' + e.y;
const scale = 1 / (Math.pow(2, -zoom));
const symbol = {
path: pathDef,
scale: scale,
strokeWeight: 2,
fillColor: 'none'
};
return <Marker
position={pos1}
clickable={false}
icon={symbol}
zIndex={0}
/>;
};
Let me know if you have any questions.
Related
I need to display different polylines from A to B. So, these lines should be distinguishable from each other. I haved tried to set polylines using pushpoint function with altitude parameter. However it is still on the ground level. And the last polyline I inserted overwrites the previous one.
Altitude value works on markers but I want to apply it on polyline.
I changed the sample code here markers with altitude as below. You can see the orange line is just on top of the gray line when you change the code with the below one. I would like both lines to be displayed like the markers you see above them.
/**
* Calculate the bicycle route.
* #param {H.service.Platform} platform A stub class to access HERE services
*/
function calculateRouteFromAtoB (platform) {
var router = platform.getRoutingService(),
routeRequestParams = {
mode: 'fastest;bicycle',
representation: 'display',
routeattributes : 'shape',
waypoint0: '-16.1647142,-67.7229166',
waypoint1: '-16.3705847,-68.0452683',
// explicitly request altitude values
returnElevation: true
};
router.calculateRoute(
routeRequestParams,
onSuccess,
onError
);
}
/**
* Process the routing response and visualise the descent with the help of the
* H.map.Marker
*/
function onSuccess(result) {
var lineString = new H.geo.LineString(),
lineString2 = new H.geo.LineString(),
routeShape = result.response.route[0].shape,
group = new H.map.Group(),
dict = {},
polyline,
polyline2;
routeShape.forEach(function(point) {
var parts = point.split(',');
var pp= new H.geo.Point(parts[0],parts[1],4000,"SL");
console.log(parts[2]);
lineString.pushLatLngAlt(parts[0], parts[1]);
lineString2.pushPoint(pp);
// normalize the altitude values for the color range
var p = (parts[2] - 1000) / (4700 - 1000);
var r = Math.round(255 * p);
var b = Math.round(255 - 255 * p);
// create or re-use icon
var icon;
if (dict[r + '_' + b]) {
icon = dict[r + '_' + b];
} else {
var canvas = document.createElement('canvas');
canvas.width = 4;
canvas.height = 4;
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgb(' + r + ', 0, ' + b + ')';
ctx.fillRect(0, 0, 4, 4);
icon = new H.map.Icon(canvas);
// cache the icon for the future reuse
dict[r + '_' + b] = icon;
}
// the marker is placed at the provided altitude
var marker = new H.map.Marker({
lat: parts[0], lng: parts[1], alt: parts[2]
}, {icon: icon});
var marker2 = new H.map.Marker({
lat: parts[0], lng: parts[1], alt: parts[2]-800
}, {icon: icon});
group.addObject(marker);
group.addObject(marker2);
});
polyline = new H.map.Polyline(lineString, {
style: {
lineWidth: 6,
strokeColor: '#555555'
}
});
polyline2 = new H.map.Polyline(lineString2, {
style: {
lineWidth: 3,
strokeColor: '#FF5733'
}
});
// Add the polyline to the map
map.addObject(polyline);
map.addObject(polyline2);
// Add markers to the map
map.addObject(group);
// Zoom to its bounding rectangle
map.getViewModel().setLookAtData({
bounds: polyline.getBoundingBox(),
tilt: 60
});
}
/**
* This function will be called if a communication error occurs during the JSON-P request
* #param {Object} error The error message received.
*/
function onError(error) {
alert('Can\'t reach the remote server');
}
/**
* Boilerplate map initialization code starts below:
*/
// set up containers for the map + panel
var mapContainer = document.getElementById('map'),
routeInstructionsContainer = document.getElementById('panel');
//Step 1: initialize communication with the platform
// In your own code, replace variable window.apikey with your own apikey
var platform = new H.service.Platform({
apikey: window.apikey
});
var defaultLayers = platform.createDefaultLayers();
//Step 2: initialize a map - this map is centered over Berlin
var map = new H.Map(mapContainer,
defaultLayers.vector.normal.map,{
center: {lat:52.5160, lng:13.3779},
zoom: 13,
pixelRatio: window.devicePixelRatio || 1
});
// add a resize listener to make sure that the map occupies the whole container
window.addEventListener('resize', () => map.getViewPort().resize());
//Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Create the default UI components
var ui = H.ui.UI.createDefault(map, defaultLayers);
// Now use the map as required...
calculateRouteFromAtoB (platform);
Unfortunately, for now only markers support altitudes.
Polylines should follow in near future.
I'm using openlayers3 and I have the encoded geometry. I can get the coordinates (lat,lng) for all points in the path (around 500 points per path). Given a random point inside the path, how do I calculate the distance between the beginning of the path up to that point?
I've taken a look at turfjs and it looks very promising, but the solution I pictured using it wouldn't be very nice. Taking a random point (p1), I could discover the point (p2) of the path that is closest to p1, then generate a new polygon and calculate its total distance. It may have performance issues, although the search would be O(log n) and the new polygon O(n).
EDIT: the random point is not necessarily inside the path, it's a GPS coordinate and there's a margin for error.
EDIT 2: estimation on the number of points was off, each path has about 500 points, not 5k
Does anyone know of a better approach? I'm not very experienced with either openlayers3 nor turfjs.
As you mentioned you're using OpenLayers 3, I've done an example using OpenLayers 3, the idea is:
Get Closest Point across the LineString given a coordinate
Iterate over LineString points calculating the distance of each individual paths and see if our closest point intersects the individual path.
/* Let's Generate a Random LineString */
var length = 5000;
var minLongitude = Math.random()*-180 + 180;
var minLatitude = Math.random()*-90 + 90;
var wgs84Sphere = new ol.Sphere(6378137);
var lastPoint = [minLongitude, minLatitude]
var points = Array.from({ length })
.map( _ =>{
var newPoint = [
Math.random() * (Math.random() > 0.8 ? -.005 : .005) + lastPoint[0]
, Math.random() * (Math.random() > 0.2 ? -.005 : .005) + lastPoint[1]
]
lastPoint = newPoint;
return newPoint;
})
var distanceTotal = points
.reduce((dis, p, i)=>{
if(points[i + 1])
dis += wgs84Sphere.haversineDistance(p, points[i + 1] )
return dis;
}, 0);
console.log(distanceTotal)
var extent = new ol.extent.boundingExtent(points)
//console.log(points)
var lineString = new ol.Feature({
geometry : new ol.geom.LineString(points)
});
var source = new ol.source.Vector();
var layer = new ol.layer.Vector({ source });
source.addFeature(lineString);
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map',
controls: ol.control.defaults({
attributionOptions: /** #type {olx.control.AttributionOptions} */ ({
collapsible: false
})
}),
view: new ol.View({
projection : 'EPSG:4326',
center: [0, 0],
zoom: 2
})
});
map.addLayer(layer)
map.getView().fit(extent, map.getSize())
var auxLayer = new ol.layer.Vector({ source : new ol.source.Vector() })
var styleAux = new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'green',
width: 2
})
});
var styleAuxLine = new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'green',
width: 0.5
})
});
var styleAuxPoint = new ol.style.Style({
image : new ol.style.Circle({
radius: 5,
fill: null,
stroke: new ol.style.Stroke({color: 'black', width: 2})
})
});
var styleAuxSourcePoint = new ol.style.Style({
image : new ol.style.Circle({
radius: 3,
fill: null,
stroke: new ol.style.Stroke({color: '#00bbff', width: 0.5})
})
});
auxLayer.setStyle(function(f, r){
var type = f.getGeometry().getType();
if(type === 'LineString') return styleAux;
return styleAuxPoint;
})
map.addLayer(auxLayer);
map.on('pointermove', function(e){
if(e.dragging) return;
var coord = e.coordinate;
var distance = 0;
var pointsGeometry = [];
var sourcePointFeature = new ol.Feature({
geometry : new ol.geom.Point(coord)
});
var closestPoint = lineString.getGeometry().getClosestPoint(coord);
var lineDiffFeature = new ol.Feature({
geometry : new ol.geom.LineString([
coord, closestPoint
])
});
for(let i = 0; i< points.length - 1; i++){
var p = points[i]
var next = points[i + 1];
var subLineStringGeom = new ol.geom.LineString([ p, next ]);
pointsGeometry.push(p);
var e = 1e-10;
var extent = [ closestPoint[0] - e, closestPoint[1] - e
, closestPoint[0] + e, closestPoint[1] + e
]
if(subLineStringGeom.intersectsExtent(extent)){
//console.log(i);
pointsGeometry.push(closestPoint);
distance += wgs84Sphere.haversineDistance(p, closestPoint);
break;
}
distance += wgs84Sphere.haversineDistance(p, next);
}
console.log(closestPoint)
var cpGeometry = new ol.geom.Point(closestPoint);
var cpFeature = new ol.Feature({ geometry : cpGeometry });
var geometry = new ol.geom.LineString(pointsGeometry);
var newFeature = new ol.Feature({ geometry });
auxLayer.getSource().clear();
auxLayer.getSource().refresh();
auxLayer.getSource().addFeature(lineDiffFeature);
auxLayer.getSource().addFeature(newFeature);
auxLayer.getSource().addFeature(sourcePointFeature);
auxLayer.getSource().addFeature(cpFeature);
sourcePointFeature.setStyle(styleAuxSourcePoint);
lineDiffFeature.setStyle(styleAuxLine);
//console.log(geometry.getLength())
console.log(distance);
})
html, body, #map {
width : 100%;
height : 100%;
padding : 0px;
margin : 0px;
}
<script src="https://openlayers.org/en/v3.20.1/build/ol.js"></script>
<link href="https://openlayers.org/en/v3.20.1/css/ol.css" rel="stylesheet"/>
<div id="map" class="map" tabindex="0"></div>
I wanted to make a map using openlayers but center it a unique way. For example I have a z/x/y coordinate of 12/2045/-1362, how do I convert it to longitude/latitude? It's quite the polar opposite of this: How to get X Y Z coordinates of tile by click on Leaflet map
It's quite hard for me to get the logic of the above link and invert it. I hope someone here has an experience or a ready-made formula for this. Thanks
Later I'll this in rendering the center of my map like this:
var z = 12;
var x = 2045;
var y = -1362;
function convertXYZtoCoor(z, x, y) {
// code here
return [lng, lat];
}
var coor = convertXYZtoCoor(z, x, y);
var view = new ol.View({
center: ol.proj.transform(
[coor[0], coor[1]], 'EPSG:4326', 'EPSG:3857'),
zoom: z
});
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map',
view: view
});
Hope my question is understood more thanks.
Edit: Added code
var tileExtent = function(tileCoord){
var z = tileCoord[0];
var x = tileCoord[1];
var y = tileCoord[2];
var tileGridOrigin = tileGrid.getOrigin(z);
var tileSizeAtResolution = tileGrid.getTileSize(z) * tileGrid.getResolution(z);
return [
tileGridOrigin[0] + tileSizeAtResolution * x,
tileGridOrigin[1] + tileSizeAtResolution * y,
tileGridOrigin[0] + tileSizeAtResolution * (x + 1),
tileGridOrigin[1] + tileSizeAtResolution * (y + 1)
];
}
You can test/verify at http://jsfiddle.net/eurx57s7/
Note (stolen from the ol3 example, but it applies here to):
The tile coordinates are ol3 normalized tile coordinates (origin bottom left), not OSM tile coordinates (origin top left)
I'm trying to put together a Image map with a custom projection. I borrowed code from the following 3 URL's:
https://developers.google.com/maps/documentation/javascript/examples/map-coordinates
https://developers.google.com/maps/documentation/javascript/examples/maptype-image
https://developers.google.com/maps/documentation/javascript/examples/map-projection-simple
I added code to loop through all Lat and Lng values in 10 degree increments, but only some markers actually show.
If I remove the line:
mapType.projection = new MercatorProjection();
then the markers all show as expected. That means I can't use my custom projection, unless there is a better way.
All the Javascript code is below and should show you the moon with markers.
Thanks.
<!DOCTYPE html>
<html>
<head>
<title>Showing pixel and tile coordinates</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script>
var map;
var TILE_SIZE = 256;
var chicago = new google.maps.LatLng(41.850033,-87.6500523);
function modulo(n, d) {
var result = (n % d + d) % d;
return result;
}
function bound(value, opt_min, opt_max) {
if (opt_min != null) value = Math.max(value, opt_min);
if (opt_max != null) value = Math.min(value, opt_max);
return value;
}
function degreesToRadians(deg) {
return deg * (Math.PI / 180);
}
function radiansToDegrees(rad) {
return rad / (Math.PI / 180);
}
/** #constructor */
function MercatorProjection() {
this.pixelOrigin_ = new google.maps.Point(TILE_SIZE / 2, TILE_SIZE / 2);
this.pixelsPerLonDegree_ = TILE_SIZE / 360;
this.pixelsPerLonRadian_ = TILE_SIZE / (2 * Math.PI);
}
MercatorProjection.prototype.fromLatLngToPoint = function(latLng, opt_point) {
var me = this;
var point = opt_point || new google.maps.Point(0, 0);
var origin = me.pixelOrigin_;
point.x = origin.x + latLng.lng() * me.pixelsPerLonDegree_;
// Truncating to 0.9999 effectively limits latitude to 89.189. This is
// about a third of a tile past the edge of the world tile.
var siny = bound(Math.sin(degreesToRadians(latLng.lat())), -0.9999, 0.9999);
point.y = origin.y + 0.5 * Math.log((1 + siny) / (1 - siny)) * -me.pixelsPerLonRadian_;
return point;
};
MercatorProjection.prototype.fromPointToLatLng = function(point) {
var me = this;
var origin = me.pixelOrigin_;
var lng = (point.x - origin.x) / me.pixelsPerLonDegree_;
var latRadians = (point.y - origin.y) / -me.pixelsPerLonRadian_;
var lat = radiansToDegrees(2 * Math.atan(Math.exp(latRadians)) - Math.PI / 2);
return new google.maps.LatLng(lat, lng);
};
// Normalizes the coords that tiles repeat across the x axis (horizontally)
// like the standard Google map tiles.
function getNormalizedCoord(coord, zoom) {
var y = coord.y;
var x = coord.x;
// tile range in one direction range is dependent on zoom level
// 0 = 1 tile, 1 = 2 tiles, 2 = 4 tiles, 3 = 8 tiles, etc
var numTiles = 1 << zoom;
// don't repeat across y-axis (vertically)
if (y < 0 || y >= numTiles) {
return null;
}
// repeat across x-axis
if (x < 0 || x >= numTiles) {
x = modulo(x, numTiles);
}
return {
x: x,
y: y
};
}
function createInfoWindowContent() {
var numTiles = 1 << map.getZoom();
var projection = new MercatorProjection();
var worldCoordinate = projection.fromLatLngToPoint(chicago);
var pixelCoordinate = new google.maps.Point(
worldCoordinate.x * numTiles,
worldCoordinate.y * numTiles);
var tileCoordinate = new google.maps.Point(
Math.floor(pixelCoordinate.x / TILE_SIZE),
Math.floor(pixelCoordinate.y / TILE_SIZE));
return [
'Chicago, IL',
'LatLng: ' + chicago.lat() + ' , ' + chicago.lng(),
'World Coordinate: ' + worldCoordinate.x + ' , ' +
worldCoordinate.y,
'Pixel Coordinate: ' + Math.floor(pixelCoordinate.x) + ' , ' +
Math.floor(pixelCoordinate.y),
'Tile Coordinate: ' + tileCoordinate.x + ' , ' +
tileCoordinate.y + ' at Zoom Level: ' + map.getZoom()
].join('<br>');
}
function initialize() {
var mapType = new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
var normalizedCoord = getNormalizedCoord(coord, zoom);
if (!normalizedCoord) {
return null;
}
var bound = Math.pow(2, zoom);
return 'http://mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw' +
'/' + zoom + '/' + normalizedCoord.x + '/' +
(bound - normalizedCoord.y - 1) + '.jpg';
},
tileSize: new google.maps.Size(TILE_SIZE, TILE_SIZE),
maxZoom: 9,
minZoom: 0,
radius: 1738000,
name: 'MyMap'
});
mapType.projection = new MercatorProjection(); // Remove and Markers Will Show Correctly
var mapOptions = {
zoom: 3,
center: chicago
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
map.mapTypes.set('mymap', mapType);
map.setMapTypeId('mymap');
var coordInfoWindow = new google.maps.InfoWindow();
coordInfoWindow.setContent(createInfoWindowContent());
coordInfoWindow.setPosition(chicago);
coordInfoWindow.open(map);
google.maps.event.addListener(map, 'zoom_changed', function() {
coordInfoWindow.setContent(createInfoWindowContent());
coordInfoWindow.open(map);
});
for (var lat=-80; lat<85; lat+=10) {
for (var lng=-180; lng<180; lng+=10) {
var markerlatlng = new google.maps.LatLng(lat, lng);
var marker = new google.maps.Marker({
position: markerlatlng,
map: map,
title: "Moon Marker"
});
}
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
There is nothing wrong with the projection, there seems to be a bug with the rendering of the markers, the missing markers are covered by tiles.
Set the optimized-option of the markers to false and all markers will appear.
I want to add a marker every 5 or 10 Kilometer on the polylines of the direction given by google maps api.
something like this :
http://www.geocodezip.com/v3_polyline_example_kmmarkers_0.html
but with the google direction's
I found a formula that works like a charm. It adds a marker every 8 meter between to given points.
I got the formula from here: How to calculate the points between two given points and given distance?
PointF pointA, pointB;
var diff_X = pointB.X - pointA.X;
var diff_Y = pointB.Y - pointA.Y;
int pointNum = 8;
var interval_X = diff_X / (pointNum + 1);
var interval_Y = diff_Y / (pointNum + 1);
List<PointF> pointList = new List<PointF>();
for (int i = 1; i <= pointNum; i++)
{
pointList.Add(new PointF(pointA.X + interval_X * i, pointA.Y + interval_Y*i));
}
Android
My end result translation
//GeoPoint PointF, pointA, pointB;
Double diff_X = lat2 - lat1;
Double diff_Y = lon2 - lon1;
int pointNum = 8;
Double interval_X = diff_X / (pointNum + 1);
Double interval_Y = diff_Y / (pointNum + 1);
//ArrayList<GeoPoint> geoPoints = new ArrayList<>();
List<GeoPoint> pointList = new ArrayList<>();
for (int i = 1; i <= pointNum; i++)
{
GeoPoint g = new GeoPoint(lat1 + interval_X * i, lon1 + interval_Y*i);
pointList.add(g);
itemizedLayer.addItem(createMarkerItem(g, R.drawable.ic_my_location));
}
map.map().updateMap(true);
Given a start point, initial bearing, and distance, this will
calculate the destination point and final bearing travelling along a
(shortest distance) great circle arc.
var lat2 = Math.asin( Math.sin(lat1)*Math.cos(d/R) +
Math.cos(lat1)*Math.sin(d/R)*Math.cos(brng) );
var lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(lat1),
Math.cos(d/R)-Math.sin(lat1)*Math.sin(lat2));
source: http://www.movable-type.co.uk/scripts/latlong.html
The radius of the earth (R) is 6371000 meters.
brng is the direction you are travelling in degrees (0 = north).
Then use this function to add markers to the map
function setMarkers(map, locations) {
// Add markers to the map
// Marker sizes are expressed as a Size of X,Y
// where the origin of the image (0,0) is located
// in the top left of the image.
// Origins, anchor positions and coordinates of the marker
// increase in the X direction to the right and in
// the Y direction down.
var image = {
url: 'images/beachflag.png',
// This marker is 20 pixels wide by 32 pixels tall.
size: new google.maps.Size(20, 32),
// The origin for this image is 0,0.
origin: new google.maps.Point(0,0),
// The anchor for this image is the base of the flagpole at 0,32.
anchor: new google.maps.Point(0, 32)
};
var shadow = {
url: 'images/beachflag_shadow.png',
// The shadow image is larger in the horizontal dimension
// while the position and offset are the same as for the main image.
size: new google.maps.Size(37, 32),
origin: new google.maps.Point(0,0),
anchor: new google.maps.Point(0, 32)
};
// Shapes define the clickable region of the icon.
// The type defines an HTML <area> element 'poly' which
// traces out a polygon as a series of X,Y points. The final
// coordinate closes the poly by connecting to the first
// coordinate.
var shape = {
coord: [1, 1, 1, 20, 18, 20, 18 , 1],
type: 'poly'
};
for (var i = 0; i < locations.length; i++) {
var beach = locations[i];
var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
shadow: shadow,
icon: image,
shape: shape,
title: beach[0],
zIndex: beach[3]
});
}
}
source:
https://developers.google.com/maps/documentation/javascript/overlays
Edit that function to have the proper marker icons and call it for each marker you want to place.