2016-11-23 78 views
0

我試圖在谷歌地圖的路徑中,以創建箭頭符號的曲線路徑的Javascript添加圖標

我試圖創建一個在Google地圖中兩個座標之間的曲線路徑,類似於kiwi.com中顯示的多段線(當在可用航班中懸停卡時)。不幸的是折線不支持這個功能,當兩點彼此靠近時,這使得2條折線相互重疊。我甚至嘗試使用測地選項創建兩條多段線,而另一條不行,但該線似乎仍然在兩個近點處重疊。我在geocodezip這個鏈接中找到了一個解決方案curve svg path,它使用svg路徑繪製曲線而不是使用折線,但未能在創建的路徑中添加箭頭。有沒有一種方法可以在類似於kiwi.com的中間使用這種方法實現箭頭?這是基於geocodezip的SVG路徑我當前的代碼:

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>