args = new ArrayList<>();
-
- // A4 画幅
- for (RainMapsEnums map : maps) {
- // qgis参数
- QgisArgsParams arg = new QgisArgsParams();
- arg.setId(map.getNum());
- arg.setEvent(assess.getRainId());
- arg.setQueueId(assess.getRainQueueId());
- arg.setCenterX(assess.getLongitude());
- arg.setCenterY(assess.getLatitude());
- arg.setInfo(EarthquakeHandler.parseRInfo(assess.getOccurrenceTime(), assess.getRainfall(), assess.getDuration()));
- arg.setMapTitle(EarthquakeHandler.combineR(assess.getPosition(), assess.getRainType(), map));
- arg.setMapTime(BaseUtils.formatTime(LocalDateTime.now(), false));
- arg.setMapLayout(BaseConstants.MAP_LAYOUT_A3); // A4
- arg.setMapUint(BaseConstants.MAP_UNIT); // 单位
- // 死信队列中获取单张图片
- arg.setName(map.getName());
- arg.setOutFile(EarthquakeHandler.getRPath(assess.getRainId(), assess.getRainQueueId(), BaseConstants.MAP_LAYOUT_A4, map, qgisProperties));
- arg.setPath(qgisProperties.getRainMapsTemplatePath() + map.getName() + ".qgz");
- arg.setDisaster(BaseConstants.RAIN_DISASTER_MAP); // 暴雨灾害
- // 按规则缩放
- arg.setZoomRule(BaseEnums.NO.getCode().toString()); // 默认不缩放
- arg.setZoomValue(""); // 默认缩放值
-
- args.add(arg);
- }
-
- // 增加 A3 画幅
- for (RainMapsEnums map : maps) {
- // qgis参数
- QgisArgsParams arg = new QgisArgsParams();
- arg.setId(map.getNum());
- arg.setEvent(assess.getRainId());
- arg.setQueueId(assess.getRainQueueId());
- arg.setCenterX(assess.getLongitude());
- arg.setCenterY(assess.getLatitude());
- arg.setInfo(EarthquakeHandler.parseRInfo(assess.getOccurrenceTime(), assess.getRainfall(), assess.getDuration()));
- arg.setMapTitle(EarthquakeHandler.combineR(assess.getPosition(), assess.getRainType(), map));
- arg.setMapTime(BaseUtils.formatTime(LocalDateTime.now(), false));
- arg.setMapLayout(BaseConstants.MAP_LAYOUT_A4); // A4
- arg.setMapUint(BaseConstants.MAP_UNIT); // 单位
- // 死信队列中获取单张图片
- arg.setName(map.getName());
- arg.setOutFile(EarthquakeHandler.getRPath(assess.getRainId(), assess.getRainQueueId(), BaseConstants.MAP_LAYOUT_A3, map, qgisProperties));
- arg.setPath(qgisProperties.getRainMapsTemplatePath() + map.getName() + ".qgz");
- arg.setDisaster(BaseConstants.RAIN_DISASTER_MAP); // 暴雨灾害
- arg.setZoomRule(BaseEnums.NO.getCode().toString()); // 默认不缩放
- arg.setZoomValue(""); // 默认缩放值
-
- args.add(arg);
- }
-
- log.info("制图参数设置完成!");
-
- return args;
- }
-
-
- /**
- * 专题图缩放变化:
- * A3:
- * 4级地震:不放缩
- * 5-6级地震:所有A3都放缩到intensity
- * 6级以上,除了影响场intensity,其他不变
- *
- * A4:
- * 所有都不变
- */
- public Map change(EarthquakeAssessmentDTO assess, String size, String name) {
- Map map = new HashMap<>();
-
- if (size.equals("A3")) {
- if (assess.getEqMagnitude() >= 4 && assess.getEqMagnitude() < 5) {
- map.put("k", BaseEnums.NO.getCode().toString());
- map.put("v", "");
- return map;
- }
- if (assess.getEqMagnitude() >= 5 && assess.getEqMagnitude() < 6) {
- map.put("k", BaseEnums.M_LAYER2.getCode().toString());
- map.put("v", "intensity");
- return map;
- }
- if (assess.getEqMagnitude() >= 6) {
- if (name.equals("地震影响估计范围分布图")) {
- map.put("k", BaseEnums.M_LAYER2.getCode().toString());
- map.put("v", "intensity");
- return map;
- } else {
- map.put("k", BaseEnums.NO.getCode().toString());
- map.put("v", "");
- return map;
- }
- }
- }
- map.put("k", BaseEnums.NO.getCode().toString());
- map.put("v", "");
- return map;
- }
-
-}
diff --git a/src/main/java/com/gis/xian/service/qgis/earthquake/impl/EarthquakeQueueServiceImpl.java b/src/main/java/com/gis/xian/service/qgis/earthquake/impl/EarthquakeQueueServiceImpl.java
index 0364ec3..b35b355 100644
--- a/src/main/java/com/gis/xian/service/qgis/earthquake/impl/EarthquakeQueueServiceImpl.java
+++ b/src/main/java/com/gis/xian/service/qgis/earthquake/impl/EarthquakeQueueServiceImpl.java
@@ -1,190 +1,36 @@
package com.gis.xian.service.qgis.earthquake.impl;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gis.xian.config.DataSource;
-import com.gis.xian.constant.BaseConstants;
-import com.gis.xian.dto.qgis.earthquake.EarthquakeAssessmentDTO;
-import com.gis.xian.dto.qgis.rain.RainAssessmentDTO;
+import com.gis.xian.dto.qgis.base.QgisTriggerDTO;
import com.gis.xian.entity.qgis.earthquake.EarthquakeQueue;
-import com.gis.xian.enums.qgis.BaseEnums;
import com.gis.xian.mapper.qgis.earthquake.EarthquakeQueueMapper;
-import com.gis.xian.service.qgis.earthquake.IEarthquakeInformationDistanceService;
-import com.gis.xian.service.qgis.earthquake.IEarthquakeInformationInfluenceService;
-import com.gis.xian.service.ex.ParmaException;
-import com.gis.xian.service.ex.ServeException;
-import com.gis.xian.service.qgis.earthquake.IEarthquakeProductService;
+import com.gis.xian.service.qgis.base.IFeignService;
import com.gis.xian.service.qgis.earthquake.IEarthquakeQueueService;
-import com.gis.xian.utils.BaseUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.time.LocalDateTime;
/**
- * @author zzw
- * @description: 地震评估业务
- * @date 2026/5/25 下午6:09
+ * 地震评估队列服务
+ * 简化为只负责触发 Python 端生成专题图
*/
@Slf4j
@Service
@DataSource("slave1")
-public class EarthquakeQueueServiceImpl extends ServiceImpl implements IEarthquakeQueueService {
+public class EarthquakeQueueServiceImpl extends ServiceImpl
+ implements IEarthquakeQueueService {
@Resource
- private IEarthquakeInformationDistanceService IEarthquakeInformationDistanceService;
- @Resource
- private IEarthquakeInformationInfluenceService IEarthquakeInformationInfluenceService;
- @Resource
- private IEarthquakeProductService IEarthquakeProductService;
+ private IFeignService feignService;
- // 地震评估
- @Transactional
@Override
- public void assess(EarthquakeAssessmentDTO assess) {
- log.info("开始评估,评估参数:{}", assess);
- // 异常值
- if (assess == null) {
- throw new ParmaException(BaseConstants.PARAMS_ERROR);
- }
- // 评估业务
- try {
- // 初始化评估
- initial(assess, BaseConstants.MANUAL);
- // 地震影响场评估 5s
- IEarthquakeInformationInfluenceService.handle(assess);
- updated(assess.getEvent(), assess.getEqQueueId(), BaseUtils.compute(1, 0), BaseEnums.CALCULATING.getCode());
- // 震中距评估
- IEarthquakeInformationDistanceService.handle(assess.getLongitude(), assess.getLatitude(), assess.getEqQueueId());
- // 专题图产出
- IEarthquakeProductService.makeEarthquakeMaps(assess);
- } catch (Exception ex) {
- log.error(ex.getMessage());
- throw new ServeException(BaseConstants.ASSESS_SERVER_ERROR);
- }
+ public void trigger(String simulationId, String type) {
+ log.info("触发专题图生成: simulationId={}, type={}", simulationId, type);
+ QgisTriggerDTO triggerDTO = new QgisTriggerDTO();
+ triggerDTO.setSimulationId(simulationId);
+ triggerDTO.setType(type);
+ feignService.trigger(triggerDTO);
+ log.info("专题图触发完成: simulationId={}", simulationId);
}
-
- @Transactional
- @Override
- public void assess(RainAssessmentDTO assess) {
- log.info("开始评估,评估参数:{}", assess);
- // 异常值
- if (assess == null) {
- throw new ParmaException(BaseConstants.PARAMS_ERROR);
- }
- // 评估业务
- try {
- // 初始化评估
- initial(assess, BaseConstants.MANUAL);
- // 专题图产出
- IEarthquakeProductService.makeRainstormMaps(assess);
- } catch (Exception ex) {
- log.error(ex.getMessage());
- throw new ServeException(BaseConstants.ASSESS_SERVER_ERROR);
- }
- }
-
- // 地震初始化评估进度和评估状态
- private void initial(EarthquakeAssessmentDTO assess, int type) {
-
- EarthquakeQueue dzqueue = new EarthquakeQueue();
- BeanUtils.copyProperties(assess, dzqueue);
- dzqueue.setId(assess.getEqQueueId());
- dzqueue.setBatch(1);
- dzqueue.setType(type); // 手动
- dzqueue.setState(BaseEnums.NOT_STARTED.getCode());
- dzqueue.setMode(1); // 0 地震参数 1 影响场
- dzqueue.setBeginTime(LocalDateTime.now());
- dzqueue.setProgress(0.0); // 评估进度
- dzqueue.setRemark(BaseEnums.NOT_STARTED.getDesc());
-
- save(dzqueue);
- log.info("地震评估业务初始化完成!");
- }
-
- // 暴雨初始化评估进度和评估状态
- private void initial(RainAssessmentDTO assess, int type) {
-
- EarthquakeQueue dzqueue = new EarthquakeQueue();
- BeanUtils.copyProperties(assess, dzqueue);
- dzqueue.setId(assess.getRainQueueId());
- dzqueue.setBatch(1);
- dzqueue.setType(type); // 手动
- dzqueue.setState(BaseEnums.NOT_STARTED.getCode());
- dzqueue.setMode(null); // 0 地震参数 1 影响场
- dzqueue.setBeginTime(LocalDateTime.now());
- dzqueue.setProgress(0.0); // 评估进度
- dzqueue.setRemark(BaseEnums.NOT_STARTED.getDesc());
-
- save(dzqueue);
- log.info("暴雨评估业务初始化完成!");
- }
-
-
- // 更新评估进度和评估状态
- public void updated(String event, String queueId, double progress, int state) {
-
- EarthquakeQueue dzqueue = new EarthquakeQueue();
- // 条件
- LambdaQueryWrapper lambdaQuery = Wrappers.lambdaQuery(EarthquakeQueue.class)
- .eq(EarthquakeQueue::getEvent, event)
- .eq(EarthquakeQueue::getId, queueId);
-
- // 评估异常终止
- if (state == BaseEnums.TIMEOUT_OR_EXCEPTION.getCode()) {
- dzqueue.setState(BaseEnums.TIMEOUT_OR_EXCEPTION.getCode());
- dzqueue.setEndTime(LocalDateTime.now());
- dzqueue.setProgress(progress); // 评估进度
- dzqueue.setRemark(BaseEnums.TIMEOUT_OR_EXCEPTION.getDesc());
- // 更新状态
- update(dzqueue, lambdaQuery);
- log.info("评估异常结束!");
- return;
- }
- // 人工停止
- if (state == BaseEnums.MANUAL_STOPPED.getCode()) {
- dzqueue.setState(BaseEnums.MANUAL_STOPPED.getCode());
- dzqueue.setEndTime(LocalDateTime.now());
- dzqueue.setProgress(progress); // 评估进度
- dzqueue.setRemark(BaseEnums.MANUAL_STOPPED.getDesc());
- // 更新状态
- update(dzqueue, lambdaQuery);
- log.info("评估人工停止!");
- return;
- }
- // 不计算
- if (state == BaseEnums.NOT_CALCULATE.getCode()) {
- dzqueue.setState(BaseEnums.NOT_CALCULATE.getCode());
- dzqueue.setEndTime(LocalDateTime.now());
- dzqueue.setProgress(progress); // 评估进度
- dzqueue.setRemark(BaseEnums.NOT_CALCULATE.getDesc());
- // 更新状态
- update(dzqueue, lambdaQuery);
- log.info("本次事件不参与评估计算!");
- return;
- }
- // 正常继续评估
- if (state == BaseEnums.CALCULATING.getCode()) {
- if (progress < 100) {
- dzqueue.setProgress(progress);
- // 更新进度
- update(dzqueue, lambdaQuery);
- log.info("评估业务进度:{}%", progress);
- return;
- }
- // 评估完成
- dzqueue.setState(BaseEnums.NORMAL_COMPLETED.getCode());
- dzqueue.setEndTime(LocalDateTime.now());
- dzqueue.setProgress(progress); // 评估进度
- dzqueue.setRemark(BaseEnums.NORMAL_COMPLETED.getDesc());
- update(dzqueue, lambdaQuery);
- log.info("评估工作结束!");
- }
-
- }
-
}
diff --git a/src/main/java/com/gis/xian/service/qgis/rain/impl/RainEventServiceImpl.java b/src/main/java/com/gis/xian/service/qgis/rain/impl/RainEventServiceImpl.java
index a7d3fdb..56d5959 100644
--- a/src/main/java/com/gis/xian/service/qgis/rain/impl/RainEventServiceImpl.java
+++ b/src/main/java/com/gis/xian/service/qgis/rain/impl/RainEventServiceImpl.java
@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gis.xian.config.DataSource;
import com.gis.xian.constant.BaseConstants;
-import com.gis.xian.dto.qgis.rain.RainAssessmentDTO;
import com.gis.xian.dto.qgis.rain.RainEventDTO;
import com.gis.xian.dto.qgis.rain.RainTriggerDTO;
import com.gis.xian.entity.qgis.rain.RainEvent;
@@ -27,31 +26,27 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
- * @author zzw
- * @description: REventServiceImpl
- * @date 2026/6/8 下午4:45
+ * 暴雨事件服务
*/
@Slf4j
@Service
@DataSource("slave1")
public class RainEventServiceImpl extends ServiceImpl implements IREventService {
- @Resource
- private IEarthquakeQueueService IEarthquakeQueueService;
- // 暴雨触发
+ @Resource
+ private IEarthquakeQueueService queueService;
+
@Transactional
@Override
public RainQuery trigger(RainTriggerDTO trigger) {
log.info("暴雨参数:{}", trigger);
- // 异常值
if (trigger == null) {
throw new ParmaException(BaseConstants.PARAMS_ERROR);
}
- // 专题图命名代码
+
String code = BaseUtils.generationRainCode(trigger.getOccurrenceTime());
- // 暴雨业务
+
try {
- // 暴雨信息存储
RainEventDTO eventdto = new RainEventDTO();
BeanUtils.copyProperties(trigger, eventdto);
eventdto.setRainId(code);
@@ -59,70 +54,42 @@ public class RainEventServiceImpl extends ServiceImpl lambdaQuery = Wrappers.lambdaQuery(RainEvent.class);
lambdaQuery.eq(RainEvent::getId, Id);
- int flag = this.baseMapper.delete(lambdaQuery);
- return flag > 0 ? true : false;
+ return this.baseMapper.delete(lambdaQuery) > 0;
}
-
- // 处理暴雨数据
private void handle(RainEventDTO eventdto) {
- // 抛出异常
if (eventdto == null) {
throw new ParmaException(BaseConstants.PARAMS_ERROR);
}
-
try {
RainEvent revent = new RainEvent();
BeanUtils.copyProperties(eventdto, revent);
- // 处理空间数据
GeometryFactory geometryFactory = new GeometryFactory();
Point point = geometryFactory.createPoint(new Coordinate(
eventdto.getLongitude(), eventdto.getLatitude()
));
revent.setGeom(point);
revent.getGeom().setSRID(4490);
- // 存库
save(revent);
- log.info("暴雨位基本信息已存库...");
+ log.info("暴雨基本信息已存库...");
} catch (Exception ex) {
log.error("暴雨触发:暴雨基本信息保存失败!", ex.getMessage());
- ex.printStackTrace();
throw new ServiceException(BaseConstants.RAIN_SERVER_ERROR);
}
-
-
}
-
}
diff --git a/src/main/java/com/gis/xian/utils/qgis/EarthquakeHandler.java b/src/main/java/com/gis/xian/utils/qgis/EarthquakeHandler.java
deleted file mode 100644
index 83b326c..0000000
--- a/src/main/java/com/gis/xian/utils/qgis/EarthquakeHandler.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package com.gis.xian.utils.qgis;
-
-import com.gis.xian.config.QgisProperties;
-import com.gis.xian.constant.BaseConstants;
-import com.gis.xian.enums.qgis.EarthquakeMapsEnums;
-import com.gis.xian.enums.qgis.RainMapsEnums;
-import com.gis.xian.utils.BaseUtils;
-
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-
-/**
- * @author zzw
- * @description: 地震烈度核心服务
- * @date 2026/5/26 上午10:47
- */
-public class EarthquakeHandler {
-
- /**
- * 获取不同烈度下的面积
- *
- * @param a 长轴
- * @param b 短轴
- * @return 返回椭圆的面积
- */
- public static double calculateArea(double a, double b) {
- return Math.PI * a * b;
- }
-
- /**
- * @param M 震级
- * @param Ia 烈度
- * @author: xiaodemos
- * @date: 2025/3/25 10:57
- * @description: 计算椭圆的长轴
- * @return: 返回长轴
- */
- public static double calculateRa(double M, double Ia) {
- return (Math.pow(10, (4.0293 + 1.3003 * M - Ia) / 3.6404) - 10) * 1000;
- }
-
- /**
- * @param M 震级
- * @param Ib 烈度
- * @author: xiaodemos
- * @date: 2025/3/25 10:58
- * @description: 计算椭圆的短轴
- * @return: 返回短轴
- */
- public static double calculateRb(double M, double Ib) {
- return (Math.pow(10, (2.3816 + 1.3003 * M - Ib) / 2.8573) - 5) * 1000;
- }
-
-
- // 格式化地震三要素信息
- public static String parseInfo(LocalDateTime eqTime, double magnitude, String addr) {
- String time = BaseUtils.formatTime(eqTime, true);
- return String.format("时间:%s\r\n震级:%s级\r\n位置:%s", time, magnitude, addr);
- }
-
- // 格式化暴雨三要素信息
- public static String parseRInfo(LocalDateTime eqTime, String magnitude, String addr) {
- String time = BaseUtils.formatTime(eqTime, true);
- return String.format("时间:%s\r\n累计降雨量:%s毫米\r\n已持续:%s小时", time, magnitude, addr);
- }
-
- // 拼接地震图件标题
- public static String combine(String eqName, String eqType, EarthquakeMapsEnums map) {
- // 地点 + 震级
- String name = eqName;
- // 图名称 + 地震类型
- String mapName = map.getName() + BaseConstants.EQ_TYPE.get(eqType);
- return String.format("%s", name + mapName);
- }
-
- // 拼接暴雨图件标题
- public static String combineR(String rainName, String rainType, RainMapsEnums map) {
- // 地点 + 暴雨名称
- String name = rainName;
- // 图名称 + 暴雨类型
- String mapName = map.getName() + BaseConstants.RAIN_TYPE.get(rainType);
- return String.format("%s", name + mapName);
- }
-
- // 拼接导出路径
-
- // 拼接导出路径
- public static String getPath(String event, String queueId, String size, EarthquakeMapsEnums map, QgisProperties qgisProperties) {
- // 地震事件 + 批次
- String batch = queueId.substring(event.length());
- String path = event + "/" + batch + "/" + size + "/" + map.getName();
- return String.format("%s", qgisProperties.getBasePath() + qgisProperties.getEqMapsOutputPath() + path + ".jpg");
- }
-
- // 拼接导出路径
- public static String getRPath(String rainId, String queueId, String size, RainMapsEnums map, QgisProperties qgisProperties) {
- // 地震事件 + 批次
- String batch = queueId.substring(rainId.length());
- String path = rainId + "/" + batch + "/" + size + "/" + map.getName();
- return String.format("%s", qgisProperties.getBasePath() + qgisProperties.getRainMapsOutputPath() + path + ".jpg");
- }
-
- public static String format(LocalDateTime time) {
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM月dd日HH时mm分");
- String timestamp = time.format(formatter);
- return timestamp;
- }
-
- public static String formatTime(LocalDateTime time) {
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分");
- String timestamp = time.format(formatter);
- return timestamp;
- }
-}
diff --git a/src/main/java/com/gis/xian/utils/qgis/EllipseToWktHandler.java b/src/main/java/com/gis/xian/utils/qgis/EllipseToWktHandler.java
deleted file mode 100644
index 0f4bef0..0000000
--- a/src/main/java/com/gis/xian/utils/qgis/EllipseToWktHandler.java
+++ /dev/null
@@ -1,156 +0,0 @@
-package com.gis.xian.utils.qgis;
-
-import com.gis.xian.dto.qgis.earthquake.EarthquakeIntensityQuery;
-import org.locationtech.jts.geom.Geometry;
-import org.locationtech.jts.geom.GeometryFactory;
-import org.locationtech.jts.geom.Polygon;
-import org.locationtech.jts.io.WKTReader;
-import org.locationtech.proj4j.*;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author zzw
- * @description: 椭圆烈度衰减圈转换为WKT格式
- * @date 2026/5/26 上午10:25
- */
-public class EllipseToWktHandler {
- // 投影转换工厂
- private static final CRSFactory crsFactory = new CRSFactory();
- private static final CoordinateTransformFactory ctFactory = new CoordinateTransformFactory();
- private static final GeometryFactory geometryFactory = new GeometryFactory();
-
- /**
- * 将椭圆参数转换为 POLYGON 格式的 WKT 字符串
- * @param query 椭圆烈度参数
- * @return POLYGON格式的WKT字符串
- */
- public static Polygon ellipseToPolygonWkt(EarthquakeIntensityQuery query) {
- try {
- // 确定UTM投影带并创建转换器
- int utmZone = (int) Math.floor((query.getCenterLon() + 180) / 6) + 1;
- String epsgCode = query.getCenterLat() >= 0 ? "EPSG:326" + utmZone : "EPSG:327" + utmZone;
-
- // 创建坐标参考系(WGS84 -> UTM)
- CoordinateReferenceSystem wgs84 = crsFactory.createFromName("EPSG:4326");
- CoordinateReferenceSystem utm = crsFactory.createFromName(epsgCode);
-
- // 创建转换器
- CoordinateTransform toUtmTransform = ctFactory.createTransform(wgs84, utm);
- CoordinateTransform toWgs84Transform = ctFactory.createTransform(utm, wgs84);
-
- // 将中心点经纬度转换为UTM坐标
- ProjCoordinate centerWgs84 = new ProjCoordinate(query.getCenterLon(), query.getCenterLat());
- ProjCoordinate centerUtm = new ProjCoordinate();
- toUtmTransform.transform(centerWgs84, centerUtm);
- double centerX = centerUtm.x;
- double centerY = centerUtm.y;
-
- // 生成椭圆的平面顶点(极坐标方式)
- double rotationRad = Math.toRadians(query.getRotation());
- List verticesUtm = new ArrayList<>();
-
- // 生成0到2π的角度序列
- double angleStep = 2 * Math.PI / query.getNumVertices();
- for (int i = 0; i < query.getNumVertices(); i++) {
- double theta = i * angleStep;
- // 椭圆极坐标方程
- double xEllipse = query.getSemiMajor() * Math.cos(theta);
- double yEllipse = query.getSemiMinor() * Math.sin(theta);
- // 旋转矩阵计算
- double xRot = xEllipse * Math.cos(rotationRad) - yEllipse * Math.sin(rotationRad);
- double yRot = xEllipse * Math.sin(rotationRad) + yEllipse * Math.cos(rotationRad);
- // 加上中心点坐标
- double xFinal = centerX + xRot;
- double yFinal = centerY + yRot;
-
- verticesUtm.add(new ProjCoordinate(xFinal, yFinal));
- }
-
- // 将UTM顶点转换回经纬度
- List verticesWgs84 = new ArrayList<>();
- for (ProjCoordinate utmCoord : verticesUtm) {
- ProjCoordinate wgs84Coord = new ProjCoordinate();
- toWgs84Transform.transform(utmCoord, wgs84Coord);
- verticesWgs84.add(wgs84Coord);
- }
-
- // 拼接WKT字符串(保留6位小数,闭合多边形)
- StringBuilder verticesStr = new StringBuilder();
- for (ProjCoordinate coord : verticesWgs84) {
- verticesStr.append(roundTo6Decimals(coord.x))
- .append(" ")
- .append(roundTo6Decimals(coord.y))
- .append(", ");
- }
-
- // 添加第一个点闭合多边形
- ProjCoordinate firstCoord = verticesWgs84.get(0);
- verticesStr.append(roundTo6Decimals(firstCoord.x))
- .append(" ")
- .append(roundTo6Decimals(firstCoord.y));
- // 构建最终WKT字符串
- String POLYGON = String.format("POLYGON ((%s)) | 4490", verticesStr);
- // 返回Polygon类型
- Polygon polygon = buildPolygonFromWKTString(POLYGON);
-
- return polygon;
- } catch (Exception e) {
- throw new RuntimeException("生成烈度多边形失败", e);
- }
- }
-
- /**
- * 解析WKT获取经纬度范围
- */
- public static void printLatLonRange(String wkt) {
- // 提取顶点坐标
- String coordsPart = wkt.replace("POLYGON ((", "").replace("))", "");
- String[] coordStrs = coordsPart.split(", ");
-
- double minLon = Double.MAX_VALUE;
- double maxLon = Double.MIN_VALUE;
- double minLat = Double.MAX_VALUE;
- double maxLat = Double.MIN_VALUE;
-
- for (String coordStr : coordStrs) {
- String[] lonLat = coordStr.split(" ");
- double lon = Double.parseDouble(lonLat[0]);
- double lat = Double.parseDouble(lonLat[1]);
-
- minLon = Math.min(minLon, lon);
- maxLon = Math.max(maxLon, lon);
- minLat = Math.min(minLat, lat);
- maxLat = Math.max(maxLat, lat);
- }
-
- System.out.println("\n椭圆的经纬度范围:");
- System.out.printf("经度范围:%.6f ~ %.6f%n", minLon, maxLon);
- System.out.printf("纬度范围:%.6f ~ %.6f%n", minLat, maxLat);
- }
-
- /**
- * 保留6位小数
- */
- private static double roundTo6Decimals(double value) {
- return new BigDecimal(value).setScale(6, RoundingMode.HALF_UP).doubleValue();
- }
-
- // 构建 Polygon 对象
- public static Polygon buildPolygonFromWKTString(String wktPolygon) {
- try {
- // WKT解析器
- WKTReader wktReader = new WKTReader(geometryFactory);
- // 解析 POLYGON 字符串
- Geometry geometry = wktReader.read(wktPolygon);
- return (Polygon) geometry;
- } catch (Exception e) {
- throw new RuntimeException("解析 POLYGON 字符串失败", e);
- }
- }
-
-
-}
diff --git a/src/main/java/com/gis/xian/utils/qgis/GeoDistanceHandler.java b/src/main/java/com/gis/xian/utils/qgis/GeoDistanceHandler.java
deleted file mode 100644
index 2a41a26..0000000
--- a/src/main/java/com/gis/xian/utils/qgis/GeoDistanceHandler.java
+++ /dev/null
@@ -1,219 +0,0 @@
-package com.gis.xian.utils.qgis;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.util.Assert;
-
-/**
- * @author zzw
- * @description: 地理距离计算工具类
- * @date 2026/5/26 上午9:41
- */
-@Slf4j
-public class GeoDistanceHandler {
-
- /**
- *地球平均半径(千米)
- */
- private static final double EARTH_RADIUS = 6371.0;
- /**
- * 计算两个经纬度点之间的球面距离(单位:千米)
- * @param lon1 点1经度
- * @param lat1 点1纬度
- * @param lon2 点2经度
- * @param lat2 点2纬度
- * @return 两点之间的距离(千米)
- */
- public static double calculateHaversineDistance(double lon1, double lat1, double lon2, double lat2) {
- // 参数校验(经纬度合理范围)
- Assert.isTrue(lon1 >= -180 && lon1 <= 180 && lat1 >= -90 && lat1 <= 90, "点1经纬度格式非法");
- Assert.isTrue(lon2 >= -180 && lon2 <= 180 && lat2 >= -90 && lat2 <= 90, "点2经纬度格式非法");
-
- // 转换为弧度(Math类三角函数默认使用弧度)
- double radLat1 = Math.toRadians(lat1);
- double radLon1 = Math.toRadians(lon1);
- double radLat2 = Math.toRadians(lat2);
- double radLon2 = Math.toRadians(lon2);
-
- // 计算纬度差、经度差
- double deltaLat = radLat1 - radLat2;
- double deltaLon = radLon1 - radLon2;
-
- // Haversine公式核心计算
- double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2)
- + Math.cos(radLat1) * Math.cos(radLat2)
- * Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);
- double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
-
- // 返回距离(千米)
- return EARTH_RADIUS * c;
- }
-
- /**
- * 计算震中点到断层的最短球面距离(单位:千米)
- * @param lon 震中经度
- * @param lat 震中纬度
- * @param lonA 线段端点A经度
- * @param latA 线段端点A纬度
- * @param lonB 线段端点B经度
- * @param latB 线段端点B纬度
- * @return 震中到线段的最短距离(千米)
- */
- public static double calculateDistanceFromPointToLineString(double lon, double lat, double lonA, double latA, double lonB, double latB) {
- // 将经纬度转换为平面直角坐标系近似值
- double x = lon;
- double y = lat;
- double xA = lonA;
- double yA = latA;
- double xB = lonB;
- double yB = latB;
-
- // 计算向量AB和向量AP
- double vectorABx = xB - xA;
- double vectorABy = yB - yA;
- double vectorAPx = x - xA;
- double vectorAPy = y - yA;
-
- // 计算点P在AB线段上的投影参数t(判断垂足是否在线段内)
- // t = (AP · AB) / |AB|²
- double dotProduct = vectorAPx * vectorABx + vectorAPy * vectorABy; // 点积
- double abLengthSquared = vectorABx * vectorABx + vectorABy * vectorABy; // AB长度的平方
-
- // 线段AB是一个点(A和B坐标重合),直接返回点到点的距离
- if (abLengthSquared < 1e-10) {
- return calculateHaversineDistance(lon, lat, lonA, latA);
- }
-
- // 确定垂足位置
- double t = Math.max(0, Math.min(1, dotProduct / abLengthSquared)); // t限制在[0,1]之间(线段范围内)
-
- // 计算垂足点C的坐标(平面坐标)
- double xC = xA + t * vectorABx;
- double yC = yA + t * vectorABy;
-
- // 计算震中点到垂足点C的球面距离(最终最短距离)
- return calculateHaversineDistance(lon, lat, xC, yC);
- }
-
- /**
- * 解析LINESTRING格式字符串,提取所有端点坐标
- * @param wktLineString LINESTRING格式的WKT字符串
- * @return 端点坐标二维数组([经度, 纬度])
- */
- public static double[][] parseLineStringCoordinates(String wktLineString) {
- // 先判空并去除首尾多余空格
- if (wktLineString == null || wktLineString.trim().isEmpty()) {
- throw new IllegalArgumentException("WKT字符串不能为空或空白");
- }
- String cleanWkt = wktLineString.trim();
-
- // 截取括号内的坐标字符串
- int startIndex = cleanWkt.indexOf("(") + 1; // 找到第一个左括号,取其后一位
- int endIndex = cleanWkt.lastIndexOf(")"); // 找到最后一个右括号
- String coordStr = cleanWkt.substring(startIndex, endIndex).trim();
-
- // 括号内无坐标数据
- if (coordStr.isEmpty()) {
- throw new IllegalArgumentException("LINESTRING内无有效坐标数据");
- }
-
- // 按逗号分割多个坐标点
- String[] pointStrArray = coordStr.split(",");
- double[][] coordinates = new double[pointStrArray.length][2];
-
- // 解析每个坐标点(经度 纬度)
- for (int i = 0; i < pointStrArray.length; i++) {
- String pointStr = pointStrArray[i].trim();
- // 容错:单个坐标点为空
- if (pointStr.isEmpty()) {
- throw new IllegalArgumentException("LINESTRING内存在空坐标点,索引:" + i);
- }
-
- String[] lonLat = pointStr.split("\\s+");
- if (lonLat.length != 2) {
- throw new IllegalArgumentException("LINESTRING内坐标格式无效:" + pointStr);
- }
-
- try {
- double lon = Double.parseDouble(lonLat[0]);
- double lat = Double.parseDouble(lonLat[1]);
- coordinates[i][0] = lon; // 经度
- coordinates[i][1] = lat; // 纬度
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("LINESTRING内坐标无法转换为数字:" + pointStr, e);
- }
- }
-
- return coordinates;
- }
-
- /**
- * 解析POINT格式WKT字符串,提取经纬度坐标
- * @param wktPoint POINT格式的WKT字符串
- * @return 坐标数组 [经度, 纬度]
- */
- public static double[] parsePointCoordinates(String wktPoint) {
- // 判空和去除首尾空格
- if (wktPoint == null || wktPoint.trim().isEmpty()) {
- throw new IllegalArgumentException("POINT类型WKT字符串不能为空或空白");
- }
- String cleanWkt = wktPoint.trim();
-
- // 校验POINT格式前缀和后缀
- boolean isValidPrefix = cleanWkt.startsWith("POINT(") || cleanWkt.startsWith("POINT (");
- boolean isValidSuffix = cleanWkt.endsWith(")");
- if (!isValidPrefix || !isValidSuffix) {
- throw new IllegalArgumentException("无效的POINT格式WKT字符串:" + wktPoint);
- }
-
- // 截取括号内的坐标字符串
- int startIndex = cleanWkt.indexOf("(") + 1;
- int endIndex = cleanWkt.lastIndexOf(")");
- String coordStr = cleanWkt.substring(startIndex, endIndex).trim();
-
- // 校验括号内是否有有效坐标
- if (coordStr.isEmpty()) {
- throw new IllegalArgumentException("POINT内无有效坐标数据:" + wktPoint);
- }
-
- // 分割经度和纬度(支持任意数量空格分隔)
- String[] lonLat = coordStr.split("\\s+");
- if (lonLat.length != 2) {
- throw new IllegalArgumentException("POINT坐标格式无效,需为 经度 纬度 格式:" + coordStr);
- }
-
- // 转换为数字并返回
- try {
- double lon = Double.parseDouble(lonLat[0]);
- double lat = Double.parseDouble(lonLat[1]);
- // 校验经纬度范围
- Assert.isTrue(lon >= -180 && lon <= 180, "经度超出合法范围[-180,180]:" + lon);
- Assert.isTrue(lat >= -90 && lat <= 90, "纬度超出合法范围[-90,90]:" + lat);
- return new double[]{lon, lat};
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("POINT坐标无法转换为数字:" + coordStr, e);
- }
- }
-
- /**
- * 计算震中点到行政区划点(POINT类型)的球面距离(单位:千米)
- * @param epicenterLon 震中经度
- * @param epicenterLat 震中纬度
- * @param regionWktPoint 行政区划点的POINT格式WKT字符串
- * @return 震中到该行政区划点的距离(千米)
- */
- public static double calculateDistanceFromEpicenterToRegionPoint(double epicenterLon, double epicenterLat, String regionWktPoint) {
- try {
- // 行政区划点经纬度
- double[] regionCoord = parsePointCoordinates(regionWktPoint);
- double regionLon = regionCoord[0];
- double regionLat = regionCoord[1];
-
- // 球面距离公式计算距离
- return calculateHaversineDistance(epicenterLon, epicenterLat, regionLon, regionLat);
- } catch (Exception e) {
- log.error("计算震中到行政区划点距离失败,WKT字符串:{},异常信息:{}", regionWktPoint, e.getMessage(), e);
- throw new RuntimeException("计算行政区划点距离失败", e);
- }
- }
-
-}
diff --git a/src/main/java/com/gis/xian/utils/qgis/GeoFilesHandler.java b/src/main/java/com/gis/xian/utils/qgis/GeoFilesHandler.java
deleted file mode 100644
index 984d9e9..0000000
--- a/src/main/java/com/gis/xian/utils/qgis/GeoFilesHandler.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package com.gis.xian.utils.qgis;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.gis.xian.config.QgisProperties;
-import com.gis.xian.dto.qgis.earthquake.EarthquakeInformationInfluenceDTO;
-import com.gis.xian.dto.qgis.earthquake.EarthquakeInfluenceGeoJsonDTO;
-import org.locationtech.jts.geom.CoordinateSequence;
-import org.locationtech.jts.geom.GeometryFactory;
-import org.locationtech.jts.geom.LinearRing;
-import org.locationtech.jts.geom.Polygon;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author zzw
- * @description: 处理空间数据文件形式
- * @date 2026/5/26 上午10:41
- */
-public class GeoFilesHandler {
-
- private static final GeometryFactory GEOMETRY_FACTORY = new GeometryFactory();
- // Deleted:private static final WKTReader WKT_READER = new WKTReader(GEOMETRY_FACTORY);
- private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
- public static void writeGeoJsonToFile(EarthquakeInfluenceGeoJsonDTO featureCollection, String fileName, QgisProperties qgisProperties) throws IOException {
- // 序列化
- String geoJsonStr = OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(featureCollection);
- // geojson文件路径
- String path = qgisProperties.getBasePath() + qgisProperties.getIntensityGeojsonPath() + fileName + ".geojson";
- // 创建文件目录
- File file = new File(path);
- File parentDir = file.getParentFile();
- if (parentDir != null && !parentDir.exists()) {
- boolean mkdirs = parentDir.mkdirs();
- if (!mkdirs) {
- throw new IOException("创建GeoJson文件目录失败!" + parentDir.getAbsolutePath());
- }
- }
-
- // 写入文件
- try (BufferedWriter writer = Files.newBufferedWriter(file.toPath(), StandardCharsets.UTF_8)) {
- writer.write(geoJsonStr);
- }
- }
-
- // 将JTS转换为GeoJSON坐标
- private static List> convertCoordinateSequenceToGeoJson(CoordinateSequence cs) {
- List> coordinates = new ArrayList<>();
- for (int i = 0; i < cs.size(); i++) {
- double lon = cs.getX(i); // 经度
- double lat = cs.getY(i); // 纬度
- List point = new ArrayList<>();
- point.add(lon);
- point.add(lat);
- coordinates.add(point);
- }
- return coordinates;
- }
-
- // 将JTS Polygon转换为GeoJSON Feature对象
- public static EarthquakeInfluenceGeoJsonDTO.GeoJsonFeature convertPolygonToGeoJsonFeature(Polygon polygon, EarthquakeInformationInfluenceDTO dzxx) {
- EarthquakeInfluenceGeoJsonDTO.GeoJsonFeature feature = new EarthquakeInfluenceGeoJsonDTO.GeoJsonFeature();
- EarthquakeInfluenceGeoJsonDTO.GeoJsonFeature.GeoJsonGeometry geometry = new EarthquakeInfluenceGeoJsonDTO.GeoJsonFeature.GeoJsonGeometry();
-
- // 设置几何类型
- geometry.setType("Polygon");
-
- // 转换JTS坐标为GeoJSON坐标格式
- List>> coordinates = new ArrayList<>();
- LinearRing exteriorRing = polygon.getExteriorRing();
- List> exteriorCoordinates = convertCoordinateSequenceToGeoJson(exteriorRing.getCoordinateSequence());
- coordinates.add(exteriorCoordinates);
-
- // 处理内部环
- for (int i = 0; i < polygon.getNumInteriorRing(); i++) {
- LinearRing interiorRing = polygon.getInteriorRingN(i);
- coordinates.add(convertCoordinateSequenceToGeoJson(interiorRing.getCoordinateSequence()));
- }
-
- geometry.setCoordinates(coordinates);
- feature.setGeometry(geometry);
-
- // 烈度等级
- feature.getProperties().setEqAddr(dzxx.getEqName());
- feature.getProperties().setLatitude(dzxx.getLatitude());
- feature.getProperties().setLongitude(dzxx.getLongitude());
- feature.getProperties().setDescription("");
- feature.getProperties().setIntensity("烈度:" + dzxx.getSInty() + "度");
- return feature;
- }
-
-}
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
index dff3a40..f229c96 100644
--- a/src/main/resources/application-dev.yml
+++ b/src/main/resources/application-dev.yml
@@ -19,35 +19,6 @@ spring:
password: zhangsan
database: 0
connect-timeout: 3000ms
- # rabbitmq 配置
- rabbitmq:
- host: localhost
- port: 5672
- username: zzw
- password: zzw0401
-# host: 47.92.216.173
-# port: 4018
- # username: xiaodemo
- # password: 1234
-# username: gis
-# password: gis502
- #虚拟host 可以不设置,使用server默认host
- # virtual-host: /xiaodemos
- #消息确认配置项
- publisher-returns: true #确认消息已发送到队列(Queue)
- publisher-confirm-type: correlated
- listener: # 手动确认消息配置
- simple:
- acknowledge-mode: manual # 全局开启消费者手动确认
- # 优化配置
- concurrency: 1 # 最小消费者数
- max-concurrency: 5 # 最大消费者数
- prefetch: 1 # 每次从队列取1条消息,处理完再取(避免消息堆积)
- retry:
- enabled: true # 开启消费者重试(建议结合业务幂等性使用)
- max-attempts: 3 # 最大重试次数
- initial-interval: 10000ms # 第一次重试间隔
- multiplier: 2 # 重试间隔倍数(第二次2s,第三次4s)
# 日志配置
logging:
level:
diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml
index 71c2af4..f1b296e 100644
--- a/src/main/resources/application-prod.yml
+++ b/src/main/resources/application-prod.yml
@@ -18,31 +18,6 @@ spring:
password: XAYJ@gis2603
database: 0
connect-timeout: 3000ms
- # rabbitmq 配置
- rabbitmq:
- host: localhost
- port: 5672
- # username: xiaodemo
- # password: 1234
- username: zzw
- password: zzw0401
- #虚拟host 可以不设置,使用server默认host
- # virtual-host: /xiaodemos
- #消息确认配置项
- publisher-returns: true #确认消息已发送到队列(Queue)
- publisher-confirm-type: correlated
- listener: # 手动确认消息配置
- simple:
- acknowledge-mode: manual # 全局开启消费者手动确认
- # 优化配置
- concurrency: 1 # 最小消费者数
- max-concurrency: 5 # 最大消费者数
- prefetch: 1 # 每次从队列取1条消息,处理完再取(避免消息堆积)
- retry:
- enabled: true # 开启消费者重试(建议结合业务幂等性使用)
- max-attempts: 3 # 最大重试次数
- initial-interval: 1000ms # 第一次重试间隔
- multiplier: 2 # 重试间隔倍数(第二次2s,第三次4s)
# 日志配置
logging: