//package org.dromara.system.api.utils;
//
//import cn.hutool.json.JSONUtil;
//import org.dromara.common.constant.GeoJsonConstant;
//import org.dromara.common.core.constant.HttpStatus;
//import org.dromara.common.core.exception.ServiceException;
//import org.dromara.common.domain.GeoPoint;
//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;
//
///**
// * @author lilemy
// * @date 2025/4/24 11:48
// */
//public class JSTUtil {
//
//    private static final GeometryFactory geometryFactory = new GeometryFactory();
//
//    /**
//     * 获取最近点的名称
//     *
//     * @param target      目标点
//     * @param nameGeoJson 点对象列表
//     * @return 最近点的名称
//     */
//    public static String findNearestText(List<Double> target, List<FacFeatureByPoint> nameGeoJson) {
//        Point targetPoint = geometryFactory.createPoint(new Coordinate(target.get(0), target.get(1)));
//        FacFeatureByPoint nearestFeature = null;
//        double minDistance = Double.MAX_VALUE;
//        for (FacFeatureByPoint feature : nameGeoJson) {
//            FacGeometryByPoint geometry = feature.getGeometry();
//            List<Double> coords = geometry.getCoordinates();
//            if (coords != null && coords.size() == 2) {
//                Point currentPoint = geometryFactory.createPoint(new Coordinate(coords.get(0), coords.get(1)));
//                double distance = targetPoint.distance(currentPoint);
//                if (distance < minDistance) {
//                    minDistance = distance;
//                    nearestFeature = feature;
//                }
//            }
//        }
//        if (nearestFeature != null && nearestFeature.getProperties() != null) {
//            return nearestFeature.getProperties().getText();
//        }
//        return null; // 如果没找到合适的点
//    }
//
//    /**
//     * 点是否在平面内
//     *
//     * @param planeLists 平面坐标
//     * @param pointList  点坐标
//     * @return 点是否在平面内
//     */
//    public static Boolean pointIsWithInPlane(List<List<Double>> planeLists, List<Double> pointList) {
//        // 构建平面
//        Coordinate[] coordinates = getPlaneCoordinate(planeLists);
//        Polygon polygon = geometryFactory.createPolygon(coordinates);
//        // 构建待判断点
//        Point point = geometryFactory.createPoint(new Coordinate(pointList.get(0), pointList.get(1)));
//        // 判断是否在多边形内
//        return polygon.contains(point);
//    }
//
//    /**
//     * 获取平面内点列表集合
//     *
//     * @param planeLists 平面坐标列表
//     * @param pointLists 点坐标列表集合
//     * @return 平面内点坐标列表集合
//     */
//    public static List<List<Double>> getPointInPlaneList(List<List<Double>> planeLists, List<List<Double>> pointLists) {
//        // 构建平面
//        Coordinate[] coordinates = getPlaneCoordinate(planeLists);
//        LinearRing shell = geometryFactory.createLinearRing(coordinates);
//        Polygon polygon = geometryFactory.createPolygon(shell);
//        // 获取平面内点结合
//        return pointLists.stream().filter(pointList -> {
//            // 构建待判断点
//            Point point = geometryFactory.createPoint(new Coordinate(pointList.get(0), pointList.get(1)));
//            // 判断是否在多边形内
//            return polygon.contains(point);
//        }).toList();
//    }
//
//    /**
//     * 平面是否在平面内
//     *
//     * @param referencePlane 参考平面
//     * @param comparePlane   比较平面
//     * @return 平面是否在平面内
//     */
//    public static Boolean planeIsWithInPlane(List<List<Double>> referencePlane, List<List<Double>> comparePlane) {
//        // 构建参考平面
//        Coordinate[] referenceCoordinates = getPlaneCoordinate(referencePlane);
//        Polygon referencePolygon = geometryFactory.createPolygon(referenceCoordinates);
//        // 构建比较平面
//        Coordinate[] compareCoordinates = getPlaneCoordinate(comparePlane);
//        Polygon comparePolygon = geometryFactory.createPolygon(compareCoordinates);
//        // 判断是否在多边形内
//        return referencePolygon.contains(comparePolygon);
//    }
//
//    /**
//     * 判断两个平面是否相交
//     *
//     * @param referencePlane 参考平面
//     * @param comparePlane   待比较平面
//     * @return 平面是否相交
//     */
//    public static Boolean arePolygonsIntersecting(List<List<Double>> referencePlane, List<List<Double>> comparePlane) {
//        // 构建 Polygon A（参考面）
//        Coordinate[] coordsA = referencePlane.stream()
//            .map(p -> new Coordinate(p.getFirst(), p.get(1)))
//            .toArray(Coordinate[]::new);
//        Polygon polygonA = geometryFactory.createPolygon(coordsA);
//        // 构建 Polygon B（比较面）
//        Coordinate[] coordsB = comparePlane.stream()
//            .map(p -> new Coordinate(p.getFirst(), p.get(1)))
//            .toArray(Coordinate[]::new);
//        Polygon polygonB = geometryFactory.createPolygon(coordsB);
//        // 使用 JTS 判断是否相交
//        return polygonA.intersects(polygonB);
//    }
//
//    /**
//     * 获取平面坐标数组
//     *
//     * @param planeLists 平面坐标列表
//     * @return 平面坐标数组
//     */
//    public static Coordinate[] getPlaneCoordinate(List<List<Double>> planeLists) {
//        return planeLists.stream().map(planeList ->
//                new Coordinate(planeList.getFirst(), planeList.get(1)))
//            .toList().toArray(new Coordinate[0]);
//    }
//
//    /**
//     * 获取二维坐标
//     *
//     * @param geometry 几何对象
//     * @return 二维坐标
//     */
//    public static List<List<Double>> getTwoDimensionalCoordinates(FacGeometry geometry) {
//        String type = geometry.getType();
//        List<Object> coordinates = geometry.getCoordinates();
//        return switch (type) {
//            case GeoJsonConstant.POINT -> throw new ServiceException("点位无法创建方阵", HttpStatus.BAD_REQUEST);
//            case GeoJsonConstant.LINE -> coordinates.stream()
//                .filter(obj -> obj instanceof List<?>)
//                .map(obj -> ((List<?>) obj).stream()
//                    .filter(num -> num instanceof Number)
//                    .map(num -> ((Number) num).doubleValue())
//                    .collect(Collectors.toList()))
//                .collect(Collectors.toList());
//            case GeoJsonConstant.POLYGON -> coordinates.stream()
//                .filter(obj -> obj instanceof List<?>)
//                .flatMap(obj -> ((List<?>) obj).stream())
//                .filter(pointObj -> pointObj instanceof List<?>)
//                .map(pointObj -> ((List<?>) pointObj).stream()
//                    .filter(num -> num instanceof Number)
//                    .map(num -> ((Number) num).doubleValue())
//                    .collect(Collectors.toList()))
//                .collect(Collectors.toList());
//            default -> throw new ServiceException("暂不支持该类型", HttpStatus.BAD_REQUEST);
//        };
//    }
//
//    /**
//     * 匹配最近的点，获取该点的名称
//     *
//     * @param polygon 平面
//     * @param points  点列表集合
//     * @return 最近点的名称
//     */
//    public static String findNearestPointText(List<List<Double>> polygon, List<FacFeatureByPoint> points) {
//        if (polygon == null || polygon.size() < 3 || points == null || points.isEmpty()) {
//            return null;
//        }
//        // 1. 构建 Polygon
//        Coordinate[] polygonCoords = polygon.stream()
//            .map(coord -> new Coordinate(coord.getFirst(), coord.get(1)))
//            .toArray(Coordinate[]::new);
//        Polygon jtsPolygon = geometryFactory.createPolygon(polygonCoords);
//        // 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;
//            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;
//                nearestCoord = point.getCoordinate();
//            }
//        }
//        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) {
//            if (polygonFeature == null || polygonFeature.getGeometry() == null) {
//                continue; // 跳过空对象
//            }
//            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;
//    }
//
//    /**
//     * 判断一个点是否在多个区域中，返回第一个匹配区域的点集合（否则 null）
//     *
//     * @param lat           纬度
//     * @param lng           经度
//     * @param rangeListJson 多边形列表，每个为 JSON 数组（多边形的点数组）
//     * @return 匹配区域的 List<Point>，否则 null
//     */
//    public static List<GeoPoint> findMatchingRange(String lat, String lng, List<String> rangeListJson) {
//        double latitude = Double.parseDouble(lat);
//        double longitude = Double.parseDouble(lng);
//        Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
//        for (String rangeJson : rangeListJson) {
//            List<GeoPoint> polygonPoints = JSONUtil.toList(rangeJson, GeoPoint.class);
//            if (polygonPoints.size() < 3) continue; // 不是有效多边形
//
//            Polygon polygon = buildPolygon(polygonPoints);
//            if (polygon.contains(point)) {
//                return polygonPoints; // 找到匹配范围
//            }
//        }
//        return null;
//    }
//
//    /**
//     * 将点集合转换为 JTS 多边形
//     */
//    private static Polygon buildPolygon(List<GeoPoint> points) {
//        Coordinate[] coordinates = points.stream()
//            .map(p -> new Coordinate(p.getLng(), p.getLat()))
//            .toArray(Coordinate[]::new);
//
//        // 需要闭合坐标环（首尾相连）
//        if (!coordinates[0].equals2D(coordinates[coordinates.length - 1])) {
//            Coordinate[] closed = new Coordinate[coordinates.length + 1];
//            System.arraycopy(coordinates, 0, closed, 0, coordinates.length);
//            closed[closed.length - 1] = coordinates[0];
//            coordinates = closed;
//        }
//
//        LinearRing shell = geometryFactory.createLinearRing(coordinates);
//        return geometryFactory.createPolygon(shell);
//    }
//
//}
