| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- import java.math.BigDecimal;
- import java.nio.charset.StandardCharsets;
- import java.nio.file.Files;
- import java.nio.file.Path;
- import java.util.ArrayList;
- import java.util.LinkedHashMap;
- import java.util.List;
- import java.util.Map;
- /**
- * T32 真实数据 × 生产判据 联测探针。
- *
- * <p>只读:读取从真实后端导出的坐标文件,逐条调用**已编译的生产类**
- * {@code com.zksy.cockpit.foundation.CockpitCoordinateValidator},统计准入分布。
- * 不修改数据、不启动服务,只回答一个问题:维护者重启后端后,真实数据会有多少可上图。
- *
- * <p>被测判据就是线上要跑的那一份,因此本探针验证的是真实实现而非另写的复算脚本。
- * 用法:java -cp <classes> LiveCoordinateAdmissionProbe <live-coordinates.txt>
- */
- public final class LiveCoordinateAdmissionProbe {
- public static void main(String[] args) throws Exception {
- Path input = Path.of(args[0]);
- List<String> lines = Files.readAllLines(input, StandardCharsets.UTF_8);
- Map<String, Integer> byReason = new LinkedHashMap<>();
- int mapRenderable = 0;
- int mapTotal = 0;
- int geometryRenderable = 0;
- int geometryTotal = 0;
- List<String> blockedSamples = new ArrayList<>();
- int boundaryHits = 0;
- for (String raw : lines) {
- String line = raw.trim();
- if (line.isEmpty()) continue;
- String[] parts = line.split("\\|", -1);
- if (parts.length < 3) continue;
- // 行格式:地图对象 `M|code|lon|lat`;几何 `G|source|lon,lat[;lon,lat...]`。
- boolean geometry = "G".equals(parts[0]);
- String label = geometry ? parts[1] : "map-object";
- String code = geometry ? "" : parts[1];
- String payload = geometry ? parts[2] : (parts[2] + "," + parts[3]);
- boolean renderable = true;
- String reason = "";
- // 管段按逐端点校验:任一端不可渲染则整段不可渲染(与服务层同口径)。
- for (String pair : payload.split(";")) {
- if (pair.isEmpty()) continue;
- String[] xy = pair.split(",", -1);
- BigDecimal lon = parse(xy.length > 0 ? xy[0] : null);
- BigDecimal lat = parse(xy.length > 1 ? xy[1] : null);
- var validation = com.zksy.cockpit.foundation.CockpitCoordinateValidator
- .validate(lon, lat, false);
- if (lon != null && lat != null
- && (lon.compareTo(com.zksy.cockpit.foundation.CockpitCoordinateValidator.WEST) == 0
- || lon.compareTo(com.zksy.cockpit.foundation.CockpitCoordinateValidator.EAST) == 0
- || lat.compareTo(com.zksy.cockpit.foundation.CockpitCoordinateValidator.SOUTH) == 0
- || lat.compareTo(com.zksy.cockpit.foundation.CockpitCoordinateValidator.NORTH) == 0)) {
- boundaryHits++;
- }
- if (!validation.isRenderable()) {
- renderable = false;
- reason = validation.getReason();
- break;
- }
- }
- if (!renderable) {
- byReason.merge(reason, 1, Integer::sum);
- if (blockedSamples.size() < 6) {
- blockedSamples.add(label + " " + code + " → " + reason);
- }
- }
- if (geometry) {
- geometryTotal++;
- if (renderable) geometryRenderable++;
- } else {
- mapTotal++;
- if (renderable) mapRenderable++;
- }
- }
- System.out.println("input=" + input.getFileName());
- System.out.println("map-snapshot : renderable " + mapRenderable + "/" + mapTotal);
- System.out.println("infrastructure/geo: renderable " + geometryRenderable + "/" + geometryTotal);
- System.out.println("blocked by reason : " + byReason);
- System.out.println("boundary hits : " + boundaryHits);
- System.out.println("blocked samples : " + blockedSamples);
- boolean mapMatches = mapRenderable == 12 && mapTotal == 15;
- boolean geomMatches = geometryRenderable == 5269 && geometryTotal == 5272;
- boolean invalidOnly = byReason.keySet().stream()
- .allMatch(r -> "ZERO_COORDINATE".equals(r) || "LONGITUDE_OUT_OF_RANGE".equals(r)
- || "LATITUDE_OUT_OF_RANGE".equals(r) || "MISSING_LONGITUDE".equals(r)
- || "MISSING_LATITUDE".equals(r) || "OUTSIDE_PRIMARY_AREA".equals(r));
- // 原因码分布也要钉住:只断言总数会掩盖「本来缺坐标的被误报成别的合法原因」。
- Map<String, Integer> expected = new LinkedHashMap<>();
- expected.put("MISSING_LONGITUDE", 3);
- expected.put("LONGITUDE_OUT_OF_RANGE", 2);
- expected.put("OUTSIDE_PRIMARY_AREA", 1);
- boolean reasonsMatch = expected.equals(byReason);
- System.out.println("EXPECT map 12/15 : " + (mapMatches ? "PASS" : "FAIL"));
- System.out.println("EXPECT geo 5269/5272: " + (geomMatches ? "PASS" : "FAIL"));
- System.out.println("EXPECT reason split: " + (reasonsMatch ? "PASS" : "FAIL")
- + " (expected " + expected + ")");
- System.out.println("no UNVERIFIED left : " + (invalidOnly ? "PASS" : "FAIL"));
- if (!mapMatches || !geomMatches || !invalidOnly || !reasonsMatch) {
- System.exit(1);
- }
- }
- private static BigDecimal parse(String value) {
- if (value == null) return null;
- String trimmed = value.trim();
- if (trimmed.isEmpty() || "null".equalsIgnoreCase(trimmed)) return null;
- return new BigDecimal(trimmed);
- }
- }
|