package com.xiaopeng.map.service.serviceimpl; import com.xiaopeng.map.config.VinSaltProperties; import com.xiaopeng.map.service.AdcOssHandleService; import com.xiaopeng.map.service.RobotaxiOssService; import com.xiaopeng.map.utils.VehicleCodec; import com.xiaopeng.map.utils.XngpAreaRTreeFbsUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; /** * ADC OSS 处理服务实现,根据坐标点生成 RTree fbs 并上传至 OSS。 */ @Slf4j @Service @RequiredArgsConstructor @ConditionalOnBean(RobotaxiOssService.class) public class AdcOssHandleServiceImpl implements AdcOssHandleService { private static final String FILE_NAME_FORMAT = "yyyyMMddHHmmss"; private final RobotaxiOssService robotaxiOssService; private final VinSaltProperties vinSaltProperties; @Override public String uploadOddLayerFile(List points, int areaId, String vin, String areaCode) { validateParams(points, vin, areaCode); String vehicleUuid = VehicleCodec.vinToUUID(vin, vinSaltProperties.getSalt1(), vinSaltProperties.getSalt2()); byte[] fbsBytes = XngpAreaRTreeFbsUtil.buildRTreeBytesFromPoints(points, areaId, false); if (fbsBytes == null || fbsBytes.length == 0) { throw new IllegalStateException("Failed to build RTree fbs from points"); } String fileName = new SimpleDateFormat(FILE_NAME_FORMAT).format(new Date()) + "_xngp_area_data.bin"; String objectKey = robotaxiOssService.uploadOddLayerFile(fbsBytes, fileName, areaCode, vehicleUuid); log.debug("AdcOssHandle uploaded ODD layer file, areaId={}, areaCode={}, objectKey={}", areaId, areaCode, objectKey); return objectKey; } @Override public List deleteOddLayerFiles(String vin, String areaCode) { if (!StringUtils.hasText(vin)) { throw new IllegalArgumentException("vin cannot be empty"); } if (!StringUtils.hasText(areaCode)) { throw new IllegalArgumentException("areaCode cannot be empty"); } String vehicleUuid = VehicleCodec.vinToUUID(vin, vinSaltProperties.getSalt1(), vinSaltProperties.getSalt2()); List deleted = robotaxiOssService.deleteOddLayerFilesByPrefix(areaCode, vehicleUuid); log.debug("AdcOssHandle deleted ODD layer files, vin={}, areaCode={}, count={}", vin, areaCode, deleted.size()); return deleted; } private void validateParams(List points, String vin, String areaCode) { if (CollectionUtils.isEmpty(points)) { throw new IllegalArgumentException("points cannot be empty"); } if (!StringUtils.hasText(vin)) { throw new IllegalArgumentException("vin cannot be empty"); } if (!StringUtils.hasText(areaCode)) { throw new IllegalArgumentException("areaCode cannot be empty"); } } }