【问题标题】:JavaScript Google Maps polylines : issue in connecting all given GPS locationsJavaScript Google Maps折线:连接所有给定GPS位置的问题
【发布时间】:2014-12-22 20:22:06
【问题描述】:

我在 html 页面中使用 Javascript 来显示带有标记的 GPS 位置,所有这些 GPS 位置都使用驾驶模式通过折线连接。所有标记都显示在输出中,但折线无法正常工作。

问题是,只有少数几个位置是由多段线连接的,其中很少有在没有连接的情况下被跳过。任何人都可以指出问题出在哪里?

html代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">

     function Call2function(){

        var msg ="41.077354,-81.511337:41.080647,-81.516579:41.077435,-81.521561:41.075253,-81.521492:41.074604,-81.520309:41.07415,-81.516335:41.073158,-81.514931:41.070534,-81.516563:41.066677,-81.516502:41.063942,-81.516502:41.06514,-81.513458:41.067383,-81.513412:41.069546,-81.513397:41.070778,-81.513382:41.072514,-81.512619:41.071106,-81.507614:41.073326,-81.506195:41.075886,-81.506058:41.077274,-81.507652:41.077354,-81.511337";
        var input_msg=msg.split(":");
        var mylatlongg = new Array();
        latlongg =input_msg[0].split(",");

        var mapOptions = {
            center: new google.maps.LatLng(mylatlongg[0],mylatlongg[1]),
            zoom: 12,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
        var infoWindow = new google.maps.InfoWindow();
        var lat_lng = new Array();
        var latlngbounds = new google.maps.LatLngBounds();
        for (i = 0; i<input_msg.length; i++) {
            var data = input_msg[i];
            var laaty =  input_msg[i].split(",")
            var myLatlng = new google.maps.LatLng(laaty[0], laaty[1]);
            lat_lng.push(myLatlng);
            var marker = new google.maps.Marker({
                position: myLatlng,
                map: map,
                title: 'location'
            });
            latlngbounds.extend(marker.position);
        }
        map.setCenter(latlngbounds.getCenter());
        map.fitBounds(latlngbounds);

        //***********ROUTING****************//

        //Intialize the Path Array
        var path = new google.maps.MVCArray();

        //Intialize the Direction Service
        var service = new google.maps.DirectionsService();

        //Set the Path Stroke Color
        var poly = new google.maps.Polyline({ map: map, strokeColor: '#4986E7' });

        //Loop and Draw Path Route between the Points on MAP
        for (var i = 0; i < lat_lng.length; i++) {
            if ((i + 1) < lat_lng.length) {
                var src = lat_lng[i];
                var des = lat_lng[i + 1];
                // path.push(src);
                poly.setPath(path);
                service.route({
                    origin: src,
                    destination: des,
                    travelMode: google.maps.DirectionsTravelMode.DRIVING
                }, function (result, status) {
                    if (status == google.maps.DirectionsStatus.OK) {
                        for (var i = 0, len = result.routes[0].overview_path.length; i < len; i++) {
                            path.push(result.routes[0].overview_path[i]);
                        }
                    }
                });
            }


        }

    }
    google.maps.event.addDomListener(window, 'load', Call2function);

</script>
<div id="dvMap" style="width: 600px; height: 600px">
</div>
</body>
</html>

【问题讨论】:

    标签: javascript google-maps


    【解决方案1】:

    路线服务受配额和费率限制。您没有检查服务返回的状态 (OVER_QUERY_LIMIT)

    您可能想要使用航路点(使用免费 API 在单个方向请求中最多支持 8 个),您目前只有 20 个点,您应该可以使用 3 个请求来完成路线。

    请参阅此相关问题中的示例:Google Maps API to get bus route

    fiddle with error checking

    service.route({
       origin: src,
       destination: des,
       travelMode: google.maps.DirectionsTravelMode.DRIVING
      }, function (result, status) {
       if (status == google.maps.DirectionsStatus.OK) {
         for (var i = 0, len = result.routes[0].overview_path.length; i < len; i++) {
           path.push(result.routes[0].overview_path[i]);
         }
       } else {
         document.getElementById('info').innerHTML += status + "<br>";
       }
    });
    

    working fiddle(基于this answer 中的示例)

    代码 sn-p:

    jQuery(function() {
      var msg = "41.077354,-81.511337:41.080647,-81.516579:41.077435,-81.521561:41.075253,-81.521492:41.074604,-81.520309:41.07415,-81.516335:41.073158,-81.514931:41.070534,-81.516563:41.066677,-81.516502:41.063942,-81.516502:41.06514,-81.513458:41.067383,-81.513412:41.069546,-81.513397:41.070778,-81.513382:41.072514,-81.512619:41.071106,-81.507614:41.073326,-81.506195:41.075886,-81.506058:41.077274,-81.507652:41.077354,-81.511337";
      var input_msg = msg.split(":");
    
      var map = new window.google.maps.Map(document.getElementById("dvMap"));
    
      // new up complex objects before passing them around
      var directionsDisplay = new window.google.maps.DirectionsRenderer({
        suppressMarkers: true
      });
      var directionsService = new window.google.maps.DirectionsService();
    
      Tour_startUp(input_msg);
    
      window.tour.loadMap(map, directionsDisplay);
      window.tour.fitBounds(map);
    
      if (input_msg.length > 1)
        window.tour.calcRoute(directionsService, directionsDisplay);
    });
    
    function Tour_startUp(stops) {
      if (!window.tour) window.tour = {
        updateStops: function(newStops) {
          stops = newStops;
        },
        // map: google map object
        // directionsDisplay: google directionsDisplay object (comes in empty)
        loadMap: function(map, directionsDisplay) {
          var myOptions = {
            zoom: 13,
            center: new window.google.maps.LatLng(51.507937, -0.076188), // default to London
            mapTypeId: window.google.maps.MapTypeId.ROADMAP
          };
          map.setOptions(myOptions);
          directionsDisplay.setMap(map);
        },
        fitBounds: function(map) {
          var bounds = new window.google.maps.LatLngBounds();
    
          // extend bounds for each record
          jQuery.each(stops, function(key, val) {
            var latlng = val.split(",");
            var myLatlng = new window.google.maps.LatLng(latlng[0], latlng[1]);
            bounds.extend(myLatlng);
          });
          map.fitBounds(bounds);
        },
        calcRoute: function(directionsService, directionsDisplay) {
          var batches = [];
          var itemsPerBatch = 10; // google API max = 10 - 1 start, 1 stop, and 8 waypoints
          var itemsCounter = 0;
          var wayptsExist = stops.length > 0;
    
          while (wayptsExist) {
            var subBatch = [];
            var subitemsCounter = 0;
    
            for (var j = itemsCounter; j < stops.length; j++) {
              subitemsCounter++;
              var latlng = stops[j].split(",");
              subBatch.push({
                location: new window.google.maps.LatLng(latlng[0], latlng[1]),
                stopover: true
              });
              if (subitemsCounter == itemsPerBatch)
                break;
            }
    
            itemsCounter += subitemsCounter;
            batches.push(subBatch);
            wayptsExist = itemsCounter < stops.length;
            // If it runs again there are still points. Minus 1 before continuing to
            // start up with end of previous tour leg
            itemsCounter--;
          }
    
          // now we should have a 2 dimensional array with a list of a list of waypoints
          var combinedResults;
          var unsortedResults = [{}]; // to hold the counter and the results themselves as they come back, to later sort
          var directionsResultsReturned = 0;
    
          for (var k = 0; k < batches.length; k++) {
            var lastIndex = batches[k].length - 1;
            var start = batches[k][0].location;
            var end = batches[k][lastIndex].location;
    
            // trim first and last entry from array
            var waypts = [];
            waypts = batches[k];
            waypts.splice(0, 1);
            waypts.splice(waypts.length - 1, 1);
    
            var request = {
              origin: start,
              destination: end,
              waypoints: waypts,
              travelMode: window.google.maps.TravelMode.WALKING
            };
            (function(kk) {
              directionsService.route(request, function(result, status) {
                if (status == window.google.maps.DirectionsStatus.OK) {
    
                  var unsortedResult = {
                    order: kk,
                    result: result
                  };
                  unsortedResults.push(unsortedResult);
    
                  directionsResultsReturned++;
    
                  if (directionsResultsReturned == batches.length) // we've received all the results. put to map
                  {
                    // sort the returned values into their correct order
                    unsortedResults.sort(function(a, b) {
                      return parseFloat(a.order) - parseFloat(b.order);
                    });
                    var count = 0;
                    for (var key in unsortedResults) {
                      if (unsortedResults[key].result != null) {
                        if (unsortedResults.hasOwnProperty(key)) {
                          if (count == 0) // first results. new up the combinedResults object
                            combinedResults = unsortedResults[key].result;
                          else {
                            // only building up legs, overview_path, and bounds in my consolidated object. This is not a complete
                            // directionResults object, but enough to draw a path on the map, which is all I need
                            combinedResults.routes[0].legs = combinedResults.routes[0].legs.concat(unsortedResults[key].result.routes[0].legs);
                            combinedResults.routes[0].overview_path = combinedResults.routes[0].overview_path.concat(unsortedResults[key].result.routes[0].overview_path);
    
                            combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getNorthEast());
                            combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getSouthWest());
                          }
                          count++;
                        }
                      }
                    }
                    directionsDisplay.setDirections(combinedResults);
                    var legs = combinedResults.routes[0].legs;
                    // alert(legs.length);
                    for (var i = 0; i < legs.length; i++) {
                      var markerletter = "A".charCodeAt(0);
                      markerletter += i;
                      markerletter = String.fromCharCode(markerletter);
                      createMarker(directionsDisplay.getMap(), legs[i].start_location, "marker" + i, "some text for marker " + i + "<br>" + legs[i].start_address, markerletter);
                    }
                    var i = legs.length;
                    var markerletter = "A".charCodeAt(0);
                    markerletter += i;
                    markerletter = String.fromCharCode(markerletter);
                    createMarker(directionsDisplay.getMap(), legs[legs.length - 1].end_location, "marker" + i, "some text for the " + i + "marker<br>" + legs[legs.length - 1].end_address, markerletter);
                  }
                }
              });
            })(k);
          }
        }
      };
    }
    var infowindow = new google.maps.InfoWindow({
      size: new google.maps.Size(150, 50)
    });
    
    var icons = new Array();
    icons["red"] = new google.maps.MarkerImage("mapIcons/marker_red.png",
      // This marker is 20 pixels wide by 34 pixels tall.
      new google.maps.Size(20, 34),
      // The origin for this image is 0,0.
      new google.maps.Point(0, 0),
      // The anchor for this image is at 9,34.
      new google.maps.Point(9, 34));
    
    
    
    function getMarkerImage(iconStr) {
        if ((typeof(iconStr) == "undefined") || (iconStr == null)) {
          iconStr = "red";
        }
        if (!icons[iconStr]) {
          icons[iconStr] = new google.maps.MarkerImage("http://www.google.com/mapfiles/marker" + iconStr + ".png",
            // This marker is 20 pixels wide by 34 pixels tall.
            new google.maps.Size(20, 34),
            // The origin for this image is 0,0.
            new google.maps.Point(0, 0),
            // The anchor for this image is at 6,20.
            new google.maps.Point(9, 34));
        }
        return icons[iconStr];
    
      }
      // Marker sizes are expressed as a Size of X,Y
      // where the origin of the image (0,0) is located
      // in the top left of the image.
    
    // Origins, anchor positions and coordinates of the marker
    // increase in the X direction to the right and in
    // the Y direction down.
    
    var iconImage = new google.maps.MarkerImage('mapIcons/marker_red.png',
      // This marker is 20 pixels wide by 34 pixels tall.
      new google.maps.Size(20, 34),
      // The origin for this image is 0,0.
      new google.maps.Point(0, 0),
      // The anchor for this image is at 9,34.
      new google.maps.Point(9, 34));
    var iconShadow = new google.maps.MarkerImage('http://www.google.com/mapfiles/shadow50.png',
      // The shadow image is larger in the horizontal dimension
      // while the position and offset are the same as for the main image.
      new google.maps.Size(37, 34),
      new google.maps.Point(0, 0),
      new google.maps.Point(9, 34));
    // Shapes define the clickable region of the icon.
    // The type defines an HTML &lt;area&gt; element 'poly' which
    // traces out a polygon as a series of X,Y points. The final
    // coordinate closes the poly by connecting to the first
    // coordinate.
    var iconShape = {
      coord: [9, 0, 6, 1, 4, 2, 2, 4, 0, 8, 0, 12, 1, 14, 2, 16, 5, 19, 7, 23, 8, 26, 9, 30, 9, 34, 11, 34, 11, 30, 12, 26, 13, 24, 14, 21, 16, 18, 18, 16, 20, 12, 20, 8, 18, 4, 16, 2, 15, 1, 13, 0],
      type: 'poly'
    };
    
    
    function createMarker(map, latlng, label, html, color) {
      // alert("createMarker("+latlng+","+label+","+html+","+color+")");
      var contentString = '<b>' + label + '</b><br>' + html;
      var marker = new google.maps.Marker({
        position: latlng,
        map: map,
        shadow: iconShadow,
        icon: getMarkerImage(color),
        shape: iconShape,
        title: label,
        zIndex: Math.round(latlng.lat() * -100000) << 5
      });
      marker.myname = label;
    
      google.maps.event.addListener(marker, 'click', function() {
        infowindow.setContent(contentString);
        infowindow.open(map, marker);
      });
      return marker;
    }
    
    
    function Call2function() {
    
        var msg = "41.077354,-81.511337:41.080647,-81.516579:41.077435,-81.521561:41.075253,-81.521492:41.074604,-81.520309:41.07415,-81.516335:41.073158,-81.514931:41.070534,-81.516563:41.066677,-81.516502:41.063942,-81.516502:41.06514,-81.513458:41.067383,-81.513412:41.069546,-81.513397:41.070778,-81.513382:41.072514,-81.512619:41.071106,-81.507614:41.073326,-81.506195:41.075886,-81.506058:41.077274,-81.507652:41.077354,-81.511337";
        var input_msg = msg.split(":");
        var mylatlongg = new Array();
        latlongg = input_msg[0].split(",");
    
        var mapOptions = {
          center: new google.maps.LatLng(mylatlongg[0], mylatlongg[1]),
          zoom: 12,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
        var infoWindow = new google.maps.InfoWindow();
        var lat_lng = new Array();
        var latlngbounds = new google.maps.LatLngBounds();
        document.getElementById('info').innerHTML = "total points: " + input_msg.length + "<br>";
        for (i = 0; i < input_msg.length; i++) {
          var data = input_msg[i];
          var laaty = input_msg[i].split(",")
          var myLatlng = new google.maps.LatLng(laaty[0], laaty[1]);
          lat_lng.push(myLatlng);
          var marker = new google.maps.Marker({
            position: myLatlng,
            map: map,
            title: 'location'
          });
          latlngbounds.extend(marker.position);
        }
        map.setCenter(latlngbounds.getCenter());
        map.fitBounds(latlngbounds);
    
        //***********ROUTING****************//
    
        //Intialize the Path Array
        var path = new google.maps.MVCArray();
    
        //Intialize the Direction Service
        var service = new google.maps.DirectionsService();
    
        //Set the Path Stroke Color
        var poly = new google.maps.Polyline({
          map: map,
          strokeColor: '#4986E7'
        });
    
        //Loop and Draw Path Route between the Points on MAP
        for (var i = 0; i < lat_lng.length; i++) {
          if ((i + 1) < lat_lng.length) {
            var src = lat_lng[i];
            var des = lat_lng[i + 1];
            // path.push(src);
            poly.setPath(path);
            service.route({
              origin: src,
              destination: des,
              travelMode: google.maps.DirectionsTravelMode.DRIVING
            }, function(result, status) {
              if (status == google.maps.DirectionsStatus.OK) {
                for (var i = 0, len = result.routes[0].overview_path.length; i < len; i++) {
                  path.push(result.routes[0].overview_path[i]);
                }
              } else {
                document.getElementById('info').innerHTML += status + "<br>";
              }
            });
          }
        }
      }
      // google.maps.event.addDomListener(window, 'load', Call2function);
    html,
    body,
    #map_canvas {
      height: 500px;
      width: 500px;
      margin: 0px;
      padding: 0px
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://maps.googleapis.com/maps/api/js"></script>
    <div id="dvMap" style="width: 600px; height: 600px"></div>
    <div id="info"></div>

    【讨论】:

    • 感谢 geocodezip:OVER_QUERY_LIMIT 有什么解决方法吗?比如休眠 10 秒,稍后再尝试连接路由?
    • 解决地理编码器的 OVER_QUERY_LIMIT 状态的方法应该适用。您需要使用多少积分?如果它是您的样本中的数字,您可以使用航路点和my answer to this question 中描述的方法。
    猜你喜欢
    • 1970-01-01
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多