java电子围栏
java版的电子围栏违规判断经过测试准确率百分之百经过各大AI审查已经无限趋近于完美本工具类支持圆形矩形多边形性能与准确率都有保障实测判断多边形围栏单线程执行千万次次只需要十几秒多线程只需要1秒废话不说直接上代码先贴工具类代码import com.core.entity.Point;import java.util.List;/*** 描述: 电子围栏计算【V4.2 上线定稿防御增强版】* 版本: 4.2.0* 日期: 2026-08-13* 数学前提与约束重要* 1. 多边形边界容差采用【经纬度平面求垂足 Haversine球面距离】组合方案* ✅ 围栏边长 ≤50km垂足误差厘米~分米级国内园区/城配业务完全可用* ⚠️ 围栏边长 100km平面垂足和球面大圆垂足存在偏差会引入数米~数十米误差不推荐使用* 2. AABB轴对齐矩形说明* ✅ 天然支持跨本初子午线(0°经度)* ⚠️ 跨±180°国际日期变更线矩形调用方必须传入 minLng maxLng 格式例minLng170,maxLng-170否则判定失效* ⚠️ 斜旋转矩形禁止使用本方法斜矩形请组装4个顶点调用多边形方法 isInPolygon* 3. 多边形射线法不支持跨±180°国际日期变更线围栏* 4. 强制约束围栏坐标、点位【坐标系必须完全一致 WGS84 / GCJ02 / BD09 不可混用】*/public class GeofencingUtils {/*** WGS84 椭球长半轴(赤道半径) 米Haversine公式使用*/private static final double EARTH_RADIUS 6378137.0;private static double rad(double d) {return d * Math.PI / 180.0;}/*** 圆形围栏判断球面大圆距离全球通用* param radius 半径米* param center 圆心点位* param point 待判断点位* return true 在圆内*/public static boolean isInCircle(double radius, Point center, Point point) {// 防御判空if (center null || point null) {return false;}double radLat1 rad(center.getLat());double radLat2 rad(point.getLat());double a radLat1 - radLat2;double b rad(center.getLng()) - rad(point.getLng());double temp Math.pow(Math.sin(a / 2), 2) Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2);if (temp 1.0) temp 1.0;if (temp 0.0) temp 0.0;double s 2 * Math.asin(Math.sqrt(temp));s s * EARTH_RADIUS;return s radius;}/*** AABB轴对齐矩形仅适用于正北正南对齐矩形* ⚠️ 斜旋转矩形绝对不要用斜矩形请组装4个顶点调用多边形方法 isInPolygon* ⚠️ 跨±180°日期变更线场景必须传入 minLng maxLng否则逻辑失效* param lng 检测点经度* param lat 检测点纬度* param minLng 最小经度跨180场景填大数如170* param maxLng 最大经度跨180场景填小数如-170* param minLat 最小纬度* param maxLat 最大纬度* return true 在矩形包围盒内*/public static boolean isInRectangleArea(double lng, double lat, double minLng, double maxLng,double minLat, double maxLat) {if (isInRange(lat, minLat, maxLat)) {if (minLng * maxLng 0) {return isInRange(lng, minLng, maxLng);} else {if (Math.abs(minLng) Math.abs(maxLng) 180) {return isInRange(lng, minLng, maxLng);} else {double left Math.max(minLng, maxLng);double right Math.min(minLng, maxLng);return isInRange(lng, left, 180) || isInRange(lng, right, -180);}}}return false;}private static boolean isInRange(double point, double left, double right) {return point Math.min(left, right) point Math.max(left, right);}/*** 球面点到线段【真实地面距离(米)】* 原理经纬度平面求垂足 → Haversine计算球面米距* ⚠️ 适用约束围栏边长 ≤50km超大范围100km会存在球面垂足近似偏差*/private static double pointToSegmentSphereMeter(Point target, Point segStart, Point segEnd) {double lng0 target.getLng();double lat0 target.getLat();double lng1 segStart.getLng();double lat1 segStart.getLat();double lng2 segEnd.getLng();double lat2 segEnd.getLat();double a lng0 - lng1;double b lat0 - lat1;double c lng2 - lng1;double d lat2 - lat1;double dot a * c b * d;double lenSq c * c d * d;double param;if (lenSq 0) {param -1;} else {param dot / lenSq;}// 平面投影垂足经纬度double footLng, footLat;if (param 0) {footLng lng1;footLat lat1;} else if (param 1) {footLng lng2;footLat lat2;} else {footLng lng1 param * c;footLat lat1 param * d;}// Haversine 计算目标点 ↔ 垂足 球面大圆距离米return calcHaversineMeter(target.getLng(), target.getLat(), footLng, footLat);}/*** Haversine 计算两点球面大圆距离返回米* ✅ 增加浮点钳位保护防止asin入参越界产生NaN*/private static double calcHaversineMeter(double lngA, double latA, double lngB, double latB) {double radLat1 rad(latA);double radLat2 rad(latB);double a radLat1 - rad(latB);double b rad(lngA) - rad(lngB);double temp Math.pow(Math.sin(a / 2), 2) Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2);// 钳位处理防止浮点精度溢出导致 asin NaNif (temp 1.0) temp 1.0;if (temp 0.0) temp 0.0;double s 2 * Math.asin(Math.sqrt(temp));return s * EARTH_RADIUS;}/*** 多边形围栏标准奇偶射线法 【球面真实米级边界容差】* ⚠️ 限制1.暂不支持跨±180°日期变更线多边形2.边长100km存在球面垂足近似误差* param point 检测点位* param pts 多边形顶点集合顺时针/逆时针均可简单不自交多边形* param toleranceMeter 边界容差(米)普通GPS推荐3米* return true 在内部/边界容差范围内*/public static boolean isInPolygon(Point point, ListPoint pts, double toleranceMeter) {// 防御校验空对象、顶点不足直接返回falseif (point null || pts null || pts.size() 3) {return false;}// 容差负数保护强制最小为0if (toleranceMeter 0) {toleranceMeter 0;}boolean inside false;int size pts.size();for (int i 0, j size - 1; i size; j i) {Point pi pts.get(i);Point pj pts.get(j);// 顶点对象防御顶点null直接跳过这条边容错避免NPEif (pi null || pj null) {continue;}double distMeter pointToSegmentSphereMeter(point, pi, pj);if (distMeter toleranceMeter) {return true;}// 标准奇偶射线穿透算法if (((pi.getLat() point.getLat()) ! (pj.getLat() point.getLat()))) {double lngIntersect ((point.getLat() - pi.getLat()) * (pj.getLng() - pi.getLng()))/ (pj.getLat() - pi.getLat()) pi.getLng();if (point.getLng() lngIntersect) {inside !inside;}}}return inside;}/*** 重载兼容老代码默认3米球面容差*/public static boolean isInPolygon(Point point, ListPoint pts) {return isInPolygon(point, pts, 3.0);}}再贴实体类package com.core.entity;import lombok.Data;import lombok.ToString;DataToStringpublic class Point {/*** 经度-180~180东经正西经负*/private double lng;/*** 纬度-90~90北纬正南纬负*/private double lat;public Point(double lng, double lat) {this.lng lng;this.lat lat;}}说明用哪种坐标系不重要但是围栏的经纬度与要判断的坐标点必须保持是同一种坐标系踩坑记录如果要用行政区划来做围栏国内的行政区划例如上海市的边界范围是由好几个独立模块组成的所以做判断的时候这几个独立模块要分开来单独判断否则会导致判断不准确

相关新闻

Seedance 2.0:下一代分布式任务编排与调度引擎深度解析

Seedance 2.0:下一代分布式任务编排与调度引擎深度解析

引言:为什么需要 Seedance 2.0? 在当今云原生与微服务架构盛行的时代,复杂的业务逻辑往往被拆分为无数个细粒度的任务。如何高效、可靠、可观测地编排与调度这些任务,成为开发者面临的核心挑战。传统的定时任务框架(如…

2026/10/12 3:44:50 阅读更多 →
嵌入式从0到精通——数据结构

嵌入式从0到精通——数据结构

一、基本概念数据结构数据结构:存储具有一种或多种特定关系的数据的集合(如何组织和存储数据)。程序设计 数据结构 算法数据与数据之间的关系逻辑结构 : 数据元素与元素之间的关系集合 :数据元素与元素之间关系平等线…

2026/10/12 3:48:22 阅读更多 →
如何快速切换OneNav主题:从默认到自定义的完整指南

如何快速切换OneNav主题:从默认到自定义的完整指南

如何快速切换OneNav主题:从默认到自定义的完整指南 【免费下载链接】onenav 使用PHP SQLite 3开发的书签管理系统,将浏览器书签集中式管理,做到一处部署,随处访问。 项目地址: https://gitcode.com/gh_mirrors/on/onenav …

2026/10/12 6:06:30 阅读更多 →

最新新闻

Docker运行Redis生产实践:从单节点到集群的高可用落地

Docker运行Redis生产实践:从单节点到集群的高可用落地

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 4:59:19 阅读更多 →
线性回归正规方程:闭式解原理、实现与工程权衡

线性回归正规方程:闭式解原理、实现与工程权衡

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 4:59:19 阅读更多 →
Llama 3架构精读与FP8量化实战:128K长上下文压测

Llama 3架构精读与FP8量化实战:128K长上下文压测

Llama 3 发布那几天,整个模型圈都在刷分。我花了两天时间把技术报告和权重包全部过了一遍,顺手在现有的推理环境里做了 FP8 量化,又把长上下文的压力测试跑了几轮。今天这篇文章就是把“精读笔记 量化实操 长上下文实测”三个部分完整复盘一…

2026/10/13 4:59:19 阅读更多 →
软件工程开发阶段实战:从编码到可交付的工程化指南

软件工程开发阶段实战:从编码到可交付的工程化指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 4:59:19 阅读更多 →
SSM框架实战:求职招聘信息管理系统设计与实现

SSM框架实战:求职招聘信息管理系统设计与实现

1. 项目概述与需求拆解做Java Web开发这几年,SSM框架几乎是我接手毕业设计和企业小项目时最常碰到的组合。这个"求职招聘信息管理系统"表面上看着是个典型的管理系统,实际上把SSM框架的三大组件(Spring、SpringMVC、MyBatis&#x…

2026/10/13 4:59:19 阅读更多 →
实习考勤不内耗:习讯云打卡全流程避坑指南

实习考勤不内耗:习讯云打卡全流程避坑指南

实习第一个月,我差点被习讯云实习考勤打卡逼到内耗。每天到公司第一件事不是换工牌,而是掏出手机打开习讯云,看定位转圈、看按钮变灰、看页面弹“不在考勤范围”,一套流程下来,本来就不多的精气神先耗掉三分之一。后来…

2026/10/13 4:58:19 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →