[update] 修改光伏板和名称匹配逻辑
This commit is contained in:
@ -17,7 +17,10 @@ import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.facility.constant.FacRedisKeyConstant;
|
||||
import org.dromara.facility.domain.FacMatrix;
|
||||
import org.dromara.facility.domain.FacPhotovoltaicPanel;
|
||||
import org.dromara.facility.domain.dto.geojson.*;
|
||||
import org.dromara.facility.domain.dto.geojson.FacFeatureByPlane;
|
||||
import org.dromara.facility.domain.dto.geojson.FacFeatureByPoint;
|
||||
import org.dromara.facility.domain.dto.geojson.FacGeoJsonByPlane;
|
||||
import org.dromara.facility.domain.dto.geojson.FacGeoJsonByPoint;
|
||||
import org.dromara.facility.domain.dto.photovoltaicpanel.FacPhotovoltaicPanelCreateByGeoJsonReq;
|
||||
import org.dromara.facility.domain.dto.photovoltaicpanel.FacPhotovoltaicPanelCreateReq;
|
||||
import org.dromara.facility.domain.dto.photovoltaicpanel.FacPhotovoltaicPanelQueryReq;
|
||||
@ -201,28 +204,30 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaic
|
||||
.in(PgsProgressCategory::getWorkType, PgsProgressCategoryConstant.PHOTOVOLTAIC_PANEL_PROGRESS_CATEGORY_WORK_TYPE).list();
|
||||
Map<Long, List<PgsProgressCategory>> progressCategoryMap = progressCategoryList.stream()
|
||||
.collect(Collectors.groupingBy(PgsProgressCategory::getMatrixId));
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||
List<FacPhotovoltaicPanel> allPanels = new ArrayList<>();
|
||||
try {
|
||||
List<Future<List<FacPhotovoltaicPanel>>> futures = new ArrayList<>();
|
||||
Long userId = LoginHelper.getUserId();
|
||||
for (FacFeatureByPlane locationFeature : locationFeatures) {
|
||||
List<Future<List<FacPhotovoltaicPanel>>> futures = new ArrayList<>();
|
||||
Long userId = LoginHelper.getUserId();
|
||||
// 构建光伏板实体集合
|
||||
try (ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())) {
|
||||
for (FacFeatureByPoint nameFeature : nameFeatures) {
|
||||
Future<List<FacPhotovoltaicPanel>> future = executorService.submit(() -> {
|
||||
List<FacPhotovoltaicPanel> panelList = new ArrayList<>();
|
||||
// ① 获取 geometry 坐标
|
||||
FacGeometryByPlane geometry = locationFeature.getGeometry();
|
||||
List<List<Double>> coordinates = geometry.getCoordinates().getFirst();
|
||||
// ② 判断方阵
|
||||
// ① 找到该点对应的 polygon(优先包含,否则最近)
|
||||
FacFeatureByPlane matchedPolygon = JSTUtil.findNearestOrContainingPolygon(nameFeature, locationFeatures);
|
||||
if (matchedPolygon == null) return Collections.emptyList();
|
||||
// ② 获取 geometry 坐标
|
||||
List<List<Double>> coordinates = matchedPolygon.getGeometry().getCoordinates().getFirst();
|
||||
// ③ 判断所属方阵
|
||||
FacMatrix matrix = matrixService.getMatrixIdBy2Coordinates(matrixList, coordinates);
|
||||
if (matrix == null) return Collections.emptyList();
|
||||
// ③ 获取名称
|
||||
String name = JSTUtil.findNearestPointText(coordinates, nameFeatures);
|
||||
if (name == null) return Collections.emptyList();
|
||||
// ④ 获取进度类别
|
||||
Long matrixId = matrix.getId();
|
||||
// ④ 获取进度类别
|
||||
List<PgsProgressCategory> progressCategoryListByMatrix = progressCategoryMap.get(matrixId);
|
||||
if (CollUtil.isEmpty(progressCategoryListByMatrix)) return Collections.emptyList();
|
||||
// ⑤ 构建光伏板
|
||||
// ⑤ 获取名称
|
||||
String name = nameFeature.getProperties() != null ? nameFeature.getProperties().getText() : null;
|
||||
if (StringUtils.isBlank(name)) return Collections.emptyList();
|
||||
// ⑥ 构建面板数据
|
||||
for (PgsProgressCategory progressCategory : progressCategoryListByMatrix) {
|
||||
FacPhotovoltaicPanel panel = new FacPhotovoltaicPanel();
|
||||
panel.setMatrixId(matrixId);
|
||||
@ -259,16 +264,6 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaic
|
||||
log.error("线程执行异常", e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
executorService.shutdown();
|
||||
try {
|
||||
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
|
||||
executorService.shutdownNow();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
executorService.shutdownNow();
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
// 自定义线程池(IO 密集型线程池)
|
||||
ThreadPoolExecutor customExecutor = new ThreadPoolExecutor(
|
||||
|
@ -3,12 +3,16 @@ package org.dromara.utils;
|
||||
import org.dromara.common.core.constant.HttpStatus;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.constant.GeoJsonConstant;
|
||||
import org.dromara.facility.domain.dto.geojson.FacFeatureByPlane;
|
||||
import org.dromara.facility.domain.dto.geojson.FacFeatureByPoint;
|
||||
import org.dromara.facility.domain.dto.geojson.FacGeometry;
|
||||
import org.dromara.facility.domain.dto.geojson.FacGeometryByPoint;
|
||||
import org.locationtech.jts.geom.*;
|
||||
import org.locationtech.jts.index.strtree.STRtree;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -185,24 +189,79 @@ public class JSTUtil {
|
||||
.map(coord -> new Coordinate(coord.getFirst(), coord.get(1)))
|
||||
.toArray(Coordinate[]::new);
|
||||
Polygon jtsPolygon = geometryFactory.createPolygon(polygonCoords);
|
||||
// 2. 查找最近点
|
||||
FacFeatureByPoint nearestFeature = null;
|
||||
double minDistance = Double.MAX_VALUE;
|
||||
// 2. 构建空间索引(JTS STRtree)
|
||||
STRtree spatialIndex = new STRtree();
|
||||
Map<Coordinate, FacFeatureByPoint> coordToFeatureMap = new HashMap<>();
|
||||
for (FacFeatureByPoint feature : points) {
|
||||
List<Double> coords = feature.getGeometry().getCoordinates();
|
||||
if (coords == null || coords.size() != 2) continue;
|
||||
Point point = geometryFactory.createPoint(new Coordinate(coords.get(0), coords.get(1)));
|
||||
Coordinate coord = new Coordinate(coords.get(0), coords.get(1));
|
||||
Point point = geometryFactory.createPoint(coord);
|
||||
// 用点的 Envelope 加入索引
|
||||
spatialIndex.insert(point.getEnvelopeInternal(), point);
|
||||
coordToFeatureMap.put(coord, feature);
|
||||
}
|
||||
// 3. 查询距离 polygon 最近的点
|
||||
// 用 polygon 中心点附近构造 Envelope(扩大一些范围)
|
||||
Envelope searchEnv = jtsPolygon.getEnvelopeInternal();
|
||||
searchEnv.expandBy(10); // 扩大搜索半径
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Point> candidatePoints = spatialIndex.query(searchEnv);
|
||||
double minDistance = Double.MAX_VALUE;
|
||||
Coordinate nearestCoord = null;
|
||||
for (Point point : candidatePoints) {
|
||||
double distance = point.distance(jtsPolygon);
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance;
|
||||
nearestFeature = feature;
|
||||
nearestCoord = point.getCoordinate();
|
||||
}
|
||||
}
|
||||
// 3. 返回最近点的 text
|
||||
if (nearestFeature != null && nearestFeature.getProperties() != null) {
|
||||
return nearestFeature.getProperties().getText();
|
||||
if (nearestCoord != null) {
|
||||
FacFeatureByPoint nearestFeature = coordToFeatureMap.get(nearestCoord);
|
||||
if (nearestFeature != null && nearestFeature.getProperties() != null) {
|
||||
return nearestFeature.getProperties().getText();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配最近的面,获取该面的信息
|
||||
*
|
||||
* @param pointFeature 点位
|
||||
* @param polygons 平面列表
|
||||
* @return 最近面的信息
|
||||
*/
|
||||
public static FacFeatureByPlane findNearestOrContainingPolygon(
|
||||
FacFeatureByPoint pointFeature,
|
||||
List<FacFeatureByPlane> polygons
|
||||
) {
|
||||
if (pointFeature == null || polygons == null || polygons.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
List<Double> coords = pointFeature.getGeometry().getCoordinates();
|
||||
if (coords == null || coords.size() != 2) return null;
|
||||
Coordinate pointCoord = new Coordinate(coords.get(0), coords.get(1));
|
||||
Point point = geometryFactory.createPoint(pointCoord);
|
||||
FacFeatureByPlane nearestPolygon = null;
|
||||
double minDistance = Double.MAX_VALUE;
|
||||
for (FacFeatureByPlane polygonFeature : polygons) {
|
||||
List<List<Double>> polyCoords = polygonFeature.getGeometry().getCoordinates().getFirst();
|
||||
Coordinate[] polygonCoords = polyCoords.stream()
|
||||
.map(c -> new Coordinate(c.getFirst(), c.get(1)))
|
||||
.toArray(Coordinate[]::new);
|
||||
Polygon polygon = geometryFactory.createPolygon(polygonCoords);
|
||||
// 优先使用包含点的 polygon
|
||||
if (polygon.contains(point)) {
|
||||
return polygonFeature;
|
||||
}
|
||||
double distance = polygon.distance(point);
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance;
|
||||
nearestPolygon = polygonFeature;
|
||||
}
|
||||
}
|
||||
return nearestPolygon;
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user