在绘制源和目的地之间的路径并连接所有点(城市)时,在 google 地图路径中出现意外线条

Getting unexpected lines in google map path when drawing path between source and destination and connecting all points(cities)

Note:click on View on Google Map button only after entering source and destination and add route points only after entering source and destination and dont left any route points textbox blank(i.e dynamic textbox)

源代码取自 geocodezip:Inconsistent behaviour drawing a route between two points in Google Maps v3

回答的源代码

// Code goes here

 var cnt = 1;
    var autocomplete = [];
    var marker = [];
    var markers = [];
    var usedIds = [];
   var map = null;
    var maxNumberOfTextboxAllowed = 5;
    var insertTextboxId = [];

  google.maps.event.addDomListener(window, 'load', function () {
        var places = new google.maps.places.Autocomplete(document.getElementById('source'));
        google.maps.event.addListener(places, 'place_changed', function () {
            var place = places.getPlace();
            var data=
                     {
                         "LocationName": document.getElementById("source").value,
                         "lat": place.geometry.location.lat().toString(),
                         "lng": place.geometry.location.lng().toString()
                     }
            if (markers.length > 0)
            {
                markers.splice(0, 1, data)
            }
            else
                markers.splice(0, 0, data);// splice(position, numberOfItemsToRemove, item)
        });
        var places1 = new google.maps.places.Autocomplete(document.getElementById('destination'));
        google.maps.event.addListener(places1, 'place_changed', function () {
            var place1 = places1.getPlace();
            var data =
                     {
                         "LocationName": document.getElementById("destination").value,
                         "lat": place1.geometry.location.lat().toString(),
                         "lng": place1.geometry.location.lng().toString()
                     }
            if (markers.length == 1) {
                markers.splice(1, 1, data);
            }
            else if(markers.length > 0)
              markers.splice(markers.length - 1, 1, data)
        });
    });





function GenerateSourceDestinationPoint() {
  if (cnt <= maxNumberOfTextboxAllowed) {
    var fieldWrapper = $("<div class='fieldwrapper' id='field" + cnt + "'/>");
    var fName = $("<input type='text' class='fieldname' id='Txtopt" + cnt + "'  name='TxtoptNm" + cnt + "'  />");
    fieldWrapper.append(fName);
    fieldWrapper.append('<br />');
    fieldWrapper.append('<br />');
    $("#abc").append(fieldWrapper);
    var newInput = [];
    var newEl = document.getElementById('Txtopt' + cnt);
    var txtboxId = 'Txtopt' + cnt;
    newInput.push(newEl);
    setupAutocomplete(autocomplete, newInput, 0, txtboxId);
    cnt = cnt + 1;
  } else
    alert("Cant create more than 5 textbox")
}

function setupAutocomplete(autocomplete, inputs, i, txtboxId) {
        insertTextboxId.push(txtboxId)
        autocomplete.push(new google.maps.places.Autocomplete(inputs[i]));
         var idx1 = autocomplete.length - 1;
        var idx = markers.length - 1;
        markers[idx + 1] = markers[idx];
        markers[idx] = {};
        google.maps.event.addListener(autocomplete[idx1], 'place_changed', function () {
            var pos = idx1 + 1;
            var place = autocomplete[idx1].getPlace();
            if (!place.geometry) {
                return;
         }
    var autoTextbox=
        {
          "LocationName": document.getElementById(insertTextboxId[idx1]).value,
                                   "lat":autocomplete[idx1].getPlace().geometry.location.lat().toString(),
 "lng": autocomplete[idx1].getPlace().geometry.location.lng().toString()
        }
            markers[idx] = autoTextbox;
            initialize();
        });
    }

   function initialize() {
        var bounds = new google.maps.LatLngBounds();
        var mapOptions = {
            center: new google.maps.LatLng(parseFloat(markers[0].lat), parseFloat(markers[0].lng)),
            zoom: 10,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        var path = new google.maps.MVCArray();
        var service = new google.maps.DirectionsService();

        var infoWindow = new google.maps.InfoWindow();
        map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
        var poly = new google.maps.Polyline({
            map: map,
            strokeColor: '#F3443C'
        });
        var lat_lng = new Array();
        var marker = new google.maps.Marker({
        position: map.getCenter(),
            map: map
        });
        bounds.extend(marker.getPosition());
        for (var i = 0; i < markers.length; i++) {
            if ((i + 1) < markers.length) {
                var src = new google.maps.LatLng(parseFloat(markers[i].lat),
                                                 parseFloat(markers[i].lng));
                var smarker = new google.maps.Marker({ position: src, map: map });
                bounds.extend(smarker.getPosition());
                var des = new google.maps.LatLng(parseFloat(markers[i + 1].lat),
                                                 parseFloat(markers[i + 1].lng));
                var dmarker = new google.maps.Marker({ position: des, map: map });
                bounds.extend(dmarker.getPosition());
                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]);
                        }
                        poly.setPath(path);
                        map.fitBounds(bounds);
                    }
                });
            }
        }
    }
  html, body, #map_canvas {
        height: 100% !important;
        margin: 0 !important;
        padding: 0 !important;
    }

    #panel {
        position: absolute;
        top: 5px;
        left: 50%;
        margin-left: -180px;
        z-index: 5;
        background-color: #fff;
        padding: 5px;
        border: 1px solid #999;
    }

    /*
        Provide the following styles for both ID and class,
        where ID represents an actual existing "panel" with
        JS bound to its name, and the class is just non-map
        content that may already have a different ID with
        JS bound to its name.
        */

    #panel, .panel {
        font-family: 'Roboto','sans-serif';
        line-height: 30px;
        padding-left: 10px;
    }

        #panel select, #panel input, .panel select, .panel input {
            font-size: 15px;
        }

        #panel select, .panel select {
            width: 100%;
        }

        #panel i, .panel i {
            font-size: 12px;
        }
 <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?v=3.exp&signed_in=true&libraries=places,geometry"></script>
<input type="button" onclick="initialize()" value="View on Google Map" />

    <br /><br />
    <label>Source</label>
    <input type="text" value="" name="source" id="source">
    <br /><br />
    <label>Destination</label>
    <input type="text" value="" name="destination" id="destination">
    <br /><br />
    <button onclick="GenerateSourceDestinationPoint()" class="btn btn-primary" type="button" >Add Points</button>
    <div style="border: 1px solid -moz-nativehyperlinktext;"></div>
    <div id="abc">
    </div>

    <br /><br />
    <div style="height:400px;width:1000px">
        <div id="map_canvas"></div>
    </div>

我想在源和目的地之间绘制路径,并连接源和目的地之间的所有点(即城市)

对于Eg:If,我的来源是英国斯旺西,目的地是英国伦敦,我的路线点如下这个:

1)添加第一条路线点即英国加的夫。趋于完美输出如下:

2)添加第二条路线点即英国纽波特.完善输出如下:

3)添加第三条路线点即英国巴斯.趋于完美输出如下:

4)现在当我改变我的 2nd 路线点时问题来了 英国纽波特英国布里斯托尔 然后我在 google 地图中得到意想不到的线条,如下所示:

5)预期输出:

问题:地理编码异步运行。无法保证路由回调将按所需顺序执行。

当你得到这些直线时,顺序将被混淆(也发生在原始演示中),因为你总是将 overview_polyline 附加到路径。

您必须先创建整个路径(以正确的顺序),然​​后绘制多段线。

但是:

  1. 总是创建一个新地图不是一个好方法(这会影响你的地图加载配额)
  2. 当您将 waypoints 限制为 5 时,您可以使用 DirectionsService 请求完整路线(最多 8 waypoints 是可能的)

如果您需要 waypoints,请将其包含在路线服务请求中。您的问题是将路线的各个部分放在一起。

function initialize() {
    var bounds = new google.maps.LatLngBounds();
    var mapOptions = {
        center: new google.maps.LatLng(parseFloat(markers[0].lat), parseFloat(markers[0].lng)),
        zoom: 10,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    var path = new google.maps.MVCArray();
    var service = new google.maps.DirectionsService();

    var infoWindow = new google.maps.InfoWindow();
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
    var poly = new google.maps.Polyline({
        map: map,
        strokeColor: '#F3443C'
    });
    var lat_lng = [];
    var marker = new google.maps.Marker({
    position: map.getCenter(),
        map: map
    });
    bounds.extend(marker.getPosition()); 
   var src,des;
   var waypoints = [];

    for (var i = 0; i < markers.length; i++) {
        if (i===0) {
            src = new google.maps.LatLng(parseFloat(markers[i].lat),
                                             parseFloat(markers[i].lng));
            var smarker = new google.maps.Marker({ position: src, map: map });
            bounds.extend(smarker.getPosition());
        } else if (i==markers.length-1) {
            des = new google.maps.LatLng(parseFloat(markers[i].lat),
                                             parseFloat(markers[i].lng));
            var dmarker = new google.maps.Marker({ position: des, map: map });
            bounds.extend(dmarker.getPosition());
        } else {
            var latlng = new google.maps.LatLng(markers[i].lat, markers[i].lng);
            waypoints.push({location: latlng,
                            stopover:true});
            var marker = new google.maps.Marker({
                position: latlng,
                map: map
            });
        }
    }
            service.route({
                origin: src,
                destination: des,
                waypoints: waypoints,
                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]);
                    }
                    poly.setPath(path);
                    map.fitBounds(bounds);
                }
            });
        }

proof of concept fiddle

代码片段:

var cnt = 1;
var autocomplete = [];
var marker = [];
var markers = [];
var usedIds = [];
var map = null;
var maxNumberOfTextboxAllowed = 5;
var insertTextboxId = [];

google.maps.event.addDomListener(window, 'load', function() {
  var places = new google.maps.places.Autocomplete(document.getElementById('source'));
  google.maps.event.addListener(places, 'place_changed', function() {
    var place = places.getPlace();
    var data = {
      "LocationName": document.getElementById("source").value,
      "lat": place.geometry.location.lat().toString(),
      "lng": place.geometry.location.lng().toString()
    };
    if (markers.length > 0) {
      markers.splice(0, 1, data);
    } else
      markers.splice(0, 0, data); // splice(position, numberOfItemsToRemove, item)
  });
  var places1 = new google.maps.places.Autocomplete(document.getElementById('destination'));
  google.maps.event.addListener(places1, 'place_changed', function() {
    var place1 = places1.getPlace();
    var data = {
      "LocationName": document.getElementById("destination").value,
      "lat": place1.geometry.location.lat().toString(),
      "lng": place1.geometry.location.lng().toString()
    }
    if (markers.length == 1) {
      markers.splice(1, 1, data);
    } else if (markers.length > 0)
      markers.splice(markers.length - 1, 1, data)
  });
});





function GenerateSourceDestinationPoint() {
  if (cnt <= maxNumberOfTextboxAllowed) {
    var fieldWrapper = $("<div class='fieldwrapper' id='field" + cnt + "'/>");
    var valueStr;
    if (cnt == 1) {
      valueStr = "Cardiff, UK";
    } else if (cnt == 2) {
      valueStr = "Newport, UK";
    } else if (cnt == 3) {
      valueStr = "Bath, UK";
    } else {
      valueStr = "";
    }
    var fName = $("<input type='text' class='fieldname' id='Txtopt" + cnt + "'  name='TxtoptNm" + cnt + "' value='" + valueStr + "' />");
    fieldWrapper.append(fName);
    fieldWrapper.append('<br />');
    fieldWrapper.append('<br />');
    $("#abc").append(fieldWrapper);
    var newInput = [];
    var newEl = document.getElementById('Txtopt' + cnt);
    var txtboxId = 'Txtopt' + cnt;
    newInput.push(newEl);
    setupAutocomplete(autocomplete, newInput, 0, txtboxId);
    cnt = cnt + 1;
  } else
    alert("Cant create more than 5 textbox");
}

function setupAutocomplete(autocomplete, inputs, i, txtboxId) {
  insertTextboxId.push(txtboxId);
  autocomplete.push(new google.maps.places.Autocomplete(inputs[i]));
  var idx1 = autocomplete.length - 1;
  var idx = markers.length - 1;
  markers[idx + 1] = markers[idx];
  markers[idx] = {};
  google.maps.event.addListener(autocomplete[idx1], 'place_changed', function() {
    var pos = idx1 + 1;
    var place = autocomplete[idx1].getPlace();
    if (!place.geometry) {
      return;
    }
    var autoTextbox = {
      "LocationName": document.getElementById(insertTextboxId[idx1]).value,
      "lat": autocomplete[idx1].getPlace().geometry.location.lat().toString(),
      "lng": autocomplete[idx1].getPlace().geometry.location.lng().toString()
    }
    markers[idx] = autoTextbox;
    initialize();
  });
}

function initialize() {
  var bounds = new google.maps.LatLngBounds();
  var mapOptions = {
    center: new google.maps.LatLng(parseFloat(markers[0].lat), parseFloat(markers[0].lng)),
    zoom: 10,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  var path = new google.maps.MVCArray();
  var service = new google.maps.DirectionsService();

  var infoWindow = new google.maps.InfoWindow();
  map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
  var poly = new google.maps.Polyline({
    map: map,
    strokeColor: '#F3443C'
  });
  var lat_lng = [];
  var marker = new google.maps.Marker({
    position: map.getCenter(),
    map: map
  });
  bounds.extend(marker.getPosition());
  var src, des;
  var waypoints = [];

  for (var i = 0; i < markers.length; i++) {
    if (i === 0) {
      src = new google.maps.LatLng(parseFloat(markers[i].lat),
        parseFloat(markers[i].lng));
      var smarker = new google.maps.Marker({
        position: src,
        map: map
      });
      bounds.extend(smarker.getPosition());
    } else if (i == markers.length - 1) {
      des = new google.maps.LatLng(parseFloat(markers[i].lat),
        parseFloat(markers[i].lng));
      var dmarker = new google.maps.Marker({
        position: des,
        map: map
      });
      bounds.extend(dmarker.getPosition());
    } else {
      var latlng = new google.maps.LatLng(markers[i].lat, markers[i].lng);
      waypoints.push({
        location: latlng,
        stopover: true
      });
      var marker = new google.maps.Marker({
        position: latlng,
        map: map
      });
    }
  }
  service.route({
    origin: src,
    destination: des,
    waypoints: waypoints,
    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]);
      }
      poly.setPath(path);
      map.fitBounds(bounds);
    }
  });
}
html,
body,
#map_canvas {
  height: 100% !important;
  margin: 0 !important;
  padding: 0 !important;
}
#panel {
  position: absolute;
  top: 5px;
  left: 50%;
  margin-left: -180px;
  z-index: 5;
  background-color: #fff;
  padding: 5px;
  border: 1px solid #999;
}
/*
        Provide the following styles for both ID and class,
        where ID represents an actual existing "panel" with
        JS bound to its name, and the class is just non-map
        content that may already have a different ID with
        JS bound to its name.
        */

#panel,
.panel {
  font-family: 'Roboto', 'sans-serif';
  line-height: 30px;
  padding-left: 10px;
}
#panel select,
#panel input,
.panel select,
.panel input {
  font-size: 15px;
}
#panel select,
.panel select {
  width: 100%;
}
#panel i,
.panel i {
  font-size: 12px;
}
<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?sensor=false&libraries=geometry,places&ext=.js"></script>
<input type="button" onclick="initialize()" value="View on Google Map" />

<br />
<br />
<label>Source</label>
<input type="text" value="Swansea, UK" name="source" id="source">
<br />
<br />
<label>Destination</label>
<input type="text" value="London, UK" name="destination" id="destination">
<br />
<br />
<button onclick="GenerateSourceDestinationPoint()" class="btn btn-primary" type="button">Add Points</button>
<div style="border: 1px solid -moz-nativehyperlinktext;"></div>
<div id="abc">
</div>

<br />
<br />
<div style="height:400px;width:600px">
  <div id="map_canvas"></div>
</div>