算法修复、站点区域算法实现

This commit is contained in:
attiya 2025-05-12 15:39:19 +08:00
parent 1784ff0239
commit cc6ed2e5df
3 changed files with 68 additions and 24 deletions

View File

@ -254,24 +254,24 @@ public class RedisUtil {
* @param candidateAreaIds 附近停车区id列表
* @return 停车区id
*/
public String checkPointInArea(double lng, double lat, List<String> candidateAreaIds,Long orgId) {
public String checkPointInArea(double lng, double lat, List<String> candidateAreaIds,Long areaId) {
Coordinate userCoordinate = new Coordinate(lng, lat);
org.locationtech.jts.geom.Point userPoint = GEOMETRY_FACTORY.createPoint(userCoordinate);
for (String areaId : candidateAreaIds) {
for (String regionId : candidateAreaIds) {
// 获取 MBR
String mbrStr = (String) redisTemplate.opsForHash().get("parking_area:meta:" + orgId, "mbr"+areaId);
String mbrStr = (String) redisTemplate.opsForHash().get("parking_area:meta:" + areaId, "mbr"+regionId);
double[] mbr = parseMBR(mbrStr);
// MBR 快速过滤
if (lng >= mbr[0] && lng <= mbr[2] && lat >= mbr[1] && lat <= mbr[3]) {
// 获取顶点数据
String verticesStr = (String) redisTemplate.opsForHash().get("parking_area:meta:" + orgId, "vertices"+areaId);
String verticesStr = (String) redisTemplate.opsForHash().get("parking_area:meta:" + areaId, "vertices"+regionId);
Polygon polygon = parsePolygon(verticesStr);
// 精确判断
if (polygon.contains(userPoint)) {
return areaId;
return regionId;
}
}
}
@ -284,18 +284,40 @@ public class RedisUtil {
* @param lat 纬度
* @return true-在内部false-在外部或边界上根据业务需求调整
*/
public boolean isPointInParking(double lng, double lat,Long orgId) {
public boolean isPointInParking(double lng, double lat,Long areaId) {
//查询附近停车区
List<String> nearbyParking = findNearbyParking(lng, lat,orgId);
List<String> nearbyParking = findNearbyParking(lng, lat,areaId);
if (nearbyParking.isEmpty()) {
return false;
}
//获取第一个包含该点位的停车区
String areaId = checkPointInArea(lng, lat, nearbyParking,orgId);
if (areaId == null) {
String regionId = checkPointInArea(lng, lat, nearbyParking,areaId);
if (regionId == null) {
return false;
}
String polygonFromWKT = getPolygonFromWKT(orgId,areaId,"parking_area:meta:");
String polygonFromWKT = getPolygonFromWKT(areaId,regionId,"parking_area:meta:");
Polygon polygon = parsePolygonFromWKT(polygonFromWKT);
return isPointInPolygon(lng, lat, polygon);
}
/**
* 判断坐标点是否在附近站点区内
* @param lng 经度
* @param lat 纬度
* @return true-在内部false-在外部或边界上根据业务需求调整
*/
public boolean isPointInSite(double lng, double lat,Long areaId) {
//查询附近停车区
List<String> nearbyParking = findNearbyParking(lng, lat,areaId);
if (nearbyParking.isEmpty()) {
return false;
}
//获取第一个包含该点位的停车区
String regionId = checkPointInArea(lng, lat, nearbyParking,areaId);
if (regionId == null) {
return false;
}
String polygonFromWKT = getPolygonFromWKT(areaId,regionId,"parking_area:meta:");
Polygon polygon = parsePolygonFromWKT(polygonFromWKT);
return isPointInPolygon(lng, lat, polygon);
}
@ -349,8 +371,8 @@ public class RedisUtil {
* 获取 WKT
* @param areaId areaId
*/
public String getPolygonFromWKT(Long orgId,String areaId,String key) {
return "POLYGON ((" + (String)redisTemplate.opsForHash().get(key + orgId, "vertices"+areaId)+"))";
public String getPolygonFromWKT(Long suffixId,String areaId,String key) {
return "POLYGON ((" + (String)redisTemplate.opsForHash().get(key + suffixId, "vertices"+areaId)+"))";
}
/**

View File

@ -288,7 +288,7 @@ public class UserOrdersServiceImpl extends ServiceImpl<UserOrdersMapper, EbikeUs
FeignEbikeRegionDto regionDto = regionResult.getData();
String jsonString = JSONObject.toJSONString(redisUtil.get(ecuInfo.getEcuSn()));
ResGPSDto resGpsDto = JSONObject.parseObject(jsonString, ResGPSDto.class);
return redisUtil.isPointInParking(resGpsDto.getLongitude(), resGpsDto.getLatitude(), regionDto.getOrgId());
return redisUtil.isPointInParking(resGpsDto.getLongitude(), resGpsDto.getLatitude(), regionDto.getOperationRegionId());
}
@Override
@ -375,7 +375,7 @@ public class UserOrdersServiceImpl extends ServiceImpl<UserOrdersMapper, EbikeUs
//是否在运营区内
boolean pointInOperation = bikeInOperation(resGpsDto.getLongitude(), resGpsDto.getLatitude(), regionDto.getOrgId(), regionDto.getOperationRegionId());
//是否在停车区内
boolean pointInParking = redisUtil.isPointInParking(resGpsDto.getLongitude(), resGpsDto.getLatitude(), regionDto.getOrgId());
boolean pointInParking = redisUtil.isPointInParking(resGpsDto.getLongitude(), resGpsDto.getLatitude(), regionDto.getOperationRegionId());
long minutes = TimeUtils.betweenMinutes(userOrders.getStartTime(), userOrders.getEndTime());
//是否取消订单
Integer freeDuration = feignEbikeSysRcostsetDto.getFreeDuration();

View File

@ -185,24 +185,24 @@ public class RedisUtil {
* @param candidateAreaIds 附近停车区id列表
* @return 停车区id
*/
public String checkPointInArea(double lng, double lat, List<String> candidateAreaIds,Long orgId) {
public String checkPointInArea(double lng, double lat, List<String> candidateAreaIds,Long areaId) {
Coordinate userCoordinate = new Coordinate(lng, lat);
org.locationtech.jts.geom.Point userPoint = GEOMETRY_FACTORY.createPoint(userCoordinate);
for (String areaId : candidateAreaIds) {
for (String regionId : candidateAreaIds) {
// 获取 MBR
String mbrStr = (String) redisTemplate.opsForHash().get("parking_area:meta:" + orgId, "mbr"+areaId);
String mbrStr = (String) redisTemplate.opsForHash().get("parking_area:meta:" + areaId, "mbr"+regionId);
double[] mbr = parseMBR(mbrStr);
// MBR 快速过滤
if (lng >= mbr[0] && lng <= mbr[2] && lat >= mbr[1] && lat <= mbr[3]) {
// 获取顶点数据
String verticesStr = (String) redisTemplate.opsForHash().get("parking_area:meta:" + orgId, "vertices"+areaId);
String verticesStr = (String) redisTemplate.opsForHash().get("parking_area:meta:" + areaId, "vertices"+regionId);
Polygon polygon = parsePolygon(verticesStr);
// 精确判断
if (polygon.contains(userPoint)) {
return areaId;
return regionId;
}
}
}
@ -215,18 +215,40 @@ public class RedisUtil {
* @param lat 纬度
* @return true-在内部false-在外部或边界上根据业务需求调整
*/
public boolean isPointInParking(double lng, double lat,Long orgId) {
public boolean isPointInParking(double lng, double lat,Long areaId) {
//查询附近停车区
List<String> nearbyParking = findNearbyParking(lng, lat,orgId);
List<String> nearbyParking = findNearbyParking(lng, lat,areaId);
if (nearbyParking.isEmpty()) {
return false;
}
//获取第一个包含该点位的停车区
String areaId = checkPointInArea(lng, lat, nearbyParking,orgId);
if (areaId == null) {
String regionId = checkPointInArea(lng, lat, nearbyParking,areaId);
if (regionId == null) {
return false;
}
String polygonFromWKT = getPolygonFromWKT(orgId,areaId,"parking_area:meta:");
String polygonFromWKT = getPolygonFromWKT(areaId,regionId,"parking_area:meta:");
Polygon polygon = parsePolygonFromWKT(polygonFromWKT);
return isPointInPolygon(lng, lat, polygon);
}
/**
* 判断坐标点是否在附近站点区内
* @param lng 经度
* @param lat 纬度
* @return true-在内部false-在外部或边界上根据业务需求调整
*/
public boolean isPointInSite(double lng, double lat,Long areaId) {
//查询附近停车区
List<String> nearbyParking = findNearbyParking(lng, lat,areaId);
if (nearbyParking.isEmpty()) {
return false;
}
//获取第一个包含该点位的停车区
String regionId = checkPointInArea(lng, lat, nearbyParking,areaId);
if (regionId == null) {
return false;
}
String polygonFromWKT = getPolygonFromWKT(areaId,regionId,"parking_area:meta:");
Polygon polygon = parsePolygonFromWKT(polygonFromWKT);
return isPointInPolygon(lng, lat, polygon);
}