2016-11-23 3 views
0

Я пытаюсь создать изогнутую линию с символом стрелки в середине пути в Google Maps JavascriptДобавление значка в середине созданного пути SVG в Google Maps

Я пытаюсь создать изогнутый путь между двумя координатами на картах Google, аналогичный полилинам, отображаемым на kiwi.com (при наведении карты на доступные рейсы). К сожалению, Polylines еще не поддерживает эту функцию, которая заставляет две полилинии перекрываться друг с другом, когда две точки находятся рядом друг с другом. Я даже пытался создать две полилинии, используя геодезическую опцию, в то время как другая не работает, но линия, похоже, все еще перекрывается на двух ближайших точках. Я нашел решение от geocodezip по этой ссылке curve svg path, который использует путь svg для рисования криволинейной линии вместо использования полилиний, но не смог добавить стрелку посреди созданного пути. Есть ли способ достичь линии со стрелкой посередине, подобной kiwi.com, используя этот подход? Вот мой текущий код, основанный на SVG пути geocodezip в:

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>

+0

Что такое "стрелка" Вы хотите поместить в середине строки? – geocodezip

ответ

0

С маркерами «SVG», вы не можете использовать ловкий symbols on a polyline, вам нужно вычислить положение и направление движения стрелки, затем добавьте их на карту.

// point for FORWARD center arrow 
var c2 = new Point(
    c.x + p1.x - curvature * o.x * 0.5, 
    c.y + p1.y - curvature * o.y * 0.5 
); 
var aPt = projection.fromPointToLatLng(c2); 
var aMkr = new google.maps.Marker({ 
    position: aPt, 
    map: map, 
    icon: { 
    path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW, 
    rotation: lineHeading, 
    scale: 2 
    } 
}); 
// point for BACKWARD center arrow 
var d2 = new Point(
    d.x + p1.x - invercurve * p.x * 0.5, 
    d.y + p1.y - invercurve * p.y * 0.5 
); 
var bPt = projection.fromPointToLatLng(d2); 
var bMkr = new google.maps.Marker({ 
    position: bPt, 
    map: map, 
    icon: { 
    path: google.maps.SymbolPath.BACKWARD_CLOSED_ARROW, 
    rotation: lineHeading, 
    scale: 2 
    } 
}); 

arrows on 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 
 
    }); 
 
    google.maps.event.addListener(map, 'click', function(evt) { 
 
    document.getElementById('status').innerHTML = evt.latLng.toUrlValue(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 
 
     mPt = projection.fromPointToLatLng(m); 
 
    console.log(mPt.toUrlValue(6)); 
 

 
    var mMkr = new google.maps.Marker({ 
 
     position: mPt, 
 
     map: map, 
 
     icon: { 
 
     path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW, 
 
     scale: 2 
 
     } 
 
    }); 
 
    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 c2 = new Point(
 
     c.x + p1.x - curvature * o.x * 0.5, 
 
     c.y + p1.y - curvature * o.y * 0.5 
 
    ); 
 

 
    var aPt = projection.fromPointToLatLng(c2); 
 
    console.log(aPt.toUrlValue(6)); 
 

 
    var aMkr = new google.maps.Marker({ 
 
     position: aPt, 
 
     map: map, 
 
     icon: { 
 
     path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW, 
 
     rotation: lineHeading, 
 
     scale: 2 
 
     } 
 
    }); 
 

 
    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); 
 
    var d2 = new Point(
 
     d.x + p1.x - invercurve * p.x * 0.5, 
 
     d.y + p1.y - invercurve * p.y * 0.5 
 
    ); 
 
    var bPt = projection.fromPointToLatLng(d2); 
 
    console.log(aPt.toUrlValue(6)); 
 
    var bMkr = new google.maps.Marker({ 
 
     position: bPt, 
 
     map: map, 
 
     icon: { 
 
     path: google.maps.SymbolPath.BACKWARD_CLOSED_ARROW, 
 
     rotation: lineHeading, 
 
     scale: 2 
 
     } 
 
    }); 
 
    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="status"></div> 
 
<div id="map-canvas"></div>

Смежные вопросы