Automatic generation of electronic fence from Gaode map

Time:2021-2-27

Automatic drawing of electronic fence by using JS API of Gaode map
Because it is not accurate to draw polygon directly, we need to draw fence along the road

E-fence idea:

1. Find the origin latitude and longitude X
const CENTER = [116.397504,39.89619]  
Const distance = 300 // unit M  

const map = new AMap.Map("container", {
    center: CENTER,
    zoom: 14
});
2. Draw a circle on the map according to point X
const circle = new AMap.Circle({
    center: CENTER,
    Radius: distance, // radius
    borderWeight: 3,
    strokeColor: "#FF33FF", 
    strokeOpacity: 1,
    strokeWeight: 6,
    strokeOpacity: 0.2,
    fillOpacity: 0.4,
    strokeStyle: 'dashed',
    strokeDasharray: [10, 10], 
    fillColor: '#1791fc',
    zIndex: 50
})
circle.setMap(map)
//Zoom the map to the appropriate view level
map.setFitView([ circle ])

reference resources:
https://lbs.amap.com/api/java…

3. On the circular sideline, find out the positions in eight directions: East, Southeast, South, southwest, West, northwest, North and northeast

Get the longitude and latitude of x1, Y1 ~ X8, Y8, 8 positions, defined as the coordinates of A1 ~ A8

First, according to the formula of the circle, find the points on the circle, and then convert the points into the longitude and latitude of the map

/**
 * 
 *Get the point on the circle (step size 45 degrees)
 *
 **/
function setCirclePoint(centerpoint = CENTER, radius = DISTANCE) {
    Const r = 6371000; // average radius of the earth
    const numpoints = 360;
    const phase = 2 * Math.PI / numpoints;
    let pointArr = []

    //Draw a dot
    for (let i = 0; i < numpoints; i+=45) {
        //Calculate coordinate points
        let dx = (radius * Math.cos(i * phase));
        let dy = (radius * Math.sin(i * phase));
        
        //Convert to latitude and longitude
        let dlng = dx / (r * Math.cos(centerpoint.lat * Math.PI / 180) * Math.PI / 180);
        let dlat = dy / (r * Math.PI / 180);
        let newlng = centerpoint.lng + dlng;
        let newlag = centerpoint.lat + dlat;
        pointArr.push([newlng,newlag])

        //Instantiation point marker
        const marker = new AMap.Marker({
            position: [newlng, newlag],
            icon: startIcon,
            offset: new AMap.Pixel(-13, -30)
        });
        markers.push(marker);
        marker.setMap(map);
    }
    return pointArr
}

As shown in the figure:
Automatic generation of electronic fence from Gaode map

reference resources:
https://blog.csdn.net/jinshit…
https://blog.csdn.net/Dust_Ev…
https://lbs.amap.com/api/andr…

4. Search the nearest POI points from A1 to A8, A1 = International Trade phase III, A2 = Dongzhimen, A3 = Olympic Forest Park…. reason by analogy
//Gaode map query
    function aMapSearchNearBy(centerPoint) {
        return new Promise((resolve,reject)=>{
            AMap.service(["AMap.PlaceSearch"], () => {
                const placeSearch = new AMap.PlaceSearch({
                    PageSize: 10, // 10 items per page
                    PageIndex: 1, // get the first page
                });

                //The first parameter is the keyword. The empty parameter passed in here does not need to be filtered according to the keyword
                //The second parameter is latitude and longitude, array type
                //The third parameter is the radius, the perimeter
                //The fourth parameter is the callback function
                placeSearch.searchNearBy('', centerPoint, 1000, (status, result) => {
                    if(result.info === 'OK') {
                        const locationList =  result.poiList.pois ; // list of surrounding landmark buildings
                        resolve(locationList[0])
                        
                    } else {
                        console.log ('Get location information failed! ");
                        reject()
                    }
                });
            });
        })
    }

Because the results of POI must be returned in a1-a8 order, and Gaode API is asynchronous, promise is used for synchronous processing

//Get POI information
const POIArr = await Promise.all(points.map(async (item)=>{
    return await aMapSearchNearBy(item)
}))

reference resources:
https://lbs.amap.com/api/java…

5. Connect the eight POI points in turn (a1-a2, A2-A3, a3-a4,… A8-a1) and draw (walk) the navigation path to get the eight paths l1-l8
/**
     *Route (walking)
    */
    function drawWalk(data, i){
        return new Promise((resolve,reject)=>{
            //Pedestrian navigation
            const walking = new AMap.Walking({
                map: map,
                panel: "panel",
                Hidemarkers: true, // sets the starting point icon of hidden path planning
            }); 

            let start = [POIArr[i].location.lng, POIArr[i].location.lat]
            let end = i === POIArr.length-1 ? [POIArr[0].location.lng, POIArr[0].location.lat] : [POIArr[i+1].location.lng, POIArr[i+1].location.lat]
            

            //Planning the walking route according to the coordinates of starting and ending points
            walking.search(start, end, (status, result) => {
                resolve(result)
                if (status === 'complete') {
                    log.success ('draw walking route completed ')
                } else {
                    log.error ('pedestrian route data query failed '+ result)
                } 
            });
        });
    }

Draw the walking path in turn

const walkRes = await Promise.all(POIArr.map(async (item, index)=>{
    return await drawWalk(item, index)
}))

As shown in the figure:

Automatic generation of electronic fence from Gaode map
reference resources:
https://lbs.amap.com/api/java…

6. Store inflection points of 8 routes

According to the information returned by each walking path, find the inflection point of the road, and save it. Before saving, it needs to be removed.

    walkRes.map((key)=>{
        const steps = key.routes[0].steps
        steps.map((item, index)=>{
            item.path.map((pos)=>{
                formatData(pos)
            })
        })
    })

Automatic generation of electronic fence from Gaode map

7. Verify whether the saved inflection point data and the drawn polygon are consistent with the route

The first value is start under the steps attribute_ Location, but as shown in the figure below

Automatic generation of electronic fence from Gaode map
But not along the road, there are also some inflection points missing

Take the route in the path under steps for the second time and get it done

Automatic generation of electronic fence from Gaode map

8. Finish.

Note: the code is incomplete, for reference only