2012-09-06 2 views
3

Google지도 자바 스크립트 API V3 솔루션을 사용하면 Google지도 앱에 드라이브 시간 다각형 기능을 추가 할 수 있습니다.Google지도 API로 운전 시간대 폴리곤

기본적으로 워크 플로는 사용자가 마커 또는지도상의 점을 클릭하고 마커/점 주위에 다각형을 생성하여 어떤 방향으로 5 분 이내에 주행 할 수있는 영역을 나타냅니다.

무작위 경로로 길 찾기 서비스에 번이 지나치게 많이 걸리므로 정확한 Google지도 API 솔루션으로도이 작업을 수행 할 수 있는지 확실하지 않습니다. 시간 임계 값은 버려집니다. 이것이 가능한지 또는 이것이 엔지니어가 될 수있는 최선의 방법이 될지 확실하지 않습니다. 이 경우 일부 백엔드 프로세싱을 사용해야 할 수도 있지만, 다른 모든 옵션은 먼저 배제하고 싶지만 백엔드 솔루션의 모든 예제를 환영합니다.

모든 도움, 제안 또는 예가 크게 환영합니다. - 2, 1 무, 그리고

  1. Google Maps Utility Library example : 드라이브 배 다음은 내가 건너 한 일부 예,하지만 하나는 순수 Google지도 API 솔루션되지 않습니다 및/또는 사용하지 않는 클릭 한 지점을 중심으로 3 분의 시간대의 다각형을 사용하지만 Esri의 샘플 Geoprocessing 서비스를 사용하여 계산을 실행하고 다각형 형상을 생성하므로 내 요구 사항에 맞지 않습니다.

  2. 30 mile directions는 - 그것은 30 개 마일 지점에서, 계산에 불과 거리 드라이브 - 시간을 고려하지 않는 길 찾기 API를 사용하여 순수 Google지도 API 솔루션입니다 그리고 좋은 다각형을 그립니다, 하지만 .

  3. Mapnificent은 - 순수 Google지도 API 솔루션이 될 것 같다, 그들은 API를 가지고 있지만이 시간를 운전하지, 대중 교통 데이터에서 가져온 대중 교통 시간으로 을 다루고있다. 따라서 시간을 늘리면 "열리는"지역은 지정된 시간 내에 대중 교통을 이용할 수있는 지점을 나타냅니다. 나는 이것을 원한다, . 그러나 번영 시간 대신에 운전 시간은와 같다. 그것은 옛날과 V2의 API로 작성된 비록 당신이 부르는

+1

뭘 "삼십마일 방향 '이라고하는 것은, 내 매쉬업입니다. 매시업이 사용하는 것과 동일한 원칙을 사용할 수 있습니다. 즉, 시작점 주변의 원을 계산하고 목적지를 해당 목적지로 사용 한 다음 원하는 경로에 도달하면 각 경로를 잘라냅니다. 나는 완전한 예제를 만들 시간이 없지만, 특정 질문을 게시하고 문제가 생기면 도와 드리겠습니다. (다른 사람들도 그렇게 할 것입니다). :) – Marcelo

+0

@Marcelo 올바른 방향으로 나를 가리켜 주셔서 감사합니다. 매시업이 확실히 인상적이며, 이미 설명하는 것을하기 시작했습니다. ** 그래서 명확히하기 위해, 당신은 어떤 거리에 도달했을 때 경로를 차단하고 있습니까? ** 그렇다면, 아마도 당신이 한 일을 많이 할 수 있고, 거리를 움켜 잡고 운전 시간을 잡을 수 있습니다. 길 찾기 서비스에 대한 실적 및 통화량에 대해 걱정할뿐입니다. 또한 v3으로 마이그레이션 할 것입니다. 다시 한 번 감사드립니다! – Gady

+0

네, 그게 바로 shortenAndShow() 함수의 기능입니다. 30 마일의 목적지 서클은 직선의 반경을 가지고 있기 때문에 도로가 곡선을 가지기 때문에 도달하지 않을 것입니다. 그래서 파란색 원의 가장자리에 도달하기 전에 30 마일에 도달합니다. 성능은 가능한 대상 지점을 설정하는 간격 (도 단위)에 따라 달라집니다. 매 1도 시도는 매 10도마다 시도보다 10 배 더 많은 요청을 취합니다 (기본값은 30도입니다). 행운을 빕니다. 잘 조사 된 질문에 대해서는 (+1)을 입력하십시오. – Marcelo

답변

3

는 "30 mile directions는"내 매쉬업입니다. 매시업이 사용하는 것과 동일한 원칙을 사용할 수 있습니다. 즉, 시작점 주변의 원을 계산하고 목적지를 해당 목적지로 사용 한 다음 원하는 경로에 도달하면 각 경로를 잘라냅니다.

일본어 링크가 죽었 (아래 코드)이 예에서

, 함수 shortenAndShow()은 경로의 일부를 차단하는 30 마일을 넘습니다. 30 마일의 목적지 서클은 직선의 반경을 가지고 있기 때문에 도로가 곡선을 가지기 때문에 도달하지 않을 것입니다. 그래서 파란색 원의 가장자리에 도달하기 전에 30 마일에 도달합니다.당신은 같은 일을 할 수 있지만, 거리 대신에 운전 시간을 기준으로 경로를 차단합니다.

성능은 가능한 대상 지점을 설정하는 간격 (도 단위)에 따라 달라집니다. 매 1도 시도는 매 10도마다 시도보다 10 배 더 많은 요청을 취합니다 (기본값은 30도입니다).

코드 : 그것은 옛날과 V2의 API로 작성된 비록

var map; 
 
var container; 
 
var zoom = 9; 
 
var centerPoint = new google.maps.LatLng(35.149534, -90.04898); 
 
var dirService = new google.maps.DirectionsService(); 
 
var centerMarker; 
 
var circleMarkers = Array(); 
 
var circlePoints = Array(); 
 
var drivePolyPoints = Array(); 
 
var searchPolygon, drivePolygon; 
 
var distToDrive = 30; // miles 
 
var pointInterval = 30; 
 
var searchPoints = []; 
 
var polyline; 
 
var polylines = []; 
 
var redIcon8 = "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle.png"; 
 

 
function initialize() { 
 
    map = new google.maps.Map(
 
    document.getElementById("map_canvas"), { 
 
     center: centerPoint, 
 
     zoom: 9, 
 
     mapTypeId: google.maps.MapTypeId.ROADMAP 
 
    }); 
 
    google.maps.event.addListener(map, "click", mapClick); 
 
} 
 
google.maps.event.addDomListener(window, "load", initialize); 
 

 
function mapClick(evt) { 
 
    // map.clearOverlays(); 
 
    circleMarkers = Array(); 
 
    if (!centerMarker) { 
 
    centerMarker = new google.maps.Marker({ 
 
     position: evt.latLng, 
 
     map: map 
 
    }); 
 
    } else { 
 
    centerMarker.setMap(null); 
 
    centerMarker.setPosition(evt.latLng); 
 
    } 
 
    centerMarker.setMap(map); 
 
    searchPoints = getCirclePoints(evt.latLng, distToDrive); 
 
    drivePolyPoints = Array(); 
 
    getDirections(); 
 
} 
 

 
function getCirclePoints(center, radius) { 
 
    var bounds = new google.maps.LatLngBounds(); 
 
    var circlePoints = Array(); 
 
    var searchPoints = Array(); 
 
    with(Math) { 
 
    var rLat = (radius/3963.189) * (180/PI); // miles 
 
    var rLng = rLat/cos(center.lat() * (PI/180)); 
 
    for (var a = 0; a < 361; a++) { 
 
     var aRad = a * (PI/180); 
 
     var x = center.lng() + (rLng * cos(aRad)); 
 
     var y = center.lat() + (rLat * sin(aRad)); 
 
     var point = new google.maps.LatLng(parseFloat(y), parseFloat(x), true); 
 
     bounds.extend(point); 
 
     circlePoints.push(point); 
 
     if (a % pointInterval == 0) { 
 
     searchPoints.push(point); 
 
     } 
 
    } 
 
    } 
 
    searchPolygon = new google.maps.Polygon({ 
 
    paths: circlePoints, 
 
    strokeColor: '#0000ff', 
 
    strokeWeight: 1, 
 
    strokeOpacity: 1, 
 
    fillColor: '#0000ff', 
 
    fillOpacity: 0.2 
 
    }); 
 
    searchPolygon.setMap(map); 
 
    map.fitBounds(bounds); 
 
    return searchPoints; 
 
} 
 

 
function getDirections() { 
 
    if (!searchPoints.length) { 
 
    return; 
 
    } 
 
    var to = searchPoints.shift(); 
 
    var request = { 
 
    origin: centerMarker.getPosition(), 
 
    destination: to, 
 
    travelMode: google.maps.TravelMode.DRIVING 
 
    }; 
 
    dirService.route(request, function(result, status) { 
 
    if (status == google.maps.DirectionsStatus.OK) { 
 
     var distance = parseInt(result.routes[0].legs[0].distance.value/1609); 
 
     var duration = parseFloat(result.routes[0].legs[0].duration.value/3600).toFixed(2); 
 
     var path = result.routes[0].overview_path; 
 
     var legs = result.routes[0].legs; 
 
     if (polyline && polyline.setPath) { 
 
     polyline.setPath([]); 
 
     } else { 
 
     polyline = new google.maps.Polyline({ 
 
      path: [], 
 
      // map: map, 
 
      strokeColor: "#FF0000", 
 
      strokeOpacity: 1 
 
     }); 
 
     } 
 
     for (i = 0; i < legs.length; i++) { 
 
     var steps = legs[i].steps; 
 
     for (j = 0; j < steps.length; j++) { 
 
      var nextSegment = steps[j].path; 
 
      for (k = 0; k < nextSegment.length; k++) { 
 
      polyline.getPath().push(nextSegment[k]); 
 
      // bounds.extend(nextSegment[k]); 
 
      } 
 
     } 
 
     } 
 
     // polyline.setMap(map); 
 
     shortenAndShow(polyline); 
 
     getDirections(); 
 
    } else { 
 
     console.log("Directions request failed, status=" + status + " [from:" + request.origin + " to:" + request.destination + "]"); 
 
     getDirections(); 
 
    } 
 
    }); 
 
} 
 

 
function shortenAndShow(polyline) { 
 
    var distToDriveM = distToDrive * 1609; 
 
    var dist = 0; 
 
    var cutoffIndex = 0; 
 
    var copyPoints = Array(); 
 
    for (var n = 0; n < polyline.getPath().getLength() - 1; n++) { 
 
    dist += google.maps.geometry.spherical.computeDistanceBetween(polyline.getPath().getAt(n), polyline.getPath().getAt(n + 1)); 
 
    //GLog.write(dist + ' - ' + distToDriveM); 
 
    if (dist < distToDriveM) { 
 
     copyPoints.push(polyline.getPath().getAt(n)); 
 
    } else { 
 
     break; 
 
    } 
 
    } 
 
    var lastPoint = copyPoints[copyPoints.length - 1]; 
 
    var newLine = new google.maps.Polyline({ 
 
    path: copyPoints, 
 
    strokeColor: '#ff0000', 
 
    strokeWeight: 2, 
 
    strokeOpacity: 1 
 
    }); 
 
    newLine.setMap(map); 
 
    polylines.push(newLine); 
 
    drivePolyPoints.push(lastPoint); 
 
    addBorderMarker(lastPoint, dist) 
 
    if (drivePolyPoints.length > 3) { 
 
    if (drivePolygon) { 
 
     drivePolygon.setMap(null); 
 
    } 
 
    drivePolygon = new google.maps.Polygon({ 
 
     paths: drivePolyPoints, 
 
     strokeColor: '#00ff00', 
 
     strokeWeight: 1, 
 
     strokeOpacity: 1, 
 
     fillColor: '#00ff00', 
 
     fillOpacity: 0.4 
 
    }); 
 
    drivePolygon.setMap(map); 
 
    } 
 
} 
 

 
function addBorderMarker(pt, d) { 
 
    var str = pt.lat().toFixed(6) + ',' + pt.lng().toFixed(6) + ' - Driving Distance: ' + (d/1609).toFixed(2) + ' miles'; 
 
    var marker = new google.maps.Marker({ 
 
    position: pt, 
 
    icon: redIcon8, 
 
    title: str 
 
    }); 
 
    circleMarkers.push(marker); 
 
    marker.setMap(map); 
 
} 
 

 
function clearOverlays() { 
 
    for (var i = 0; i < circleMarkers.length; i++) { 
 
    circleMarkers[i].setMap(null); 
 
    } 
 
    circleMarkers = []; 
 
    for (var i = 0; i < circlePoints.length; i++) { 
 
    circlePoints[i].setMap(null); 
 
    } 
 
    circlePoints = []; 
 
    for (var i = 0; i < polylines.length; i++) { 
 
    polylines[i].setMap(null); 
 
    } 
 
    polylines = []; 
 
    if (searchPolygon && searchPolygon.setMap) searchPolygon.setMap(null); 
 
    if (drivePolygon && drivePolygon.setMap) drivePolygon.setMap(null); 
 
    if (centerMarker && centerMarker.setMap) centerMarker.setMap(null); 
 
}
html, 
 
body, 
 
#map_canvas { 
 
    height: 100%; 
 
    width: 100%; 
 
    margin: 0px; 
 
    padding: 0px 
 
}
<a href="#" onclick="clearOverlays();">Clear</a>&nbsp;|&nbsp; 
 
<a href="#" onclick="pointInterval=30;clearOverlays();">interval 30 (default)</a>&nbsp;|&nbsp; 
 
<a href="#" onclick="pointInterval=20;clearOverlays();">interval 20</a>&nbsp;|&nbsp; 
 

 
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script> 
 
<div id="map_canvas"></div>

관련 문제