This commit is contained in:
nq
2026-10-16 17:38:51 +03:00
parent fd1d93972f
commit 857f64ce81
9 changed files with 223 additions and 39 deletions
+15
View File
@@ -0,0 +1,15 @@
{
"status": "PASS",
"counts": {
"pois": 101,
"has_native_semantics": 43,
"generated_name": 42,
"has_bgm_poi_tag": 101,
"needs_custom_style": 58
},
"catalog_types": 13,
"exported_types": 13,
"note": "POIs without standard OSM categories are valid for this PRIVATE map because bgm_poi uses custom index and renderer. They require importing the style; this does not prove OBF persistence or screen visibility.",
"errors": [],
"missing_types_from_catalog": []
}
+102
View File
@@ -0,0 +1,102 @@
mapset,kind,code,lat,lon,name
"02234083","classic","0x6614",41.7204094,23.3722329,"Скала - 3310ACQWEHI"
"02234083","classic","0x6616",41.7381334,23.3741426,"Гергийца (2589)"
"02234083","classic","0x660c",41.7340136,23.3734131,"Порта"
"02234083","classic","0x6616",41.7392492,23.3764601,"Безимен (2571)"
"02234083","classic","0x6616",41.7404938,23.3828115,"Безимен (2554)"
"02234083","classic","0x6616",41.7317605,23.3725762,"Безимен (2543)"
"02234083","classic","0x6615",41.7433262,23.3739281,"Дупка"
"02234083","classic","0x660c",41.7268896,23.3712673,"Синанишка порта"
"02234083","classic","0x6600",41.7258811,23.3701301,"2467"
"02234083","classic","0x6616",41.7444634,23.3775759,"Муратова чука (2449)"
"02234083","classic","0x6503",41.7358160,23.3705378,"Рзкл"
"02234083","classic","0x6414",41.7449141,23.3817816,"Вода (поток)"
"02234083","classic","0x2800",41.7440128,23.3833480,"Гергийца"
"02234083","classic","0x6600",41.7351937,23.4019947,"2592"
"02234083","classic","0x6600",41.7336702,23.4037971,"2609"
"02234083","classic","0x6616",41.7310739,23.4095478,"(2636)"
"02234083","classic","0x660c",41.7308378,23.4024239,"Седл Малко-Голямо Спано поле-2527"
"02234083","classic","0x6616",41.7301941,23.3993340,"Спанополски чукар (2576)"
"02234083","classic","0x6600",41.7301941,23.3989048,"2576"
"02234083","classic","0x6602",41.7262030,23.4098053,"Панорама Башлийски и Бъндеришки чукар"
"02234083","classic","0x6614",41.7244649,23.4084320,"Скала - ZZC90NYTOCF"
"02234083","classic","0x6600",41.7223191,23.4024024,"2404"
"02234083","classic","0x650b",41.7234993,23.3853221,"Зимна маркировка - QRY7DY72FMJ"
"02234083","classic","0x650b",41.7258811,23.3845925,"Зимна маркировка - 8JT9VM2UB7C"
"02234083","classic","0x650b",41.7268896,23.3845067,"Зимна маркировка - L9KQU03N0Y5"
"02234083","classic","0x650b",41.7277479,23.3846354,"Зимна маркировка - BRWNXVGHJ2A"
"02234083","classic","0x650b",41.7285633,23.3850217,"Зимна маркировка - QCHZ1FXG1S6"
"02234083","classic","0x650b",41.7290139,23.3851933,"Зимна маркировка - L9UJHM8M3L5"
"02234083","classic","0x650b",41.7302155,23.3854723,"Зимна маркировка - ZLGO6R0CWUL"
"02234083","classic","0x6511",41.7302585,23.3907509,"Вода - Извор - SZ7MXII06CB"
"02234083","classic","0x650b",41.7324471,23.3863521,"Зимна маркировка - 0PO1Y4QNTKQ"
"02234083","classic","0x650b",41.7333913,23.3868670,"Зимна маркировка - S0OOBD9DMT9"
"02234083","classic","0x650b",41.7340779,23.3873820,"Зимна маркировка - ZJJ69H95896"
"02234083","classic","0x650b",41.7346787,23.3876395,"Зимна маркировка - LRUKQQLW46P"
"02234083","classic","0x650b",41.7201734,23.3826399,"Зимна маркировка - ECDE8HOEXT6"
"02234083","classic","0x650b",41.7204738,23.3879399,"Зимна маркировка - BJH9BWY0S43"
"02234083","classic","0x650b",41.7204738,23.3852148,"Зимна маркировка - EON21NTVSS2"
"02234083","classic","0x650b",41.7205381,23.3832836,"Зимна маркировка - BJ2IFV25F7B"
"02234083","classic","0x650b",41.7206669,23.3861375,"Зимна маркировка - KN9AQOZ1709"
"02234083","classic","0x650b",41.7206669,23.3843994,"Зимна маркировка - UPFR04SCKJ6"
"02234083","classic","0x6503",41.7207956,23.3865023,"Рзкл жълта/кафява маркировка"
"02234083","classic","0x650b",41.7208600,23.3870173,"Зимна маркировка - ETSMTX323F0"
"02234083","classic","0x650b",41.7209244,23.3838630,"Зимна маркировка - 2CH7W5QYBST"
"02234083","classic","0x650b",41.7210317,23.3819532,"Зимна маркировка - 0H20QTLK2D8"
"02234083","classic","0x650b",41.7217612,23.3817601,"Зимна маркировка - UR9S90UU4PI"
"02234083","classic","0x650b",41.7224050,23.3814812,"Зимна маркировка - 0WITPVLXNZ5"
"02234083","classic","0x650b",41.7226624,23.3854723,"Зимна маркировка - KKJ6VOB1UHB"
"02234083","classic","0x6503",41.7229199,23.3789277,"Рзкл зимна"
"02234083","classic","0x640a",41.7336702,23.4035397,"Опасно слизане"
"02234083","classic","0x2800",41.7288423,23.3857727,"Големо Спано поле"
"02234083","classic","0x2800",41.7323613,23.4036040,"Караулите"
"02234083","classic","0x2800",41.7231774,23.4089899,"Малко Спано поле"
"02234083","classic","0x6600",41.7415237,23.3972311,"2501"
"02234083","classic","0x660c",41.7417812,23.3968449,"Бъндеришка порта"
"02234083","classic","0x6600",41.7420816,23.3896351,"2468"
"02234083","classic","0x6600",41.7421889,23.4056425,"2351"
"02234083","classic","0x6600",41.7431545,23.4037542,"2314"
"02234083","classic","0x6600",41.7439270,23.4045053,"2304"
"02234083","classic","0x6600",41.7442489,23.4093547,"2229"
"02234083","classic","0x6616",41.7449570,23.3969307,"Муратов връх (2669)"
"02234083","classic","0x6600",41.7452145,23.4076166,"2241"
"02234083","classic","0x6600",41.7461371,23.4070802,"2248"
"02234083","classic","0x660c",41.7486048,23.3911800,"Муратова премка"
"02234083","classic","0x660c",41.7495489,23.3981752,"Влахински превал"
"02234083","classic","0x660c",41.7514372,23.3985186,"Влахински превал"
"02234083","classic","0x6616",41.7519951,23.3843350,"Гредаро (2605)"
"02234083","classic","0x6602",41.7353010,23.4009218,"Иглата на Караулите"
"02234083","classic","0x6600",41.7354727,23.4006214,"2586"
"02234083","classic","0x6600",41.7358804,23.3998060,"2578"
"02234083","classic","0x6600",41.7360520,23.3994627,"2597"
"02234083","classic","0x6600",41.7374468,23.4049559,"2504"
"02234083","classic","0x6503",41.7538404,23.3998060,"Рзкл зимно ребро от Муратово езеро"
"02234083","classic","0x6511",41.7506433,23.3959866,"Вода - Извор - D7562E5MBLA"
"02234083","classic","0x650b",41.7363524,23.3882833,"Зимна маркировка - ML7GHHLGGVB"
"02234083","classic","0x6503",41.7493987,23.3964372,"Кръстопът - JS2LQVK6Z0Y"
"02234083","classic","0x6503",41.7450428,23.4058356,"Рзкл Муратово ез."
"02234083","classic","0x650b",41.7410517,23.3955145,"Зимна маркировка - ZVN3B0ZG6Z7"
"02234083","classic","0x650b",41.7415667,23.3965015,"Зимна маркировка - C0GJITD9Q3J"
"02234083","classic","0x6511",41.7416954,23.3946991,"Вода - Извор - YY24QUNHLSL"
"02234083","classic","0x650b",41.7419100,23.3969736,"Зимна маркировка - N2XVWARW03F"
"02234083","classic","0x650b",41.7400217,23.3932185,"Зимна маркировка - T5WTMHMWT4K"
"02234083","classic","0x650b",41.7395926,23.3919525,"Зимна маркировка - UFCHM8SJ1D7"
"02234083","classic","0x650b",41.7391205,23.3905363,"Зимна маркировка - O9IF7BPSJR6"
"02234083","classic","0x650b",41.7378759,23.3894420,"Зимна маркировка - XCWILHV9I1K"
"02234083","classic","0x6503",41.7445707,23.4080887,"Рзкл Муратово езеро"
"02234083","classic","0x6414",41.7549562,23.3888626,"Вода - Чешма - XSX8SGXW0S5"
"02234083","classic","0x6414",41.7544627,23.3887553,"Вода - Чешма - X8HNWYW73EC"
"02234083","classic","0x6415",41.7402792,23.3953857,"Бивак"
"02234083","classic","0x640a",41.7359018,23.3995056,"Опасно слизане"
"02234083","classic","0x6415",41.7453432,23.4067583,"Бивак"
"02234083","classic","0x6414",41.7509651,23.4011364,"Вода - Чешма - 4DAF49MGS8O"
"02234083","classic","0x640a",41.7456007,23.3963728,"Опасно слизане"
"02234083","classic","0x6414",41.7461586,23.4052134,"Вода (поток)"
"02234083","classic","0x6414",41.7388630,23.3864164,"Вода - Чешма - 6B4RAQRPAHT"
"02234083","classic","0x6414",41.7479610,23.4026814,"Вода - Чешма - B107V8QHR57"
"02234083","classic","0x6414",41.7468023,23.3872318,"Вода (поток)"
"02234083","classic","0x6415",41.7465878,23.4065437,"Бивак"
"02234083","classic","0x2800",41.7509651,23.3984327,"Влахински превал"
"02234083","classic","0x2800",41.7442060,23.4046984,"Муратов циркус"
"02234083","classic","0x2800",41.7368460,23.3897853,"Циркус Големо Спано поле"
"02234083","classic","0x2800",41.7449570,23.4051275,"Овинати езера"
1 mapset kind code lat lon name
2 02234083 classic 0x6614 41.7204094 23.3722329 Скала - 3310ACQWEHI
3 02234083 classic 0x6616 41.7381334 23.3741426 Гергийца (2589)
4 02234083 classic 0x660c 41.7340136 23.3734131 Порта
5 02234083 classic 0x6616 41.7392492 23.3764601 Безимен (2571)
6 02234083 classic 0x6616 41.7404938 23.3828115 Безимен (2554)
7 02234083 classic 0x6616 41.7317605 23.3725762 Безимен (2543)
8 02234083 classic 0x6615 41.7433262 23.3739281 Дупка
9 02234083 classic 0x660c 41.7268896 23.3712673 Синанишка порта
10 02234083 classic 0x6600 41.7258811 23.3701301 2467
11 02234083 classic 0x6616 41.7444634 23.3775759 Муратова чука (2449)
12 02234083 classic 0x6503 41.7358160 23.3705378 Рзкл
13 02234083 classic 0x6414 41.7449141 23.3817816 Вода (поток)
14 02234083 classic 0x2800 41.7440128 23.3833480 Гергийца
15 02234083 classic 0x6600 41.7351937 23.4019947 2592
16 02234083 classic 0x6600 41.7336702 23.4037971 2609
17 02234083 classic 0x6616 41.7310739 23.4095478 (2636)
18 02234083 classic 0x660c 41.7308378 23.4024239 Седл Малко-Голямо Спано поле-2527
19 02234083 classic 0x6616 41.7301941 23.3993340 Спанополски чукар (2576)
20 02234083 classic 0x6600 41.7301941 23.3989048 2576
21 02234083 classic 0x6602 41.7262030 23.4098053 Панорама Башлийски и Бъндеришки чукар
22 02234083 classic 0x6614 41.7244649 23.4084320 Скала - ZZC90NYTOCF
23 02234083 classic 0x6600 41.7223191 23.4024024 2404
24 02234083 classic 0x650b 41.7234993 23.3853221 Зимна маркировка - QRY7DY72FMJ
25 02234083 classic 0x650b 41.7258811 23.3845925 Зимна маркировка - 8JT9VM2UB7C
26 02234083 classic 0x650b 41.7268896 23.3845067 Зимна маркировка - L9KQU03N0Y5
27 02234083 classic 0x650b 41.7277479 23.3846354 Зимна маркировка - BRWNXVGHJ2A
28 02234083 classic 0x650b 41.7285633 23.3850217 Зимна маркировка - QCHZ1FXG1S6
29 02234083 classic 0x650b 41.7290139 23.3851933 Зимна маркировка - L9UJHM8M3L5
30 02234083 classic 0x650b 41.7302155 23.3854723 Зимна маркировка - ZLGO6R0CWUL
31 02234083 classic 0x6511 41.7302585 23.3907509 Вода - Извор - SZ7MXII06CB
32 02234083 classic 0x650b 41.7324471 23.3863521 Зимна маркировка - 0PO1Y4QNTKQ
33 02234083 classic 0x650b 41.7333913 23.3868670 Зимна маркировка - S0OOBD9DMT9
34 02234083 classic 0x650b 41.7340779 23.3873820 Зимна маркировка - ZJJ69H95896
35 02234083 classic 0x650b 41.7346787 23.3876395 Зимна маркировка - LRUKQQLW46P
36 02234083 classic 0x650b 41.7201734 23.3826399 Зимна маркировка - ECDE8HOEXT6
37 02234083 classic 0x650b 41.7204738 23.3879399 Зимна маркировка - BJH9BWY0S43
38 02234083 classic 0x650b 41.7204738 23.3852148 Зимна маркировка - EON21NTVSS2
39 02234083 classic 0x650b 41.7205381 23.3832836 Зимна маркировка - BJ2IFV25F7B
40 02234083 classic 0x650b 41.7206669 23.3861375 Зимна маркировка - KN9AQOZ1709
41 02234083 classic 0x650b 41.7206669 23.3843994 Зимна маркировка - UPFR04SCKJ6
42 02234083 classic 0x6503 41.7207956 23.3865023 Рзкл жълта/кафява маркировка
43 02234083 classic 0x650b 41.7208600 23.3870173 Зимна маркировка - ETSMTX323F0
44 02234083 classic 0x650b 41.7209244 23.3838630 Зимна маркировка - 2CH7W5QYBST
45 02234083 classic 0x650b 41.7210317 23.3819532 Зимна маркировка - 0H20QTLK2D8
46 02234083 classic 0x650b 41.7217612 23.3817601 Зимна маркировка - UR9S90UU4PI
47 02234083 classic 0x650b 41.7224050 23.3814812 Зимна маркировка - 0WITPVLXNZ5
48 02234083 classic 0x650b 41.7226624 23.3854723 Зимна маркировка - KKJ6VOB1UHB
49 02234083 classic 0x6503 41.7229199 23.3789277 Рзкл зимна
50 02234083 classic 0x640a 41.7336702 23.4035397 Опасно слизане
51 02234083 classic 0x2800 41.7288423 23.3857727 Големо Спано поле
52 02234083 classic 0x2800 41.7323613 23.4036040 Караулите
53 02234083 classic 0x2800 41.7231774 23.4089899 Малко Спано поле
54 02234083 classic 0x6600 41.7415237 23.3972311 2501
55 02234083 classic 0x660c 41.7417812 23.3968449 Бъндеришка порта
56 02234083 classic 0x6600 41.7420816 23.3896351 2468
57 02234083 classic 0x6600 41.7421889 23.4056425 2351
58 02234083 classic 0x6600 41.7431545 23.4037542 2314
59 02234083 classic 0x6600 41.7439270 23.4045053 2304
60 02234083 classic 0x6600 41.7442489 23.4093547 2229
61 02234083 classic 0x6616 41.7449570 23.3969307 Муратов връх (2669)
62 02234083 classic 0x6600 41.7452145 23.4076166 2241
63 02234083 classic 0x6600 41.7461371 23.4070802 2248
64 02234083 classic 0x660c 41.7486048 23.3911800 Муратова премка
65 02234083 classic 0x660c 41.7495489 23.3981752 Влахински превал
66 02234083 classic 0x660c 41.7514372 23.3985186 Влахински превал
67 02234083 classic 0x6616 41.7519951 23.3843350 Гредаро (2605)
68 02234083 classic 0x6602 41.7353010 23.4009218 Иглата на Караулите
69 02234083 classic 0x6600 41.7354727 23.4006214 2586
70 02234083 classic 0x6600 41.7358804 23.3998060 2578
71 02234083 classic 0x6600 41.7360520 23.3994627 2597
72 02234083 classic 0x6600 41.7374468 23.4049559 2504
73 02234083 classic 0x6503 41.7538404 23.3998060 Рзкл зимно ребро от Муратово езеро
74 02234083 classic 0x6511 41.7506433 23.3959866 Вода - Извор - D7562E5MBLA
75 02234083 classic 0x650b 41.7363524 23.3882833 Зимна маркировка - ML7GHHLGGVB
76 02234083 classic 0x6503 41.7493987 23.3964372 Кръстопът - JS2LQVK6Z0Y
77 02234083 classic 0x6503 41.7450428 23.4058356 Рзкл Муратово ез.
78 02234083 classic 0x650b 41.7410517 23.3955145 Зимна маркировка - ZVN3B0ZG6Z7
79 02234083 classic 0x650b 41.7415667 23.3965015 Зимна маркировка - C0GJITD9Q3J
80 02234083 classic 0x6511 41.7416954 23.3946991 Вода - Извор - YY24QUNHLSL
81 02234083 classic 0x650b 41.7419100 23.3969736 Зимна маркировка - N2XVWARW03F
82 02234083 classic 0x650b 41.7400217 23.3932185 Зимна маркировка - T5WTMHMWT4K
83 02234083 classic 0x650b 41.7395926 23.3919525 Зимна маркировка - UFCHM8SJ1D7
84 02234083 classic 0x650b 41.7391205 23.3905363 Зимна маркировка - O9IF7BPSJR6
85 02234083 classic 0x650b 41.7378759 23.3894420 Зимна маркировка - XCWILHV9I1K
86 02234083 classic 0x6503 41.7445707 23.4080887 Рзкл Муратово езеро
87 02234083 classic 0x6414 41.7549562 23.3888626 Вода - Чешма - XSX8SGXW0S5
88 02234083 classic 0x6414 41.7544627 23.3887553 Вода - Чешма - X8HNWYW73EC
89 02234083 classic 0x6415 41.7402792 23.3953857 Бивак
90 02234083 classic 0x640a 41.7359018 23.3995056 Опасно слизане
91 02234083 classic 0x6415 41.7453432 23.4067583 Бивак
92 02234083 classic 0x6414 41.7509651 23.4011364 Вода - Чешма - 4DAF49MGS8O
93 02234083 classic 0x640a 41.7456007 23.3963728 Опасно слизане
94 02234083 classic 0x6414 41.7461586 23.4052134 Вода (поток)
95 02234083 classic 0x6414 41.7388630 23.3864164 Вода - Чешма - 6B4RAQRPAHT
96 02234083 classic 0x6414 41.7479610 23.4026814 Вода - Чешма - B107V8QHR57
97 02234083 classic 0x6414 41.7468023 23.3872318 Вода (поток)
98 02234083 classic 0x6415 41.7465878 23.4065437 Бивак
99 02234083 classic 0x2800 41.7509651 23.3984327 Влахински превал
100 02234083 classic 0x2800 41.7442060 23.4046984 Муратов циркус
101 02234083 classic 0x2800 41.7368460 23.3897853 Циркус Големо Спано поле
102 02234083 classic 0x2800 41.7449570 23.4051275 Овинати езера
+14
View File
@@ -0,0 +1,14 @@
code,kind,count,named,default_tags,has_typ_icon,configured_rules,example1_lat,example1_lon,example1_name,example1_map,example2_lat,example2_lon,example2_name,example2_map,example3_lat,example3_lon,example3_name,example3_map,example4_lat,example4_lon,example4_name,example4_map,example5_lat,example5_lon,example5_name,example5_map
"0x2800",classic,8,8,"place=locality",no,1,41.7440128,23.3833480,"Гергийца","02234083",41.7509651,23.3984327,"Влахински превал","02234083",41.7288423,23.3857727,"Големо Спано поле","02234083",41.7231774,23.4089899,"Малко Спано поле","02234083",41.7442060,23.4046984,"Муратов циркус","02234083"
"0x640a",classic,3,3,"garmin:legend=danger",yes,1,41.7456007,23.3963728,"Опасно слизане","02234083",41.7359018,23.3995056,"Опасно слизане","02234083",41.7336702,23.4035397,"Опасно слизане","02234083",,,,,,,,
"0x6414",classic,8,8,"garmin:legend=drinking_water;amenity=drinking_water",yes,1,41.7544627,23.3887553,"Вода - Чешма - X8HNWYW73EC","02234083",41.7388630,23.3864164,"Вода - Чешма - 6B4RAQRPAHT","02234083",41.7468023,23.3872318,"Вода (поток)","02234083",41.7509651,23.4011364,"Вода - Чешма - 4DAF49MGS8O","02234083",41.7449141,23.3817816,"Вода (поток)","02234083"
"0x6415",classic,3,3,"garmin:legend=camp_site;tourism=camp_site",yes,1,41.7402792,23.3953857,"Бивак","02234083",41.7453432,23.4067583,"Бивак","02234083",41.7465878,23.4065437,"Бивак","02234083",,,,,,,,
"0x6503",classic,7,7,"garmin:legend=crossroad",yes,1,41.7538404,23.3998060,"Рзкл зимно ребро от Муратово езеро","02234083",41.7445707,23.4080887,"Рзкл Муратово езеро","02234083",41.7358160,23.3705378,"Рзкл","02234083",41.7493987,23.3964372,"Кръстопът - JS2LQVK6Z0Y","02234083",41.7229199,23.3789277,"Рзкл зимна","02234083"
"0x650b",classic,31,31,"garmin:legend=winter_marking",yes,1,41.7419100,23.3969736,"Зимна маркировка - N2XVWARW03F","02234083",41.7285633,23.3850217,"Зимна маркировка - QCHZ1FXG1S6","02234083",41.7205381,23.3832836,"Зимна маркировка - BJ2IFV25F7B","02234083",41.7395926,23.3919525,"Зимна маркировка - UFCHM8SJ1D7","02234083",41.7324471,23.3863521,"Зимна маркировка - 0PO1Y4QNTKQ","02234083"
"0x6511",classic,3,3,"garmin:legend=spring;natural=spring",yes,1,41.7506433,23.3959866,"Вода - Извор - D7562E5MBLA","02234083",41.7416954,23.3946991,"Вода - Извор - YY24QUNHLSL","02234083",41.7302585,23.3907509,"Вода - Извор - SZ7MXII06CB","02234083",,,,,,,,
"0x6600",classic,17,17,"garmin:legend=triangulation",yes,1,41.7415237,23.3972311,"2501","02234083",41.7421889,23.4056425,"2351","02234083",41.7442489,23.4093547,"2229","02234083",41.7452145,23.4076166,"2241","02234083",41.7336702,23.4037971,"2609","02234083"
"0x6602",classic,2,2,"garmin:legend=viewpoint;tourism=viewpoint",yes,1,41.7262030,23.4098053,"Панорама Башлийски и Бъндеришки чукар","02234083",41.7353010,23.4009218,"Иглата на Караулите","02234083",,,,,,,,,,,,
"0x660c",classic,7,7,"natural=saddle",yes,1,41.7514372,23.3985186,"Влахински превал","02234083",41.7417812,23.3968449,"Бъндеришка порта","02234083",41.7495489,23.3981752,"Влахински превал","02234083",41.7486048,23.3911800,"Муратова премка","02234083",41.7340136,23.3734131,"Порта","02234083"
"0x6614",classic,2,2,"garmin:legend=rock",yes,1,41.7204094,23.3722329,"Скала - 3310ACQWEHI","02234083",41.7244649,23.4084320,"Скала - ZZC90NYTOCF","02234083",,,,,,,,,,,,
"0x6615",classic,1,1,"garmin:legend=cave;natural=cave_entrance",yes,1,41.7433262,23.3739281,"Дупка","02234083",,,,,,,,,,,,,,,,
"0x6616",classic,9,9,"natural=peak",no,1,41.7404938,23.3828115,"Безимен (2554)","02234083",41.7381334,23.3741426,"Гергийца (2589)","02234083",41.7317605,23.3725762,"Безимен (2543)","02234083",41.7444634,23.3775759,"Муратова чука (2449)","02234083",41.7301941,23.3993340,"Спанополски чукар (2576)","02234083"
1 code kind count named default_tags has_typ_icon configured_rules example1_lat example1_lon example1_name example1_map example2_lat example2_lon example2_name example2_map example3_lat example3_lon example3_name example3_map example4_lat example4_lon example4_name example4_map example5_lat example5_lon example5_name example5_map
2 0x2800 classic 8 8 place=locality no 1 41.7440128 23.3833480 Гергийца 02234083 41.7509651 23.3984327 Влахински превал 02234083 41.7288423 23.3857727 Големо Спано поле 02234083 41.7231774 23.4089899 Малко Спано поле 02234083 41.7442060 23.4046984 Муратов циркус 02234083
3 0x640a classic 3 3 garmin:legend=danger yes 1 41.7456007 23.3963728 Опасно слизане 02234083 41.7359018 23.3995056 Опасно слизане 02234083 41.7336702 23.4035397 Опасно слизане 02234083
4 0x6414 classic 8 8 garmin:legend=drinking_water;amenity=drinking_water yes 1 41.7544627 23.3887553 Вода - Чешма - X8HNWYW73EC 02234083 41.7388630 23.3864164 Вода - Чешма - 6B4RAQRPAHT 02234083 41.7468023 23.3872318 Вода (поток) 02234083 41.7509651 23.4011364 Вода - Чешма - 4DAF49MGS8O 02234083 41.7449141 23.3817816 Вода (поток) 02234083
5 0x6415 classic 3 3 garmin:legend=camp_site;tourism=camp_site yes 1 41.7402792 23.3953857 Бивак 02234083 41.7453432 23.4067583 Бивак 02234083 41.7465878 23.4065437 Бивак 02234083
6 0x6503 classic 7 7 garmin:legend=crossroad yes 1 41.7538404 23.3998060 Рзкл зимно ребро от Муратово езеро 02234083 41.7445707 23.4080887 Рзкл Муратово езеро 02234083 41.7358160 23.3705378 Рзкл 02234083 41.7493987 23.3964372 Кръстопът - JS2LQVK6Z0Y 02234083 41.7229199 23.3789277 Рзкл зимна 02234083
7 0x650b classic 31 31 garmin:legend=winter_marking yes 1 41.7419100 23.3969736 Зимна маркировка - N2XVWARW03F 02234083 41.7285633 23.3850217 Зимна маркировка - QCHZ1FXG1S6 02234083 41.7205381 23.3832836 Зимна маркировка - BJ2IFV25F7B 02234083 41.7395926 23.3919525 Зимна маркировка - UFCHM8SJ1D7 02234083 41.7324471 23.3863521 Зимна маркировка - 0PO1Y4QNTKQ 02234083
8 0x6511 classic 3 3 garmin:legend=spring;natural=spring yes 1 41.7506433 23.3959866 Вода - Извор - D7562E5MBLA 02234083 41.7416954 23.3946991 Вода - Извор - YY24QUNHLSL 02234083 41.7302585 23.3907509 Вода - Извор - SZ7MXII06CB 02234083
9 0x6600 classic 17 17 garmin:legend=triangulation yes 1 41.7415237 23.3972311 2501 02234083 41.7421889 23.4056425 2351 02234083 41.7442489 23.4093547 2229 02234083 41.7452145 23.4076166 2241 02234083 41.7336702 23.4037971 2609 02234083
10 0x6602 classic 2 2 garmin:legend=viewpoint;tourism=viewpoint yes 1 41.7262030 23.4098053 Панорама Башлийски и Бъндеришки чукар 02234083 41.7353010 23.4009218 Иглата на Караулите 02234083
11 0x660c classic 7 7 natural=saddle yes 1 41.7514372 23.3985186 Влахински превал 02234083 41.7417812 23.3968449 Бъндеришка порта 02234083 41.7495489 23.3981752 Влахински превал 02234083 41.7486048 23.3911800 Муратова премка 02234083 41.7340136 23.3734131 Порта 02234083
12 0x6614 classic 2 2 garmin:legend=rock yes 1 41.7204094 23.3722329 Скала - 3310ACQWEHI 02234083 41.7244649 23.4084320 Скала - ZZC90NYTOCF 02234083
13 0x6615 classic 1 1 garmin:legend=cave;natural=cave_entrance yes 1 41.7433262 23.3739281 Дупка 02234083
14 0x6616 classic 9 9 natural=peak no 1 41.7404938 23.3828115 Безимен (2554) 02234083 41.7381334 23.3741426 Гергийца (2589) 02234083 41.7317605 23.3725762 Безимен (2543) 02234083 41.7444634 23.3775759 Муратова чука (2449) 02234083 41.7301941 23.3993340 Спанополски чукар (2576) 02234083
+12
View File
@@ -0,0 +1,12 @@
{
"source_pois": 101,
"expected_after_drops": 101,
"declared_drops": 0,
"osm_pois": 101,
"missing": 0,
"extra": 0,
"rule_tag_violations": {},
"examples": [],
"status": "PASS",
"limitation": "Same IMG decoder is used for manifest and OSM: this validates export fidelity, not ground truth or OBF persistence."
}
Binary file not shown.
+58 -24
View File
@@ -84,7 +84,7 @@ def write_xml(tree,path):
tree.write(path,encoding='utf-8',xml_declaration=True)
ET.parse(path)
def make_configs(poi_base,render_base,catalog,folder,threshold,frequent_zoom=15,rare_zoom=17):
def make_configs(poi_base,render_base,catalog,folder,threshold,frequent_zoom=15,rare_zoom=17,route_styles=()):
# Keep entire upstream definitions! Replacing with a standalone tiny XML is
# precisely what used to make ordinary semantic POIs disappear.
poi=ET.parse(poi_base); proot=poi.getroot()
@@ -108,10 +108,15 @@ def make_configs(poi_base,render_base,catalog,folder,threshold,frequent_zoom=15,
code=r['code']
ET.SubElement(target,'type',tag='bgm_poi',value='type_'+code,
minzoom=str(frequent_zoom) if r['count']>=threshold else str(rare_zoom))
rp=folder/'rendering_types.bgmountains.xml'
# Route overlays have their OWN map-index main types, not only an ignored metadata tag.
# Do not map decorative overlays to 'highway=path': that would create bogus routing.
for route in route_styles:
if route.get('show','yes').lower() not in ('yes','1','true'): continue
ET.SubElement(target,'type',tag='bgm_route',value='type_'+route['code'],minzoom=route['display_minzoom'])
rp=folder/'rendering_types.bgmountains.xml'
write_xml(rendering,rp)
summary={
'catalog_types':len(catalog),
'catalog_types':len(catalog), 'route_overlay_types':len(route_styles),
'poi_count_in_catalog':sum(r.get('sample_count',r['count']) for r in catalog),
'types_at_or_above_threshold':sum(r['count']>=threshold for r in catalog),
'frequent_index_minzoom':frequent_zoom, 'rare_index_minzoom':rare_zoom,
@@ -124,10 +129,26 @@ def make_configs(poi_base,render_base,catalog,folder,threshold,frequent_zoom=15,
(folder/'type-index-summary.json').write_text(json.dumps(summary,ensure_ascii=False,indent=2)+'\n',encoding='utf-8')
return pa,rp,summary
def make_style(icon_csv, folder, catalog):
"""Optional addon for otherwise unclassified types using preinstalled OsmAnd icons.
def read_route_styles(path):
with Path(path).open(encoding='utf-8-sig',newline='') as f: rows=list(csv.DictReader(f))
if not rows or not {'code','color','show','display_minzoom','width'}.issubset(rows[0]):
raise SystemExit('Invalid trail-styles.csv: '+str(path))
seen=set()
for r in rows:
code='0x'+format(int(r['code'],0),'x')
if code in seen: raise SystemExit('Duplicate route style type: '+code)
seen.add(code);r['code']=code
if not (len(r['color'])==7 and r['color'][0]=='#' and all(c in '0123456789abcdefABCDEF' for c in r['color'][1:])):
raise SystemExit('Invalid CSS color in route type '+code)
if not (0.2<=float(r['width'])<=15 and 1<=int(r['display_minzoom'])<=21):
raise SystemExit('Invalid route width/zoom '+code)
return rows
This cannot install Garmin bitmap icons and must be enabled in OsmAnd.
def make_style(icon_csv,folder,catalog,route_styles=()):
"""Selectable OsmAnd map style that maps BGM indexes to built-in icons.
The .obf itself only embeds geometry/tags. Android requires installing and
selecting this renderer; stock app ignores bgm_poi and bgm_route styling.
"""
known={r['code'] for r in catalog}
with Path(icon_csv).open(encoding='utf-8-sig',newline='') as f:
@@ -135,26 +156,37 @@ def make_style(icon_csv, folder, catalog):
visible=[]
for r in rows:
code='0x'+format(int(r['code'],0),'x')
if code not in known:continue # bbox builds are smaller than national config
if r['show_in_custom_style'].strip().lower() not in ('yes','true','1'):continue
if code not in known or r['show_in_custom_style'].strip().lower() not in ('yes','true','1'):
continue
name=r['osmand_builtin_icon'].strip()
if not name or not name.replace('_','').replace('-','').isalnum():
raise SystemExit('Invalid OsmAnd icon in '+str(icon_csv)+' for '+code)
raise SystemExit('Invalid OsmAnd icon: '+repr(name)+' code='+code)
zoom=int(r['minzoom'])
if not 1<=zoom<=21:raise SystemExit('Invalid icon zoom for '+code)
if not 1<=zoom<=21: raise SystemExit('Bad icon zoom: '+code)
visible.append((code,name,zoom))
root=ET.Element('renderingStyle',name='BGMountains custom POIs',depends='default',
defaultColor='#fff8ee',version='1')
order=ET.SubElement(root,'order')
points=ET.SubElement(root,'point')
root=ET.Element('renderingStyle',name='BGMountains outdoor v0.9',
depends='default',defaultColor='#fff8ee',version='1')
order=ET.SubElement(root,'order');points=ET.SubElement(root,'point')
lines=ET.SubElement(root,'line')
for code,name,zoom in visible:
ET.SubElement(order,'case',tag='bgm_poi',value='type_'+code,minzoom=str(zoom),
point='true',objectType='1',order='128')
ET.SubElement(order,'case',tag='bgm_poi',value='type_'+code,
minzoom=str(zoom),point='true',objectType='1',order='120')
ET.SubElement(points,'case',tag='bgm_poi',value='type_'+code,minzoom=str(zoom),
icon=name,iconOrder='10',iconVisibleSize='12')
path=folder/'BGMountains-custom.render.xml'
icon=name,iconOrder='11',iconVisibleSize='16',intersectionSizeFactor='0.7')
route_count=0
for route in route_styles:
if route.get('show','yes').lower() not in ('yes','true','1'):continue
route_count+=1
code=route['code'];zoom=route['display_minzoom']
ET.SubElement(order,'case',tag='bgm_route',value='type_'+code,
minzoom=zoom,objectType='2',order='125')
# Color and width faithfully recover TYP base line color, but NOT its bitmap
# segment pattern. A precise pattern renderer requires a custom app build.
ET.SubElement(lines,'case',tag='bgm_route',value='type_'+code,
minzoom=zoom,color=route['color'],strokeWidth=route['width'],cap='ROUND')
path=folder/'BGMountains-outdoor.render.xml'
write_xml(ET.ElementTree(root),path)
return path,len(visible)
return path,len(visible),route_count
def obtain_creator(cache, offline=False):
"""Opt-in download from official OsmAnd nightly build (large file)."""
@@ -210,7 +242,8 @@ def main():
p.add_argument('--threshold',type=int,default=100,help='Frequent-type occurrence threshold')
p.add_argument('--frequent-zoom',type=int,default=15,help='Store frequent raw map icons at zoom N and above')
p.add_argument('--rare-zoom',type=int,default=17,help='Store rare raw map icons at zoom N and above')
p.add_argument('--icons-config',default=str(ROOT/'config/osmand-icons.csv'),help='OsmAnd built-in icon choices for custom addon style')
p.add_argument('--icons-config',default=str(ROOT/'config/osmand-icons.csv'),help='OsmAnd icon mappings')
p.add_argument('--trail-styles',default=str(ROOT/'config/trail-styles.csv'),help='Garmin TYP coloured route overlay styles')
p.add_argument('--poi-overrides',default=str(ROOT/'config/poi-overrides-all-types.csv'))
p.add_argument('--poi-name-fixes',default=str(ROOT/'config/poi-name-fixes.csv'))
p.add_argument('--poi-labels',default=str(ROOT/'config/poi-labels-bg.csv'),help='Bulgarian prefixes for stable generated names on nameless Garmin POIs')
@@ -272,9 +305,10 @@ def main():
folder=dest/'osmand-config';folder.mkdir(exist_ok=True)
poi_base=base_xml(args.poi_base,creator,'poi',dest/'upstream',args.offline)
rendering_base=base_xml(args.rendering_base,creator,'rendering',dest/'upstream',args.offline)
poi_cfg,render_cfg,summary=make_configs(poi_base,rendering_base,rows,folder,args.threshold,args.frequent_zoom,args.rare_zoom)
style,nicons=make_style(args.icons_config,folder,rows)
print('Indexed POI types:',summary['catalog_types'],'frequent:',summary['types_at_or_above_threshold'],'custom style icons:',nicons,flush=True)
route_styles=read_route_styles(args.trail_styles)
poi_cfg,render_cfg,summary=make_configs(poi_base,rendering_base,rows,folder,args.threshold,args.frequent_zoom,args.rare_zoom,route_styles)
style,nicons,nlines=make_style(args.icons_config,folder,rows,route_styles)
print('Indexed POI types:',summary['catalog_types'],'frequent:',summary['types_at_or_above_threshold'],'custom icons:',nicons,'colored route types:',nlines,flush=True)
if args.prepare_only:
print('PREPARED (no OBF generated). Files at:',dest)
return 0
@@ -299,7 +333,7 @@ def main():
'created_at_utc':dt.datetime.now(dt.timezone.utc).isoformat(),
'obf':str(built),'obf_bytes':built.stat().st_size,
'input_osm':str(osm),'poi_types':str(poi_cfg),'rendering_types':str(render_cfg),
'custom_style':str(style), 'custom_style_icon_rules':nicons,
'custom_style':str(style), 'custom_style_icon_rules':nicons, 'custom_route_rules':nlines,
'summary':summary
},ensure_ascii=False,indent=2)+'\n',encoding='utf-8')
return 0
+11 -6
View File
@@ -23,9 +23,13 @@ Options parse(int argc,char**argv){Options o;for(int i=1;i<argc;i++){std::string
if(o.input.empty())fail("--input required");if(o.output.empty()&&!o.inspect&&o.poiTypesOut.empty()&&o.poiManifest.empty()&&o.iconsDir.empty())fail("--output, --inspect or an inventory output required");if(!o.poiAdditions.empty()&&o.output.empty())fail("--poi-additions requires --output");if(o.jobs<1||o.jobs>64)fail("--jobs must be 1..64");if(o.examples<1||o.examples>20)fail("--poi-examples must be 1..20");if(o.clip&&(!o.bbox.valid()||o.bbox.w< -180||o.bbox.e>180||o.bbox.s< -90||o.bbox.n>90))fail("Invalid bbox");return o;}
Tags lineTags(int t,bool ext,const std::string&name){Tags v;tag(v,"garmin:type",code(t));tag(v,"garmin:feature",ext?"extended_polyline":"polyline");tag(v,"name",name);
if(ext){ // Physical trail identity not proven: preserve Garmin overlay, mark it as a hiking path geometry.
tag(v,"highway","path");tag(v,"foot","yes");tag(v,"trailblazed","yes");tag(v,"garmin:route_overlay","yes");
const auto it=gStyles.lines.find(t);if(it!=gStyles.lines.end()&&it->second.color)tag(v,"colour",hexColor(it->second.color));return v;
if(ext){ // TYP route overlay is graphical, NOT independently verified routable geometry.
tag(v,"bgm_route","type_"+code(t));tag(v,"garmin:route_overlay","yes");
const auto it=gStyles.lines.find(t);if(it!=gStyles.lines.end()){
if(it->second.color)tag(v,"colour",hexColor(it->second.color));
if(it->second.hasPattern())tag(v,"bgm:line_pattern","garmin_bitmap");
}
return v;
}
if(t<=0x0c){const char*klass=nullptr;
switch(t){case 0:klass="road";break;case 1:klass="motorway";break;case 2:klass="primary";break;case 3:klass="secondary";break;case 4:klass="tertiary";break;case 5:klass="unclassified";break;case 6:klass="residential";break;case 7:klass="service";break;case 8:case 9:case 11:klass="motorway_link";break;case 10:klass="track";break;case 12:klass="residential";break;}
@@ -44,7 +48,7 @@ Tags areaTags(int t,const std::string&name){Tags v;tag(v,"garmin:type",code(t));
case 0x05:tag(v,"amenity","parking");break;case 0x07:tag(v,"aeroway","aerodrome");break;
case 0x0b:tag(v,"amenity","hospital");break;case 0x0c:tag(v,"landuse","industrial");break;
case 0x13:tag(v,"building","yes");break;case 0x17:tag(v,"leisure","park");break;
case 0x18:tag(v,"leisure","golf_course");break;case 0x09:tag(v,"leisure","marina");break;
case 0x18:tag(v,"leisure","sports_centre");break;case 0x09:tag(v,"landuse","retail");break;
case 0x14:case 0x15:case 0x16:tag(v,"boundary","national_park");break;
case 0x28:case 0x32:tag(v,"natural","water");tag(v,"water","sea");break;
case 0x3c:case 0x3d:case 0x40:case 0x41:tag(v,"natural","water");break;
@@ -69,13 +73,14 @@ Tags poiTags(int t,const std::string&name){Tags v;tag(v,"garmin:type",code(t));t
else if(t==0x6407){tag(v,"tourism","picnic_site");}
else if(t==0x640d){tag(v,"aerialway","station");}
else if(t==0x6404||t==0x640b||t==0x641a||t==0x2c0b){tag(v,"amenity","place_of_worship");}
else if(t==0x6602||t==0x6608){tag(v,"tourism","viewpoint");}
else if(t==0x6602){tag(v,"tourism","viewpoint");}
else if(t==0x6608){tag(v,"tourism","hotel");}
else if(t==0x2800){tag(v,"place","locality");}
else if(t==0x6600){ // Geographic spot heights; don't misclassify elevations as villages.
try{size_t parsed=0;int n=std::stoi(name,&parsed);if(parsed==name.size()&&n>=0&&n<=8848)tag(v,"ele",std::to_string(n));}catch(...){}
}
else if(t==0x6614){tag(v,"garmin:marker","distance_or_index");}
else if(t==0x6500){tag(v,"man_made","water_works");}
else if(t==0x6500){tag(v,"man_made","water_intake");}
else if(t==0x6402&&name.find("Посетителски")!=std::string::npos){tag(v,"tourism","information");tag(v,"information","office");}
else if(t==0x6411){tag(v,"man_made","tower");}
// 0x6414 handled above as drinking_water: conflicting old water_well branch removed.
+3 -3
View File
@@ -14,13 +14,13 @@ class TestLocalDisplay(unittest.TestCase):
c=x['code'];self.assertEqual(r[c]['mode'],'replace',c)
self.assertTrue(names[c],c)
t=r[c]['tags']
self.assertTrue(any(a+'=' in t for a in ['amenity','shop','tourism','natural','man_made','leisure','historic','place','building','emergency','power','highway','waterway','sport','industrial']),c)
self.assertTrue(t,c) # BGMountains custom POI index handles non-standard types
self.assertNotIn('tags,,',t)
def test_key_places(self):
r={x['code']:x for x in load('config/poi-overrides-all-types.csv')}
self.assertIn('man_made=water_intake',r['0x6500']['tags'])
self.assertIn('bgm:synthetic_icon=yes',r['0x6500']['tags'])
self.assertIn('tourism=information',r['0x6500']['tags'])
self.assertNotIn('bgm:synthetic_icon=yes',r['0x6500']['tags'])
self.assertNotIn('tourism=information',r['0x6500']['tags'])
self.assertIn('tourism=viewpoint',r['0x6602']['tags'])
self.assertNotIn('bgm:synthetic_icon',r['0x6602']['tags'])
def test_all_legacy_codes_retained_for_review(self):
+8 -6
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
"""Audit whether IMG-derived POIs have both OSM display tags and names.
"""Audit IMG-derived POIs for custom indexability and truthfully report native semantic tags.
This measures converted OSM, NOT actual OsmAnd screen visibility nor .obf indexing.
Output inventory always includes Garmin codes and example coordinates.
@@ -23,18 +23,20 @@ def main():
if tags.get('garmin:feature')!='poi':el.clear();continue
code=tags.get('garmin:type','').lower();counts[code]+=1;overview['pois']+=1
name=tags.get('name','');kind=[f'{k}={tags[k]}' for k in CLASS_KEYS if k in tags]
if not kind:bad.append((code,name,el.get('lat'),el.get('lon'),'no_osm_semantic_tag'));overview['unclassified']+=1
if not kind:overview['needs_custom_style']+=1
else:overview['has_native_semantics']+=1
if not name:overview['nameless']+=1
if tags.get('bgm:generated_name')=='yes':stats[code]['generated_name']+=1;overview['generated_name']+=1
if tags.get('bgm:synthetic_icon')=='yes':stats[code]['synthetic_icon']+=1;overview['synthetic_icon']+=1
if not tags.get('bgm_poi'):overview['missing_raw_type_index_tag']+=1
else:overview['has_bgm_poi_tag']+=1
if len(samples[code])<args.samples:samples[code].append((el.get('lat'),el.get('lon'),name, '|'.join(kind)))
el.clear()
rows=[]
for code in sorted(counts,key=lambda x:(-counts[x],x)):
base=catalog.get(code,{})
row=dict(code=code,osm_poi_count=counts[code],nationwide_type_count=base.get('count',''),
icon_strategy=('synthetic' if stats[code]['synthetic_icon'] else 'native-osm'),
icon_strategy=('native+custom' if samples[code][0][3] else 'custom_style_required'),
synthetic_count=stats[code]['synthetic_icon'],generated_name_count=stats[code]['generated_name'],
legend=base.get('verified_legend_bg',''),review_status=base.get('review_status',''),
example_lat=samples[code][0][0],example_lon=samples[code][0][1],
@@ -44,11 +46,11 @@ def main():
path=Path(args.csv);path.parent.mkdir(parents=True,exist_ok=True)
with path.open('w',encoding='utf-8',newline='') as f:
if rows:w=csv.DictWriter(f,fieldnames=list(rows[0]));w.writeheader();w.writerows(rows)
summary=dict(status='PASS' if not bad and not overview['nameless'] and not overview['missing_raw_type_index_tag'] else 'FAIL',
summary=dict(status='PASS' if not overview['nameless'] and not overview['missing_raw_type_index_tag'] else 'FAIL',
counts=dict(overview),catalog_types=len(catalog),exported_types=len(counts),
note='Audit is for OSM tags only. A real .obf inspector comparison and OsmAnd visual inspection remain required.',
note='POIs without standard OSM categories are valid for this PRIVATE map because bgm_poi uses custom index and renderer. They require importing the style; this does not prove OBF persistence or screen visibility.',
errors=bad[:100],missing_types_from_catalog=sorted(set(counts)-set(catalog)))
Path(args.json).write_text(json.dumps(summary,ensure_ascii=False,indent=2)+'\n',encoding='utf-8')
print(json.dumps(summary,ensure_ascii=False,indent=2))
return 0 if summary['status']=='PASS' and not summary['missing_types_from_catalog'] else 0
return 0 if summary['status']=='PASS' and not summary['missing_types_from_catalog'] else 2
if __name__=='__main__':raise SystemExit(main())