我从数据库加载标记,然后在标记之间绘制折线。我使用折线来计算总距离,而不必计算从marker-a到marker-b到marker-c的距离,等等。
我的距离不准确,因为如果两条标记围绕弯曲的道路,折线只是连接它们而不是沿着道路绘制。
我知道这可以在Google Maps API中使用,但使用限制不适合我,这就是我决定使用传单的原因。
我的标记距离不远,因为我的GPS设备每隔10秒发送一次位置。
我找到了leaflet-routing-machine插件,我想知道我是否可以使用此插件让我的折线卡在路上?
这就是我在地图中添加标记的方法:
function getlocationsfromdb(){
group.clearLayers();
latlngArray.length=0;
var deviceid = $("#selectid").val();
$.ajax({
type: "POST",
url: "functionhandlers/getlocations.php",
data: {deviceid:deviceid,start:start,end:end},
dataType: 'json',
cache: false,
})
.success(function(response) {
$('input').removeClass('error').next('.errormessage').html('');
if(!response.errors && response.result) {
$.each(response.result, function( index, value) {
var latlng = L.latLng(value[7], value[8]);
var marker = L.circleMarker(latlng,{radius:2}).addTo(group);
latlngArray.push(latlng);
});
var polyline = L.polyline(latlngArray, {color: '#605ca8'}).addTo(group);
map.fitBounds(group.getBounds());
var distancetravelled=polyline.measuredDistance();
$("#distancetravelled").html(distancetravelled);
} else {
$.each(response.errors, function( index, value) {
// add error classes
$('input[name*='+index+']').addClass('error').after('<div class="errormessage">'+value+'</div>')
});
}
});
}
有人可以指出我正确的方向吗?
答案 0 :(得分:7)
使用传单路由机可以很容易地做到这一点。初始化路由控件时,您可以将waypoints
设置为latlngArray
:
var control = L.Routing.control({
waypoints: latlngArray,
show: false,
waypointMode: 'snap',
createMarker: function() {}
}).addTo(map);
此处,show: false
阻止控件在地图上显示,而空createMarker
函数会覆盖路由计算机创建的默认标记,而不执行任何操作(尽管我们删除时标记将被删除控件,这样可以防止它们在找到路线时在屏幕上闪烁。)
您可以通过侦听routeselected
事件来提取路由计算机结果的所有顶点,该事件将返回包含路径的所有方向和几何的IRoute
object。将.route.coordinates
置于新的L.polyline
对象中将保持路由,因此我们可以摆脱路由控制:
control.on('routeselected', function(e) {
L.polyline(e.route.coordinates).addTo(group);
map.removeControl(control);
});
在填充.success
之后立即将上述代码块放在latlngArray
回调函数中,应该会为您提供所需的路径。这是一个在工作中表现出来的小提琴:
http://fiddle.jshell.net/nathansnider/ygktexbj/
此外,如果您没有使用路由控件来完成任何其他操作并且希望防止它完全显示(在计算路径时仍可能出现一个小的白色控件框),您只需将其隐藏在CSS中:
.leaflet-routing-container {
display:none;
}
答案 1 :(得分:1)
我意识到这个解决方案有点迂回,因为它创建了一个控件,然后一半代码只是阻止控件显示在地图上
您实际上不必将其添加到地图中。此外,您可以直接攻击内部路由器的route
功能。
var routingControl = L.Routing.control({
waypointMode: 'snap'
});
然后
routingControl._router.route(latLngCoordinates, function(err, waypoints) {
var a = waypoints;
});
小心,它是原始的复制/粘贴: - 航点适合内部格式(检查) - latLngCoordinates必须采用{lat:,lng:}格式 - 它可能需要一些清理,因为生成的url封装了一些非常长的“提示”数据。