如何用DuckDB构建完整的GeoJSON要素集合?
解决方案
核心SQL写法(生成完整GeoJSON要素集合)
假设你的Parquet数据导入后表名为parquet_data,几何列名为wkb_geom,其他属性列无需手动枚举,直接用EXCLUDE排除几何列即可生成properties:
-- 生成完整GeoJSON FeatureCollection SELECT json_object( 'type', 'FeatureCollection', 'features', json_array_agg(feature) ) AS geojson_collection FROM ( -- 生成单个Feature SELECT json_object( 'type', 'Feature', 'geometry', json(ST_AsGeoJSON(wkb_geom)), -- 将几何字符串转为JSON对象 'properties', json_object(*) EXCLUDE (wkb_geom) -- 自动生成所有非几何列的properties ) AS feature FROM parquet_data LIMIT 10 -- 调试用的限制,可移除 );
关键细节说明
- 解决几何片段问题:用
json(ST_AsGeoJSON(wkb_geom))将ST_AsGeoJSON返回的字符串转成JSON对象,确保最终GeoJSON的geometry是标准对象而非字符串片段。 - 避免重复字段错误:通过
EXCLUDE (wkb_geom)明确排除几何列,防止它被混入properties中导致重复或无效字段。 - 消除冗余键名:
json_object(*) EXCLUDE (...)自动映射所有非几何列的键值对,无需手动逐个指定列名,既简洁又避免冗余。
NodeJS客户端执行示例
const duckdb = require('duckdb'); const db = new duckdb.Database(':memory:'); async function fetchGeoJSON() { // 加载依赖扩展 await db.run('LOAD spatial;'); await db.run('LOAD json;'); // 导入Parquet数据到临时表 await db.run("CREATE TABLE parquet_data AS SELECT * FROM 'your_data.parquet';"); // 执行GeoJSON生成查询 const queryResult = await db.get(` SELECT json_object( 'type', 'FeatureCollection', 'features', json_array_agg(feature) ) AS geojson_collection FROM ( SELECT json_object( 'type', 'Feature', 'geometry', json(ST_AsGeoJSON(wkb_geom)), 'properties', json_object(*) EXCLUDE (wkb_geom) ) AS feature FROM parquet_data LIMIT 10 ); `); // 解析为JSON对象直接使用 const geoJSON = JSON.parse(queryResult.geojson_collection); console.log(geoJSON); } fetchGeoJSON().catch(err => console.error(err));
自定义列的写法(如果不需要所有非几何列)
如果只需要指定部分列作为properties,可手动枚举键值对:
SELECT json_object( 'type', 'Feature', 'geometry', json(ST_AsGeoJSON(wkb_geom)), 'properties', json_object( 'id', id, 'name', name, 'value', value ) ) AS feature FROM parquet_data LIMIT 10;
内容的提问来源于stack exchange,提问作者Drew Scatterday
相关产品推荐
相关产品推荐

