171 lines
20 KiB
JavaScript
171 lines
20 KiB
JavaScript
/**
|
|
* Items — GeoJSON boundary fetcher.
|
|
*
|
|
* Reads geometry from a local GeoPackage file when available,
|
|
* falls back to the GADM CDN. Results include corrected names
|
|
* from the parquet database.
|
|
*/
|
|
import { getNames } from './names.js';
|
|
import { getBoundaryFromGpkg } from './gpkg-reader.js';
|
|
// ---------- constants ----------
|
|
const GADM_URL = 'https://geodata.ucdavis.edu/gadm/gadm4.1/json/gadm41_{}_{}.json';
|
|
/** Continent → ISO3 codes mapping (inlined to avoid runtime file-system dependency) */
|
|
const CONTINENT_MAP = {
|
|
africa: ["DZA", "AGO", "BEN", "BWA", "BFA", "BDI", "CPV", "CMR", "CAF", "ESH", "TCD", "COM", "COG", "COD", "DJI", "EGY", "GNQ", "ERI", "SWZ", "ETH", "GAB", "GMB", "GHA", "GIN", "GNB", "CIV", "KEN", "LSO", "LBR", "LBY", "MDG", "MWI", "MLI", "MRT", "MUS", "MYT", "MAR", "MOZ", "NAM", "NER", "NGA", "REU", "RWA", "STP", "SEN", "SYC", "SLE", "SOM", "ZAF", "SSD", "SDN", "TZA", "TGO", "TUN", "UGA", "ZMB", "ZWE"],
|
|
asia: ["AFG", "ARM", "AZE", "BGD", "BTN", "IOT", "BHR", "BRN", "KHM", "CHN", "IND", "IDN", "IRN", "IRQ", "ISR", "JPN", "JOR", "KAZ", "KWT", "KGZ", "LAO", "LBN", "MYS", "MDV", "MNG", "MMR", "NPL", "PRK", "OMN", "PAK", "PSE", "PHL", "QAT", "RUS", "SAU", "SGP", "KOR", "LKA", "SYR", "THA", "TWN", "TJK", "TLS", "TKM", "ARE", "UZB", "VNM", "YEM", "SJM", "XCA", "XPI", "Z01", "Z02", "Z03", "Z04", "Z05", "Z06", "Z07", "Z08", "Z09"],
|
|
europe: ["ALA", "ALB", "AND", "AUT", "BLR", "BEL", "BIH", "BGR", "HRV", "CYP", "CZE", "DNK", "EST", "FIN", "FRA", "FRO", "GEO", "GIB", "GGY", "DEU", "GRC", "HUN", "ISL", "IRL", "ITA", "LVA", "LIE", "LTU", "LUX", "MLT", "MDA", "MCO", "MNE", "NLD", "MKD", "NOR", "POL", "PRT", "ROU", "SMR", "SRB", "SVK", "SVN", "ESP", "SWE", "CHE", "TUR", "UKR", "GBR", "VAT", "IMN", "JEY", "XAD", "ZNC", "XKO"],
|
|
"north america": ["ATG", "BHS", "BRB", "BLZ", "CAN", "CRI", "CUB", "DMA", "DOM", "SLV", "GRD", "GTM", "HTI", "HND", "JAM", "MEX", "NIC", "PAN", "KNA", "LCA", "VCT", "TTO", "USA", "AIA", "ABW", "BMU", "BES", "VGB", "CYM", "XCL", "CUW", "GRL", "GLP", "MTQ", "MSR", "UMI", "PRI", "BLM", "MAF", "SPM", "SXM", "TCA", "VIR"],
|
|
"south america": ["ARG", "BOL", "BRA", "CHL", "COL", "ECU", "GUY", "PRY", "PER", "SUR", "URY", "VEN", "BVT", "FLK", "GUF", "SGS", "SHN"],
|
|
oceania: ["AUS", "CCK", "CXR", "FJI", "KIR", "MHL", "FSM", "NRU", "NZL", "PLW", "PNG", "WSM", "SLB", "TON", "TUV", "VUT", "ASM", "COK", "PYF", "GUM", "NCL", "NIU", "NFK", "MNP", "PCN", "TKL", "WLF", "HMD", "XSP"],
|
|
antartica: ["ATA", "ATF"],
|
|
};
|
|
// ---------- main function ----------
|
|
/**
|
|
* Fetch GeoJSON boundaries for administrative areas.
|
|
* Tries local GeoPackage first, falls back to GADM CDN.
|
|
*/
|
|
export async function getItems(opts) {
|
|
let { name, admin, contentLevel = -1, cache } = opts;
|
|
// Normalize to arrays
|
|
let names = typeof name === 'string' ? [name] : (name || []);
|
|
let admins = typeof admin === 'string' ? [admin] : (admin || []);
|
|
if (names.length === 0 && admins.length === 0) {
|
|
throw new Error('At least "name" or "admin" need to be set.');
|
|
}
|
|
// Continent expansion
|
|
if (names.length === 1 && names[0].toLowerCase() in CONTINENT_MAP) {
|
|
admins = CONTINENT_MAP[names[0].toLowerCase()];
|
|
names = [];
|
|
}
|
|
// Fetch all items
|
|
const allFeatures = [];
|
|
for (const n of names) {
|
|
const features = await fetchSingleItem(n, '', contentLevel, cache);
|
|
allFeatures.push(...features);
|
|
}
|
|
for (const a of admins) {
|
|
const features = await fetchSingleItem('', a, contentLevel, cache);
|
|
allFeatures.push(...features);
|
|
}
|
|
return {
|
|
type: 'FeatureCollection',
|
|
features: allFeatures,
|
|
};
|
|
}
|
|
// ---------- internal ----------
|
|
async function fetchSingleItem(name, admin, contentLevel, cache) {
|
|
// Step 1: Look up the area to find its level + GID
|
|
const lookupOpts = name ? { name } : { admin };
|
|
const lookup = await getNames(lookupOpts);
|
|
if (lookup.rows.length > 1) {
|
|
const id = name || admin;
|
|
throw new Error(`The requested name ("${id}") is not unique (${lookup.rows.length} results). ` +
|
|
`Use the "admin" parameter instead. ` +
|
|
`To find the GADM code, use: getNames({ name: "${id}" })`);
|
|
}
|
|
const level = lookup.level;
|
|
const gidCol = `GID_${level}`;
|
|
const gadmId = lookup.rows[0][gidCol] || '';
|
|
// Step 2: Resolve content level
|
|
const contentLookup = await getNames({
|
|
...(name ? { name } : { admin }),
|
|
contentLevel,
|
|
});
|
|
const resolvedLevel = contentLookup.level;
|
|
// Step 3: Try local GeoPackage first
|
|
let localResult = await tryLocalGpkg(gadmId, name || admin, level, resolvedLevel, cache);
|
|
// Step 4: Fallback to GADM CDN
|
|
if (!localResult) {
|
|
localResult = await fetchFromCDN(name, admin, gadmId, level, resolvedLevel);
|
|
}
|
|
if (resolvedLevel === level) {
|
|
localResult.forEach(f => f.properties.isOuter = true);
|
|
}
|
|
return localResult;
|
|
}
|
|
/**
|
|
* Read boundaries from local GeoPackage.
|
|
* Returns features with all matching rows at the resolved content level.
|
|
*/
|
|
async function tryLocalGpkg(gadmId, id, level, resolvedLevel, cache) {
|
|
// Query the GeoPackage for all rows belonging to this region
|
|
const gidCol = `GID_${level}`;
|
|
const nameCols = [];
|
|
for (let l = 0; l <= Math.min(resolvedLevel, 5); l++) {
|
|
nameCols.push(`NAME_${l}`, `GID_${l}`);
|
|
}
|
|
const result = await getBoundaryFromGpkg(gadmId, resolvedLevel, cache);
|
|
if (!result || result.features.length === 0)
|
|
return null;
|
|
// Convert BoundaryFeature → GeoJSONFeature
|
|
const features = result.features.map(f => ({
|
|
type: 'Feature',
|
|
properties: f.properties,
|
|
geometry: f.geometry,
|
|
}));
|
|
return features;
|
|
}
|
|
/**
|
|
* Fallback: fetch from GADM CDN + correct names from parquet.
|
|
*/
|
|
async function fetchFromCDN(name, admin, gadmId, level, resolvedLevel) {
|
|
const iso3 = gadmId.substring(0, 3);
|
|
const url = GADM_URL.replace('{}', iso3).replace('{}', String(resolvedLevel));
|
|
let data;
|
|
try {
|
|
const res = await fetch(url);
|
|
if (!res.ok)
|
|
throw new Error(`HTTP ${res.status}`);
|
|
data = await res.json();
|
|
}
|
|
catch (e) {
|
|
throw new Error(`Cannot retrieve data from GADM server. ` +
|
|
`Try opening: ${url}. ` +
|
|
`If it fails, the error is from GADM servers.`);
|
|
}
|
|
// Convert to features
|
|
const rawFeatures = data.features || [];
|
|
let features = rawFeatures.map((f) => ({
|
|
type: 'Feature',
|
|
properties: { ...f.properties, ...(f.properties?.COUNTRY ? { NAME_0: f.properties.COUNTRY } : {}) },
|
|
geometry: f.geometry,
|
|
}));
|
|
// Name correction from parquet
|
|
const isos = [...new Set(features.map(f => f.properties.GID_0).filter(Boolean))];
|
|
if (isos.length > 0) {
|
|
const completeRows = [];
|
|
for (const iso of isos) {
|
|
const nr = await getNames({ admin: iso, contentLevel: resolvedLevel, complete: true });
|
|
completeRows.push(...nr.rows);
|
|
}
|
|
const gidKey = (row) => {
|
|
const parts = [];
|
|
for (let i = 0; i <= resolvedLevel; i++) {
|
|
parts.push(row[`GID_${i}`] || '');
|
|
}
|
|
return parts.join('|');
|
|
};
|
|
const nameLookup = new Map();
|
|
for (const row of completeRows) {
|
|
nameLookup.set(gidKey(row), row);
|
|
}
|
|
for (const feature of features) {
|
|
const key = gidKey(feature.properties);
|
|
const correct = nameLookup.get(key);
|
|
if (correct) {
|
|
for (let i = 0; i <= resolvedLevel; i++) {
|
|
if (correct[`NAME_${i}`]) {
|
|
feature.properties[`NAME_${i}`] = correct[`NAME_${i}`];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Filter to the requested area
|
|
const id = name || admin;
|
|
const colPrefix = name ? 'NAME_' : 'GID_';
|
|
const filterCol = `${colPrefix}${level}`;
|
|
features = features.filter(f => f.properties[filterCol]?.toLowerCase() === id.toLowerCase());
|
|
return features;
|
|
}
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXRlbXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaXRlbXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBQ0gsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN0QyxPQUFPLEVBQUUsbUJBQW1CLEVBQWtCLE1BQU0sa0JBQWtCLENBQUM7QUErQnZFLGtDQUFrQztBQUVsQyxNQUFNLFFBQVEsR0FBRyxpRUFBaUUsQ0FBQztBQUVuRix1RkFBdUY7QUFDdkYsTUFBTSxhQUFhLEdBQTZCO0lBQzVDLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDO0lBQ3ZaLElBQUksRUFBRSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDO0lBQzFhLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQztJQUN6WSxlQUFlLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUM7SUFDOVQsZUFBZSxFQUFFLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtB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
|