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

时间:2018-10-30 00:19:28

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

我正在使用 google maps api v3 ,并且正在尝试使用捕捉点来获得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();
    });
  }

我更改了代码,但是即使我最终得到了2557个坐标数组,也无法正常工作。

我也尝试过这种想法,认为这可以让我有时间掌握所有坐标:

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);
    });
  }

谢谢。

1 个答案:

答案 0 :(得分:0)

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

如果您的原始路径中有550个坐标,则说明您必须调用Roads API 6次(5次100分+ 1次50分)。然后,您应该能够在某个地方设置一个计数器,以便在从Roads API获得6条响应后仅绘制(完整的)折线。

或者您可以根据最终数组的长度(与原始路径相比)来确定,尽管我不知道在某些点无法“捕捉”的情况下会发生什么。