10

Google Maps API v3 を使用して、ルートの出発地、ウェイポイント、および目的地に基づいて、米国の州ごとにマイレージを計算する方法を探しています。

Google の Distance Matrix API を使用してみましたが、これは 2 点間の距離を計算しています。これは良いことですが、州ごとに移動したマイルの内訳が必要です。税金の目的のため (輸送に関する 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/

4

1 に答える 1

5

以下は、Google Maps Javascript API を使用する完全に機能する実装です。追加する必要があるのは、独自の Maps API キーだけです。上記の投稿で言及されているように、Google マップは漸近的な速度でリクエストを調整するため、ルートが長くなるほど、計算に時間がかかります。大ざっぱに言えば、コネチカット州ニューヘイブンからニュージャージー州とペンシルベニア州の国境までのルートは約 5 分です。コネチカット州ニューヘブンからロサンゼルスへの移動は、インデックス作成に 45 分かかります。もう 1 つの注意事項: 水域を通るいくつかの州境があります。Google では、これらはどの州にも属していないと見なされるため、undefined を州名として報告します。これらのセクションは、ほとんどの場合、明らかに数十分の 1 マイルにすぎませんが、それが起こったときに何が起こっているのかを明確にするために、それについて言及する必要があると感じました.

更新しました:

<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>
于 2015-12-16T13:32:08.567 に答える