Browse Source

feat: 易达分析接口新增无人机图片位姿XMP信息

master
yinhuaiwei 2 months ago
parent
commit
3d680663dd
4 changed files with 201 additions and 100 deletions
  1. +6
    -1
      inspect-main/inspect-main-task/pom.xml
  2. +1
    -0
      inspect-main/inspect-main-task/src/main/java/com/inspect/partrolresult/domain/AnalyseReqItem.java
  3. +140
    -99
      inspect-main/inspect-main-task/src/main/java/com/inspect/partrolresult/service/AnalyseRequestServiceImpl.java
  4. +54
    -0
      inspect-main/inspect-main-task/src/main/java/com/inspect/partrolresult/util/XmpUtil.java

+ 6
- 1
inspect-main/inspect-main-task/pom.xml View File

@ -73,6 +73,11 @@
<artifactId>redisson</artifactId> <artifactId>redisson</artifactId>
<version>3.23.5</version> <version>3.23.5</version>
</dependency> </dependency>
<!-- 解析图片XMP -->
<dependency>
<groupId>com.drewnoakes</groupId>
<artifactId>metadata-extractor</artifactId>
<version>2.18.0</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

+ 1
- 0
inspect-main/inspect-main-task/src/main/java/com/inspect/partrolresult/domain/AnalyseReqItem.java View File

@ -16,6 +16,7 @@ public class AnalyseReqItem implements Serializable {
private String imageNormalUrlPath; private String imageNormalUrlPath;
private String[] typeList; private String[] typeList;
private String[] imageUrlList; private String[] imageUrlList;
private String[] dronePoseList;
public AnalyseReqItem clone() { public AnalyseReqItem clone() {
return JSONObject.parseObject(JSONObject.toJSONString(this), AnalyseReqItem.class); return JSONObject.parseObject(JSONObject.toJSONString(this), AnalyseReqItem.class);


+ 140
- 99
inspect-main/inspect-main-task/src/main/java/com/inspect/partrolresult/service/AnalyseRequestServiceImpl.java View File

@ -3,51 +3,136 @@ package com.inspect.partrolresult.service;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.util.StringUtil; import com.github.pagehelper.util.StringUtil;
import com.inspect.analysis.constant.AnalyseConstants; import com.inspect.analysis.constant.AnalyseConstants;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import com.inspect.analysis.domain.AnalyseLog; import com.inspect.analysis.domain.AnalyseLog;
import com.inspect.analysis.service.IAnalyseLogService; import com.inspect.analysis.service.IAnalyseLogService;
import com.inspect.base.core.constant.AlgConstants; import com.inspect.base.core.constant.AlgConstants;
import com.inspect.base.core.constant.RedisConst; import com.inspect.base.core.constant.RedisConst;
import com.inspect.base.core.sftp.SftpClient;
import com.inspect.base.core.utils.DateUtils; import com.inspect.base.core.utils.DateUtils;
import com.inspect.base.core.utils.HttpClientUtils; import com.inspect.base.core.utils.HttpClientUtils;
import com.inspect.base.core.utils.StringUtils; import com.inspect.base.core.utils.StringUtils;
import com.inspect.base.redis.service.RedisService; import com.inspect.base.redis.service.RedisService;
import com.inspect.partrolresult.domain.AnalyseReqItem; import com.inspect.partrolresult.domain.AnalyseReqItem;
import com.inspect.partrolresult.domain.AnalyseRequest; import com.inspect.partrolresult.domain.AnalyseRequest;
import com.inspect.partrolresult.util.XmpUtil;
import com.inspect.task.service.IPatrolTaskService; import com.inspect.task.service.IPatrolTaskService;
import com.inspect.taskstatus.domain.PatrolTaskStatus;
import com.inspect.taskstatus.service.IPatrolTaskStatusService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
@Slf4j @Slf4j
@Component @Component
public class AnalyseRequestServiceImpl implements IAnalyseRequestService { public class AnalyseRequestServiceImpl implements IAnalyseRequestService {
private static final Set<String> INFRARED_TYPES = new HashSet<>(Arrays.asList(
AlgConstants.INFRA_1800,
AlgConstants.INFRA_YU3,
AlgConstants.INFRA_CAMERA,
AlgConstants.INFRA_CAMERA_REVERSE
));
private static final Set<String> INFRARED_TYPES_2 = new HashSet<>(Arrays.asList(
AlgConstants.INFRA_CAMERA_REVERSE
));
private static final Set<String> OLD_INFRARED_TYPES = new HashSet<>(Arrays.asList(
"infrared"
));
private static final Set<String> METER_TYPES = new HashSet<>(Arrays.asList(
AlgConstants.METER
));
@Resource @Resource
private RedisService redisService; private RedisService redisService;
@Value("${task.test-mode:false}") @Value("${task.test-mode:false}")
private boolean testMode; private boolean testMode;
@Value("${server.port}") @Value("${server.port}")
private String port; private String port;
@Value("${task.drone-xmp:false}")
private boolean droneXmpEnabled;
@Resource @Resource
private IPatrolTaskService patrolTaskService; private IPatrolTaskService patrolTaskService;
@Resource @Resource
private AnalyseRequestRetryableDelegate retryDelegate; private AnalyseRequestRetryableDelegate retryDelegate;
@Resource @Resource
private DelayQueueService<String> delayQueueService; private DelayQueueService<String> delayQueueService;
@Resource @Resource
private IAnalyseLogService analysisLogService; private IAnalyseLogService analysisLogService;
@Resource
private IPatrolTaskStatusService patrolTaskStatusService;
@Resource
private SftpClient sftpClient;
public static boolean checkInfraredType(String[] typeList) {
if (typeList == null) {
return false;
}
for (String type : typeList) {
if (INFRARED_TYPES.contains(type)) {
return true;
}
}
return false;
}
public static boolean checkInfraredType2(String[] typeList) {
if (typeList == null) {
return false;
}
for (String type : typeList) {
if (INFRARED_TYPES_2.contains(type)) {
return true;
}
}
return false;
}
public static boolean checkOldInfraredType(String[] typeList) {
if (typeList == null) {
return false;
}
for (String type : typeList) {
if (OLD_INFRARED_TYPES.contains(type)) {
return true;
}
}
return false;
}
public static boolean checkMeterType(String[] typeList) {
if (typeList == null) {
return false;
}
for (String type : typeList) {
if (METER_TYPES.contains(type)) {
return true;
}
}
return false;
}
public static void main(String[] args) {
try {
ObjectMapper mapper = new ObjectMapper();
AnalyseRequest r1 = new AnalyseRequest();
r1.setRequestId("3177fe1c5d6f44f7bc527d5de8451ab9");
String json = mapper.writeValueAsString(r1);
AnalyseRequest r2 = mapper.readValue(json, AnalyseRequest.class);
boolean res = r1.equals(r2);
System.out.println(res); // 应为 true
boolean res2 = r1.hashCode() == r2.hashCode();
System.out.println(res2); // 应为 true
} catch (Exception e) {
e.printStackTrace();
}
}
//qinyl //qinyl
public void sendRequest(AnalyseRequest analyseReq, String[] typeList, boolean isFilter) throws IOException { public void sendRequest(AnalyseRequest analyseReq, String[] typeList, boolean isFilter) throws IOException {
@ -148,6 +233,11 @@ public class AnalyseRequestServiceImpl implements IAnalyseRequestService {
delayQueueService.submitRequest(AnalyseConstants.ALGORITHM_REQUEST_DELAY_QUEUE, analyseReq.getRequestId(), requestTimeout, TimeUnit.DAYS); delayQueueService.submitRequest(AnalyseConstants.ALGORITHM_REQUEST_DELAY_QUEUE, analyseReq.getRequestId(), requestTimeout, TimeUnit.DAYS);
} }
// 读取无机人图片XMP位姿信息
if (droneXmpEnabled) {
readDroneImageXmpInfo(analyseReq);
}
if (retryDelegate.callRemoteAnalyseService(analyseReq)) { if (retryDelegate.callRemoteAnalyseService(analyseReq)) {
log.info("CALL_REMOTE_ANALYSE SUCCESS, taskPatrolId: {}, requestId: {}", log.info("CALL_REMOTE_ANALYSE SUCCESS, taskPatrolId: {}, requestId: {}",
analyseReq.getTaskPatrolId(), analyseReq.getTaskPatrolId(),
@ -181,108 +271,59 @@ public class AnalyseRequestServiceImpl implements IAnalyseRequestService {
} }
} }
public void sendCompensateRequest(AnalyseRequest request) {
final String defaultUrl = "http://localhost:" + this.port + AnalyseConstants.ANALYSE_RET_URI;
String[] typeList = request.getTypeList();
if(typeList == null || typeList.length == 0) {
log.info("SEND_COMPENSATE_REQUEST typeList empty: {}", request);
public void readDroneImageXmpInfo(AnalyseRequest analyseReq) {
String taskPatrolId = analyseReq.getTaskPatrolId();
PatrolTaskStatus taskStatus = patrolTaskStatusService.selectPatrolTaskStatusByTaskPatrolledId(taskPatrolId);
if (taskStatus == null || !"2".equals(taskStatus.getPosType())) {
return; return;
} }
log.info("XMP reader, taskPatrolId:{}", taskPatrolId);
boolean containsInfrared = Arrays.asList(typeList).contains("infrared");
log.info("SEND_COMPENSATE_REQUEST containsInfrared: {}, request: {}", containsInfrared, request);
if(containsInfrared) {
HttpClientUtils.sendPostAgain(defaultUrl, request.toInfraredResultStr());
} else {
HttpClientUtils.sendPostAgain(defaultUrl, request.toErrorResultStr());
}
}
private static final Set<String> INFRARED_TYPES = new HashSet<>(Arrays.asList(
AlgConstants.INFRA_1800,
AlgConstants.INFRA_YU3,
AlgConstants.INFRA_CAMERA,
AlgConstants.INFRA_CAMERA_REVERSE
));
private static final Set<String> INFRARED_TYPES_2 = new HashSet<>(Arrays.asList(
AlgConstants.INFRA_CAMERA_REVERSE
));
private static final Set<String> OLD_INFRARED_TYPES = new HashSet<>(Arrays.asList(
"infrared"
));
private static final Set<String> METER_TYPES = new HashSet<>(Arrays.asList(
AlgConstants.METER
));
public static boolean checkInfraredType(String[] typeList) {
if (typeList == null) {
return false;
}
for (String type : typeList) {
if (INFRARED_TYPES.contains(type)) {
return true;
}
List<AnalyseReqItem> imgUrlList = analyseReq.getObjectList();
if (imgUrlList == null) {
return;
} }
return false;
}
public static boolean checkInfraredType2(String[] typeList) {
if (typeList == null) {
return false;
}
for (String type : typeList) {
if (INFRARED_TYPES_2.contains(type)) {
return true;
for (AnalyseReqItem item : imgUrlList) {
if (item == null || item.getImageUrlList() == null) {
continue;
} }
}
return false;
}
public static boolean checkOldInfraredType(String[] typeList) {
if (typeList == null) {
return false;
}
for (String type : typeList) {
if (OLD_INFRARED_TYPES.contains(type)) {
return true;
String[] imageUrlList = item.getImageUrlList();
String[] droneDataList = new String[imageUrlList.length];
for (int i = 0; i < imageUrlList.length; i++) {
try {
String imageUrl = imageUrlList[i];
int finalI = i;
sftpClient.downLoad(imageUrl, (inputStream -> {
log.info("XMP imageUrl:{}", imageUrl);
String droneDataStr = XmpUtil.parseDrone(inputStream);
droneDataList[finalI] = droneDataStr;
}));
} catch (Exception e) {
log.error("读取XMP失败", e.getMessage());
}
} }
item.setDronePoseList(droneDataList);
} }
return false;
} }
public static boolean checkMeterType(String[] typeList) {
if (typeList == null) {
return false;
}
for (String type : typeList) {
if (METER_TYPES.contains(type)) {
return true;
}
public void sendCompensateRequest(AnalyseRequest request) {
final String defaultUrl = "http://localhost:" + this.port + AnalyseConstants.ANALYSE_RET_URI;
String[] typeList = request.getTypeList();
if (typeList == null || typeList.length == 0) {
log.info("SEND_COMPENSATE_REQUEST typeList empty: {}", request);
return;
} }
return false;
}
public static void main(String[] args) {
try {
ObjectMapper mapper = new ObjectMapper();
AnalyseRequest r1 = new AnalyseRequest();
r1.setRequestId("3177fe1c5d6f44f7bc527d5de8451ab9");
String json = mapper.writeValueAsString(r1);
AnalyseRequest r2 = mapper.readValue(json, AnalyseRequest.class);
boolean res = r1.equals(r2);
System.out.println(res); // 应为 true
boolean res2 = r1.hashCode() == r2.hashCode();
System.out.println(res2); // 应为 true
} catch (Exception e) {
e.printStackTrace();
boolean containsInfrared = Arrays.asList(typeList).contains("infrared");
log.info("SEND_COMPENSATE_REQUEST containsInfrared: {}, request: {}", containsInfrared, request);
if (containsInfrared) {
HttpClientUtils.sendPostAgain(defaultUrl, request.toInfraredResultStr());
} else {
HttpClientUtils.sendPostAgain(defaultUrl, request.toErrorResultStr());
} }
} }
} }

+ 54
- 0
inspect-main/inspect-main-task/src/main/java/com/inspect/partrolresult/util/XmpUtil.java View File

@ -0,0 +1,54 @@
package com.inspect.partrolresult.util;
import com.alibaba.fastjson.JSON;
import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Metadata;
import com.drew.metadata.xmp.XmpDirectory;
import lombok.extern.slf4j.Slf4j;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
/**
* 解析图片的XMP信息
*/
@Slf4j
public class XmpUtil {
private static final String DJI_XMP_FLAG = "drone-dji:";
private static final String[] DJI_XMP_TAGS = {
"AbsoluteAltitude", "RelativeAltitude", "GpsLongitude", "GpsLatitude",
"GimbalPitchDegree", "GimbalRollDegree", "GimbalYawDegree",
"FlightPitchDegree", "FlightRollDegree", "FlightYawDegree"
};
/**
* 解析无人机图片的XMP信息
* @return 位姿信息JSON字符串
*/
public static String parseDrone(InputStream inputStream) {
try {
Metadata metadata = ImageMetadataReader.readMetadata(inputStream);
Map<String, String> xmpMap = new HashMap<>();
for (XmpDirectory xmpDir : metadata.getDirectoriesOfType(XmpDirectory.class)) {
Map<String, String> props = xmpDir.getXmpProperties();
getDjiTags(xmpMap, props);
}
String jsonStr = JSON.toJSONString(xmpMap);
log.info("Drone XMP info: {}", jsonStr);
return jsonStr;
} catch (Exception e) {
log.error("getXmpInfo error: {}", e.getMessage());
}
return "";
}
private static void getDjiTags(Map<String, String> xmpMap, Map<String, String> props) {
for (String tag : DJI_XMP_TAGS) {
String val = props.get(DJI_XMP_FLAG + tag);
if (val != null) {
xmpMap.put(tag, val);
}
}
}
}

Loading…
Cancel
Save