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> |
<a href="#" onclick="pointInterval=30;clearOverlays();">interval 30 (default)</a> |
<a href="#" onclick="pointInterval=20;clearOverlays();">interval 20</a> |
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<div id="map_canvas"></div>
뭘 "삼십마일 방향 '이라고하는 것은, 내 매쉬업입니다. 매시업이 사용하는 것과 동일한 원칙을 사용할 수 있습니다. 즉, 시작점 주변의 원을 계산하고 목적지를 해당 목적지로 사용 한 다음 원하는 경로에 도달하면 각 경로를 잘라냅니다. 나는 완전한 예제를 만들 시간이 없지만, 특정 질문을 게시하고 문제가 생기면 도와 드리겠습니다. (다른 사람들도 그렇게 할 것입니다). :) – Marcelo
@Marcelo 올바른 방향으로 나를 가리켜 주셔서 감사합니다. 매시업이 확실히 인상적이며, 이미 설명하는 것을하기 시작했습니다. ** 그래서 명확히하기 위해, 당신은 어떤 거리에 도달했을 때 경로를 차단하고 있습니까? ** 그렇다면, 아마도 당신이 한 일을 많이 할 수 있고, 거리를 움켜 잡고 운전 시간을 잡을 수 있습니다. 길 찾기 서비스에 대한 실적 및 통화량에 대해 걱정할뿐입니다. 또한 v3으로 마이그레이션 할 것입니다. 다시 한 번 감사드립니다! – Gady
네, 그게 바로 shortenAndShow() 함수의 기능입니다. 30 마일의 목적지 서클은 직선의 반경을 가지고 있기 때문에 도로가 곡선을 가지기 때문에 도달하지 않을 것입니다. 그래서 파란색 원의 가장자리에 도달하기 전에 30 마일에 도달합니다. 성능은 가능한 대상 지점을 설정하는 간격 (도 단위)에 따라 달라집니다. 매 1도 시도는 매 10도마다 시도보다 10 배 더 많은 요청을 취합니다 (기본값은 30도입니다). 행운을 빕니다. 잘 조사 된 질문에 대해서는 (+1)을 입력하십시오. – Marcelo