【问题标题】:More than 100 points and one polyline, Google Maps v3100多个点和一条折线,谷歌地图v3
【发布时间】:2019-04-02 23:40:01
【问题描述】:

我正在使用 google maps api v3,我正在尝试使用 100 多个点的 snap to road,但最后我只能用一条折线来完成整个路线放一个小动画。视图是一个 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);
    });
  }

提前谢谢你。

【问题讨论】:

  • 然后呢?有什么问题?什么不起作用?你什么都没解释。我可以使用上面的代码来重现问题吗?没有。
  • @MrUpsidown 我添加了更多信息和一个包含 200 个坐标的文件。
  • 嗯...每次收到来自 Roads API 的响应时,您都会调用 drawSnappedPolyline,因此很明显,您最终会得到必须相互重叠的多条折线(每条折线还应包含来自之前的 Snap to Road 响应)。当您处理完所有坐标并且所有坐标都在 snappedCoordinates 数组中时,您应该只调用一次该函数。
  • @MrUpsidown 我试过只是等待 snapedCoordinates 数组已满,但我不知道为什么它不起作用。
  • 怎么样?您做了什么来“等待”直到阵列已满?一条折线可以容纳的点数应该没有限制。

标签: ruby-on-rails google-maps-api-3 gmaps4rails


【解决方案1】:

您正在使用 $.get() 查询作为异步调用的 Roads API,因此当您从 breadCrumbsGrapher 函数中调用 drawSnappedPolyline() 时,您很可能(还)没有从您的AJAX 调用。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-25
    • 2013-07-02
    • 2019-03-01
    • 2013-10-04
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多