Add a circle overlay to Google Maps API v3
February 9, 2010 — Florent ClairambaultThere’s a better alternative :
I only leave the code as it is for people interested in extending the google maps javascript framework.
As you might not know, google doesn’t give a circle overlay with its Google Maps API. With the V2 version, someone published it. As it wasn’t available anywhere (at least I could not find it), here is the V3 version of this app.
For my little tests, I added some methods : setCenter, setCircleRadius,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | // This file adds a new circle overlay to Google Maps v3 // Original Google Maps API v2 File : http://dawsdesign.com/drupal/google_maps_circle_overlay // Ported to GMaps v3 by http://florent.clairambault.fr/ /** * Filled circle overlay */ var MapCircleOverlay = function(center, radius, strokeWeight, strokeColor, strokeOpacity, fillColor, fillOpacity) { this.center = center; this.radius = radius; this.strokeWeight = strokeWeight; this.strokeColor = strokeColor; this.strokeOpacity = strokeOpacity; this.fillColor = fillColor; this.fillOpacity = fillOpacity; this.circlePolygon = null; // 50 lines look like a pretty good circle this.numPoints = 50; this.d2r = Math.PI / 180; this.bound = null; this.setCenter = function( latLng ) { this.center = latLng; this.draw(); }; this.setRadius = function( radius ) { this.radius = radius; this.draw(); }; }; /* base class overloads follow this comment */ MapCircleOverlay.prototype = new google.maps.OverlayView; // Calculate all the points and draw them // Base method must be implemented like this MapCircleOverlay.prototype.draw = function() { if ( ! isFinite( this.radius ) || ! isFinite( this.center.lat() ) || ! isFinite( this.center.lng() ) ) { if ( console != undefined ) console.error('Radius has to be a number !'); return; } circleLatLngs = new Array(); // Remove the "* 0.621371192" to use miles instead of kilometers var circleLat = this.radius * 0.621371192 * 0.014483; // Convert statute into miles and miles into degrees latitude var circleLng = circleLat / Math.cos( this.center.lat() * this.d2r); // 2PI = 360 degrees, +1 so that the end points meet for (var i = 0; i < this.numPoints+1; i++) { var theta = Math.PI * (i / (this.numPoints / 2)); var vertexLat = this.center.lat() + (circleLat * Math.sin(theta)); var vertexLng = this.center.lng() + (circleLng * Math.cos(theta)); var vertextLatLng = new google.maps.LatLng(vertexLat, vertexLng); circleLatLngs.push( vertextLatLng ); } // Before drawing the new polygon, we have to remove the old one this.clear(); this.circlePolygon = new google.maps.Polygon({ paths: circleLatLngs, strokeColor: this.strokeColor, strokeOpacity: this.strokeOpacity, strokeWeight: this.strokeWeight, fillColor: this.fillColor, fillOpacity: this.fillOpacity }); this.circlePolygon.setMap( this.map ); }; MapCircleOverlay.prototype.clear = function() { if ( this.circlePolygon != null ) { this.circlePolygon.setMap( null ); this.circlePolygon = null; } }; MapCircleOverlay.prototype.onRemove = function() { this.clear(); }; |
It can be used like any other V3 overlay :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <div id="map_canvas" style="width:100%; height:100%"></div> <script type="text/javascript"> // We load the map var latlng = new google.maps.LatLng(-34.397, 150.644); var myOptions = { zoom: 8, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); // We load the circle var circle = new MapCircleOverlay( latlng.getPosition(), 10, "#FF0000", 0.8, 3, "#FF0000", 0.35 ); // And we attach it to the map circle.setMap( map ); </script> |
I made an other version to get the bounds, because I found it to be very useful to get the right zoom level around the circle :
1 | map.fitBounds( circle.getBounds() ); |
