Reputation:
I'm drawing an area on Google Maps using the Geometry API. I want to know if it is possible to draw a repeating element onto an area that is dynamic in size?
For example, if I draw my area to look like this:
Then I want to be able to hit 'Next Step' and see something like this, with the rectangles drawn in the area, but only if they will fit. i.e., they have to be 'full' rectangles, not part rectangles:
The only problem is, I'm not entirely sure how to go about this. I would use HTML5 <canvas>
but unfortunately, this needs to be as browser-friendly as possible, but if it has to be <canvas>
then so be it!
Upvotes: 5
Views: 7553
Reputation: 6158
@Joshua M
Sorry for keeping you wait.
Ok, the new code is below.
You can specify the small box size at var boxSize = new google.maps.Size(10, 20);
<!DOCTYPE html>
<html>
<head>
<script src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry"></script>
<script type='text/javascript'>
var mapCanvas, boxes = new google.maps.MVCArray();
function initialize() {
var mapDiv = document.getElementById("map_canvas");
mapCanvas = new google.maps.Map(mapDiv, {
center : new google.maps.LatLng(37.422191,-122.084585),
mapTypeId : google.maps.MapTypeId.SATELLITE,
zoom : 19,
tilt : 0
});
//Encoded path
var encodedPath = "eblcFnuchVv@D@q@P?a@eD]AC~@b@DCz@a@A";
var points = google.maps.geometry.encoding.decodePath(encodedPath);
//Draw a polygon
var polygonOpts = {
paths : points,
strokeWeight : 6,
strokeColor : "#FF0000",
strokeOpacity : 1,
//fillColor : "blue",
fillOpacity : 0,
map : mapCanvas,
editable : true
};
var poly = new google.maps.Polygon(polygonOpts);
var proc = function() {
onPolygonComplete(poly);
};
google.maps.event.addListener(mapCanvas, "projection_changed", proc);
google.maps.event.addListener(poly.getPath(), 'insert_at', proc);
google.maps.event.addListener(poly.getPath(), 'remove_at', proc);
google.maps.event.addListener(poly.getPath(), 'set_at', proc);
}
function onDrawMgr_complete(polygon) {
var path = polygon.getPath();
console.log(google.maps.geometry.encoding.encodePath(path));
}
function onPolygonComplete(polygon) {
var bounds, paths, sw, ne, ystep, xstep, boxH, boxW, posArry, flag, pos, x, y, i, box;
//Delete old boxes.
boxes.forEach(function(box, i) {
box.setMap(null);
delete box;
});
//Calculate the bounds that contains entire polygon.
bounds = new google.maps.LatLngBounds();
paths = polygon.getPath();
paths.forEach(function(latlng, i) {
bounds.extend(latlng);
});
var projection = mapCanvas.getProjection();
var zoom = mapCanvas.getZoom();
var powBase = Math.pow(2, zoom);
//Calculate the small box size.
sw = bounds.getSouthWest();
ne = bounds.getNorthEast();
var swPoint = projection.fromLatLngToPoint(sw);
var nePoint = projection.fromLatLngToPoint(ne);
var boxSize = new google.maps.Size(10, 20); //in pixels.
boxSize.width /= powBase;
boxSize.height /= powBase;
var maxX = Math.floor(Math.abs((swPoint.x - nePoint.x)) / boxSize.width);
var maxY = Math.floor(Math.abs((swPoint.y - nePoint.y)) / boxSize.height);
for ( y = 0; y < maxY; y++) {
for (x = 0; x < maxX; x++) {
//Detect that polygon is able to contain a small box.
bounds = new google.maps.LatLngBounds();
posArry = [];
posArry.push(new google.maps.Point(swPoint.x + boxSize.width * x, swPoint.y - boxSize.height * y));
posArry.push(new google.maps.Point(swPoint.x + boxSize.width * x, swPoint.y - boxSize.height * (y + 1)));
posArry.push(new google.maps.Point(swPoint.x + boxSize.width * (x + 1), swPoint.y - boxSize.height * y));
posArry.push(new google.maps.Point(swPoint.x + boxSize.width * (x + 1), swPoint.y - boxSize.height * (y + 1)));
var flag = true;
for (var i = 0; i < posArry.length; i++) {
pos = projection.fromPointToLatLng(posArry[i]);
if (flag) {
flag = google.maps.geometry.poly.containsLocation(pos, polygon);
bounds.extend(pos);
}
}
if (flag) {
box = new google.maps.Rectangle({
bounds : bounds,
map : mapCanvas,
strokeColor : 'green',
strokeOpacity : 1,
strokeWeight : 1,
fillColor : 'yellow',
fillOpacity : 0.5,
clickable : false
});
boxes.push(box);
}
}
}
}
google.maps.event.addDomListener(window, "load", initialize);
</script>
<style type="text/css">
window,html,#map_canvas{
width : 700px;
height : 500px;
}
</style>
</head>
<body>
<div id="map_canvas"/>
</body>
</html>
Upvotes: 7
Reputation: 6158
Although I didn't use canvas, how about this code?
function onPolygonComplete(polygon) {
var bounds, paths, sw, ne, ystep, xstep,
boxH, boxW, posArry, flag, pos,
x, y, i, box, maxBoxCnt;
//Delete old boxes.
boxes.forEach(function(box, i) {
box.setMap(null);
delete box;
});
//Calculate the bounds that contains entire polygon.
bounds = new google.maps.LatLngBounds();
paths = polygon.getPath();
paths.forEach(function(latlng, i){
bounds.extend(latlng);
});
//Calculate the small box size.
maxBoxCnt = 8;
sw = bounds.getSouthWest();
ne = bounds.getNorthEast();
ystep = Math.abs(sw.lat() - ne.lat()) / maxBoxCnt;
boxH = Math.abs(sw.lat() - ne.lat()) / (maxBoxCnt + 1);
xstep = Math.abs(sw.lng() - ne.lng()) / maxBoxCnt;
boxW = Math.abs(sw.lng() - ne.lng()) / (maxBoxCnt + 1);
for (y = 0; y < maxBoxCnt; y++) {
for (x = 0; x < maxBoxCnt; x++) {
//Detect that polygon is able to contain a small box.
bounds = new google.maps.LatLngBounds();
posArry = [];
posArry.push(new google.maps.LatLng(sw.lat() + ystep * y, sw.lng() + xstep * x));
posArry.push(new google.maps.LatLng(sw.lat() + ystep * y, sw.lng() + xstep * x + boxW));
posArry.push(new google.maps.LatLng(sw.lat() + ystep * y + boxH, sw.lng() + xstep * x));
posArry.push(new google.maps.LatLng(sw.lat() + ystep * y + boxH, sw.lng() + xstep * x + boxW));
flag = true;
for (i = 0; i < posArry.length; i++) {
pos = posArry[i];
if (flag) {
flag = google.maps.geometry.poly.containsLocation(pos, polygon);
bounds.extend(pos);
}
}
//Draw a small box.
if (flag) {
box = new google.maps.Rectangle({
bounds : bounds,
map : mapCanvas,
strokeColor: '#00ffff',
strokeOpacity: 0.5,
strokeWeight: 1,
fillColor: '#00ffff',
fillOpacity : 0.5,
clickable: false
});
boxes.push(box);
}
}
}
}
This code works like this image.
I wrote a page that explains the code. http://googlemaps.googlermania.com/google_maps_api_v3/en/poly_containsLocation.html
Upvotes: 14