1111iso = ISO19139OutputSchema ()
1212
1313
14+ def guess_type (driver : str ) -> str :
15+ # TODO: improve mapping based on the driver
16+ return "image/tiff"
17+
18+
1419def to_iso19139 (metadata : dict ) -> str :
1520 loaded = orjson .loads (metadata )
1621 log .debug (loaded , id = loaded .get ("identification" , {}).get ("identifier" ))
@@ -359,6 +364,7 @@ def generate_geoapi_config(base_url: str = DMS_DATASETS_BASE, lang="en"):
359364
360365 conn = duckdb .connect ()
361366 conn .sql ("Install spatial; load spatial" )
367+ conn .create_function ("guess_type" , guess_type )
362368
363369 datasets = conn .read_parquet (base_url + "datasets_dataset.parquet" ).filter (
364370 "json_keys(metadata) <> []"
@@ -429,14 +435,15 @@ def generate_geoapi_config(base_url: str = DMS_DATASETS_BASE, lang="en"):
429435 ],
430436 crs: 4326
431437 }
432- } as extent ,
438+ } as extents ,
433439 [{
434440 "type": 'coverage',
435441 "default": true,
436442 "name": 'rasterio',
437443 "data": '/vsicurl/' || r.uri,
438444 "format": {
439- "name": r.metadata->>'$.driverShortName'
445+ "name": r.metadata->>'$.driverShortName',
446+ "mimetype": guess_type(r.metadata->>'$.driverShortName')
440447 }
441448 }] as providers
442449 where r.extent is not null and r.metadata is not null
@@ -445,6 +452,75 @@ def generate_geoapi_config(base_url: str = DMS_DATASETS_BASE, lang="en"):
445452 log .debug (geo_raster )
446453 conn .sql ("copy geo_raster to 'dms-raster.json' (FORMAT json, ARRAY true)" )
447454
455+ descriptions = (
456+ (
457+ vectors .set_alias ("r" )
458+ .join (datasets .set_alias ("d" ), condition = "r.dataset_id = d.id" )
459+ .select (
460+ f"r.id, unnest(json_transform(d.metadata->'$.descriptions[*]', '{ descriptions_structure } '), recursive := true)" # noqa: E501
461+ )
462+ )
463+ .filter (
464+ duckdb .ColumnExpression ("lang" ) == duckdb .ConstantExpression (lang ),
465+ )
466+ .aggregate (
467+ "id, lang, string_agg('# ' || descriptionType || '\n ' || description, '\n ') as description" # noqa: E501
468+ )
469+ )
470+ log .debug (descriptions )
471+
472+ subjects = (
473+ vectors .set_alias ("r" )
474+ .join (datasets .set_alias ("d" ), condition = "r.dataset_id = d.id" )
475+ .select (
476+ """r.id, unnest(json_transform(d.metadata->'$.subjects[*]', '[{"subject": "VARCHAR", "subjectScheme": "VARCHAR", "schemeURI": "VARCHAR", "valueURI": "VARCHAR", "classificationCode": "VARCHAR"}]'), recursive := true)""" # noqa: E501
477+ )
478+ .aggregate (
479+ "id, array_agg(subject) as keywords" # noqa: E501
480+ )
481+ )
482+ log .debug (subjects )
483+
484+ geo_vector = conn .sql ("""
485+ from vectors as r
486+ join datasets as d on d.id = r.dataset_id
487+ join datatables as dt on dt.resource_id = r.id
488+ left join descriptions as descr on descr.id = d.id
489+ left join subjects as sbj on sbj.id = d.id
490+ select
491+ d.id || '/' || r.id || '/' || dt.name as id,
492+ 'collection' as type,
493+ 'default' as visibility,
494+ d.title || ' - ' || r.title as title,
495+ coalesce(sbj.keywords, []) as keywords,
496+ coalesce(r.description || '\n ' || descr.description, '') as description,
497+ {
498+ "spatial": {
499+ bbox: [
500+ ST_XMIN(dt.extent), ST_YMIN(dt.extent),
501+ ST_XMAX(dt.extent), ST_YMAX(dt.extent),
502+ ],
503+ crs: 4326
504+ }
505+ } as extents,
506+ [{
507+ "type": 'feature',
508+ "default": true,
509+ "name": 'OGR',
510+ "editable": false,
511+ "id_field": coalesce(dt.fields->>'$[0].name', 'fid'),
512+ "data": {
513+ "source": '/vsicurl/' || r.uri,
514+ "source_type": r.metadata->>'$.driverShortName',
515+ },
516+ "layer": dt.name
517+ }] as providers
518+ where dt.extent is not null and dt.metadata is not null
519+ """ )
520+ log .debug (geo_vector )
521+
522+ conn .sql ("copy geo_vector to 'dms-vector.json' (FORMAT json, ARRAY true)" )
523+
448524
449525if __name__ == "__main__" :
450526 app ()
0 commit comments