Reputation: 22978
I am working on a PHP script which takes XML input, parses it and then displays (eventually rotated) rectangle and ellipses areas.
Because area can be rotated, I have to use google.maps.Polygon
and not Rectangle
.
To handle rotation I hope to use the google-maps-polygon-rotate library (that part comes later).
My problem is: from the given XML input I only know the coordinates of the rectangle centerpoint and the dimensions of the area (width and height).
Currently I just display the centerpoint as a marker:
My question is: how to draw a rectangle with google.maps.Polygon
when only the latitude and longitude of the center point and the width, height are known?
I.e. how to calculate the latitude and longitude of the 4 endpoints?
Can I somehow use google.maps.geometry.spherical.computeOffset() method here?
Upvotes: 0
Views: 7819
Reputation: 161334
One option would be to use the v3 ported version of Mike Williams' v2 Eshapes library
// ==- Tilted rectangles ===
var point = new google.maps.LatLng(44, -78);
var tiltedRectangle1 = google.maps.Polygon.Shape(point, 50000, 10000, 50000, 10000, -60, 4, "#000000", 3, 1, "#ffffff", 1, {}, true);
var tiltedRectangle2 = google.maps.Polyline.Shape(point, 50000, 10000, 50000, 10000, 30, 4, "#000000", 3, 1, {}, true);
tiltedRectangle1.setMap(map);
tiltedRectangle2.setMap(map);
The function google.maps.Polygon.Shape(point, 50000, 10000, 50000, 10000, -60, defines a rectangle with sides 100000 meters x 20000 meters rotated -60 degrees, the second call defines one the same size rotated 30 degrees.
working snippet:
var map = null;
function initialize() {
var myOptions = {
zoom: 8,
center: new google.maps.LatLng(44, -78),
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);
// ==- Tilted rectangles ===
var point = new google.maps.LatLng(44, -78);
var tiltedRectangle1 = google.maps.Polygon.Shape(point, 50000, 10000, 50000, 10000, -60, 4, "#000000", 3, 1, "#ffffff", 1, {}, true);
var tiltedRectangle2 = google.maps.Polyline.Shape(point, 50000, 10000, 50000, 10000, 30, 4, "#000000", 3, 1, {}, true);
tiltedRectangle1.setMap(map);
tiltedRectangle2.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
// 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.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
}))
}
google.maps.Polygon.Shape = function (point, r1, r2, r3, r4, rotation, vertexCount, strokeColour, strokeWeight, Strokepacity, fillColour, fillOpacity, opts, tilt) {
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.Polygon({
paths: points,
strokeColor: strokeColour,
strokeWeight: strokeWeight,
strokeOpacity: Strokepacity,
fillColor: fillColour,
fillOpacity: fillOpacity
}))
}
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>
<div id="map"></div>
Upvotes: 3
Reputation: 22978
My own answer (see the screenshot below) - first add the geometry
library:
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?v=3&libraries=geometry">
</script>
And then use it to create the corners of the rectangle:
var NORTH = 0;
var WEST = -90;
var SOUTH = 180;
var EAST = 90;
function drawRect(map, lat, lng, width, height, color) {
var center = new google.maps.LatLng(lat, lng);
var north = google.maps.geometry.spherical.computeOffset(center, height / 2, NORTH);
var south = google.maps.geometry.spherical.computeOffset(center, height / 2, SOUTH);
var northEast = google.maps.geometry.spherical.computeOffset(north, width / 2, EAST);
var northWest = google.maps.geometry.spherical.computeOffset(north, width / 2, WEST);
var southEast = google.maps.geometry.spherical.computeOffset(south, width / 2, EAST);
var southWest = google.maps.geometry.spherical.computeOffset(south, width / 2, WEST);
var corners = [ northEast, northWest, southWest, southEast ];
var rect = new google.maps.Polygon({
paths: corners,
strokeColor: color,
strokeOpacity: 0.9,
strokeWeight: 1,
fillColor: color,
fillOpacity: 0.3,
map: map
});
}
And to rotate the rectangle by an angle
I probably could add it to the 2nd argument of the computeOffset()
calls. Haven't tried that yet.
Upvotes: 3