利用高德地图 API自动生成电子围栏

大致思路

  • 绘制和导航 需要高德 KEY 自己去注册申请
  • 使用高德步行导航找到围栏的多边形的拐点
  • 绘制多边形

小试牛刀 利用高德地图在紫禁城画个圈

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
    <style>
        html,
        body,
        #container {
            width: 100%;
            height: 100%;
        }
    </style>
    <title>紫禁城画个圆圈</title>
    <link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css"/>
    <script src="https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值&plugin=AMap.CircleEditor"></script>
    <script src="https://a.amap.com/jsapi_demos/static/demo-center/js/demoutils.js"></script>
</head>
<body>
<div id="container"></div>
<div class="input-card" style="width: 120px">
    <button class="btn" onclick="circleEditor.open()" style="margin-bottom: 5px">开始编辑</button>
    <button class="btn" onclick="circleEditor.close()">结束编辑</button>
</div>
<script type="text/javascript">
    let map = new AMap.Map("container", {
        center: [116.433322, 39.900256],
        zoom: 14
    });
    let circle = new AMap.Circle({
        center: [116.433322, 39.900255],
        radius: 1000,
        borderWeight: 3,
        strokeColor: "#FF33FF",
        strokeOpacity: 1,
        strokeWeight: 6,
        fillOpacity: 0.4,
        strokeStyle: 'dashed',
        strokeDasharray: [10, 10],
        fillColor: '#1791fc',
        zIndex: 50,
    })
    circle.setMap(map)
    map.setFitView([circle])


</script>
</body>
</html>

电子围栏的大概的点
  • 圆圈的 45 度角均匀的 分布 8 个点
<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
    <style>
        html,
        body,
        #container {
            width: 100%;
            height: 100%;
        }

        #panel {
            position: fixed;
            background-color: white;
            max-height: 90%;
            overflow-y: auto;
            top: 10px;
            right: 10px;
            width: 280px;
        }

        #panel .amap-call {
            background-color: #009cf9;
            border-top-left-radius: 4px;
            border-top-right-radius: 4px;
        }

        #panel .amap-lib-walking {
            border-bottom-left-radius: 4px;
            border-bottom-right-radius: 4px;
            overflow: hidden;
        }
    </style>
    <title>电子围栏定位</title>
    <script type="text/javascript">
        window._AMapSecurityConfig = {
            securityJsCode: '5dfaddb510ffa01104ce9c25166f7f53',
        }
    </script>
    <link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css"/>
    <script src="https://webapi.amap.com/maps?v=1.4.15&key=8ed6ab55d9456bfe6c1d020ce9b2a1c9&plugin=AMap.MouseTool"></script>
    <script src="https://a.amap.com/jsapi_demos/static/demo-center/js/demoutils.js"></script>
</head>
<body>
<div id="container"></div>
<div id="panel"></div>
<script type="text/javascript">

    const lng = 116.397504
    const lat = 39.89619
    const map = new AMap.Map("container", {
        center: [lng, lat],
        zoom: 14,
        resizeEnable: true
    });

    let circle = new AMap.Circle({
        center: [lng, lat],
        radius: 300,
        borderWeight: 3,
        strokeColor: "#3355ff",
        strokeOpacity: 1,
        strokeWeight: 6,
        fillOpacity: 0.4,
        strokeStyle: 'solid',
        strokeDasharray: [10, 10],
        fillColor: '#ffffff',
        zIndex: 50,
    })
    const r = 6371000;
    const phase = 2 * Math.PI / 360;
    let pointArr = []
    let LngLatArr = []
    for (let i = 0; i < 360; i += 45) {

        let newLng = lng + ((300 * Math.cos(i * phase))) / (r * Math.cos(lat * Math.PI / 180) * Math.PI / 180);
        let newLag = lat + ((300 * Math.sin(i * phase))) / (r * Math.PI / 180);
        LngLatArr.push([newLng, newLag])

        let startIcon = new AMap.Icon({
            size: new AMap.Size(25, 34),
            image: 'https://a.amap.com/jsapi_demos/static/demo-center/icons/dir-marker.png',
            imageSize: new AMap.Size(135, 40),
            imageOffset: new AMap.Pixel(-9, -3)
        });
        const marker = new AMap.Marker({
            position: [newLng, newLag],
            icon: startIcon,
            offset: new AMap.Pixel(-13, -30)
        });
        pointArr.push(marker)
    }

    map.add(pointArr)
    circle.setMap(map)
    map.setFitView([circle])


</script>
</body>
</html>

在八个点之间 使用到步行导航确定电子围栏的外围部分

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
    <style>
        html,
        body,
        #container {
            width: 100%;
            height: 100%;
        }

        #panel {
            position: fixed;
            background-color: white;
            max-height: 90%;
            overflow-y: auto;
            top: 10px;
            right: 10px;
            width: 280px;
        }

        #panel .amap-call {
            background-color: #009cf9;
            border-top-left-radius: 4px;
            border-top-right-radius: 4px;
        }

        #panel .amap-lib-walking {
            border-bottom-left-radius: 4px;
            border-bottom-right-radius: 4px;
            overflow: hidden;
        }
    </style>
    <title>电子围栏定位</title>
    <script type="text/javascript">
        window._AMapSecurityConfig = {
            securityJsCode: '5dfaddb510ffa01104ce9c25166f7f53',
        }
    </script>
    <link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css"/>
    <script src="https://webapi.amap.com/maps?v=1.4.15&key=8ed6ab55d9456bfe6c1d020ce9b2a1c9&plugin=AMap.MouseTool"></script>
    <script src="https://webapi.amap.com/maps?v=1.4.15&key=8ed6ab55d9456bfe6c1d020ce9b2a1c9&plugin=AMap.Walking"></script>
    <script src="https://a.amap.com/jsapi_demos/static/demo-center/js/demoutils.js"></script>
</head>
<body>
<div id="container"></div>
<div id="panel"></div>
<script type="text/javascript">

    const lng = 116.397504
    const lat = 39.89619
    const map = new AMap.Map("container", {
        center: [lng, lat],
        zoom: 14,
        resizeEnable: true
    });

    let circle = new AMap.Circle({
        center: [lng, lat],
        radius: 300,
        borderWeight: 3,
        strokeColor: "#3355ff",
        strokeOpacity: 1,
        strokeWeight: 6,
        fillOpacity: 0.4,
        strokeStyle: 'solid',
        strokeDasharray: [10, 10],
        fillColor: '#ffffff',
        zIndex: 50,
    })
    const phase = 2 * Math.PI / 360;
    let LngLatArr = []
    for (let i = 0; i < 360; i += 45) {
        let newLng = lng + ((300 * Math.cos(i * phase))) / (6371000 * Math.cos(lat * Math.PI / 180) * Math.PI / 180);
        let newLag = lat + ((300 * Math.sin(i * phase))) / (6371000 * Math.PI / 180);
        LngLatArr.push([newLng, newLag])
    }

    let opt = {
        map: map,
        panel: "panel",
        hideMarkers: true,
        isOutline: true,
        outlineColor: '#ffeeee',
        autoFitView: true
    }
    LngLatArr.push(LngLatArr[0])
    LngLatArr.flatMap((k, i) => {
        let walking = new AMap.Walking(opt)
        walking.search(LngLatArr[i], LngLatArr[i + 1], function (status, result) {
            if (status === 'complete') {
                console.info('步行路线数据查询成功')
            } else {
                console.info('步行路线数据查询失败' + result)
            }
        });
    })

</script>
</body>
</html>

获取获取 多边形的拐点位 绘制多边形 形成成电子围栏

  • 需要裁剪一些点
<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
    <title>电子围栏</title>

    <link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css"/>
    <style>
        html, body, #container {
            height: 100%;
            width: 100%;
        }

        .amap-icon img {
            width: 25px;
            height: 34px;
        }
    </style>
</head>
<body>
<div id="container"></div>
<div id="panel"></div>
<script type="text/javascript">
    window._AMapSecurityConfig = {
        securityJsCode: '5dfaddb510ffa01104ce9c25166f7f53',
    }
</script>
<script type="text/javascript"
        src="https://webapi.amap.com/maps?v=1.4.15&key=8ed6ab55d9456bfe6c1d020ce9b2a1c9"></script>
<script src="https://webapi.amap.com/maps?v=1.4.15&key=8ed6ab55d9456bfe6c1d020ce9b2a1c9&plugin=AMap.Walking"></script>
<script type="text/javascript">

    const lng = 116.397504
    const lat = 39.89619
    let map = new AMap.Map("container", {
        center: [116.397504, 39.89619],
        zoom: 14
    });

    const circle = new AMap.Circle({
        center: [lng, lat],
        radius: 300, //半径
        borderWeight: 3,
        strokeColor: "#FF33FF",
        strokeWeight: 6,
        strokeOpacity: 0.2,
        fillOpacity: 0.4,
        strokeStyle: 'dashed',
        strokeDasharray: [10, 10],
        fillColor: '#1791fc',
        zIndex: 50
    })


    const r = 6371000;
    const phase = 2 * Math.PI / 360;
    let pointArr = []
    let LngLatArr = []
    for (let i = 0; i < 360; i += 45) {

        let newLng = lng + ((300 * Math.cos(i * phase))) / (r * Math.cos(lat * Math.PI / 180) * Math.PI / 180);
        let newLag = lat + ((300 * Math.sin(i * phase))) / (r * Math.PI / 180);
        LngLatArr.push([newLng, newLag])

        let startIcon = new AMap.Icon({
            size: new AMap.Size(25, 34),
            image: 'dir-marker.png',
            imageSize: new AMap.Size(135, 40),
            imageOffset: new AMap.Pixel(-9, -3)
        });
        const marker = new AMap.Marker({
            position: [newLng, newLag],
            icon: startIcon,
            offset: new AMap.Pixel(-13, -30)
        });
        pointArr.push(marker)
    }

    LngLatArr.push(LngLatArr[0])


    let pathResult = []
    LngLatArr.forEach(async (item, i) => {
        let walking = new AMap.Walking({})
        await walking.search(LngLatArr[i], LngLatArr[i + 1], async function (status, result) {
            if (status === 'complete') {
                pathResult.push(result)
                console.info('步行路线数据查询成功')
            } else {
                console.info('步行路线数据查询失败' + result)
            }
        })
    });

    setTimeout(() => {
       let map = new AMap.Map("container", {
            center: [116.397504, 39.89619],
            zoom: 14
        });
        let pathArr = []
        let pathRawArr = []
        let kneePoint = {}
        pathResult.flatMap((term) => {
            term.routes[0].steps.flatMap((item, index) => {
                item.path.flatMap((pos) => {
                    pathRawArr.push([pos.lng, pos.lat])
                    key = "" + pos.lng + pos.lat
                    if (!(key in kneePoint)) {
                        pathArr.push([pos.lng, pos.lat])
                        kneePoint[key] = {}
                    }
                })
            })
        })
        let polygon = new AMap.Polygon({
            path: pathRawArr,
            strokeColor: "#1E9FFF",
            strokeWeight: 2,
            strokeStyle: 'dashed',
            strokeOpacity: 1,
            fillOpacity: 0.1,
            fillColor: '#1E9FFF',
            zIndex: 50,
        })

        map.add(polygon)
        map.setFitView([polygon])
    }, 500)

</script>
</body>
</html>

posted @ 2023-08-15 12:00  vx_guanchaoguo0  阅读(297)  评论(0编辑  收藏  举报