2017-02-09 89 views
-1

我用Google Maps API的小腳本 - 從用戶(開始和目的地)獲取地址,腳本向我顯示地理座標和距離Google Matrix Service的距離。問題是:當我點擊按鈕來計算座標和距離時,我需要點擊兩次 - 第一次顯示座標,第二次顯示它之間的距離。也許你知道解決方案嗎?必須兩次點擊按鈕Javascript - 谷歌地圖

 var firstCityLocationLtd = ""; 
 
\t \t var secondCityLocationLtd = ""; 
 
     var distanceKm = ""; 
 

 
     document.getElementById('submit').addEventListener('click', function() { 
 
      initGeocoder(); 
 
     }); 
 
\t 
 
\t  function initGeocoder() { 
 
\t \t var geocoder = new google.maps.Geocoder(); 
 
     var firstCityLocation = document.getElementById('firstLocation').value; 
 
\t \t var secondCityLocation = document.getElementById('secondLocation').value; \t \t 
 
\t \t 
 
\t \t 
 
     geocoder.geocode({'address': firstCityLocation}, function(results, status) { 
 
      if (status === 'OK') { 
 
\t \t  firstCityLocationLtd = results[0].geometry.location; 
 
      document.getElementById("result1").innerHTML = firstCityLocationLtd; 
 
      } else { 
 
      alert('Error: ' + status); 
 
      } 
 
     }); 
 
\t \t 
 
\t \t geocoder.geocode({'address': secondCityLocation}, function(results, status) { 
 
      if (status === 'OK') { 
 
\t \t  secondCityLocationLtd = results[0].geometry.location; 
 
      document.getElementById("result2").innerHTML = secondCityLocationLtd; 
 
      } else { 
 
      alert('Error: ' + status); 
 
      } 
 
     }); 
 
\t \t var service = new google.maps.DistanceMatrixService; 
 
     service.getDistanceMatrix({ 
 
      origins: [firstCityLocationLtd], 
 
      destinations: [secondCityLocationLtd], 
 
      travelMode: 'DRIVING', 
 
      unitSystem: google.maps.UnitSystem.METRIC, 
 
      avoidHighways: false, 
 
      avoidTolls: false 
 
     }, function callback(response, status) { 
 
      if (status !== 'OK') { 
 
      alert('Error was: ' + status); 
 
      } else { 
 
      var originList = response.originAddresses; 
 
      var destinationList = response.destinationAddresses; 
 
      //var outputDiv = document.getElementById('output'); 
 
      //outputDiv.innerHTML = ''; 
 

 
      for (var i = 0; i < originList.length; i++) { 
 
       var results = response.rows[i].elements; 
 
       geocoder.geocode({'address': originList[i]}); 
 
       for (var j = 0; j < results.length; j++) { 
 
       geocoder.geocode({'address': destinationList[j]}); 
 
       distanceKm += results[j].distance.value; \t \t \t \t 
 
       } 
 
\t \t \t 
 
      } 
 
\t \t \t showRoadDetails(firstCityLocationLtd, secondCityLocationLtd, distanceKm); 
 
      } 
 
     }) 
 
\t \t } 
 
\t \t 
 
\t \t function showRoadDetails(start, end, distance){ 
 
\t \t \t document.getElementById("result1").innerHTML = start; 
 
\t \t \t document.getElementById("result2").innerHTML = end; 
 
\t \t \t document.getElementById("output").innerHTML = distance/1000; 
 
\t \t 
 
\t \t }
body { 
 
height:100%; 
 
} 
 

 
.jumbotron { 
 
\t margin-top:20%; 
 
\t background-color: rgba(238,238,238,0.9); 
 
} 
 

 
.game p.labels { 
 
\t margin-bottom:2px; 
 
\t font-size:14px; 
 
\t text-transform:uppercase; 
 
} 
 

 
.inputForm { 
 
\t margin-bottom:10px; 
 
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<nav class="navbar navbar-default navbar-fixed-top"> 
 
     <div class="container"> 
 
     <div class="navbar-header"> 
 
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> 
 
      <span class="sr-only">Toggle navigation</span> 
 
      <span class="icon-bar"></span> 
 
      <span class="icon-bar"></span> 
 
      <span class="icon-bar"></span> 
 
      </button> 
 
      <a class="navbar-brand" href="#">Brand</a> 
 
     </div> 
 
     <div id="navbar" class="navbar-collapse collapse"> 
 
      <ul class="nav navbar-nav"> 
 
      <li><a href="#">1</a></li> 
 
      <li class="active"><a href="#">2</a></li> 
 
      <li><a href="#">3</a></li> 
 
      </ul> 
 
     </div><!--/.nav-collapse --> 
 
     </div> 
 
    </nav> 
 

 
    <div class="container-fluid main"> 
 
\t \t <div class="container"> 
 

 
     <!-- Main component for a primary marketing message or call to action --> 
 
     <div class="jumbotron"> 
 
\t <div class="game"> 
 
\t <div class="row"> 
 
\t <div class="col-md-4"> 
 
     <h3>Your road</h3> 
 
     
 
\t \t \t <p class="labels">From</p><input id="firstLocation" type="textbox" value="Wrocław, Poland" class="inputForm"> 
 
\t \t \t <p class="labels">To</p><input id="secondLocation" type="textbox" value="Warszawa, Poland" class="inputForm"><br/> 
 
\t \t \t 
 
\t \t </div> 
 
     </div> 
 
\t <div class="row"> 
 
\t \t <div class="col-md-12 text-center"> 
 
\t \t \t \t <input id="submit" type="button" value="Calculate it"> 
 
\t \t \t <div id="result1"></div> 
 
\t \t \t <div id="result2"></div> 
 
\t \t \t <div id="output"></div> 
 
\t \t </div> 
 
\t </div> 
 
\t \t </div> 
 
    </div> <!-- /container --> 
 
\t </div> 
 
\t </div> 
 
    <script async defer 
 
    src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBU2QyOcVY_qoDykdLzX4ywANyPbXJVfZI&callback=initGeocoder&libraries=geometry"> 
 
    </script>

+0

你爲什麼調用回調到distanceMatrix裏面的地理編碼器?這肯定會使問題複雜化(並且呼叫沒有回叫功能,所以它不會做任何有用的事情,但會佔用您的配額) – geocodezip

+0

距離矩陣也適用於用戶的地址。你有什麼理由使用Geocoder來獲取座標並將它們傳遞給距離矩陣? – Coder

+0

@geocodezip我在Google Maps API網站上看到了這個解決方案,我不知道這是不必要的。謝謝! – Adrian

回答

1

您必須調用DistanceMatrixService之前等待的地理編碼服務的結果。你可以用承諾做到這一點(採取對波紋管段一看)

// Code goes here 
 

 
var firstCityLocationLtd = ""; 
 
var secondCityLocationLtd = ""; 
 
var distanceKm = ""; 
 

 
document.getElementById('submit').addEventListener('click', function() { 
 
    initGeocoder(); 
 
}); 
 

 
function initGeocoder() { 
 
    var geocoder = new google.maps.Geocoder(); 
 
    var firstCityLocation = document.getElementById('firstLocation').value; 
 
    var secondCityLocation = document.getElementById('secondLocation').value; 
 

 
    var deferFistLocation = $.Deferred(); 
 
    var deferSecondLocation = $.Deferred(); 
 
    geocoder.geocode({ 
 
    'address': firstCityLocation 
 
    }, function(results, status) { 
 
    if (status === 'OK') { 
 
     firstCityLocationLtd = results[0].geometry.location; 
 
     document.getElementById("result1").innerHTML = firstCityLocationLtd; 
 
     deferFistLocation.resolve(); 
 

 
    } else { 
 
     deferFistLocation.reject(); 
 
     alert('Error: ' + status); 
 
    } 
 
    }); 
 

 
    geocoder.geocode({ 
 
    'address': secondCityLocation 
 
    }, function(results, status) { 
 
    if (status === 'OK') { 
 
     secondCityLocationLtd = results[0].geometry.location; 
 
     document.getElementById("result2").innerHTML = secondCityLocationLtd; 
 
     deferSecondLocation.resolve(); 
 
    } else { 
 
     deferSecondLocation.reject(); 
 
     alert('Error: ' + status); 
 
    } 
 
    }); 
 

 
    $.when(deferFistLocation, deferSecondLocation).done(function() { 
 
     var service = new google.maps.DistanceMatrixService; 
 
     service.getDistanceMatrix({ 
 
     origins: [firstCityLocationLtd], 
 
     destinations: [secondCityLocationLtd], 
 
     travelMode: 'DRIVING', 
 
     unitSystem: google.maps.UnitSystem.METRIC, 
 
     avoidHighways: false, 
 
     avoidTolls: false 
 
     }, function callback(response, status) { 
 
     if (status !== 'OK') { 
 
      alert('Error was: ' + status); 
 
     } else { 
 
      var originList = response.originAddresses; 
 
      var destinationList = response.destinationAddresses; 
 
      //var outputDiv = document.getElementById('output'); 
 
      //outputDiv.innerHTML = ''; 
 

 
      for (var i = 0; i < originList.length; i++) { 
 
      var results = response.rows[i].elements; 
 
      geocoder.geocode({ 
 
       'address': originList[i] 
 
      }); 
 
      for (var j = 0; j < results.length; j++) { 
 
       geocoder.geocode({ 
 
       'address': destinationList[j] 
 
       }); 
 
       distanceKm += results[j].distance.value; 
 
      } 
 

 
      } 
 
      showRoadDetails(firstCityLocationLtd, secondCityLocationLtd, distanceKm); 
 
     } 
 
     }) 
 
    }); 
 
} 
 

 
function showRoadDetails(start, end, distance) { 
 
    document.getElementById("result1").innerHTML = start; 
 
    document.getElementById("result2").innerHTML = end; 
 
    document.getElementById("output").innerHTML = distance/1000; 
 

 
}
body { 
 
height:100%; 
 
} 
 

 
.jumbotron { 
 
\t margin-top:20%; 
 
\t background-color: rgba(238,238,238,0.9); 
 
} 
 

 
.game p.labels { 
 
\t margin-bottom:2px; 
 
\t font-size:14px; 
 
\t text-transform:uppercase; 
 
} 
 

 
.inputForm { 
 
\t margin-bottom:10px; 
 
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<nav class="navbar navbar-default navbar-fixed-top"> 
 
     <div class="container"> 
 
     <div class="navbar-header"> 
 
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> 
 
      <span class="sr-only">Toggle navigation</span> 
 
      <span class="icon-bar"></span> 
 
      <span class="icon-bar"></span> 
 
      <span class="icon-bar"></span> 
 
      </button> 
 
      <a class="navbar-brand" href="#">Brand</a> 
 
     </div> 
 
     <div id="navbar" class="navbar-collapse collapse"> 
 
      <ul class="nav navbar-nav"> 
 
      <li><a href="#">1</a></li> 
 
      <li class="active"><a href="#">2</a></li> 
 
      <li><a href="#">3</a></li> 
 
      </ul> 
 
     </div><!--/.nav-collapse --> 
 
     </div> 
 
    </nav> 
 

 
    <div class="container-fluid main"> 
 
\t \t <div class="container"> 
 

 
     <!-- Main component for a primary marketing message or call to action --> 
 
     <div class="jumbotron"> 
 
\t <div class="game"> 
 
\t <div class="row"> 
 
\t <div class="col-md-4"> 
 
     <h3>Your road</h3> 
 
     
 
\t \t \t <p class="labels">From</p><input id="firstLocation" type="textbox" value="Wrocław, Poland" class="inputForm"> 
 
\t \t \t <p class="labels">To</p><input id="secondLocation" type="textbox" value="Warszawa, Poland" class="inputForm"><br/> 
 
\t \t \t 
 
\t \t </div> 
 
     </div> 
 
\t <div class="row"> 
 
\t \t <div class="col-md-12 text-center"> 
 
\t \t \t \t <input id="submit" type="button" value="Calculate it"> 
 
\t \t \t <div id="result1"></div> 
 
\t \t \t <div id="result2"></div> 
 
\t \t \t <div id="output"></div> 
 
\t \t </div> 
 
\t </div> 
 
\t \t </div> 
 
    </div> <!-- /container --> 
 
\t </div> 
 
\t </div> 
 
    <script async defer 
 
    src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBU2QyOcVY_qoDykdLzX4ywANyPbXJVfZI&callback=initGeocoder&libraries=geometry"> 
 
    </script>

+0

這是我正在尋找的解決方案,非常有用的東西,謝謝! – Adrian

+0

歡迎。你可以標記爲解決了這個問題 - > http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work –