定位区域判断更新,更加准确

This commit is contained in:
磷叶 2025-04-10 19:56:50 +08:00
parent 8534e08033
commit 578adc465c
11 changed files with 222 additions and 79 deletions

View File

@ -24,6 +24,7 @@ import org.locationtech.jts.io.WKTWriter;
import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransform;
import org.locationtech.jts.operation.distance.DistanceOp;
import java.io.File; import java.io.File;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -243,51 +244,37 @@ public class GeoUtils {
double toleranceValue = tolerance == null ? 0 : tolerance.doubleValue(); double toleranceValue = tolerance == null ? 0 : tolerance.doubleValue();
GeometryFactory geometryFactory = new GeometryFactory(); GeometryFactory geometryFactory = new GeometryFactory();
Coordinate coordinate = new Coordinate(lon, lat); Point point = geometryFactory.createPoint(new Coordinate(lon, lat));
Point point = geometryFactory.createPoint(coordinate);
if (polygon != null && polygon.contains(point)) { if (polygon != null && polygon.contains(point)) {
return true; return true;
} else { } else {
// 获取多边形的外边界 // 计算点到多边形的最短距离若在误差范围内则认为在多边形内
Coordinate[] coordinates = polygon.getCoordinates(); double distance = calculateMinDistanceToPolygon(polygon, lon, lat);
for (Coordinate coord : coordinates) { return distance <= toleranceValue;
double distance = calculateDistance(lat, lon, coord.y, coord.x);
if (distance <= toleranceValue) {
return true;
}
}
return false;
} }
} }
/** /**
* 判断一个点是否在一个缩短后的圆形区域内 * 判断一个点是否在缩短后的区域内
* */ * */
public static boolean isInPolygonWithShorten(BigDecimal longitude, BigDecimal latitude, Geometry polygon, BigDecimal shortenDistance) { public static boolean isInPolygonWithShorten(BigDecimal longitude, BigDecimal latitude, Geometry polygon, BigDecimal shortenDistance) {
if (longitude == null || latitude == null || polygon == null ) { if (longitude == null || latitude == null || polygon == null) {
return false; return false;
} }
double lon = longitude.doubleValue(); double lon = longitude.doubleValue();
double lat = latitude.doubleValue(); double lat = latitude.doubleValue();
double shortenDistanceValue = shortenDistance == null ? 0 : shortenDistance.doubleValue(); double shortenDistanceValue = shortenDistance == null ? 0 : shortenDistance.doubleValue();
GeometryFactory geometryFactory = new GeometryFactory();
Coordinate coordinate = new Coordinate(lon, lat); Point point = GEOMETRY_FACTORY.createPoint(new Coordinate(lon, lat));
Point point = geometryFactory.createPoint(coordinate);
if (polygon.contains(point)) { if (polygon.contains(point)) {
// 获取多边形的外边界 // 计算点到多边形边界的最短距离
Coordinate[] coordinates = polygon.getCoordinates(); double minDistance = calculateMinDistanceToPolygon(polygon, lon, lat);
for (Coordinate coord : coordinates) { // 如果最短距离小于缩短距离则认为点在缩短区域外
double distance = calculateDistance(lat, lon, coord.y, coord.x); return minDistance > shortenDistanceValue;
if (shortenDistanceValue >= distance) {
return false;
}
}
return true;
} else {
return false;
} }
return false;
} }
// 将角度转换为弧度 // 将角度转换为弧度
@ -346,34 +333,65 @@ public class GeoUtils {
return EARTH_RADIUS * c; // 距离 return EARTH_RADIUS * c; // 距离
} }
/** /**
* 判获取到最近一个运营区 * 计算给定点到多边形的最短距离单位
* */ */
public static boolean getNearestOperatingArea (String longitude, String latitude, List<Geometry> polygon) { public static double calculateMinDistanceToPolygon(Geometry polygon, double lon, double lat) {
double lon = Double.parseDouble(longitude); Point point = GEOMETRY_FACTORY.createPoint(new Coordinate(lon, lat));
double lat = Double.parseDouble(latitude);
GeometryFactory geometryFactory = new GeometryFactory(); // 获取多边形的边界
Coordinate coordinate = new Coordinate(lon, lat); Geometry boundary = polygon.getBoundary();
Point point = geometryFactory.createPoint(coordinate); Coordinate[] coordinates = boundary.getCoordinates();
for (Geometry geometry : polygon) { double minDistance = Double.MAX_VALUE;
if (geometry.contains(point)) {
return true;
}else{
} // 遍历多边形的每条边
for (int i = 0; i < coordinates.length - 1; i++) {
Coordinate c1 = coordinates[i];
Coordinate c2 = coordinates[i + 1];
// 计算点到线段的最短距离
double distance = calculateDistanceToSegment(lat, lon, c1.y, c1.x, c2.y, c2.x);
minDistance = Math.min(minDistance, distance);
} }
return false;
return minDistance;
} }
/** /**
* 计算给定点到多边形的最短距离 * 计算点到线段的最短距离单位
* */ */
public double calculateMinDistanceToPolygon(Geometry polygon, double lon, double lat) { private static double calculateDistanceToSegment(double lat, double lon,
Coordinate coord = new Coordinate(lon, lat); double lat1, double lon1,
Point point = new GeometryFactory().createPoint(coord); double lat2, double lon2) {
return polygon.distance(point); // 返回给定点到多边形的最短距离 // 计算点到线段两端点的距离
double d1 = calculateDistance(lat, lon, lat1, lon1);
double d2 = calculateDistance(lat, lon, lat2, lon2);
double lineLength = calculateDistance(lat1, lon1, lat2, lon2);
// 如果线段长度接近0返回到端点的距离
if (lineLength < 0.000001) {
return Math.min(d1, d2);
}
// 计算点到线段的投影是否在线段上
double t = ((lat - lat1) * (lat2 - lat1) + (lon - lon1) * (lon2 - lon1)) /
((lat2 - lat1) * (lat2 - lat1) + (lon2 - lon1) * (lon2 - lon1));
if (t < 0) {
return d1; // 最近点是第一个端点
}
if (t > 1) {
return d2; // 最近点是第二个端点
}
// 计算投影点的坐标
double projLat = lat1 + t * (lat2 - lat1);
double projLon = lon1 + t * (lon2 - lon1);
// 返回点到投影点的距离
return calculateDistance(lat, lon, projLat, projLon);
} }
} }

View File

@ -0,0 +1,33 @@
package com.ruoyi.bst.area.domain.vo;
import com.ruoyi.bst.areaSub.domain.AreaSubVO;
import lombok.Data;
/**
* 定位所属区域信息
*/
@Data
public class LocationAreaVO {
// 是否在运营区内
private Boolean isInArea;
// 是否在运营区最小内边界
private Boolean isInAreaMin;
// 是否在运营区最大外边界
private Boolean isInAreaMax;
// 是否在禁行区内
private Boolean isInNoRidingArea;
// 位于的禁行区
private AreaSubVO inNoRidingArea;
// 是否靠近禁行区
private Boolean isNearNoRidingArea;
// 靠近的禁行区
private AreaSubVO nearNoRidingArea;
}

View File

@ -1,10 +1,12 @@
package com.ruoyi.bst.area.service; package com.ruoyi.bst.area.service;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
import com.ruoyi.bst.area.domain.Area; import com.ruoyi.bst.area.domain.Area;
import com.ruoyi.bst.area.domain.AreaQuery; import com.ruoyi.bst.area.domain.AreaQuery;
import com.ruoyi.bst.area.domain.AreaVO; import com.ruoyi.bst.area.domain.AreaVO;
import com.ruoyi.bst.area.domain.vo.LocationAreaVO;
/** /**
* 运营区Service接口 * 运营区Service接口
@ -83,4 +85,13 @@ public interface AreaService
*/ */
public List<AreaVO> selectSimpleList(AreaQuery query); public List<AreaVO> selectSimpleList(AreaQuery query);
/**
* 查询定位所属区域信息
* @param lon 经度
* @param lat 纬度
* @param areaId 运营区ID
* @return 定位所属区域信息
*/
public LocationAreaVO selectLocationArea(BigDecimal lon, BigDecimal lat, Long areaId);
} }

View File

@ -1,5 +1,6 @@
package com.ruoyi.bst.area.service.impl; package com.ruoyi.bst.area.service.impl;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Geometry;
@ -10,8 +11,12 @@ import com.github.pagehelper.PageHelper;
import com.ruoyi.bst.area.domain.Area; import com.ruoyi.bst.area.domain.Area;
import com.ruoyi.bst.area.domain.AreaQuery; import com.ruoyi.bst.area.domain.AreaQuery;
import com.ruoyi.bst.area.domain.AreaVO; import com.ruoyi.bst.area.domain.AreaVO;
import com.ruoyi.bst.area.domain.vo.LocationAreaVO;
import com.ruoyi.bst.area.mapper.AreaMapper; import com.ruoyi.bst.area.mapper.AreaMapper;
import com.ruoyi.bst.area.service.AreaService; import com.ruoyi.bst.area.service.AreaService;
import com.ruoyi.bst.area.utils.AreaUtil;
import com.ruoyi.bst.areaSub.domain.AreaSubVO;
import com.ruoyi.bst.areaSub.service.AreaSubService;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.collection.CollectionUtils; import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.common.utils.map.GeoUtils; import com.ruoyi.common.utils.map.GeoUtils;
@ -31,6 +36,9 @@ public class AreaServiceImpl implements AreaService
@Autowired @Autowired
private AreaMapper areaMapper; private AreaMapper areaMapper;
@Autowired
private AreaSubService areaSubService;
/** /**
* 查询运营区 * 查询运营区
* *
@ -150,4 +158,20 @@ public class AreaServiceImpl implements AreaService
return areaMapper.logicDel(ids); return areaMapper.logicDel(ids);
} }
@Override
public LocationAreaVO selectLocationArea(BigDecimal lon, BigDecimal lat, Long areaId) {
if (lon == null || lat == null || areaId == null) {
return null;
}
// 查询运营区
AreaVO area = this.selectAreaById(areaId);
if (area == null) {
return null;
}
// 查询运营区内的禁行区
List<AreaSubVO> noRidingList = areaSubService.selectNoRidingListByAreaId(areaId);
return AreaUtil.getLocationArea(lon, lat, area, noRidingList);
}
} }

View File

@ -1,23 +1,27 @@
package com.ruoyi.bst.area.utils; package com.ruoyi.bst.area.utils;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List;
import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Geometry;
import com.ruoyi.bst.area.domain.Area; import com.ruoyi.bst.area.domain.Area;
import com.ruoyi.bst.area.domain.AreaVO; import com.ruoyi.bst.area.domain.AreaVO;
import com.ruoyi.bst.area.domain.vo.LocationAreaVO;
import com.ruoyi.bst.areaSub.domain.AreaSubVO;
import com.ruoyi.bst.areaSub.utils.AreaSubUtil;
import com.ruoyi.common.utils.map.GeoUtils; import com.ruoyi.common.utils.map.GeoUtils;
public class AreaUtil { public class AreaUtil {
// 是否在运营区内 // 是否在运营区内0误差
public static boolean isInArea(Area area, BigDecimal longitude, BigDecimal latitude) { public static boolean isInArea(Area area, BigDecimal longitude, BigDecimal latitude) {
Geometry geometry = GeoUtils.fromWkt(area.getBoundary()); Geometry geometry = GeoUtils.fromWkt(area.getBoundary());
if (geometry == null) { if (geometry == null) {
return false; return false;
} }
return GeoUtils.isInPolygonWithTolerance(longitude, latitude, geometry, area.getOutageDistance()); return GeoUtils.isInPolygonWithTolerance(longitude, latitude, geometry, BigDecimal.ZERO);
} }
// 是否在运营区最小内边界 // 是否在运营区最小内边界
@ -44,4 +48,35 @@ public class AreaUtil {
return GeoUtils.isInPolygonWithTolerance(longitude, latitude, geometry, area.getOutageDistance()); return GeoUtils.isInPolygonWithTolerance(longitude, latitude, geometry, area.getOutageDistance());
} }
public static LocationAreaVO getLocationArea(BigDecimal lon, BigDecimal lat, AreaVO area, List<AreaSubVO> noRidingList) {
if (lon == null || lat == null) {
return null;
}
LocationAreaVO vo = new LocationAreaVO();
// 是否在运营区内
vo.setIsInArea(AreaUtil.isInArea(area, lon, lat));
// 是否在运营区最小内边界
vo.setIsInAreaMin(AreaUtil.isInAreaMin(area, lon, lat));
// 是否在运营区最大外边界
vo.setIsInAreaMax(AreaUtil.isInAreaMax(area, lon, lat));
// 是否在禁行区内
AreaSubVO inNoRidingArea = AreaSubUtil.getInAreaSub(noRidingList, lon, lat, area.getError());
vo.setInNoRidingArea(inNoRidingArea);
vo.setIsInNoRidingArea(inNoRidingArea != null);
// 靠近运营区边界时的播报距离
BigDecimal boundaryDistance = area.getBoundaryDistance();
// 是否在禁行区内
AreaSubVO nearAreaSub = AreaSubUtil.getNearAreaSub(noRidingList, lon, lat, area.getError(), boundaryDistance);
vo.setNearNoRidingArea(nearAreaSub);
vo.setIsNearNoRidingArea(nearAreaSub != null);
return vo;
}
} }

View File

@ -47,24 +47,33 @@ public class AreaSubUtil {
} }
/** /**
* 获取靠近的区域 * 获取靠近的区域而非是在区域内
* @param areaSubList 区域列表 * @param areaSubList 区域列表
* @param longitude 经度 * @param longitude 经度
* @param latitude 纬度 * @param latitude 纬度
* @param error 误差 * @param distance 靠近多少
* @return 靠近的区域 * @return 靠近的区域
*/ */
public static AreaSubVO getNearAreaSub(List<AreaSubVO> areaSubList, BigDecimal longitude, BigDecimal latitude, BigDecimal error) { public static AreaSubVO getNearAreaSub(List<AreaSubVO> areaSubList, BigDecimal longitude, BigDecimal latitude, BigDecimal areaError, BigDecimal distance) {
if (CollectionUtils.isEmptyElement(areaSubList)) { if (CollectionUtils.isEmptyElement(areaSubList)) {
return null; return null;
} }
BigDecimal tolerance = BigDecimal.ZERO; // 误差距离
if (areaError != null) {
tolerance = areaError;
}
for (AreaSubVO area : areaSubList) { for (AreaSubVO area : areaSubList) {
Geometry geometry = GeoUtils.fromWkt(area.getBoundary()); Geometry geometry = GeoUtils.fromWkt(area.getBoundary());
if (geometry == null) { if (geometry == null) {
continue; continue;
} }
boolean inCircle = GeoUtils.isInPolygonWithTolerance(longitude, latitude, geometry, error); if (area.getError() != null) {
if (inCircle) { tolerance = area.getError();
}
boolean inMax = GeoUtils.isInPolygonWithTolerance(longitude, latitude, geometry, distance); // 在外侧误差范围内
boolean inCircle = GeoUtils.isInPolygonWithTolerance(longitude, latitude, geometry, tolerance); // 在内部
// 不在内部但在外侧误差范围内视为靠近
if (!inCircle && inMax) {
return area; return area;
} }
} }

View File

@ -230,7 +230,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</insert> </insert>
<update id="updateDevice" parameterType="Device"> <update id="updateDevice" parameterType="Device">
update bst_device update bst_device bd
<trim prefix="SET" suffixOverrides=","> <trim prefix="SET" suffixOverrides=",">
<include refid="updateColumns"/> <include refid="updateColumns"/>
</trim> </trim>

View File

@ -163,6 +163,7 @@ public class OrderValidatorImpl implements OrderValidator{
ServiceUtil.assertion(!DeviceStatus.canUse().contains(device.getStatus()), "ID为%s的车辆当前状态不可使用", device.getId()); ServiceUtil.assertion(!DeviceStatus.canUse().contains(device.getStatus()), "ID为%s的车辆当前状态不可使用", device.getId());
ServiceUtil.assertion(MathUtils.smallerThan(device.getRemainingPower(), device.getAreaUndercharge()), "ID为%s的车辆电量不足%s%%,暂时无法使用", device.getId(), device.getAreaUndercharge()); ServiceUtil.assertion(MathUtils.smallerThan(device.getRemainingPower(), device.getAreaUndercharge()), "ID为%s的车辆电量不足%s%%,暂时无法使用", device.getId(), device.getAreaUndercharge());
ServiceUtil.assertion(OrderStatus.PROCESSING.getCode().equals(device.getOrderStatus()), "ID为%s的车辆当前有正在进行的订单无法使用", device.getId()); ServiceUtil.assertion(OrderStatus.PROCESSING.getCode().equals(device.getOrderStatus()), "ID为%s的车辆当前有正在进行的订单无法使用", device.getId());
ServiceUtil.assertion(device.getAreaId() == null, "当前车辆未绑定运营区,无法使用");
// 设备能否在该订单上使用换车 // 设备能否在该订单上使用换车
if (order != null) { if (order != null) {

View File

@ -154,10 +154,10 @@ public class OrderUtil {
} }
// 通过设备定位获取是否在运营区 // 通过设备定位获取是否在运营区
boolean deviceInArea = AreaUtil.isInArea(area, device.getLongitude(), device.getLatitude()); // 是否在运营区 boolean deviceInArea = AreaUtil.isInAreaMax(area, device.getLongitude(), device.getLatitude()); // 是否在运营区
vo.setDeviceInArea(deviceInArea); vo.setDeviceInArea(deviceInArea);
// 通过手机定位获取是否在运营区 // 通过手机定位获取是否在运营区
boolean mobileInArea = AreaUtil.isInArea(area, lon, lat); // 是否在运营区 boolean mobileInArea = AreaUtil.isInAreaMax(area, lon, lat); // 是否在运营区
vo.setMobileInArea(mobileInArea); vo.setMobileInArea(mobileInArea);
// 是否在运营区 // 是否在运营区
boolean inArea = deviceInArea || mobileInArea; boolean inArea = deviceInArea || mobileInArea;

View File

@ -1,24 +1,23 @@
package com.ruoyi.iot.service.impl; package com.ruoyi.iot.service.impl;
import java.math.BigDecimal;
import java.time.Duration; import java.time.Duration;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import com.ruoyi.bst.device.domain.enums.DeviceUnLockType;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ruoyi.bst.area.domain.AreaVO; import com.ruoyi.bst.area.domain.AreaVO;
import com.ruoyi.bst.area.domain.vo.LocationAreaVO;
import com.ruoyi.bst.area.service.AreaService; import com.ruoyi.bst.area.service.AreaService;
import com.ruoyi.bst.area.utils.AreaUtil; import com.ruoyi.bst.area.utils.AreaUtil;
import com.ruoyi.bst.areaSub.domain.AreaSubVO; import com.ruoyi.bst.areaSub.domain.AreaSubVO;
import com.ruoyi.bst.areaSub.service.AreaSubService; import com.ruoyi.bst.areaSub.service.AreaSubService;
import com.ruoyi.bst.areaSub.utils.AreaSubUtil;
import com.ruoyi.bst.device.domain.DeviceVO; import com.ruoyi.bst.device.domain.DeviceVO;
import com.ruoyi.bst.device.domain.enums.DeviceLockStatus; import com.ruoyi.bst.device.domain.enums.DeviceLockStatus;
import com.ruoyi.bst.device.domain.enums.DeviceStatus; import com.ruoyi.bst.device.domain.enums.DeviceStatus;
import com.ruoyi.bst.device.domain.enums.DeviceUnLockType;
import com.ruoyi.bst.device.service.DeviceIotService; import com.ruoyi.bst.device.service.DeviceIotService;
import com.ruoyi.bst.device.service.DeviceService; import com.ruoyi.bst.device.service.DeviceService;
import com.ruoyi.bst.device.utils.DeviceUtil; import com.ruoyi.bst.device.utils.DeviceUtil;
@ -152,14 +151,17 @@ public class IotReceiveServiceImpl implements IotReceiveService {
boolean isOpen = DeviceLockStatus.OPEN.getCode().equals(device.getLockStatus()); // 是否开锁 boolean isOpen = DeviceLockStatus.OPEN.getCode().equals(device.getLockStatus()); // 是否开锁
boolean isQLocked = DeviceStatus.Q_LOCKED.getCode().equals(device.getStatus()); // 是否强制断电 boolean isQLocked = DeviceStatus.Q_LOCKED.getCode().equals(device.getStatus()); // 是否强制断电
// 是否在运营区最大外边界
boolean isInAreaMax = AreaUtil.isInAreaMax(area, device.getLongitude(), device.getLatitude());
// 是否在禁行区内
AreaSubVO inAreaSub = AreaSubUtil.getInAreaSub(noRidingList, device.getLongitude(), device.getLatitude(), area.getError());
boolean isInNoRidingArea = inAreaSub != null;
// 是否有正在使用的订单 // 是否有正在使用的订单
boolean hasOrder = device.getOrderDeviceId() != null && OrderDeviceStatus.USING.getCode().equals(device.getOrderDeviceStatus()); boolean hasOrder = device.getOrderDeviceId() != null && OrderDeviceStatus.USING.getCode().equals(device.getOrderDeviceStatus());
// 获取车辆位置信息
LocationAreaVO locationArea = AreaUtil.getLocationArea(device.getLongitude(), device.getLatitude(), area, noRidingList);
boolean isInArea = locationArea.getIsInArea() != null && locationArea.getIsInArea();
boolean isInAreaMin = locationArea.getIsInAreaMin() != null && locationArea.getIsInAreaMin();
boolean isInAreaMax = locationArea.getIsInAreaMax() != null && locationArea.getIsInAreaMax();
boolean isInNoRidingArea = locationArea.getIsInNoRidingArea() != null && locationArea.getIsInNoRidingArea();
boolean isNearNoRidingArea = locationArea.getIsNearNoRidingArea() != null && locationArea.getIsNearNoRidingArea();
// 在运营区内并且不在禁行区内并且车辆为强制断电状态为车辆上电 // 在运营区内并且不在禁行区内并且车辆为强制断电状态为车辆上电
if (isInAreaMax && !isInNoRidingArea && isQLocked && !isOpen && hasOrder) { if (isInAreaMax && !isInNoRidingArea && isQLocked && !isOpen && hasOrder) {
deviceIotService.unlock(device, DeviceUnLockType.BACK_AREA, "重新返回运营区上电", false); deviceIotService.unlock(device, DeviceUnLockType.BACK_AREA, "重新返回运营区上电", false);
@ -176,9 +178,8 @@ public class IotReceiveServiceImpl implements IotReceiveService {
deviceIotService.qLock(device, "超出运营区外边界最大值,强制断电", false); deviceIotService.qLock(device, "超出运营区外边界最大值,强制断电", false);
return 1; return 1;
} }
boolean isInArea = AreaUtil.isInArea(area, device.getLongitude(), device.getLatitude()); // 是否在运营区内
boolean isInAreaMin = AreaUtil.isInAreaMin(area, device.getLongitude(), device.getLatitude()); // 是否在运营区最小内边界
// 一次警告 // 一次警告
log.info("车辆MAC{},定位:{},{}。是否在运营区内:{},是否在运营区最小内边界:{},是否在运营区最大外边界:{}", device.getMac(), device.getLongitude(), device.getLatitude(), isInArea, isInAreaMin, isInAreaMax);
if (isInArea && !isInAreaMin) { if (isInArea && !isInAreaMin) {
deviceIotService.play(device, IotConstants.PLAY_BOUNDARY_NEAR, "靠近运营区内边界"); deviceIotService.play(device, IotConstants.PLAY_BOUNDARY_NEAR, "靠近运营区内边界");
return 1; return 1;
@ -199,10 +200,7 @@ public class IotReceiveServiceImpl implements IotReceiveService {
} }
// 靠近禁行区播报语音警告 // 靠近禁行区播报语音警告
BigDecimal boundaryDistance = area.getBoundaryDistance();// 靠近运营区边界时的播报距离 if (isNearNoRidingArea) {
AreaSubVO nearAreaSub = AreaSubUtil.getNearAreaSub(noRidingList, device.getLongitude(), device.getLatitude(), boundaryDistance);
boolean isNearyNoRidingArea = nearAreaSub != null;
if (isNearyNoRidingArea) {
deviceIotService.play(device, IotConstants.PLAY_BOUNDARY_NEAR, "靠近禁行区"); deviceIotService.play(device, IotConstants.PLAY_BOUNDARY_NEAR, "靠近禁行区");
return 1; return 1;
} }

View File

@ -1,5 +1,6 @@
package com.ruoyi.web.bst; package com.ruoyi.web.bst;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -156,4 +157,17 @@ public class AreaController extends BaseController
} }
return toAjax(areaService.logicDel(ids)); return toAjax(areaService.logicDel(ids));
} }
/**
* 获取定位所属区域信息Debug
* @param lon 经度
* @param lat 纬度
* @param areaId 运营区ID
* @return 定位所属区域信息
*/
@PreAuthorize("@ss.hasPermi('bst:area:locationArea')")
@GetMapping("/locationArea")
public AjaxResult locationArea(BigDecimal lon, BigDecimal lat, Long areaId) {
return success(areaService.selectLocationArea(lon, lat, areaId));
}
} }