I am trying to make a figure here. But the browser is giving the following error. I am trying to use the google maps api with conjunction to geometry library. But not able to run it.
Error:curve.html:79 Uncaught TypeError: Cannot read property 'computeOffset' of undefined
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 50%;
}
</style>
</head>
<body>
<div id="map"></div>
<div>
</br>
<input type="number" name="" id="Radius" placeholder="FrontFace" style="margin:30px" onchange="initMap()">
</br>
<input type="number" name="" id="Backface" placeholder="BackFace" style="margin:30px" onchange="initMap()">
</div>
<script>
var map;
function initMap() {
debugger;
var radius=parseInt(document.getElementById("Radius").value);
var radius2=parseInt(document.getElementById("Backface").value);
var cen= {lat: -34.397, lng: 150.644}
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 8
});
google.maps.event.addListener(map,"click",function(event){
var lat=event.latLng.lat();
var lng=event.latLng.lng();
cen={lat:lat,lng:lng};
});
map.addListener('click', function(e) {
debugger;
placeMarkerAndPanTo(e.latLng, map);
// drawCircle(map,cen,radius);
drawBlastClearance(map,cen,radius,radius2)
});
}
function convertLat(r,angle,cen)
{
debugger;
sin=Math.sin(Math.PI*(angle/180))
dy=((r*sin)/ (110540) );
return cen.lat+dy;
}
function convertLng(r,angle,cen)
{
debugger;
cos=Math.cos(Math.PI*(angle/180))
dx=((r*cos)/ (11320*Math.cos(Math.PI*(angle/180))) );
return cen.lng+dx;
}
function drawBlastClearance(map,cen,r1,r2){
debugger;
LatLng=google.maps.LatLng
spherical=google.maps.spherical;
//CODE TO GENERATE BLAST CLEARANCE ZONE POINTS
Apos=spherical.computeOffset(cen, 158, -45);
Bpos= spherical.computeOffset(cen, 156, 45);
CPos=spherical.computeOffset(cen, 80, 237);
DPos=spherical.computeOffset(cen, 80, 113);
///LINE 1
var pos1 = new LatLng(Apos.lat, Apos.lng);
var pos2 = new LatLng(Bpos.lat, Bpos.lng);
var pos3 = new LatLng(CPos.lat, CPos.lng);
var pos4 = new LatLng(DPos.lat, DPos.lng);
var marker = new google.maps.Marker({
position: Apos,
map: map,
label:'A',
title: 'Hello World!'
});
var marker1 = new google.maps.Marker({
position: Bpos,
map: map,
label:'B',
dragable:true,
});
var marker2 = new google.maps.Marker({
position: CPos,
label:'C',
map: map,
});
var marker3 = new google.maps.Marker({
position: DPos,
map: map,
label:'D',
});
var line = new google.maps.Polyline({
path: [
DPos,Bpos
],
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2,
map: map
});
var line1 = new google.maps.Polyline({
path: [
CPos,Apos
],
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2,
map: map
});
function updateCurveMarker() {
Point=google.maps.Point;
curvature=-.45;
var curveMarker;
var pos1 = marker.getPosition(), // latlng
pos2 = marker1.getPosition(),
projection = map.getProjection(),
p1 = projection.fromLatLngToPoint(pos1), // xy
p2 = projection.fromLatLngToPoint(pos2);
// Calculate the arc.
// To simplify the math, these points
// are all relative to p1:
var e = new Point(p2.x - p1.x, p2.y - p1.y), // endpoint (p2 relative to p1)
m = new Point(e.x / 2, e.y / 2), // midpoint
o = new Point(e.y, -e.x), // orthogonal
c = new Point( // curve control point
m.x + curvature * o.x,
m.y + curvature * o.y);
var pathDef = 'M 0,0 ' +
'q ' + c.x + ',' + c.y + ' ' + e.x + ',' + e.y;
var zoom = map.getZoom(),
scale = 1 / (Math.pow(2, -zoom));
var symbol = {
path: pathDef,
scale: scale,
strokeWeight: 2,
fillColor: '#FF0000'
};
if (!curveMarker) {
curveMarker = new google.maps.Marker({
position: pos1,
clickable: false,
icon: symbol,
zIndex: 0, // behind the other markers
map: map
});
} else {
curveMarker.setOptions({
position: pos1,
icon: symbol,
});
}
}
google.maps.event.addListener(map, 'projection_changed', updateCurveMarker);
google.maps.event.addListener(map, 'zoom_changed', updateCurveMarker);
google.maps.event.addListener(marker1, 'position_changed', updateCurveMarker);
google.maps.event.addListener(marker2, 'position_changed', updateCurveMarker);
function updateCurveMarker1() {
Point=google.maps.Point;
curvature=.45;
var curveMarker;
var pos1 = marker2.getPosition(), // latlng
pos2 = marker3.getPosition(),
projection = map.getProjection(),
p1 = projection.fromLatLngToPoint(pos1), // xy
p2 = projection.fromLatLngToPoint(pos2);
// Calculate the arc.
// To simplify the math, these points
// are all relative to p1:
var e = new Point(p2.x - p1.x, p2.y - p1.y), // endpoint (p2 relative to p1)
m = new Point(e.x / 2, e.y / 2), // midpoint
o = new Point(e.y, -e.x), // orthogonal
c = new Point( // curve control point
m.x + curvature * o.x,
m.y + curvature * o.y);
var pathDef = 'M 0,0 ' +
'q ' + c.x + ',' + c.y + ' ' + e.x + ',' + e.y;
var zoom = map.getZoom(),
scale = 1 / (Math.pow(2, -zoom));
var symbol = {
path: pathDef,
scale: scale,
strokeWeight: 2,
fillColor: '#FF0000'
};
if (!curveMarker) {
curveMarker = new google.maps.Marker({
position: pos1,
clickable: false,
icon: symbol,
zIndex: 0, // behind the other markers
map: map
});
} else {
curveMarker.setOptions({
position: pos1,
icon: symbol,
});
}
}
google.maps.event.addListener(map, 'projection_changed', updateCurveMarker1);
google.maps.event.addListener(map, 'zoom_changed', updateCurveMarker1);
google.maps.event.addListener(marker1, 'position_changed', updateCurveMarker1);
google.maps.event.addListener(marker2, 'position_changed', updateCurveMarker1);
}
var markersArray=[];
var circleArray=[];
function placeMarkerAndPanTo(latLng, map) {
while(markersArray.length) { markersArray.pop().setMap(null); }
var marker = new google.maps.Marker({
position: latLng,
map: map
});
markersArray.push(marker) ;
}
function drawCircle(map,cen,radii)
{
while(circleArray.length){circleArray.pop().setMap(null);}
var cityCircle = new google.maps.Circle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
center:cen,
radius: radii
});
circleArray.push(cityCircle);
}
</script>
<!-- <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCVhit3Aj--xP28zBUyThLQ7bAHOt72B1c&cal async defer></script> -->
<!-- lback=initMap libraries=geometry"&sensor=false
-->
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCVhit3Aj--xP28zBUyThLQ7bAHOt72B1c&libraries=geometry,places">
</script>
</body>
</html>
You have a typo in your code. This is incorrect:
spherical=google.maps.spherical;
It should be
spherical=google.maps.geometry.spherical;
fiddle
Related
I have two sets of points coordinates that I need to connect on google map, like this, just much larger:
var start = ['42.81405, 12.4886861111', '32.7994444444, 20.506775', '44.8062644989, 20.5005495758'];
var end = ['47.81405, 18.4886861111', '33.7994444444, 21.506775', '39.8062644989, 16.5005495758'];
The first coordinate from "start" needs to be connected to the first coord from "end", and so on, until the end. Got that, but now I need to make "start" and "end" points more recognizable, put some kind of dots in a different color on them. What I have:
var geocoder;
var map;
function initialize() {
var center = new google.maps.LatLng(51.97559, 4.12565);
map = new google.maps.Map(document.getElementById('map'), {
center: center,
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var bounds = new google.maps.LatLngBounds();
var start = ['42.81405, 12.4886861111', '32.7994444444, 20.506775', '44.8062644989, 20.5005495758'];
var end = ['47.81405, 18.4886861111', '33.7994444444, 21.506775', '39.8062644989, 16.5005495758'];
var paths = [];
for (var i=0; i < end.length; i++){
var startCoords = start[i].split(",");
var startPt = new google.maps.LatLng(startCoords[0],startCoords[1]);
var endCoords = end[i].split(",");
var endPt = new google.maps.LatLng(endCoords[0],endCoords[1]);
paths.push([startPt, endPt]);
bounds.extend(startPt);
bounds.extend(endPt);
}
map.fitBounds(bounds);
var polyline = new google.maps.Polygon({
paths: paths,
strokeColor: 'red',
strokeWeight: 2,
strokeOpacity: 1
});
polyline.setMap(map);
}
google.maps.event.addDomListener(window, "load", initialize);
Any kind of help is welcomed.
The simplest thing you can just create markers for start and end points. Like the following code
for (var i=0; i < end.length; i++){
var startCoords = start[i].split(",");
var startPt = new google.maps.LatLng(startCoords[0],startCoords[1]);
var endCoords = end[i].split(",");
var endPt = new google.maps.LatLng(endCoords[0],endCoords[1]);
paths.push([startPt, endPt]);
bounds.extend(startPt);
bounds.extend(endPt);
//Create start and end markers
var markerStart = new google.maps.Marker({
position: startPt,
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 3,
fillColor: 'blue',
strokeColor: 'blue'
},
draggable: true,
map: map
});
var markerEnd = new google.maps.Marker({
position: endPt,
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 3,
fillColor: 'green',
strokeColor: 'green'
},
draggable: true,
map: map
});
}
It will give you something like
Code snippet
var map;
function initMap() {
var center = new google.maps.LatLng(51.97559, 4.12565);
map = new google.maps.Map(document.getElementById('map'), {
center: center,
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var bounds = new google.maps.LatLngBounds();
var start = ['42.81405, 12.4886861111', '32.7994444444, 20.506775', '44.8062644989, 20.5005495758'];
var end = ['47.81405, 18.4886861111', '33.7994444444, 21.506775', '39.8062644989, 16.5005495758'];
var paths = [];
for (var i=0; i < end.length; i++){
var startCoords = start[i].split(",");
var startPt = new google.maps.LatLng(startCoords[0],startCoords[1]);
var endCoords = end[i].split(",");
var endPt = new google.maps.LatLng(endCoords[0],endCoords[1]);
paths.push([startPt, endPt]);
bounds.extend(startPt);
bounds.extend(endPt);
//Create start and end markers
var markerStart = new google.maps.Marker({
position: startPt,
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 3,
fillColor: 'blue',
strokeColor: 'blue'
},
draggable: true,
map: map
});
var markerEnd = new google.maps.Marker({
position: endPt,
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 3,
fillColor: 'green',
strokeColor: 'green'
},
draggable: true,
map: map
});
}
map.fitBounds(bounds);
var polyline = new google.maps.Polygon({
paths: paths,
strokeColor: 'red',
strokeWeight: 2,
strokeOpacity: 1
});
polyline.setMap(map);
}
#map {
height: 100%;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDztlrk_3CnzGHo7CFvLFqE_2bUKEq1JEU&callback=initMap"
async defer></script>
Can anyone please help me in connecting specified points with an arc or parabola or any curve line in my google map? It is currently connected with a straight line. I have tried using the other stack overflow question where this was asked but those codes only connects two points, I might have multiple markers in the future so i need something that can be resused over and over... Please see the codes below...
<!DOCTYPE html>
<html>
<head>
<script src="http://maps.googleapis.com/maps/api/js"></script>
<script>
var x=new google.maps.LatLng(14.560774500000008,121.02631410000006);
var rcbc=new google.maps.LatLng(14.560648, 121.016781);
var powerplant=new google.maps.LatLng(14.565066, 121.036184);
var trafalgar=new google.maps.LatLng(14.560774500000008,121.02631410000006);
var mapua=new google.maps.LatLng(14.562883, 121.022039);
function initialize()
{
var mapProp = {
center:x,
zoom:15,
mapTypeId:google.maps.MapTypeId.ROADMAP
};
var map=new google.maps.Map(document.getElementById("googleMap"),mapProp);
var myTrip=[trafalgar,rcbc];
var myTrip2=[rcbc,powerplant];
var flightPath2=new google.maps.Polyline({
path:myTrip2,
strokeColor:"##35495e",
strokeOpacity:0.8,
strokeWeight:3
});
var flightPath=new google.maps.Polyline({
path:myTrip,
strokeColor:"##35495e",
strokeOpacity:0.8,
strokeWeight:3
});
var marker=new google.maps.Marker({
position:x,
});
var marker2=new google.maps.Marker({
position:london,
});
var marker3=new google.maps.Marker({
position:rcbc,
});
var marker4=new google.maps.Marker({
position:powerplant,
});
marker4.setMap(map);
marker3.setMap(map);
marker2.setMap(map);
marker.setMap(map);
flightPath.setMap(map);
flightPath2.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="googleMap" style="width:1000px;height:680px;"></div>
</body>
</html>
One option would be to use the code from this related question: How to display curved polyline on one side of a straight line? (a Bezier curve).
proof of concept fiddle
code snippet:
function drawCurve(P1, P2, map) {
var lineLength = google.maps.geometry.spherical.computeDistanceBetween(P1, P2);
var lineHeading = google.maps.geometry.spherical.computeHeading(P1, P2);
if (lineHeading < 0) {
var lineHeading1 = lineHeading + 45;
var lineHeading2 = lineHeading + 135;
} else {
var lineHeading1 = lineHeading + -45;
var lineHeading2 = lineHeading + -135;
}
var pA = google.maps.geometry.spherical.computeOffset(P1, lineLength / 2.2, lineHeading1);
var pB = google.maps.geometry.spherical.computeOffset(P2, lineLength / 2.2, lineHeading2);
var curvedLine = new GmapsCubicBezier(P1, pA, pB, P2, 0.01, map);
}
var x = new google.maps.LatLng(14.560774500000008, 121.02631410000006);
var london = new google.maps.LatLng(51.5073509, -0.12775829999998223);
var rcbc = new google.maps.LatLng(14.560648, 121.016781);
var powerplant = new google.maps.LatLng(14.565066, 121.036184);
var trafalgar = new google.maps.LatLng(14.560774500000008, 121.02631410000006);
var mapua = new google.maps.LatLng(14.562883, 121.022039);
function initialize() {
var mapProp = {
center: x,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
var myTrip = [trafalgar, rcbc];
var myTrip2 = [rcbc, powerplant];
drawCurve(trafalgar, rcbc, map);
drawCurve(rcbc, powerplant, map);
var marker = new google.maps.Marker({
position: x,
});
var marker2 = new google.maps.Marker({
position: london,
});
var marker3 = new google.maps.Marker({
position: rcbc,
});
var marker4 = new google.maps.Marker({
position: powerplant,
});
marker4.setMap(map);
marker3.setMap(map);
marker2.setMap(map);
marker.setMap(map);
flightPath.setMap(map);
flightPath2.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
// original Belzier Curve code from nicoabie's answer to this question on StackOverflow:
// https://stackoverflow.com/questions/5347984/letting-users-draw-curved-lines-on-a-google-map
var GmapsCubicBezier = function(latlong1, latlong2, latlong3, latlong4, resolution, map) {
var lat1 = latlong1.lat();
var long1 = latlong1.lng();
var lat2 = latlong2.lat();
var long2 = latlong2.lng();
var lat3 = latlong3.lat();
var long3 = latlong3.lng();
var lat4 = latlong4.lat();
var long4 = latlong4.lng();
var points = [];
for (it = 0; it <= 1; it += resolution) {
points.push(this.getBezier({
x: lat1,
y: long1
}, {
x: lat2,
y: long2
}, {
x: lat3,
y: long3
}, {
x: lat4,
y: long4
}, it));
}
var path = [];
for (var i = 0; i < points.length - 1; i++) {
path.push(new google.maps.LatLng(points[i].x, points[i].y));
path.push(new google.maps.LatLng(points[i + 1].x, points[i + 1].y, false));
}
var Line = new google.maps.Polyline({
path: path,
geodesic: true,
strokeColor: "##35495e",
strokeOpacity: 0.8,
strokeWeight: 3
/* dashed line:
icons: [{
icon: {
path: 'M 0,-1 0,1',
strokeOpacity: 1,
scale: 4
},
offset: '0',
repeat: '20px'
}], */
});
Line.setMap(map);
return Line;
};
GmapsCubicBezier.prototype = {
B1: function(t) {
return t * t * t;
},
B2: function(t) {
return 3 * t * t * (1 - t);
},
B3: function(t) {
return 3 * t * (1 - t) * (1 - t);
},
B4: function(t) {
return (1 - t) * (1 - t) * (1 - t);
},
getBezier: function(C1, C2, C3, C4, percent) {
var pos = {};
pos.x = C1.x * this.B1(percent) + C2.x * this.B2(percent) + C3.x * this.B3(percent) + C4.x * this.B4(percent);
pos.y = C1.y * this.B1(percent) + C2.y * this.B2(percent) + C3.y * this.B3(percent) + C4.y * this.B4(percent);
return pos;
}
};
html,
body,
#googleMap {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<div id="googleMap"></div>
When you load the Google Maps JS, specify the geometry library:
<script src="http://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
This means you can then add the geodesic attribute when you create the polylines, e.g.
var flightPath2=new google.maps.Polyline({
path:myTrip2,
geodesic: true,
strokeColor:"##35495e",
strokeOpacity:0.8,
strokeWeight:3
});
"When true, edges of the polygon are interpreted as geodesic and will
follow the curvature of the Earth. When false, edges of the polygon
are rendered as straight lines in screen space."
See Google's examples and documentation:
https://developers.google.com/maps/documentation/javascript/geometry#Navigation
https://developers.google.com/maps/documentation/javascript/examples/geometry-headings
https://developers.google.com/maps/documentation/javascript/3.exp/reference#PolylineOptions
I've been playing with Google Map API for a few days now and it's pretty straight forward for the most part, but one thing that we need to do, I can't figure out. I've played with the labels as you can see in the example below, but I'm unable to give them to look that I have in the image below. Can someone point me to a reference so I can achieve my requirements?
If your looking for the makerwithlable.js, you can get it from here.. Its where I got it:
https://code.google.com/p/google-maps-utility-library-v3/source/browse/trunk/markerwithlabel/src/markerwithlabel.js?r=288
<!DOCTYPE html>
<html>
<head>
<script src="http://maps.googleapis.com/maps/api/js"></script>
<script src="markerwithlabel.js" type="text/javascript"></script>
<script>
{
var showOnStartInfoWindows = true;
//create locations..
var arrayAll = [];
var marker = [];
var jax = new google.maps.LatLng(30.318028, -81.674474);
var leesburg = new google.maps.LatLng(28.810750, -81.880056);
var map = null;
arrayAll[0] = {loc: jax, size: 5000, info: "Jacksonville, FL 32204"};
arrayAll[1] = {loc: leesburg, size: 1000, info: "Leesburg, FL"};
//EO create locations..
}
function initialize()
{
//center the map on Jacksonville
var mapProp = {
center:arrayAll[0].loc,
zoom:6,
mapTypeId:google.maps.MapTypeId.ROADMAP
};
//set google's API and pass the DIV by ID.
map = new google.maps.Map(document.getElementById("googleMap"),mapProp);
var bounds = new google.maps.LatLngBounds(leesburg, jax);
map.fitBounds(bounds);
var maxSize = 0;
for(var i = 0; i < arrayAll.length; i++)
{
if(maxSize<arrayAll[i].size)
maxSize = arrayAll[i].size;
}
for(var i = 0; i < arrayAll.length; i++)
{
var size = Math.round((arrayAll[i].size/maxSize)*100);
//create marker
marker[i] = new google.maps.Marker({
position:arrayAll[i].loc,
map: map,
title: 'Right-Click to zoom all the way in.\nLeft-Click to zoom to a state level.',
draggable: false,
raiseOnDrag: false,
labelAnchor: new google.maps.Point(22, 0),
labelClass: "googleLabel", // the CSS class for the label
labelContent: arrayAll[i].info,
icon: {
path: google.maps.SymbolPath.CIRCLE, //BACKWARD_CLOSED_ARROW
fillOpacity: 0.3,
fillColor: '#0000ff',
strokeOpacity: 1.0,
strokeColor: '#0000ff',
strokeWeight: 1.0,
scale: size, //pixels
}
});
marker[i].setMap(map);
//EO create marker
marker_onclick(marker[i]);
marker_info(marker[i]);
}
}
function marker_onclick(marker) {
google.maps.event.addListener(marker, 'dblclick', function(o) {
map.setZoom(18);
map.setCenter(marker.position);
});
google.maps.event.addListener(marker, 'click', function(o) {
map.setZoom(7);
map.setCenter(marker.position);
});
google.maps.event.addListener(marker, 'rightclick', function(o) {
alert('Could route to different URL:\n' + marker.position);
});
}
function marker_info(marker) {
//create popup notice..
var infowindow = new google.maps.InfoWindow({
content:marker.labelContent
});
if(showOnStartInfoWindows)
infowindow.open(map, marker);
google.maps.event.addListener(marker, 'mouseover', function (o) {
//alert('over');
infowindow.open(map, marker);
});
google.maps.event.addListener(marker, 'mouseout', function (o) {
//alert('out');
infowindow.close(map, marker);
});
//EO create popup notice..
}
{
google.maps.event.addDomListener(window, 'load', initialize);
}
</script>
</head>
<body>
<div id="googleMap" style="width:640px;height:640px;"></div>
</body>
</html>
Example of what I'm trying to do.
Based on the value of size you may set the style(fontSize,width,height etc.) and the labelAnchor
{
var showOnStartInfoWindows = true;
//create locations..
var arrayAll = [];
var marker = [];
var jax = new google.maps.LatLng(30.318028, -81.674474);
var leesburg = new google.maps.LatLng(28.810750, -81.880056);
var map = null;
arrayAll[0] = {
loc: jax,
size: 5000,
info: "Jacksonville, FL 32204"
};
arrayAll[1] = {
loc: leesburg,
size: 1000,
info: "Leesburg, FL"
};
//EO create locations..
}
function initialize() {
//center the map on Jacksonville
var mapProp = {
center: arrayAll[0].loc,
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//set google's API and pass the DIV by ID.
map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
var bounds = new google.maps.LatLngBounds(leesburg, jax);
map.fitBounds(bounds);
var maxSize = 0;
for (var i = 0; i < arrayAll.length; i++) {
if (maxSize < arrayAll[i].size)
maxSize = arrayAll[i].size;
}
for (var i = 0; i < arrayAll.length; i++) {
var size = Math.round((arrayAll[i].size / maxSize) * 100);
//create MarkerWithLabel
marker[i] = new MarkerWithLabel({
labelInBackground:false,
position: arrayAll[i].loc,
map: map,
title: 'Right-Click to zoom all the way in.\nLeft-Click to zoom to a state level.',
labelAnchor: new google.maps.Point((size * 1.8) / 2, (size / 3)),
labelClass: "googleLabel", // the CSS class for the label
labelStyle: {
width: (size * 1.8) + 'px',
height: (size / 1.5) + 'px',
lineHeight: (size / 1.5) + 'px',
fontSize: (size / 1.5) + 'px'
},
labelContent: arrayAll[i].size,
icon: {
path: google.maps.SymbolPath.CIRCLE,
fillOpacity: 0.6,
fillColor: 'gold',
strokeOpacity: 1.0,
strokeColor: '#0000ff',
strokeWeight: 1.0,
scale: size, //pixels
}
});
marker[i].setMap(map);
}
}
{
google.maps.event.addDomListener(window, 'load', initialize);
}
html,
body,
#googleMap {
margin: 0;
padding: 0;
height: 100%;
}
.googleLabel {
color: #000;
font-weight: bold;
text-align: center;
}
<script src="http://maps.googleapis.com/maps/api/js"></script>
<script src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerwithlabel/src/markerwithlabel.js" type="text/javascript"></script>
<div id="googleMap"></div>
I'm trying to draw a bezier curve in google maps by using a SVG path in a Polyline. At first I used a Marker instead similar to Curved line between two near points in google maps, which gave the results that I'm after. However, since it's not possible to drag the map under the marker, I can't use this method.
So I switched to a Polyline instead of a marker. Now I get the same good results when I zoom out, but when I zoom in the curve becomes "cropped".
Here is the code:
function initialize() {
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var coord1 = new google.maps.LatLng(49.165876, -123.152446);
var coord2 = new google.maps.LatLng(25.786328, -80.193694);
var bounds = new google.maps.LatLngBounds();
bounds.extend(coord1);
bounds.extend(coord2);
map.fitBounds(bounds);
pLineOpt = {
path: [coord1, coord2],
strokeWeight: 4,
strokeOpacity: 0,
map: map,
}
pLine = new google.maps.Polyline(pLineOpt);
var markers = [
new google.maps.Marker({
position: coord1,
map: map
}),
new google.maps.Marker({
position: coord2,
map: map
})
];
google.maps.event.addListener(map, 'zoom_changed', function () {
//points
var p1 = map.getProjection().fromLatLngToPoint(coord1);
var p2 = map.getProjection().fromLatLngToPoint(coord2);
//distance between points
var d = new google.maps.Point(p2.x - p1.x, p2.y - p1.y);
var lengthSqr = d.x * d.x + d.y * d.y;
//middle point
var m = new google.maps.Point(d.x / 2, d.y / 2);
//slope of perpendicular line
var perpK = -d.x / d.y;
//distance to control point
var ratioDistanceControlLengthSqr = 9;
var controlDSqr = lengthSqr / ratioDistanceControlLengthSqr;
var p3dX = Math.sqrt(controlDSqr / (Math.pow(perpK, 2) + 1));
var p3dY = perpK * p3dX;
//control point
var p3 = new google.maps.Point(m.x - p3dX, m.y - p3dY);
//curve path
var path = "M 0 0 q " + p3.x + " " + p3.y + " " + d.x + " " + d.y;
//calc scale
var zoom = map.getZoom();
var scale = 1 / (Math.pow(2, -zoom));
var icon = {
path: path,
scale: scale,
strokeWeight: 3,
strokeOpacity: 1,
};
pLineOpt.icons = [{
fixedRotation: true,
icon: icon,
offset: '0'
}];
pLine.setOptions(pLineOpt);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
I have made a jsfiddle with the code: http://jsfiddle.net/s7djLzyd/3/
Does anyone know why the Polyline is cropped when zooming, and if there is a way around this?
Thanks
You need to fix your Polyline Options :
pLineOpt = {
path: [coord1, coord2],
geodesic: true,
strokeColor: '#000',
strokeOpacity: 1.0,
strokeWeight: 4
}
Please try this code snippet : May be this is what you want... :)
function initialize() {
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var coord1 = new google.maps.LatLng(49.165876, -123.152446);
var coord2 = new google.maps.LatLng(25.786328, -80.193694);
var bounds = new google.maps.LatLngBounds();
bounds.extend(coord1);
bounds.extend(coord2);
map.fitBounds(bounds);
pLineOpt = {
path: [coord1, coord2],
geodesic: true,
strokeColor: '#000',
strokeOpacity: 1.0,
strokeWeight: 4
}
pLine = new google.maps.Polyline(pLineOpt);
var markers = [
new google.maps.Marker({
position: coord1,
map: map
}),
new google.maps.Marker({
position: coord2,
map: map
})];
pLine.setMap(map);
google.maps.event.addListener(map, 'zoom_changed', function () {
});
}
google.maps.event.addDomListener(window, 'load', initialize);
html, body, #map-canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry,places&ext=.js"></script>
<div id="map-canvas"></div>
From this related question: Google Maps API: Bézier curve polyline wrap
var curvedLine = new GmapsCubicBezier(
49.165876, -123.152446,
33.811192,-115.032444,
30.820807,-123.749998,
25.786328, -80.193694,
0.01, map);
example fiddle
code snippet:
var map;
var origLoc = new google.maps.LatLng(45, -85);
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(33.811192, -115.032444),
zoom: 3
};
map = new google.maps.Map(document.getElementById("map"), mapOptions);
var coord1 = new google.maps.LatLng(49.165876, -123.152446);
var coord2 = new google.maps.LatLng(25.786328, -80.193694);
var marker1 = new google.maps.Marker({
position: coord1,
title: "marker 1",
map: map
});
var marker2 = new google.maps.Marker({
position: coord2,
title: "marker 2",
map: map
});
var curvedLine = new GmapsCubicBezier(
49.165876, -123.152446,
33.811192, -115.032444,
30.820807, -123.749998,
25.786328, -80.193694,
0.01, map);
}
google.maps.event.addDomListener(window, 'load', initialize);
var GmapsCubicBezier = function(lat1, long1, lat2, long2, lat3, long3, lat4, long4, resolution, map) {
var points = [];
for (it = 0; it <= 1; it += resolution) {
points.push(this.getBezier({
x: lat1,
y: long1
}, {
x: lat2,
y: long2
}, {
x: lat3,
y: long3
}, {
x: lat4,
y: long4
}, it));
}
for (var i = 0; i < points.length - 1; i++) {
var Line = new google.maps.Polyline({
path: [new google.maps.LatLng(points[i].x, points[i].y), new google.maps.LatLng(points[i + 1].x, points[i + 1].y, false)],
geodesic: true,
strokeOpacity: 1,
strokeColor: 'black',
/* icons: [{
icon: {
path: 'M 0,-2 0,2',
strokeColor: 'violet',
strokeOpacity: 1,
strokeWeight: 4
},
repeat: '36px'
}, {
icon: {
path: 'M -1,-2 -1,2',
strokeColor: 'black',
strokeOpacity: 1,
strokeWeight: 2
},
repeat: '36px'
}] */
});
Line.setMap(map);
}
// connect end of line to first point
var Line = new google.maps.Polyline({
path: [new google.maps.LatLng(lat1,long1),new google.maps.LatLng(points[points.length-1].x, points[points.length-1].y)],
geodesic: true,
strokeOpacity: 1,
strokeColor: 'black',
/* icons: [{
icon: {
path: 'M 0,-2 0,2',
strokeColor: 'violet',
strokeOpacity: 1,
strokeWeight: 4
},
repeat: '36px'
}, {
icon: {
path: 'M -1,-2 -1,2',
strokeColor: 'black',
strokeOpacity: 1,
strokeWeight: 2
},
repeat: '36px'
}] */
});
Line.setMap(map);
return Line;
};
GmapsCubicBezier.prototype = {
B1: function(t) {
return t * t * t;
},
B2: function(t) {
return 3 * t * t * (1 - t);
},
B3: function(t) {
return 3 * t * (1 - t) * (1 - t);
},
B4: function(t) {
return (1 - t) * (1 - t) * (1 - t);
},
getBezier: function(C1, C2, C3, C4, percent) {
var pos = {};
pos.x = C1.x * this.B1(percent) + C2.x * this.B2(percent) + C3.x * this.B3(percent) + C4.x * this.B4(percent);
pos.y = C1.y * this.B1(percent) + C2.y * this.B2(percent) + C3.y * this.B3(percent) + C4.y * this.B4(percent);
return pos;
}
};
html,
body,
#map {
height: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=geometry"></script>
<div id="map" style="float:left;width:100%;height:100%;"></div>
This question already has an answer here:
How do I fade out a circle in a Google Map, x seconds after I've added it to the map?
(1 answer)
Closed 8 years ago.
I am attempting to fade circles out with a setInterval on fillOpacity. However a console log shows the opacity changing but the appearance of the circle does not seem to change. Is there a different set function required to do this?
http://jsfiddle.net/faaxeskg/5/
setInterval(function() {
marker.fillOpacity -= .01;
console.log(marker.fillOpacity);
}, 200);
code snippet:
var map = null;
function initialize() {
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(-25.363882, 131.044922)
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
// Add 500 markers to the map at random locations
var southWest = new google.maps.LatLng(-31.203405, 125.244141);
var northEast = new google.maps.LatLng(-25.363882, 131.044922);
var bounds = new google.maps.LatLngBounds(southWest, northEast);
map.fitBounds(bounds);
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
setInterval(function() {
var position = new google.maps.LatLng(
southWest.lat() + latSpan * Math.random(),
southWest.lng() + lngSpan * Math.random());
var populationOptions = {
strokeOpacity: 0,
fillColor: '#FF0000',
fillOpacity: 0.65,
map: map,
center: position,
radius: 40000
};
var marker = new google.maps.Circle(populationOptions);
setInterval(function() {
marker.fillOpacity -= .01;
console.log(marker.fillOpacity);
}, 200);
setTimeout(function() {
marker.setMap(null);
delete marker;
}, 30000);
}, 2000);
}
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?v=3&libraries=geometry"></script>
<div id="map-canvas" style="float:left;width:100%;height:100%;"></div>
You need to associate the "opacity change" to the marker, you can do that with function closure (a createCircleMarker function).
Don't use undocumented properties. Use the documented methods.
marker.set("fillOpacity, marker.get("fillOpacity")-0.01);
working code snippet:
var map = null;
function initialize() {
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(-25.363882, 131.044922)
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
// Add 500 markers to the map at random locations
var southWest = new google.maps.LatLng(-31.203405, 125.244141);
var northEast = new google.maps.LatLng(-25.363882, 131.044922);
var bounds = new google.maps.LatLngBounds(southWest, northEast);
map.fitBounds(bounds);
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
setInterval(function() {
var position = new google.maps.LatLng(
southWest.lat() + latSpan * Math.random(),
southWest.lng() + lngSpan * Math.random());
var populationOptions = {
strokeOpacity: 0,
fillColor: '#FF0000',
fillOpacity: 0.65,
map: map,
center: position,
radius: 40000
};
createCircleMarker(populationOptions);
}, 2000);
}
function createCircleMarker(populationOptions) {
var marker = new google.maps.Circle(populationOptions);
setInterval(function() {
marker.set("fillOpacity",marker.get("fillOpacity")-0.05);
console.log(marker.fillOpacity);
}, 200);
setTimeout(function() {
marker.setMap(null);
delete marker;
}, 30000);
}
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?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=geometry"></script>
<div id="map-canvas" style="float:left;width:100%;height:100%;"></div>