add-static-dataset
Add a new static dataset to app/scripts/StaticDatasets/geojson. Infers config from prompt, asks for missing data, uses types to guide required fields.
npxskills add fixmyberlin/tilda-geo--skill add-static-datasetLoading…
Add a new static dataset to app/scripts/StaticDatasets/geojson. Infers config from prompt, asks for missing data, uses types to guide required fields.
npxskills add fixmyberlin/tilda-geo--skill add-static-datasetLoading…
Adds a new static dataset folder to tilda-static-data and uses the tilda-geo upload pipeline to process it. In tilda-geo, app/scripts/StaticDatasets/geojson is a symlink and must point at the matching tilda-static-data worktree before editing data files.
Extract from user prompt or ask if missing:
region-berlin, region-bb) - parent folder nameberlin-bezirkeregion-berlinberlin-<name><name>['infravelo'], ['berlin'])tilda-static-data worktree and symlinkStatic dataset files live in the sibling repo tilda-static-data, not in tilda-geo.
../../../../tilda-static-data/geojson is enough.tilda-static-data worktree and relink geojson there.For a branch named my-branch:
cd ../tilda-static-data
git worktree add ../tilda-static-data--my-branch my-branch
cd ../tilda-geo--my-branch/app
rm -f scripts/StaticDatasets/geojson
ln -s ../../../../tilda-static-data--my-branch/geojson scripts/StaticDatasets/geojson
Do not edit app/scripts/StaticDatasets/geojson when it points at the regular shared ../tilda-static-data checkout.
app/scripts/StaticDatasets/geojson/<GROUP_FOLDER>/<SUB_FOLDER>/
Important: /geojson is a symlink. Before creating folders, ensure it points at the matching tilda-static-data--my-branch worktree.
Create directory if group folder doesn't exist. Ensure sub-folder name follows naming convention (see Required Information above).
Run these in order on committed data files. Never reproject, round, or pretty-print coordinates in transform.ts — use ogr2ogr (2.2–2.3) and oxfmt (2.4) on the files instead.
Move source file to:
app/scripts/StaticDatasets/geojson/<GROUP_FOLDER>/<SUB_FOLDER>/<FILENAME>.geojson
This path should resolve into ../tilda-static-data--my-branch/geojson/....
Check: Inspect the first coordinate pair after moving. For Germany, expect roughly lon 5–15, lat 47–55. Web Mercator (EPSG:3857) uses large meter values (e.g. ~1.5e6).
Fix (only if not WGS84): Reproject in place:
cd app/scripts/StaticDatasets/geojson/<GROUP_FOLDER>/<SUB_FOLDER>
ogr2ogr -f GeoJSON -t_srs EPSG:4326 -lco COORDINATE_PRECISION=8 \
<FILENAME>.geojson.tmp <FILENAME>.geojson \
&& mv <FILENAME>.geojson.tmp <FILENAME>.geojson
Check: Coordinates should have at most 8 decimal places (matches upload pipeline and API exports).
Fix (only if more than 8): Round in place (file must already be EPSG:4326):
cd app/scripts/StaticDatasets/geojson/<GROUP_FOLDER>/<SUB_FOLDER>
ogr2ogr -f GeoJSON -lco COORDINATE_PRECISION=8 \
<FILENAME>.geojson.tmp <FILENAME>.geojson \
&& mv <FILENAME>.geojson.tmp <FILENAME>.geojson
Upload runs validateProjection again on WGS84 bounds.
From app/ (skill / agents only — devs use format-on-save in the editor):
bun run format-static-datasets-geojson -- \
scripts/StaticDatasets/geojson/<GROUP_FOLDER>/<SUB_FOLDER>/*.{json,geojson}
Check: Uncompressed .geojson size after formatting.
cd app/scripts/StaticDatasets/geojson/<GROUP_FOLDER>/<SUB_FOLDER>
gzip -9 -f <FILENAME>.geojson
gzip replaces the file with <FILENAME>.geojson.gz and removes the plain .geojson (-9 max compression, -f overwrite).
Only if transformation required (not for CRS or coordinate precision — Step 2 only). Use helpers from app/scripts/StaticDatasets/geojson/_utils:
transformUtils.ts - property transformationsdefaultLayerStyles.ts - default styling helperstranslateUtils.ts - translation helpersExample:
import { FeatureCollection } from 'geojson'
export const transform = (data: FeatureCollection) => {
// Use helper functions from _utils when possible
return data
}
Critical: Research similar datasets in same group folder first.
Before writing meta.ts:
<GROUP_FOLDER>/ directorymeta.ts files (similar geometry type, similar purpose)Required fields (from app/scripts/StaticDatasets/types.ts):
regions: RegionSlug[] (required)public: boolean (required)dataSourceType: 'local' (required)configs: Array with at least one config (required)Config required fields:
name: stringattributionHtml: stringinspector: { enabled: boolean, ... } or { enabled: false }layers: Layer[] (required)Config optional fields:
category: string | null — grouping key; titles/order are managed in Admin → Statische Datensatz-Kategorien (DB).updatedAt: stringdescription: stringdataSourceMarkdown: stringlicence: License type (see types.ts)licenceOsmCompatible: 'licence' | 'waiver' | 'no'legends: Legend[]Style/Legend: If not specified, make best guess:
defaultLayerStyles() from _utils/defaultLayerStyles.ts for simple casesStripe / Schraffur (fill-pattern): For diagonal stripes over polygons, reuse the existing map sprite image id stripe_texture (same hatch as private Parkflächen in generated parking_areas; listed in app/public/map-style/sprite.json). Do not add a new sprite. Stack a second fill layer above the solid fill: fill-color 'rgba(0, 0, 0, 0)', fill-opacity around 0.5 (tune as needed), fill-pattern 'stripe_texture'. Skip fill-outline-color on the stripe layer if the base fill already defines an outline. Use a filter on the stripe layer when only some features should be hatched; if exports mix boolean true and string 'true', either use an any / match filter in meta.ts or normalize values in transform.ts (step 3) so the filter stays simple.
Example structure:
import { MetaData } from '../../../types'
import { defaultLayerStyles } from '../../_utils/defaultLayerStyles'
export const data: MetaData = {
regions: ['infravelo'], // From user or infer from group folder
public: true,
dataSourceType: 'local',
configs: [
{
name: 'Dataset Name',
category: 'berlin/misc', // Infer from similar datasets
attributionHtml: 'Source Name', // Ask if unclear
licence: 'DL-DE/ZERO-2.0', // Infer from similar datasets
inspector: { enabled: false }, // Default unless specified
layers: defaultLayerStyles(), // Or custom layers
},
],
}
Check app/scripts/StaticDatasets/updateStaticDatasets.ts for correct params:
--folder-filter=<SUB_FOLDER_NAME> (matches full path, so sub-folder name works)--env=dev (or staging/production; omit to be prompted)One-click command from app/ (replace <SUB_FOLDER_NAME> with actual folder name; static-datasets-update uses the repository root .env via bun --env-file=../.env, same as bun run dev):
bun run static-datasets-update -- --folder-filter=<SUB_FOLDER_NAME> --env=dev
Note: updateDownloadSources.ts is for WFS downloads (requires downloadConfig.ts). Use updateStaticDatasets.ts for local GeoJSON files.
Always run this after creating or modifying TypeScript files (meta.ts, transform.ts, or any imports). From app/ (same as Step 5):
bun run type-check-deploy
This temporarily removes the geojson symlink, runs TypeScript type-checking, and restores the symlink. It simulates the Docker build environment where symlinks aren't available, ensuring your code will compile correctly during builds.
Before completing:
transform.ts only if needed — never for CRS (Step 2); meta.ts / transform.ts via format-on-save or format-static-datasets-geojsonbun run type-check-deploy run successfully (see Step 6)app/scripts/StaticDatasets/types.tsapp/scripts/StaticDatasets/geojson/region-berlin/*/meta.tsapp/scripts/StaticDatasets/geojson/_utils/docs/Features-Parameter-Deeplinks.md, docs/Regional-Masks.mdapp/scripts/StaticDatasets/updateStaticDatasets.tsCreate or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Set up and use 1Password CLI (op). Use when installing the CLI, enabling desktop app integration, signing in (single or multi-account), or reading/injecting/running secrets via op.
CLI to manage emails via IMAP/SMTP. Use `himalaya` to list, read, write, reply, forward, search, and organize emails from the terminal. Supports multiple accounts and message composition with MML (MIME Meta Language).
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Set up and use 1Password CLI (op). Use when installing the CLI, enabling desktop app integration, signing in (single or multi-account), or reading/injecting/running secrets via op.
CLI to manage emails via IMAP/SMTP. Use `himalaya` to list, read, write, reply, forward, search, and organize emails from the terminal. Supports multiple accounts and message composition with MML (MIME Meta Language).