feat(regions): open four more provinces for play

Dong Nai, Binh Duong, Thanh Hoa and Quang Nam join the tree, and Long An
gains Ben Luc and Can Giuoc, taking coverage from 5 provinces to 9 and the
panorama index from 425k locations to 493k.

A province outline is now simplified no more loosely than the leaves it is
the union of. It is not only drawn: the district assignment clips each
province's panoramas against it, and at the old tolerance the outline bulged
past its own districts, crediting every panorama in that band to a district
it does not sit in. That band held 571 panoramas across the tree, 2.53% of
Binh Duong's.

Unioning adjacent districts also leaves hairline sliver rings along shared
borders, some of only three points, which turf.simplify refuses to clean.
Those are dropped before the outline is simplified.
This commit is contained in:
tiennm99 committed 2026-09-04 15:20:13 +07:00
1 parent 6251ea5f4b
commit d1332cd689
91 files changed
+80524 -8184

No files matched your search

+3 -2
View File
@@ -17,8 +17,9 @@
### 2. Region Selection
- Choose anywhere on the region tree:
- **Vietnam** — draws from every covered province
- **A province** — Ha Noi, Ho Chi Minh, Da Nang, Lam Dong, Long An
- **A district or town** — 61 of them, expanded from their province
- **A province** — Ha Noi, Ho Chi Minh, Da Nang, Lam Dong, Long An, Dong Nai,
Binh Duong, Thanh Hoa, Quang Nam
- **A district or town** — 75 of them, expanded from their province
- Regions with no usable panoramas are listed but disabled, with the reason
shown. See the Coverage note in [project-overview.md](project-overview.md)
+5 -5
View File
@@ -6,7 +6,7 @@ it was taken. Built with Next.js 16, React 19 and Tailwind CSS 4.
## Key Characteristics
- **Nested regions**: one country, five provinces, 61 districts and towns. The
- **Nested regions**: one country, nine provinces, 75 districts and towns. The
tree is generated into `src/data/regions/` — see `src/lib/regions.js` for the
client-safe traversal API.
- **Rollup scoring**: a guess is credited to the district its panorama actually
@@ -40,13 +40,13 @@ Tau, which is not what people mean by the city. Two consequences to remember:
## Coverage
Five provinces — Ha Noi, Ho Chi Minh, Da Nang, Lam Dong, Long An — split into 61
districts and towns. Coverage is deliberately partial and will grow in future
releases. **None are planned at present.**
Nine provinces — Ha Noi, Ho Chi Minh, Da Nang, Lam Dong, Long An, Dong Nai,
Binh Duong, Thanh Hoa, Quang Nam — split into 75 districts and towns. Coverage
is deliberately partial and will grow in future releases.
Absent coverage has three distinct causes. Only one is a defect:
**Not yet added** — any province outside the five. Roadmap, not a bug. Adding one
**Not yet added** — any province outside the nine. Roadmap, not a bug. Adding one
is an entry in the `REGIONS` config of `scripts/build-region-boundaries.mjs`, a
boundary build, a panorama index build, a district assignment run, and a
database seed (`npm run data:seed`). No application code changes: every UI
@@ -0,0 +1,209 @@
# Research Report: Mapillary Coverage — Which Cities/Districts to Add Next
Conducted 2026-09-04 11:59 (+07). Method: direct probe of the Mapillary z14
vector tile API with the token in `.env`, counted inside real OSM boundaries.
No web search — coverage is a measurable fact, not a documented one.
## Executive Summary
**Add Dong Nai first.** Bien Hoa alone holds ~29,700 distinct 33m locations
across 153 cells — second only to Thu Duc (41,338) among everything already in
the game, and larger than every Hanoi district. Its neighbours Nhon Trach
(6,202), Vinh Cuu (1,377+), Long Thanh (1,341), Trang Bom (490) and Thong Nhat
(448) make Dong Nai a complete six-district province, ~39,500 locations, for
~610 tile requests.
**Then Binh Duong** (Di An 5,663 / Thu Dau Mot 3,554 / Ben Cat 3,389 / Thuan An
3,005 ≈ 15,600 locations in ~70 tiles — the cheapest coverage per request found)
**and two more Long An districts** (Ben Luc 4,277, Can Giuoc 4,203), which need
no new province node since LA already exists and is flagged
`partialCoverage: 'one town covered'`.
**Do not bother with**: Can Tho, Vinh, Thai Nguyen, Lao Cai, Quy Nhon, Ca Mau,
Phu Quoc, Ha Long, Tan An — all measured **zero** panoramas. Nha Trang (4
locations) and Phan Thiet (9, median capture 2019) are effectively zero too.
Vietnam's Mapillary pano coverage does not follow population; it follows a
handful of contributors around the HCMC industrial belt, Thanh Hoa and the
Mekong.
All 32 recommended queries resolve to a `class=boundary` OSM **relation**, which
is what `scripts/build-region-boundaries.mjs` requires — so nothing here is
blocked on an unresolvable boundary.
## Method
- Same source and filter as `scripts/build-pano-index.mjs`: z14
`mly1_public` tiles, `image` layer, `is_pano` only.
- Points counted only inside the OSM polygon (turf point-in-polygon), the same
polygon `build-region-boundaries.mjs` would fetch.
- **locations** = distinct 0.0003° (~33m) cells = what the index would actually
store. **cells** = distinct 0.01° (~1.1km) cells = the `counts.js` metric that
drives `playable`/`thin` (`MIN_PANOS 3`, `MIN_CELLS 3`, `THIN_CELLS 10`).
- Areas over 150 tiles were stride-sampled; those rows are marked and scaled.
- ~5,600 tile requests spent of the 50,000/day budget.
**Controls (method validation)** — probe vs. what the shipped index holds:
| Region | Probe locations | `counts.js` panos | Probe cells | `counts.js` cells |
|---|---|---|---|---|
| Duc Hoa (LA) | 11,721 | 11,717 | 107 | 106 |
| Hai Chau (DN) | 176 | 172 | 5 | 5 |
Within 0.04%. The numbers below are directly comparable to `counts.js`.
## Ranked Candidates
Playable = `panos >= 3 && cells >= 3`. Thin = fewer than 10 cells.
| Rank | Region | Locations (~33m) | Cells | Median capture | Tiles to build | Verdict |
|---|---|---|---|---|---|---|
| 1 | **Bien Hoa** (Dong Nai) | 29,667 | 153 | 2024 | 67 | strong |
| 2 | **Nhon Trach** (Dong Nai) | 6,202 | 61 | 2025 | 33 | strong |
| 3 | **Di An** (Binh Duong) | 5,663 | 30 | 2024 | 11 | strong |
| 4 | **Rach Gia** (Kien Giang) | 4,763 | 42 | 2024 | 34 | strong |
| 5 | **Ben Luc** (Long An) | 4,277 | 49 | 2024 | 76 | strong |
| 6 | **Can Giuoc** (Long An) | 4,203 | 44 | 2024 | 21 | strong |
| 7 | **Thu Dau Mot** (Binh Duong) | 3,554 | 20 | 2024 | 12 | strong |
| 8 | **Ben Cat** (Binh Duong) | 3,389 | 20 | 2016 | 38 | strong, but dated |
| 9 | **Thuan An** (Binh Duong) | 3,005 | 23 | 2024 | 9 | strong |
| 10 | **Thanh Hoa city** | 2,935 | 73 | 2025 | 63 | strong |
| 11 | **Hoi An** (Quang Nam) | 1,485 | 23 | 2026 | 33 | strong, freshest |
| 12 | **Viet Tri** (Phu Tho) | 1,407 | 33 | 2025 | 41 | strong |
| 13 | **Vinh Cuu** (Dong Nai) | 1,377 sampled, est. 5,400 | 54 | 2024 | 251 | strong |
| 14 | **Long Thanh** (Dong Nai) | 1,341 | 36 | 2025 | 102 | strong |
| 15 | **Vung Tau** | 922 | 17 | 2024 | 9 | good (undercount, see caveats) |
| 16 | **Ninh Binh** | 848 | 26 | 2024 | 20 | good |
| 17 | **Long Xuyen** (An Giang) | 847 | 32 | 2026 | 33 | good |
| 18 | **My Tho** (Tien Giang) | 820 | 34 | 2024 | 26 | good |
| 19 | **Duong Kinh** (Hai Phong) | 664 | 13 | 2024 | 13 | good |
| 20 | **Thuy Nguyen** (Hai Phong) | 629 | 18 | 2024 | 20 | good |
| 21 | **Chau Doc** (An Giang) | 589 | 29 | 2024 | 34 | good |
| 22 | **Vinh Long city** | 587 | 25 | 2024 | 19 | good |
| 23 | **Trang Bom** (Dong Nai) | 490 | 17 | 2024 | 82 | good |
| 24 | **Thong Nhat** (Dong Nai) | 448 | 14 | 2024 | 71 | good |
| 25 | **Sam Son** (Thanh Hoa) | 438 | 9 | 2025 | 21 | playable, thin |
| 26 | **Bac Ninh city** | 393 | 14 | 2025 | 29 | good |
| 27 | **Le Chan** (Hai Phong) | 320 | 8 | 2024 | 4 | playable, thin |
| 28 | **Buon Ma Thuot** (Dak Lak) | 293 | 19 | 2025 | 97 | good |
| 29 | **Quang Xuong** (Thanh Hoa) | 249 | 7 | 2025 | 53 | playable, thin |
| 30 | **Hai An** (Hai Phong) | 180 | 10 | 2024 | 15 | playable |
| 31 | **Pleiku** (Gia Lai) | 155 | 15 | 2025 | 75 | playable |
| 32 | **Hoang Hoa** (Thanh Hoa) | 149 | 5 | 2025 | 15 | playable, thin |
| 33 | **Dong Hoi** (Quang Binh) | 128 | 4 | 2023 | 50 | playable, thin |
| 34 | **Long Khanh** (Dong Nai) | 73 | 2 | 2024 | 57 | NOT playable (cells < 3) |
| 35 | **Hong Bang** (Hai Phong) | 62 | 2 | 2024 | 9 | NOT playable (cells < 3) |
For scale: `DN-HAICHAU` ships with 172 locations / 5 cells and is playable, so
everything down to rank 33 is already better than a district in the live game.
### Zero coverage — skip
Can Tho (incl. its Ninh Kieu core), Vinh, Thai Nguyen city, Lao Cai city, Quy
Nhon, Ca Mau, Phu Quoc, Ha Long, Bim Son, Tan An (Long An), Kien An and An Duong
(Hai Phong), Hue's Phu Xuan core. Nha Trang: 4 locations. Phan Thiet: 9, median
2019.
Province-wide sampled probes suggest scattered rural coverage exists in Nam Dinh
(est. 9,600), Hai Phong overall (est. 8,500), Bac Giang (est. 2,300) and Hue
(est. 2,300), but it is spread over thousands of km² of countryside — poor
guessing material and expensive to index. Not recommended.
## Recommended Rollout
### Phase 1 — Dong Nai (new province, ~39,500 locations, ~610 tiles)
Add to `REGIONS` in `scripts/build-region-boundaries.mjs`:
```js
// -- Dong Nai -------------------------------------------------------------
DNA: { name: 'Dong Nai', level: 'province', parent: 'VN', center: [10.9447, 106.8243] },
'DNA-BIENHOA': { name: 'Bien Hoa', level: 'district', parent: 'DNA', query: 'Thành phố Biên Hòa, Đồng Nai, Việt Nam' },
'DNA-NHONTRACH': { name: 'Nhon Trach', level: 'district', parent: 'DNA', query: 'Nhơn Trạch, Đồng Nai, Việt Nam' },
'DNA-LONGTHANH': { name: 'Long Thanh', level: 'district', parent: 'DNA', query: 'Long Thành, Đồng Nai, Việt Nam' },
'DNA-TRANGBOM': { name: 'Trang Bom', level: 'district', parent: 'DNA', query: 'Trảng Bom, Đồng Nai, Việt Nam' },
'DNA-VINHCUU': { name: 'Vinh Cuu', level: 'district', parent: 'DNA', query: 'Vĩnh Cửu, Đồng Nai, Việt Nam' },
'DNA-THONGNHAT': { name: 'Thong Nhat', level: 'district', parent: 'DNA', query: 'Thống Nhất, Đồng Nai, Việt Nam' },
```
Code `DN` is taken by Da Nang — hence `DNA`. Skip Long Khanh (2 cells, not
playable).
### Phase 2 — Binh Duong (new province, ~15,600 locations, ~70 tiles)
Best coverage-per-request in the whole survey.
```js
BD: { name: 'Binh Duong', level: 'province', parent: 'VN', center: [10.9804, 106.6519] },
'BD-DIAN': { name: 'Di An', level: 'district', parent: 'BD', query: 'Dĩ An, Việt Nam' },
'BD-THUANAN': { name: 'Thuan An', level: 'district', parent: 'BD', query: 'Thuận An, Việt Nam' },
'BD-THUDAUMOT': { name: 'Thu Dau Mot', level: 'district', parent: 'BD', query: 'Thủ Dầu Một, Việt Nam' },
'BD-BENCAT': { name: 'Ben Cat', level: 'district', parent: 'BD', query: 'Bến Cát, Việt Nam' },
```
Ben Cat's median capture is 2016 — decade-old imagery guesses worse. Include it,
or drop it and keep three fresh districts.
### Phase 3 — extend Long An (~8,500 locations, ~97 tiles)
`LA` already exists with one leaf. Add two, and drop its
`partialCoverage: 'one town covered'` note:
```js
'LA-BENLUC': { name: 'Ben Luc', level: 'district', parent: 'LA', query: 'Bến Lức, Việt Nam' },
'LA-CANGIUOC': { name: 'Can Giuoc', level: 'district', parent: 'LA', query: 'Cần Giuộc, Việt Nam' },
```
Existing leaf `DH` keeps its bare code for leaderboard-key compatibility; new
leaves should use the prefixed form.
### Phase 4 — single-city provinces, cheap and fresh
Same shape as the existing `LD`/`DL` one-town pattern. In value order: Rach Gia
(Kien Giang, 4,763), Thanh Hoa city + Sam Son (2,935 + 438), Hoi An (1,485,
median 2026 — the freshest imagery found), Viet Tri (1,407), Ninh Binh (848),
Long Xuyen + Chau Doc (An Giang, 1,436 together), My Tho (820), Vung Tau (922),
Vinh Long (587), Bac Ninh (393), Buon Ma Thuot (293).
### Build sequence (unchanged)
```
node scripts/build-region-boundaries.mjs DNA BD LA
node scripts/build-pano-index.mjs DNA BD LA
node scripts/assign-pano-districts.mjs
npm run data:seed
npm test
```
Phases 1-3 together cost ~780 tile requests, ~1.5% of the daily budget, and add
~63,600 locations to an index that currently holds 424,617 — a 15% increase.
## Caveats
- Several boundaries resolved to a smaller polygon than the pre-2025 district
(Thu Dau Mot 16km² vs ~118, Thuan An 16 vs ~84, Di An 21 vs ~60, Nhon Trach
109 vs ~410, Vung Tau 15 vs ~141, Can Giuoc 61 vs ~210). Those counts are
**undercounts**; the real build will find the same or more.
- The probe took the first polygon match; `build-region-boundaries.mjs` takes
the first `class=boundary` match. All 32 recommended queries have such a match
(verified), but for the undercounted rows above the polygon may differ
slightly from what was measured.
- Sampled rows (Vinh Cuu, and the province-wide screens) are estimates scaled by
tiles fetched vs tiles in area; density is not uniform, so treat them as
order-of-magnitude.
- Vietnam's 2025 merger deleted many city relations from OSM. Bare-name queries
(`Dĩ An, Việt Nam`) hit `boundary/historic` relations where the
`Thành phố ...` form now misses entirely. That is why several first-round
probes falsely reported zero.
- Scratch probe scripts live in the gitignored `data-build/probe/`; nothing in
`src/` or `scripts/` was touched.
## Unresolved Questions
1. Ben Cat's imagery is from 2016 — is decade-old streetscape acceptable, or
should a median-capture floor (say 2020) gate what gets added?
2. Bien Hoa at ~29,700 locations would be the second-largest region in the game.
Is one dominant district fine, or should the picker weight regions?
3. New leaf codes: prefixed (`LA-BENLUC`) or bare (`DH` style)? Existing bare
codes exist only for leaderboard-key compatibility; confirm before adding.
4. `DN-CAMLE` and `DN-HOAVANG` still read 0 panos, and `TPHCM-CUCHI` has no OSM
relation. Re-check them in the same pass, or leave as is?
+90 -8
View File
@@ -38,10 +38,16 @@ const REQUEST_GAP_MS = 1100;
// Leaves are simplified tightly: at district scale a loose tolerance opens gaps
// along shared borders, and scripts/assign-pano-districts.mjs has to decide
// which side of those borders every panorama falls on. Province outlines are
// only ever drawn at city zoom, so they stay coarse.
// which side of those borders every panorama falls on.
//
// A province outline is simplified no more loosely than the leaves it is the
// union of, because it is not only drawn: assign-pano-districts.mjs clips each
// province's panoramas against it before handing them to the leaves. At a
// coarser tolerance the outline bulges past its own districts, and every
// panorama in that band survives the clip but lands in no district -- credited
// by proximity to a district it does not sit in. Binh Duong, small and densely
// covered along its edges, put 2.53% of its panoramas in that band at ~55m.
const LEAF_TOLERANCE = 0.0001; // ~11m
const PROVINCE_TOLERANCE = 0.0005; // ~55m
// The region tree. One entry per node.
//
@@ -136,13 +142,50 @@ const REGIONS = {
'DN-HOAVANG': { name: 'Hoa Vang', level: 'district', parent: 'DN', query: 'Huyện Hòa Vang, Đà Nẵng, Việt Nam' },
// -- Lam Dong / Long An ---------------------------------------------------
// One town each. The leaf codes stay bare because their leaderboard keys
// already exist under those names.
// DL and DH keep bare codes because their leaderboard keys already exist
// under those names. Every leaf added since is prefixed with its province.
LD: { name: 'Lam Dong', level: 'province', parent: 'VN', partialCoverage: 'one town covered', legacyBbox: [108.31521, 11.80798, 108.5944, 12.00855] },
DL: { name: 'Da Lat', level: 'district', parent: 'LD', query: 'Thành phố Đà Lạt, Việt Nam', center: [11.9404, 108.4583] },
LA: { name: 'Long An', level: 'province', parent: 'VN', partialCoverage: 'one town covered', legacyBbox: [106.27082, 10.7409, 106.53287, 11.02578] },
// Long An covers three of its districts now, so legacyBbox is the whole
// pre-2025 province rather than the extent of Duc Hoa alone -- a leaf
// lookup is rejected when its centre falls outside the parent box, and
// Ben Luc and Can Giuoc both sit well south of Duc Hoa.
LA: { name: 'Long An', level: 'province', parent: 'VN', partialCoverage: 'three districts covered', legacyBbox: [105.45, 10.35, 106.85, 11.1] },
DH: { name: 'Duc Hoa', level: 'district', parent: 'LA', query: 'Đức Hòa, Việt Nam', center: [10.8888, 106.3825] },
'LA-BENLUC': { name: 'Ben Luc', level: 'district', parent: 'LA', query: 'Bến Lức, Việt Nam' },
'LA-CANGIUOC': { name: 'Can Giuoc', level: 'district', parent: 'LA', query: 'Cần Giuộc, Việt Nam' },
// -- Dong Nai -------------------------------------------------------------
// Code DNA, not DN: Da Nang holds that one. Long Khanh is left out -- its
// panoramas fall in only two 1.1km cells, one short of playable.
DNA: { name: 'Dong Nai', level: 'province', parent: 'VN', partialCoverage: 'six districts covered', legacyBbox: [106.6, 10.45, 107.85, 11.6] },
'DNA-BIENHOA': { name: 'Bien Hoa', level: 'district', parent: 'DNA', query: 'Thành phố Biên Hòa, Đồng Nai, Việt Nam' },
'DNA-NHONTRACH': { name: 'Nhon Trach', level: 'district', parent: 'DNA', query: 'Nhơn Trạch, Đồng Nai, Việt Nam' },
'DNA-LONGTHANH': { name: 'Long Thanh', level: 'district', parent: 'DNA', query: 'Long Thành, Đồng Nai, Việt Nam' },
'DNA-TRANGBOM': { name: 'Trang Bom', level: 'district', parent: 'DNA', query: 'Trảng Bom, Đồng Nai, Việt Nam' },
'DNA-VINHCUU': { name: 'Vinh Cuu', level: 'district', parent: 'DNA', query: 'Vĩnh Cửu, Đồng Nai, Việt Nam' },
'DNA-THONGNHAT': { name: 'Thong Nhat', level: 'district', parent: 'DNA', query: 'Thống Nhất, Đồng Nai, Việt Nam' },
// -- Binh Duong -----------------------------------------------------------
// Ben Cat is deliberately absent despite having coverage: its imagery was
// captured in 2016, and a decade-old streetscape makes a worse round than
// no round at all.
BD: { name: 'Binh Duong', level: 'province', parent: 'VN', partialCoverage: 'three cities covered', legacyBbox: [106.35, 10.85, 107.2, 11.85] },
'BD-DIAN': { name: 'Di An', level: 'district', parent: 'BD', query: 'Dĩ An, Việt Nam' },
'BD-THUANAN': { name: 'Thuan An', level: 'district', parent: 'BD', query: 'Thuận An, Việt Nam' },
'BD-THUDAUMOT': { name: 'Thu Dau Mot', level: 'district', parent: 'BD', query: 'Thủ Dầu Một, Việt Nam' },
// -- Thanh Hoa / Quang Nam ------------------------------------------------
// Two provinces carried by a couple of towns each, the same shape as Lam
// Dong. Both are here for variety: everything else added alongside them is
// the industrial ring around Ho Chi Minh City, which all looks alike.
TH: { name: 'Thanh Hoa', level: 'province', parent: 'VN', partialCoverage: 'two towns covered', legacyBbox: [104.35, 19.3, 106.1, 20.65] },
'TH-THANHHOA': { name: 'Thanh Hoa City', level: 'district', parent: 'TH', query: 'Thành phố Thanh Hóa, Thanh Hóa, Việt Nam' },
'TH-SAMSON': { name: 'Sam Son', level: 'district', parent: 'TH', query: 'Sầm Sơn, Thanh Hóa, Việt Nam' },
QNA: { name: 'Quang Nam', level: 'province', parent: 'VN', partialCoverage: 'one town covered', legacyBbox: [107.1, 14.9, 108.75, 16.2] },
'QNA-HOIAN': { name: 'Hoi An', level: 'district', parent: 'QNA', query: 'Hội An, Việt Nam' },
};
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
@@ -317,6 +360,45 @@ async function buildLeaf(code) {
* @param {string} code Province code.
* @returns {number} Children that could not be included.
*/
// Unioning adjacent districts leaves hairline slivers wherever two boundaries
// were digitised from slightly different surveys. They are artifacts of the
// merge rather than geography, and some come out as rings of three points,
// which turf.simplify refuses to clean ("invalid polygon, fewer than 4
// points"). Anything under this area is one of those, so it is dropped before
// the outline is simplified. The smallest real part in the tree is two orders
// of magnitude larger.
const SLIVER_KM2 = 0.05;
/**
* Drop sliver parts and rings left by a union.
* @param {Object} feature Unioned polygon or multipolygon feature.
* @returns {Object} Feature with only real parts left.
*/
function dropSlivers(feature) {
const isMulti = feature.geometry.type === 'MultiPolygon';
const polygons = isMulti ? feature.geometry.coordinates : [feature.geometry.coordinates];
const kept = polygons
// A hole has to enclose something real to be a hole; the union leaves
// dozens of four-point ones along every shared border.
.map((rings) => rings.filter((ring, index) => index === 0 || isReal(ring)))
.filter((rings) => isReal(rings[0]));
if (kept.length === 0) return feature;
return kept.length === 1
? turf.polygon(kept[0], feature.properties)
: turf.multiPolygon(kept, feature.properties);
}
/**
* Whether a ring encloses more than a sliver.
* @param {number[][]} ring Closed ring.
* @returns {boolean} True when it is worth keeping.
*/
function isReal(ring) {
return ring.length >= 4 && turf.area(turf.polygon([ring])) / 1e6 >= SLIVER_KM2;
}
function buildProvince(code) {
const children = childrenOf(code);
const resolved = children.filter((child) => existsSync(`${OUT_DIR}/${fileFor(child)}`));
@@ -339,8 +421,8 @@ function buildProvince(code) {
for (const feature of features.slice(1)) {
merged = turf.union(turf.featureCollection([merged, feature]));
}
geometry = turf.simplify(merged, {
tolerance: PROVINCE_TOLERANCE,
geometry = turf.simplify(dropSlivers(merged), {
tolerance: LEAF_TOLERANCE,
highQuality: true,
}).geometry;
}
+522
View File
@@ -0,0 +1,522 @@
{
"type": "Feature",
"properties": {
"code": "BD-DIAN",
"name": "Di An",
"level": "district",
"parent": "BD",
"basis": "pre-2025-merger extent, from OSM boundary/historic relations",
"areaKm2": 21.4,
"bbox": [
106.73418,
10.86348,
106.79462,
10.93726
],
"center": [
10.90191,
106.75607
],
"generatedAt": "2026-09-04T08:18:21.994Z",
"osm": "relation/8448992"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
106.7341768,
10.8805112
],
[
106.7353749,
10.8802261
],
[
106.7360653,
10.8796048
],
[
106.7366584,
10.8806
],
[
106.7384029,
10.8794311
],
[
106.7391056,
10.8800758
],
[
106.7396693,
10.8809044
],
[
106.7403898,
10.8807626
],
[
106.7411417,
10.8814406
],
[
106.7432901,
10.8804375
],
[
106.7435357,
10.8809347
],
[
106.7437697,
10.8807094
],
[
106.7449812,
10.8816265
],
[
106.7456581,
10.8807856
],
[
106.744687,
10.8800774
],
[
106.7471969,
10.8773867
],
[
106.7483768,
10.8782166
],
[
106.749396,
10.8767632
],
[
106.7503719,
10.8772949
],
[
106.751339,
10.8754629
],
[
106.7464425,
10.8738789
],
[
106.7470408,
10.872075
],
[
106.7459858,
10.8717248
],
[
106.747341,
10.8694849
],
[
106.747918,
10.8692233
],
[
106.7479409,
10.8673159
],
[
106.7487055,
10.8656559
],
[
106.7490898,
10.8658042
],
[
106.7500353,
10.8642951
],
[
106.7502574,
10.864407
],
[
106.7505076,
10.8640323
],
[
106.7512102,
10.8644268
],
[
106.7515679,
10.8638639
],
[
106.7516204,
10.8634757
],
[
106.7524971,
10.863786
],
[
106.7528282,
10.8644404
],
[
106.7537465,
10.8651952
],
[
106.7535757,
10.8657096
],
[
106.7549172,
10.8664007
],
[
106.7560405,
10.8663954
],
[
106.7575009,
10.8670868
],
[
106.7583481,
10.8671125
],
[
106.7595389,
10.8668755
],
[
106.7610992,
10.8672488
],
[
106.7622395,
10.8672623
],
[
106.7631743,
10.8689733
],
[
106.7632849,
10.8699203
],
[
106.7628632,
10.8701772
],
[
106.7622139,
10.8710848
],
[
106.7603765,
10.8723815
],
[
106.7617939,
10.8743899
],
[
106.7612713,
10.8745629
],
[
106.76134,
10.8748582
],
[
106.7618984,
10.8755415
],
[
106.7614269,
10.8785209
],
[
106.7619415,
10.8787059
],
[
106.7605209,
10.8812602
],
[
106.7612073,
10.8820412
],
[
106.7635609,
10.883864
],
[
106.7640119,
10.8849425
],
[
106.7645467,
10.8848594
],
[
106.764737,
10.8863171
],
[
106.7649905,
10.8866611
],
[
106.7652788,
10.8876148
],
[
106.7660192,
10.8884548
],
[
106.7668916,
10.8915511
],
[
106.7676681,
10.8916337
],
[
106.7672646,
10.8925065
],
[
106.7684183,
10.8922433
],
[
106.7684209,
10.8940402
],
[
106.769114,
10.8940297
],
[
106.7691189,
10.8947783
],
[
106.7687995,
10.8951752
],
[
106.7687803,
10.8961326
],
[
106.7694766,
10.8985429
],
[
106.7693579,
10.898588
],
[
106.7694951,
10.8996786
],
[
106.7690657,
10.9006336
],
[
106.7702731,
10.9013278
],
[
106.7707496,
10.9023349
],
[
106.7722517,
10.9017811
],
[
106.7723164,
10.9021302
],
[
106.7724933,
10.9020941
],
[
106.7728905,
10.9027572
],
[
106.773187,
10.9046834
],
[
106.7769478,
10.9050468
],
[
106.7781427,
10.9048901
],
[
106.7786377,
10.9046603
],
[
106.7823726,
10.904624
],
[
106.7827147,
10.9036736
],
[
106.786809,
10.9029465
],
[
106.7868544,
10.9034443
],
[
106.7895691,
10.9037535
],
[
106.7911467,
10.9048952
],
[
106.7928977,
10.9054449
],
[
106.7930396,
10.9058437
],
[
106.7936361,
10.9056544
],
[
106.7939401,
10.9057814
],
[
106.7943623,
10.9056657
],
[
106.7946162,
10.9065161
],
[
106.783114,
10.9099945
],
[
106.7809427,
10.9116953
],
[
106.7782001,
10.9130906
],
[
106.7692037,
10.9156158
],
[
106.7685646,
10.9159922
],
[
106.7684528,
10.9190709
],
[
106.7675334,
10.9210985
],
[
106.7664591,
10.9223568
],
[
106.7651412,
10.9249683
],
[
106.7560161,
10.9295608
],
[
106.7507001,
10.9372637
],
[
106.7467395,
10.9346945
],
[
106.7471453,
10.9341056
],
[
106.7463945,
10.9341165
],
[
106.7448573,
10.9333578
],
[
106.745123,
10.9325688
],
[
106.7431445,
10.932169
],
[
106.7431316,
10.9318766
],
[
106.7421014,
10.9318818
],
[
106.7397603,
10.8903818
],
[
106.7393762,
10.8893058
],
[
106.7368702,
10.8848386
],
[
106.7341768,
10.8805112
]
]
]
}
}
+510
View File
@@ -0,0 +1,510 @@
{
"type": "Feature",
"properties": {
"code": "BD-THUANAN",
"name": "Thuan An",
"level": "district",
"parent": "BD",
"basis": "pre-2025-merger extent, from OSM boundary/historic relations",
"areaKm2": 16.2,
"bbox": [
106.6502,
10.9208,
106.7073,
10.9636
],
"center": [
10.9418,
106.67865
],
"generatedAt": "2026-09-04T08:18:23.874Z",
"osm": "relation/13470588"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
106.6502,
10.9362
],
[
106.6504,
10.93448
],
[
106.6508,
10.93312
],
[
106.6525,
10.93027
],
[
106.6534,
10.92909
],
[
106.6572929,
10.9258852
],
[
106.6615605,
10.9232574
],
[
106.6639035,
10.9221742
],
[
106.6678204,
10.920909
],
[
106.6689416,
10.9208007
],
[
106.6701062,
10.9208999
],
[
106.678145,
10.9233694
],
[
106.6804494,
10.9235207
],
[
106.6802602,
10.9253921
],
[
106.6803632,
10.9258346
],
[
106.6806507,
10.9262138
],
[
106.6817236,
10.9269933
],
[
106.6818137,
10.9276886
],
[
106.6816635,
10.9287252
],
[
106.6820078,
10.9299733
],
[
106.6837535,
10.9289398
],
[
106.684507,
10.930771
],
[
106.6848282,
10.9307161
],
[
106.6859272,
10.9321151
],
[
106.6879421,
10.9336763
],
[
106.6889446,
10.9356994
],
[
106.6894453,
10.9358007
],
[
106.6891692,
10.9362417
],
[
106.689347,
10.9366202
],
[
106.6921975,
10.9391471
],
[
106.6939526,
10.938126
],
[
106.6951528,
10.9393742
],
[
106.6983049,
10.9385845
],
[
106.7023308,
10.9368893
],
[
106.7029136,
10.936983
],
[
106.7029131,
10.9374278
],
[
106.704071,
10.939484
],
[
106.7047215,
10.9399272
],
[
106.7045863,
10.9400326
],
[
106.705396,
10.9410859
],
[
106.7061422,
10.9412373
],
[
106.7065393,
10.9442678
],
[
106.7064999,
10.945285
],
[
106.7062513,
10.9452755
],
[
106.7062638,
10.9468474
],
[
106.7072993,
10.9470288
],
[
106.7068654,
10.9488045
],
[
106.7061101,
10.9506523
],
[
106.7049049,
10.9508832
],
[
106.7039919,
10.9513482
],
[
106.7025042,
10.9516024
],
[
106.6999701,
10.9515069
],
[
106.700065,
10.9519641
],
[
106.7006921,
10.9528304
],
[
106.699439,
10.9536488
],
[
106.7016542,
10.9556867
],
[
106.6986223,
10.9586318
],
[
106.6962018,
10.9603108
],
[
106.6892607,
10.9636049
],
[
106.686103,
10.9608946
],
[
106.6856309,
10.9600371
],
[
106.6817521,
10.9573098
],
[
106.6805619,
10.9598448
],
[
106.6800463,
10.9614635
],
[
106.6781473,
10.9606129
],
[
106.6772849,
10.9598625
],
[
106.6750145,
10.9591988
],
[
106.6750279,
10.9589855
],
[
106.6737834,
10.9590592
],
[
106.6737941,
10.9588012
],
[
106.6728446,
10.9585273
],
[
106.6730618,
10.957761
],
[
106.6719808,
10.9572096
],
[
106.6723001,
10.9563522
],
[
106.6719219,
10.9561758
],
[
106.6718522,
10.9563733
],
[
106.671423,
10.9562311
],
[
106.6715491,
10.9558492
],
[
106.6696718,
10.9549367
],
[
106.6691082,
10.9544035
],
[
106.66955,
10.9540007
],
[
106.6699317,
10.9532528
],
[
106.6678305,
10.9520079
],
[
106.6672708,
10.9520624
],
[
106.6663445,
10.9526524
],
[
106.6658918,
10.9510288
],
[
106.6664348,
10.9505317
],
[
106.6678248,
10.9498416
],
[
106.6684367,
10.9482744
],
[
106.6701104,
10.9469431
],
[
106.6681962,
10.943853
],
[
106.6677121,
10.9433286
],
[
106.6672448,
10.9432958
],
[
106.6669324,
10.943528
],
[
106.6666608,
10.9442887
],
[
106.6664791,
10.9444116
],
[
106.6661765,
10.9443446
],
[
106.6656424,
10.9436399
],
[
106.6652084,
10.9435908
],
[
106.6648412,
10.943853
],
[
106.6644239,
10.9456229
],
[
106.663606,
10.9466717
],
[
106.6617199,
10.9464095
],
[
106.6609521,
10.9461473
],
[
106.6605515,
10.9456393
],
[
106.6600007,
10.9439841
],
[
106.659116,
10.9428861
],
[
106.6580645,
10.9400018
],
[
106.6574469,
10.9397232
],
[
106.656412,
10.940264
],
[
106.6556943,
10.9403623
],
[
106.6546427,
10.9400837
],
[
106.654142,
10.9401165
],
[
106.6533909,
10.9405918
],
[
106.6529466,
10.9411258
],
[
106.6525994,
10.9419639
],
[
106.6516,
10.94217
],
[
106.6504,
10.93846
],
[
106.6502,
10.93742
],
[
106.6502,
10.9362
]
]
]
}
}
+518
View File
@@ -0,0 +1,518 @@
{
"type": "Feature",
"properties": {
"code": "BD-THUDAUMOT",
"name": "Thu Dau Mot",
"level": "district",
"parent": "BD",
"basis": "pre-2025-merger extent, from OSM boundary/historic relations",
"areaKm2": 15.6,
"bbox": [
106.6298,
10.93972,
106.68926,
10.99723
],
"center": [
10.9701,
106.6585
],
"generatedAt": "2026-09-04T08:18:25.774Z",
"osm": "relation/8448188"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
106.6298032,
10.9822892
],
[
106.6300323,
10.9817609
],
[
106.6305985,
10.9813545
],
[
106.6302207,
10.980452
],
[
106.6304247,
10.9785269
],
[
106.6337022,
10.977713
],
[
106.6360022,
10.977443
],
[
106.6374022,
10.977443
],
[
106.6386022,
10.977983
],
[
106.6415022,
10.979913
],
[
106.6431022,
10.980673
],
[
106.6459,
10.9813
],
[
106.6475,
10.98096
],
[
106.6486,
10.98004
],
[
106.6492,
10.97888
],
[
106.6502,
10.97444
],
[
106.6499884,
10.9723419
],
[
106.6492,
10.96968
],
[
106.6488,
10.96706
],
[
106.6489,
10.96449
],
[
106.6496,
10.96138
],
[
106.6518,
10.95474
],
[
106.6521,
10.95353
],
[
106.6524,
10.95096
],
[
106.6525,
10.94943
],
[
106.6524,
10.9472
],
[
106.6516,
10.94217
],
[
106.6525994,
10.9419639
],
[
106.6529466,
10.9411258
],
[
106.6533909,
10.9405918
],
[
106.654142,
10.9401165
],
[
106.6546427,
10.9400837
],
[
106.6556943,
10.9403623
],
[
106.656412,
10.940264
],
[
106.6574469,
10.9397232
],
[
106.6580645,
10.9400018
],
[
106.659116,
10.9428861
],
[
106.6600007,
10.9439841
],
[
106.6605515,
10.9456393
],
[
106.6609521,
10.9461473
],
[
106.6617199,
10.9464095
],
[
106.663606,
10.9466717
],
[
106.6644239,
10.9456229
],
[
106.6648412,
10.943853
],
[
106.6652084,
10.9435908
],
[
106.6656424,
10.9436399
],
[
106.6661765,
10.9443446
],
[
106.6664791,
10.9444116
],
[
106.6666608,
10.9442887
],
[
106.6669324,
10.943528
],
[
106.6672448,
10.9432958
],
[
106.6677121,
10.9433286
],
[
106.6681962,
10.943853
],
[
106.6701104,
10.9469431
],
[
106.6684367,
10.9482744
],
[
106.6678248,
10.9498416
],
[
106.6664348,
10.9505317
],
[
106.6658918,
10.9510288
],
[
106.6663445,
10.9526524
],
[
106.6672708,
10.9520624
],
[
106.6678305,
10.9520079
],
[
106.6699317,
10.9532528
],
[
106.66955,
10.9540007
],
[
106.6691082,
10.9544035
],
[
106.6696718,
10.9549367
],
[
106.6715491,
10.9558492
],
[
106.671423,
10.9562311
],
[
106.6718522,
10.9563733
],
[
106.6719219,
10.9561758
],
[
106.6723001,
10.9563522
],
[
106.6719808,
10.9572096
],
[
106.6730618,
10.957761
],
[
106.6728446,
10.9585273
],
[
106.6737941,
10.9588012
],
[
106.6737834,
10.9590592
],
[
106.6750279,
10.9589855
],
[
106.6750145,
10.9591988
],
[
106.6772849,
10.9598625
],
[
106.6781473,
10.9606129
],
[
106.6800463,
10.9614635
],
[
106.6805619,
10.9598448
],
[
106.6817521,
10.9573098
],
[
106.6856309,
10.9600371
],
[
106.686103,
10.9608946
],
[
106.6892607,
10.9636049
],
[
106.6815189,
10.9672355
],
[
106.6754919,
10.9706402
],
[
106.6721901,
10.9722399
],
[
106.6710515,
10.9730759
],
[
106.6703094,
10.9742764
],
[
106.6671288,
10.9809148
],
[
106.6656724,
10.9859466
],
[
106.6634488,
10.9903859
],
[
106.6625981,
10.9914295
],
[
106.6611224,
10.9921717
],
[
106.6568807,
10.9926245
],
[
106.6559413,
10.9928846
],
[
106.648752,
10.9972336
],
[
106.6495565,
10.9963669
],
[
106.6491086,
10.9954754
],
[
106.6489721,
10.9945275
],
[
106.6484258,
10.9941432
],
[
106.6485954,
10.9938331
],
[
106.6482171,
10.9936313
],
[
106.6482326,
10.9933085
],
[
106.647727,
10.993007
],
[
106.6475219,
10.9933849
],
[
106.6466689,
10.9932506
],
[
106.6465884,
10.9929636
],
[
106.64575,
10.9926694
],
[
106.6441932,
10.9926529
],
[
106.6441798,
10.9900804
],
[
106.6424912,
10.9899595
],
[
106.6406125,
10.9893906
],
[
106.6394999,
10.9893236
],
[
106.6378283,
10.9894893
],
[
106.6362043,
10.990112
],
[
106.6346714,
10.9901436
],
[
106.6345471,
10.9880254
],
[
106.6315067,
10.9860566
],
[
106.6307219,
10.9846761
],
[
106.6298032,
10.9822892
]
]
]
}
}
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -17,7 +17,7 @@
16.01409,
108.19606
],
"generatedAt": "2026-08-30T07:35:16.948Z",
"generatedAt": "2026-09-04T08:17:54.407Z",
"osm": "relation/19403875"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
16.05669,
108.21143
],
"generatedAt": "2026-08-30T07:35:08.257Z",
"generatedAt": "2026-09-04T08:17:44.961Z",
"osm": "relation/19403876"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
16.06583,
108.01436
],
"generatedAt": "2026-08-30T07:35:20.035Z",
"generatedAt": "2026-09-04T08:17:58.301Z",
"osm": "relation/7053087"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
16.13388,
108.14835
],
"generatedAt": "2026-08-30T07:35:15.060Z",
"generatedAt": "2026-09-04T08:17:52.526Z",
"osm": "relation/19403874"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
15.99755,
108.25003
],
"generatedAt": "2026-08-30T07:35:13.283Z",
"generatedAt": "2026-09-04T08:17:50.165Z",
"osm": "relation/19403879"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
16.11094,
108.26514
],
"generatedAt": "2026-08-30T07:35:11.759Z",
"generatedAt": "2026-09-04T08:17:48.700Z",
"osm": "relation/19403877"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
16.06315,
108.19039
],
"generatedAt": "2026-08-30T07:35:09.742Z",
"generatedAt": "2026-09-04T08:17:46.845Z",
"osm": "relation/19403878"
},
"geometry": {
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+910
View File
@@ -0,0 +1,910 @@
{
"type": "Feature",
"properties": {
"code": "DNA-NHONTRACH",
"name": "Nhon Trach",
"level": "district",
"parent": "DNA",
"basis": "pre-2025-merger extent, from OSM boundary/historic relations",
"areaKm2": 108.5,
"bbox": [
106.82559,
10.68785,
106.96365,
10.78522
],
"center": [
10.73706,
106.89264
],
"generatedAt": "2026-09-04T08:18:10.191Z",
"osm": "relation/9806927"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
106.8255932,
10.7055101
],
[
106.8347017,
10.7048368
],
[
106.8407457,
10.7040514
],
[
106.8429409,
10.704073
],
[
106.8429985,
10.6981789
],
[
106.8475386,
10.69817
],
[
106.8475432,
10.6961888
],
[
106.8494944,
10.6964815
],
[
106.8506123,
10.6958757
],
[
106.8508729,
10.6963066
],
[
106.8531477,
10.6948249
],
[
106.8543718,
10.6937543
],
[
106.854535,
10.692212
],
[
106.8560392,
10.6905561
],
[
106.8563366,
10.690902
],
[
106.8570406,
10.6912658
],
[
106.8573744,
10.6908961
],
[
106.8584058,
10.6916905
],
[
106.8587511,
10.6913705
],
[
106.8609196,
10.6939984
],
[
106.8619378,
10.6967927
],
[
106.8670935,
10.6978911
],
[
106.8694682,
10.7004064
],
[
106.869579,
10.704183
],
[
106.8777171,
10.7041716
],
[
106.878094,
10.7047042
],
[
106.8772686,
10.705011
],
[
106.878393,
10.7062408
],
[
106.879003,
10.7074736
],
[
106.8802516,
10.7073335
],
[
106.8820932,
10.7078404
],
[
106.8822753,
10.7071367
],
[
106.8828458,
10.707262
],
[
106.8830522,
10.7068207
],
[
106.883389,
10.7050048
],
[
106.8839868,
10.7049452
],
[
106.8843862,
10.7040463
],
[
106.8879571,
10.7055195
],
[
106.8977987,
10.6924737
],
[
106.8990522,
10.6905109
],
[
106.8987437,
10.6902804
],
[
106.9001239,
10.6878485
],
[
106.9018642,
10.6899172
],
[
106.9075387,
10.6944133
],
[
106.9206868,
10.6912735
],
[
106.9208841,
10.6917312
],
[
106.9218611,
10.6913213
],
[
106.9253403,
10.6965687
],
[
106.9252585,
10.6969306
],
[
106.9362576,
10.6994722
],
[
106.9341736,
10.7083028
],
[
106.9386785,
10.7093762
],
[
106.9379361,
10.7124442
],
[
106.9423001,
10.7134732
],
[
106.941319,
10.717527
],
[
106.9457928,
10.71868
],
[
106.9455418,
10.7197318
],
[
106.947704,
10.7202448
],
[
106.947676,
10.7206577
],
[
106.9495627,
10.7211166
],
[
106.9503753,
10.7215204
],
[
106.9518185,
10.7228846
],
[
106.9529912,
10.7245646
],
[
106.9536077,
10.7241602
],
[
106.9568612,
10.7275983
],
[
106.9585485,
10.7289702
],
[
106.9588251,
10.7285967
],
[
106.9595952,
10.7291894
],
[
106.959205,
10.7298092
],
[
106.9636502,
10.7317474
],
[
106.9619108,
10.7323318
],
[
106.9597536,
10.7335586
],
[
106.9584931,
10.7360032
],
[
106.958072,
10.7371565
],
[
106.9571968,
10.7382596
],
[
106.9562006,
10.7417065
],
[
106.9563422,
10.7455981
],
[
106.9579558,
10.7481279
],
[
106.9583671,
10.7497713
],
[
106.9589822,
10.7510176
],
[
106.9582132,
10.7513824
],
[
106.9557753,
10.757038
],
[
106.9532919,
10.7609661
],
[
106.9529093,
10.7611965
],
[
106.9520398,
10.7608603
],
[
106.951145,
10.7607323
],
[
106.9498919,
10.7613706
],
[
106.9482167,
10.7618172
],
[
106.9478438,
10.7624195
],
[
106.944628,
10.7609517
],
[
106.9442148,
10.7626119
],
[
106.9435099,
10.7621051
],
[
106.9425531,
10.7628118
],
[
106.9423577,
10.762781
],
[
106.9420978,
10.7624355
],
[
106.9417825,
10.7624479
],
[
106.9409193,
10.7629004
],
[
106.9418513,
10.7641616
],
[
106.9422732,
10.7661142
],
[
106.9423289,
10.7680302
],
[
106.9418842,
10.7686013
],
[
106.9416853,
10.7694675
],
[
106.9421493,
10.7707287
],
[
106.9420193,
10.7716513
],
[
106.938588,
10.7713811
],
[
106.9383281,
10.7720831
],
[
106.9383205,
10.7727232
],
[
106.9376574,
10.7727615
],
[
106.9376731,
10.7730668
],
[
106.9368321,
10.7732467
],
[
106.9369118,
10.7735747
],
[
106.9365465,
10.7736616
],
[
106.9365774,
10.7737959
],
[
106.9242867,
10.7763209
],
[
106.9241079,
10.7774198
],
[
106.9242843,
10.7776456
],
[
106.9229959,
10.7792385
],
[
106.9205901,
10.7793551
],
[
106.9197978,
10.7803661
],
[
106.9189389,
10.7802883
],
[
106.9166402,
10.778717
],
[
106.9159592,
10.777812
],
[
106.9153832,
10.776558
],
[
106.9150872,
10.77478
],
[
106.9139832,
10.774542
],
[
106.9126852,
10.777143
],
[
106.9108102,
10.775736
],
[
106.9100532,
10.775928
],
[
106.9086522,
10.776713
],
[
106.9027022,
10.777017
],
[
106.9023502,
10.776992
],
[
106.9016822,
10.776592
],
[
106.9012212,
10.776608
],
[
106.9008702,
10.776811
],
[
106.9006432,
10.777294
],
[
106.9002102,
10.777444
],
[
106.8999382,
10.777325
],
[
106.8996292,
10.776604
],
[
106.8993372,
10.776629
],
[
106.8978532,
10.777722
],
[
106.8973642,
10.779934
],
[
106.8960482,
10.781854
],
[
106.8954682,
10.782286
],
[
106.8934962,
10.783074
],
[
106.8925562,
10.782715
],
[
106.8918082,
10.782691
],
[
106.8916392,
10.782882
],
[
106.8911802,
10.784722
],
[
106.8901672,
10.785223
],
[
106.8893712,
10.785199
],
[
106.8883102,
10.784625
],
[
106.8868152,
10.784195
],
[
106.8856092,
10.784242
],
[
106.8844512,
10.784624
],
[
106.8838732,
10.784576
],
[
106.8828122,
10.783572
],
[
106.8819442,
10.782377
],
[
106.8813242,
10.78199
],
[
106.8804732,
10.782105
],
[
106.8785192,
10.783523
],
[
106.8777952,
10.783809
],
[
106.8771432,
10.783388
],
[
106.8772662,
10.780559
],
[
106.8769772,
10.779842
],
[
106.8745382,
10.778639
],
[
106.871809,
10.7765179
],
[
106.8733521,
10.7736419
],
[
106.873868,
10.7722942
],
[
106.8741548,
10.7704548
],
[
106.8738005,
10.7687001
],
[
106.8726326,
10.7669322
],
[
106.8717511,
10.7661577
],
[
106.8694652,
10.7648269
],
[
106.8682886,
10.7645651
],
[
106.8668961,
10.7644838
],
[
106.8652882,
10.764637
],
[
106.8638538,
10.7650669
],
[
106.8624117,
10.765739
],
[
106.8609354,
10.766716
],
[
106.8584194,
10.7691155
],
[
106.8536416,
10.7741461
],
[
106.8521205,
10.7749362
],
[
106.8487105,
10.7754991
],
[
106.8465768,
10.7754044
],
[
106.8450574,
10.7750983
],
[
106.8416745,
10.7737327
],
[
106.8390248,
10.771997
],
[
106.8363335,
10.7699108
],
[
106.8313625,
10.7642026
],
[
106.8293199,
10.761024
],
[
106.8289198,
10.7606319
],
[
106.8292771,
10.7569516
],
[
106.830006,
10.75503
],
[
106.8307783,
10.7537891
],
[
106.8321857,
10.7522221
],
[
106.8343943,
10.750265
],
[
106.8371225,
10.74823
],
[
106.8393271,
10.7459183
],
[
106.8410509,
10.7436802
],
[
106.8425006,
10.7411776
],
[
106.8433823,
10.7386326
],
[
106.8436681,
10.7365266
],
[
106.8436375,
10.7346212
],
[
106.8433313,
10.7327058
],
[
106.8426372,
10.7305496
],
[
106.8418512,
10.7287846
],
[
106.8401161,
10.7262189
],
[
106.8393959,
10.7255529
],
[
106.8384127,
10.7250102
],
[
106.8374841,
10.7247598
],
[
106.8354024,
10.7249506
],
[
106.8336241,
10.7256364
],
[
106.8300287,
10.727928
],
[
106.828417,
10.7263652
],
[
106.8280837,
10.726595
],
[
106.8267853,
10.7240686
],
[
106.8268478,
10.7184687
],
[
106.825961,
10.7079972
],
[
106.826314,
10.7063764
],
[
106.8255932,
10.7055101
]
]
]
}
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -17,7 +17,7 @@
21.07198,
105.7613
],
"generatedAt": "2026-08-30T07:33:16.285Z",
"generatedAt": "2026-09-04T08:15:52.279Z",
"osm": "relation/9421138"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.03578,
105.826
],
"generatedAt": "2026-08-30T07:33:00.443Z",
"generatedAt": "2026-09-04T08:15:37.266Z",
"osm": "relation/9421136"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.14125,
105.38297
],
"generatedAt": "2026-08-30T07:33:26.262Z",
"generatedAt": "2026-09-04T08:16:03.199Z",
"osm": "relation/7115003"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.0306,
105.79168
],
"generatedAt": "2026-08-30T07:33:07.812Z",
"generatedAt": "2026-09-04T08:15:43.205Z",
"osm": "relation/9421132"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
20.87763,
105.66036
],
"generatedAt": "2026-08-30T07:33:29.843Z",
"generatedAt": "2026-09-04T08:16:06.786Z",
"osm": "relation/7115367"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.11385,
105.67739
],
"generatedAt": "2026-08-30T07:33:31.743Z",
"generatedAt": "2026-09-04T08:16:08.279Z",
"osm": "relation/7115780"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.13619,
105.84265
],
"generatedAt": "2026-08-30T07:33:36.328Z",
"generatedAt": "2026-09-04T08:16:11.345Z",
"osm": "relation/7114815"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.01547,
105.82503
],
"generatedAt": "2026-08-30T07:33:09.725Z",
"generatedAt": "2026-09-04T08:15:45.002Z",
"osm": "relation/9421135"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.02888,
105.95055
],
"generatedAt": "2026-08-30T07:33:40.318Z",
"generatedAt": "2026-09-04T08:16:14.679Z",
"osm": "relation/7115759"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
20.95356,
105.75706
],
"generatedAt": "2026-08-30T07:33:19.741Z",
"generatedAt": "2026-09-04T08:15:55.292Z",
"osm": "relation/9424587"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.00564,
105.8585
],
"generatedAt": "2026-08-30T07:33:11.569Z",
"generatedAt": "2026-09-04T08:15:47.199Z",
"osm": "relation/9421134"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.02405,
105.69946
],
"generatedAt": "2026-08-30T07:33:42.269Z",
"generatedAt": "2026-09-04T08:16:16.692Z",
"osm": "relation/7115795"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
20.97454,
105.86322
],
"generatedAt": "2026-08-30T07:33:13.064Z",
"generatedAt": "2026-09-04T08:15:48.703Z",
"osm": "relation/9421133"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.02901,
105.85378
],
"generatedAt": "2026-08-30T07:33:02.346Z",
"generatedAt": "2026-09-04T08:15:38.737Z",
"osm": "relation/9421131"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.04246,
105.89397
],
"generatedAt": "2026-08-30T07:33:05.809Z",
"generatedAt": "2026-09-04T08:15:41.752Z",
"osm": "relation/7115863"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.18352,
105.7058
],
"generatedAt": "2026-08-30T07:33:46.120Z",
"generatedAt": "2026-09-04T08:16:20.632Z",
"osm": "relation/7114823"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
20.68678,
105.72026
],
"generatedAt": "2026-08-30T07:33:50.074Z",
"generatedAt": "2026-09-04T08:16:25.330Z",
"osm": "relation/7115398"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.01256,
105.76151
],
"generatedAt": "2026-08-30T07:33:18.197Z",
"generatedAt": "2026-09-04T08:15:53.777Z",
"osm": "relation/9421137"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.11707,
105.58374
],
"generatedAt": "2026-08-30T07:33:58.043Z",
"generatedAt": "2026-09-04T08:16:32.771Z",
"osm": "relation/7114829"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
20.73559,
105.90112
],
"generatedAt": "2026-08-30T07:33:53.465Z",
"generatedAt": "2026-09-04T08:16:29.235Z",
"osm": "relation/7115635"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
20.96769,
105.59765
],
"generatedAt": "2026-08-30T07:34:01.644Z",
"generatedAt": "2026-09-04T08:16:36.242Z",
"osm": "relation/7115194"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.27256,
105.83045
],
"generatedAt": "2026-08-30T07:34:04.713Z",
"generatedAt": "2026-09-04T08:16:39.590Z",
"osm": "relation/7114806"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.09694,
105.47954
],
"generatedAt": "2026-08-30T07:33:23.202Z",
"generatedAt": "2026-09-04T08:15:58.994Z",
"osm": "relation/7114847"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.06931,
105.81988
],
"generatedAt": "2026-08-30T07:33:03.809Z",
"generatedAt": "2026-09-04T08:15:40.277Z",
"osm": "relation/9421139"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
21.01894,
105.53016
],
"generatedAt": "2026-08-30T07:34:08.230Z",
"generatedAt": "2026-09-04T08:16:43.575Z",
"osm": "relation/7115008"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
20.85577,
105.78086
],
"generatedAt": "2026-08-30T07:34:11.571Z",
"generatedAt": "2026-09-04T08:16:46.510Z",
"osm": "relation/7115593"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
20.93266,
105.84089
],
"generatedAt": "2026-08-30T07:34:13.362Z",
"generatedAt": "2026-09-04T08:16:48.105Z",
"osm": "relation/7115709"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
20.99482,
105.81531
],
"generatedAt": "2026-08-30T07:33:14.827Z",
"generatedAt": "2026-09-04T08:15:50.791Z",
"osm": "relation/9421130"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
20.84497,
105.87482
],
"generatedAt": "2026-08-30T07:34:17.166Z",
"generatedAt": "2026-09-04T08:16:51.533Z",
"osm": "relation/7115632"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
20.7119,
105.79932
],
"generatedAt": "2026-08-30T07:34:20.691Z",
"generatedAt": "2026-09-04T08:16:54.961Z",
"osm": "relation/7115580"
},
"geometry": {
File diff suppressed because it is too large. Load diff
+36
View File
@@ -3,6 +3,10 @@
// Lists only the boundaries that have actually been built, so a partial
// build still compiles.
import bd_dian from './bd/bd-dian.json';
import bd_thuanan from './bd/bd-thuanan.json';
import bd_thudaumot from './bd/bd-thudaumot.json';
import bd from './bd/bd.json';
import dn_camle from './dn/dn-camle.json';
import dn_haichau from './dn/dn-haichau.json';
import dn_hoavang from './dn/dn-hoavang.json';
@@ -11,6 +15,13 @@ import dn_nguhanhson from './dn/dn-nguhanhson.json';
import dn_sontra from './dn/dn-sontra.json';
import dn_thanhkhe from './dn/dn-thanhkhe.json';
import dn from './dn/dn.json';
import dna_bienhoa from './dna/dna-bienhoa.json';
import dna_longthanh from './dna/dna-longthanh.json';
import dna_nhontrach from './dna/dna-nhontrach.json';
import dna_thongnhat from './dna/dna-thongnhat.json';
import dna_trangbom from './dna/dna-trangbom.json';
import dna_vinhcuu from './dna/dna-vinhcuu.json';
import dna from './dna/dna.json';
import hn_bactuliem from './hn/hn-bactuliem.json';
import hn_badinh from './hn/hn-badinh.json';
import hn_bavi from './hn/hn-bavi.json';
@@ -43,9 +54,16 @@ import hn_thuongtin from './hn/hn-thuongtin.json';
import hn_unghoa from './hn/hn-unghoa.json';
import hn from './hn/hn.json';
import dh from './la/dh.json';
import la_benluc from './la/la-benluc.json';
import la_cangiuoc from './la/la-cangiuoc.json';
import la from './la/la.json';
import dl from './ld/dl.json';
import ld from './ld/ld.json';
import qna_hoian from './qna/qna-hoian.json';
import qna from './qna/qna.json';
import th_samson from './th/th-samson.json';
import th_thanhhoa from './th/th-thanhhoa.json';
import th from './th/th.json';
import tphcm_binhchanh from './tphcm/tphcm-binhchanh.json';
import tphcm_binhtan from './tphcm/tphcm-binhtan.json';
import tphcm_binhthanh from './tphcm/tphcm-binhthanh.json';
@@ -70,6 +88,10 @@ import tphcm_thuduc from './tphcm/tphcm-thuduc.json';
import tphcm from './tphcm/tphcm.json';
export const REGION_BOUNDARIES = {
"BD-DIAN": bd_dian,
"BD-THUANAN": bd_thuanan,
"BD-THUDAUMOT": bd_thudaumot,
"BD": bd,
"DN-CAMLE": dn_camle,
"DN-HAICHAU": dn_haichau,
"DN-HOAVANG": dn_hoavang,
@@ -78,6 +100,13 @@ export const REGION_BOUNDARIES = {
"DN-SONTRA": dn_sontra,
"DN-THANHKHE": dn_thanhkhe,
"DN": dn,
"DNA-BIENHOA": dna_bienhoa,
"DNA-LONGTHANH": dna_longthanh,
"DNA-NHONTRACH": dna_nhontrach,
"DNA-THONGNHAT": dna_thongnhat,
"DNA-TRANGBOM": dna_trangbom,
"DNA-VINHCUU": dna_vinhcuu,
"DNA": dna,
"HN-BACTULIEM": hn_bactuliem,
"HN-BADINH": hn_badinh,
"HN-BAVI": hn_bavi,
@@ -110,9 +139,16 @@ export const REGION_BOUNDARIES = {
"HN-UNGHOA": hn_unghoa,
"HN": hn,
"DH": dh,
"LA-BENLUC": la_benluc,
"LA-CANGIUOC": la_cangiuoc,
"LA": la,
"DL": dl,
"LD": ld,
"QNA-HOIAN": qna_hoian,
"QNA": qna,
"TH-SAMSON": th_samson,
"TH-THANHHOA": th_thanhhoa,
"TH": th,
"TPHCM-BINHCHANH": tphcm_binhchanh,
"TPHCM-BINHTAN": tphcm_binhtan,
"TPHCM-BINHTHANH": tphcm_binhthanh,
+1 -1
View File
@@ -17,7 +17,7 @@
10.8888,
106.3825
],
"generatedAt": "2026-08-30T07:35:24.081Z",
"generatedAt": "2026-09-04T08:18:02.635Z",
"osm": "relation/19392506"
},
"geometry": {
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -17,7 +17,7 @@
11.9404,
108.4583
],
"generatedAt": "2026-08-30T07:35:22.336Z",
"generatedAt": "2026-09-04T08:18:00.507Z",
"osm": "relation/19394120"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
11.92055,
108.4644
],
"generatedAt": "2026-08-30T07:36:51.992Z",
"generatedAt": "2026-09-04T08:18:00.514Z",
"parts": 1,
"missingParts": 0
},
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -17,7 +17,7 @@
10.73382,
106.57587
],
"generatedAt": "2026-08-30T07:34:55.532Z",
"generatedAt": "2026-09-04T08:17:31.126Z",
"osm": "relation/7157268"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.76473,
106.59754
],
"generatedAt": "2026-08-30T07:34:40.995Z",
"generatedAt": "2026-09-04T08:17:15.871Z",
"osm": "relation/6909710"
},
"geometry": {
@@ -17,7 +17,7 @@
10.81206,
106.7162
],
"generatedAt": "2026-08-30T07:34:43.044Z",
"generatedAt": "2026-09-04T08:17:18.086Z",
"osm": "relation/3797166"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.51704,
106.881
],
"generatedAt": "2026-08-30T07:34:59.472Z",
"generatedAt": "2026-09-04T08:17:34.608Z",
"osm": "relation/7157255"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.8383,
106.66741
],
"generatedAt": "2026-08-30T07:34:44.646Z",
"generatedAt": "2026-09-04T08:17:20.089Z",
"osm": "relation/6908316"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.88585,
106.58983
],
"generatedAt": "2026-08-30T07:35:04.527Z",
"generatedAt": "2026-09-04T08:17:40.201Z",
"osm": "relation/7157219"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.6543,
106.73051
],
"generatedAt": "2026-08-30T07:35:06.228Z",
"generatedAt": "2026-09-04T08:17:42.357Z",
"osm": "relation/7157197"
},
"geometry": {
@@ -17,7 +17,7 @@
10.80033,
106.67817
],
"generatedAt": "2026-08-30T07:34:46.089Z",
"generatedAt": "2026-09-04T08:17:21.583Z",
"osm": "relation/3851694"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.77622,
106.69715
],
"generatedAt": "2026-08-30T07:34:23.479Z",
"generatedAt": "2026-09-04T08:16:57.820Z",
"osm": "relation/2587287"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.77237,
106.66826
],
"generatedAt": "2026-08-30T07:34:36.038Z",
"generatedAt": "2026-09-04T08:17:11.038Z",
"osm": "relation/6228121"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.76412,
106.64773
],
"generatedAt": "2026-08-30T07:34:37.523Z",
"generatedAt": "2026-09-04T08:17:12.563Z",
"osm": "relation/6846181"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.86453,
106.65697
],
"generatedAt": "2026-08-30T07:34:39.203Z",
"generatedAt": "2026-09-04T08:17:14.263Z",
"osm": "relation/6923167"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.78146,
106.68284
],
"generatedAt": "2026-08-30T07:34:25.565Z",
"generatedAt": "2026-09-04T08:16:59.916Z",
"osm": "relation/3819816"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.75846,
106.70554
],
"generatedAt": "2026-08-30T07:34:27.069Z",
"generatedAt": "2026-09-04T08:17:01.802Z",
"osm": "relation/2778323"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.75494,
106.66946
],
"generatedAt": "2026-08-30T07:34:28.965Z",
"generatedAt": "2026-09-04T08:17:03.709Z",
"osm": "relation/3820432"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.74587,
106.63524
],
"generatedAt": "2026-08-30T07:34:30.860Z",
"generatedAt": "2026-09-04T08:17:05.702Z",
"osm": "relation/6228792"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.73646,
106.72962
],
"generatedAt": "2026-08-30T07:34:32.649Z",
"generatedAt": "2026-09-04T08:17:07.253Z",
"osm": "relation/2764875"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.7245,
106.64055
],
"generatedAt": "2026-08-30T07:34:34.548Z",
"generatedAt": "2026-09-04T08:17:09.147Z",
"osm": "relation/6888445"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.80882,
106.65239
],
"generatedAt": "2026-08-30T07:34:48.592Z",
"generatedAt": "2026-09-04T08:17:23.124Z",
"osm": "relation/6846177"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.79255,
106.62689
],
"generatedAt": "2026-08-30T07:34:50.584Z",
"generatedAt": "2026-09-04T08:17:24.805Z",
"osm": "relation/6846128"
},
"geometry": {
+1 -1
View File
@@ -17,7 +17,7 @@
10.82035,
106.78951
],
"generatedAt": "2026-08-30T07:34:52.776Z",
"generatedAt": "2026-09-04T08:17:26.964Z",
"osm": "relation/19407794"
},
"geometry": {
File diff suppressed because it is too large. Load diff
+42 -24
View File
@@ -8,71 +8,89 @@
// Safe to import from a client component: numbers and flags, no coordinates.
export const REGION_COUNTS = {
"VN": { panos: 424617, cells: 2216, playable: true, thin: false },
"HN": { panos: 225966, cells: 1281, playable: true, thin: false },
"VN": { panos: 493061, cells: 2872, playable: true, thin: false },
"HN": { panos: 225944, cells: 1281, playable: true, thin: false },
"HN-BADINH": { panos: 2977, cells: 19, playable: true, thin: false },
"HN-HOANKIEM": { panos: 1887, cells: 11, playable: true, thin: false },
"HN-TAYHO": { panos: 5054, cells: 31, playable: true, thin: false },
"HN-LONGBIEN": { panos: 17680, cells: 62, playable: true, thin: false },
"HN-CAUGIAY": { panos: 4372, cells: 23, playable: true, thin: false },
"HN-DONGDA": { panos: 3125, cells: 19, playable: true, thin: false },
"HN-HAIBATRUNG": { panos: 3240, cells: 13, playable: true, thin: false },
"HN-HOANGMAI": { panos: 10123, cells: 46, playable: true, thin: false },
"HN-HAIBATRUNG": { panos: 3243, cells: 13, playable: true, thin: false },
"HN-HOANGMAI": { panos: 10125, cells: 46, playable: true, thin: false },
"HN-THANHXUAN": { panos: 2815, cells: 17, playable: true, thin: false },
"HN-BACTULIEM": { panos: 9989, cells: 52, playable: true, thin: false },
"HN-NAMTULIEM": { panos: 10366, cells: 44, playable: true, thin: false },
"HN-HADONG": { panos: 16001, cells: 53, playable: true, thin: false },
"HN-HADONG": { panos: 16002, cells: 53, playable: true, thin: false },
"HN-SONTAY": { panos: 2007, cells: 34, playable: true, thin: false },
"HN-BAVI": { panos: 1708, cells: 41, playable: true, thin: false },
"HN-CHUONGMY": { panos: 1853, cells: 44, playable: true, thin: false },
"HN-DANPHUONG": { panos: 11121, cells: 63, playable: true, thin: false },
"HN-DONGANH": { panos: 32226, cells: 175, playable: true, thin: false },
"HN-GIALAM": { panos: 16216, cells: 87, playable: true, thin: false },
"HN-DONGANH": { panos: 32222, cells: 175, playable: true, thin: false },
"HN-GIALAM": { panos: 16198, cells: 87, playable: true, thin: false },
"HN-HOAIDUC": { panos: 19263, cells: 82, playable: true, thin: false },
"HN-MELINH": { panos: 1337, cells: 26, playable: true, thin: false },
"HN-MELINH": { panos: 1336, cells: 26, playable: true, thin: false },
"HN-MYDUC": { panos: 458, cells: 15, playable: true, thin: false },
"HN-PHUXUYEN": { panos: 1665, cells: 26, playable: true, thin: false },
"HN-PHUCTHO": { panos: 2203, cells: 43, playable: true, thin: false },
"HN-QUOCOAI": { panos: 4384, cells: 50, playable: true, thin: false },
"HN-SOCSON": { panos: 8321, cells: 126, playable: true, thin: false },
"HN-SOCSON": { panos: 8316, cells: 126, playable: true, thin: false },
"HN-THACHTHAT": { panos: 13236, cells: 126, playable: true, thin: false },
"HN-THANHOAI": { panos: 3122, cells: 34, playable: true, thin: false },
"HN-THANHTRI": { panos: 9832, cells: 64, playable: true, thin: false },
"HN-THUONGTIN": { panos: 8152, cells: 82, playable: true, thin: false },
"HN-UNGHOA": { panos: 1233, cells: 35, playable: true, thin: false },
"TPHCM": { panos: 184938, cells: 787, playable: true, thin: false },
"TPHCM": { panos: 184799, cells: 787, playable: true, thin: false },
"TPHCM-Q1": { panos: 2803, cells: 14, playable: true, thin: false },
"TPHCM-Q3": { panos: 2025, cells: 11, playable: true, thin: false },
"TPHCM-Q4": { panos: 1015, cells: 8, playable: true, thin: true },
"TPHCM-Q5": { panos: 1851, cells: 9, playable: true, thin: true },
"TPHCM-Q6": { panos: 3659, cells: 12, playable: true, thin: false },
"TPHCM-Q7": { panos: 8504, cells: 37, playable: true, thin: false },
"TPHCM-Q8": { panos: 5984, cells: 31, playable: true, thin: false },
"TPHCM-Q8": { panos: 5991, cells: 31, playable: true, thin: false },
"TPHCM-Q10": { panos: 2684, cells: 12, playable: true, thin: false },
"TPHCM-Q11": { panos: 2314, cells: 11, playable: true, thin: false },
"TPHCM-Q11": { panos: 2315, cells: 11, playable: true, thin: false },
"TPHCM-Q12": { panos: 15576, cells: 65, playable: true, thin: false },
"TPHCM-BINHTAN": { panos: 15877, cells: 59, playable: true, thin: false },
"TPHCM-BINHTHANH": { panos: 5718, cells: 26, playable: true, thin: false },
"TPHCM-BINHTAN": { panos: 15903, cells: 59, playable: true, thin: false },
"TPHCM-BINHTHANH": { panos: 5720, cells: 26, playable: true, thin: false },
"TPHCM-GOVAP": { panos: 8259, cells: 27, playable: true, thin: false },
"TPHCM-PHUNHUAN": { panos: 2055, cells: 12, playable: true, thin: false },
"TPHCM-TANBINH": { panos: 6037, cells: 24, playable: true, thin: false },
"TPHCM-TANPHU": { panos: 7437, cells: 23, playable: true, thin: false },
"TPHCM-THUDUC": { panos: 41338, cells: 188, playable: true, thin: false },
"TPHCM-BINHCHANH": { panos: 26762, cells: 211, playable: true, thin: false },
"TPHCM-PHUNHUAN": { panos: 2057, cells: 12, playable: true, thin: false },
"TPHCM-TANBINH": { panos: 6040, cells: 24, playable: true, thin: false },
"TPHCM-TANPHU": { panos: 7440, cells: 23, playable: true, thin: false },
"TPHCM-THUDUC": { panos: 41207, cells: 188, playable: true, thin: false },
"TPHCM-BINHCHANH": { panos: 26718, cells: 211, playable: true, thin: false },
"TPHCM-CANGIO": { panos: 1525, cells: 42, playable: true, thin: false },
"TPHCM-CUCHI": { panos: 0, cells: 0, playable: false, thin: false },
"TPHCM-HOCMON": { panos: 17087, cells: 97, playable: true, thin: false },
"TPHCM-NHABE": { panos: 6428, cells: 72, playable: true, thin: false },
"DN": { panos: 1521, cells: 39, playable: true, thin: false },
"TPHCM-HOCMON": { panos: 17080, cells: 97, playable: true, thin: false },
"TPHCM-NHABE": { panos: 6427, cells: 72, playable: true, thin: false },
"DN": { panos: 1520, cells: 39, playable: true, thin: false },
"DN-HAICHAU": { panos: 172, cells: 5, playable: true, thin: true },
"DN-THANHKHE": { panos: 171, cells: 6, playable: true, thin: true },
"DN-SONTRA": { panos: 190, cells: 6, playable: true, thin: true },
"DN-NGUHANHSON": { panos: 517, cells: 14, playable: true, thin: false },
"DN-NGUHANHSON": { panos: 516, cells: 14, playable: true, thin: false },
"DN-LIENCHIEU": { panos: 471, cells: 13, playable: true, thin: false },
"DN-CAMLE": { panos: 0, cells: 0, playable: false, thin: false },
"DN-HOAVANG": { panos: 0, cells: 0, playable: false, thin: false },
"LD": { panos: 475, cells: 8, playable: true, thin: true },
"DL": { panos: 475, cells: 8, playable: true, thin: true },
"LA": { panos: 11717, cells: 106, playable: true, thin: false },
"LA": { panos: 20117, cells: 198, playable: true, thin: false },
"DH": { panos: 11717, cells: 106, playable: true, thin: false },
"LA-BENLUC": { panos: 4259, cells: 49, playable: true, thin: false },
"LA-CANGIUOC": { panos: 4141, cells: 43, playable: true, thin: false },
"DNA": { panos: 43533, cells: 416, playable: true, thin: false },
"DNA-BIENHOA": { panos: 29639, cells: 153, playable: true, thin: false },
"DNA-NHONTRACH": { panos: 6164, cells: 61, playable: true, thin: false },
"DNA-LONGTHANH": { panos: 1338, cells: 36, playable: true, thin: false },
"DNA-TRANGBOM": { panos: 488, cells: 17, playable: true, thin: false },
"DNA-VINHCUU": { panos: 5465, cells: 151, playable: true, thin: false },
"DNA-THONGNHAT": { panos: 439, cells: 14, playable: true, thin: false },
"BD": { panos: 11818, cells: 68, playable: true, thin: false },
"BD-DIAN": { panos: 5488, cells: 30, playable: true, thin: false },
"BD-THUANAN": { panos: 2896, cells: 23, playable: true, thin: false },
"BD-THUDAUMOT": { panos: 3434, cells: 20, playable: true, thin: false },
"TH": { panos: 3370, cells: 81, playable: true, thin: false },
"TH-THANHHOA": { panos: 2933, cells: 73, playable: true, thin: false },
"TH-SAMSON": { panos: 437, cells: 9, playable: true, thin: true },
"QNA": { panos: 1485, cells: 23, playable: true, thin: false },
"QNA-HOIAN": { panos: 1485, cells: 23, playable: true, thin: false },
};
+22 -4
View File
@@ -7,7 +7,7 @@
// not a build failure; see the Coverage note in docs/project-overview.md.
export const REGIONS = {
"VN": {"code":"VN","name":"Vietnam","parent":null,"level":"country","children":["HN","TPHCM","DN","LD","LA"],"center":[15.87185,106.94179],"bbox":[105.28896,10.35828,108.59461,21.38542]},
"VN": {"code":"VN","name":"Vietnam","parent":null,"level":"country","children":["HN","TPHCM","DN","LD","LA","DNA","BD","TH","QNA"],"center":[15.8718,106.99349],"bbox":[105.28896,10.35818,108.69802,21.38542]},
"HN": {"code":"HN","name":"Ha Noi","parent":"VN","level":"province","children":["HN-BADINH","HN-HOANKIEM","HN-TAYHO","HN-LONGBIEN","HN-CAUGIAY","HN-DONGDA","HN-HAIBATRUNG","HN-HOANGMAI","HN-THANHXUAN","HN-BACTULIEM","HN-NAMTULIEM","HN-HADONG","HN-SONTAY","HN-BAVI","HN-CHUONGMY","HN-DANPHUONG","HN-DONGANH","HN-GIALAM","HN-HOAIDUC","HN-MELINH","HN-MYDUC","HN-PHUXUYEN","HN-PHUCTHO","HN-QUOCOAI","HN-SOCSON","HN-THACHTHAT","HN-THANHOAI","HN-THANHTRI","HN-THUONGTIN","HN-UNGHOA"],"center":[21.0285,105.8542],"bbox":[105.28896,20.56452,106.02004,21.38542]},
"HN-BADINH": {"code":"HN-BADINH","name":"Ba Dinh","parent":"HN","level":"district","children":[],"center":[21.03578,105.826],"bbox":[105.80135,21.01596,105.85597,21.05337]},
"HN-HOANKIEM": {"code":"HN-HOANKIEM","name":"Hoan Kiem","parent":"HN","level":"district","children":[],"center":[21.02901,105.85378],"bbox":[105.84093,21.01813,105.86728,21.04321]},
@@ -39,7 +39,7 @@ export const REGIONS = {
"HN-THANHTRI": {"code":"HN-THANHTRI","name":"Thanh Tri","parent":"HN","level":"district","children":[],"center":[20.93266,105.84089],"bbox":[105.78821,20.89699,105.91311,20.98653]},
"HN-THUONGTIN": {"code":"HN-THUONGTIN","name":"Thuong Tin","parent":"HN","level":"district","children":[],"center":[20.84497,105.87482],"bbox":[105.81267,20.75192,105.93617,20.91223]},
"HN-UNGHOA": {"code":"HN-UNGHOA","name":"Ung Hoa","parent":"HN","level":"district","children":[],"center":[20.7119,105.79932],"bbox":[105.69662,20.61188,105.90562,20.80969]},
"TPHCM": {"code":"TPHCM","name":"Ho Chi Minh","parent":"VN","level":"province","children":["TPHCM-Q1","TPHCM-Q3","TPHCM-Q4","TPHCM-Q5","TPHCM-Q6","TPHCM-Q7","TPHCM-Q8","TPHCM-Q10","TPHCM-Q11","TPHCM-Q12","TPHCM-BINHTAN","TPHCM-BINHTHANH","TPHCM-GOVAP","TPHCM-PHUNHUAN","TPHCM-TANBINH","TPHCM-TANPHU","TPHCM-THUDUC","TPHCM-BINHCHANH","TPHCM-CANGIO","TPHCM-CUCHI","TPHCM-HOCMON","TPHCM-NHABE"],"center":[10.8231,106.6297],"bbox":[106.46356,10.35828,107.02758,10.92934],"missingParts":1},
"TPHCM": {"code":"TPHCM","name":"Ho Chi Minh","parent":"VN","level":"province","children":["TPHCM-Q1","TPHCM-Q3","TPHCM-Q4","TPHCM-Q5","TPHCM-Q6","TPHCM-Q7","TPHCM-Q8","TPHCM-Q10","TPHCM-Q11","TPHCM-Q12","TPHCM-BINHTAN","TPHCM-BINHTHANH","TPHCM-GOVAP","TPHCM-PHUNHUAN","TPHCM-TANBINH","TPHCM-TANPHU","TPHCM-THUDUC","TPHCM-BINHCHANH","TPHCM-CANGIO","TPHCM-CUCHI","TPHCM-HOCMON","TPHCM-NHABE"],"center":[10.8231,106.6297],"bbox":[106.46356,10.35818,107.02767,10.92934],"missingParts":1},
"TPHCM-Q1": {"code":"TPHCM-Q1","name":"District 1","parent":"TPHCM","level":"district","children":[],"center":[10.77622,106.69715],"bbox":[106.68169,10.75352,106.7152,10.79693]},
"TPHCM-Q3": {"code":"TPHCM-Q3","name":"District 3","parent":"TPHCM","level":"district","children":[],"center":[10.78146,106.68284],"bbox":[106.66429,10.76543,106.69813,10.79251]},
"TPHCM-Q4": {"code":"TPHCM-Q4","name":"District 4","parent":"TPHCM","level":"district","children":[],"center":[10.75846,106.70554],"bbox":[106.68642,10.75171,106.72228,10.76976]},
@@ -62,7 +62,7 @@ export const REGIONS = {
"TPHCM-CUCHI": {"code":"TPHCM-CUCHI","name":"Cu Chi","parent":"TPHCM","level":"district","children":[],"coverage":"unresolved"},
"TPHCM-HOCMON": {"code":"TPHCM-HOCMON","name":"Hoc Mon","parent":"TPHCM","level":"district","children":[],"center":[10.88585,106.58983],"bbox":[106.49562,10.8261,106.69279,10.92934]},
"TPHCM-NHABE": {"code":"TPHCM-NHABE","name":"Nha Be","parent":"TPHCM","level":"district","children":[],"center":[10.6543,106.73051],"bbox":[106.67328,10.57636,106.78373,10.72563]},
"DN": {"code":"DN","name":"Da Nang","parent":"VN","level":"province","children":["DN-HAICHAU","DN-THANHKHE","DN-SONTRA","DN-NGUHANHSON","DN-LIENCHIEU","DN-CAMLE","DN-HOAVANG"],"center":[16.0544,108.2022],"bbox":[107.81854,15.91799,108.33864,16.2255]},
"DN": {"code":"DN","name":"Da Nang","parent":"VN","level":"province","children":["DN-HAICHAU","DN-THANHKHE","DN-SONTRA","DN-NGUHANHSON","DN-LIENCHIEU","DN-CAMLE","DN-HOAVANG"],"center":[16.0544,108.2022],"bbox":[107.81854,15.91799,108.33864,16.22576]},
"DN-HAICHAU": {"code":"DN-HAICHAU","name":"Hai Chau","parent":"DN","level":"district","children":[],"center":[16.05669,108.21143],"bbox":[108.18883,16.02131,108.236,16.10365]},
"DN-THANHKHE": {"code":"DN-THANHKHE","name":"Thanh Khe","parent":"DN","level":"district","children":[],"center":[16.06315,108.19039],"bbox":[108.16378,16.02637,108.21456,16.08084]},
"DN-SONTRA": {"code":"DN-SONTRA","name":"Son Tra","parent":"DN","level":"district","children":[],"center":[16.11094,108.26514],"bbox":[108.20903,16.05099,108.33864,16.15565]},
@@ -72,6 +72,24 @@ export const REGIONS = {
"DN-HOAVANG": {"code":"DN-HOAVANG","name":"Hoa Vang","parent":"DN","level":"district","children":[],"center":[16.06583,108.01436],"bbox":[107.81854,15.91799,108.22494,16.21544]},
"LD": {"code":"LD","name":"Lam Dong","parent":"VN","level":"province","children":["DL"],"center":[11.92055,108.4644],"bbox":[108.31521,11.80798,108.59461,12.00855],"partialCoverage":"one town covered"},
"DL": {"code":"DL","name":"Da Lat","parent":"LD","level":"district","children":[],"center":[11.9404,108.4583],"bbox":[108.31521,11.80798,108.59461,12.00855]},
"LA": {"code":"LA","name":"Long An","parent":"VN","level":"province","children":["DH"],"center":[10.88908,106.40895],"bbox":[106.27082,10.7409,106.53287,11.02578],"partialCoverage":"one town covered"},
"LA": {"code":"LA","name":"Long An","parent":"VN","level":"province","children":["DH","LA-BENLUC","LA-CANGIUOC"],"center":[10.77014,106.48428],"bbox":[106.27082,10.57389,106.73324,11.02578],"partialCoverage":"three districts covered"},
"DH": {"code":"DH","name":"Duc Hoa","parent":"LA","level":"district","children":[],"center":[10.8888,106.3825],"bbox":[106.27082,10.7409,106.53287,11.02578]},
"LA-BENLUC": {"code":"LA-BENLUC","name":"Ben Luc","parent":"LA","level":"district","children":[],"center":[10.69188,106.45105],"bbox":[106.33144,10.58941,106.56008,10.79766]},
"LA-CANGIUOC": {"code":"LA-CANGIUOC","name":"Can Giuoc","parent":"LA","level":"district","children":[],"center":[10.61496,106.68721],"bbox":[106.63494,10.57389,106.73324,10.65666]},
"DNA": {"code":"DNA","name":"Dong Nai","parent":"VN","level":"province","children":["DNA-BIENHOA","DNA-NHONTRACH","DNA-LONGTHANH","DNA-TRANGBOM","DNA-VINHCUU","DNA-THONGNHAT"],"center":[11.03911,107.02893],"bbox":[106.76197,10.64365,107.25919,11.51163],"partialCoverage":"six districts covered"},
"DNA-BIENHOA": {"code":"DNA-BIENHOA","name":"Bien Hoa","parent":"DNA","level":"district","children":[],"center":[10.91804,106.88104],"bbox":[106.76197,10.8225,106.98711,11.00586]},
"DNA-NHONTRACH": {"code":"DNA-NHONTRACH","name":"Nhon Trach","parent":"DNA","level":"district","children":[],"center":[10.73706,106.89264],"bbox":[106.82559,10.68785,106.96365,10.78522]},
"DNA-LONGTHANH": {"code":"DNA-LONGTHANH","name":"Long Thanh","parent":"DNA","level":"district","children":[],"center":[10.76537,107.02319],"bbox":[106.86427,10.64365,107.1463,10.87903]},
"DNA-TRANGBOM": {"code":"DNA-TRANGBOM","name":"Trang Bom","parent":"DNA","level":"district","children":[],"center":[10.96923,107.03504],"bbox":[106.90356,10.85913,107.12883,11.10274]},
"DNA-VINHCUU": {"code":"DNA-VINHCUU","name":"Vinh Cuu","parent":"DNA","level":"district","children":[],"center":[11.23874,107.04996],"bbox":[106.77447,10.97383,107.23242,11.51163]},
"DNA-THONGNHAT": {"code":"DNA-THONGNHAT","name":"Thong Nhat","parent":"DNA","level":"district","children":[],"center":[10.99013,107.15468],"bbox":[107.05891,10.8488,107.25919,11.10027]},
"BD": {"code":"BD","name":"Binh Duong","parent":"VN","level":"province","children":["BD-DIAN","BD-THUANAN","BD-THUDAUMOT"],"center":[10.92921,106.7089],"bbox":[106.6298,10.86348,106.79462,10.99723],"partialCoverage":"three cities covered"},
"BD-DIAN": {"code":"BD-DIAN","name":"Di An","parent":"BD","level":"district","children":[],"center":[10.90191,106.75607],"bbox":[106.73418,10.86348,106.79462,10.93726]},
"BD-THUANAN": {"code":"BD-THUANAN","name":"Thuan An","parent":"BD","level":"district","children":[],"center":[10.9418,106.67865],"bbox":[106.6502,10.9208,106.7073,10.9636]},
"BD-THUDAUMOT": {"code":"BD-THUDAUMOT","name":"Thu Dau Mot","parent":"BD","level":"district","children":[],"center":[10.9701,106.6585],"bbox":[106.6298,10.93972,106.68926,10.99723]},
"TH": {"code":"TH","name":"Thanh Hoa","parent":"VN","level":"province","children":["TH-THANHHOA","TH-SAMSON"],"center":[19.79405,105.7771],"bbox":[105.64736,19.6996,105.93343,19.88351],"partialCoverage":"two towns covered"},
"TH-THANHHOA": {"code":"TH-THANHHOA","name":"Thanh Hoa City","parent":"TH","level":"district","children":[],"center":[19.80359,105.7578],"bbox":[105.64736,19.72713,105.86242,19.88351]},
"TH-SAMSON": {"code":"TH-SAMSON","name":"Sam Son","parent":"TH","level":"district","children":[],"center":[19.74492,105.87647],"bbox":[105.81954,19.6996,105.93343,19.78598]},
"QNA": {"code":"QNA","name":"Quang Nam","parent":"VN","level":"province","children":["QNA-HOIAN"],"center":[15.89237,108.47816],"bbox":[108.28964,15.81121,108.69802,15.98104],"partialCoverage":"one town covered"},
"QNA-HOIAN": {"code":"QNA-HOIAN","name":"Hoi An","parent":"QNA","level":"district","children":[],"center":[15.89237,108.47816],"bbox":[108.28964,15.81121,108.69802,15.98104]},
};
+3 -3
View File
@@ -54,11 +54,11 @@ describe('region tree shape', () => {
}
});
it('holds one country, five provinces and 61 leaves', () => {
it('holds one country, nine provinces and 75 leaves', () => {
const byLevel = (level) => allRegions().filter((c) => getRegion(c).level === level);
expect(byLevel('country')).toHaveLength(1);
expect(byLevel('province')).toHaveLength(5);
expect(LEAVES).toHaveLength(61);
expect(byLevel('province')).toHaveLength(9);
expect(LEAVES).toHaveLength(75);
});
it('gives every province the country as parent', () => {