var map;
var curvature = 0.5; // how curvy to make the arc
function init() {
var Map = google.maps.Map,
LatLng = google.maps.LatLng,
LatLngBounds = google.maps.LatLngBounds,
Marker = google.maps.Marker,
Point = google.maps.Point;
// This is the initial location of the points
// (you can drag the markers around after the map loads)
var pos1 = new LatLng(23.634501, -102.552783);
var pos2 = new LatLng(17.987557, -92.929147);
var bounds = new LatLngBounds();
bounds.extend(pos1);
bounds.extend(pos2);
map = new Map(document.getElementById('map-canvas'), {
center: bounds.getCenter(),
zoom: 12
});
map.fitBounds(bounds);
var markerP1 = new Marker({
position: pos1,
label: "1",
draggable: true,
map: map
});
var markerP2 = new Marker({
position: pos2,
label: "2",
draggable: true,
map: map
});
var curveMarker;
var endArrowMarker;
function updateCurveMarker() {
var pos1 = markerP1.getPosition(), // latlng
pos2 = markerP2.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: 'none'
};
if (!curveMarker) {
curveMarker = new Marker({
position: pos1,
clickable: false,
icon: symbol,
zIndex: 0, // behind the other markers
map: map
});
} else {
curveMarker.setOptions({
position: pos1,
icon: symbol,
});
}
var heading = google.maps.geometry.spherical.computeHeading(pos1, pos2);
var directionIcon = {
path: google.maps.SymbolPath.FORWARD_OPEN_ARROW,
scale: 5,
rotation: heading
};
if (!endArrowMarker) {
endArrowMarker = new Marker({
position: pos2,
clickable: false,
icon: directionIcon,
map: map
});
} else {
endArrowMarker.setIcon(directionIcon);
}
}
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);
}
google.maps.event.addDomListener(window, 'load', init);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>
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id = "map-canvas" style = "border: 2px solid #3872ac;"></div>Прочитав кое-где, я попробовал использовать решение от geocodezip здесь
Я хотел добавить направление конца стрелки между двумя точками, и в итоге я добавил дополнительный код, подобный этому
var heading = google.maps.geometry.spherical.computeHeading(pos1, pos2);
var directionIcon = {
path: google.maps.SymbolPath.FORWARD_OPEN_ARROW,
scale: 5,
rotation: heading
};
if (!endArrowMarker) {
endArrowMarker = new Marker({
position: pos2,
clickable: false,
icon: directionIcon,
map: map
});
} else {
endArrowMarker.setIcon(directionIcon);
}
Как правильно настроить направление стрелки заголовка из-за изогнутой линии? Заранее спасибо.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете использовать изогнутую полилинию, используя оригинальный код Belzier Curve из ответа Никоаби на этот вопрос в StackOverflow: Разрешить пользователям рисовать изогнутые линии на карте Google?.
Добавьте иконку в конце:
icons: [{
icon: {
path: google.maps.SymbolPath.FORWARD_OPEN_ARROW,
scale: 5,
},
offset: '100%'
}],
он будет автоматически настроен, чтобы указывать правильное направление (пример в документации)
доказательство концепции скрипки
фрагмент кода:
var map;
var curvature = 0.5; // how curvy to make the arc
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(23.634501, -102.552783);
var pos2 = new LatLng(17.987557, -92.929147);
var bounds = new LatLngBounds();
bounds.extend(pos1);
bounds.extend(pos2);
map = new Map(document.getElementById('map-canvas'), {
center: bounds.getCenter(),
zoom: 12
});
map.fitBounds(bounds);
var markerP1 = new Marker({
position: pos1,
label: "1",
draggable: false,
map: map
});
var markerP2 = new Marker({
position: pos2,
label: "2",
draggable: false,
map: map
});
drawCurve(pos2, pos1, map);
drawCurve(new google.maps.LatLng(19.4326077, -99.133208), new google.maps.LatLng(19.173773, -96.1342240), map);
}
google.maps.event.addDomListener(window, 'load', init);
function drawCurve(P1, P2, map) {
var lineLength = google.maps.geometry.spherical.computeDistanceBetween(P1, P2);
var lineHeading = google.maps.geometry.spherical.computeHeading(P1, P2);
var lineHeading1, lineHeading2;
if (lineHeading < 0) {
lineHeading1 = lineHeading + 45;
lineHeading2 = lineHeading + 135;
} else {
lineHeading1 = lineHeading + -45;
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);
}
// original Belzier Curve code from nicoabie's answer to this question on StackOverflow:
// http://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,
icons: [{
icon: {
path: google.maps.SymbolPath.FORWARD_OPEN_ARROW,
scale: 5,
},
offset: '100%'
}],
});
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-canvas {
height: 98%;
width: 98%;
margin: 0px;
padding: 0px;
}<script src = "https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id = "map-canvas" style = "border: 2px solid #3872ac;"></div>