Более 100 точек и одна ломаная линия, Google Maps v3 - PullRequest
0 голосов
/ 30 октября 2018

Я работаю с 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+ точек.

Результат, который я имею с предоставленным кодом

После всего этого проблема заключается в том, что я не знаю, как объединить полилинии, чтобы иметь только одну линию и иметь возможность анимировать только эту одну линию. Если есть более 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 голосов
/ 31 октября 2018

Вы используете $.get() для запроса к Roads API, который является асинхронным вызовом, поэтому, когда вы вызываете drawSnappedPolyline() из вашей функции breadCrumbsGrapher, вы, скорее всего, (пока) не получите все координаты, возвращаемые из вашего AJAX вызов (ы).

Если у вас есть 550 координат в исходном пути, вы знаете, что должны вызывать API дорог 6 раз (5 раз с 100 точками + 1 раз с 50 точками). После этого вы сможете установить счетчик где-нибудь, чтобы нарисовать свою (полную) полилинию, как только вы получите свои 6 ответов от Roads API.

Или вы можете основывать это на длине вашего окончательного массива (по сравнению с исходным путем), хотя я не знаю, что произойдет, если некоторые точки не могут быть "привязаны".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...