Java实现电子围栏的小例子

主要需求是实现一个电子围栏判断的小例子其中包括前端和后端的demo代码
引入对应的依赖库

<!--jts库通常用于几何计算和表示地理空间数据-->
<dependency>
    <groupId>org.locationtech.jts</groupId>
    <artifactId>jts-core</artifactId>
    <version>1.18.0</version>
</dependency>
public class GeoFenceUtils {

    /** geometryFactory */
    private static final GeometryFactory geometryFactory = new GeometryFactory();

    /**
     * 判断指定的GPS点是否在电子围栏内
     *
     * @param fencePointsList 包含电子围栏的经纬度数据的列表,格式为 "经度,纬度"
     * @param pointStr        指定的GPS点,格式为 "经度,纬度"
     * @return 如果在电子围栏内则返回true,否则返回false
     */
    public static boolean isPointInGeoFence(List<String> fencePointsList, String pointStr) {
        // 将电子围栏的经纬度数据转换为坐标数组
        Coordinate[] fencePoints = parseCoordinates(fencePointsList);

        // 将指定的GPS点转换为坐标
        Coordinate targetPoint = parseCoordinate(pointStr);

        // 创建电子围栏多边形
        Polygon geoFencePolygon = createPolygon(fencePoints);

        // 创建指定的GPS点
        Point point = geometryFactory.createPoint(targetPoint);

        // 检查指定的GPS点是否在电子围栏内
        return geoFencePolygon.contains(point);
    }

    /**
     * 判断指定的GPS点是否在电子围栏内
     *
     * @param geoFencePolygon geo fence polygon
     * @param pointStr        指定的GPS点,格式为 "经度,纬度"
     * @return 如果在电子围栏内则返回true ,否则返回false
     * @since 2.0.0
     */
    public static boolean isPointInGeoFence(Polygon geoFencePolygon, String pointStr) {
        // 将指定的GPS点转换为坐标
        Coordinate testPoint = parseCoordinate(pointStr);

        // 创建指定的GPS点
        Point point = geometryFactory.createPoint(testPoint);

        // 检查指定的GPS点是否在电子围栏内
        return geoFencePolygon.contains(point);
    }

    /**
     * 判断指定的GPS点是否在电子围栏内
     *
     * @param fencePointsList 包含电子围栏的经纬度数据的列表,格式为 "经度,纬度"
     * @return 如果在电子围栏内则返回true,否则返回false
     */
    public static Polygon getPointInGeoFence(List<String> fencePointsList) {
        // 将电子围栏的经纬度数据转换为坐标数组
        Coordinate[] fencePoints = parseCoordinates(fencePointsList);
        // 创建电子围栏
        return createPolygon(fencePoints);
    }


    /**
     * 根据GPS点集合创建多边形
     *
     * @param coordinates GPS点集合
     * @return 多边形对象
     */
    private static Polygon createPolygon(Coordinate[] coordinates) {
        // Ensure the polygon is closed by adding the first coordinate at the end if necessary
        if (!coordinates[0].equals(coordinates[coordinates.length - 1])) {
            Coordinate[] closedCoordinates = new Coordinate[coordinates.length + 1];
            System.arraycopy(coordinates, 0, closedCoordinates, 0, coordinates.length);
            closedCoordinates[closedCoordinates.length - 1] = coordinates[0];
            coordinates = closedCoordinates;
        }
        return geometryFactory.createPolygon(coordinates);
    }

    /**
     * 将包含经纬度数据的列表转换为坐标数组
     *
     * @param pointsList 包含经纬度数据的列表
     * @return 坐标数组
     */
    private static Coordinate[] parseCoordinates(List<String> pointsList) {
        Coordinate[] coordinates = new Coordinate[pointsList.size()];
        for (int i = 0; i < pointsList.size(); i++) {
            coordinates[i] = parseCoordinate(pointsList.get(i));
        }
        return coordinates;
    }

    /**
     * 将经纬度数据字符串转换为坐标
     *
     * @param pointStr 经纬度数据字符串,格式为 "经度,纬度"
     * @return 坐标
     */
    private static Coordinate parseCoordinate(String pointStr) {
        String[] parts = pointStr.split(StringPool.COMMA);
        double lon = Double.parseDouble(parts[0]);
        double lat = Double.parseDouble(parts[1]);
        return new Coordinate(lon, lat);
    }

}

单元测试类

public class GeoFenceUtilTest {


    /**
     * Test geo
     *
     * @since 2.0.0
     */
    @Test
    public void testGeo() {
        // 示例电子围栏点集合
        List<String> fencePointsList = List.of(
                "116.403322,39.920255",
                "116.429043,39.913906",
                "116.438447,39.882655",
                "116.419252,39.873514",
                "116.406656,39.881143",
                "116.389347,39.884167",
                "116.389846,39.891365",
                "116.377436,39.908228",
                "116.410512,39.901984"
        );

        // 指定的GPS点
        String testPointStr = "116.384112,39.899172";
        // 检查指定的GPS点是否在电子围栏内
        boolean isWithinFence = GeoFenceUtils.isPointInGeoFence(fencePointsList, testPointStr);
        System.out.println("指定的GPS点是否在电子围栏内: " + isWithinFence);
    }

}

前端的测试demo,高德开放平台JS API测试平台,找到多边形编辑器,将下面的代码粘贴到执行器里面,然后点击右上角的执行代码,就可以获取到对应范围的点位地址

在这里插入图片描述

<!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=2.0&key=您申请的key值&plugin=AMap.PolygonEditor"></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="polyEditor.open()" style="margin-bottom: 5px">开始编辑</button> 
   <button class="btn" onclick="polyEditor.close()">结束编辑</button> 
</div>
<script type="text/javascript">
    var map = new AMap.Map("container", {
      center: [116.400274, 39.905812],
      zoom: 14,
      viewMode: '3D',
    });

    var path = [
      [116.403322, 39.920255],
      [116.410703, 39.897555],
      [116.402292, 39.892353],
      [116.389846, 39.891365]
    ]
    var path1 = [
      [116.453322, 39.920255],
      [116.460703, 39.897555],
      [116.452292, 39.892353],
      [116.439846, 39.891365]
    ]

    var polygon = new AMap.Polygon({
      path: path,
      strokeColor: "#FF33FF",
      strokeWeight: 6,
      strokeOpacity: 0.2,
      fillOpacity: 0.4,
      fillColor: '#1791fc',
      zIndex: 50,
      bubble: true,
    })
    var polygon1 = new AMap.Polygon({
      path: path1,
      strokeColor: "green",
      strokeWeight: 6,
      strokeOpacity: 0.2,
      fillOpacity: 0.4,
      fillColor: '#1791fc',
      zIndex: 50,
      bubble: true,

    })
    map.add([polygon, polygon1])

    // 缩放地图到合适的视野级别
    map.setFitView()
    var polyEditor;
      // var polyEditor = new AMap.PolyEditor(map, polygon)
      // polyEditor = new AMap.PolygonEditor(map)
    polyEditor = new AMap.PolygonEditor(map, polygon);
    polyEditor.addAdsorbPolygons(polygon1)
    polyEditor.open();

   polyEditor.on("addnode", (event) => {
        let path = event.target.getPath();
       console.log('addnode');
  console.log(path);
     
      });

 

      polyEditor.on("adjust", (event) => {
        let path = event.target.getPath();
             console.log('adjust');
  console.log(path);
      });

      polyEditor.on("removenode", (event) => {
        let path = event.target.getPath();
          console.log('removenode');
  console.log(path);
      });

      polyEditor.on("end", (event) => {
        let path = event.target.getPath();
            console.log('end');
  console.log(path);
      });


     map.on('click',(e)=>{
       console.log('您在 [ '+e.lnglat.getLng()+','+e.lnglat.getLat()+']的位置点击了多边形!');
    });

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/772454.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

web学习笔记(七十五)

目录 1.小程序修改响应式数据 1.1修改基本数据类型的值 1.2修改复合数据类型的值 2. 发送请求 3.小程序解决跨域问题 1.小程序修改响应式数据 1.1修改基本数据类型的值 在小程序中需要先将data中的数据拿过来并结构&#xff0c;才可以在this.setdata中修改数据&#xf…

2024攻防演练:亚信安全推出MSS/SaaS短期定制服务

随着2024年攻防演练周期延长的消息不断传出&#xff0c;各参与方将面临前所未有的挑战。面对强大的攻击队伍和日益严格的监管压力&#xff0c;防守单位必须提前进行全面而周密的准备和部署。为应对这一形势&#xff0c;亚信安全特别推出了为期三个月的MSS/SaaS短期订阅方案。该…

SpringBoot Task 定时任务

springboot中使用Task定时任务非常简单 springboot 中自带的都有注解不需要引入依赖 第一步&#xff1a;在启动类上添加启用定时任务注解 EnableScheduling //开启任务调度 第二步&#xff1a;创建一个springboot组件用于定时任务管理 package cn.lsy.api.Task;import cn.ls…

【LeetCode】十一、滑动窗口:长度最小的子数组 + 定长子串的元音最大数目

文章目录 1、滑动窗口2、leetcode209&#xff1a;长度最小的子数组3、leetcode1456&#xff1a;定长子串中元音的最大数目 1、滑动窗口 如下&#xff0c;有一个数组&#xff0c;现三个元素为一组&#xff0c;求最大的和&#xff0c;自然可以while循环实现&#xff1a;i 、i1、…

着色器预热?为什么 Flutter 需要?为什么原生 App 不需要?那 Compose 呢?Impeller 呢?

依旧是来自网友的问题&#xff0c;这个问题在一定程度上还是很意思的&#xff0c;因为大家可能会想&#xff0c;Flutter 使用 skia&#xff0c;原生 App 是用 skia &#xff0c;那为什么在 Flutter 上会有着色器预热&#xff08;Shader Warmup&#xff09;这样的说法&#xff1…

使用getline()从文件中读取一行字符串

我们知道&#xff0c;getline() 方法定义在 istream 类中&#xff0c;而 fstream 和 ifstream 类继承自 istream 类&#xff0c;因此 fstream 和 ifstream 的类对象可以调用 getline() 成员方法。 当文件流对象调用 getline() 方法时&#xff0c;该方法的功能就变成了从指定文件…

lnternet 发展史

一&#xff0c;lnternet 发展史 ARPA net &#xff08;上世纪50年代二战结束&#xff09; 无线 战场指挥通信协议落后 TCP/IP 包交换 WEB (70年代 ) 80年代 90年代 二&#xff0c;互联网的典型应用&#xff1a; 96年到2008年 第一代技术…

8.ApplicationContext常见实现

ClassPathXmlApplicationContext 基于classpath下xml格式的配置文件来创建 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-i…

Linux-页表如何对物理内存进行映射

1.1 页框和页帧 我们知道通过页表可以将虚拟内存映射到对应的物理内存&#xff0c;而操作系统对于物理内存的管理并不是以字节为单位的&#xff0c;而是将物理内存分为许多大小为4KB的块&#xff0c;称为页框或页帧&#xff0c;这就是为什么我们在创建共享内存是建议将大小设定…

【server】3、注册中心与配置中心

1、服务注册与发现 1.1、consul 1.1.1 是什么 官网&#xff1a; Consul by HashiCorp spring-cloud-consul: Spring Cloud Consul :: Spring Cloud Consul gitHub 官网 &#xff1a;GitHub - hashicorp/consul: Consul is a distributed, highly available, and data cent…

上海-灵曼科技(面经)

上海-灵曼科技 hr电话面 个人简介 个人信息的询问 是否知道芋道框架 技术面 算法题 14. 最长公共前缀&#xff08;写出来即可&#xff09; 聊一下Docker Docker核心概念总结Docker实战 聊一下AOP Spring AOP详解 聊一下JWT JWT 基础概念详解JWT 身份认证优缺点分析 Spri…

2024华为OD机试真题- 电脑病毒感染-(C++/Python)-C卷D卷-200分

2024华为OD机试题库-(C卷+D卷)-(JAVA、Python、C++) 题目描述 一个局域网内有很多台电脑,分别标注为 0 ~ N-1 的数字。相连接的电脑距离不一样,所以感染时间不一样,感染时间用 t 表示。 其中网络内一台电脑被病毒感染,求其感染网络内所有的电脑最少需要多长时间。如果…

Spzhi知识付费社区主题免费下载

主题介绍 用typecho打造一款知识付费社区主题&#xff0c;带会员功能&#xff0c;为内容创业者提供知识变现一站式解决方案&#xff0c;让用户沉淀到自己的平台&#xff0c;形成自己的私域流量池&#xff0c;打造流量闭环&#xff0c;零门槛搭建你的移动网络课堂 主题功能 支…

RpcChannel的调用过程

目录 1. RPC调用方&#xff08;caller&#xff09;的调用(消费)过程 2.在caller下创建文件&#xff1a;calluserservice.cc 3.在src的include下创建文件&#xff1a;mprpcchannel.h 4.在src下创建mprpcchannel.cc 1. RPC调用方&#xff08;caller&#xff09;的调用(消费)过…

Python:Python基础知识(注释、命名、数据类型、运算符)

四、Python基础知识&#xff08;注释、命名、数据类型、运算符&#xff09; 1.注释 Python有两种注释方法&#xff1a;单行注释和多行注释。单行注释以#开头&#xff0c;多行注释以‘’‘开头和结尾。 2.命名规则 命名规则: 大小写字母、数字、下划线和汉字等字符及组合&am…

Three.js机器人与星系动态场景(三):如何实现动画

在前面的博客中分别介绍了如何快速搭建3D交互场景以及通过坐标辅助工具加深对坐标系的理解。本文将继续探讨其中动画实现的细节。通过调整rotation加深对动画的印象。 Three.js机器人与星系动态场景&#xff1a;实现3D渲染与交互式控制-CSDN博客 Three.js机器人与星系动态场景…

如何在操作使用ufw设置防火墙

UFW&#xff08;简单防火墙&#xff09;是用于管理iptables防火墙规则的用户友好型前端。它的主要目标是使iptables的管理更容易。 在学习Linux的时候大家一般都会关心命令&#xff0c;Posix API和桌面等&#xff0c;很少会去了解防护墙。其实除了一些网络安全厂商提供的付费防…

大疆2025校招内推

需要内推码的请留言哦 期待你的加入

【你真的了解double和float吗】

&#x1f308;个人主页&#xff1a;努力学编程’ ⛅个人推荐&#xff1a;基于java提供的ArrayList实现的扑克牌游戏 |C贪吃蛇详解 ⚡学好数据结构&#xff0c;刷题刻不容缓&#xff1a;点击一起刷题 &#x1f319;心灵鸡汤&#xff1a;总有人要赢&#xff0c;为什么不能是我呢 …

2024亚洲国际餐饮展览会(北京餐饮展|火锅展|预制菜展会)

2024北京餐饮展会&#xff0c;2024北京食材展会&#xff0c;2024北京火锅展会&#xff0c;2024北京火锅食材展会&#xff0c;2024北京预制菜展会&#xff0c;2024北京预制食材展会&#xff0c; 2024亚洲国际餐饮展览会&#xff08;北京餐饮展|火锅展|预制菜展会&#xff09; …