目的:
计算给定点到最近道路的距离。 我需要确定一个点是否落在道路上。要做到这一点,我想看到从点到最近的道路的距离。因此,距离为0意味着该点实际上是在道路上。
其他信息:
我不受Google地图的限制。如果Bing地图或其他地图服务提供此功能,那么该服务也是一个考虑因素。
问题:
您是否知道使用Google Maps API v3计算距离给定点最近道路的距离?如果不是,您是否知道我可以实现目标的其他方法或服务?
答案 0 :(得分:8)
问题解决了。以下是演示:http://jsfiddle.net/63sWv/
var marker = null;
var roadMarker = null;
var geocoder = new google.maps.Geocoder();
var map;
var directionsService = new google.maps.DirectionsService();
$(document).ready(function(){
var latlng = new google.maps.LatLng(54.97430382488778, -1.611546277999878);
var mapOptions = {
zoom: 22,
center: latlng
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
google.maps.event.addListener(map, 'click', function(event) {
placeMarkers(event);
});
});
function placeMarkers(e) {
var markerImage = "https://chart.googleapis.com/chart?chst=d_map_pin_icon&chld=home|FFFF00";
var roadMarkerImage ="https://chart.googleapis.com/chart?chst=d_map_xpin_letter&chld=pin||FF0000|000000";
if(marker !== null){
marker.setMap(null);
}
marker = new google.maps.Marker({
position: e.latLng,
map: map,
icon: markerImage
});
var request = {
origin:e.latLng,
destination:e.latLng,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
if(roadMarker !== null){
roadMarker.setMap(null);
}
roadMarker = new google.maps.Marker({
position: response.routes[0].legs[0].start_location,
map: map,
icon: roadMarkerImage
});
var distance = getDistance(request.origin,
response.routes[0].legs[0].steps[0].end_point);
$(".output .distance").html(distance);
}
});
}
var rad = function(x) {
return x * Math.PI / 180;
};
var getDistance = function(p1, p2) {
//trim up to 5 decimal places because it is at that point where the difference
p1.lat = parseFloat(p1.lat().toFixed(5));
p1.lng = parseFloat(p1.lng().toFixed(5));
p2.lat = parseFloat(p2.lat().toFixed(5));
p2.lng = parseFloat(p2.lng().toFixed(5));
var R = 6378137; // Earth’s mean radius in meter
var dLat = rad(p2.lat - p1.lat);
var dLong = rad(p2.lng - p1.lng);
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(rad(p1.lat)) * Math.cos(rad(p2.lat)) * Math.sin(dLong / 2) * Math.sin(dLong / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d; // returns the distance in meter
};
答案 1 :(得分:2)
另一种可能性是使用Google的Road Snap API:https://developers.google.com/maps/documentation/roads/snap
这很简单,真的。您提供了您的位置点,并返回最近的道路点,例如像这样: https://roads.googleapis.com/v1/snapToRoads?key=your_api_key&path=60.170880,24.942795
然后它返回:
{
"snappedPoints": [
{
"location": {
"latitude": 60.170877918672588,
"longitude": 24.942699821922421
},
"originalIndex": 0,
"placeId": "ChIJNX9BrM0LkkYRIM-cQg265e8"
}
]
}
答案 2 :(得分:0)
我需要确定一个点是否落在道路上。
我不相信有合法的方法可以用这些API做你想做的事。但是,您可以使用Google的Street View Image API或使用Google Maps API's StreetView objects进行更精细的控制来做一些黑客的,未经推荐的技巧。
以下是这样的想法:如果街景视图API返回有效结果(即全景街景图像),那么可能在街道。如果没有,那你就不在街上了。
使用stand-alone Street View Image API识别“真实”回复可能存在挑战。一种选择是将失败响应的图像文件大小like this one(内容长度为4868)与为测试点返回的图像文件大小(例如a valid one like this)进行比较。内容长度为38701 ..任何“真实”响应都会导致图像内容长度值显着增加,因为图像中有实际数据。坦率地说,只要您请求相同大小的图像(即宽度和高度),失败的内容长度应始终相同。然而,API可能会稍微改变并打破这种期望。所以这很危险。
实际Google Maps JavaScript API's Street View objects提供的更高粒度的控件将为您提供更清晰的处理,因为google.maps.StreetViewStatus
将返回三个值中的一个并解决此问题:OK
,{{1如果您使用了之前描述的静态图像API,则删除必要的脆弱猜测工作。
但这种方法很脏。首先,我认为街景不仅仅是靠近街头的图像。我正在考虑公园里的小道,用户上传的全景图等。其次,街景API似乎使用了邋“的”捕捉“容差(like, 50 meters)。换句话说,如果你的观点足够接近,它会给你怀疑的好处,无论如何都会返回附近的街景全景。换句话说,要注意误报。
如果您正在考虑采用这种方法,这是一个有效的端点示例:
http://maps.googleapis.com/maps/api/streetview?size=600x300&location=34.055526,-81.008087
这是一个失败的..
http://maps.googleapis.com/maps/api/streetview?size=600x300&location=34.05637,-81.00583
作为后记,如果您的应用程序的要求是由铸铁业务需求定义的,我不建议实际使用此方法。但如果它只是为了娱乐和游戏,也许它足够接近?
如果你想认真对待这个问题,你真的需要进入PostGRESql及其PostGIS扩展,你需要一套超级详细的街道中心线。 Open Street Map data可以帮助你入门,但要注意这些数据的质量是可变的..在某些地方可能比其他地方更糟糕。
答案 3 :(得分:0)
如果它是一条直线,你可以选择该线的中点并获得该点的欧几里德距离:http://en.m.wikipedia.org/wiki/Euclidean_distance。