@@ -2,7 +2,7 @@ import { exportLayerAsGeoJSON } from '../geojson/geojson-export';
22import { parseCrsString , parsePrj } from '../crs/mapshaper-projections' ;
33import { runningInBrowser } from '../mapshaper-env' ;
44import { getFileExtension } from '../utils/mapshaper-filename-utils' ;
5- import { stop } from '../utils/mapshaper-logging' ;
5+ import { stop , warn } from '../utils/mapshaper-logging' ;
66import utils from '../utils/mapshaper-utils' ;
77import require from '../mapshaper-require' ;
88
@@ -19,22 +19,26 @@ export async function exportGeoParquet(dataset, opts, filenameOverride) {
1919 extension = getFileExtension ( opts . file ) || extension ;
2020 }
2121 dataset . layers . forEach ( function ( lyr ) {
22- if ( ! lyr . geometry_type ) {
23- stop ( 'GeoParquet export requires a geometry layer' ) ;
24- }
2522 var features = exportLayerAsGeoJSON ( lyr , dataset , opts , true , null ) ;
26- var output = buildGeoParquetColumns ( features , writer ) ;
27- var geoMetadata = buildGeoMetadata ( features , dataset ) ;
28- var content = writer . parquetWriteBuffer ( {
23+ var hasGeometry = features . some ( function ( feat ) {
24+ return ! ! feat . geometry ;
25+ } ) ;
26+ var output = buildGeoParquetColumns ( features , hasGeometry ) ;
27+ var writeOptions = {
2928 columnData : output . columnData ,
3029 codec : compression . codec ,
3130 compressors : compression . compressors ,
32- pageSize : compression . pageSize ,
33- kvMetadata : [ {
31+ pageSize : compression . pageSize
32+ } ;
33+ if ( hasGeometry ) {
34+ writeOptions . kvMetadata = [ {
3435 key : 'geo' ,
35- value : JSON . stringify ( geoMetadata )
36- } ]
37- } ) ;
36+ value : JSON . stringify ( buildGeoMetadata ( features , dataset ) )
37+ } ] ;
38+ } else {
39+ warn ( 'GeoParquet export: layer has no geometry; writing attribute data only.' ) ;
40+ }
41+ var content = writer . parquetWriteBuffer ( writeOptions ) ;
3842 files . push ( {
3943 filename : filenameOverride || ( lyr . name + '.' + extension ) ,
4044 content : content
@@ -43,23 +47,31 @@ export async function exportGeoParquet(dataset, opts, filenameOverride) {
4347 return files ;
4448}
4549
46- function buildGeoParquetColumns ( features , writer ) {
50+ function buildGeoParquetColumns ( features , includeGeometry ) {
4751 var geometryName = 'geometry' ;
4852 var names = getPropertyNames ( features ) ;
4953 var columnData = [ ] ;
50- columnData . push ( {
51- name : geometryName ,
52- data : features . map ( function ( feat ) {
53- return feat . geometry || null ;
54- } ) ,
55- type : 'GEOMETRY'
56- } ) ;
54+ if ( features . length === 0 ) {
55+ stop ( 'GeoParquet export requires at least one record' ) ;
56+ }
57+ if ( includeGeometry ) {
58+ columnData . push ( {
59+ name : geometryName ,
60+ data : features . map ( function ( feat ) {
61+ return feat . geometry || null ;
62+ } ) ,
63+ type : 'GEOMETRY'
64+ } ) ;
65+ }
5766 names . forEach ( function ( name ) {
5867 var values = features . map ( function ( feat ) {
5968 return feat . properties ? feat . properties [ name ] : null ;
6069 } ) ;
6170 columnData . push ( buildAttributeColumn ( name , values ) ) ;
6271 } ) ;
72+ if ( columnData . length === 0 ) {
73+ stop ( 'GeoParquet export requires geometry or attribute data' ) ;
74+ }
6375 return { columnData : columnData , geometryColumn : geometryName } ;
6476}
6577
0 commit comments