@loaders.gl/shapefile 4.3.1 → 4.4.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/dbf-arrow-loader.d.ts +52 -0
  2. package/dist/dbf-arrow-loader.d.ts.map +1 -0
  3. package/dist/dbf-arrow-loader.js +32 -0
  4. package/dist/dbf-format.d.ts +10 -0
  5. package/dist/dbf-format.d.ts.map +1 -0
  6. package/dist/dbf-format.js +12 -0
  7. package/dist/dbf-loader.js +1 -1
  8. package/dist/dbf-worker.js +1 -1
  9. package/dist/dist.dev.js +12231 -33
  10. package/dist/dist.min.js +11 -2
  11. package/dist/index.cjs +277 -10
  12. package/dist/index.cjs.map +4 -4
  13. package/dist/index.d.ts +1 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +1 -0
  16. package/dist/lib/parsers/parse-dbf-to-arrow.d.ts +26 -0
  17. package/dist/lib/parsers/parse-dbf-to-arrow.d.ts.map +1 -0
  18. package/dist/lib/parsers/parse-dbf-to-arrow.js +321 -0
  19. package/dist/lib/parsers/parse-dbf.d.ts +1 -1
  20. package/dist/lib/parsers/parse-dbf.d.ts.map +1 -1
  21. package/dist/lib/parsers/parse-shapefile.js +2 -2
  22. package/dist/lib/parsers/parse-shp-geometry.d.ts +1 -1
  23. package/dist/lib/parsers/parse-shp-geometry.d.ts.map +1 -1
  24. package/dist/lib/parsers/types.d.ts +1 -1
  25. package/dist/lib/parsers/types.d.ts.map +1 -1
  26. package/dist/shapefile-loader.d.ts.map +1 -1
  27. package/dist/shapefile-loader.js +1 -1
  28. package/dist/shp-loader.js +1 -1
  29. package/dist/shp-worker.js +1 -1
  30. package/package.json +6 -6
  31. package/src/dbf-arrow-loader.ts +46 -0
  32. package/src/dbf-format.ts +15 -0
  33. package/src/index.ts +1 -0
  34. package/src/lib/parsers/parse-dbf-to-arrow.ts +382 -0
  35. package/src/lib/parsers/parse-dbf.ts +1 -1
  36. package/src/lib/parsers/parse-shapefile.ts +2 -2
  37. package/src/lib/parsers/parse-shp-geometry.ts +1 -1
  38. package/src/lib/parsers/types.ts +1 -1
  39. package/src/shapefile-loader.ts +1 -1
@@ -0,0 +1,321 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+ import { ArrowTableBuilder } from '@loaders.gl/schema-utils';
5
+ import { BinaryChunkReader } from "../streaming/binary-chunk-reader.js";
6
+ const LITTLE_ENDIAN = true;
7
+ const DBF_HEADER_SIZE = 32;
8
+ var STATE;
9
+ (function (STATE) {
10
+ STATE[STATE["START"] = 0] = "START";
11
+ STATE[STATE["FIELD_DESCRIPTORS"] = 1] = "FIELD_DESCRIPTORS";
12
+ STATE[STATE["FIELD_PROPERTIES"] = 2] = "FIELD_PROPERTIES";
13
+ STATE[STATE["END"] = 3] = "END";
14
+ STATE[STATE["ERROR"] = 4] = "ERROR";
15
+ })(STATE || (STATE = {}));
16
+ class DBFParser {
17
+ binaryReader = new BinaryChunkReader();
18
+ textDecoder;
19
+ state = STATE.START;
20
+ result = {};
21
+ constructor(options) {
22
+ this.textDecoder = new TextDecoder(options.encoding);
23
+ }
24
+ /**
25
+ * @param arrayBuffer
26
+ */
27
+ write(arrayBuffer) {
28
+ this.binaryReader.write(arrayBuffer);
29
+ this.state = parseState(this.state, this.result, this.binaryReader, this.textDecoder);
30
+ // this.result.progress.bytesUsed = this.binaryReader.bytesUsed();
31
+ // important events:
32
+ // - schema available
33
+ // - first rows available
34
+ // - all rows available
35
+ }
36
+ end() {
37
+ this.binaryReader.end();
38
+ this.state = parseState(this.state, this.result, this.binaryReader, this.textDecoder);
39
+ // this.result.progress.bytesUsed = this.binaryReader.bytesUsed();
40
+ if (this.state !== STATE.END) {
41
+ this.state = STATE.ERROR;
42
+ this.result.error = 'DBF incomplete file';
43
+ }
44
+ }
45
+ }
46
+ /**
47
+ * @param arrayBuffer
48
+ * @param options
49
+ * @returns DBFTable or rows
50
+ */
51
+ export function parseDBF(arrayBuffer, options = {}) {
52
+ const { encoding = 'latin1' } = options.dbf || {};
53
+ const dbfParser = new DBFParser({ encoding });
54
+ dbfParser.write(arrayBuffer);
55
+ dbfParser.end();
56
+ const tableBuilder = dbfParser.result.tableBuilder;
57
+ const arrowTable = tableBuilder.finishTable();
58
+ return arrowTable;
59
+ }
60
+ /**
61
+ * @param asyncIterator
62
+ * @param options
63
+ */
64
+ export async function* parseDBFInBatches(asyncIterator, options = {}) {
65
+ const { encoding = 'latin1' } = options.dbf || {};
66
+ const parser = new DBFParser({ encoding });
67
+ let headerReturned = false;
68
+ for await (const arrayBuffer of asyncIterator) {
69
+ parser.write(arrayBuffer);
70
+ if (!headerReturned && parser.result.dbfHeader) {
71
+ headerReturned = true;
72
+ const tableBuilder = parser.result.tableBuilder;
73
+ const tableBatch = tableBuilder.firstBatch();
74
+ if (tableBatch) {
75
+ yield tableBatch;
76
+ }
77
+ }
78
+ const tableBuilder = parser.result.tableBuilder;
79
+ const tableBatch = tableBuilder.flushBatch();
80
+ if (tableBatch) {
81
+ yield tableBatch;
82
+ }
83
+ }
84
+ parser.end();
85
+ const tableBuilder = parser.result.tableBuilder;
86
+ const tableBatch = tableBuilder.finishBatch();
87
+ if (tableBatch) {
88
+ yield tableBatch;
89
+ }
90
+ }
91
+ /**
92
+ * https://www.dbase.com/Knowledgebase/INT/db7_file_fmt.htm
93
+ * @param state
94
+ * @param result
95
+ * @param binaryReader
96
+ * @param textDecoder
97
+ * @returns
98
+ */
99
+ /* eslint-disable complexity, max-depth */
100
+ function parseState(state, result, binaryReader, textDecoder) {
101
+ // eslint-disable-next-line no-constant-condition
102
+ while (true) {
103
+ try {
104
+ switch (state) {
105
+ case STATE.ERROR:
106
+ case STATE.END:
107
+ return state;
108
+ case STATE.START:
109
+ // Parse initial file header
110
+ // DBF Header
111
+ const dataView = binaryReader.getDataView(DBF_HEADER_SIZE);
112
+ if (!dataView) {
113
+ return state;
114
+ }
115
+ result.dbfHeader = parseDBFHeader(dataView);
116
+ result.progress = {
117
+ bytesUsed: 0,
118
+ rowsTotal: result.dbfHeader.nRecords,
119
+ rows: 0
120
+ };
121
+ state = STATE.FIELD_DESCRIPTORS;
122
+ break;
123
+ case STATE.FIELD_DESCRIPTORS:
124
+ // Parse DBF field descriptors (schema)
125
+ const fieldDescriptorView = binaryReader.getDataView(
126
+ // @ts-ignore
127
+ result.dbfHeader.headerLength - DBF_HEADER_SIZE);
128
+ if (!fieldDescriptorView) {
129
+ return state;
130
+ }
131
+ result.dbfFields = parseFieldDescriptors(fieldDescriptorView, textDecoder);
132
+ const schema = {
133
+ fields: result.dbfFields.map((dbfField) => makeField(dbfField)),
134
+ metadata: {}
135
+ };
136
+ result.tableBuilder = new ArrowTableBuilder(schema);
137
+ state = STATE.FIELD_PROPERTIES;
138
+ // TODO(kyle) Not exactly sure why start offset needs to be headerLength + 1?
139
+ // parsedbf uses ((fields.length + 1) << 5) + 2;
140
+ binaryReader.skip(1);
141
+ break;
142
+ case STATE.FIELD_PROPERTIES:
143
+ const { recordLength = 0, nRecords = 0 } = result?.dbfHeader || {};
144
+ let rowCount = 0;
145
+ while (rowCount < nRecords) {
146
+ rowCount++;
147
+ const recordView = binaryReader.getDataView(recordLength - 1);
148
+ if (!recordView) {
149
+ return state;
150
+ }
151
+ // Note: Avoid actually reading the last byte, which may not be present
152
+ binaryReader.skip(1);
153
+ // @ts-ignore
154
+ const row = parseRow(recordView, result.dbfFields, textDecoder);
155
+ result.tableBuilder.addObjectRow(row);
156
+ // result.progress.rows = result.data.length;
157
+ }
158
+ state = STATE.END;
159
+ break;
160
+ default:
161
+ state = STATE.ERROR;
162
+ result.error = `illegal parser state ${state}`;
163
+ return state;
164
+ }
165
+ }
166
+ catch (error) {
167
+ state = STATE.ERROR;
168
+ result.error = `DBF parsing failed: ${error.message}`;
169
+ return state;
170
+ }
171
+ }
172
+ }
173
+ /**
174
+ * @param headerView
175
+ */
176
+ function parseDBFHeader(headerView) {
177
+ return {
178
+ // Last updated date
179
+ year: headerView.getUint8(1) + 1900,
180
+ month: headerView.getUint8(2),
181
+ day: headerView.getUint8(3),
182
+ // Number of records in data file
183
+ nRecords: headerView.getUint32(4, LITTLE_ENDIAN),
184
+ // Length of header in bytes
185
+ headerLength: headerView.getUint16(8, LITTLE_ENDIAN),
186
+ // Length of each record
187
+ recordLength: headerView.getUint16(10, LITTLE_ENDIAN),
188
+ // Not sure if this is usually set
189
+ languageDriver: headerView.getUint8(29)
190
+ };
191
+ }
192
+ /**
193
+ * @param view
194
+ */
195
+ function parseFieldDescriptors(view, textDecoder) {
196
+ // NOTE: this might overestimate the number of fields if the "Database
197
+ // Container" container exists and is included in the headerLength
198
+ const nFields = (view.byteLength - 1) / 32;
199
+ const fields = [];
200
+ let offset = 0;
201
+ for (let i = 0; i < nFields; i++) {
202
+ const name = textDecoder
203
+ .decode(new Uint8Array(view.buffer, view.byteOffset + offset, 11))
204
+ // eslint-disable-next-line no-control-regex
205
+ .replace(/\u0000/g, '');
206
+ fields.push({
207
+ name,
208
+ dataType: String.fromCharCode(view.getUint8(offset + 11)),
209
+ fieldLength: view.getUint8(offset + 16),
210
+ decimal: view.getUint8(offset + 17)
211
+ });
212
+ offset += 32;
213
+ }
214
+ return fields;
215
+ }
216
+ /**
217
+ *
218
+ * @param view
219
+ * @param fields
220
+ * @param textDecoder
221
+ * @returns
222
+ */
223
+ function parseRow(view, fields, textDecoder) {
224
+ const out = {};
225
+ let offset = 0;
226
+ for (const field of fields) {
227
+ const text = textDecoder.decode(new Uint8Array(view.buffer, view.byteOffset + offset, field.fieldLength));
228
+ out[field.name] = parseField(text, field.dataType);
229
+ offset += field.fieldLength;
230
+ }
231
+ return out;
232
+ }
233
+ /**
234
+ * Should NaN be coerced to null?
235
+ * @param text
236
+ * @param dataType
237
+ * @returns Field depends on a type of the data
238
+ */
239
+ function parseField(text, dataType) {
240
+ switch (dataType) {
241
+ case 'B':
242
+ return parseNumber(text);
243
+ case 'C':
244
+ return parseCharacter(text);
245
+ case 'F':
246
+ return parseNumber(text);
247
+ case 'N':
248
+ return parseNumber(text);
249
+ case 'O':
250
+ return parseNumber(text);
251
+ case 'D':
252
+ return parseDate(text);
253
+ case 'L':
254
+ return parseBoolean(text);
255
+ default:
256
+ throw new Error('Unsupported data type');
257
+ }
258
+ }
259
+ /**
260
+ * Parse YYYYMMDD to date in milliseconds
261
+ * @param str YYYYMMDD
262
+ * @returns new Date as a number
263
+ */
264
+ function parseDate(str) {
265
+ return Date.UTC(str.slice(0, 4), parseInt(str.slice(4, 6), 10) - 1, str.slice(6, 8));
266
+ }
267
+ /**
268
+ * Read boolean value
269
+ * any of Y, y, T, t coerce to true
270
+ * any of N, n, F, f coerce to false
271
+ * otherwise null
272
+ * @param value
273
+ * @returns boolean | null
274
+ */
275
+ function parseBoolean(value) {
276
+ return /^[nf]$/i.test(value) ? false : /^[yt]$/i.test(value) ? true : null;
277
+ }
278
+ /**
279
+ * Return null instead of NaN
280
+ * @param text
281
+ * @returns number | null
282
+ */
283
+ function parseNumber(text) {
284
+ const number = parseFloat(text);
285
+ return isNaN(number) ? null : number;
286
+ }
287
+ /**
288
+ *
289
+ * @param text
290
+ * @returns string | null
291
+ */
292
+ function parseCharacter(text) {
293
+ return text.trim() || null;
294
+ }
295
+ /**
296
+ * Create a standard Arrow-style `Field` from field descriptor.
297
+ * TODO - use `fieldLength` and `decimal` to generate smaller types?
298
+ * @param param0
299
+ * @returns Field
300
+ */
301
+ // eslint-disable
302
+ function makeField({ name, dataType, fieldLength, decimal }) {
303
+ switch (dataType) {
304
+ case 'B':
305
+ return { name, type: 'float64', nullable: true, metadata: {} };
306
+ case 'C':
307
+ return { name, type: 'utf8', nullable: true, metadata: {} };
308
+ case 'F':
309
+ return { name, type: 'float64', nullable: true, metadata: {} };
310
+ case 'N':
311
+ return { name, type: 'float64', nullable: true, metadata: {} };
312
+ case 'O':
313
+ return { name, type: 'float64', nullable: true, metadata: {} };
314
+ case 'D':
315
+ return { name, type: 'timestamp-millisecond', nullable: true, metadata: {} };
316
+ case 'L':
317
+ return { name, type: 'bool', nullable: true, metadata: {} };
318
+ default:
319
+ throw new Error('Unsupported data type');
320
+ }
321
+ }
@@ -1,4 +1,4 @@
1
- import { ObjectRowTable } from '@loaders.gl/schema';
1
+ import type { ObjectRowTable } from '@loaders.gl/schema';
2
2
  import { DBFLoaderOptions, DBFTableOutput, DBFHeader, DBFRowsOutput } from "./types.js";
3
3
  /**
4
4
  * @param arrayBuffer
@@ -1 +1 @@
1
- {"version":3,"file":"parse-dbf.d.ts","sourceRoot":"","sources":["../../../src/lib/parsers/parse-dbf.ts"],"names":[],"mappings":"AAIA,OAAO,EAAQ,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EACL,gBAAgB,EAEhB,cAAc,EACd,SAAS,EACT,aAAa,EAEd,mBAAgB;AAkDjB;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,WAAW,EAAE,WAAW,EACxB,OAAO,GAAE,gBAAqB,GAC7B,aAAa,GAAG,cAAc,GAAG,cAAc,CAwBjD;AACD;;;GAGG;AACH,wBAAuB,iBAAiB,CACtC,aAAa,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,EACjE,OAAO,GAAE,gBAAqB,GAC7B,aAAa,CAAC,SAAS,GAAG,aAAa,GAAG,cAAc,CAAC,CAqB3D"}
1
+ {"version":3,"file":"parse-dbf.d.ts","sourceRoot":"","sources":["../../../src/lib/parsers/parse-dbf.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAQ,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAE9D,OAAO,EACL,gBAAgB,EAEhB,cAAc,EACd,SAAS,EACT,aAAa,EAEd,mBAAgB;AAkDjB;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,WAAW,EAAE,WAAW,EACxB,OAAO,GAAE,gBAAqB,GAC7B,aAAa,GAAG,cAAc,GAAG,cAAc,CAwBjD;AACD;;;GAGG;AACH,wBAAuB,iBAAiB,CACtC,aAAa,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,EACjE,OAAO,GAAE,gBAAqB,GAC7B,aAAa,CAAC,SAAS,GAAG,aAAa,GAAG,cAAc,CAAC,CAqB3D"}
@@ -3,7 +3,7 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
  // import type {Feature} from '@loaders.gl/gis';
5
5
  import { parseInBatchesFromContext, parseFromContext } from '@loaders.gl/loader-utils';
6
- import { binaryToGeometry, transformGeoJsonCoords } from '@loaders.gl/gis';
6
+ import { convertBinaryGeometryToGeometry, transformGeoJsonCoords } from '@loaders.gl/gis';
7
7
  import { Proj4Projection } from '@math.gl/proj4';
8
8
  import { parseShx } from "./parse-shx.js";
9
9
  import { zipBatchIterators } from "../streaming/zip-batch-iterators.js";
@@ -133,7 +133,7 @@ export async function parseShapefile(arrayBuffer, options, context) {
133
133
  function parseGeometries(geometries) {
134
134
  const geojsonGeometries = [];
135
135
  for (const geom of geometries) {
136
- geojsonGeometries.push(binaryToGeometry(geom));
136
+ geojsonGeometries.push(convertBinaryGeometryToGeometry(geom));
137
137
  }
138
138
  return geojsonGeometries;
139
139
  }
@@ -1,4 +1,4 @@
1
- import { BinaryGeometry } from '@loaders.gl/schema';
1
+ import type { BinaryGeometry } from '@loaders.gl/schema';
2
2
  import { SHPLoaderOptions } from "./types.js";
3
3
  /**
4
4
  * Parse individual record
@@ -1 +1 @@
1
- {"version":3,"file":"parse-shp-geometry.d.ts","sourceRoot":"","sources":["../../../src/lib/parsers/parse-shp-geometry.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,cAAc,EAAqB,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAC,gBAAgB,EAAC,mBAAgB;AAIzC;;;;;GAKG;AAEH,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,cAAc,GAAG,IAAI,CAoD7F"}
1
+ {"version":3,"file":"parse-shp-geometry.d.ts","sourceRoot":"","sources":["../../../src/lib/parsers/parse-shp-geometry.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,cAAc,EAAqB,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAC,gBAAgB,EAAC,mBAAgB;AAIzC;;;;;GAKG;AAEH,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,cAAc,GAAG,IAAI,CAoD7F"}
@@ -1,4 +1,4 @@
1
- import { Schema, ObjectRowTable } from '@loaders.gl/schema';
1
+ import type { Schema, ObjectRowTable } from '@loaders.gl/schema';
2
2
  import type { LoaderOptions } from '@loaders.gl/loader-utils';
3
3
  export type SHPLoaderOptions = LoaderOptions & {
4
4
  shp?: {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/parsers/types.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,MAAM,EAAE,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAC;AAE5D,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG;IAC7C,GAAG,CAAC,EAAE;QACJ,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG;IAC7C,GAAG,CAAC,EAAE;QACJ,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,kBAAkB,CAAC;KAC/C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,aAAa,GAChD,gBAAgB,GAAG;IACjB,SAAS,CAAC,EAAE;QACV,KAAK,CAAC,EAAE,eAAe,CAAC;KACzB,CAAC;IACF,GAAG,CAAC,EAAE;QACJ,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH,CAAC;AAEJ,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;AAEnD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,aAAa,CAAC;CACrB;AAED,MAAM,MAAM,SAAS,GAAG;IAEtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IAEZ,QAAQ,EAAE,MAAM,CAAC;IAEjB,YAAY,EAAE,MAAM,CAAC;IAErB,YAAY,EAAE,MAAM,CAAC;IAErB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAC,EAAE,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE;QACT,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/parsers/types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,MAAM,EAAE,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAC;AAE5D,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG;IAC7C,GAAG,CAAC,EAAE;QACJ,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG;IAC7C,GAAG,CAAC,EAAE;QACJ,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,kBAAkB,CAAC;KAC/C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,aAAa,GAChD,gBAAgB,GAAG;IACjB,SAAS,CAAC,EAAE;QACV,KAAK,CAAC,EAAE,eAAe,CAAC;KACzB,CAAC;IACF,GAAG,CAAC,EAAE;QACJ,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH,CAAC;AAEJ,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;AAEnD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,aAAa,CAAC;CACrB;AAED,MAAM,MAAM,SAAS,GAAG;IAEtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IAEZ,QAAQ,EAAE,MAAM,CAAC;IAEjB,YAAY,EAAE,MAAM,CAAC;IAErB,YAAY,EAAE,MAAM,CAAC;IAErB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAC,EAAE,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE;QACT,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"shapefile-loader.d.ts","sourceRoot":"","sources":["../src/shapefile-loader.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,aAAa,EAAmB,MAAM,0BAA0B,CAAC;AAE9E,OAAO,EAAC,cAAc,EAAE,uBAAuB,EAAC,yCAAsC;AAOtF,MAAM,MAAM,sBAAsB,GAAG,aAAa,GAAG;IACnD,SAAS,CAAC,EAAE;QACV,KAAK,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;QAC/B,qFAAqF;QACrF,SAAS,CAAC,EAAE,KAAK,CAAC;KACnB,CAAC;CACH,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;CAqBsD,CAAC"}
1
+ {"version":3,"file":"shapefile-loader.d.ts","sourceRoot":"","sources":["../src/shapefile-loader.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,aAAa,EAAmB,MAAM,0BAA0B,CAAC;AAG9E,OAAO,EAAC,cAAc,EAAE,uBAAuB,EAAC,yCAAsC;AAMtF,MAAM,MAAM,sBAAsB,GAAG,aAAa,GAAG;IACnD,SAAS,CAAC,EAAE;QACV,KAAK,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;QAC/B,qFAAqF;QACrF,SAAS,CAAC,EAAE,KAAK,CAAC;KACnB,CAAC;CACH,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;CAqBsD,CAAC"}
@@ -5,7 +5,7 @@ import { SHP_MAGIC_NUMBER } from "./shp-loader.js";
5
5
  import { parseShapefile, parseShapefileInBatches } from "./lib/parsers/parse-shapefile.js";
6
6
  // __VERSION__ is injected by babel-plugin-version-inline
7
7
  // @ts-ignore TS2304: Cannot find name '__VERSION__'.
8
- const VERSION = typeof "4.3.0" !== 'undefined' ? "4.3.0" : 'latest';
8
+ const VERSION = typeof "4.4.0-alpha.0" !== 'undefined' ? "4.4.0-alpha.0" : 'latest';
9
9
  /**
10
10
  * Shapefile loader
11
11
  * @note Shapefile is multifile format and requires providing additional files
@@ -4,7 +4,7 @@
4
4
  import { parseSHP, parseSHPInBatches } from "./lib/parsers/parse-shp.js";
5
5
  // __VERSION__ is injected by babel-plugin-version-inline
6
6
  // @ts-ignore TS2304: Cannot find name '__VERSION__'.
7
- const VERSION = typeof "4.3.0" !== 'undefined' ? "4.3.0" : 'latest';
7
+ const VERSION = typeof "4.4.0-alpha.0" !== 'undefined' ? "4.4.0-alpha.0" : 'latest';
8
8
  export const SHP_MAGIC_NUMBER = [0x00, 0x00, 0x27, 0x0a];
9
9
  /**
10
10
  * SHP file loader
@@ -484,7 +484,7 @@
484
484
  }
485
485
 
486
486
  // src/shp-loader.ts
487
- var VERSION = true ? "4.3.0" : "latest";
487
+ var VERSION = true ? "4.4.0-alpha.0" : "latest";
488
488
  var SHP_MAGIC_NUMBER2 = [0, 0, 39, 10];
489
489
  var SHPWorkerLoader = {
490
490
  dataType: null,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@loaders.gl/shapefile",
3
3
  "description": "Loader for the Shapefile Format",
4
- "version": "4.3.1",
4
+ "version": "4.4.0-alpha.1",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "publishConfig": {
@@ -45,13 +45,13 @@
45
45
  "build-worker-dbf": "esbuild src/workers/dbf-worker.ts --bundle --outfile=dist/dbf-worker.js --define:__VERSION__=\\\"$npm_package_version\\\""
46
46
  },
47
47
  "dependencies": {
48
- "@loaders.gl/gis": "4.3.1",
49
- "@loaders.gl/loader-utils": "4.3.1",
50
- "@loaders.gl/schema": "4.3.1",
48
+ "@loaders.gl/gis": "4.4.0-alpha.1",
49
+ "@loaders.gl/loader-utils": "4.4.0-alpha.1",
50
+ "@loaders.gl/schema": "4.4.0-alpha.1",
51
51
  "@math.gl/proj4": "^4.1.0"
52
52
  },
53
53
  "peerDependencies": {
54
- "@loaders.gl/core": "^4.3.0"
54
+ "@loaders.gl/core": "4.4.0-alpha.0"
55
55
  },
56
- "gitHead": "70a883ab6bc84647c49963215dd6ff62d4d61de3"
56
+ "gitHead": "f1732de45907bd500bf4eedb4803beca8bf4bfb0"
57
57
  }
@@ -0,0 +1,46 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import type {Loader, LoaderWithParser, LoaderOptions} from '@loaders.gl/loader-utils';
6
+ import type {ArrowTable, ArrowTableBatch} from '@loaders.gl/schema';
7
+ import {parseDBF, parseDBFInBatches} from './lib/parsers/parse-dbf-to-arrow';
8
+ import {DBFFormat} from './dbf-format';
9
+
10
+ // __VERSION__ is injected by babel-plugin-version-inline
11
+ // @ts-ignore TS2304: Cannot find name '__VERSION__'.
12
+ const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
13
+
14
+ export type DBFLoaderOptions = LoaderOptions & {
15
+ dbf?: {
16
+ encoding?: string;
17
+ /** Override the URL to the worker bundle (by default loads from unpkg.com) */
18
+ workerUrl?: string;
19
+ };
20
+ };
21
+
22
+ /**
23
+ * DBFLoader - DBF files are used to contain non-geometry columns in Shapefiles
24
+ */
25
+ export const DBFArrowWorkerLoader = {
26
+ ...DBFFormat,
27
+ dataType: null as unknown as ArrowTable,
28
+ batchType: null as unknown as ArrowTableBatch,
29
+ version: VERSION,
30
+ worker: true,
31
+ options: {
32
+ dbf: {
33
+ encoding: 'latin1'
34
+ }
35
+ }
36
+ } as const satisfies Loader<ArrowTable, ArrowTableBatch, DBFLoaderOptions>;
37
+
38
+ /** DBF file loader */
39
+ export const DBFArrowLoader = {
40
+ ...DBFArrowWorkerLoader,
41
+ parse: async (arrayBuffer, options) => parseDBF(arrayBuffer, options),
42
+ parseSync: parseDBF,
43
+ parseInBatches(arrayBufferIterator: AsyncIterable<ArrayBuffer> | Iterable<ArrayBuffer>, options) {
44
+ return parseDBFInBatches(arrayBufferIterator, options);
45
+ }
46
+ } as const satisfies LoaderWithParser<ArrowTable, ArrowTableBatch, DBFLoaderOptions>;
@@ -0,0 +1,15 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import type {Format} from '@loaders.gl/loader-utils';
6
+
7
+ /** Information about the DBF format */
8
+ export const DBFFormat = {
9
+ name: 'DBF',
10
+ id: 'dbf',
11
+ module: 'shapefile',
12
+ category: 'table',
13
+ extensions: ['dbf'],
14
+ mimeTypes: ['application/x-dbf']
15
+ } as const satisfies Format;
package/src/index.ts CHANGED
@@ -7,6 +7,7 @@ export {ShapefileLoader} from './shapefile-loader';
7
7
 
8
8
  export type {DBFLoaderOptions} from './dbf-loader';
9
9
  export {DBFLoader, DBFWorkerLoader} from './dbf-loader';
10
+ export {DBFArrowLoader, DBFArrowWorkerLoader} from './dbf-arrow-loader';
10
11
 
11
12
  export type {SHPLoaderOptions} from './shp-loader';
12
13
  export {SHPLoader, SHPWorkerLoader} from './shp-loader';