7

Я ищу способ расчета пробега по штату США на основе происхождения, путевых точек и адресата маршрута с использованием API карт Google v3.Google maps api v3 вычисляет пробег по состоянию

Я пробовал использовать API-интерфейс Матрицы расстояний Googles, но это вычисляет расстояние между двумя точками, что хорошо, но мне нужен прорыв для миль, пройденных для каждого штата. Для целей налогообложения (отчеты IFTA для транспортировки).

Я проделал много поискового запроса и просмотрел документацию, но я не вижу ничего, что подсчитывает пробег на каждое государство.

Я знаю, как использовать карты Google, и я знаю, что это возможно, так как я видел это на одном видео. Нет кода, который я могу показать, потому что я понятия не имею, как это сделать. Есть предположения?

Полезные ссылки я нашел:

Как рисовать маршруты и рассчитать маршрут Время и расстояния на лету с помощью Google Map API V3 http://www.c-sharpcorner.com/UploadFile/8911c4/how-to-draw-routes-and-calculate-route-time-and-distance-on/

Как построить Distance Finder с Google Maps API http://www.1stwebdesigner.com/distance-finder-google-maps-api/

+0

Похожий вопрос уже задавался и ответил. http://stackoverflow.com/questions/17660677/google-maps-api-detect-when-crossing-state-lines-and-calculate-distance-travel. Надеюсь, это поможет, если не отредактируйте свой вопрос и не сравните его с приведенным выше :) – AniV

+0

Спасибо за ваш ответ. Я видел это раньше. К сожалению, это не отвечает на вопрос. Просто предполагая некоторые вещи и предлагаю использовать текст «Ввод» из текста текста, который не является надежным вообще. –

+0

Нет, не часть «Ввод ...», проверьте [принятый ответ] (http://stackoverflow.com/a/17755943/). Если вы используете API инструкций, вы можете вернуть маршрут, который имеет несколько шагов, каждый с расстоянием. На каждом шаге также есть места начала и конца, которые вы можете использовать, чтобы выяснить, когда маршрут пересекает государственную границу. Теперь, когда у вас есть маршрут, разбитый состояниями, просто суммируйте расстояния. – approxiblue

ответ

3

Ниже приведена полностью функциональная реализация, использующая API Javascript Google Maps. Все, что вам нужно добавить, это ваш собственный API Карт Google. Как отмечено в сообщениях, упомянутых выше, Google Maps дросселирует запросы с асимптотической скоростью, и, таким образом, чем длиннее маршрут, тем дольше он будет вычисляться. Чтобы дать стадион, маршрут из Нью-Хейвен КТ на границу NJ/PA занимает приблизительно 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> 
+0

Ты знаешь, так как ты единственный, кто отправил ответ, я дам тебе. Я не могу дождаться редактирования. :) –

+0

Спасибо! Будет пытаться что-то твердое в течение следующих нескольких часов :-) –

+0

Это поможет многим людям. Вопрос уже имеет 6 голосов. Благодарю. –