From 5e60d1701c7dafc8a07758421b47d91c8aae2ea3 Mon Sep 17 00:00:00 2001 From: Petri Hienonen Date: Sun, 9 Nov 2025 22:45:00 +0200 Subject: Add peruspiiri --- app/geometry.js | 1 - app/models.js | 7 +-- download.js | 142 +++++++++++++++++++++++++------------------------------- 3 files changed, 67 insertions(+), 83 deletions(-) diff --git a/app/geometry.js b/app/geometry.js index d0f5467..ac6b46c 100644 --- a/app/geometry.js +++ b/app/geometry.js @@ -149,7 +149,6 @@ export class Geometry { case "MultiPolygon": return Polygon.fromGeoJSON(geojson); default: - debugger; throw new Error(`Invalid GeoJSON object: missing required 'type' property`); } } diff --git a/app/models.js b/app/models.js index 9a0e2ca..d2c5b55 100644 --- a/app/models.js +++ b/app/models.js @@ -175,8 +175,8 @@ export class District { */ static fromFeature(feature) { const name = - "nimi" in feature.properties && typeof feature.properties.nimi === "string" - ? feature.properties.nimi + "nimi_fi" in feature.properties && typeof feature.properties.nimi_fi === "string" + ? feature.properties.nimi_fi : ""; const municipality = "kunta" in feature.properties && typeof feature.properties.kunta === "string" @@ -508,6 +508,7 @@ export class DataProvider { // Use CouchDB view to get all features for the layer const viewUrl = `${DataProvider.couchBaseUrl}/${DataProvider.wfsDbName}/_design/layers/_view/by_layer`; const params = new URLSearchParams({ + // biome-ignore lint/style/useNamingConvention: header names are not optional include_docs: "true", key: JSON.stringify(layerName), }); @@ -544,7 +545,7 @@ export class DataProvider { /** @returns {Promise} */ static async getDistricts() { - const collection = await DataProvider.getCollectionFromCouch("Seutukartta_aluejako_pienalue"); + const collection = await DataProvider.getCollectionFromCouch("Piirijako_peruspiiri"); const districts = District.fromCollection(collection); return districts; } diff --git a/download.js b/download.js index ad149d7..90a7d81 100644 --- a/download.js +++ b/download.js @@ -18,6 +18,7 @@ const baseUrl = "https://kartta.hel.fi/ws/geoserver/avoindata/wfs"; const layers = [ "Aluesarjat_avainluvut_2024", "Piirijako_pienalue", + "Piirijako_peruspiiri", "Seutukartta_liikenne_paatiet", "Seutukartta_liikenne_metroasemat", "Seutukartta_liikenne_metro_rata", @@ -42,6 +43,7 @@ if (!fs.existsSync(outputDir)) { function getHeaders() { return new Headers({ + // biome-ignore lint/style/useNamingConvention: database Authorization: getAuthHeader(), "Content-Type": "application/json", }); @@ -50,18 +52,14 @@ function getHeaders() { // === COUCHDB HELPERS === async function createDatabase() { const url = `${couchUrl}/${dbName}`; - try { - const res = await fetch(url, { - headers: getHeaders(), - method: "PUT", - }); - if (res.ok || res.status === 412) { - console.log(`Database ${dbName} ready.`); - } else { - throw new Error(await res.text()); - } - } catch (e) { - console.error("DB create error:", e.message); + const res = await fetch(url, { + headers: getHeaders(), + method: "PUT", + }); + if (res.ok || res.status === 412) { + console.log(`Database ${dbName} ready.`); + } else { + throw new Error(await res.text()); } } @@ -69,6 +67,7 @@ async function ensureDesignDocs() { const designDoc = { _id: "_design/layers", views: { + // biome-ignore lint/style/useNamingConvention: database by_layer: { map: `function(doc) { if (doc.type === 'feature' && doc.layer) { @@ -80,43 +79,33 @@ async function ensureDesignDocs() { }; const url = `${couchUrl}/${dbName}/_design/layers`; - try { - const res = await fetch(url, { headers: getHeaders() }); - if (res.status === 404) { - await fetch(url, { - body: JSON.stringify(designDoc), - headers: getHeaders(), - method: "PUT", - }); - console.log("Created design document: layers/by_layer"); - } else if (res.ok) { - const existing = await res.json(); - designDoc._rev = existing._rev; - await fetch(url, { - body: JSON.stringify(designDoc), - headers: getHeaders(), - method: "PUT", - }); - console.log("Updated design document"); - } - } catch (e) { - console.error("Design doc error:", e.message); - process.exit(1); + const res = await fetch(url, { headers: getHeaders() }); + if (res.status === 404) { + await fetch(url, { + body: JSON.stringify(designDoc), + headers: getHeaders(), + method: "PUT", + }); + console.log("Created design document: layers/by_layer"); + } else if (res.ok) { + const existing = await res.json(); + designDoc._rev = existing._rev; + await fetch(url, { + body: JSON.stringify(designDoc), + headers: getHeaders(), + method: "PUT", + }); + console.log("Updated design document"); } } // === DOWNLOAD === async function downloadLayer(layer) { const url = `${baseUrl}?service=WFS&version=2.0.0&request=GetFeature&typeName=avoindata:${layer}&outputFormat=json&srsname=EPSG:4326`; - try { - const res = await fetch(url); - if (!res.ok) throw new Error(res.statusText); - const response = await res.json(); - return response; - } catch (e) { - console.error(`Download: \n${url}\nfailed [${layer}] ${e.toString()}`); - return null; - } + const res = await fetch(url); + if (!res.ok) throw new Error(res.statusText); + const response = await res.json(); + return response; } function saveToFile(layer, data) { @@ -128,9 +117,12 @@ function saveToFile(layer, data) { // === UPLOAD METADATA === async function uploadLayerMetadata(layer, featureCount) { const docId = `layer_metadata:${layer}`; + const doc = { _id: docId, + // biome-ignore lint/style/useNamingConvention: database feature_count: featureCount, + // biome-ignore lint/style/useNamingConvention: database last_updated: new Date().toISOString(), name: layer, projection: "EPSG:4326", @@ -138,51 +130,42 @@ async function uploadLayerMetadata(layer, featureCount) { }; const url = `${couchUrl}/${dbName}/${docId}`; - try { - const getRes = await fetch(url, { headers: getHeaders() }); - if (getRes.ok) { - const existing = await getRes.json(); - doc._rev = existing._rev; - } - const putRes = await fetch(url, { - body: JSON.stringify(doc), - headers: getHeaders(), - method: "PUT", - }); - if (!putRes.ok) throw new Error(await putRes.text()); - console.log(`Metadata updated: ${layer} (${featureCount} features)`); - } catch (e) { - console.error(`Metadata error [${layer}]:`, e.message); + const getRes = await fetch(url, { headers: getHeaders() }); + if (getRes.ok) { + const existing = await getRes.json(); + doc._rev = existing._rev; } + const putRes = await fetch(url, { + body: JSON.stringify(doc), + headers: getHeaders(), + method: "PUT", + }); + if (!putRes.ok) throw new Error(await putRes.text()); + console.log(`Metadata updated: ${layer} (${featureCount} features)`); } // === UPLOAD SINGLE FEATURE (with deduplication) === async function uploadFeature(doc) { const url = `${couchUrl}/${dbName}/${doc._id}`; - try { - const getRes = await fetch(url, { headers: getHeaders() }); - if (getRes.ok) { - const existing = await getRes.json(); - doc._rev = existing._rev; - - const geomEqual = JSON.stringify(doc.geometry) === JSON.stringify(existing.geometry); - const propEqual = JSON.stringify(doc.properties) === JSON.stringify(existing.properties); - if (geomEqual && propEqual) { - return false; // skipped - } + const getRes = await fetch(url, { headers: getHeaders() }); + if (getRes.ok) { + const existing = await getRes.json(); + doc._rev = existing._rev; + + const geomEqual = JSON.stringify(doc.geometry) === JSON.stringify(existing.geometry); + const propEqual = JSON.stringify(doc.properties) === JSON.stringify(existing.properties); + if (geomEqual && propEqual) { + return false; // skipped } + } - const putRes = await fetch(url, { - body: JSON.stringify(doc), - headers: getHeaders(), - method: "PUT", - }); + const putRes = await fetch(url, { + body: JSON.stringify(doc), + headers: getHeaders(), + method: "PUT", + }); - return putRes.ok; - } catch (e) { - console.warn(`Upload failed [${doc._id}]:`, e.message); - return false; - } + return putRes.ok; } // === PROCESS LAYER === @@ -207,6 +190,7 @@ async function processLayer(layer) { const doc = { _id: `feature:${layer}:${propId}`, + // biome-ignore lint/style/useNamingConvention: database downloaded_at: new Date().toISOString(), geometry: feature.geometry, layer: layer, -- cgit v1.2.3-70-g09d2