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

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列表 * @param candidateAreaIds 附近停车区id列表
* @return 停车区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); Coordinate userCoordinate = new Coordinate(lng, lat);
org.locationtech.jts.geom.Point userPoint = GEOMETRY_FACTORY.createPoint(userCoordinate); org.locationtech.jts.geom.Point userPoint = GEOMETRY_FACTORY.createPoint(userCoordinate);
for (String areaId : candidateAreaIds) { for (String regionId : candidateAreaIds) {
// 获取 MBR // 获取 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); double[] mbr = parseMBR(mbrStr);
// MBR 快速过滤 // MBR 快速过滤
if (lng >= mbr[0] && lng <= mbr[2] && lat >= mbr[1] && lat <= mbr[3]) { 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); Polygon polygon = parsePolygon(verticesStr);
// 精确判断 // 精确判断
if (polygon.contains(userPoint)) { if (polygon.contains(userPoint)) {
return areaId; return regionId;
} }
} }
} }
@ -284,18 +284,40 @@ public class RedisUtil {
* @param lat 纬度 * @param lat 纬度
* @return true-在内部false-在外部或边界上根据业务需求调整 * @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()) { if (nearbyParking.isEmpty()) {
return false; return false;
} }
//获取第一个包含该点位的停车区 //获取第一个包含该点位的停车区
String areaId = checkPointInArea(lng, lat, nearbyParking,orgId); String regionId = checkPointInArea(lng, lat, nearbyParking,areaId);
if (areaId == null) { if (regionId == null) {
return false; 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); Polygon polygon = parsePolygonFromWKT(polygonFromWKT);
return isPointInPolygon(lng, lat, polygon); return isPointInPolygon(lng, lat, polygon);
} }
@ -349,8 +371,8 @@ public class RedisUtil {
* 获取 WKT * 获取 WKT
* @param areaId areaId * @param areaId areaId
*/ */
public String getPolygonFromWKT(Long orgId,String areaId,String key) { public String getPolygonFromWKT(Long suffixId,String areaId,String key) {
return "POLYGON ((" + (String)redisTemplate.opsForHash().get(key + orgId, "vertices"+areaId)+"))"; 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(); FeignEbikeRegionDto regionDto = regionResult.getData();
String jsonString = JSONObject.toJSONString(redisUtil.get(ecuInfo.getEcuSn())); String jsonString = JSONObject.toJSONString(redisUtil.get(ecuInfo.getEcuSn()));
ResGPSDto resGpsDto = JSONObject.parseObject(jsonString, ResGPSDto.class); 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 @Override
@ -375,7 +375,7 @@ public class UserOrdersServiceImpl extends ServiceImpl<UserOrdersMapper, EbikeUs
//是否在运营区内 //是否在运营区内
boolean pointInOperation = bikeInOperation(resGpsDto.getLongitude(), resGpsDto.getLatitude(), regionDto.getOrgId(), regionDto.getOperationRegionId()); 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()); long minutes = TimeUtils.betweenMinutes(userOrders.getStartTime(), userOrders.getEndTime());
//是否取消订单 //是否取消订单
Integer freeDuration = feignEbikeSysRcostsetDto.getFreeDuration(); Integer freeDuration = feignEbikeSysRcostsetDto.getFreeDuration();

View File

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