diff --git a/policeSecurityServer/pom.xml b/policeSecurityServer/pom.xml index 61d3d4b..140472e 100644 --- a/policeSecurityServer/pom.xml +++ b/policeSecurityServer/pom.xml @@ -23,6 +23,7 @@ 3.3.4 8.0.32 3.5.7 + 25.2 1.2.20 8.4.3 4.8.1 @@ -190,6 +191,17 @@ mybatis-plus-spring-boot3-starter ${mybatis.plus.version} + + + org.geotools + gt-main + ${geotools.version} + + + org.geotools + gt-geojson + ${geotools.version} + io.minio diff --git a/policeSecurityServer/src/main/java/com/changhu/common/utils/GeometryUtil.java b/policeSecurityServer/src/main/java/com/changhu/common/utils/GeometryUtil.java new file mode 100644 index 0000000..fc330d7 --- /dev/null +++ b/policeSecurityServer/src/main/java/com/changhu/common/utils/GeometryUtil.java @@ -0,0 +1,428 @@ +package com.changhu.common.utils; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.StrUtil; +import com.changhu.common.exception.MessageException; +import lombok.extern.slf4j.Slf4j; +import org.geotools.geojson.geom.GeometryJSON; +import org.geotools.geometry.jts.JTS; +import org.geotools.referencing.CRS; +import org.geotools.referencing.GeodeticCalculator; +import org.locationtech.jts.geom.*; +import org.locationtech.jts.io.ParseException; +import org.locationtech.jts.io.WKBReader; +import org.locationtech.jts.io.WKTReader; +import org.opengis.referencing.FactoryException; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.operation.MathTransform; +import org.opengis.referencing.operation.TransformException; + +import java.awt.geom.Point2D; +import java.io.IOException; +import java.io.StringReader; +import java.math.BigDecimal; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.List; +import java.util.Objects; + +/** + * author: luozhun + * desc: GeometryUtil + * createTime: 2023/8/25 18:03 + */ +@Slf4j +public class GeometryUtil { + + /** + * - WGS 84(srid=4326):用于全球地理坐标系统的标准参考坐标系。 + * - 美国地理参考系统(srid=4269):用于美国本土的地图和地理数据。 + * - 欧洲地理参考系统(srid=4258):用于欧洲地图和地理数据。 + * - 中国国家大地坐标系(srid=4490):用于中国的地图和地理数据。 + */ + public static final int SRID = 4326; + public static final String ST_GeomFromText = StrUtil.format("ST_GeomFromText({},{},{})", "?", SRID, "'axis-order=long-lat'"); + private static final GeometryFactory GEOMETRY_FACTORY = new GeometryFactory(new PrecisionModel(), SRID); + private static final GeometryFactory LOCATION_TECH_GEOMETRY_FACTORY = new GeometryFactory(new PrecisionModel(), SRID); + + /** + * 空对象,因为简历空间索引不能为空 Mysql 不支持创建 Empty 的数据 这里自定义一个类型 标识为null + */ + public static Point emptyPoint() { + return createPoint("POINT(0 0)"); + } + + public static Polygon emptyPolygon() { + return createPolygon("POLYGON((0 0, 0 0, 0 0, 0 0))"); + } + + public static LineString emptyLineString() { + return createLineString("LINESTRING(0 0, 0 0)"); + } + + public static MultiPoint emptyMultiPoint() { + return createMultiPoint("MULTIPOINT((0 0))"); + } + + public static MultiPolygon emptyMultiPolygon() { + return createMultiPolygon("MULTIPOLYGON(((0 0, 0 0, 0 0, 0 0)))"); + } + + public static MultiLineString emptyMultiLineString() { + return createMultiLineString("MULTILINESTRING(((0 0, 0 0)))"); + } + + + public static boolean equals(Geometry geometry1, Geometry geometry2) { + return StrUtil.equals(geometry1.toText(), geometry2.toText()); + } + + //** 点 **\\ + + /** + * 创建点对象 + */ + public static Point createPoint(List param) { + if (param == null) { + return null; + } + BigDecimal longitude = param.get(0); + BigDecimal latitude = param.get(1); + if (longitude == null || latitude == null) { + return null; + } + Coordinate coordinate = new Coordinate(longitude.doubleValue(), latitude.doubleValue()); + return GEOMETRY_FACTORY.createPoint(coordinate); + } + + public static Point createPoint(double longitude, double latitude) { + Coordinate coordinate = new Coordinate(longitude, latitude); + return GEOMETRY_FACTORY.createPoint(coordinate); + } + + /** + * 从WKT创建点对象 + * + * @param wkt 注WKT类似: POINT(109.013388 32.715519) + */ + public static Point createPoint(String wkt) { + return createGeometryFromWkt(wkt, Point.class); + } + + /** + * 从WKT创建点对象 + * + * @param bytes 数据库二进制数据 + */ + public static Point createPoint(byte[] bytes) { + return createGeometryFromBytes(bytes, Point.class); + } + + + //** 多边形 **\\ + + /** + * 创建多边形对象 + *

+ * 注:后面可能考虑兼容折线类型,如果是折线类型那么需要规范首尾结点要相同才能构成 polygon 否则构成 polyline + * 目前暂时没有做这方面的规划,用代码兼容了首尾不相等的情况构成polygon + */ + public static Polygon createPolygon(List> params) { + if (params == null || params.size() < 4) { + throw new MessageException("构成多边形至少需要三个有效坐标,并且保证尾部坐标和首部坐标相同"); + } + // 检测首尾是否相等,不相等则补充尾坐标 + List startPoint = params.get(0); + List entPoint = params.get(params.size() - 1); + if (!Objects.equals(startPoint.get(0), entPoint.get(0)) + || !Objects.equals(startPoint.get(1), entPoint.get(1))) { + params.add(params.get(0)); + } + Coordinate[] coordinates = convertBigDecimalList2CoordinateArray(params); + return GEOMETRY_FACTORY.createPolygon(coordinates); + } + + public static Polygon createPolygonWithDouble(List> params) { + if (params == null || params.size() < 4) { + throw new MessageException("构成多边形至少需要三个有效坐标,并且保证尾部坐标和首部坐标相同"); + } + // 检测首尾是否相等,不相等则补充尾坐标 + List startPoint = params.get(0); + List entPoint = params.get(params.size() - 1); + if (!Objects.equals(startPoint.get(0), entPoint.get(0)) + || !Objects.equals(startPoint.get(1), entPoint.get(1))) { + params.add(params.get(0)); + } + Coordinate[] coordinates = convertDoubleList2CoordinateArray(params); + return GEOMETRY_FACTORY.createPolygon(coordinates); + } + + /** + * 从WKT创建多边形对象 + * + * @param wkt 注WKT类似:POLYGON((20 10, 30 0, 40 10, 30 20, 20 10)) + */ + public static Polygon createPolygon(String wkt) { + return createGeometryFromWkt(wkt, Polygon.class); + } + + /** + * 创建多边形对象 + * + * @param bytes 数据库二进制数据 + */ + public static Polygon createPolygon(byte[] bytes) { + return createGeometryFromBytes(bytes, Polygon.class); + } + + //** 折线 **\\ + + /** + * 创建折线对象 + */ + public static LineString createLineString(List> params) { + if (params == null || params.size() < 2) { + throw new MessageException("构成折线至少需要两个有效坐标"); + } + Coordinate[] coordinates = convertBigDecimalList2CoordinateArray(params); + return GEOMETRY_FACTORY.createLineString(coordinates); + } + + /** + * 从 wkt 创建折线对象 + */ + public static LineString createLineString(String wkt) { + return createGeometryFromWkt(wkt, LineString.class); + } + + /** + * 从 bytes 创建折线对象 + */ + public static LineString createLineString(byte[] bytes) { + return createGeometryFromBytes(bytes, LineString.class); + } + + + //** 多点 **\\ + + /** + * 创建多点对象 + */ + public static MultiPoint createMultiPoint(List> multiParam) { + int size = multiParam.size(); + Point[] points = new Point[size]; + for (int i = 0; i < size; i++) { + points[i] = createPoint(multiParam.get(i)); + } + return GEOMETRY_FACTORY.createMultiPoint(points); + } + + + /** + * 从 wkt 创建多点对象 + */ + public static MultiPoint createMultiPoint(String wkt) { + return createGeometryFromWkt(wkt, MultiPoint.class); + } + + + /** + * 从 bytes 创建多点对象 + */ + public static MultiPoint createMultiPoint(byte[] bytes) { + return createGeometryFromBytes(bytes, MultiPoint.class); + } + + + //** 多折线 **\\ + + /** + * 创建多折线对象 + */ + public static MultiLineString createMultiLineString(List>> multiParams) { + int size = multiParams.size(); + LineString[] lineStrings = new LineString[size]; + for (int i = 0; i < size; i++) { + lineStrings[i] = createLineString(multiParams.get(i)); + } + return GEOMETRY_FACTORY.createMultiLineString(lineStrings); + } + + /** + * 从 wkt 创建多折线对象 + */ + public static MultiLineString createMultiLineString(String wkt) { + return createGeometryFromWkt(wkt, MultiLineString.class); + } + + /** + * 从 wkt 创建多折线对象 + */ + public static MultiLineString createMultiLineString(byte[] bytes) { + return createGeometryFromBytes(bytes, MultiLineString.class); + } + + //** 多多边形 **\\ + + /** + * 创建多多边形 + */ + public static MultiPolygon createMultiPolygon(List>> multiParams) { + int size = multiParams.size(); + Polygon[] polygons = new Polygon[size]; + for (int i = 0; i < size; i++) { + polygons[i] = createPolygon(multiParams.get(i)); + } + return GEOMETRY_FACTORY.createMultiPolygon(polygons); + } + + /** + * 从 wkt 创建多多边形 + */ + public static MultiPolygon createMultiPolygon(String wkt) { + return createGeometryFromWkt(wkt, MultiPolygon.class); + } + + /** + * 从 bytes 创建多多边形 + */ + public static MultiPolygon createMultiPolygon(byte[] bytes) { + return createGeometryFromBytes(bytes, MultiPolygon.class); + } + + //** 通用工具 **\\ + + + /** + * bytes 创建空间对象 + * + * @param bytes 数据库的二进制数据 + */ + public static T createGeometryFromBytes(byte[] bytes, Class clazz) { + if (bytes == null) { + return null; + } + try { + WKBReader wkbReader = new WKBReader(GEOMETRY_FACTORY); + byte[] geomBytes = ByteBuffer.allocate(bytes.length - 4).order(ByteOrder.LITTLE_ENDIAN) + .put(bytes, 4, bytes.length - 4).array(); + Geometry geometry = wkbReader.read(geomBytes); + return Convert.convert(clazz, geometry); + } catch (Exception e) { + throw new MessageException("从 Bytes 创建空间对象 {} 时出现错误:{}", clazz.getSimpleName(), e.getMessage()); + } + } + + /** + * 从 wkt 创建空间对象 + * + * @param wkt 类似:POLYGON((20 10, 30 0, 40 10, 30 20, 20 10)) , POINT(109.013388 32.715519) 等 + * @param clazz 继承 + */ + public static T createGeometryFromWkt(String wkt, Class clazz) { + if (wkt == null || StrUtil.isBlank(wkt)) { + return null; + } + try { + WKTReader reader = new WKTReader(GEOMETRY_FACTORY); + Geometry geometry = reader.read(wkt); + return Convert.convert(clazz, geometry); + } catch (ParseException e) { + throw new MessageException("从WKT创建空间对象 {} 时出现错误。wkt:{}", clazz.getSimpleName(), wkt); + } + } + + /** + * 从 GeoJson 创建空间对象 + */ + public static T createGeometryFromGeoJson(String geoJson, Class clazz) { + try { + GeometryJSON geometryJson = new GeometryJSON(20); + Geometry read = geometryJson.read(new StringReader(geoJson)); + return createGeometryFromWkt(read.toString(), clazz); + } catch (IOException e) { + log.error("从 GeoJson 创建空间对象出错:{}", e.getMessage()); + } + return null; + } + + /** + * 将 List 转化为 Coordinate[] + */ + private static Coordinate[] convertBigDecimalList2CoordinateArray(List> params) { + int size = params.size(); + Coordinate[] coordinates = new Coordinate[size]; + for (int i = 0; i < params.size(); i++) { + List param = params.get(i); + Coordinate coordinate = new Coordinate(param.get(0).doubleValue(), param.get(1).doubleValue()); + coordinates[i] = coordinate; + } + return coordinates; + } + + private static Coordinate[] convertDoubleList2CoordinateArray(List> params) { + int size = params.size(); + Coordinate[] coordinates = new Coordinate[size]; + for (int i = 0; i < params.size(); i++) { + List param = params.get(i); + Coordinate coordinate = new Coordinate(param.get(0), param.get(1)); + coordinates[i] = coordinate; + } + return coordinates; + } + + /** + * 计算面积 平方米 + * 28155 .195928.042862 + */ + public static BigDecimal getApproximateArea(Geometry geometry) { + try { + String wkt = geometry.toText(); + WKTReader wktReader = new WKTReader(LOCATION_TECH_GEOMETRY_FACTORY); + Geometry geom = wktReader.read(wkt); + // WGS84(一般项目中常用的是CSR:84和EPSG:4326) + CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4326"); + // Pseudo-Mercator(墨卡托投影) + CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4490"); + MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true); + Geometry geometryMercator = JTS.transform(geom, transform); + // 面积、周长 + return BigDecimal.valueOf(geometryMercator.getArea()); + } catch (FactoryException | TransformException | ParseException e) { + log.error("计算面积出错:{}", e.getMessage()); + } + return null; + } + + /** + * 当前数据库的数据来源都是高德数据源 坐标系为GCJ02 如果来源是其他的地图的需要根据规则转换成GCJ02 + * 同理如果需要转换到其他的数据源的坐标系也需要进行转换 + */ + public static T convertWgs84ToGcj02(T geometry) { + log.info("原始数据:{}", geometry.toText()); + Coordinate[] coordinates = geometry.getCoordinates(); + for (Coordinate coordinate : coordinates) { + double lon = coordinate.x; + double lat = coordinate.y; + double[] doubles = GpsConvertUtil.wgs84ToGcj02(lon, lat); + coordinate.x = doubles[0]; + coordinate.y = doubles[1]; + } + log.info("转后数据:{}", geometry.toText()); + return geometry; + } + + public static double distance(Point p0, Point p1) { + GeodeticCalculator calculator = new GeodeticCalculator(); + calculator.setStartingGeographicPoint(p0.getX(), p0.getY()); + calculator.setDestinationGeographicPoint(p1.getX(), p1.getY()); + return calculator.getOrthodromicDistance(); + } + + public static Point2D calculateEndingGlobalCoordinates(double longitude, double latitude, double azi, double dis) { + GeodeticCalculator calculator = new GeodeticCalculator(); + calculator.setStartingGeographicPoint(longitude, latitude); + calculator.setDirection(azi, dis); + return calculator.getDestinationGeographicPoint(); + } +} \ No newline at end of file diff --git a/policeSecurityServer/src/main/java/com/changhu/common/utils/GpsConvertUtil.java b/policeSecurityServer/src/main/java/com/changhu/common/utils/GpsConvertUtil.java new file mode 100644 index 0000000..e524a80 --- /dev/null +++ b/policeSecurityServer/src/main/java/com/changhu/common/utils/GpsConvertUtil.java @@ -0,0 +1,135 @@ +package com.changhu.common.utils; + +/** + * author: luozhun + * desc: 坐标系转换 + * createTime: 2023/8/25 18:18 + */ +public class GpsConvertUtil { + public static final double pi = 3.1415926535897932384626; + public static final double xpi = 3.14159265358979324 * 3000.0 / 180.0; + public static final double a = 6378245.0; + public static final double ee = 0.00669342162296594323; + + public static double transformLat(double x, double y) { + double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + + 0.2 * Math.sqrt(Math.abs(x)); + ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0; + ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0; + ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0; + return ret; + } + + public static double transformLon(double x, double y) { + double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 + * Math.sqrt(Math.abs(x)); + ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0; + ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0; + ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 + * pi)) * 2.0 / 3.0; + return ret; + } + + public static double[] transform(double lon, double lat) { + if (outOfChina(lon, lat)) { + return new double[]{lon, lat}; + } + double dLat = transformLat(lon - 105.0, lat - 35.0); + double dLon = transformLon(lon - 105.0, lat - 35.0); + double radLat = lat / 180.0 * pi; + double magic = Math.sin(radLat); + magic = 1 - ee * magic * magic; + double sqrtMagic = Math.sqrt(magic); + dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); + dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi); + double mgLat = lat + dLat; + double mgLon = lon + dLon; + return new double[]{mgLon, mgLat}; + } + + public static boolean outOfChina(double lon, double lat) { + if (lon < 72.004 || lon > 137.8347) + return true; + return lat < 0.8293 || lat > 55.8271; + } + + /** + * 84 to 火星坐标系 (GCJ-02) World Geodetic System ==> Mars Geodetic System + */ + public static double[] wgs84ToGcj02(double lon, double lat) { + if (outOfChina(lon, lat)) { + return new double[]{lon, lat}; + } + double dLat = transformLat(lon - 105.0, lat - 35.0); + double dLon = transformLon(lon - 105.0, lat - 35.0); + double radLat = lat / 180.0 * pi; + double magic = Math.sin(radLat); + magic = 1 - ee * magic * magic; + double sqrtMagic = Math.sqrt(magic); + dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); + dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi); + double mgLat = lat + dLat; + double mgLon = lon + dLon; + return new double[]{mgLon, mgLat}; + } + + /** + * * 火星坐标系 (GCJ-02) to 84 * * @param lon * @param lat * @return + */ + public static double[] gcj02ToWgs84(double lon, double lat) { + double[] gps = transform(lon, lat); + double longitude = lon * 2 - gps[0]; + double latitude = lat * 2 - gps[1]; + return new double[]{longitude, latitude}; + } + + /** + * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标 + */ + public static double[] gcj02ToBd09(double lon, double lat) { + double z = Math.sqrt(lon * lon + lat * lat) + 0.00002 * Math.sin(lat * xpi); + double theta = Math.atan2(lat, lon) + 0.000003 * Math.cos(lon * xpi); + double tempLon = z * Math.cos(theta) + 0.0065; + double tempLat = z * Math.sin(theta) + 0.006; + return new double[]{tempLon, tempLat}; + } + + /** + * * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标 * * @param + * bdlat * @param bdlon * @return + */ + public static double[] bd09ToGcj02(double lon, double lat) { + double x = lon - 0.0065, y = lat - 0.006; + double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * xpi); + double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * xpi); + double tempLon = z * Math.cos(theta); + double tempLat = z * Math.sin(theta); + return new double[]{tempLon, tempLat}; + } + + /** + * 将wgs84转为bd09 + */ + public static double[] wgs84ToBd09(double lon, double lat) { + double[] gcj02 = wgs84ToGcj02(lon, lat); + return gcj02ToBd09(gcj02[0], gcj02[1]); + } + + public static double[] bd09ToWgs84(double lon, double lat) { + double[] gcj02 = bd09ToGcj02(lon, lat); + double[] wgs84 = gcj02ToWgs84(gcj02[0], gcj02[1]); + // 保留小数点后六位 + wgs84[1] = retain6(wgs84[1]); + wgs84[0] = retain6(wgs84[0]); + return wgs84; + } + + /** + * 保留小数点后六位 + */ + private static double retain6(double num) { + String result = String.format("%.6f", num); + return Double.parseDouble(result); + } + +} diff --git a/policeSecurityServer/src/main/java/com/changhu/module/management/pojo/entity/EnterprisesUnit.java b/policeSecurityServer/src/main/java/com/changhu/module/management/pojo/entity/EnterprisesUnit.java index b5f5b6a..9b3fc65 100644 --- a/policeSecurityServer/src/main/java/com/changhu/module/management/pojo/entity/EnterprisesUnit.java +++ b/policeSecurityServer/src/main/java/com/changhu/module/management/pojo/entity/EnterprisesUnit.java @@ -11,6 +11,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; +import org.locationtech.jts.geom.Point; import java.io.Serial; import java.io.Serializable; @@ -73,6 +74,11 @@ public class EnterprisesUnit extends BaseEntity implements Serializable { */ private String address; + /** + * 坐标 + */ + private Point point; + /** * 联系人 */ diff --git a/policeSecurityServer/src/main/java/com/changhu/module/management/pojo/params/EnterprisesUnitSaveOrUpdateParams.java b/policeSecurityServer/src/main/java/com/changhu/module/management/pojo/params/EnterprisesUnitSaveOrUpdateParams.java index 7751ec3..4b7114f 100644 --- a/policeSecurityServer/src/main/java/com/changhu/module/management/pojo/params/EnterprisesUnitSaveOrUpdateParams.java +++ b/policeSecurityServer/src/main/java/com/changhu/module/management/pojo/params/EnterprisesUnitSaveOrUpdateParams.java @@ -7,6 +7,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.Data; +import org.locationtech.jts.geom.Point; import java.util.List; @@ -40,6 +41,9 @@ public class EnterprisesUnitSaveOrUpdateParams { @Schema(description = "详细地址") private String address; + @Schema(description = "坐标") + private Point point; + @Schema(description = "联系人") private ContactPersonInfo contactPersonInfo; diff --git a/policeSecurityServer/src/main/java/com/changhu/module/management/pojo/vo/EnterprisesUnitPagerVo.java b/policeSecurityServer/src/main/java/com/changhu/module/management/pojo/vo/EnterprisesUnitPagerVo.java index 6fac384..594c1ef 100644 --- a/policeSecurityServer/src/main/java/com/changhu/module/management/pojo/vo/EnterprisesUnitPagerVo.java +++ b/policeSecurityServer/src/main/java/com/changhu/module/management/pojo/vo/EnterprisesUnitPagerVo.java @@ -4,6 +4,7 @@ import com.changhu.common.db.enums.EnterprisesUnitType; import com.changhu.module.management.pojo.model.ContactPersonInfo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import org.locationtech.jts.geom.Point; /** * @author 20252 @@ -46,6 +47,9 @@ public class EnterprisesUnitPagerVo { @Schema(description = "地址") private String address; + @Schema(description = "坐标") + private Point point; + @Schema(description = "联系方式") private ContactPersonInfo contactPersonInfo; diff --git a/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/FastJson2Config.java b/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/FastJson2Config.java index 13fc834..10cf050 100644 --- a/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/FastJson2Config.java +++ b/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/FastJson2Config.java @@ -8,9 +8,18 @@ import com.alibaba.fastjson2.support.spring6.http.converter.FastJsonHttpMessageC import com.changhu.common.db.BaseEnum; import com.changhu.common.properties.Fastjson2Properties; import com.changhu.support.fastjson2.deserialze.DbEnumDeserializer; +import com.changhu.support.fastjson2.deserialze.LatitudeDeserializer; +import com.changhu.support.fastjson2.deserialze.LongitudeDeserializer; +import com.changhu.support.fastjson2.deserialze.PointDeserializer; import com.changhu.support.fastjson2.filter.DesensitizedFilter; import com.changhu.support.fastjson2.serializer.DbEnumSerializer; +import com.changhu.support.fastjson2.serializer.LatitudeSerializer; +import com.changhu.support.fastjson2.serializer.LongitudeSerializer; +import com.changhu.support.fastjson2.serializer.PointSerializer; import lombok.extern.slf4j.Slf4j; +import org.geotools.measure.Latitude; +import org.geotools.measure.Longitude; +import org.locationtech.jts.geom.Point; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.context.annotation.Bean; @@ -47,9 +56,17 @@ public class FastJson2Config { JSON.register(clazz, DbEnumDeserializer.instance); }); - JSON.config(JSONWriter.Feature.WriteLongAsString); + JSON.register(Latitude.class, LatitudeSerializer.instance); + JSON.register(Longitude.class, LongitudeSerializer.instance); + JSON.register(Point.class, PointSerializer.instance); //反序列化配置 + JSON.register(Latitude.class, LatitudeDeserializer.instance); + JSON.register(Longitude.class, LongitudeDeserializer.instance); + JSON.register(Point.class, PointDeserializer.instance); + + JSON.config(JSONWriter.Feature.WriteLongAsString); + } @Bean diff --git a/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/deserialze/LatitudeDeserializer.java b/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/deserialze/LatitudeDeserializer.java new file mode 100644 index 0000000..98c55b4 --- /dev/null +++ b/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/deserialze/LatitudeDeserializer.java @@ -0,0 +1,31 @@ +package com.changhu.support.fastjson2.deserialze; + +import com.alibaba.fastjson2.JSONReader; +import com.alibaba.fastjson2.reader.ObjectReader; +import org.geotools.measure.Latitude; + +import java.lang.reflect.Type; +import java.math.BigDecimal; + +/** + * author: luozhun + * desc: LatitudeDeserializer + * createTime: 2023/8/26 16:10 + */ +public class LatitudeDeserializer implements ObjectReader { + + public static final LatitudeDeserializer instance = new LatitudeDeserializer(); + + private LatitudeDeserializer() { + } + + @Override + public Latitude readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) { + //读取为BigDecimal来确保精度和避免浮点数的舍入误差 + BigDecimal value = jsonReader.readBigDecimal(); + if (value == null) { + return null; + } + return new Latitude(value.doubleValue()); + } +} diff --git a/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/deserialze/LongitudeDeserializer.java b/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/deserialze/LongitudeDeserializer.java new file mode 100644 index 0000000..b8ba7fe --- /dev/null +++ b/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/deserialze/LongitudeDeserializer.java @@ -0,0 +1,31 @@ +package com.changhu.support.fastjson2.deserialze; + +import com.alibaba.fastjson2.JSONReader; +import com.alibaba.fastjson2.reader.ObjectReader; +import org.geotools.measure.Longitude; + +import java.lang.reflect.Type; +import java.math.BigDecimal; + +/** + * author: luozhun + * desc: LongitudeDeserializer + * createTime: 2023/8/26 16:15 + */ +public class LongitudeDeserializer implements ObjectReader { + + public static final LongitudeDeserializer instance = new LongitudeDeserializer(); + + private LongitudeDeserializer() { + } + + @Override + public Longitude readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) { + //读取为BigDecimal来确保精度和避免浮点数的舍入误差 + BigDecimal value = jsonReader.readBigDecimal(); + if (value == null) { + return null; + } + return new Longitude(value.doubleValue()); + } +} \ No newline at end of file diff --git a/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/deserialze/PointDeserializer.java b/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/deserialze/PointDeserializer.java new file mode 100644 index 0000000..c1c4f13 --- /dev/null +++ b/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/deserialze/PointDeserializer.java @@ -0,0 +1,35 @@ +package com.changhu.support.fastjson2.deserialze; + +import cn.hutool.core.collection.CollUtil; +import com.alibaba.fastjson2.JSONReader; +import com.alibaba.fastjson2.reader.ObjectReader; +import com.changhu.common.utils.GeometryUtil; +import org.locationtech.jts.geom.Point; + +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +/** + * author: luozhun + * desc: PointDeserializer + * createTime: 2023/8/26 16:28 + */ +public class PointDeserializer implements ObjectReader { + + public static final PointDeserializer instance = new PointDeserializer(); + + private PointDeserializer() { + } + + @Override + public Point readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) { + List list = new ArrayList<>(); + jsonReader.readArray(list, BigDecimal.class); + if (CollUtil.isEmpty(list)) { + return null; + } + return GeometryUtil.createPoint(list); + } +} \ No newline at end of file diff --git a/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/serializer/LatitudeSerializer.java b/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/serializer/LatitudeSerializer.java new file mode 100644 index 0000000..55deee1 --- /dev/null +++ b/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/serializer/LatitudeSerializer.java @@ -0,0 +1,30 @@ +package com.changhu.support.fastjson2.serializer; + +import com.alibaba.fastjson2.JSONWriter; +import com.alibaba.fastjson2.writer.ObjectWriter; +import org.geotools.measure.Latitude; + +import java.lang.reflect.Type; + +/** + * author: luozhun + * desc: LatitudeSerializer + * createTime: 2023/8/26 15:44 + */ +public class LatitudeSerializer implements ObjectWriter { + + public static final LatitudeSerializer instance = new LatitudeSerializer(); + + private LatitudeSerializer() { + } + + @Override + public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) { + if (object == null) { + jsonWriter.writeNull(); + return; + } + jsonWriter.writeDouble(((Latitude) object).degrees()); + } +} + diff --git a/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/serializer/LongitudeSerializer.java b/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/serializer/LongitudeSerializer.java new file mode 100644 index 0000000..42b27df --- /dev/null +++ b/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/serializer/LongitudeSerializer.java @@ -0,0 +1,30 @@ +package com.changhu.support.fastjson2.serializer; + +import com.alibaba.fastjson2.JSONWriter; +import com.alibaba.fastjson2.writer.ObjectWriter; +import org.geotools.measure.Longitude; + +import java.lang.reflect.Type; + +/** + * author: luozhun + * desc: LongitudeSerializer + * createTime: 2023/8/26 15:46 + */ +public class LongitudeSerializer implements ObjectWriter { + + public static final LongitudeSerializer instance = new LongitudeSerializer(); + + private LongitudeSerializer() { + } + + @Override + public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) { + if (object == null) { + jsonWriter.writeNull(); + return; + } + jsonWriter.writeDouble(((Longitude) object).degrees()); + } +} + diff --git a/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/serializer/PointSerializer.java b/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/serializer/PointSerializer.java new file mode 100644 index 0000000..3815c21 --- /dev/null +++ b/policeSecurityServer/src/main/java/com/changhu/support/fastjson2/serializer/PointSerializer.java @@ -0,0 +1,45 @@ +package com.changhu.support.fastjson2.serializer; + +import com.alibaba.fastjson2.JSONWriter; +import com.alibaba.fastjson2.writer.ObjectWriter; +import com.changhu.common.utils.GeometryUtil; +import org.geotools.measure.Latitude; +import org.geotools.measure.Longitude; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.Point; + +import java.lang.reflect.Type; +import java.util.Arrays; + +/** + * author: luozhun + * desc: PointSerializer + * createTime: 2023/8/26 15:59 + */ +public class PointSerializer implements ObjectWriter { + + public static final PointSerializer instance = new PointSerializer(); + + private PointSerializer() { + } + + @Override + public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) { + if (object == null) { + jsonWriter.writeNull(); + return; + } + Point point = (Point) object; + if (GeometryUtil.equals(GeometryUtil.emptyPoint(), point)) { + jsonWriter.writeNull(); + return; + } + jsonWriter.writeAny( + Arrays.asList( + new Longitude(point.getCoordinate().getOrdinate(Coordinate.X)).degrees(), + new Latitude(point.getCoordinate().getOrdinate(Coordinate.Y)).degrees() + ) + ); + } +} + diff --git a/policeSecurityServer/src/main/java/com/changhu/support/mybatisplus/config/CustomMybatisPlusConfig.java b/policeSecurityServer/src/main/java/com/changhu/support/mybatisplus/config/CustomMybatisPlusConfig.java index cd63570..6421501 100644 --- a/policeSecurityServer/src/main/java/com/changhu/support/mybatisplus/config/CustomMybatisPlusConfig.java +++ b/policeSecurityServer/src/main/java/com/changhu/support/mybatisplus/config/CustomMybatisPlusConfig.java @@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionIntercepto import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import com.changhu.support.mybatisplus.interceptor.CustomDataPermissionHandler; +import com.changhu.support.mybatisplus.interceptor.GeometryInnerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -30,6 +31,8 @@ public class CustomMybatisPlusConfig { interceptor.addInnerInterceptor(paginationInterceptor(DbType.MYSQL)); // sql性能规范 // interceptor.addInnerInterceptor(new IllegalSQLInnerInterceptor()); + // 地理位置支持 配合 + interceptor.addInnerInterceptor(new GeometryInnerInterceptor()); interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor()); //乐观锁插件 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); diff --git a/policeSecurityServer/src/main/java/com/changhu/support/mybatisplus/handler/global/geo/AbstractGeometryTypeHandler.java b/policeSecurityServer/src/main/java/com/changhu/support/mybatisplus/handler/global/geo/AbstractGeometryTypeHandler.java new file mode 100644 index 0000000..cf908b8 --- /dev/null +++ b/policeSecurityServer/src/main/java/com/changhu/support/mybatisplus/handler/global/geo/AbstractGeometryTypeHandler.java @@ -0,0 +1,13 @@ +package com.changhu.support.mybatisplus.handler.global.geo; + +import org.apache.ibatis.type.BaseTypeHandler; +import org.locationtech.jts.geom.Geometry; + +/** + * author: luozhun + * desc: GeometryTypeHandler + * createTime: 2023/8/25 17:59 + */ +public abstract class AbstractGeometryTypeHandler extends BaseTypeHandler { +} + diff --git a/policeSecurityServer/src/main/java/com/changhu/support/mybatisplus/handler/global/geo/PointTypeHandler.java b/policeSecurityServer/src/main/java/com/changhu/support/mybatisplus/handler/global/geo/PointTypeHandler.java new file mode 100644 index 0000000..3c0208d --- /dev/null +++ b/policeSecurityServer/src/main/java/com/changhu/support/mybatisplus/handler/global/geo/PointTypeHandler.java @@ -0,0 +1,55 @@ +package com.changhu.support.mybatisplus.handler.global.geo; + +import cn.hutool.core.util.ClassUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.changhu.common.utils.GeometryUtil; +import org.apache.ibatis.type.JdbcType; +import org.apache.ibatis.type.MappedJdbcTypes; +import org.apache.ibatis.type.MappedTypes; +import org.locationtech.jts.geom.Point; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * author: luozhun + * desc: PointTypeHandler + * createTime: 2023/8/26 13:17 + */ +@MappedJdbcTypes(JdbcType.VARCHAR) +@MappedTypes(Point.class) +public class PointTypeHandler extends AbstractGeometryTypeHandler { + + @Override + public void setNonNullParameter(PreparedStatement preparedStatement, int i, Point point, JdbcType jdbcType) throws SQLException { + preparedStatement.setString(i, point.toText()); + } + + @Override + public Point getNullableResult(ResultSet resultSet, String s) throws SQLException { + return createPoint(resultSet.getString(s), resultSet.getBytes(s)); + } + + @Override + public Point getNullableResult(ResultSet resultSet, int i) throws SQLException { + return createPoint(resultSet.getString(i), resultSet.getBytes(i)); + } + + @Override + public Point getNullableResult(CallableStatement callableStatement, int i) throws SQLException { + return createPoint(callableStatement.getString(i), callableStatement.getBytes(i)); + } + + public Point createPoint(String pointStr, byte[] pointBytes) { + if (JSONUtil.isTypeJSON(pointStr)) { + return GeometryUtil.createGeometryFromGeoJson(pointStr, Point.class); + } + if (StrUtil.startWithIgnoreCase(pointStr, ClassUtil.getClassName(Point.class, true))) { + return GeometryUtil.createGeometryFromWkt(pointStr, Point.class); + } + return GeometryUtil.createPoint(pointBytes); + } +} diff --git a/policeSecurityServer/src/main/java/com/changhu/support/mybatisplus/interceptor/GeometryInnerInterceptor.java b/policeSecurityServer/src/main/java/com/changhu/support/mybatisplus/interceptor/GeometryInnerInterceptor.java new file mode 100644 index 0000000..7d6dccc --- /dev/null +++ b/policeSecurityServer/src/main/java/com/changhu/support/mybatisplus/interceptor/GeometryInnerInterceptor.java @@ -0,0 +1,133 @@ +package com.changhu.support.mybatisplus.interceptor; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ReUtil; +import cn.hutool.core.util.ReflectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.core.toolkit.PluginUtils; +import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport; +import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.executor.statement.StatementHandler; +import org.apache.ibatis.mapping.BoundSql; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.SqlCommandType; +import org.locationtech.jts.geom.*; + +import java.lang.reflect.Field; +import java.sql.Connection; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static com.changhu.common.utils.GeometryUtil.ST_GeomFromText; + + +/** + * @author 20252 + * @createTime 2024/6/6 下午4:32 + * @desc 注意!!!此拦截器只针对mp提供的基本构造方法管用 可以进行参数对象拦截 如果是xml,请自行添加ST_GeomFromText函数 + */ +@Slf4j +public class GeometryInnerInterceptor extends JsqlParserSupport implements InnerInterceptor { + + + public static final List> GEOMETRY_CLASS_LIST = CollUtil.newArrayList( + Point.class, + MultiPoint.class, + Polygon.class, + MultiPolygon.class, + LineString.class, + MultiLineString.class + ); + + public GeometryInnerInterceptor() { + } + + @Override + public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) { + PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh); + MappedStatement ms = mpSh.mappedStatement(); + //sql类型:INSERT UPDATE DELETE + SqlCommandType sct = ms.getSqlCommandType(); + //mp参数 + Object parameter = mpSh.parameterHandler().getParameterObject(); + //参数对象 + Object object = null; + //获取参数的属性 + switch (sct) { + case UPDATE: + try { + object = BeanUtil.beanToMap(parameter).get(Constants.ENTITY); + } catch (Exception ignored) { + } + break; + case INSERT: + object = parameter; + break; + } + //如果没有参数 就不进行sql修改 + if (object == null) { + return; + } + //获取 parameter 对象 中有关 geometry 的属性名对应 + List geoFields = this.getGeoFields(object); + //如果没有geometry字段 就不进行sql修改 + if (geoFields.isEmpty()) { + return; + } + //获取原始sql + BoundSql boundSql = ms.getBoundSql(parameter); + //UPDATE geo_test SET update_by=?,update_time=?,delete_flag=1 WHERE id=? AND delete_flag=0 + String originalSql = StrUtil.removeAllLineBreaks(boundSql.getSql()); + switch (sct) { + case UPDATE: + for (String geometryField : geoFields) { + String regex = geometryField + "\\s*=\\s*\\?"; + originalSql = ReUtil.replaceAll(originalSql, regex, StrUtil.format("{}={}", geometryField, ST_GeomFromText)); + } + break; + case INSERT: + for (String geometryField : geoFields) { + originalSql = this.replaceFindGeo(originalSql, geometryField); + } + break; + } + PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql(); + //修改sql + mpBs.sql(originalSql); + } + + private String replaceFindGeo(String originalSql, String geometryField) { + List split = StrUtil.split(originalSql, geometryField); + //找出geo字段在sql中的位置 + int geometryFieldIndex = StrUtil.count(split.get(0), ","); + StringBuilder stringBuffer = new StringBuilder(); + Matcher matcher = Pattern.compile("\\?").matcher(originalSql); + int count = 0; + while (matcher.find()) { + if (count == geometryFieldIndex) { + matcher.appendReplacement(stringBuffer, ST_GeomFromText); + break; + } + count++; + } + matcher.appendTail(stringBuffer); + return stringBuffer.toString(); + } + + /** + * 获取对象中的geo字段 + */ + private List getGeoFields(Object object) { + return Arrays.stream(ReflectUtil.getFields(object.getClass())) + .filter(field -> GEOMETRY_CLASS_LIST.contains(field.getType())) + .map(Field::getName) + .collect(Collectors.toList()); + } + +} diff --git a/superManagement/.env.development b/superManagement/.env.development index e416923..024b5f7 100644 --- a/superManagement/.env.development +++ b/superManagement/.env.development @@ -18,3 +18,4 @@ VITE_APP_MINIO_BUCKET=police-security-dev # 高德 VITE_APP_GAODE_KEY=f379a3f860a68d7438526275d6a94b05 VITE_APP_GAODE_VERSION=2.0 +VITE_APP_SECURITY_JS_CODE=432125a0f8d8cad2dac38b77d6f6728f diff --git a/superManagement/.env.production b/superManagement/.env.production index 70b36e1..3104a00 100644 --- a/superManagement/.env.production +++ b/superManagement/.env.production @@ -18,3 +18,4 @@ VITE_APP_MINIO_BUCKET=police-security # 高德 VITE_APP_GAODE_KEY=f379a3f860a68d7438526275d6a94b05 VITE_APP_GAODE_VERSION=2.0 +VITE_APP_SECURITY_JS_CODE=432125a0f8d8cad2dac38b77d6f6728f diff --git a/superManagement/src/components/aMap/MapContainer.vue b/superManagement/src/components/aMap/MapContainer.vue index d637e87..fdd897c 100644 --- a/superManagement/src/components/aMap/MapContainer.vue +++ b/superManagement/src/components/aMap/MapContainer.vue @@ -10,7 +10,7 @@ import {initMap} from "@/utils/aMapUtil"; const props = withDefaults(defineProps<{ plugins?: string[], - initCallback?: () => void, + initCallback?: (map: AMap.Map) => void, mapOptions?: AMap.MapOptions }>(), { plugins: () => { @@ -36,8 +36,8 @@ defineExpose({ onMounted(() => { initMap(props.plugins).then(AMap => { - props.initCallback && props.initCallback() map.value = new AMap.Map(mapId, props.mapOptions) + props.initCallback && props.initCallback(map.value) }) }) diff --git a/superManagement/src/types/views/unitManage/police/policeUnit.ts b/superManagement/src/types/views/unitManage/police/policeUnit.ts index c3bdb3b..7c38d1b 100644 --- a/superManagement/src/types/views/unitManage/police/policeUnit.ts +++ b/superManagement/src/types/views/unitManage/police/policeUnit.ts @@ -76,6 +76,7 @@ export interface EnterprisesUnitPagerVo extends BaseTableRowRecord { streetName?: string; /** 地址 **/ address?: string; + point: [number, number] /** 联系方式 **/ contactPersonInfo?: { name: string; @@ -98,6 +99,7 @@ export interface EnterprisesUnitSaveOrUpdateParams { administrativeDivisionCodes: string[]; /** 详细地址 **/ address?: string; + point?: [number, number] /** 联系人 **/ contactPersonInfo?: { name: string; diff --git a/superManagement/src/utils/aMapUtil.ts b/superManagement/src/utils/aMapUtil.ts index 574e061..5d90620 100644 --- a/superManagement/src/utils/aMapUtil.ts +++ b/superManagement/src/utils/aMapUtil.ts @@ -4,7 +4,7 @@ type Amap = typeof AMap; export const initMap = (plugins?: string[]): Promise => new Promise((resolve, reject) => { //@ts-ignore window._AMapSecurityConfig = { - securityJsCode: '432125a0f8d8cad2dac38b77d6f6728f' + securityJsCode: __APP_ENV.VITE_APP_SECURITY_JS_CODE } AMapLoader.load({ key: __APP_ENV.VITE_APP_GAODE_KEY, diff --git a/superManagement/src/views/unitManage/police/unitManage/index.tsx b/superManagement/src/views/unitManage/police/unitManage/index.tsx index 1b615cc..e4ef716 100644 --- a/superManagement/src/views/unitManage/police/unitManage/index.tsx +++ b/superManagement/src/views/unitManage/police/unitManage/index.tsx @@ -29,6 +29,21 @@ const saveOrUpdateEnterprisesUnit = (params: _FormType, callback: Function) => { let city = ''; + const initMarker = (map: AMap.Map) => { + //添加maker点 设置point + const maker = new AMap.Marker({ + position: _formParams.value.point, + draggable: true + }) + maker.on("dragend", ({lnglat}) => { + _formParams.value.point = lnglat + }) + map.clearMap() + map.add(maker) + map.setFitView() + console.log(123); + } + const _formOptions = ref>({ name: { type: 'input', @@ -62,7 +77,7 @@ const saveOrUpdateEnterprisesUnit = (params: _FormType, callback: Function) => { customRender: () => { + initCallback={(map) => { AMap.plugin(['AMap.AutoComplete'], () => { //@ts-ignore const auto = new AMap.AutoComplete({ @@ -76,25 +91,19 @@ const saveOrUpdateEnterprisesUnit = (params: _FormType, callback: Function) => { message.error('所选点位没有经纬度信息 建议选则附近的手动移动!'); return } - //添加maker点 设置point - const maker = new AMap.Marker({ - position: e.poi.location, - draggable: true - }) - console.log(e); - maker.on("dragend", (e) => { - console.log(e); - - }) - _mapRef.value.mapInstance.add(maker) - _mapRef.value.mapInstance.setFitView() + _formParams.value.point = e.poi.location + initMarker(map) }); }) + if (_formParams.value.point) { + initMarker(map) + } }} >

@@ -176,6 +185,7 @@ export const showEnterprisesUnit = (policeUnitPagerVo: PoliceUnitPagerVo) => { type: record.type.value, administrativeDivisionCodes: [record.province, record.city, record.districts, record.street].filter(Boolean), address: record.address, + point: record.point, contactPersonInfoName: record.contactPersonInfo?.name, contactPersonInfoTelephone: record.contactPersonInfo?.telephone, remark: record.remark diff --git a/superManagement/src/views/unitManage/police/unitManage/index.vue b/superManagement/src/views/unitManage/police/unitManage/index.vue index 68b9f03..3c3975d 100644 --- a/superManagement/src/views/unitManage/police/unitManage/index.vue +++ b/superManagement/src/views/unitManage/police/unitManage/index.vue @@ -129,6 +129,29 @@ const searchFormOptions = ref({ } }) +const a = { + groupId1: { + itemId1: { + standardId: 123123, + deductionPoints: 2 + }, + itemId2: { + standardId: 345345, + deductionPoints: 4 + } + }, + groupId2: { + itemId1: { + standardId: 456456, + deductionPoints: 2 + }, + itemId2: { + standardId: 567567, + deductionPoints: 4 + } + } +} +