I'm trying to create a curved path with arrow symbol in the middle of the path in Google Maps Javascript
I'm trying to create a curved path in between two coordinates in Google maps, similar to the polylines displayed in kiwi.com (when hovering a card in the available flights). Unfortunately Polylines do not support this feature yet which makes 2 polylines overlap each other when the two points are near each other. I even tried to create two polylines one using geodesic option while the other don't but the line seems to still overlap on two near points. I found a solution from geocodezip in this link curve svg path which uses svg path to draw the curved line instead of using polylines but failed to add an arrow in the middle of the created path. Is there a way to achieve a line with an arrow in the middle similar to kiwi.com using this approach? Here's my current code based on geocodezip's svg path:
var map;
var curvature = 0.175;
var invercurve = -0.175;
$(window).load(function() {
init();
});
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(35.6730185, 139.4302008);
var pos2 = new LatLng(34.678395, 135.4601306);
var bounds = new LatLngBounds();
bounds.extend(pos1);
bounds.extend(pos2);
map = new Map(document.getElementById('map-canvas'), {
center: bounds.getCenter(),
zoom: 6
});
map.fitBounds(bounds);
var markerP1 = new Marker({
position: pos1,
map: map
});
var markerP2 = new Marker({
position: pos2,
map: map
});
var curveMarker, curveMarkerInv;
function updateCurveMarker() {
var pos1 = markerP1.getPosition(), // latlng
pos2 = markerP2.getPosition(),
projection = map.getProjection(),
p1 = projection.fromLatLngToPoint(pos1), // xy
p2 = projection.fromLatLngToPoint(pos2);
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 f = new Point(p2.x - p1.x, p2.y - p1.y), // endpoint (p2 relative to p1)
n = new Point(f.x / 2, f.y / 2), // midpoint
p = new Point(f.y, -f.x), // orthogonal
d = new Point( // curve control point
n.x + invercurve * p.x,
n.y + invercurve * p.y);
console.log('F:' + p1.x * curvature / 2 + ' ' + p1.y * curvature / 2);
var pathDef = 'M 0,0 ' +
'q ' + c.x + ',' + c.y + ' ' + e.x + ',' + e.y;
var pathDefInv = 'M 0,0 ' +
'q ' + d.x + ',' + d.y + ' ' + f.x + ',' + f.y;
var zoom = map.getZoom(),
scale = 1 / (Math.pow(2, -zoom));
var marker = new google.maps.Marker({
position: new google.maps.LatLng,
icon: {
path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
scale: 10
},
//draggable: true,
map: map
});
var symbol = {
path: pathDef,
scale: scale,
strokeWeight: 2,
strokeColor: '#f00',
fillColor: 'none'
};
var symbolInv = {
path: pathDefInv,
scale: scale,
strokeWeight: 2,
strokeColor: '#f00',
fillColor: 'none'
};
if (!curveMarker) {
curveMarker = new Marker({
position: pos1,
clickable: false,
icon: symbol,
zIndex: 0, // behind the other markers
map: map
});
curveMarkerInv = new Marker({
position: pos1,
clickable: false,
icon: symbolInv,
zIndex: 0, // behind the other markers
map: map
});
} else {
curveMarker.setOptions({
position: pos1,
icon: symbol,
});
curveMarkerInv.setOptions({
position: pos1,
icon: symbolInv,
});
}
}
google.maps.event.addListener(map, 'projection_changed', updateCurveMarker);
google.maps.event.addListener(map, 'zoom_changed', updateCurveMarker);
google.maps.event.addListener(markerP1, 'position_changed', updateCurveMarker);
google.maps.event.addListener(markerP2, 'position_changed', updateCurveMarker);
var lineLength = google.maps.geometry.spherical.computeDistanceBetween(markerP1.getPosition(), markerP2.getPosition());
var lineHeading = google.maps.geometry.spherical.computeHeading(markerP1.getPosition(), markerP2.getPosition());
}
#map-canvas {
height: 100%;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://maps.google.com/maps/api/js?libraries=geometry&sensor=false"></script>
<div id="map-canvas"></div>