luoxuancong

luoxuancong

Gaode Map generates route plans with more than 16 waypoints (VUE technology stack)

<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?2aeca2dc0b3e03b3ed85e50251925ecf";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>

### Development Requirements


> Recently, a project for assembly transportation was completed, which includes a function for [route planning]. After the user inputs the starting point and destination, a navigation route is generated by default. It is necessary to set waypoints to reasonably plan the map route, and speed limits need to be set for each waypoint.



### Implementation Process


#### 1. Complete by generating waypoints through the drag-and-drop feature provided by Amap

​	[Amap Map Draggable Route Planning](https://lbs.amap.com/api/javascript-api/example/driving-route/route-can-be-dragged)

``` js
<script type="text/javascript">
    var map, route, marker;
    // Basic map loading
    map = new AMap.Map("container", {
        resizeEnable: true
    });
    // Draw initial path
    var path = [];
    path.push([116.303843, 39.983412]);
    path.push([116.321354, 39.896436]);
    path.push([116.407012, 39.992093]);
    map.plugin("AMap.DragRoute", function() {
        route = new AMap.DragRoute(map, path, AMap.DrivingPolicy.LEAST_FEE); // Construct drag navigation class
        route.search(); // Query navigation path and start drag navigation
    });
</script>

The official demo is quite powerful, achieving draggable functionality with just a few lines of code, and my first reaction was to use this, as the basic functionality meets the requirements.

The official implementation effect is as follows:

Draggable waypoint image

When implementing the speed limit setting for the clicked waypoints, I surprisingly found that the official API does not provide a callback method for these generated waypoints, which is a bit of a pitfall.

Setting the click method for waypoints

// Use the official mousemove method to get the current mouse position on the map in real-time
triggerClick() {
  const that = this
  that.map.on('mousemove', function(ev) {
  	var lnglat = ev.lnglat
  	that.currentLngLat = lnglat // Save the latitude and longitude information
	})
},
addMarkerClick() { // Define the click method
      const that = this
      var infoWindow = new that.AMap.InfoWindow({
        offset: new that.AMap.Pixel(0, -20)
      })
      // Get the marker points on the map

      setTimeout(() => {
        var dom = document.getElementById('container').getElementsByClassName('amap-marker') // Get all waypoint DOMs on the map
        dom = Array.from(dom).filter((item) => {
          if (item.style.display !== 'none') {
            return item
          }
        })
        dom.forEach((item, index) => { // Iterate over DOM
          const img = item.getElementsByTagName('img')[0]
          if (img) {
            img.onclick = (e) => { // Marker click event
              const list = [ // Latitude and longitude array format data
                that.currentLngLat.lng,
                that.currentLngLat.lat
              ]
              const distanceList = this.mapData.waypoints.map(item => { // Get the distance list from each waypoint to the current point
                const p = [item.lng, item.lat]
                return that.AMap.GeometryUtil.distance(list, p)
              })
              const min = Math.min.apply(null, distanceList) // Get the closest point to the current position
              const index = distanceList.indexOf(min) // Get the index
              const currentPoint = this.mapData.waypoints[index] // Get the latitude and longitude data of the clicked waypoint
              const LngLat = new that.AMap.LngLat(currentPoint.lng, currentPoint.lat)
              infoWindow.setMap(that.map)
              // Set the content to display in the marker information
              const speedLimit = currentPoint.speedLimit ? currentPoint.speedLimit + 'KM' : 'Not set'
              infoWindow.setContent(
                '<b>Alarm Information &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</b>  <br/><br/>' +
            '<b> Speed Limit: </b> <span class="speed-input">' + speedLimit + '</span><br/><br/>' +
            `<button id="closeBtn" type="button" class="el-button el-button--small" "><span>Close</span></button> <button id="editBtn" type="button" class="el-button el-button--primary el-button--small"><span>Set</span></button>`
              )
              infoWindow.open(that.map, LngLat) // Open the popup message
              setTimeout(() => {
                document.getElementById('closeBtn').onclick = () => {
                  infoWindow.close()
                }
                document.getElementById('editBtn').onclick = () => {
                  that.limitSet(index)
                }
              }, 500)
            }
          }
        })
      }, 500)
   }

At this point, the desired effect can basically be achieved.

Draggable point effect

However, due to the limitations of the official API, when I exceed sixteen waypoints, the following situation occurs.

More than sixteen points

When there are more than sixteen points, the previous points are no longer within the route planning range, which is definitely not acceptable.

2. Abandon the official drag method to implement waypoint planning routes#

Due to time constraints, I will first showcase the final completed effect, and the specific implementation method will be improved next time.

Final effect diagram

3. Source Code#

Today I spent some time organizing the map demo, and the basic functionality has been released. Everyone can adjust the specific business logic according to their needs.
GitHub source code address
Basic interaction

Route detail display

4. Preview Address#

Demo preview address

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.