“mitao”
2026-03-14 921d981e8ea363f28d04409fb5d68a3eaaa31386
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package com.xiaopeng.map.service.serviceimpl;
 
import com.xiaopeng.map.config.VinSaltProperties;
import com.xiaopeng.map.dto.AreaInput;
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<AreaInput> areas, String vin) {
        validateParams(areas, vin);
 
        String vehicleUuid = VehicleCodec.vinToUUID(vin, vinSaltProperties.getSalt1(), vinSaltProperties.getSalt2());
 
        byte[] fbsBytes = XngpAreaRTreeFbsUtil.buildRTreeBytesFromMultiAreas(areas);
        if (fbsBytes == null || fbsBytes.length == 0) {
            throw new IllegalStateException("Failed to build RTree fbs from areas");
        }
 
        int version = (int) (System.currentTimeMillis() / 1000);
        String binFileName = version + "_xngp_area_data.bin";
 
        String objectKey = robotaxiOssService.uploadOddLayerFile(fbsBytes, binFileName, vehicleUuid);
 
        byte[] pbBytes = MapAreaVersionProtoWriter.toByteArray(version, fbsBytes.length);
        robotaxiOssService.uploadOddLayerFile(pbBytes, "xngp_area_version.pb", vehicleUuid);
 
        log.debug("AdcOssHandle uploaded ODD layer file, areasCount={}, objectKey={}", areas.size(), objectKey);
        return objectKey;
    }
 
    @Override
    public List<String> deleteOddLayerFiles(String vin) {
        if (!StringUtils.hasText(vin)) {
            throw new IllegalArgumentException("vin cannot be empty");
        }
        String vehicleUuid = VehicleCodec.vinToUUID(vin, vinSaltProperties.getSalt1(), vinSaltProperties.getSalt2());
        List<String> deleted = robotaxiOssService.deleteOddLayerFilesByPrefix(vehicleUuid);
        log.debug("AdcOssHandle deleted ODD layer files, vin={}, count={}", vin, deleted.size());
        return deleted;
    }
 
    private void validateParams(List<AreaInput> areas, String vin) {
        if (CollectionUtils.isEmpty(areas)) {
            throw new IllegalArgumentException("areas cannot be empty");
        }
        for (AreaInput area : areas) {
            if (CollectionUtils.isEmpty(area.getPoints())) {
                throw new IllegalArgumentException("each area must have non-empty points");
            }
        }
        if (!StringUtils.hasText(vin)) {
            throw new IllegalArgumentException("vin cannot be empty");
        }
    }
}