@loaders.gl/shapefile 4.3.2 → 4.4.0-alpha.2
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.
- package/dist/dbf-arrow-loader.d.ts +52 -0
- package/dist/dbf-arrow-loader.d.ts.map +1 -0
- package/dist/dbf-arrow-loader.js +32 -0
- package/dist/dbf-format.d.ts +10 -0
- package/dist/dbf-format.d.ts.map +1 -0
- package/dist/dbf-format.js +12 -0
- package/dist/dbf-loader.js +1 -1
- package/dist/dbf-worker.js +1 -1
- package/dist/dist.dev.js +12231 -33
- package/dist/dist.min.js +11 -2
- package/dist/index.cjs +277 -10
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/lib/parsers/parse-dbf-to-arrow.d.ts +26 -0
- package/dist/lib/parsers/parse-dbf-to-arrow.d.ts.map +1 -0
- package/dist/lib/parsers/parse-dbf-to-arrow.js +321 -0
- package/dist/lib/parsers/parse-dbf.d.ts +1 -1
- package/dist/lib/parsers/parse-dbf.d.ts.map +1 -1
- package/dist/lib/parsers/parse-shapefile.js +2 -2
- package/dist/lib/parsers/parse-shp-geometry.d.ts +1 -1
- package/dist/lib/parsers/parse-shp-geometry.d.ts.map +1 -1
- package/dist/lib/parsers/types.d.ts +1 -1
- package/dist/lib/parsers/types.d.ts.map +1 -1
- package/dist/shapefile-loader.d.ts.map +1 -1
- package/dist/shapefile-loader.js +1 -1
- package/dist/shp-loader.js +1 -1
- package/dist/shp-worker.js +1 -1
- package/package.json +6 -6
- package/src/dbf-arrow-loader.ts +46 -0
- package/src/dbf-format.ts +15 -0
- package/src/index.ts +1 -0
- package/src/lib/parsers/parse-dbf-to-arrow.ts +382 -0
- package/src/lib/parsers/parse-dbf.ts +1 -1
- package/src/lib/parsers/parse-shapefile.ts +2 -2
- package/src/lib/parsers/parse-shp-geometry.ts +1 -1
- package/src/lib/parsers/types.ts +1 -1
- 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 +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;
|
|
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 {
|
|
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(
|
|
136
|
+
geojsonGeometries.push(convertBinaryGeometryToGeometry(geom));
|
|
137
137
|
}
|
|
138
138
|
return geojsonGeometries;
|
|
139
139
|
}
|
|
@@ -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;
|
|
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 +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;
|
|
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;
|
|
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"}
|
package/dist/shapefile-loader.js
CHANGED
|
@@ -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.
|
|
8
|
+
const VERSION = typeof "4.4.0-alpha.1" !== 'undefined' ? "4.4.0-alpha.1" : 'latest';
|
|
9
9
|
/**
|
|
10
10
|
* Shapefile loader
|
|
11
11
|
* @note Shapefile is multifile format and requires providing additional files
|
package/dist/shp-loader.js
CHANGED
|
@@ -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.
|
|
7
|
+
const VERSION = typeof "4.4.0-alpha.1" !== 'undefined' ? "4.4.0-alpha.1" : 'latest';
|
|
8
8
|
export const SHP_MAGIC_NUMBER = [0x00, 0x00, 0x27, 0x0a];
|
|
9
9
|
/**
|
|
10
10
|
* SHP file loader
|
package/dist/shp-worker.js
CHANGED
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.
|
|
4
|
+
"version": "4.4.0-alpha.2",
|
|
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.
|
|
49
|
-
"@loaders.gl/loader-utils": "4.
|
|
50
|
-
"@loaders.gl/schema": "4.
|
|
48
|
+
"@loaders.gl/gis": "4.4.0-alpha.2",
|
|
49
|
+
"@loaders.gl/loader-utils": "4.4.0-alpha.2",
|
|
50
|
+
"@loaders.gl/schema": "4.4.0-alpha.2",
|
|
51
51
|
"@math.gl/proj4": "^4.1.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
|
-
"@loaders.gl/core": "
|
|
54
|
+
"@loaders.gl/core": "4.4.0-alpha.1"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "3d9fed050eabdc0812ddf2f4d5fb9914a34ee0c2"
|
|
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';
|