draw an svg arc between lat longs - google-maps

The following draws a curve:
var curvedLine = {
path: 'M 50,-150 A 100,100 0 0 100 -3,0',
fillColor: 'transparent',
fillOpacity: 0.5,
scale: 1,
strokeColor: 'gold',
strokeOpacity: 0.6,
strokeWeight: 7
};
var marker = new google.maps.Marker({
position: newLoc,
icon: curvedLine,
map: map
});
In the curvedLine, after A, can I give a location coordinates on the map?
Because when the map is zoomed out, curvedLine size remains same. I want it to scale along with the map zoom.

I have written a function. Please review it.
function drawCurvedLine(startLatLng, endLatLng, offset, right, left, lineColor) {
var midLoc = getMidPoint(startLatLng, endLatLng);// Get the mid point of the start and end LatLngs
var midLoc1 = getMidPoint(startLatLng, midLoc);// Get the mid point of the start LatLng and mid LatLng
var midLoc2 = getMidPoint(midLoc, endLatLng);// Get the mid point of the mid LatLng and end LatLng
var heading = google.maps.geometry.spherical.computeHeading(startLatLng, endLatLng);// Compute the heading of the start and end LatLngs
// Change the heading based on right or left value
var headingOffset;
if (right == 1 && left == 0) {
headingOffset = 90;
}
else if (right == 0 && left == 1) {
headingOffset = -90;
}
var offsetLoc = google.maps.geometry.spherical.computeOffset(midLoc, offset / 1.5, heading + headingOffset);// Get the offset location of the mid point of start and end LatLngs
var offsetLoc1 = google.maps.geometry.spherical.computeOffset(midLoc1, offset / 2, heading + headingOffset);// Get the offset location of the mid point of midLoc and start LatLng
var offsetLoc2 = google.maps.geometry.spherical.computeOffset(midLoc2, offset / 2, heading + headingOffset);// Get the offset location of the mid point of midLoc and start LatLng
// Draw poly line along above computed locations
var curve = new google.maps.Polyline({
path: [startLatLng, offsetLoc1, offsetLoc, offsetLoc2, endLatLng],
geodesic: true,
strokeColor: lineColor,
strokeOpacity: 0.6,
strokeWeight: 7
});
curve.setMap(map);
// Add an arrow to the end of the curved line
var arrow = new google.maps.Marker({
position: newLoc,
map: map,
icon: {
path: google.maps.SymbolPath.FORWARD_OPEN_ARROW,
scale: 4,
strokeColor: lineColor,
strokeOpacity: 1,
strokeWeight: 5.0,
fillColor: 'transparent',
fillOpacity: 0.6,
rotation: google.maps.geometry.spherical.computeHeading(offsetLoc2, endLatLng)
},
});
}

Related

Google Maps - Animated Polyline -- Stop / Remove Animation

I'm plotting a polyline on Google Maps API V3, from a GPX file.
On mouseover of that polyline, I have an animated dot, moving along the polyline, using function animateRoute();
Currently however, I don't have a way to remove the animated dot on mouseout, and as a result, if you mouseover, mouseout, mouseover etc, you end up with multiple animated dots moving along the same line.
Code snippet: (see full working URL below too)
var gmarkers = [];
function loadGPXFileIntoGoogleMap(map, filename,recordNum, name, hex_code) {
$.ajax({
type: "GET",
url: filename,
dataType: "xml",
success: function(xml) {
var points = [];
var bounds = new google.maps.LatLngBounds ();
$(xml).find("trkpt").each(function() {
var lat = $(this).attr("lat");
var lon = $(this).attr("lon");
if((lat != 0) && (lon != 0))
{
var p = new google.maps.LatLng(lat, lon);
points.push(p);
bounds.extend(p);
}
});
var strokeColor = "#ff0000";
var poly = new google.maps.Polyline({
path: points,
strokeColor: strokeColor,
strokeOpacity: 1,
strokeWeight: 4,
recordNum: recordNum,
});
poly.setMap(map);
google.maps.event.addListener(poly, 'mouseover', function() {
var start = {
path: "M-20,0a20,20 0 1,0 40,0a20,20 0 1,0 -40,0",
fillColor: '#00ff00',
fillOpacity: 1,
strokeColor:'#000000',
strokeWeight: 4,
scale: 0.5
}
var end = {
path: "M-20,0a20,20 0 1,0 40,0a20,20 0 1,0 -40,0",
fillColor: '#FF0000',
fillOpacity: 1,
strokeColor:'#000000',
strokeWeight: 4,
scale: 0.5
}
var markerStart = new google.maps.Marker({
position: poly.getPath().getAt(0),
icon: start,
map: map,
zIndex: 200,
scale: 1
});
gmarkers.push(markerStart);
var markerEnd = new google.maps.Marker({
position: poly.getPath().getAt(poly.getPath().getLength() - 1),
icon: end,
map: map,
zIndex: 200,
scale: 1
});
gmarkers.push(markerEnd);
var icons = this.setOptions({
icons: [{
icon: {
path: google.maps.SymbolPath.CIRCLE,
strokeOpacity: 1,
strokeColor: "#000000",
strokeWeight: 2,
scale: 4
},
}]});
animateRoute(poly);
});
function animateRoute(line) {
var count = 0;
window.setInterval(function() {
count = (count + 1) % 200;
var icons = poly.get('icons');
icons[0].offset = (count / 2) + '%';
poly.set('icons', icons);
}, 60);
}
google.maps.event.addListener(poly, 'mouseout', function() {
removeMarkers();
});
// fit bounds to track
map.fitBounds(bounds);
}
});
}
function removeMarkers(){
for(i=0; i<gmarkers.length; i++){
gmarkers[i].setMap(null);
}
}
$(document).ready(function() {
var mapOptions = {
zoom: 17,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById("map"),
mapOptions);
loadGPXFileIntoGoogleMap(map, "cmsAdmin/uploads/blue_and_green_not_comfortable_.gpx","724","Example A","FFFF00");
loadGPXFileIntoGoogleMap(map, "cmsAdmin/uploads/taraweratrailrouterecce.gpx","431","Example B","4F4CBE");
});
Full working example:
https://www.wildthings.club/mapStack.php
Hover over the blue line and you'll see the animated dot.
Mouse off, and then after a few seconds hover again - a second dot will appear, and the first dot is still going.
Repeat and you'll soon have a bunch of jittery dots.
Ideally I'd like to remove all animated dots on mouseout.
Second option would be to not add a subsequent animated dot icon if there is already one on that polyLine (note there are multiple polyLines on the map).
Third option failing that would be to have the animated dot stop and remove once it reaches the end (position markerEnd) so at least it doesn't loop.
I have tried placing the icons into an array and then removing from there (like I have done with the gmarkers array and removeMarkers(), but no luck.
I also had a play with Animate google maps polyline but this just works with straight line point to point, rather than following a series of points from a GPX file.
Any help, most appreciated
Cheers
You should use the window.clearInterval() function to remove the interval you are using to animate the icon on the polyline. You should save the id when call window.setInterval() in animateRoute(). Here is a simple JSBin proof of concept adapted from the code on that website. In my code, I'm just simply using a global id variable, and updating that variable in animateRoute():
<!DOCTYPE html>
<html>
<head>
<title>Polyline path</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
html, body, #map {
height: 100%;
width: 100%;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
var map;
var id;
var gmarkers = [];
var gmarkersicons = [];
function initMap() {
var mapOptions = {
zoom: 3,
mapTypeId: google.maps.MapTypeId.TERRAIN,
center: {lat: 9.291, lng: -157.821}
};
map = new google.maps.Map(document.getElementById("map"),
mapOptions);
var points = [
{lat: 37.772, lng: -122.214},
{lat: 21.291, lng: -157.821},
{lat: -18.142, lng: 178.431},
{lat: -27.467, lng: 153.027}
];
var poly = new google.maps.Polyline({
path: points,
strokeColor: "red",
strokeOpacity: 1,
strokeWeight: 4,
recordNum: "test"
});
poly.setMap(map);
google.maps.event.addListener(poly, 'mouseover', function() {
var start = {
path: "M-20,0a20,20 0 1,0 40,0a20,20 0 1,0 -40,0",
fillColor: '#00ff00',
fillOpacity: 1,
strokeColor:'#000000',
strokeWeight: 4,
scale: 0.5
}
var end = {
path: "M-20,0a20,20 0 1,0 40,0a20,20 0 1,0 -40,0",
fillColor: '#FF0000',
fillOpacity: 1,
strokeColor:'#000000',
strokeWeight: 4,
scale: 0.5
}
var go = {
path: "M-20,0a20,20 0 1,0 40,0a20,20 0 1,0 -40,0",
fillColor: '#000000',
fillOpacity: 1,
strokeColor:'#fff',
strokeWeight: 4,
scale: 0.5
}
var markerStart = new google.maps.Marker({
position: poly.getPath().getAt(0),
icon: start,
map: map,
zIndex: 200,
scale: 1
});
gmarkers.push(markerStart);
var markerEnd = new google.maps.Marker({
position: poly.getPath().getAt(poly.getPath().getLength() - 1),
icon: end,
map: map,
zIndex: 200,
scale: 1
});
gmarkers.push(markerEnd);
var icons = this.setOptions({
icons: [{
icon: {
path: google.maps.SymbolPath.CIRCLE,
strokeOpacity: 1,
strokeColor: "#000000",
strokeWeight: 2,
scale: 4
},
}]});
this.setOptions({
strokeColor: "red",
scale: 1,
strokeWeight:15,
strokeOpacity:.6
});
var contentString = "Testing";
var infowindow = new google.maps.InfoWindow({
content: contentString
});
infowindow.open(map, markerStart);
id = animateRoute(poly);
});
function animateRoute(line) {
var count = 0;
var id = window.setInterval(function() {
count = (count + 1) % 200;
var icons = poly.get('icons');
icons[0].offset = (count / 2) + '%';
poly.set('icons', icons);
}, 60);
return id;
}
google.maps.event.addListener(poly, 'mouseout', function() {
removeMarkers();
this.setOptions({strokeColor:"red",strokeWeight:4,strokeOpacity:1});
this.setOptions( { suppressMarkers: true } );
this.setOptions({
icons: [{}]});
window.clearInterval(id);
});
function removeMarkers(){
for(i=0; i<gmarkers.length; i++){
gmarkers[i].setMap(null);
}
}
}
$(document).ready(function() {
initMap();
});
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>

Adjust google.maps.Circle radius to be more accurate

I have two points represented by (lat, lng) and a circle represented center = point(lat, lng) and radius.
[2] pry(main)> points
=> [#<struct Geography::Point x=8.6836, y=56.7619>, #<struct Geography::Point x=8.7501, y=56.8298>]
[3] pry(main)> circle
=> #<struct Geography::Circle center=#<struct Geography::Point x=8.71685, y=56.79585>, radius=5253.053885917054>
I have a method that calculates the distance using Haversine formula so if I do it from the center of the circle towards both points, I'll get:
[4] pry(main)> Geography::Utils.distance_between(circle.center, points.first)
=> 5253.053885917054
[5] pry(main)> Geography::Utils.distance_between(circle.center, points.second)
=> 5252.8180384905045
Please note that the distance between the first point and the center of the circle is the actual radius of the circle. All the distances are in meters. What I mean by this is that one point is on the arc and the one should be super close.
Expected result:
If I represent that in google maps, the arc of the circle will pass through one point and be super close to second.
Actual result:
Question
How does google maps projection works in my case and how can I have an ouput that satisfies the reality?
Map code:
:coffeescript
window.createPostcodeMarker = (postcode) ->
marker = new google.maps.Marker
draggable: false
raiseOnDrag: false
position: postcode.position
map: map
tooltip: postcode.name
icon:
path: google.maps.SymbolPath.CIRCLE
fillOpacity: 1
strokeOpacity: 1
strokeColor: postcode.stroke_color
strokeWeight: 1
scale: 3
fillColor: postcode.stroke_color
circle = new google.maps.Circle
map: map
radius: postcode.radius
fillColor: postcode.fill_color
strokeColor: postcode.stroke_color
strokeWeight: 1
strokeOpacity: 0.8
circle.bindTo('center', marker, 'position')
marker
window.createAreaMarker = (area) ->
marker = new google.maps.Marker
draggable: false
raiseOnDrag: false
position: area.position
map: map
tooltip: area.name
icon:
path: google.maps.SymbolPath.CIRCLE
fillOpacity: 0.3
strokeOpacity: 0.3
strokeColor: area.stroke_color
strokeWeight: 1
scale: 0
fillColor: area.stroke_color
circle = new google.maps.Circle
map: map
radius: area.radius
fillColor: area.fill_color
strokeColor: area.stroke_color
strokeWeight: 1
strokeOpacity: 0.3
circle.bindTo('center', marker, 'position')
marker
window.googleMapsInitializePostcodesMap = ->
if PageData?.postcodesData?
window.bounds = new google.maps.LatLngBounds()
window.markers = []
mapOptions =
mapTypeId: google.maps.MapTypeId.ROADMAP
maxZoom: 13
window.map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions)
# Create markers & extend bounds
for postcode in PageData.postcodesData
marker = createPostcodeMarker(postcode)
markers.push(marker)
bounds.extend(marker.position)
for area in PageData.areasData
marker = createAreaMarker(area)
markers.push(marker)
window.map.fitBounds(bounds)
= json_data_tag(#postcodes_map_data, 'postcodesData')
= json_data_tag(#areas_map_data, 'areasData')
#map-canvas{style: "width: 100%; height: 600px;"}
- content_for :footer_javascripts do
= google_maps_api_js("googleMapsInitializePostcodesMap")
Codepen: https://codepen.io/radubogdan/pen/gWEvZP
You should use the Spherical Geometry library that can be loaded as part of the Javascript Maps API by appending &libraries=geometry when loading the API - for example:
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">
The advantage of this method is that it abstracts away the implementation details of the default projection in the Maps API. This makes your life easy, and more importantly, will not break if that default projection ever changes.
Pass the lat/lng coordinates down to the browser and compute the distance between them (in meters) as follows:
var location1 = new google.maps.LatLng(lat1, lng1);
var location2 = new google.maps.LatLng(lat2, lng2);
var distance = google.maps.geometry.spherical.computeDistanceBetween(location1, location2);
or in Coffeescript:
location1 = new google.maps.LatLng lat1, lng1;
location2 = new google.maps.LatLng lat2, lng2;
distance = google.maps.geometry.spherical.computeDistanceBetween location1, location2;
The radius for the circle needs to be the distance between the center of the circle and CoordinateA in meters.
Once you convert to meters, the following site shows that 4288 should be the radius of the circle https://www.daftlogic.com/projects-google-maps-distance-calculator.htm?route=56.79585,8.716850000000022|56.7619,8.68360000000007
Basically, your Haversine formula isn't giving you exactly what you need yet.

Intersection of two polygons in google map

I am trying to draw multiple polygons using google shapes API. I need to get the intersection of two polygons.
Here I can draw the background polygon(in black) by giving the array of path of each polygon.
Below is my code, here I am giving MVC Array as paths for polygon.
I just want the intersection area to be in separate color. Please check the screen shot link attached after the code.
var bgAreaCoordinates = [];
var bgbounds = map.getBounds(); // Boundary coordinates of the visible area of map
var NE = bgbounds.getNorthEast();
var SW = bgbounds.getSouthWest();
var bgPathCoordinates = [NE, new google.maps.LatLng(NE.lat(),SW.lng()),
SW, new google.maps.LatLng(SW.lat(),NE.lng())];
// Array of boundary coordinates of the visible part of the map
bgAreaCoordinates.push(bgPathCoordinates);
for (var key in flightPlanCoordinates) {
for (var k in flightPlanCoordinates[key]) {
bgAreaCoordinates.push(flightPlanCoordinates[key][k]);// Getting array of coordinates of each polygon
}
}
if (bgPath['bg']) {
bgPath['bg'].setMap(null); // remove the previous bg
}
console.info(bgAreaCoordinates);
bgPath['bg'] = new google.maps.Polygon({
// paths: [bgPathCoordinates, bgAreaCoordinates],
paths:bgAreaCoordinates,
geodesic: true,
strokeColor: '',
strokeOpacity: 0,
strokeWeight: 0,
fillColor: '#687472',
fillOpacity: 0.7
});
bgPath['bg'].setMap(map); // Draw the bg polygon : Google shapes Api
http://i.stack.imgur.com/VjTZe.png
Thanks in advance!
Here is an example that does what I think you want to do (make a hole in a polygon that covers the earth and cover that hole with a polygon with a different color). The example polygon happens to be a circle.
code snippet
// This example creates circles on the map, representing
// populations in the United States.
// First, create an object containing LatLng and population for each city.
var citymap = {};
citymap['chicago'] = {
center: new google.maps.LatLng(41.878113, -87.629798),
population: 2842518
};
citymap['newyork'] = {
center: new google.maps.LatLng(40.714352, -74.005973),
population: 8143197
};
citymap['losangeles'] = {
center: new google.maps.LatLng(34.052234, -118.243684),
population: 3844829
};
var cityCircle;
var bounds = new google.maps.LatLngBounds();
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 = 32;
// 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;
}
function initialize() {
// Create the map.
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(37.09024, -95.712891),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
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)
];
var populationOptions = {
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
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);
var coverHole = new google.maps.Polygon({
strokeColor: '#FFFF00',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#0000FF',
fillOpacity: 0.35,
map: map,
paths: [drawCircle(citymap['newyork'].center, 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>

How do I fade out a circle in a Google Map, x seconds after I've added it to the map?

What I basically had in mind is what Google did in this example
Every second I want to add circles at certain coordinates and then slowly fade them out. I already managed to add circles to the map:
var citymap = {};
citymap['chicago'] = {
center: new google.maps.LatLng(41.878113, -87.629798),
population: 100
};
citymap['amsterdam'] = {
center: new google.maps.LatLng(52.878113, 5.629798),
population: 40
};
citymap['paris'] = {
center: new google.maps.LatLng(48.9021449, 2.4699208),
population: 100
};
citymap['moscow'] = {
center: new google.maps.LatLng(56.021369, 37.9650909),
population: 100
};
citymap['newyork'] = {
center: new google.maps.LatLng(40.9152414, -73.70027209999999),
population: 80
};
citymap['losangeles'] = {
center: new google.maps.LatLng(34.3373061, -118.1552891),
population: 65
}
for (var city in citymap) {
var populationOptions = {
strokeColor: "#900057",
strokeOpacity: 1,
strokeWeight: 1,
fillColor: "#900057",
fillOpacity: 0.35,
map: map,
clickable: false,
center: citymap[city].center,
radius: citymap[city].population * 2000
};
cityCircle = new google.maps.Circle(populationOptions);
}
But I can't find how to fade them out anywhere. Already tried going through the Google Maps API documentation and even the example's code, but maybe I missed something.
To fade them out you need to decrease the opacity of the fill and the stroke until it is 0.0.
setInterval(fadeCityCircles,1000);
function fadeCityCircles() {
for (var city in citymap) {
var fillOpacity = citymap[city].cityCircle.get("fillOpacity");
fillOpacity -= 0.02;
if (fillOpacity < 0) fillOpacity =0.0;
var strokeOpacity = citymap[city].cityCircle.get("strokeOpacity");
strokeOpacity -= 0.05;
if (strokeOpacity < 0) strokeOpacity =0.0;
citymap[city].cityCircle.setOptions({fillOpacity:fillOpacity, strokeOpacity:strokeOpacity});
}
}
example

Google Maps Rotate Polygon

After drawing a Polygon shape on the map. I would like to change what direction the polygon is pointing when the map is refreshed by rotating around one of the points of the polygon. For example point the polygon in the direction of 90 degrees rotating around my first polygon point (code shown below). Can anyone provide any code examples of this working?
I have seen some similar posts however examples given appear over complicated.
poly = new google.maps.Polygon({
strokeWeight: 3,
fillColor: '#5555FF'
});
poly.setMap(map);
poly.setPaths(new google.maps.MVCArray([path]));
var triangleCoords = [
new google.maps.LatLng(51.5087, -0.1277),
new google.maps.LatLng(51.5387, -0.1077),
new google.maps.LatLng(51.5387, -0.1477),
new google.maps.LatLng(51.5087, -0.1277)
];
// Construct the polygon
triangle = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.8
});
triangle.setMap(map);
google.maps.event.addListener(map, 'click', triangle);
}
The following example demonstrates how to rotate a polygon
Note: the rotation is performed around the first point
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 5,
center: {lat: 24.886, lng: -70.268},
mapTypeId: google.maps.MapTypeId.TERRAIN
});
// Define the LatLng coordinates for the polygon's path.
var triangleCoords = [
{lat: 25.774, lng: -80.190},
{lat: 18.466, lng: -66.118},
{lat: 32.321, lng: -64.757},
{lat: 25.774, lng: -80.190}
];
// Construct the polygon.
var bermudaTriangle = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
});
bermudaTriangle.setMap(map);
//rotate a polygon
document.getElementById('btnRotate').onclick = function() {
rotatePolygon(bermudaTriangle, 90);
};
}
function rotatePolygon(polygon,angle) {
var map = polygon.getMap();
var prj = map.getProjection();
var origin = prj.fromLatLngToPoint(polygon.getPath().getAt(0)); //rotate around first point
var coords = polygon.getPath().getArray().map(function(latLng){
var point = prj.fromLatLngToPoint(latLng);
var rotatedLatLng = prj.fromPointToLatLng(rotatePoint(point,origin,angle));
return {lat: rotatedLatLng.lat(), lng: rotatedLatLng.lng()};
});
polygon.setPath(coords);
}
function rotatePoint(point, origin, angle) {
var angleRad = angle * Math.PI / 180.0;
return {
x: Math.cos(angleRad) * (point.x - origin.x) - Math.sin(angleRad) * (point.y - origin.y) + origin.x,
y: Math.sin(angleRad) * (point.x - origin.x) + Math.cos(angleRad) * (point.y - origin.y) + origin.y
};
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
#floating-panel {
position: absolute;
top: 10px;
left: 25%;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
text-align: center;
font-family: 'Roboto','sans-serif';
line-height: 30px;
padding-left: 10px;
}
<div id="floating-panel">
<input type="button" id="btnRotate" value="Rotate 90"></div>
<div id="map"></div>
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>
JSFiddle
You might want to look at something like Mike Williams' eshapes library. It was written originally for the Google Maps API v2, but this page demonstrates the version that I ported to the Google Maps API v3.
example
proof of concept fiddle
code snippet;
var map = null;
var triangle, angle, point;
function initMap() {
point = new google.maps.LatLng(44, -80);
var myOptions = {
zoom: 8,
center: point,
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);
angle = 0;
// === Triangle ===
triangle = google.maps.Polyline.RegularPoly(point, 30000, 3, angle, "#ff0000", 8, 1);
triangle.setMap(map);
google.maps.event.addListener(triangle, "click", rotateTriangle);
}
google.maps.event.addDomListener(window, 'load', initMap);
function rotateTriangle() {
triangle.setMap(null);
angle += 90;
if (angle >= 360) angle -= 360;
triangle = google.maps.Polyline.RegularPoly(point, 30000, 3, angle, "#ff0000", 8, 1);
triangle.setMap(map);
google.maps.event.addListener(triangle, "click", rotateTriangle);
}
// This Javascript is based on code provided by the
// Community Church Javascript Team
// http://www.bisphamchurch.org.uk/
// http://econym.org.uk/gmap/
// From v3_eshapes.js:
// 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.RegularPoly = function(point, radius, vertexCount, rotation, colour, weight, opacity, opts) {
rotation = rotation || 0;
var tilt = !(vertexCount & 1);
return google.maps.Polyline.Shape(point, radius, radius, radius, radius, rotation, vertexCount, colour, weight, opacity, opts, tilt)
}
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
}))
}
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>
<b>Click triangle's border to rotate it.</b>
<div id="map"></div>
I had the same issue, i wanted to rotate a symbol or polygon. The rotation attribute defines the rotation of the object and thats all.
Try it.
The path defines the shape of the polygon and uses SVG notation like (x,y) coordinates.
function init_nuevo_mapa(){
var mapOptions = {
zoom: 13
center: new google.maps.LatLng(-33.5351136,-70.5876618)
};
var new_map = new google.maps.Map(document.getElementById('new-map'), mapOptions);
var myLatLng = new google.maps.LatLng(-33.5351136,-70.5876618)
var image = {
path: 'M 0,0 -10,-30 10,-30 z',
rotation: 10, //10ยบ clockwise
fillColor: "red",
fillOpacity: 0.5,
scale: 1,
strokeColor: "red",
strokeWeight: 4
};
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
zIndex: zIndex,
title: location[2]
});
You can easily do it with the new Google Maps symbol object. Just take a look at https://developers.google.com/maps/documentation/javascript/reference#Symbol.
Warning: This works really bad with IE 9 when you have a lot of markers.
Good luck!