Google maps api v3 рассчитать пробег по штатам
Я ищу способ рассчитать пробег по штату США на основе источника, путевых точек и пункта назначения маршрута, используя Google Maps API v3.
Я пытался использовать Googles Distance Matrix API, но он рассчитывает расстояние между двумя точками, и это хорошо, но мне нужно разбить количество миль, пройденных для каждого штата. Для целей налогообложения (отчеты IFTA для перевозки).
Я много гуглил и просматривал документацию, но я не вижу ничего, что рассчитывало бы пробег в каждом штате.
Я знаю, как использовать карты Google, и я знаю, что это возможно, так как я видел это на одном видео. Я не могу показать код, потому что понятия не имею, как это сделать. Какие-нибудь мысли?
Полезные ссылки, которые я нашел:
Как рисовать маршруты и рассчитывать время и расстояние маршрута на лету, используя Google Map API V3 http://www.c-sharpcorner.com/UploadFile/8911c4/how-to-draw-routes-and-calculate-route-time-and-distance-on/
Как создать дальномер с помощью Google Maps API http://www.1stwebdesigner.com/distance-finder-google-maps-api/
1 ответ
Ниже приведена полнофункциональная реализация, использующая API Google Maps Javascript. Все, что вам нужно добавить, это ваш собственный ключ API Карт. Как отмечалось в сообщениях, упомянутых выше, Google Maps управляет запросами с асимптотической скоростью, и, следовательно, чем длиннее маршрут, тем дольше он будет рассчитываться. Чтобы приблизиться, путь от Нью-Хейвен до границы с Нью-Джерси / Пенсильвания занимает около 5 минут. Поездка из Нью-Хейвен в Лос-Анджелес занимает 45 минут. Еще одно примечание: есть несколько государственных границ, которые проходят через водоемы. Google считает, что они находятся не в каком-либо штате, и поэтому сообщает, что они не определены в качестве названия штата. Эти разделы, очевидно, составляют всего лишь несколько десятых мили в большинстве случаев, но я чувствовал, что должен упомянуть об этом, просто чтобы прояснить, что происходит, когда это происходит.
ОБНОВЛЕНО:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=<YOUR-KEY-HERE>"></script>
<div id="map" style="height:400px"></div>
<div id="status"></div>
<div id="results" style="height:400px"><b>Results:</b></div>
<script>
var directionsRequest = {
origin: "New York, NY", //default
destination: "Los Angeles, LA", //default
optimizeWaypoints: true,
provideRouteAlternatives: false,
travelMode: google.maps.TravelMode.DRIVING,
drivingOptions: {
departureTime: new Date(),
trafficModel: google.maps.TrafficModel.PESSIMISTIC
}
};
directionsRequest.origin = prompt("Enter your starting address");
directionsRequest.destination = prompt("Enter your destination address");
var starttime = new Date();
var geocoder = new google.maps.Geocoder();
var startState;
var currentState;
var routeData;
var index = 0;
var stateChangeSteps = [];
var borderLatLngs = {};
var startLatLng;
var endLatLng;
directionsService = new google.maps.DirectionsService();
directionsService.route(directionsRequest, init);
function init(data){
routeData = data;
displayRoute();
startLatLng = data.routes[0].legs[0].start_location;
endLatLng = data.routes[0].legs[0].end_location;
geocoder.geocode({location:data.routes[0].legs[0].start_location}, assignInitialState)
}
function assignInitialState(data){
startState = getState(data);
currentState = startState;
compileStates(routeData);
}
function getState(data){
for (var i = 0; i < data.length; i++) {
if (data[i].types[0] === "administrative_area_level_1") {
var state = data[i].address_components[0].short_name;
}
}
return state;
}
function compileStates(data, this_index){
if(typeof(this_index) == "undefined"){
index = 1;
geocoder.geocode({location:data.routes[0].legs[0].steps[0].start_location}, compileStatesReceiver);
}else{
if(index >= data.routes[0].legs[0].steps.length){
console.log(stateChangeSteps);
index = 0;
startBinarySearch();
return;
}
setTimeout(function(){
geocoder.geocode({location:data.routes[0].legs[0].steps[index].start_location}, compileStatesReceiver);
$("#status").html("Indexing Step "+index+"... ("+data.routes[0].legs[0].steps.length+" Steps Total)");
}, 3000)
}
}
function compileStatesReceiver(response){
state = getState(response);
console.log(state);
if(state != currentState){
currentState = state;
stateChangeSteps.push(index-1);
}
index++;
compileStates(routeData, index);
}
var stepIndex = 0;
var stepStates = [];
var binaryCurrentState = "";
var stepNextState;
var stepEndState;
var step;
var myLatLng = {lat:39.8282, lng:-98.5795};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng
});
function displayRoute() {
directionsDisplay = new google.maps.DirectionsRenderer();
directionsDisplay.setMap(map);
directionsDisplay.setDirections(routeData);
}
var orderedLatLngs = [];
function startBinarySearch(iterating){
if(stepIndex >= stateChangeSteps.length){
for(step in borderLatLngs){
for(state in borderLatLngs[step]){
for(statename in borderLatLngs[step][state]){
$("#results").append("<br>Cross into "+statename+" at "+JSON.stringify(borderLatLngs[step][state][statename], null, 4));
orderedLatLngs.push([borderLatLngs[step][state][statename], statename]);
}
}
}
compileMiles(true);
return;
}
step = routeData.routes[0].legs[0].steps[stateChangeSteps[stepIndex]];
console.log("Looking at step "+stateChangeSteps[stepIndex]);
borderLatLngs[stepIndex] = {};
if(!iterating){
binaryCurrentState = startState;
}
geocoder.geocode({location:step.end_location},
function(data){
if(data === null){
setTimeout(function(){startBinarySearch(true);}, 6000);
}else{
stepNextState = getState(data);
stepEndState = stepNextState;
binaryStage2(true);
}
});
}
var minIndex;
var maxIndex;
var currentIndex;
function binaryStage2(init){
if (typeof(init) != "undefined"){
minIndex = 0;
maxIndex = step.path.length - 1;
}
if((maxIndex-minIndex)<2){
borderLatLngs[stepIndex][maxIndex]={};
borderLatLngs[stepIndex][maxIndex][stepNextState]=step.path[maxIndex];
var marker = new google.maps.Marker({
position: borderLatLngs[stepIndex][maxIndex][stepNextState],
map: map,
});
if(stepNextState != stepEndState){
minIndex = maxIndex;
maxIndex = step.path.length - 1;
binaryCurrentState = stepNextState;
stepNextState = stepEndState;
}else{
stepIndex++;
binaryCurrentState = stepNextState;
startBinarySearch(true);
return;
}
}
console.log("Index starts: "+minIndex+" "+maxIndex);
console.log("current state is "+binaryCurrentState);
console.log("next state is "+ stepNextState);
console.log("end state is "+ stepEndState);
currentIndex = Math.floor((minIndex+maxIndex)/2);
setTimeout(function(){
geocoder.geocode({location:step.path[currentIndex]}, binaryStage2Reciever);
$("#status").html("Searching for division between "+binaryCurrentState+" and "+stepNextState+" between indexes "+minIndex+" and "+maxIndex+"...")
}, 3000);
}
function binaryStage2Reciever(response){
if(response === null){
setTimeout(binaryStage2, 6000);
}else{
state = getState(response)
if(state == binaryCurrentState){
minIndex = currentIndex +1;
}else{
maxIndex = currentIndex - 1
if(state != stepNextState){
stepNextState = state;
}
}
binaryStage2();
}
}
var currentStartPoint;
var compileMilesIndex = 0;
var stateMiles = {};
var trueState;
function compileMiles(init){
if(typeof(init)!= "undefined"){
currentStartPoint = startLatLng;
trueState = startState;
}
if(compileMilesIndex == orderedLatLngs.length){
directionsRequest.destination = endLatLng;
}else{
directionsRequest.destination = orderedLatLngs[compileMilesIndex][0];
}
directionsRequest.origin = currentStartPoint;
currentStartPoint = directionsRequest.destination;
directionsService.route(directionsRequest, compileMilesReciever)
}
function compileMilesReciever(data){
if(data===null){
setTimeout(compileMiles, 6000);
}else{
if(compileMilesIndex == orderedLatLngs.length){
stateMiles[stepEndState]=data.routes[0].legs[0].distance["text"];
$("#results").append("<br><br><b>Distances Traveled</b>");
for(state in stateMiles){
$("#results").append("<br>"+state+": "+stateMiles[state]);
}
var endtime = new Date();
totaltime = endtime - starttime;
$("#results").append("<br><br>Operation took "+Math.floor(totaltime/60000)+" minute(s) and "+(totaltime%60000)/1000+" second(s) to run.");
return;
}else{
stateMiles[trueState]=data.routes[0].legs[0].distance["text"];
}
trueState = orderedLatLngs[compileMilesIndex][1];
compileMilesIndex++;
setTimeout(compileMiles, 3000);
}
}
</script>
</script>