This question is related to this SO question and answered by @geocodezip.
A problem I have is drawing a line from either north-to-south or south-to-north. The curved line is now bent like number 8 or a S. How do I control the curved line to display on one side of the straight line. Sometimes the curved line is expanded beyond the starting point and contracted at the ending point. Thanks.
Here are my codes. I have two sample polylines north-to-south.
var map;
function init() {
var Map = google.maps.Map,
LatLng = google.maps.LatLng,
LatLngBounds = google.maps.LatLngBounds,
Marker = google.maps.Marker,
Point = google.maps.Point;
var pos1 = new LatLng(29.703642, -95.152274);
var pos2 = new LatLng(29.702452, -95.152296);
var pos3 = new LatLng(29.703514, -95.151405);
var pos4 = new LatLng(29.702359, -95.152078);
var bounds = new LatLngBounds();
bounds.extend(pos1);
bounds.extend(pos2);
var mapOptions = {
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId.SATELLITE,
draggableCursor: 'auto',
panControl: true,
scaleControl: true,
smallMapControl: true,
tilt: 0,
zoom: 19,
zoomControl: true,
rotateControl:true,
zoomControlOptions: { style: google.maps.ZoomControlStyle.SMALL }
};
map = new Map(document.getElementById('map-canvas'), mapOptions);
map.fitBounds(bounds);
var markerP1 = new Marker({
position: pos1,
draggable: true,
map: map
});
var markerP2 = new Marker({
position: pos2,
draggable: true,
map: map
});
var markerP2 = new Marker({
position: pos3,
draggable: true,
map: map
});
var markerP3 = new Marker({
position: pos4,
draggable: true,
map: map
});
var curvedLine = new GmapsCubicBezier(pos1, pos2, 0.01, map);
var curvedLine = new GmapsCubicBezier(pos3, pos4, 0.01, map);
var line = new google.maps.Polyline({
path: [pos1, pos2],
strokeOpacity: 0,
icons: [{
icon: {
path: 'M 0,-1 0,1',
strokeOpacity: 1,
scale: 4
},
offset: '0',
repeat: '20px'
}],
map: map
});
var line = new google.maps.Polyline({
path: [pos3, pos4],
strokeOpacity: 0,
icons: [{
icon: {
path: 'M 0,-1 0,1',
strokeOpacity: 1,
scale: 4
},
offset: '0',
repeat: '20px'
}],
map: map
});
}
google.maps.event.addDomListener(window, 'load', init);
var GmapsCubicBezier = function (latlong1, latlong4, resolution, map) {
var lineLength = google.maps.geometry.spherical.computeDistanceBetween(latlong1, latlong4);
var lineHeading = google.maps.geometry.spherical.computeHeading(latlong1, latlong4);
var positionA = google.maps.geometry.spherical.computeOffset(latlong1, lineLength / 3, lineHeading - 60);
var positionB = google.maps.geometry.spherical.computeOffset(latlong4, lineLength / 3, -lineHeading + 120);
var lat1 = latlong1.lat();
var long1 = latlong1.lng();
var lat2 = positionA.lat();
var long2 = positionA.lng();
var lat3 = positionB.lat();
var long3 = positionB.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,
strokeOpacity: 0.0,
icons: [{
icon: {
path: 'M 0,-1 0,1',
strokeOpacity: 1,
scale: 4
},
offset: '0',
repeat: '20px'
}],
strokeColor: 'grey'
});
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;
}
};