Is there any way to split circle in google maps in to the sectors by 120 degrees? Currently i draw a simple circle with radius, it looks like this:
map = new google.maps.Map(document.getElementById('map_canvas'), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoom: 16,
center: new google.maps.LatLng(55.685025, 21.118995)
});
var lat_lng = new google.maps.LatLng(55.685025, 21.118995);
marker = new google.maps.Marker({
position: lat_lng,
map: map,
icon: 'map_green.png'
});
circle = new google.maps.Circle({
map: map,
radius: 200,
fillColor: 'green',
center: lat_lng
});
Then i think i need to draw three polygons on top of the circle, but dont know how to calculate the position...
It should be like this:
Is there any way to split circle in google maps in to the sectors by 120 degrees? Currently i draw a simple circle with radius, it looks like this:
map = new google.maps.Map(document.getElementById('map_canvas'), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoom: 16,
center: new google.maps.LatLng(55.685025, 21.118995)
});
var lat_lng = new google.maps.LatLng(55.685025, 21.118995);
marker = new google.maps.Marker({
position: lat_lng,
map: map,
icon: 'map_green.png'
});
circle = new google.maps.Circle({
map: map,
radius: 200,
fillColor: 'green',
center: lat_lng
});
Then i think i need to draw three polygons on top of the circle, but dont know how to calculate the position...
It should be like this:
Share Improve this question asked Nov 14, 2013 at 9:37 KinKin 4,59614 gold badges59 silver badges114 bronze badges 2- Was just wondering, can you clarify reasoning behind splitting to three sections? Do you actually need three different polygons (which could be used for 'hit testing' of sorts or filled with different colors), or would just the three division lines suffice (as a sort of 'crosshairs' implementation)? – astupidname Commented Nov 14, 2013 at 9:46
- @astupidname need 3 different colors, o i think the polygon will be the best thing. – Kin Commented Nov 14, 2013 at 9:48
2 Answers
Reset to default 5Another way to do it, this one using the google.maps.geometry library, note the 'libraries=geometry' parameter in the google maps script src:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Some Title</title>
</head>
<body>
<div id="map_canvas" style="width:800px; height:600px; margin:0 auto;"></div>
<script src="https://maps.googleapis./maps/api/js?v=3.exp&libraries=geometry&sensor=false"></script>
<script type="text/javascript">
function initialize() {
var gm = google.maps,
centerPt = new gm.LatLng(55.685025, 21.118995),
map = new gm.Map(document.getElementById('map_canvas'), {
mapTypeId: gm.MapTypeId.ROADMAP,
zoom: 16,
center: centerPt
}),
marker = new gm.Marker({
position: centerPt,
map: map,
//Colors available (marker.png is red):
//black, brown, green, grey, orange, purple, white & yellow
icon: 'http://maps.google./mapfiles/marker_green.png'
}),
slices = [
//startAngle, endAngle, color to fill polygon with
[300, 60, 'red'],
[60, 180, 'green'],
[180, 300, 'blue']
],
polys = [],
i = 0,
radiusMeters = 200;
for (; i < slices.length; i++) {
var path = getArcPath(centerPt, radiusMeters, slices[i][0], slices[i][1]);
//Insert the center point of our circle as first item in path
path.unshift(centerPt);
//Add the center point of our circle as last item in path to create closed path.
//Note google does not actually require us to close the path,
//but doesn't hurt to do so
path.push(centerPt);
var poly = new gm.Polygon({
path: path,
map: map,
fillColor:slices[i][2],
fillOpacity:0.6
});
polys.push(poly);
}
}
/***
* REQUIRES: google.maps.geometry library, via a 'libraries=geometry' parameter
* on url to google maps script
* @param center must be a google.maps.LatLng object.
* @param radiusMeters must be a number, radius in meters.
* @param startAngle must be an integer from 0 to 360, angle at which to begin arc.
* @param endAngle must be an integer from 0 to 360, angle at which to end arc.
* For a full circle, use startAngle of 0 and endAngle of 360
* which will create a closed path.
* @param direction -optional- defaults to clockwise,
* pass string 'counterclockwise' to reverse direction.
* @Returns array of google.maps.LatLng objects.
***/
function getArcPath(center, radiusMeters, startAngle, endAngle, direction){
var point, previous,
atEnd = false,
points = Array(),
a = startAngle;
while (true) {
point = google.maps.geometry.spherical.puteOffset(center, radiusMeters, a);
points.push(point);
if (a == endAngle){
break;
}
a++;
if (a > 360) {
a = 1;
}
}
if (direction == 'counterclockwise') {
points = points.reverse();
}
return points;
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</body>
</html>
Example viewable here: http://jsfiddle/rkC2S/
One way to do it would be like this example
function drawArc(center, initialBearing, finalBearing, radius) {
var d2r = Math.PI / 180; // degrees to radians
var r2d = 180 / Math.PI; // radians to degrees
var points = 32;
// find the raidus in lat/lon
var rlat = (radius / EarthRadiusMeters) * r2d;
var rlng = rlat / Math.cos(center.lat() * d2r);
var extp = new Array();
if (initialBearing > finalBearing) finalBearing += 360;
var deltaBearing = finalBearing - initialBearing;
deltaBearing = deltaBearing/points;
for (var i=0; (i < points+1); i++)
{
extp.push(center.DestinationPoint(initialBearing + i*deltaBearing, radius));
bounds.extend(extp[extp.length-1]);
}
return extp;
}
var arcPts = drawArc(centerPoint, centerPoint.Bearing(startPoint), centerPoint.Bearing(endPoint), centerPoint.distanceFrom(startPoint), -1.0);
// add the start and end lines
arcPts.push(centerPoint);
bounds.extend(centerPoint);
arcPts.push(startPoint);
var piePoly = new google.maps.Polygon({
paths: [arcPts],
strokeColor: "#00FF00",
strokeOpacity: 0.5,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35,
map: map
})
It is from before the geometry library was available so it does some of the functionality available there differently, but that could be changed.
example using the geometry library
// from http://en.wikipedia/wiki/Earth_radius
/*
/ Equatorial radius
/ The Earth's equatorial radius a, or semi-major axis, is the distance from its center to the equator and equals 6,378.1370 km (?3,963.191 mi; ?3,443.918 nmi).
*/
var EarthRadiusMeters = 6378137.0; // meters
/* Based the on the Latitude/longitude spherical geodesy formulae & scripts
at http://www.movable-type.co.uk/scripts/latlong.html
(c) Chris Veness 2002-2010
*/
google.maps.LatLng.prototype.DestinationPoint = function (brng, dist) {
var R = EarthRadiusMeters; // earth's mean radius in meters
var brng = brng.toRad();
var lat1 = this.lat().toRad(), lon1 = this.lng().toRad();
var lat2 = Math.asin( Math.sin(lat1)*Math.cos(dist/R) +
Math.cos(lat1)*Math.sin(dist/R)*Math.cos(brng) );
var lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(dist/R)*Math.cos(lat1),
Math.cos(dist/R)-Math.sin(lat1)*Math.sin(lat2));
return new google.maps.LatLng(lat2.toDeg(), lon2.toDeg());
}
// === A function which returns the bearing between two LatLng in radians ===
// === If v1 is null, it returns the bearing between the first and last vertex ===
// === If v1 is present but v2 is null, returns the bearing from v1 to the next vertex ===
// === If either vertex is out of range, returns void ===
google.maps.LatLng.prototype.Bearing = function(otherLatLng) {
var from = this;
var to = otherLatLng;
if (from.equals(to)) {
return 0;
}
var lat1 = from.latRadians();
var lon1 = from.lngRadians();
var lat2 = to.latRadians();
var lon2 = to.lngRadians();
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 > Math.PI ) angle -= Math.PI * 2.0;
return parseFloat(angle.toDeg());
}
/**
* Extend the Number object to convert degrees to radians
*
* @return {Number} Bearing in radians
* @ignore
*/
Number.prototype.toRad = function () {
return this * Math.PI / 180;
};
/**
* Extend the Number object to convert radians to degrees
*
* @return {Number} Bearing in degrees
* @ignore
*/
Number.prototype.toDeg = function () {
return this * 180 / Math.PI;
};
/**
* Normalize a heading in degrees to between 0 and +360
*
* @return {Number} Return
* @ignore
*/
Number.prototype.toBrng = function () {
return (this.toDeg() + 360) % 360;
};