GoogleMaps Polyline Length in V3 - google-maps

There doesn't seem to be a length funciton for the Polyline in Google Maps anymore in V3.
Has anyone found a workaround for this functionality gap?

<script type="text/javascript"
src="http://maps.google.com/maps/api/js?libraries=geometry&sensor=true"></script>
... var path = poly.getPath(); // or:
var path = polygon.getPath();
... = google.maps.geometry.spherical.computeLength(path.getArray())
... = google.maps.geometry.spherical.computeArea(path.getArray())
--> distance for polyline, area for polygon
and between two points:
computeDistanceBetween()
Don't forget to specify the geometry library (libraries=geometry)
http://code.google.com/apis/maps/documentation/javascript/geometry.html

here's the prototypes for the required function - hope this helps any further:
google.maps.Polygon.prototype.Distance = function() {
var dist = 0;
for (var i=1; i < this.getPath().getLength(); i++) {
dist += this.getPath().getAt(i).distanceFrom(this.getPath().getAt(i-1));
}
return dist;
}
google.maps.LatLng.prototype.distanceFrom = function(newLatLng) {
//var R = 6371; // km (change this constant to get miles)
var R = 6378100; // meters
var lat1 = this.lat();
var lon1 = this.lng();
var lat2 = newLatLng.lat();
var lon2 = newLatLng.lng();
var dLat = (lat2-lat1) * Math.PI / 180;
var dLon = (lon2-lon1) * Math.PI / 180;
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1 * Math.PI / 180 ) * Math.cos(lat2 * Math.PI / 180 ) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return d;
}
source

There is now a method in the Google Maps Javascript API v3 geometry library to compute the distance between two google.maps.LatLng objects in meters google.maps.geometry.spherical.computeDistanceBetween.
And a method in the Google Maps Javascript API v3 geometry library to compute the length of a polyline google.maps.geometry.poly.computeLength.
Concept from the Google Maps JavaScript API v3 groups post referenced in Hamish's answer, but using the Google Maps Javascript API v3 geometry library method computeDistanceBetween:
google.maps.Polyline.prototype.inKm = function(n) {
var a = this.getPath(n),
len = a.getLength(),
dist = 0;
for (var i = 0; i < len - 1; i++) {
dist += google.maps.geometry.spherical.computeDistanceBetween(a.getAt(i), a.getAt(i + 1));
}
return dist / 1000;
}
The result is the length of the polyline in kilometers. The optional
parameter is the path index of multi path polylines.
proof of concept fiddle
Using computeLength:
google.maps.geometry.spherical.computeLength(poly.getPath())/1000
proof of concept fiddle
code snippet:
var map;
var poly;
var gmarkers = [];
function initialize() {
map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 11,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
google.maps.event.addListener(map, 'click', addLatLng);
var polyCoord = [
new google.maps.LatLng(41.86, 8.73),
new google.maps.LatLng(41.88, 8.75)
];
var bounds = new google.maps.LatLngBounds();
bounds.extend(polyCoord[0]);
bounds.extend(polyCoord[1]);
map.fitBounds(bounds);
google.maps.event.addListenerOnce(map, 'bounds_changed', function() {
map.setZoom(map.getZoom() - 2);
});
// Polyline
poly = new google.maps.Polyline({
path: polyCoord
});
poly.binder = new MVCArrayBinder(poly.getPath());
var marker0 = new google.maps.Marker({
position: event.latLng,
title: '#0',
map: map,
icon: {
path: 'M256,320c-70.688,0-128-57.312-128-128c0-70.687,57.313-128,128-128c70.688,0,128,57.313,128,128C384,262.688,326.688,320,256,320z',
fillColor: 'white',
fillOpacity: 1,
scale: 0.025,
strokeColor: 'black',
strokeWeight: 1,
strokeOpacity: 1,
anchor: new google.maps.Point(200, 200)
},
draggable: true
});
marker0.bindTo('position', poly.binder, (0).toString());
google.maps.event.addListener(marker0, 'dragend', updateLength);
gmarkers.push(marker0);
var marker1 = new google.maps.Marker({
position: event.latLng,
title: '#1',
map: map,
icon: {
path: 'M256,320c-70.688,0-128-57.312-128-128c0-70.687,57.313-128,128-128c70.688,0,128,57.313,128,128C384,262.688,326.688,320,256,320z',
fillColor: 'white',
fillOpacity: 1,
scale: 0.025,
strokeColor: 'black',
strokeWeight: 1,
strokeOpacity: 1,
anchor: new google.maps.Point(200, 200)
},
draggable: true
});
marker1.bindTo('position', poly.binder, (1).toString());
google.maps.event.addListener(marker1, 'dragend', updateLength);
gmarkers.push(marker1);
poly.setMap(map);
updateLength();
}
function updateLength() {
document.getElementById('length').value = (google.maps.geometry.spherical.computeLength(poly.getPath()) / 1000).toFixed(2);
};
google.maps.event.addDomListener(window, "load", initialize);
/**
* Handles click events on a map, and adds a new point to the Polyline.
* #param {MouseEvent} mouseEvent
*/
function addLatLng(event) {
var path = poly.getPath();
path.push(event.latLng);
var len = path.getLength();
var marker = new google.maps.Marker({
position: event.latLng,
title: '#' + len,
map: map,
icon: {
path: 'M256,320c-70.688,0-128-57.312-128-128c0-70.687,57.313-128,128-128c70.688,0,128,57.313,128,128C384,262.688,326.688,320,256,320z',
fillColor: 'white',
fillOpacity: 1,
scale: 0.025,
strokeColor: 'black',
strokeWeight: 1,
strokeOpacity: 1,
anchor: new google.maps.Point(200, 200)
},
draggable: true
});
gmarkers.push(marker);
marker.bindTo('position', poly.binder, (len - 1).toString());
google.maps.event.addListener(marker, 'dragend', updateLength);
document.getElementById('length').value = poly.inKm().toFixed(2);
}
/*
* Use bindTo to allow dynamic drag of markers to refresh poly.
*/
function MVCArrayBinder(mvcArray) {
this.array_ = mvcArray;
}
MVCArrayBinder.prototype = new google.maps.MVCObject();
MVCArrayBinder.prototype.get = function(key) {
if (!isNaN(parseInt(key))) {
return this.array_.getAt(parseInt(key));
} else {
this.array_.get(key);
}
}
MVCArrayBinder.prototype.set = function(key, val) {
if (!isNaN(parseInt(key))) {
this.array_.setAt(parseInt(key), val);
} else {
this.array_.set(key, val);
}
}
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<label>polyline length (km):</label>
<input id="length" type="text" />
<div id="map_canvas" style="border: 2px solid #3872ac;"></div>

It has to be done segment by segment.
See this Google Maps JavaScript API v3 groups post for a suggested solution.

I went looking for the same information and found that the api call you're looking for is in the geometry.spherical namespace.
Here's the code I'm using:
//Path is the mvc array of lat/lng that makes up the polyline
var path = $scope.courseLine.getPath();
$scope.totalDistance = google.maps.geometry.spherical.computeLength(path);
$scope.totalMiles = ($scope.totalDistance * 0.00062137).toFixed(2) + " mi";
});

If you got the polyline from DirectionsService, check distance and duration in DirectionsLeg.
https://developers.google.com/maps/documentation/javascript/reference#DirectionsLeg

Get the distance between the 2 LatLngs it connects using the haversine formula

Related

How to add Multiple Polylines using Google Map JS Api while using addListeners

I am trying to add multiple polylines to the following sample and if i do so it is drawing the latest polyline and removing the old one. I know it can be done while loading the map. I have to use the following logic as it is perfectly drawing the arc between markers.
var map;
var curvature = 0.5; // how curvy to make the arc
function init() {
var Map = google.maps.Map,
LatLng = google.maps.LatLng,
LatLngBounds = google.maps.LatLngBounds,
Marker = google.maps.Marker,
Point = google.maps.Point;
// This is the initial location of the points
// (you can drag the markers around after the map loads)
var pos1 = new LatLng(38.60971599083999, -105.42822913560047);
var pos2 = new LatLng(31.549917555822212, -99.49938531446615);
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,
// draggable: true,
map: map
});
var markerP2 = new Marker({
position: pos2,
// draggable: true,
map: map
});
var curveMarker;
function updateCurveMarker() {
var pos1 = markerP1.getPosition(), // latlng
pos2 = markerP2.getPosition(),
projection = map.getProjection(),
p1 = projection.fromLatLngToPoint(pos1), // xy
p2 = projection.fromLatLngToPoint(pos2);
// Calculate the arc.
// To simplify the math, these points
// are all relative to p1:
var e = new Point(p2.x - p1.x, p2.y - p1.y), // endpoint (p2 relative to p1)
m = new Point(e.x / 2, e.y / 2), // midpoint
o = new Point(e.y, -e.x), // orthogonal
c = new Point( // curve control point
m.x + curvature * o.x,
m.y + curvature * o.y);
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.addDomListener(window, 'load', init);
html, body, #map-canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry,places&key=YOUR_API_KEY"></script>
<div id="map-canvas" style="border: 2px solid #3872ac;"></div>
How to add multiple polylines by adapting to the curve logic above?
Encapsulate the functionality to make the curve in a function and call it for every curve you want to appear on the map:
function createCurveMarker(marker1, marker2, map) {
var curveMarker;
function updateCurveMarker() {
var pos1 = marker1.getPosition(), // latlng
pos2 = marker2.getPosition(),
projection = map.getProjection(),
p1 = projection.fromLatLngToPoint(pos1), // xy
p2 = projection.fromLatLngToPoint(pos2);
// Calculate the arc.
// To simplify the math, these points
// are all relative to p1:
var e = new google.maps.Point(p2.x - p1.x, p2.y - p1.y), // endpoint (p2 relative to p1)
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( // curve control point
m.x + curvature * o.x,
m.y + curvature * o.y);
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 google.maps.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);
}
working code snippet:
var map;
var curvature = 0.5; // how curvy to make the arc
function init() {
// This is the initial location of the points
// (you can drag the markers around after the map loads)
var pos1 = new google.maps.LatLng(38.60971599083999, -105.42822913560047);
var pos2 = new google.maps.LatLng(31.549917555822212, -99.49938531446615);
var bounds = new google.maps.LatLngBounds();
bounds.extend(pos1);
bounds.extend(pos2);
map = new google.maps.Map(document.getElementById('map-canvas'), {
center: bounds.getCenter(),
zoom: 12
});
var markerP1 = new google.maps.Marker({
position: pos1,
zIndex: 10,
map: map
});
var markerP2 = new google.maps.Marker({
position: pos2,
zIndex: 10,
map: map
});
createCurveMarker(markerP1, markerP2, map);
var pos3 = new google.maps.LatLng(43.8041334, -120.5542012);
var pos4 = new google.maps.LatLng(38.8026097, -116.419389);
bounds.extend(pos3);
bounds.extend(pos4);
map.fitBounds(bounds);
var markerP3 = new google.maps.Marker({
position: pos3,
zIndex: 10,
map: map
});
var markerP4 = new google.maps.Marker({
position: pos4,
zIndex: 10,
map: map
});
createCurveMarker(markerP3, markerP4, map);
}
google.maps.event.addDomListener(window, 'load', init);
function createCurveMarker(marker1, marker2, map) {
var curveMarker;
function updateCurveMarker() {
var pos1 = marker1.getPosition(), // latlng
pos2 = marker2.getPosition(),
projection = map.getProjection(),
p1 = projection.fromLatLngToPoint(pos1), // xy
p2 = projection.fromLatLngToPoint(pos2);
// Calculate the arc.
// To simplify the math, these points
// are all relative to p1:
var e = new google.maps.Point(p2.x - p1.x, p2.y - p1.y), // endpoint (p2 relative to p1)
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( // curve control point
m.x + curvature * o.x,
m.y + curvature * o.y);
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 google.maps.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);
}
html,
body,
#map-canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map-canvas" ></div>

Google maps v3 - Add markers at the center of tiles

function initialize() {
var myLatlng;
var mapOptions;
myLatlng = new google.maps.LatLng(29.98439980, -95.34140015);
mapOptions = {
zoom: 16,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(
document.getElementById("map-canvas"), mapOptions);
google.maps.event.addListenerOnce(map, 'idle', function() {
drawRectangle(map);
var result = {"regionList":[{"centerLongitude":-95.34890747070312,"imageIcon":"../images/untested-icon.png","centerLatitude":29.980682373046875},{"centerLongitude":-95.34890747070312,"imageIcon":"../images/untested-icon.png","centerLatitude":29.988117218017578},{"centerLongitude":-95.33389282226562,"imageIcon":"../images/untested-icon.png","centerLatitude":29.980682373046875},{"centerLongitude":-95.33389282226562,"imageIcon":"../images/untested-icon.png","centerLatitude":29.988117218017578}]};
alert(result);
addMarkersAtRegionCenter(map, result);
});
function addMarkersAtRegionCenter(map, result) {
var length = result.regionList.length;
var regionUrl = "drilledDownToRegion.jsp?";
for(var i=0; i<length; i++)
{
var image = result.regionList[i].imageIcon;
//alert("Latitude : " + result.regionList[i].centerLatitude);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(result.regionList[i].centerLatitude,result.regionList[i].centerLongitude),
icon: 'http://maps.google.com/mapfiles/ms/icons/blue.png',
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) { return function() {
window.location.href = marker.url;
}
})(marker, i));
}
}
function drawRectangle(map) {
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var numberOfParts = 4;
var tileWidth = (northEast.lng() - southWest.lng()) / numberOfParts;
var tileHeight = (northEast.lat() - southWest.lat()) / numberOfParts;
for (var x = 0; x < numberOfParts; x++) {
for (var y = 0; y < numberOfParts; y++) {
var areaBounds = {
north: southWest.lat() + (tileHeight * (y+1)),
south: southWest.lat() + (tileHeight * y),
east: southWest.lng() + (tileWidth * (x+1)),
west: southWest.lng() + (tileWidth * x)
};
var area = new google.maps.Rectangle({
strokeColor: '#FF0000',
//strokeOpacity: 0.8,
strokeWeight: 2,
//fillColor: '#FF0000',
//fillOpacity: 0.35,
map: map,
bounds: areaBounds
});
}
}
}
}
google.maps.event.addDomListener(window, "load", initialize);
In the above code, I am trying to add markers at the center of each rectangle. But I am not able to add markers. I have hard coded image icon value since I don't have image mentioned in the array.
Thanks in advance for your help.
Related question: Google maps api v3 - divide region into equal parts using tiles
Simpler to add the markers to the centers of the rectangles when you create them:
var centerMark = new google.maps.Marker({
position: area.getBounds().getCenter(),
map: map
});
proof of concept fiddle
To add the markers from the response to the map (the positions in the posted response are not at the center of the squares), this is the same function you posted in your question, it works for me (the blue markers), I modified your click listener to open an infowindow (rather than do a redirect of the page):
function addMarkersAtRegionCenter(map, result) {
var length = result.regionList.length;
var regionUrl = "drilledDownToRegion.jsp?";
for (var i = 0; i < length; i++) {
var image = result.regionList[i].imageIcon;
var marker = new google.maps.Marker({
position: new google.maps.LatLng(result.regionList[i].centerLatitude, result.regionList[i].centerLongitude),
icon: 'http://maps.google.com/mapfiles/ms/icons/blue.png',
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
// window.location.href = marker.url;
infowindow.setContent("regionList:" + i + "<br>centLat=" + result.regionList[i].centerLatitude + "<br>centLng=" + result.regionList[i].centerLongitude + "<br>imageIcon=" + result.regionList[i].imageIcon + "<br>" + marker.getPosition().toUrlValue(6));
infowindow.open(map, marker);
}
})(marker, i));
}
}

Intersection of two polygons in google map

I am trying to draw multiple polygons using google shapes API. I need to get the intersection of two polygons.
Here I can draw the background polygon(in black) by giving the array of path of each polygon.
Below is my code, here I am giving MVC Array as paths for polygon.
I just want the intersection area to be in separate color. Please check the screen shot link attached after the code.
var bgAreaCoordinates = [];
var bgbounds = map.getBounds(); // Boundary coordinates of the visible area of map
var NE = bgbounds.getNorthEast();
var SW = bgbounds.getSouthWest();
var bgPathCoordinates = [NE, new google.maps.LatLng(NE.lat(),SW.lng()),
SW, new google.maps.LatLng(SW.lat(),NE.lng())];
// Array of boundary coordinates of the visible part of the map
bgAreaCoordinates.push(bgPathCoordinates);
for (var key in flightPlanCoordinates) {
for (var k in flightPlanCoordinates[key]) {
bgAreaCoordinates.push(flightPlanCoordinates[key][k]);// Getting array of coordinates of each polygon
}
}
if (bgPath['bg']) {
bgPath['bg'].setMap(null); // remove the previous bg
}
console.info(bgAreaCoordinates);
bgPath['bg'] = new google.maps.Polygon({
// paths: [bgPathCoordinates, bgAreaCoordinates],
paths:bgAreaCoordinates,
geodesic: true,
strokeColor: '',
strokeOpacity: 0,
strokeWeight: 0,
fillColor: '#687472',
fillOpacity: 0.7
});
bgPath['bg'].setMap(map); // Draw the bg polygon : Google shapes Api
http://i.stack.imgur.com/VjTZe.png
Thanks in advance!
Here is an example that does what I think you want to do (make a hole in a polygon that covers the earth and cover that hole with a polygon with a different color). The example polygon happens to be a circle.
code snippet
// This example creates circles on the map, representing
// populations in the United States.
// First, create an object containing LatLng and population for each city.
var citymap = {};
citymap['chicago'] = {
center: new google.maps.LatLng(41.878113, -87.629798),
population: 2842518
};
citymap['newyork'] = {
center: new google.maps.LatLng(40.714352, -74.005973),
population: 8143197
};
citymap['losangeles'] = {
center: new google.maps.LatLng(34.052234, -118.243684),
population: 3844829
};
var cityCircle;
var bounds = new google.maps.LatLngBounds();
function drawCircle(point, radius, dir) {
var d2r = Math.PI / 180; // degrees to radians
var r2d = 180 / Math.PI; // radians to degrees
var earthsradius = 3963; // 3963 is the radius of the earth in miles
var points = 32;
// find the raidus in lat/lon
var rlat = (radius / earthsradius) * r2d;
var rlng = rlat / Math.cos(point.lat() * d2r);
var extp = new Array();
if (dir == 1) {
var start = 0;
var end = points + 1
} // one extra here makes sure we connect the ends
else {
var start = points + 1;
var end = 0
}
for (var i = start;
(dir == 1 ? i < end : i > end); i = i + dir) {
var theta = Math.PI * (i / (points / 2));
ey = point.lng() + (rlng * Math.cos(theta)); // center a + radius x * cos(theta)
ex = point.lat() + (rlat * Math.sin(theta)); // center b + radius y * sin(theta)
extp.push(new google.maps.LatLng(ex, ey));
bounds.extend(extp[extp.length - 1]);
}
return extp;
}
function initialize() {
// Create the map.
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(37.09024, -95.712891),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var outerbounds = [
new google.maps.LatLng(85, 180),
new google.maps.LatLng(85, 90),
new google.maps.LatLng(85, 0),
new google.maps.LatLng(85, -90),
new google.maps.LatLng(85, -180),
new google.maps.LatLng(0, -180),
new google.maps.LatLng(-85, -180),
new google.maps.LatLng(-85, -90),
new google.maps.LatLng(-85, 0),
new google.maps.LatLng(-85, 90),
new google.maps.LatLng(-85, 180),
new google.maps.LatLng(0, 180),
new google.maps.LatLng(85, 180)
];
var populationOptions = {
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
paths: [outerbounds, drawCircle(citymap['newyork'].center, 10, -1)]
};
// Add the circle for this city to the map.
cityCircle = new google.maps.Polygon(populationOptions);
map.fitBounds(bounds);
var coverHole = new google.maps.Polygon({
strokeColor: '#FFFF00',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#0000FF',
fillOpacity: 0.35,
map: map,
paths: [drawCircle(citymap['newyork'].center, 10, -1)]
});
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map-canvas"></div>

Google Maps get the center of coordinates (place label at center of polygon)

I use Google maps, I mark areas on the maps like that:
var areaCoords2 = [
new google.maps.LatLng(32.819649, 35.073102),
new google.maps.LatLng(32.819604, 35.073026),
new google.maps.LatLng(32.817169, 35.071321),
new google.maps.LatLng(32.817097, 35.071353),
new google.maps.LatLng(32.816042, 35.073391),
new google.maps.LatLng(32.818513, 35.075119),
new google.maps.LatLng(32.818612, 35.075054)
];
I want to achieve: place the label and the marker in the middle(approximately) of the marked red area.
instead of place it with static Latitude and Longitude(I have a lot of areas)
There is a way of doing so programmatically?
The following code constructs a google.maps.Polygon and places a MapLabel at the center of its bounds.
// Construct the polygon.
var mypolygon2 = new google.maps.Polygon({
paths: polyCoords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 3,
fillColor: '#FF0000',
fillOpacity: 0.35
});
mypolygon2.setMap(map);
//Define position of label
var bounds = new google.maps.LatLngBounds();
for (var i=0; i< polyCoords.length; i++) {
bounds.extend(polyCoords[i]);
}
var myLatlng = bounds.getCenter();
var mapLabel2 = new MapLabel({
text: '2',
position: myLatlng,
map: map,
fontSize: 20,
align: 'left'
});
mapLabel2.set('position', myLatlng);
var obj = {};
obj.poly = mypolygon2;
obj.label = mapLabel2;
working fiddle
code snippet:
var map;
var gpolygons = [];
var infoWindow;
function initialize() {
var mapOptions = {
zoom: 17,
center: new google.maps.LatLng(50.71392, -1.983551),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
// Define the LatLng coordinates for the polygon.
var triangleCoords = [
new google.maps.LatLng(50.71433, -1.98392),
new google.maps.LatLng(50.71393, -1.98239),
new google.maps.LatLng(50.71388, -1.98226),
new google.maps.LatLng(50.71377, -1.98246),
new google.maps.LatLng(50.71332, -1.98296),
new google.maps.LatLng(50.71334, -1.98324),
new google.maps.LatLng(50.71374, -1.9845),
new google.maps.LatLng(50.71436, -1.98389)
];
// Construct the polygon.
var mypolygon = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 3,
fillColor: '#FF0000',
fillOpacity: 0.35
});
mypolygon.setMap(map);
//Define position of label
var myLatlng = new google.maps.LatLng(50.71392, -1.983551);
var mapLabel = new MapLabel({
text: '1',
position: myLatlng,
map: map,
fontSize: 20,
align: 'left'
});
mapLabel.set('position', myLatlng);
var obj = {};
obj.poly = mypolygon;
obj.label = mapLabel;
gpolygons.push(obj);
var polyCoords = [
new google.maps.LatLng(50.713689004418, -1.9845771789550781),
new google.maps.LatLng(50.71316590540595, -1.9829249382019043),
new google.maps.LatLng(50.71296209901576, -1.983107328414917),
new google.maps.LatLng(50.71296889257639, -1.9837510585784912),
new google.maps.LatLng(50.713186285996215, -1.9845235347747803),
new google.maps.LatLng(50.71293492476347, -1.9847595691680908),
new google.maps.LatLng(50.71311155712187, -1.9853174686431885),
new google.maps.LatLng(50.71335612390394, -1.9853603839874268),
new google.maps.LatLng(50.713396884910225, -1.9850599765777588),
new google.maps.LatLng(50.71348520030224, -1.9848453998565674),
new google.maps.LatLng(50.71357351552787, -1.9846951961517334)
]
// Construct the polygon.
var mypolygon2 = new google.maps.Polygon({
paths: polyCoords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 3,
fillColor: '#FF0000',
fillOpacity: 0.35
});
mypolygon2.setMap(map);
//Define position of label
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < polyCoords.length; i++) {
bounds.extend(polyCoords[i]);
}
var myLatlng = bounds.getCenter();
var mapLabel2 = new MapLabel({
text: '2',
position: myLatlng,
map: map,
fontSize: 20,
align: 'left'
});
mapLabel2.set('position', myLatlng);
var obj = {};
obj.poly = mypolygon2;
obj.label = mapLabel2;
gpolygons.push(obj);
// Add a listener for the click event. You can expand this to change the color of the polygon
google.maps.event.addListener(mypolygon, 'click', showArrays);
google.maps.event.addListener(mypolygon2, 'click', showArrays);
infoWindow = new google.maps.InfoWindow();
}
/** #this {google.maps.Polygon} */
function showArrays(event) {
//Change the color here
// toggle it
if (this.get("fillColor") != '#0000ff') {
this.setOptions({
fillColor: '#0000ff'
});
} else {
this.setOptions({
fillColor: '#ff0000'
});
}
// Since this polygon has only one path, we can call getPath()
// to return the MVCArray of LatLngs.
var vertices = this.getPath();
var contentString = '<b>My polygon</b><br>' +
'Clicked location: <br>' + event.latLng.lat() + ',' + event.latLng.lng() +
'<br>';
// Iterate over the vertices.
for (var i = 0; i < vertices.getLength(); i++) {
var xy = vertices.getAt(i);
contentString += '<br>' + 'Coordinate ' + i + ':<br>' + xy.lat() + ',' + xy.lng();
}
// Replace the info window's content and position.
infoWindow.setContent(contentString);
infoWindow.setPosition(event.latLng);
infoWindow.open(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map-canvas {
height: 100%;
margin: 0px;
padding: 0px;
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<script src="https://cdn.rawgit.com/googlemaps/js-map-label/gh-pages/src/maplabel.js"></script>
<title>Polygon Arrays</title>
<div id="map-canvas">
</div>
Here is a method that does what you ask for Android/Java. You can try to adjust it for use in the web:
public Location GetCentrePointFromListOfLocations(List<Location> coordList)
{
int total = coordList.size();
double X = 0;
double Y = 0;
double Z = 0;
for(Location location : coordList)
{
double lat = location.getLatitude() * Math.PI / 180;
double lon = location.getLongitude() * Math.PI / 180;
double x = Math.cos(lat) * Math.cos(lon);
double y = Math.cos(lat) * Math.sin(lon);
double z = Math.sin(lat);
X += x;
Y += y;
Z += z;
}
X = X / total;
Y = Y / total;
Z = Z / total;
double Lon = Math.atan2(Y, X);
double Hyp = Math.sqrt(X * X + Y * Y);
double Lat = Math.atan2(Z, Hyp);
Location tempLocation = new Location("");
tempLocation.setLatitude(Lat * 180 / Math.PI);
tempLocation.setLongitude(Lon * 180 / Math.PI);
return tempLocation;
}
Did you add
zoom: 10,
center: myLatlng,
for you Marker Object
(or)
// map: an instance of GMap3
// latlng: an array of instances of GLatLng
var latlngbounds = new google.maps.LatLngBounds();
latlng.each(function(n){
latlngbounds.extend(n);
});
map.setCenter(latlngbounds.getCenter());
map.fitBounds(latlngbounds);
This one works for me with the dynamic polygon values.
<script type="text/javascript" src="https://cdn.rawgit.com/googlemaps/js-map-label/gh-pages/src/maplabel.js"></script>
<script>
// This example creates a simple polygon representing the Bermuda Triangle.
var gpolygons = [];
function initStaticMap() {
var bounds = new google.maps.LatLngBounds();
var latlng = new google.maps.LatLng(-22.5747697,-43.857650); //-22.820554842103107--43.184738187119365
var map = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
});
// Define the LatLng coordinates for the polygon's path.
<?php if($store_delivery_zone){ foreach($store_delivery_zone as $point){ ?>
var coord<?php echo $point['delivery_zone_id']; ?> = <?php echo $point['polygon_points']; ?>;
// Construct the polygon.
var poly<?php echo $point['delivery_zone_id']; ?> = new google.maps.Polygon({
paths: coord<?php echo $point['delivery_zone_id']; ?>,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
});
poly<?php echo $point['delivery_zone_id']; ?>.setMap(map);
//var center = poly<?php echo $point['delivery_zone_id']; ?>.getBounds().getCenter();
//map.fitBounds(poly<?php echo $point['delivery_zone_id']; ?>.getBounds());
//Define position of label
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < coord<?php echo $point['delivery_zone_id']; ?>.length; i++) {
bounds.extend(coord<?php echo $point['delivery_zone_id']; ?>[i]);
}
var myLatlng<?php echo $point['delivery_zone_id']; ?> = bounds.getCenter();
var mapLabel<?php echo $point['delivery_zone_id']; ?> = new MapLabel({
text: '<?php echo $point['delivery_cost']; ?>',
position: myLatlng<?php echo $point['delivery_zone_id']; ?>,
map: map,
fontSize: 20,
align: 'left'
});
mapLabel<?php echo $point['delivery_zone_id']; ?>.set('position', myLatlng<?php echo $point['delivery_zone_id']; ?>);
var obj = {};
obj.poly = poly<?php echo $point['delivery_zone_id']; ?>;
obj.label = mapLabel<?php echo $point['delivery_zone_id']; ?>;
gpolygons.push(obj);
<?php } } ?>
google.maps.event.addListener(map, "idle", function()
{
google.maps.event.trigger(map, 'resize');
});
}
</script>
For Android/Java there is no need to start inventing an algorithm yourself, JTS is the package for such functionality.
// use jts to get suitable coordinate for label inside polygon
// convert google maps latlong to jts coordinates
List<Coordinate> jtsCoordinateList = new ArrayList<>();
for (LatLng gMapLatLng : polygon.getPoints())
jtsCoordinateList.add(new Coordinate(gMapLatLng.latitude, gMapLatLng.longitude));
Coordinate[] jtsCoordinateArray = jtsCoordinateList.toArray(new Coordinate[0]);
// create jts polygon
Geometry jtsGeometry = new GeometryFactory().createPolygon(jtsCoordinateArray);
// initiate InteriorPointArea
InteriorPointArea interiorPointArea = new InteriorPointArea(jtsGeometry);
// use InteriorPointArea to get the coordinate
Coordinate jtsInteriorPoint = interiorPointArea.getInteriorPoint();
// convert jts coordinate to google maps coordinate
LatLng polygonPoint = new LatLng(jtsInteriorPoint.getX(), jtsInteriorPoint.getY());
// use the calculated coordinate to place a marker
marker = createViewMarker(context, map, polygonPoint, legend);

Google Maps Rotate Polygon

After drawing a Polygon shape on the map. I would like to change what direction the polygon is pointing when the map is refreshed by rotating around one of the points of the polygon. For example point the polygon in the direction of 90 degrees rotating around my first polygon point (code shown below). Can anyone provide any code examples of this working?
I have seen some similar posts however examples given appear over complicated.
poly = new google.maps.Polygon({
strokeWeight: 3,
fillColor: '#5555FF'
});
poly.setMap(map);
poly.setPaths(new google.maps.MVCArray([path]));
var triangleCoords = [
new google.maps.LatLng(51.5087, -0.1277),
new google.maps.LatLng(51.5387, -0.1077),
new google.maps.LatLng(51.5387, -0.1477),
new google.maps.LatLng(51.5087, -0.1277)
];
// Construct the polygon
triangle = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.8
});
triangle.setMap(map);
google.maps.event.addListener(map, 'click', triangle);
}
The following example demonstrates how to rotate a polygon
Note: the rotation is performed around the first point
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 5,
center: {lat: 24.886, lng: -70.268},
mapTypeId: google.maps.MapTypeId.TERRAIN
});
// Define the LatLng coordinates for the polygon's path.
var triangleCoords = [
{lat: 25.774, lng: -80.190},
{lat: 18.466, lng: -66.118},
{lat: 32.321, lng: -64.757},
{lat: 25.774, lng: -80.190}
];
// Construct the polygon.
var bermudaTriangle = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
});
bermudaTriangle.setMap(map);
//rotate a polygon
document.getElementById('btnRotate').onclick = function() {
rotatePolygon(bermudaTriangle, 90);
};
}
function rotatePolygon(polygon,angle) {
var map = polygon.getMap();
var prj = map.getProjection();
var origin = prj.fromLatLngToPoint(polygon.getPath().getAt(0)); //rotate around first point
var coords = polygon.getPath().getArray().map(function(latLng){
var point = prj.fromLatLngToPoint(latLng);
var rotatedLatLng = prj.fromPointToLatLng(rotatePoint(point,origin,angle));
return {lat: rotatedLatLng.lat(), lng: rotatedLatLng.lng()};
});
polygon.setPath(coords);
}
function rotatePoint(point, origin, angle) {
var angleRad = angle * Math.PI / 180.0;
return {
x: Math.cos(angleRad) * (point.x - origin.x) - Math.sin(angleRad) * (point.y - origin.y) + origin.x,
y: Math.sin(angleRad) * (point.x - origin.x) + Math.cos(angleRad) * (point.y - origin.y) + origin.y
};
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
#floating-panel {
position: absolute;
top: 10px;
left: 25%;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
text-align: center;
font-family: 'Roboto','sans-serif';
line-height: 30px;
padding-left: 10px;
}
<div id="floating-panel">
<input type="button" id="btnRotate" value="Rotate 90"></div>
<div id="map"></div>
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>
JSFiddle
You might want to look at something like Mike Williams' eshapes library. It was written originally for the Google Maps API v2, but this page demonstrates the version that I ported to the Google Maps API v3.
example
proof of concept fiddle
code snippet;
var map = null;
var triangle, angle, point;
function initMap() {
point = new google.maps.LatLng(44, -80);
var myOptions = {
zoom: 8,
center: point,
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
},
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map"),
myOptions);
angle = 0;
// === Triangle ===
triangle = google.maps.Polyline.RegularPoly(point, 30000, 3, angle, "#ff0000", 8, 1);
triangle.setMap(map);
google.maps.event.addListener(triangle, "click", rotateTriangle);
}
google.maps.event.addDomListener(window, 'load', initMap);
function rotateTriangle() {
triangle.setMap(null);
angle += 90;
if (angle >= 360) angle -= 360;
triangle = google.maps.Polyline.RegularPoly(point, 30000, 3, angle, "#ff0000", 8, 1);
triangle.setMap(map);
google.maps.event.addListener(triangle, "click", rotateTriangle);
}
// This Javascript is based on code provided by the
// Community Church Javascript Team
// http://www.bisphamchurch.org.uk/
// http://econym.org.uk/gmap/
// From v3_eshapes.js:
// EShapes.js
//
// Based on an idea, and some lines of code, by "thetoy"
//
// This Javascript is provided by Mike Williams
// Community Church Javascript Team
// http://www.bisphamchurch.org.uk/
// http://econym.org.uk/gmap/
//
// This work is licenced under a Creative Commons Licence
// http://creativecommons.org/licenses/by/2.0/uk/
//
// Version 0.0 04/Apr/2008 Not quite finished yet
// Version 1.0 10/Apr/2008 Initial release
// Version 3.0 12/Oct/2011 Ported to v3 by Lawrence Ross
google.maps.Polyline.RegularPoly = function(point, radius, vertexCount, rotation, colour, weight, opacity, opts) {
rotation = rotation || 0;
var tilt = !(vertexCount & 1);
return google.maps.Polyline.Shape(point, radius, radius, radius, radius, rotation, vertexCount, colour, weight, opacity, opts, tilt)
}
google.maps.Polyline.Shape = function(point, r1, r2, r3, r4, rotation, vertexCount, colour, weight, opacity, opts, tilt) {
if (!colour) {
colour = "#0000FF";
}
if (!weight) {
weight = 4;
}
if (!opacity) {
opacity = 0.45;
}
var rot = -rotation * Math.PI / 180;
var points = [];
var latConv = google.maps.geometry.spherical.computeDistanceBetween(point, new google.maps.LatLng(point.lat() + 0.1, point.lng())) * 10;
var lngConv = google.maps.geometry.spherical.computeDistanceBetween(point, new google.maps.LatLng(point.lat(), point.lng() + 0.1)) * 10;
var step = (360 / vertexCount) || 10;
var flop = -1;
if (tilt) {
var I1 = 180 / vertexCount;
} else {
var I1 = 0;
}
for (var i = I1; i <= 360.001 + I1; i += step) {
var r1a = flop ? r1 : r3;
var r2a = flop ? r2 : r4;
flop = -1 - flop;
var y = r1a * Math.cos(i * Math.PI / 180);
var x = r2a * Math.sin(i * Math.PI / 180);
var lng = (x * Math.cos(rot) - y * Math.sin(rot)) / lngConv;
var lat = (y * Math.cos(rot) + x * Math.sin(rot)) / latConv;
points.push(new google.maps.LatLng(point.lat() + lat, point.lng() + lng));
}
return (new google.maps.Polyline({
path: points,
strokeColor: colour,
strokeWeight: weight,
strokeOpacity: opacity
}))
}
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<b>Click triangle's border to rotate it.</b>
<div id="map"></div>
I had the same issue, i wanted to rotate a symbol or polygon. The rotation attribute defines the rotation of the object and thats all.
Try it.
The path defines the shape of the polygon and uses SVG notation like (x,y) coordinates.
function init_nuevo_mapa(){
var mapOptions = {
zoom: 13
center: new google.maps.LatLng(-33.5351136,-70.5876618)
};
var new_map = new google.maps.Map(document.getElementById('new-map'), mapOptions);
var myLatLng = new google.maps.LatLng(-33.5351136,-70.5876618)
var image = {
path: 'M 0,0 -10,-30 10,-30 z',
rotation: 10, //10ยบ clockwise
fillColor: "red",
fillOpacity: 0.5,
scale: 1,
strokeColor: "red",
strokeWeight: 4
};
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
zIndex: zIndex,
title: location[2]
});
You can easily do it with the new Google Maps symbol object. Just take a look at https://developers.google.com/maps/documentation/javascript/reference#Symbol.
Warning: This works really bad with IE 9 when you have a lot of markers.
Good luck!