0

Is it possible to draw a circle on top of a Google Maps and make only that inner part position/drag the entire map?

I tried this with and other methods, but without succes. Beneath is a quick photoshop example of what i'm trying to achieve.

Example screenshot

Matthias O.
  • 192
  • 1
  • 2
  • 13
  • Do you want the circular hole to stay fixed in the center? Or fixed to the map? What have you tried? – geocodezip Aug 02 '15 at 17:30
  • Indeed, the darker part should be a 'layer'. Visually this is easily to achieve by laying a png on top of it where the 'hole' is transparent, but then the functionality of dragging the map around is gone (you then click and drag the image layer, not the map). I've tried making masks with canvas, svg, and data URI, all without success. Thanks – Matthias O. Aug 02 '15 at 17:42

1 Answers1

2

One option for putting a "hole" at the center of the map, based off of an answer to this question on SO: Google Map API v3 shade everything EXCEPT for polygon

Probably can make it somewhat less jittery by binding the center of the hole to the map center (rather than doing it in a center_changed event listener)

var citymap = {};
citymap['newyork'] = {
  center: new google.maps.LatLng(40.714352, -74.005973),
  population: 8143197
};
var cityCircle;
var bounds = new google.maps.LatLngBounds();
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)
];

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 = 64;

  // 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;
}

var map;
function initialize() {
  // Create the map.
  var mapOptions = {
    zoom: 4,
    center: new google.maps.LatLng(37.09024, -95.712891),
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  map = new google.maps.Map(document.getElementById('map-canvas'),
    mapOptions);
  var populationOptions = {
    strokeColor: '#000000',
    strokeOpacity: 0.8,
    strokeWeight: 0,
    fillColor: '#000000',
    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);
  google.maps.event.addListener(map, 'center_changed', redrawPoly);

}

function redrawPoly() {
  // update the circle.
  cityCircle.setPaths([outerbounds, drawCircle(map.getCenter(), 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>
Community
  • 1
  • 1
geocodezip
  • 158,664
  • 13
  • 220
  • 245
  • Why does the circle have angles around it? It looks more like a polygon, it is not smooth as it should be – EugenSunic Aug 02 '15 at 18:06
  • 1
    It isn't a circle, its a polygon with a configurable number of sides. If you want more sides, change the number (but beware, more sides is more processing). – geocodezip Aug 02 '15 at 18:16
  • Works like a charm! Thanks! Just a few parameters i can't get my head around. I would like the map to be more zoomed in, the zoom in mapOptions is no longer working. Any idea how i can set the zoom of the map layer? "Probably can make it somewhat less jittery by binding the center of the hole to the map center" can you explain a bit further? I don't have much maps-knowledge. Thanks again! – Matthias O. Aug 03 '15 at 11:05
  • To set the map center and zoom using the mapOptions, remove the call to map.fitBounds in the code. See my answer to: [How to set zoom level in google map](http://stackoverflow.com/questions/11454229/how-to-set-zoom-level-in-google-map) – geocodezip Aug 03 '15 at 11:21