超过 100 个点和一条折线,Google Maps v3

More than 100 points and one polyline, Google Maps v3

我正在使用 google 地图 api v3 我正在尝试使用 snap to road 超过 100 个点,但另外最终只有一条包含整个路线的多段线,我可以放一个小动画。视图是 html.erb.

  var apiKey = any_key;
  var map = handler.getMap();
  var drawingManager;
  var placeIdArray = [];
  var snappedCoordinates = [];
  var path = <%= raw(@locations) %>
  var markers = <%= raw(@markers) %>
  var centerOn = path[0].split(',');

  function breadCrumbsGrapher(path) {
    handler.removeMarkers(Gmaps.store.markers);
    for(var i = 0; i < polylines.length; i++) {
      polylines[i].setMap(null);
    }
    var divided = handlePath(path);
    if (typeof divided[0] == 'object') {
      for(var i = 0; i < divided.length; i++) {
        runSnapToRoad(divided[i]);
      }
    } else {
      runSnapToRoad(path);
    }
  }

  function waypointsLimiter(path) {
    var path_loc_size = path.length;
    var limited = [];
    if(path_loc_size > 30) {
      var stepper = Math.ceil(path_loc_size/30);
      for(var i = stepper; i < path_loc_size; i += stepper) {
        limited.push(path[i]);
      }
      if(limited.indexOf(path[path_loc_size-1]) == -1) {
        limited.push(path[path_loc_size-1]);
      } 
    } else {
      limited = path;
    }
    return limited;
  }

  function handlePath(path) {
    var i = 0;
    var j = path.length;
    if (j > 100) {
      var newArray = [],
      chunk = j/2;
      if (j >= 200) {
        chunk = j/3;
      } else if (j >= 300) {
        chunk = j/4;
      } else if (j >= 400) {
        chunk = j/5;
      } else if (j >= 500 ) {
        chunk = j/6;
      } else if (j >= 600) {
        chunk = j/7;
      } else if (j >= 700 || j <= 799) {
        chunk = j/8;
      } else {
        alert('La ruta no puede ser mostrada');
      }
      for (i, j; i < j; i+=chunk) {
        newArray.push(path.slice(i,i+chunk+1));
      }
      return newArray;
    } else {
      return path;
    }
  }

  // Snap a user-created polyline to roads and draw the snapped path
  function runSnapToRoad(path) {
    var path = path.join('|');
    $.get('https://roads.googleapis.com/v1/snapToRoads', {
      interpolate: true,
      key: apiKey,
      path: path,
    }, function(data) {
      processSnapToRoadResponse(data);
      drawSnappedPolyline();
    });
  }

  // Store snapped polyline returned by the snap-to-road service.
  function processSnapToRoadResponse(data) {
    snappedCoordinates = [];
    placeIdArray = [];
    for (var i = 0; i < data.snappedPoints.length; i++) {
      var latlng = new google.maps.LatLng(
        data.snappedPoints[i].location.latitude,
          data.snappedPoints[i].location.longitude);
      snappedCoordinates.push(latlng);
      placeIdArray.push(data.snappedPoints[i].placeId);
    }
  }

  // Draws the snapped polyline (after processing snap-to-road response).
  function drawSnappedPolyline() {
    var symbol = {
      path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
      scale: 3,
      strokeColor: '#3B16B3'
    };
    var snappedPolyline = new google.maps.Polyline({
      path: snappedCoordinates,
      strokeColor: '#E51E25',
      strokeWeight: 3,
      icons: [{
        icon: symbol,
        offset: '0%'
      }]
    });
    snappedPolyline.setMap(map);
    animate(snappedPolyline);
    zoomToObject(snappedPolyline);
    polylines.push(snappedPolyline);
  }

  function zoomToObject(obj){
    var bounds = new google.maps.LatLngBounds();
    var points = obj.getPath().getArray();
    for (var n = 0; n < points.length ; n++){
      bounds.extend(points[n]);
    }
    map.fitBounds(bounds);
  }

  function animate(line) {
    var count = 0;
    window.setInterval(function() {
      count = (count + 1) % 600;
      var icons = line.get('icons');
      icons[0].offset = (count / 6) + '%';
      line.set('icons', icons);
    }, 70);
  }

  breadCrumbsGrapher(path);

我也试过在外部声明一个变量,这样我就可以连接所有坐标并用它生成折线,但似乎不起作用。实际上那个大数组最终有 2000+ 个点。

The result that I have with the provided code

毕竟,问题是我不知道如何将多段线合并为只有一根线,并且能够只为那一根线制作动画。如果有超过 100 个坐标,我会绘制更多折线。在图像中你可以看到有 3 个图标(每条折线一个),我只需要画一条线并有 1 个图标。

要重现该问题,只需添加一个键,如果您想使用这组坐标:

https://drive.google.com/file/d/1jLb7Djv5DiSdR3k4QZRSatXBwrohlxcI/view?usp=sharing

function breadCrumbsGrapher(path) {
    //mapMarkers();
    snappedCoordinates = [];
    handler.removeMarkers(Gmaps.store.markers);
    for(var i = 0; i < polylines.length; i++) {
      polylines[i].setMap(null);
    }
    var divided = handlePath(path);
    if (typeof divided[0] == 'object') {
      for(var i = 0; i < divided.length; i++) {
        runSnapToRoad(divided[i]);
      }
    } else {
      runSnapToRoad(path);
    }
    console.log(snappedCoordinates);
    drawSnappedPolyline();
  }

function runSnapToRoad(path) {
    var path = path.join('|');
    $.get('https://roads.googleapis.com/v1/snapToRoads', {
      interpolate: true,
      key: apiKey,
      path: path,
    }, function(data) {
      processSnapToRoadResponse(data);
      //drawSnappedPolyline();
    });
  }

我已经更改了代码,但它不起作用,即使我最终得到一个 2,557 坐标数组。

我试过也试过这个认为这可以让我有时间拥有所有坐标:

async function breadCrumbsGrapher(path) {
        //mapMarkers();
        snappedCoordinates = [];
        handler.removeMarkers(Gmaps.store.markers);
        for(var i = 0; i < polylines.length; i++) {
          polylines[i].setMap(null);
        }
        var divided = handlePath(path);
        if (typeof divided[0] == 'object') {
          for(var i = 0; i < divided.length; i++) {
            await runSnapToRoad(divided[i]);
          }
        } else {
          await runSnapToRoad(path);
        }
        console.log(snappedCoordinates);
        drawSnappedPolyline();
      }

和:

async function runSnapToRoad(path) {
    var path = path.join('|');
    await $.get('https://roads.googleapis.com/v1/snapToRoads', {
      interpolate: true,
      key: apiKey,
      path: path,
    }, function(data) {
      processSnapToRoadResponse(data);
    });
  }

提前谢谢你。

您正在使用 $.get() 查询道路 API 这是一个异步调用,因此当您从 breadCrumbsGrapher 函数中调用 drawSnappedPolyline() 时,您很可能没有AJAX 呼叫中的 return 中的所有坐标(尚未)。

如果您在原始路径中有 550 个坐标,那么您就知道必须调用道路 API 6 次(5 次 100 点 + 1 次 50 点)。然后你应该能够在某个地方设置一个计数器,一旦你从道路 API 得到 6 个响应,就只绘制你的(完整的)折线。

或者您可以基于最终数组的长度(与原始路径相比),尽管我不知道如果某些点不能 "snapped" 会发生什么。