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.MapAreaVersionProtoWriter; 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.util.List; /** * ADC OSS 处理服务实现,根据坐标点生成 RTree fbs 并上传至 OSS。 */ @Slf4j @Service @RequiredArgsConstructor @ConditionalOnBean(RobotaxiOssService.class) public class AdcOssHandleServiceImpl implements AdcOssHandleService { 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"); } int version = (int) (System.currentTimeMillis() / 1000); String binFileName = version + "_xngp_area_data.bin"; String objectKey = robotaxiOssService.uploadOddLayerFile(fbsBytes, binFileName, areaCode, vehicleUuid); byte[] pbBytes = MapAreaVersionProtoWriter.toByteArray(version, fbsBytes.length); robotaxiOssService.uploadOddLayerFile(pbBytes, "xngp_area_version.pb", 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"); } } }