• 【高德地图API】JS高德地图API实现多边形绘画,高德获取多边形提交数据


    前言

    高德地图官方API:https://lbs.amap.com/demo/javascript-api/example/overlayers/polygon-draw-and-edit
    高德地图API版本:1.4.15
    使用JS实现高德地图多边形围栏设置(除了简单的例子,还附带本人在项目中的实现)

    效果

    在这里插入图片描述

    实现

    引入js

    需要添加安全密钥和key,之所以要使用安全密钥是官方在2021-12-02的时候改的,原本只需要key即可的
    参考网址:https://lbs.amap.com/api/javascript-api/guide/abc/prepare
    这里plugin=AMap.*****是自己需要到的对象

    <script type="text/javascript">
            window._AMapSecurityConfig = {
                securityJsCode:'bf5ed*********************886', // 安全密钥(正式项目官方推荐使用nginx代理方式引入密钥)
            }
    script>
    <script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=22d1******************b8&plugin=AMap.Autocomplete,AMap.PlaceSearch,AMap.PolyEditor,AMap.Marker">script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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%;
    			}
    		style>
    		<title>多边形的绘制和编辑title>
    		<link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" />
    		<script type="text/javascript">
    		        window._AMapSecurityConfig = {
    		            securityJsCode:'bf5******************886',
    		        }
    		script>
    		<script src="https://webapi.amap.com/maps?v=1.4.15&key=22d******************a20b8&plugin=AMap.PolyEditor">script>
    	head>
    
    	<body>
    		<div id="container">div>
    		<div class="input-card" style="width: 120px">
    			<button class="btn" onclick="startEdit()" style="margin-bottom: 5px">开始编辑button>
    			<button class="btn" onclick="submitMap()">结束编辑button>
    		div>
    		<script type="text/javascript">
    			
    			var temp_lnglat = []; // 临时存储位置
    			var tempMap = {}; // 临时存储地图对象
    			
    			// 要绘画位置的经纬度
    			var lngLat = [116.400274, 39.905812];
    			
    			initMap(lngLat);
    			
    			/**
    			 * ---------------------------------------------------------------------------------------------------------------
    			 * 初始化地图
    			 */
    			function initMap(lngLat){
    				tempMap.map = new AMap.Map("container", {
    					center: lngLat,
    					zoom: 14
    				});
    				
    				createPolygon(lngLat);
    			}
    			
    			/**
    			 * ---------------------------------------------------------------------------------------------------------------
    			 * 创建多边形
    			 * @param {Object} paths
    			 */
    			function createPolygon(lngLat, paths){
    				// 绘画多边形的各个角的经纬度(如果没有就使用这个,在当前位置上创建默认的多边形)
    				if(!paths || paths.length < 1){
    					paths = [
    						[lngLat[0] + 0.003048, lngLat[1] + 0.014442],
    						[lngLat[0] + 0.010429, lngLat[1] - 0.008257],
    						[lngLat[0] + 0.002018, lngLat[1] -  0.013458],
    						[lngLat[0] - 0.010427, lngLat[1] - 0.014446]
    					]
    				}
    				// 赋值给临时数组(提交的时候要这些多边形角的经纬度)
    				temp_lnglat = paths;
    				// 创建绘画
    				var polygon = new AMap.Polygon({
    					path: paths,
    					strokeColor: "#0f79d7",
    					strokeWeight: 3,
    					strokeOpacity: 0.6,
    					fillOpacity: 0.4,
    					fillColor: '#1791fc',
    					zIndex: 50,
    				})
    				tempMap.map.add(polygon)
    				// 缩放地图到合适的视野级别
    				tempMap.map.setFitView([polygon])
    				// 编辑绘画对象
    				tempMap.polyEditor = new AMap.PolyEditor(tempMap.map, polygon)
    				// 事件
    				tempMap.polyEditor.on('addnode', function(event) {
    					console.log('触发事件:addnode ------------------------------------------')
    					console.log("添加:", event)
    					console.log("添加-经度:", event.lnglat.lng, "纬度:", event.lnglat.lat)
    				})
    				tempMap.polyEditor.on('adjust', function(event) {
    					console.log('触发事件:adjust ------------------------------------------')
    					console.log("修改:", event)
    					console.log("修改-经度:", event.lnglat.lng, "纬度:", event.lnglat.lat)
    				})
    				tempMap.polyEditor.on('removenode', function(event) {
    					console.log('触发事件:removenode ------------------------------------------')
    					console.log("removenode:", event)
    				})
    				tempMap.polyEditor.on('end', function(event) {
    					console.log('触发事件: end ------------------------------------------')
    					console.log("end:", event)
    					// event.target 即为编辑后的多边形对象
    				})
    			}
    			
    			/**
    			 * ---------------------------------------------------------------------------------------------------------
    			 * 清除绘画
    			 */
    			function clearMap() {
    			    tempMap.map.clearMap(tempMap.polyEditor)
    			    tempMap.map.remove(tempMap.polyEditor)
    			}
    
    			/**
    			 * ---------------------------------------------------------------------------------------------------------------
    			 * 开始编辑
    			 */
    			function startEdit(){
    				// 打开编辑
    				tempMap.polyEditor.open(); 
    			}
    
    			/**
    			 * ---------------------------------------------------------------------------------------------------------------
    			 * 提交经纬度
    			 */
    			function submitMap() {
    				// 关闭绘画
    				//tempMap.polyEditor.close();
    				// 获取所有的经纬度
    				if(tempMap.polyEditor.bu){
    					temp_lnglat = tempMap.polyEditor.bu[0];
    				}
    				// 去除Q和R属性值,保留lng和lat的值
    				temp_lnglat = temp_lnglat.map(function(item, index){
    					return [item.lng, item.lat];
    				})
    				console.log("获取所有坐标:", JSON.stringify(temp_lnglat));
    			}
    			
    		script>
    	body>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148

    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 {
              width: 100%;
              height: 100%;
            }
        style>
    head>
    <body>
    <div id="container">div>
    <div class="info">
        <div class="input-item">
          <div class="input-item-prepend">
            <span class="input-item-text" style="width:8rem;">请输入关键字span>
          div>
          <input id='tipinput' type="text">
        div>
    div>
    
    <script type="text/javascript">
            window._AMapSecurityConfig = {
                securityJsCode:'bf5********************886',
            }
    script>
    <script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=22d********************0b8&plugin=AMap.Autocomplete,AMap.PlaceSearch">script>
    <script type="text/javascript">
        /**
    	 * ---------------------------------------------------------------------------------------------------------
    	 * 渲染地图
    	 */
    	function initMap(){
    		var map = new AMap.Map('container', {
    			resizeEnable: true, //是否监控地图容器尺寸变化
    		});
    		// 输入提示
    	    var autoOptions = {
    	        input: "tipinput"
    	    };
    	    var auto = new AMap.Autocomplete(autoOptions);
    	    // 构造地点查询类
    	    var placeSearch = new AMap.PlaceSearch({
    	        map: map
    	    });
    	    // 注册监听,当选中某条记录时会触发
    	    AMap.event.addListener(auto, "select", selectSearch);
    	    function selectSearch(e) {
    	    	console.log(e)
    	        placeSearch.setCity(e.poi.adcode);
    	        placeSearch.search(e.poi.name);  // 关键字查询查询
    	    }
    	}
    	initMap();
    script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    在项目中使用

    效果图

    在这里插入图片描述

    这是本人在项目中的使用(复制粘贴可用)

    引入

    记得把安全密钥和key改了

    <script type="text/javascript">
    	window._AMapSecurityConfig = {
    		securityJsCode:'bf5e**********************886',
    	}
    script>
    <script src="https://webapi.amap.com/maps?v=1.4.15&key=22d**********************20b8&plugin=AMap.Autocomplete,AMap.PlaceSearch,AMap.PolyEditor,AMap.Marker">script>
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    html

    这里使用layui框架的,所有直接复制过来了,只取关键即可

    <div class="layui-form-item">
    	<label class="layui-form-label">项目地址label>
    	<div class="layui-input-block" style="width: 500px;">
    		<input type="text" name="addr" id="addr" placeholder="输入地址后选择详细,再操作地图"autocomplete="off" class="layui-input">
    		<div class="lay-search-content">
    			<ul>ul>
    		div>
    	div>
    div>
    <div class="layui-form-item">
    	
    	<div class="container" id="container" style="height: 500px;width: 750px;">div>
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    CSS

    自己写的效果

    .lay-search-content{
    	padding: 10px;
    	background: white;
    	border-radius: 4px;
    	color: #333333;
    	line-height: 15px;
    	box-shadow: #00000024 0px 2px 5px 0;
    	max-height: 300px;
    	overflow: auto;
    	display: none;
    	position: absolute;z-index: 99999;
    	width: 99%;
    }
    .lay-search-content li{
    	list-style: none;
    	margin: 5px 0px;
    	padding: 8px 0px;
    	border-bottom: 1px solid whitesmoke;
    	cursor: pointer;
    }
    .lay-search-content li:hover{
    	background: #f1f1f1;
    }
    .lay-search-mark{
    	width: 16px;
    	display: inline-block;
    	height: 16px;
    	background: #c1c1c1;
    	text-align: center;
    	line-height: 16px;
    	border-radius: 50%;
    	margin-right: 4px;
    	color: white;
    	font-size: 12px;
    	position: relative;
    	top: -1px;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    具体实现JS

    
    var temp_lnglat = [116.400274, 39.905812]; // 临时存储当前位置
    var temp_fence_lnglat = []; // 临时存储所有位置
    var tempMap = {}; // 临时存储地图对象
    
    /**
     * ---------------------------------------------------------------------------------------------------------
     * 重置地图值
     */
    function clearMap(state) {
        if(!state){ // 修改的话不赋值
            temp_lnglat = [116.400274, 39.905812];
            temp_fence_lnglat = [];
        }
        if(tempMap.polyEditor){
            tempMap.map.clearMap(tempMap.polyEditor)
            tempMap.map.remove(tempMap.polyEditor)
        }
    }
    
    /**
     * ---------------------------------------------------------------------------------------------------------
     * 渲染地图
     */
    function initMap(state){
        tempMap.map = new AMap.Map('container', {
    		resizeEnable: true, //是否监控地图容器尺寸变化
            center: temp_lnglat,
            zoom: 14,
    	});
        // 构造地点查询类
        tempMap.placeSearch = new AMap.PlaceSearch({
            city: "全国", // 兴趣点城市
        });
        $("#addr").bind('input propertychange', function() {
            var text = $("#addr").val();
            searchAddr(text)
        })
        clickPosition(temp_lnglat[0], temp_lnglat[1], state);
    }
    
    /**
     * --------------------------------------------------------------------------------------------------------------------
     * 地图搜索
     * @return
     */
    function searchAddr(text) {
        // 关键字查询,设置成输入框input就好了,下面返回的集合中有name,可以自己重新查询结果选择
        tempMap.placeSearch.search(text, function (status, result) {
            // 查询成功时,result即对应匹配的POI信息
            console.log("搜索结果坐标:", result)
            if (!result.poiList){
                return;
            }
            var pois = result.poiList.pois;
            $(".lay-search-content").css("display", "block");
            $(".lay-search-content>ul").empty();
            for (var i = 0; i < pois.length; i++) {
                var poi = pois[i];
                var s = '
  • + poi.location.lng + ', ' + poi.location.lat + ')">'; var index = i + 1; if (index == 1) { s += ' ' + index + '' + poi.name; } else if (index == 2) { s += ' ' + index + '' + poi.name; } else if (index == 3) { s += ' ' + index + '' + poi.name; } else { s += ' ' + index + '' + poi.name; } s += ' (' + poi.address + ')'; s += '
  • '
    ; $(".lay-search-content>ul").append(s); var marker = []; marker[i] = new AMap.Marker({ position: poi.location, // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9] offset: new AMap.Pixel(0, -20),// 相对于基点的偏移位置 title: poi.name }); // [点标上面显示内容信息] var infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(0, -30)});// 地图位置对象 // 点击弹出内容 marker[i].content = poi.name; marker[i].on('click', markerClick); function markerClick(e) { var position = e.target.getPosition(); var content = "
    " + e.target.content + "
    "
    ; // 要显示的内容 content += "" infoWindow.setContent(content); infoWindow.open(tempMap.map, position); } // 将创建的点标记添加到已有的地图实例: tempMap.map.add(marker[i]); } tempMap.map.setFitView(); }) } /** * -------------------------------------------------------------------------------------------------------------------- * 搜索结果选择设置围栏 * @param lng * @param lat */ function clickPosition(lng, lat, state) { $(".lay-search-content").css("display", "none"); clearMap(state); temp_lnglat = [lng, lat]; // 添加点标 var markers = new AMap.Marker({ position: temp_lnglat, // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9] offset: new AMap.Pixel(0, -20),// 相对于基点的偏移位置 }); tempMap.map.add(markers); tempMap.map.setCenter(temp_lnglat) createPolygon(temp_lnglat, temp_fence_lnglat); } /** * --------------------------------------------------------------------------------------------------------------- * 创建多边形 * @param {Object} paths */ function createPolygon(lngLat, paths){ // 绘画多边形的各个角的经纬度(如果没有就使用这个,在当前位置上创建默认的多边形) if(!paths || paths.length < 1){ paths = [ [lngLat[0] + 0.003048, lngLat[1] + 0.014442], [lngLat[0] + 0.010429, lngLat[1] - 0.008257], [lngLat[0] + 0.002018, lngLat[1] - 0.013458], [lngLat[0] - 0.010427, lngLat[1] - 0.014446] ] } // 赋值给临时数组(提交的时候要这些多边形角的经纬度) temp_fence_lnglat = paths; // 创建绘画 var polygon = new AMap.Polygon({ path: paths, strokeColor: "#0f79d7", strokeWeight: 3, strokeOpacity: 0.6, fillOpacity: 0.4, fillColor: '#1791fc', zIndex: 50, }) tempMap.map.add(polygon) // 缩放地图到合适的视野级别 tempMap.map.setFitView([polygon]) // 编辑绘画对象 tempMap.polyEditor = new AMap.PolyEditor(tempMap.map, polygon) // 事件 tempMap.polyEditor.on('addnode', function(event) { console.log('触发事件:addnode ------------------------------------------') console.log("添加:", event) console.log("添加-经度:", event.lnglat.lng, "纬度:", event.lnglat.lat) }) tempMap.polyEditor.on('adjust', function(event) { console.log('触发事件:adjust ------------------------------------------') console.log("修改:", event) console.log("修改-经度:", event.lnglat.lng, "纬度:", event.lnglat.lat) }) tempMap.polyEditor.on('removenode', function(event) { console.log('触发事件:removenode ------------------------------------------') console.log("removenode:", event) }) tempMap.polyEditor.on('end', function(event) { console.log('触发事件: end ------------------------------------------') console.log("end:", event) // event.target 即为编辑后的多边形对象 }) // 打开编辑 tempMap.polyEditor.open(); } /** * --------------------------------------------------------------------------------------------------------------- * 开始编辑 */ function startEdit(){ // 打开编辑 tempMap.polyEditor.open(); } /** * --------------------------------------------------------------------------------------------------------------- * 提交经纬度 */ function submitMap() { // 关闭绘画 //tempMap.polyEditor.close(); // 获取所有的经纬度 if(tempMap.polyEditor.bu){ temp_fence_lnglat = tempMap.polyEditor.bu[0]; } // 去除Q和R属性值,保留lng和lat的值 temp_fence_lnglat = temp_fence_lnglat.map(function(item, index){ return [item.lng, item.lat]; }) console.log("获取所有坐标:", JSON.stringify(temp_fence_lnglat)); }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201

    调用说明

    基于上面写好的js,直接复制去调用即可

    添加的时候

    initMap();
    
    • 1

    修改的时候

    data.lngLat和data.fenceLngLat就是我们存储起来已经设置的经纬度

    temp_lnglat = JSON.parse(data.lngLat);
    temp_fence_lnglat = JSON.parse(data.fenceLngLat);
    initMap(true);
    
    • 1
    • 2
    • 3

    判断是否在范围内

    参考API:https://lbs.amap.com/demo/javascript-api/example/relationship-judgment/point-surface-relation

    // 创建点(显示当前用户的点位)
    var marker = new AMap.Marker({
    	map: map,
    	position: [116.566298, 40.014179]
    });
    // 判断是否在范围内
    var point = marker.getPosition();
    var isPointInRing = AMap.GeometryUtil.isPointInRing(point, paths); // paths 就是多边形的那些坐标数组
    console.log("是否在范围内:", isPointInRing?'是':'否')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    java绘画和判断是否在范围内

    方式一

    参考网址1:https://blog.csdn.net/qq_39190679/article/details/102524601
    参考网址2:https://www.jianshu.com/p/5a2398a84889
    参考网址3:https://zhuanlan.zhihu.com/p/534997829

    package cn.geesuntar.utils;
    
    import com.alibaba.fastjson.JSONArray;
    
    import java.awt.geom.Point2D;
    import java.util.ArrayList;
    import java.util.List;
    
    public class RegionUtil {
    
        private static double EARTH_RADIUS = 6378137;
    
        private static double rad(double d) {
            return d * Math.PI / 180.0;
        }
     
        /**
         * 多边形
         * @param point   要判断的点的横纵坐标
         * @param polygon 组成的顶点坐标集合
         * @return
         */
        public static boolean isInPolygon(Point2D.Double point, List<Point2D.Double> polygon) {
            java.awt.geom.GeneralPath peneralPath = new java.awt.geom.GeneralPath();
            Point2D.Double first = polygon.get(0);
            peneralPath.moveTo(first.x, first.y);
            polygon.remove(0);
            for (Point2D.Double d : polygon) {
                peneralPath.lineTo(d.x, d.y);
            }
            peneralPath.lineTo(first.x, first.y);
            peneralPath.closePath();
            return peneralPath.contains(point);
        }
     
        /**
         * 通过经纬度获取距离(单位:米)
         *
         * @param lat1 纬度1
         * @param lng1 经度1
         * @param lat2 纬度2
         * @param lng2 经度2
         * @return 距离
         */
        public static double getDistance(double lat1, double lng1, double lat2,
                                         double lng2) {
            double radLat1 = rad(lat1);
            double radLat2 = rad(lat2);
            double a = radLat1 - radLat2;
            double b = rad(lng1) - rad(lng2);
            double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                    Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
            s = s * EARTH_RADIUS;
            s = Math.round(s * 10000d) / 10000d;
            return s;
        }
     
        /**
         * 圆形	
         * @param lat1   纬度
         * @param lat2   经度
         * @param lng1   纬度
         * @param lng2   经度
         * @param radius 判断一个点是否在圆形区域内,比较坐标点与圆心的距离是否小于半径
         */
        public static boolean isInCircle(double lng1, double lat1, double lng2, double lat2, double radius) {
            double distance = getDistance(lat1, lng1, lat2, lng2);
            System.out.println("半径:"+radius+"解析半径:"+distance);
            if (distance > radius) {
                return false;
            } else {
                return true;
            }
        }
    
        public static void main(String[] args) {
            String str = "[[114.125986,22.607612],[114.125241,22.607122],[114.125547,22.606775],[114.126303,22.607236]]";
            JSONArray jsonArray = JSONArray.parseArray(str);
            JSONArray jsonArray1 = null;
            List<Point2D.Double> polygon = new ArrayList<>();
            for (Object o : jsonArray) {
                jsonArray1 = JSONArray.parseArray(o.toString());
                polygon.add(new Point2D.Double(jsonArray1.getDouble(0),jsonArray1.getDouble(1)));
            }
            System.out.println(RegionUtil.isInPolygon(new Point2D.Double(114.125872,22.606983), polygon));
        }
     
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89

    方式二

    使用“文言一心”AI解答,经过测试校验正常

    pom.xml依赖引入

    多边形需要

    
    <dependency>
        <groupId>org.locationtech.jtsgroupId>
        <artifactId>jts-coreartifactId>
        <version>1.18.1version> 
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    多边形实现

    package com.modules.util;
    
    import org.locationtech.jts.geom.*;
    import org.locationtech.jts.operation.valid.IsValidOp;
    
    /**
     * 高德地图-多边形围栏范围校验
     * @author yyq
     */
    public class GeoFenceCheck {
    
    
        public static boolean isPointInPolygon(double longitude, double latitude, Coordinate[] polygonCoordinates) {
            // 创建GeometryFactory实例,用于创建几何对象
            GeometryFactory geometryFactory = new GeometryFactory();
    
            // 创建多边形
            Polygon polygon = geometryFactory.createPolygon(polygonCoordinates); // 第二个参数是多边形的孔(如果有的话),这里为null
    
            // 确保多边形是有效的
            IsValidOp isValidOp = new IsValidOp(polygon);
            if (!isValidOp.isValid()) {
                throw new IllegalArgumentException("The polygon is not valid.");
            }
    
            // 创建点
            Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
    
            // 判断点是否在多边形内
            return polygon.contains(point);
        }
    
        public static void main(String[] args) {
            // 多边形的顶点坐标(经纬度),需要按照顺时针或逆时针顺序排列
            Coordinate[] polygonCoordinates = new Coordinate[] {
                    new Coordinate(116.397128, 39.90923),
                    new Coordinate(116.407741, 39.899414),
                    new Coordinate(116.416826, 39.907761),
                    new Coordinate(116.402292, 39.913825),
                    new Coordinate(116.397128, 39.90923) // 多边形的起始和结束坐标相同,以闭合多边形
            };
    
            // 待检查的点(经纬度)
            double longitude = 116.405;
            double latitude = 39.905;
    
            // 判断点是否在多边形内
            boolean isInside = isPointInPolygon(longitude, latitude, polygonCoordinates);
            System.out.println("点是否在多边形内:" + isInside);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    圆形实现

    package com.modules.util;
    
    /**
     * 高德地图-圆形围栏范围校验
     * @author yyq
     */
    public class GaoDeMapUtil {
    
        /**
         * 判断一个点是否在圆形围栏内。
         *
         * @param longitude     点的经度
         * @param latitude      点的纬度
         * @param centerLong    圆心的经度
         * @param centerLat     圆心的纬度
         * @param radiusInMeter 圆的半径(单位:米)
         * @return 如果点在圆形围栏内,返回true;否则返回false。
         */
        public static boolean isPointInCircle(double longitude, double latitude, double centerLong, double centerLat, double radiusInMeter) {
            // 将经纬度转换为弧度
            double lat1 = Math.toRadians(latitude);
            double lon1 = Math.toRadians(longitude);
            double lat2 = Math.toRadians(centerLat);
            double lon2 = Math.toRadians(centerLong);
    
            // 使用哈弗辛公式计算两点之间的地球表面距离(单位:米)
            // 地球平均半径(单位:米)
            double EARTH_RADIUS = 6371000;
            double dLat = lat2 - lat1;
            double dLon = lon2 - lon1;
            double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                    Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
            double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
            double distance = EARTH_RADIUS * c;
    
            // 判断距离是否小于等于圆的半径
            return distance <= radiusInMeter;
        }
    
        public static void main(String[] args) {
            double longitude = 114.056547; // 待检查的点的经度
            double latitude = 22.532864; // 待检查的点的纬度
            double centerLong = 114.055639; // 圆心的经度
            double centerLat = 22.533181; // 圆心的纬度
            double radiusInMeter = 100; // 圆的半径(单位:米)
    
            // 判断点是否在圆形围栏内
            boolean isInside = isPointInCircle(longitude, latitude, centerLong, centerLat, radiusInMeter);
            System.out.println("点是否在圆内:" + isInside);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    所应用的功能大概就是这样啦!

    圆形围栏可参考https://blog.csdn.net/weixin_43992507/article/details/130731955

  • 相关阅读:
    【ONLYOFFICE震撼8.1】ONLYOFFICE8.1版本桌面编辑器测评
    Nue JS 造全新的 Web 生态
    RealVCN连接超时怎么解决
    软降工程概述----软件过程
    再谈函数的栈帧
    SpringSecurity初识及使用
    R语言深度学习-4-识别异常数据(无监督学习/自动编码器)
    朴素贝叶斯----评论情感分析系统
    3DGS语义分割之LangSplat
    uniapp 微信授权获取用户信息和手机号
  • 原文地址:https://blog.csdn.net/weixin_43992507/article/details/134245725