|
@@ -2,29 +2,29 @@ package com.fdkankan.indoor.core.service.impl;
|
|
|
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.io.FileUtil;
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.fdkankan.indoor.base.constant.CmdConstant;
|
|
|
+import com.fdkankan.indoor.base.constant.ConfigConstant;
|
|
|
import com.fdkankan.indoor.base.constant.MsgCode;
|
|
|
+import com.fdkankan.indoor.base.convert.GisCoordinateUtil;
|
|
|
import com.fdkankan.indoor.base.convert.ImageClipUtil;
|
|
|
import com.fdkankan.indoor.base.exception.BaseRuntimeException;
|
|
|
import com.fdkankan.indoor.base.util.AliYunOssUtil;
|
|
|
import com.fdkankan.indoor.base.util.CmdUtils;
|
|
|
import com.fdkankan.indoor.base.util.MyFileUtils;
|
|
|
import com.fdkankan.indoor.base.util.Result;
|
|
|
-import com.fdkankan.indoor.core.entity.CutModelEntity;
|
|
|
-import com.fdkankan.indoor.core.entity.InitEntity;
|
|
|
-import com.fdkankan.indoor.core.entity.MapEntity;
|
|
|
+import com.fdkankan.indoor.core.entity.*;
|
|
|
import com.fdkankan.indoor.core.entity.dto.CropDto;
|
|
|
import com.fdkankan.indoor.core.entity.dto.CutModelDto;
|
|
|
import com.fdkankan.indoor.core.entity.dto.MapDto;
|
|
|
import com.fdkankan.indoor.core.entity.dto.PoiTypeDto;
|
|
|
+import com.fdkankan.indoor.core.entity.po.DataSetPo;
|
|
|
import com.fdkankan.indoor.core.entity.po.MapPo;
|
|
|
import com.fdkankan.indoor.core.mapper.CutModelMapper;
|
|
|
import com.fdkankan.indoor.core.mapper.InitMapper;
|
|
|
import com.fdkankan.indoor.core.mapper.MapMapper;
|
|
|
-import com.fdkankan.indoor.core.service.CutModelService;
|
|
|
-import com.fdkankan.indoor.core.service.InitService;
|
|
|
-import com.fdkankan.indoor.core.service.MapService;
|
|
|
+import com.fdkankan.indoor.core.service.*;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
@@ -52,6 +52,17 @@ public class CutModelServiceImpl extends IBaseServiceImpl implements CutModelSer
|
|
|
@Autowired
|
|
|
AliYunOssUtil aliYunOssUtil;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ MergeInfoService mergeInfoService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ DataSetService dataSetService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ ControlPointCalculateService controlPointCalculateService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ ConfigConstant configConstant;
|
|
|
|
|
|
|
|
|
|
|
@@ -252,14 +263,140 @@ public class CutModelServiceImpl extends IBaseServiceImpl implements CutModelSer
|
|
|
* 2021-9-23
|
|
|
* 多点云剪裁
|
|
|
* @param sceneCode
|
|
|
- * @param param
|
|
|
* @return
|
|
|
*/
|
|
|
@Override
|
|
|
- public Result multipleCrop(String sceneCode, CropDto param) {
|
|
|
- // 1. 合并场景表(t_merge_info)获取dataSetId, 场景码
|
|
|
- // 2. 根据dataSetId 将dataSet表location(需要转本地坐标), orientation, path, 封装到merge_cut_model.json
|
|
|
- return null;
|
|
|
+ public Result multipleCrop(String sceneCode) {
|
|
|
+
|
|
|
+
|
|
|
+ // 1. 根据dataSetId 将dataSet表location(需要转本地坐标), orientation, path, 封装到merge_cut_model.json
|
|
|
+ List<DataSetPo> dataSetInfos = dataSetService.getDataBySceneCode(sceneCode);
|
|
|
+
|
|
|
+
|
|
|
+ // 转坐标,获取控制点计算值
|
|
|
+ ControlPointCalculateEntity pointCalculate = controlPointCalculateService.findById(sceneCode);
|
|
|
+
|
|
|
+ HashMap<Object, double[] > covertPoint = new HashMap<>();
|
|
|
+ for (DataSetPo po : dataSetInfos) {
|
|
|
+ Double[] location = po.getLocation();
|
|
|
+ // gis坐标转本地坐标
|
|
|
+ double[] doubles = GisCoordinateUtil.transformBLToLocation(location[0], location[1], pointCalculate);
|
|
|
+
|
|
|
+ Double orientation = po.getOrientation();
|
|
|
+
|
|
|
+ // 将本地坐标, 旋转角度按顺序封装起来
|
|
|
+ double[] resParam = {doubles[0], doubles[1], location[2], orientation};
|
|
|
+ Integer id = po.getId();
|
|
|
+
|
|
|
+ // dataSetId做为key
|
|
|
+ covertPoint.put(id, resParam);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 2. 合并场景表(t_merge_info)获取dataSetId, 场景码
|
|
|
+ List<MergeInfoEntity> mergeInfo = mergeInfoService.findBySceneCode(sceneCode);
|
|
|
+
|
|
|
+ int SizeDataSet = dataSetInfos.size();
|
|
|
+ int SizeMergeDataSet = mergeInfo.size();
|
|
|
+ log.info("数据集数量:{}, 合并数据集数量: {}", SizeDataSet, SizeMergeDataSet);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ JSONArray models = new JSONArray();
|
|
|
+ for (MergeInfoEntity info : mergeInfo) {
|
|
|
+ // 获取本地坐标,旋转角度
|
|
|
+ Integer dataSetId = info.getDataSetId();
|
|
|
+ double[] point = covertPoint.get(dataSetId);
|
|
|
+
|
|
|
+ JSONObject cutJson = new JSONObject();
|
|
|
+ cutJson.put("file", info.getPath() + "/laser.las");
|
|
|
+ cutJson.put("sceneCode", info.getMergeCode());
|
|
|
+ cutJson.put("dataSetId", dataSetId);
|
|
|
+ // 算法要求用空格隔开
|
|
|
+ cutJson.put("translation", point[0] + " " + point[1] + " " + point[2]);
|
|
|
+ cutJson.put("rotation", point[3]);
|
|
|
+ models.add(cutJson);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 修剪模型参数
|
|
|
+ JSONObject mergeCut = new JSONObject();
|
|
|
+ mergeCut.put("model", models);
|
|
|
+ // 这个值目前写死
|
|
|
+ mergeCut.put("aabb", "b-0.5 -0.5 -0.5 0.5 0.5 0.5");
|
|
|
+
|
|
|
+ // json写入服务器
|
|
|
+ String basePath = redisPath(sceneCode);
|
|
|
+ if ("dev".equals(configConstant.active)){
|
|
|
+ basePath = configConstant.serverBasePath + "/" + sceneCode + "/results/laserData";
|
|
|
+ }
|
|
|
+ String savePath = basePath + "/merge_cut_param.json";
|
|
|
+ log.info("剪切参数:{}", savePath);
|
|
|
+ FileUtil.writeUtf8String(mergeCut.toJSONString(), savePath);
|
|
|
+ log.info("剪切参数json写入完成");
|
|
|
+
|
|
|
+ // 剪切并上传模型
|
|
|
+ String ossUrl = cutLas(basePath, sceneCode);
|
|
|
+
|
|
|
+ // 数据更新到数据库
|
|
|
+ saveLasInfo(sceneCode, ossUrl);
|
|
|
+
|
|
|
+ JSONObject result = new JSONObject();
|
|
|
+ // 返回值id, 默认1
|
|
|
+ result.put("job_id", 1);
|
|
|
+ return Result.success(result);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 模型剪切信息保存数据库
|
|
|
+ */
|
|
|
+ private void saveLasInfo(String sceneCode, String ossUrl){
|
|
|
+ // 保存数据到数据库
|
|
|
+ CutModelEntity cutEntity = this.findById(sceneCode);
|
|
|
+ if (cutEntity == null) {
|
|
|
+ cutEntity = new CutModelEntity();
|
|
|
+ cutEntity.setId(sceneCode);
|
|
|
+ cutEntity.setCreateTime(LocalDateTime.now());
|
|
|
+ cutEntity.setData(initCutModelDto(ossUrl, null));
|
|
|
+ } else {
|
|
|
+ // 更新las数据
|
|
|
+ cutEntity.setData(initCutModelDto(ossUrl, null));
|
|
|
+ cutEntity.setUpdateTime(LocalDateTime.now());
|
|
|
+ }
|
|
|
+ entityMapper.save(cutEntity);
|
|
|
+ log.info("模型剪切信息保存完成");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 2021-9-23
|
|
|
+ * 剪切模型 , 并上传oss
|
|
|
+ * String ossPath = "data/" +sceneCode + "/data/chunk1/cut/" + time + ".las";
|
|
|
+ * String ossPath = "data/" +sceneCode + "/data/cut/download.las"?time;
|
|
|
+ * @param basePath
|
|
|
+ */
|
|
|
+ //
|
|
|
+ private String cutLas(String basePath, String sceneCode){
|
|
|
+ // 调用命令切模型
|
|
|
+ String cmd = CmdConstant.MERGE_CUT_MODEL;
|
|
|
+ String inPath = basePath + "/merge_cut_param.json";
|
|
|
+
|
|
|
+ String outPath = basePath + "/merge_cut.las";
|
|
|
+
|
|
|
+ cmd = cmd.replace("@inPath", inPath);
|
|
|
+ cmd = cmd.replace("@outPath", outPath);
|
|
|
+
|
|
|
+ CmdUtils.callLineSh(cmd);
|
|
|
+ log.info("剪切模型完成: {}", outPath);
|
|
|
+
|
|
|
+ // 将剪裁后的las上传oss
|
|
|
+ String ossPath = "data/" +sceneCode + "/data/cut/download.las";
|
|
|
+ aliYunOssUtil.upload(outPath, ossPath);
|
|
|
+
|
|
|
+ String ossUrl = configConstant.ossDomain + ossPath + "?" + System.currentTimeMillis();
|
|
|
+ log.info("剪切模型上传oss完成: {}", ossUrl);
|
|
|
+
|
|
|
+ return ossUrl;
|
|
|
}
|
|
|
|
|
|
private List<CutModelDto> getDataBySceneCode(String sceneCode){
|