@loaders.gl/pmtiles 4.0.0-beta.8 → 4.0.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.
- package/dist/dist.dev.js +123 -55
- package/dist/index.cjs +32 -19
- package/dist/lib/blob-source.d.ts +14 -0
- package/dist/lib/blob-source.d.ts.map +1 -0
- package/dist/lib/blob-source.js +19 -0
- package/dist/lib/blob-source.js.map +1 -0
- package/dist/lib/parse-pmtiles.d.ts +19 -18
- package/dist/lib/parse-pmtiles.d.ts.map +1 -1
- package/dist/lib/parse-pmtiles.js +20 -30
- package/dist/lib/parse-pmtiles.js.map +1 -1
- package/dist/pmtiles-source.d.ts +3 -8
- package/dist/pmtiles-source.d.ts.map +1 -1
- package/dist/pmtiles-source.js +9 -20
- package/dist/pmtiles-source.js.map +1 -1
- package/package.json +6 -6
- package/src/lib/blob-source.ts +40 -0
- package/src/lib/parse-pmtiles.ts +48 -56
- package/src/pmtiles-source.ts +14 -35
package/dist/dist.dev.js
CHANGED
|
@@ -1805,7 +1805,7 @@ var __exports__ = (() => {
|
|
|
1805
1805
|
}
|
|
1806
1806
|
};
|
|
1807
1807
|
|
|
1808
|
-
// ../gis/src/lib/flat-geojson-to-binary.ts
|
|
1808
|
+
// ../gis/src/lib/binary-features/flat-geojson-to-binary.ts
|
|
1809
1809
|
function flatGeojsonToBinary(features, geometryInfo, options) {
|
|
1810
1810
|
const propArrayTypes = extractNumericPropTypes(features);
|
|
1811
1811
|
const numericPropKeys = Object.keys(propArrayTypes).filter((k) => propArrayTypes[k] !== Array);
|
|
@@ -2837,70 +2837,88 @@ var __exports__ = (() => {
|
|
|
2837
2837
|
|
|
2838
2838
|
// ../mvt/src/lib/parse-tilejson.ts
|
|
2839
2839
|
var isObject = (x3) => x3 !== null && typeof x3 === "object";
|
|
2840
|
-
function parseTileJSON(jsonMetadata) {
|
|
2840
|
+
function parseTileJSON(jsonMetadata, options) {
|
|
2841
2841
|
if (!jsonMetadata || !isObject(jsonMetadata)) {
|
|
2842
2842
|
return null;
|
|
2843
2843
|
}
|
|
2844
|
-
const boundingBox = parseBounds(jsonMetadata.bounds);
|
|
2845
|
-
const center = parseCenter(jsonMetadata.center);
|
|
2846
|
-
const maxZoom = safeParseFloat(jsonMetadata.maxzoom);
|
|
2847
|
-
const minZoom = safeParseFloat(jsonMetadata.minzoom);
|
|
2848
2844
|
let tileJSON = {
|
|
2849
2845
|
name: jsonMetadata.name || "",
|
|
2850
|
-
description: jsonMetadata.description || ""
|
|
2851
|
-
boundingBox,
|
|
2852
|
-
center,
|
|
2853
|
-
maxZoom,
|
|
2854
|
-
minZoom,
|
|
2855
|
-
layers: []
|
|
2846
|
+
description: jsonMetadata.description || ""
|
|
2856
2847
|
};
|
|
2848
|
+
if (typeof jsonMetadata.generator === "string") {
|
|
2849
|
+
tileJSON.generator = jsonMetadata.generator;
|
|
2850
|
+
}
|
|
2851
|
+
if (typeof jsonMetadata.generator_options === "string") {
|
|
2852
|
+
tileJSON.generatorOptions = jsonMetadata.generator_options;
|
|
2853
|
+
}
|
|
2854
|
+
tileJSON.boundingBox = parseBounds(jsonMetadata.bounds) || parseBounds(jsonMetadata.antimeridian_adjusted_bounds);
|
|
2855
|
+
tileJSON.center = parseCenter(jsonMetadata.center);
|
|
2856
|
+
tileJSON.maxZoom = safeParseFloat(jsonMetadata.maxzoom);
|
|
2857
|
+
tileJSON.minZoom = safeParseFloat(jsonMetadata.minzoom);
|
|
2857
2858
|
if (typeof jsonMetadata?.json === "string") {
|
|
2858
2859
|
try {
|
|
2859
2860
|
tileJSON.metaJson = JSON.parse(jsonMetadata.json);
|
|
2860
|
-
} catch (
|
|
2861
|
+
} catch (error) {
|
|
2862
|
+
console.warn("Failed to parse tilejson.json field", error);
|
|
2861
2863
|
}
|
|
2862
2864
|
}
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2865
|
+
const tilestats = jsonMetadata.tilestats || tileJSON.metaJson?.tilestats;
|
|
2866
|
+
const tileStatsLayers = parseTilestatsLayers(tilestats, options);
|
|
2867
|
+
const tileJSONlayers = parseTileJSONLayers(jsonMetadata.vector_layers);
|
|
2868
|
+
const layers = mergeLayers(tileJSONlayers, tileStatsLayers);
|
|
2867
2869
|
tileJSON = {
|
|
2868
2870
|
...tileJSON,
|
|
2869
2871
|
layers
|
|
2870
2872
|
};
|
|
2873
|
+
if (tileJSON.maxZoom === null && layers.length > 0) {
|
|
2874
|
+
tileJSON.maxZoom = layers[0].maxZoom || null;
|
|
2875
|
+
}
|
|
2876
|
+
if (tileJSON.minZoom === null && layers.length > 0) {
|
|
2877
|
+
tileJSON.minZoom = layers[0].minZoom || null;
|
|
2878
|
+
}
|
|
2871
2879
|
return tileJSON;
|
|
2872
2880
|
}
|
|
2873
2881
|
function parseTileJSONLayers(layers) {
|
|
2874
2882
|
if (!Array.isArray(layers)) {
|
|
2875
2883
|
return [];
|
|
2876
2884
|
}
|
|
2877
|
-
return layers.map((layer) => (
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2885
|
+
return layers.map((layer) => parseTileJSONLayer(layer));
|
|
2886
|
+
}
|
|
2887
|
+
function parseTileJSONLayer(layer) {
|
|
2888
|
+
const fields = Object.entries(layer.fields || []).map(([key, datatype]) => ({
|
|
2889
|
+
name: key,
|
|
2890
|
+
...attributeTypeToFieldType(String(datatype))
|
|
2883
2891
|
}));
|
|
2892
|
+
const layer2 = {
|
|
2893
|
+
...layer
|
|
2894
|
+
};
|
|
2895
|
+
delete layer2.fields;
|
|
2896
|
+
return {
|
|
2897
|
+
name: layer.id || "",
|
|
2898
|
+
...layer2,
|
|
2899
|
+
fields
|
|
2900
|
+
};
|
|
2884
2901
|
}
|
|
2885
|
-
function parseTilestatsLayers(tilestats) {
|
|
2902
|
+
function parseTilestatsLayers(tilestats, options) {
|
|
2886
2903
|
if (isObject(tilestats) && Array.isArray(tilestats.layers)) {
|
|
2887
|
-
return tilestats.layers.map((layer) => parseTilestatsForLayer(layer));
|
|
2904
|
+
return tilestats.layers.map((layer) => parseTilestatsForLayer(layer, options));
|
|
2888
2905
|
}
|
|
2889
2906
|
return [];
|
|
2890
2907
|
}
|
|
2891
|
-
function parseTilestatsForLayer(layer) {
|
|
2908
|
+
function parseTilestatsForLayer(layer, options) {
|
|
2892
2909
|
const fields = [];
|
|
2893
2910
|
const indexedAttributes = {};
|
|
2894
2911
|
const attributes = layer.attributes || [];
|
|
2895
|
-
for (const
|
|
2896
|
-
const name =
|
|
2912
|
+
for (const attribute of attributes) {
|
|
2913
|
+
const name = attribute.attribute;
|
|
2897
2914
|
if (typeof name === "string") {
|
|
2898
2915
|
if (name.split("|").length > 1) {
|
|
2899
2916
|
const fname = name.split("|")[0];
|
|
2900
2917
|
indexedAttributes[fname] = indexedAttributes[fname] || [];
|
|
2901
|
-
indexedAttributes[fname].push(
|
|
2918
|
+
indexedAttributes[fname].push(attribute);
|
|
2919
|
+
console.warn("ignoring tilestats indexed field", fname);
|
|
2902
2920
|
} else if (!fields[name]) {
|
|
2903
|
-
fields
|
|
2921
|
+
fields.push(attributeToField(attribute, options));
|
|
2904
2922
|
} else {
|
|
2905
2923
|
}
|
|
2906
2924
|
}
|
|
@@ -2911,6 +2929,21 @@ var __exports__ = (() => {
|
|
|
2911
2929
|
fields
|
|
2912
2930
|
};
|
|
2913
2931
|
}
|
|
2932
|
+
function mergeLayers(layers, tilestatsLayers) {
|
|
2933
|
+
return layers.map((layer) => {
|
|
2934
|
+
const tilestatsLayer = tilestatsLayers.find((tsLayer) => tsLayer.name === layer.name);
|
|
2935
|
+
const fields = tilestatsLayer?.fields || [];
|
|
2936
|
+
const layer2 = {
|
|
2937
|
+
...layer
|
|
2938
|
+
};
|
|
2939
|
+
delete layer2.fields;
|
|
2940
|
+
return {
|
|
2941
|
+
...layer2,
|
|
2942
|
+
...tilestatsLayer,
|
|
2943
|
+
fields
|
|
2944
|
+
};
|
|
2945
|
+
});
|
|
2946
|
+
}
|
|
2914
2947
|
function parseBounds(bounds) {
|
|
2915
2948
|
const result = fromArrayOrString(bounds);
|
|
2916
2949
|
if (Array.isArray(result) && result.length === 4 && [result[0], result[2]].every(isLng) && [result[1], result[3]].every(isLat)) {
|
|
@@ -2975,12 +3008,25 @@ var __exports__ = (() => {
|
|
|
2975
3008
|
type: "boolean"
|
|
2976
3009
|
}
|
|
2977
3010
|
};
|
|
2978
|
-
function attributeToField(attribute = {}) {
|
|
3011
|
+
function attributeToField(attribute = {}, options) {
|
|
2979
3012
|
const fieldTypes = attributeTypeToFieldType(attribute.type);
|
|
2980
|
-
|
|
3013
|
+
const field = {
|
|
2981
3014
|
name: attribute.attribute,
|
|
2982
3015
|
...fieldTypes
|
|
2983
3016
|
};
|
|
3017
|
+
if (typeof attribute.min === "number") {
|
|
3018
|
+
field.min = attribute.min;
|
|
3019
|
+
}
|
|
3020
|
+
if (typeof attribute.max === "number") {
|
|
3021
|
+
field.max = attribute.max;
|
|
3022
|
+
}
|
|
3023
|
+
if (typeof attribute.count === "number") {
|
|
3024
|
+
field.uniqueValueCount = attribute.count;
|
|
3025
|
+
}
|
|
3026
|
+
if (options.maxValues !== false && attribute.values) {
|
|
3027
|
+
field.values = attribute.values?.slice(0, options.maxValues);
|
|
3028
|
+
}
|
|
3029
|
+
return field;
|
|
2984
3030
|
}
|
|
2985
3031
|
function attributeTypeToFieldType(aType) {
|
|
2986
3032
|
const type = aType.toLowerCase();
|
|
@@ -3003,16 +3049,26 @@ var __exports__ = (() => {
|
|
|
3003
3049
|
mimeTypes: ["application/json"],
|
|
3004
3050
|
text: true,
|
|
3005
3051
|
options: {
|
|
3006
|
-
tilejson: {
|
|
3052
|
+
tilejson: {
|
|
3053
|
+
maxValues: 10
|
|
3054
|
+
}
|
|
3007
3055
|
},
|
|
3008
3056
|
parse: async (arrayBuffer, options) => {
|
|
3009
3057
|
const jsonString = new TextDecoder().decode(arrayBuffer);
|
|
3010
3058
|
const json = JSON.parse(jsonString);
|
|
3011
|
-
|
|
3059
|
+
const tilejsonOptions = {
|
|
3060
|
+
...TileJSONLoader.options.tilejson,
|
|
3061
|
+
...options?.tilejson
|
|
3062
|
+
};
|
|
3063
|
+
return parseTileJSON(json, tilejsonOptions);
|
|
3012
3064
|
},
|
|
3013
3065
|
parseTextSync: (text, options) => {
|
|
3014
3066
|
const json = JSON.parse(text);
|
|
3015
|
-
|
|
3067
|
+
const tilejsonOptions = {
|
|
3068
|
+
...TileJSONLoader.options.tilejson,
|
|
3069
|
+
...options?.tilejson
|
|
3070
|
+
};
|
|
3071
|
+
return parseTileJSON(json, tilejsonOptions);
|
|
3016
3072
|
}
|
|
3017
3073
|
};
|
|
3018
3074
|
|
|
@@ -4551,23 +4607,31 @@ var __exports__ = (() => {
|
|
|
4551
4607
|
|
|
4552
4608
|
// src/lib/parse-pmtiles.ts
|
|
4553
4609
|
var {
|
|
4554
|
-
PMTiles: PMTiles2,
|
|
4555
4610
|
TileType: TileType2
|
|
4556
4611
|
} = dist_exports;
|
|
4557
|
-
function parsePMTilesHeader(header,
|
|
4612
|
+
function parsePMTilesHeader(header, pmtilesMetadata, options) {
|
|
4613
|
+
let tilejson = null;
|
|
4614
|
+
if (pmtilesMetadata) {
|
|
4615
|
+
try {
|
|
4616
|
+
const string = JSON.stringify(pmtilesMetadata);
|
|
4617
|
+
tilejson = TileJSONLoader.parseTextSync?.(string) || null;
|
|
4618
|
+
} catch (error) {
|
|
4619
|
+
console.warn("PMTiles metadata could not be interpreted as TileJSON", error);
|
|
4620
|
+
}
|
|
4621
|
+
}
|
|
4558
4622
|
const partialMetadata = {};
|
|
4559
|
-
if (typeof
|
|
4560
|
-
partialMetadata.name =
|
|
4623
|
+
if (typeof tilejson?.name === "string") {
|
|
4624
|
+
partialMetadata.name = tilejson.name;
|
|
4561
4625
|
}
|
|
4562
|
-
if (typeof
|
|
4563
|
-
partialMetadata.attributions = [
|
|
4626
|
+
if (typeof tilejson?.htmlAttribution === "string") {
|
|
4627
|
+
partialMetadata.attributions = [tilejson.htmlAttribution];
|
|
4564
4628
|
}
|
|
4565
4629
|
const metadata = {
|
|
4566
4630
|
...partialMetadata,
|
|
4567
4631
|
format: "pmtiles",
|
|
4568
4632
|
formatVersion: header.specVersion,
|
|
4569
|
-
|
|
4570
|
-
|
|
4633
|
+
attributions: [],
|
|
4634
|
+
tileMIMEType: decodeTileType(header.tileType),
|
|
4571
4635
|
minZoom: header.minZoom,
|
|
4572
4636
|
maxZoom: header.maxZoom,
|
|
4573
4637
|
boundingBox: [[header.minLon, header.minLat], [header.maxLon, header.maxLat]],
|
|
@@ -4575,15 +4639,12 @@ var __exports__ = (() => {
|
|
|
4575
4639
|
centerZoom: header.centerZoom,
|
|
4576
4640
|
etag: header.etag
|
|
4577
4641
|
};
|
|
4578
|
-
if (
|
|
4579
|
-
|
|
4580
|
-
metadata.tileJSON = TileJSONLoader.parseTextSync?.(JSON.stringify(tilejsonMetadata)) || void 0;
|
|
4581
|
-
} catch (error) {
|
|
4582
|
-
metadata.tilejsonMetadata = tilejsonMetadata;
|
|
4583
|
-
}
|
|
4642
|
+
if (tilejson) {
|
|
4643
|
+
metadata.tilejson = tilejson;
|
|
4584
4644
|
}
|
|
4585
4645
|
if (options?.includeFormatHeader) {
|
|
4586
4646
|
metadata.formatHeader = header;
|
|
4647
|
+
metadata.formatMetadata = metadata;
|
|
4587
4648
|
}
|
|
4588
4649
|
return metadata;
|
|
4589
4650
|
}
|
|
@@ -4604,10 +4665,7 @@ var __exports__ = (() => {
|
|
|
4604
4665
|
}
|
|
4605
4666
|
}
|
|
4606
4667
|
|
|
4607
|
-
// src/
|
|
4608
|
-
var {
|
|
4609
|
-
PMTiles: PMTiles3
|
|
4610
|
-
} = dist_exports;
|
|
4668
|
+
// src/lib/blob-source.ts
|
|
4611
4669
|
var BlobSource = class {
|
|
4612
4670
|
constructor(blob, key) {
|
|
4613
4671
|
this.blob = blob;
|
|
@@ -4624,12 +4682,19 @@ var __exports__ = (() => {
|
|
|
4624
4682
|
};
|
|
4625
4683
|
}
|
|
4626
4684
|
};
|
|
4685
|
+
|
|
4686
|
+
// src/pmtiles-source.ts
|
|
4687
|
+
var {
|
|
4688
|
+
PMTiles: PMTiles2
|
|
4689
|
+
} = dist_exports;
|
|
4627
4690
|
var PMTilesSource = class extends DataSource {
|
|
4691
|
+
mimeType = null;
|
|
4628
4692
|
constructor(props) {
|
|
4629
4693
|
super(props);
|
|
4630
4694
|
this.props = props;
|
|
4631
4695
|
const url = typeof props.url === "string" ? resolvePath(props.url) : new BlobSource(props.url, "pmtiles");
|
|
4632
|
-
this.
|
|
4696
|
+
this.data = props.url;
|
|
4697
|
+
this.pmtiles = new PMTiles2(url);
|
|
4633
4698
|
this.getTileData = this.getTileData.bind(this);
|
|
4634
4699
|
this.metadata = this.getMetadata();
|
|
4635
4700
|
}
|
|
@@ -4640,6 +4705,9 @@ var __exports__ = (() => {
|
|
|
4640
4705
|
if (this.props.attributions) {
|
|
4641
4706
|
metadata.attributions = [...this.props.attributions, ...metadata.attributions || []];
|
|
4642
4707
|
}
|
|
4708
|
+
if (metadata?.tileMIMEType) {
|
|
4709
|
+
this.mimeType = metadata?.tileMIMEType;
|
|
4710
|
+
}
|
|
4643
4711
|
return metadata;
|
|
4644
4712
|
}
|
|
4645
4713
|
async getTile(tileParams) {
|
|
@@ -4662,7 +4730,7 @@ var __exports__ = (() => {
|
|
|
4662
4730
|
z
|
|
4663
4731
|
} = tileParams.index;
|
|
4664
4732
|
const metadata = await this.metadata;
|
|
4665
|
-
switch (metadata.
|
|
4733
|
+
switch (metadata.tileMIMEType) {
|
|
4666
4734
|
case "application/vnd.mapbox-vector-tile":
|
|
4667
4735
|
return await this.getVectorTile({
|
|
4668
4736
|
x: x3,
|
package/dist/index.cjs
CHANGED
|
@@ -38,26 +38,36 @@ module.exports = __toCommonJS(src_exports);
|
|
|
38
38
|
var import_loader_utils = require("@loaders.gl/loader-utils");
|
|
39
39
|
var import_images = require("@loaders.gl/images");
|
|
40
40
|
var import_mvt2 = require("@loaders.gl/mvt");
|
|
41
|
+
var pmtiles2 = __toESM(require("pmtiles"), 1);
|
|
41
42
|
|
|
42
43
|
// src/lib/parse-pmtiles.ts
|
|
43
44
|
var import_mvt = require("@loaders.gl/mvt");
|
|
44
45
|
var pmtiles = __toESM(require("pmtiles"), 1);
|
|
45
|
-
var {
|
|
46
|
-
function parsePMTilesHeader(header,
|
|
46
|
+
var { TileType } = pmtiles;
|
|
47
|
+
function parsePMTilesHeader(header, pmtilesMetadata, options) {
|
|
47
48
|
var _a, _b;
|
|
49
|
+
let tilejson = null;
|
|
50
|
+
if (pmtilesMetadata) {
|
|
51
|
+
try {
|
|
52
|
+
const string = JSON.stringify(pmtilesMetadata);
|
|
53
|
+
tilejson = ((_b = (_a = import_mvt.TileJSONLoader).parseTextSync) == null ? void 0 : _b.call(_a, string)) || null;
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.warn("PMTiles metadata could not be interpreted as TileJSON", error);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
48
58
|
const partialMetadata = {};
|
|
49
|
-
if (typeof (
|
|
50
|
-
partialMetadata.name =
|
|
59
|
+
if (typeof (tilejson == null ? void 0 : tilejson.name) === "string") {
|
|
60
|
+
partialMetadata.name = tilejson.name;
|
|
51
61
|
}
|
|
52
|
-
if (typeof (
|
|
53
|
-
partialMetadata.attributions = [
|
|
62
|
+
if (typeof (tilejson == null ? void 0 : tilejson.htmlAttribution) === "string") {
|
|
63
|
+
partialMetadata.attributions = [tilejson.htmlAttribution];
|
|
54
64
|
}
|
|
55
65
|
const metadata = {
|
|
56
66
|
...partialMetadata,
|
|
57
67
|
format: "pmtiles",
|
|
58
68
|
formatVersion: header.specVersion,
|
|
59
|
-
|
|
60
|
-
|
|
69
|
+
attributions: [],
|
|
70
|
+
tileMIMEType: decodeTileType(header.tileType),
|
|
61
71
|
minZoom: header.minZoom,
|
|
62
72
|
maxZoom: header.maxZoom,
|
|
63
73
|
boundingBox: [
|
|
@@ -68,15 +78,12 @@ function parsePMTilesHeader(header, tilejsonMetadata, options) {
|
|
|
68
78
|
centerZoom: header.centerZoom,
|
|
69
79
|
etag: header.etag
|
|
70
80
|
};
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
metadata.tileJSON = ((_b = (_a = import_mvt.TileJSONLoader).parseTextSync) == null ? void 0 : _b.call(_a, JSON.stringify(tilejsonMetadata))) || void 0;
|
|
74
|
-
} catch (error) {
|
|
75
|
-
metadata.tilejsonMetadata = tilejsonMetadata;
|
|
76
|
-
}
|
|
81
|
+
if (tilejson) {
|
|
82
|
+
metadata.tilejson = tilejson;
|
|
77
83
|
}
|
|
78
84
|
if (options == null ? void 0 : options.includeFormatHeader) {
|
|
79
85
|
metadata.formatHeader = header;
|
|
86
|
+
metadata.formatMetadata = metadata;
|
|
80
87
|
}
|
|
81
88
|
return metadata;
|
|
82
89
|
}
|
|
@@ -97,9 +104,7 @@ function decodeTileType(tileType) {
|
|
|
97
104
|
}
|
|
98
105
|
}
|
|
99
106
|
|
|
100
|
-
// src/
|
|
101
|
-
var pmtiles2 = __toESM(require("pmtiles"), 1);
|
|
102
|
-
var { PMTiles: PMTiles2 } = pmtiles2;
|
|
107
|
+
// src/lib/blob-source.ts
|
|
103
108
|
var BlobSource = class {
|
|
104
109
|
constructor(blob, key) {
|
|
105
110
|
this.blob = blob;
|
|
@@ -120,12 +125,17 @@ var BlobSource = class {
|
|
|
120
125
|
};
|
|
121
126
|
}
|
|
122
127
|
};
|
|
128
|
+
|
|
129
|
+
// src/pmtiles-source.ts
|
|
130
|
+
var { PMTiles } = pmtiles2;
|
|
123
131
|
var PMTilesSource = class extends import_loader_utils.DataSource {
|
|
124
132
|
constructor(props) {
|
|
125
133
|
super(props);
|
|
134
|
+
this.mimeType = null;
|
|
126
135
|
this.props = props;
|
|
127
136
|
const url = typeof props.url === "string" ? (0, import_loader_utils.resolvePath)(props.url) : new BlobSource(props.url, "pmtiles");
|
|
128
|
-
this.
|
|
137
|
+
this.data = props.url;
|
|
138
|
+
this.pmtiles = new PMTiles(url);
|
|
129
139
|
this.getTileData = this.getTileData.bind(this);
|
|
130
140
|
this.metadata = this.getMetadata();
|
|
131
141
|
}
|
|
@@ -136,6 +146,9 @@ var PMTilesSource = class extends import_loader_utils.DataSource {
|
|
|
136
146
|
if (this.props.attributions) {
|
|
137
147
|
metadata.attributions = [...this.props.attributions, ...metadata.attributions || []];
|
|
138
148
|
}
|
|
149
|
+
if (metadata == null ? void 0 : metadata.tileMIMEType) {
|
|
150
|
+
this.mimeType = metadata == null ? void 0 : metadata.tileMIMEType;
|
|
151
|
+
}
|
|
139
152
|
return metadata;
|
|
140
153
|
}
|
|
141
154
|
async getTile(tileParams) {
|
|
@@ -152,7 +165,7 @@ var PMTilesSource = class extends import_loader_utils.DataSource {
|
|
|
152
165
|
async getTileData(tileParams) {
|
|
153
166
|
const { x, y, z } = tileParams.index;
|
|
154
167
|
const metadata = await this.metadata;
|
|
155
|
-
switch (metadata.
|
|
168
|
+
switch (metadata.tileMIMEType) {
|
|
156
169
|
case "application/vnd.mapbox-vector-tile":
|
|
157
170
|
return await this.getVectorTile({ x, y, zoom: z, layers: [] });
|
|
158
171
|
default:
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as pmtiles from 'pmtiles';
|
|
2
|
+
/**
|
|
3
|
+
* A PMTiles library compatible source that reads from blobs
|
|
4
|
+
* @deprecated TODO - reimplement as ReadableFileSource
|
|
5
|
+
* Use loaders.gl HTTP range requests instead
|
|
6
|
+
*/
|
|
7
|
+
export declare class BlobSource implements pmtiles.Source {
|
|
8
|
+
blob: Blob;
|
|
9
|
+
key: string;
|
|
10
|
+
constructor(blob: Blob, key: string);
|
|
11
|
+
getKey(): any;
|
|
12
|
+
getBytes(offset: number, length: number, signal?: AbortSignal): Promise<pmtiles.RangeResponse>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=blob-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blob-source.d.ts","sourceRoot":"","sources":["../../src/lib/blob-source.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAEnC;;;;GAIG;AACH,qBAAa,UAAW,YAAW,OAAO,CAAC,MAAM;IAC/C,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;gBAEA,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM;IAMnC,MAAM;IAKA,QAAQ,CACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;CAUlC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export class BlobSource {
|
|
2
|
+
constructor(blob, key) {
|
|
3
|
+
this.blob = void 0;
|
|
4
|
+
this.key = void 0;
|
|
5
|
+
this.blob = blob;
|
|
6
|
+
this.key = key;
|
|
7
|
+
}
|
|
8
|
+
getKey() {
|
|
9
|
+
return this.blob.url || '';
|
|
10
|
+
}
|
|
11
|
+
async getBytes(offset, length, signal) {
|
|
12
|
+
const slice = this.blob.slice(offset, offset + length);
|
|
13
|
+
const data = await slice.arrayBuffer();
|
|
14
|
+
return {
|
|
15
|
+
data
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=blob-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blob-source.js","names":["BlobSource","constructor","blob","key","getKey","url","getBytes","offset","length","signal","slice","data","arrayBuffer"],"sources":["../../src/lib/blob-source.ts"],"sourcesContent":["// loaders.gl, MIT license\n// Copyright (c) vis.gl contributors\n\nimport * as pmtiles from 'pmtiles';\n\n/**\n * A PMTiles library compatible source that reads from blobs\n * @deprecated TODO - reimplement as ReadableFileSource\n * Use loaders.gl HTTP range requests instead\n */\nexport class BlobSource implements pmtiles.Source {\n blob: Blob;\n key: string;\n\n constructor(blob: Blob, key: string) {\n this.blob = blob;\n this.key = key;\n }\n\n // TODO - how is this used?\n getKey() {\n // @ts-expect-error url is only defined on File subclass\n return this.blob.url || '';\n }\n\n async getBytes(\n offset: number,\n length: number,\n signal?: AbortSignal\n ): Promise<pmtiles.RangeResponse> {\n const slice = this.blob.slice(offset, offset + length);\n const data = await slice.arrayBuffer();\n return {\n data\n // etag: response.headers.get('ETag') || undefined,\n // cacheControl: response.headers.get('Cache-Control') || undefined,\n // expires: response.headers.get('Expires') || undefined\n };\n }\n}\n"],"mappings":"AAUA,OAAO,MAAMA,UAAU,CAA2B;EAIhDC,WAAWA,CAACC,IAAU,EAAEC,GAAW,EAAE;IAAA,KAHrCD,IAAI;IAAA,KACJC,GAAG;IAGD,IAAI,CAACD,IAAI,GAAGA,IAAI;IAChB,IAAI,CAACC,GAAG,GAAGA,GAAG;EAChB;EAGAC,MAAMA,CAAA,EAAG;IAEP,OAAO,IAAI,CAACF,IAAI,CAACG,GAAG,IAAI,EAAE;EAC5B;EAEA,MAAMC,QAAQA,CACZC,MAAc,EACdC,MAAc,EACdC,MAAoB,EACY;IAChC,MAAMC,KAAK,GAAG,IAAI,CAACR,IAAI,CAACQ,KAAK,CAACH,MAAM,EAAEA,MAAM,GAAGC,MAAM,CAAC;IACtD,MAAMG,IAAI,GAAG,MAAMD,KAAK,CAACE,WAAW,CAAC,CAAC;IACtC,OAAO;MACLD;IAIF,CAAC;EACH;AACF"}
|
|
@@ -2,19 +2,15 @@ import type { TileJSON } from '@loaders.gl/mvt';
|
|
|
2
2
|
import * as pmtiles from 'pmtiles';
|
|
3
3
|
/** Metadata describing a PMTiles file */
|
|
4
4
|
export type PMTilesMetadata = {
|
|
5
|
-
/** Name of the tileset (extracted from JSON metadata if available) */
|
|
6
|
-
name?: string;
|
|
7
|
-
/** Attribution string (extracted from JSON metadata if available) */
|
|
8
|
-
attributions?: string[];
|
|
9
5
|
format: 'pmtiles';
|
|
10
6
|
/** Version of pm tiles format used by this tileset */
|
|
11
7
|
formatVersion: number;
|
|
12
|
-
/** PMTiles format specific header */
|
|
13
|
-
formatHeader?: pmtiles.Header;
|
|
14
8
|
/** MIME type for tile contents. Unknown tile types will return 'application/octet-stream */
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
|
|
9
|
+
tileMIMEType: 'application/vnd.mapbox-vector-tile' | 'image/png' | 'image/jpeg' | 'image/webp' | 'image/avif' | 'application/octet-stream';
|
|
10
|
+
/** Name of the tileset (extracted from JSON metadata if available) */
|
|
11
|
+
name?: string;
|
|
12
|
+
/** Attribution string (extracted from JSON metadata if available) */
|
|
13
|
+
attributions?: string[];
|
|
18
14
|
/** Minimal zoom level of tiles in this tileset */
|
|
19
15
|
minZoom: number;
|
|
20
16
|
/** Maximal zoom level of tiles in this tileset */
|
|
@@ -27,16 +23,21 @@ export type PMTilesMetadata = {
|
|
|
27
23
|
centerZoom: number;
|
|
28
24
|
/** Cache tag */
|
|
29
25
|
etag?: string;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
/** Parsed TileJSON/tilestats metadata, if present */
|
|
27
|
+
tilejson?: TileJSON;
|
|
28
|
+
/** @deprecated PMTiles format specific header */
|
|
29
|
+
formatHeader?: pmtiles.Header;
|
|
30
|
+
/** @deprecated Unparsed metadata (Assumption metadata generated by e.g. tippecanoe, typically TileJSON) */
|
|
31
|
+
formatMetadata?: Record<string, unknown>;
|
|
36
32
|
};
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Parse PMTiles metdata from a PMTiles file
|
|
35
|
+
* @param header
|
|
36
|
+
* @param tilejsonMetadata
|
|
37
|
+
* @param options
|
|
38
|
+
* @returns
|
|
39
|
+
*/
|
|
40
|
+
export declare function parsePMTilesHeader(header: pmtiles.Header, pmtilesMetadata: Record<string, unknown> | null, options?: {
|
|
40
41
|
includeFormatHeader?: boolean;
|
|
41
42
|
}): PMTilesMetadata;
|
|
42
43
|
//# sourceMappingURL=parse-pmtiles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-pmtiles.d.ts","sourceRoot":"","sources":["../../src/lib/parse-pmtiles.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,iBAAiB,CAAC;AAG9C,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAGnC,yCAAyC;AACzC,MAAM,MAAM,eAAe,GAAG;IAC5B,
|
|
1
|
+
{"version":3,"file":"parse-pmtiles.d.ts","sourceRoot":"","sources":["../../src/lib/parse-pmtiles.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,iBAAiB,CAAC;AAG9C,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAGnC,yCAAyC;AACzC,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,SAAS,CAAC;IAClB,sDAAsD;IACtD,aAAa,EAAE,MAAM,CAAC;IAEtB,4FAA4F;IAC5F,YAAY,EACR,oCAAoC,GACpC,WAAW,GACX,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,0BAA0B,CAAC;IAE/B,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,WAAW,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACxE,uCAAuC;IACvC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,qDAAqD;IACrD,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB,iDAAiD;IACjD,YAAY,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC;IAC9B,2GAA2G;IAC3G,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,OAAO,CAAC,MAAM,EACtB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EAC/C,OAAO,CAAC,EAAE;IAAC,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAAC,GACxC,eAAe,CAqDjB"}
|
|
@@ -1,39 +1,33 @@
|
|
|
1
1
|
import { TileJSONLoader } from '@loaders.gl/mvt';
|
|
2
2
|
import * as pmtiles from 'pmtiles';
|
|
3
3
|
const {
|
|
4
|
-
PMTiles,
|
|
5
4
|
TileType
|
|
6
5
|
} = pmtiles;
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
6
|
+
export function parsePMTilesHeader(header, pmtilesMetadata, options) {
|
|
7
|
+
var _tilejson, _tilejson2;
|
|
8
|
+
let tilejson = null;
|
|
9
|
+
if (pmtilesMetadata) {
|
|
10
|
+
try {
|
|
11
|
+
var _TileJSONLoader$parse;
|
|
12
|
+
const string = JSON.stringify(pmtilesMetadata);
|
|
13
|
+
tilejson = ((_TileJSONLoader$parse = TileJSONLoader.parseTextSync) === null || _TileJSONLoader$parse === void 0 ? void 0 : _TileJSONLoader$parse.call(TileJSONLoader, string)) || null;
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.warn('PMTiles metadata could not be interpreted as TileJSON', error);
|
|
16
|
+
}
|
|
18
17
|
}
|
|
19
|
-
const [z, x, y] = options.tileZxy;
|
|
20
|
-
const tile = await pmTiles.getZxy(z, x, y);
|
|
21
|
-
return tile === null || tile === void 0 ? void 0 : tile.data;
|
|
22
|
-
}
|
|
23
|
-
export function parsePMTilesHeader(header, tilejsonMetadata, options) {
|
|
24
18
|
const partialMetadata = {};
|
|
25
|
-
if (typeof (
|
|
26
|
-
partialMetadata.name =
|
|
19
|
+
if (typeof ((_tilejson = tilejson) === null || _tilejson === void 0 ? void 0 : _tilejson.name) === 'string') {
|
|
20
|
+
partialMetadata.name = tilejson.name;
|
|
27
21
|
}
|
|
28
|
-
if (typeof (
|
|
29
|
-
partialMetadata.attributions = [
|
|
22
|
+
if (typeof ((_tilejson2 = tilejson) === null || _tilejson2 === void 0 ? void 0 : _tilejson2.htmlAttribution) === 'string') {
|
|
23
|
+
partialMetadata.attributions = [tilejson.htmlAttribution];
|
|
30
24
|
}
|
|
31
25
|
const metadata = {
|
|
32
26
|
...partialMetadata,
|
|
33
27
|
format: 'pmtiles',
|
|
34
28
|
formatVersion: header.specVersion,
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
attributions: [],
|
|
30
|
+
tileMIMEType: decodeTileType(header.tileType),
|
|
37
31
|
minZoom: header.minZoom,
|
|
38
32
|
maxZoom: header.maxZoom,
|
|
39
33
|
boundingBox: [[header.minLon, header.minLat], [header.maxLon, header.maxLat]],
|
|
@@ -41,16 +35,12 @@ export function parsePMTilesHeader(header, tilejsonMetadata, options) {
|
|
|
41
35
|
centerZoom: header.centerZoom,
|
|
42
36
|
etag: header.etag
|
|
43
37
|
};
|
|
44
|
-
if (
|
|
45
|
-
|
|
46
|
-
var _TileJSONLoader$parse;
|
|
47
|
-
metadata.tileJSON = ((_TileJSONLoader$parse = TileJSONLoader.parseTextSync) === null || _TileJSONLoader$parse === void 0 ? void 0 : _TileJSONLoader$parse.call(TileJSONLoader, JSON.stringify(tilejsonMetadata))) || undefined;
|
|
48
|
-
} catch (error) {
|
|
49
|
-
metadata.tilejsonMetadata = tilejsonMetadata;
|
|
50
|
-
}
|
|
38
|
+
if (tilejson) {
|
|
39
|
+
metadata.tilejson = tilejson;
|
|
51
40
|
}
|
|
52
41
|
if (options !== null && options !== void 0 && options.includeFormatHeader) {
|
|
53
42
|
metadata.formatHeader = header;
|
|
43
|
+
metadata.formatMetadata = metadata;
|
|
54
44
|
}
|
|
55
45
|
return metadata;
|
|
56
46
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-pmtiles.js","names":["TileJSONLoader","pmtiles","
|
|
1
|
+
{"version":3,"file":"parse-pmtiles.js","names":["TileJSONLoader","pmtiles","TileType","parsePMTilesHeader","header","pmtilesMetadata","options","_tilejson","_tilejson2","tilejson","_TileJSONLoader$parse","string","JSON","stringify","parseTextSync","call","error","console","warn","partialMetadata","name","htmlAttribution","attributions","metadata","format","formatVersion","specVersion","tileMIMEType","decodeTileType","tileType","minZoom","maxZoom","boundingBox","minLon","minLat","maxLon","maxLat","center","centerLon","centerLat","centerZoom","etag","includeFormatHeader","formatHeader","formatMetadata","Mvt","Png","Jpeg","Webp","Avif"],"sources":["../../src/lib/parse-pmtiles.ts"],"sourcesContent":["// loaders.gl, MIT license\n// Copyright (c) vis.gl contributors\n\nimport type {TileJSON} from '@loaders.gl/mvt';\nimport {TileJSONLoader} from '@loaders.gl/mvt';\n// import {Source, PMTiles, Header, TileType} from 'pmtiles';\nimport * as pmtiles from 'pmtiles';\nconst {TileType} = pmtiles;\n\n/** Metadata describing a PMTiles file */\nexport type PMTilesMetadata = {\n format: 'pmtiles';\n /** Version of pm tiles format used by this tileset */\n formatVersion: number;\n\n /** MIME type for tile contents. Unknown tile types will return 'application/octet-stream */\n tileMIMEType:\n | 'application/vnd.mapbox-vector-tile'\n | 'image/png'\n | 'image/jpeg'\n | 'image/webp'\n | 'image/avif'\n | 'application/octet-stream';\n\n /** Name of the tileset (extracted from JSON metadata if available) */\n name?: string;\n /** Attribution string (extracted from JSON metadata if available) */\n attributions?: string[];\n\n /** Minimal zoom level of tiles in this tileset */\n minZoom: number;\n /** Maximal zoom level of tiles in this tileset */\n maxZoom: number;\n /** Bounding box of tiles in this tileset `[[w, s], [e, n]]` */\n boundingBox: [min: [x: number, y: number], max: [x: number, y: number]];\n /** Center long, lat of this tileset */\n center: [number, number];\n /** Center zoom level of this tileset */\n centerZoom: number;\n /** Cache tag */\n etag?: string;\n\n /** Parsed TileJSON/tilestats metadata, if present */\n tilejson?: TileJSON;\n\n /** @deprecated PMTiles format specific header */\n formatHeader?: pmtiles.Header;\n /** @deprecated Unparsed metadata (Assumption metadata generated by e.g. tippecanoe, typically TileJSON) */\n formatMetadata?: Record<string, unknown>;\n};\n\n/**\n * Parse PMTiles metdata from a PMTiles file\n * @param header\n * @param tilejsonMetadata\n * @param options\n * @returns\n */\nexport function parsePMTilesHeader(\n header: pmtiles.Header,\n pmtilesMetadata: Record<string, unknown> | null,\n options?: {includeFormatHeader?: boolean}\n): PMTilesMetadata {\n // Ironically, to use the TileJSON loader we need to stringify the metadata again.\n // This is the price of integrating with the existing pmtiles library.\n // TODO - provide a non-standard TileJSONLoader parsers that accepts a JSON object?\n let tilejson: TileJSON | null = null;\n if (pmtilesMetadata) {\n try {\n const string = JSON.stringify(pmtilesMetadata);\n tilejson = TileJSONLoader.parseTextSync?.(string) || null;\n } catch (error) {\n // eslint-disable-next-line no-console\n console.warn('PMTiles metadata could not be interpreted as TileJSON', error);\n }\n }\n\n const partialMetadata: Partial<PMTilesMetadata> = {};\n\n if (typeof tilejson?.name === 'string') {\n partialMetadata.name = tilejson.name;\n }\n\n if (typeof tilejson?.htmlAttribution === 'string') {\n partialMetadata.attributions = [tilejson.htmlAttribution];\n }\n\n const metadata: PMTilesMetadata = {\n ...partialMetadata,\n format: 'pmtiles',\n formatVersion: header.specVersion,\n attributions: [],\n tileMIMEType: decodeTileType(header.tileType),\n minZoom: header.minZoom,\n maxZoom: header.maxZoom,\n boundingBox: [\n [header.minLon, header.minLat],\n [header.maxLon, header.maxLat]\n ],\n center: [header.centerLon, header.centerLat],\n centerZoom: header.centerZoom,\n etag: header.etag\n };\n\n if (tilejson) {\n metadata.tilejson = tilejson;\n }\n\n // Application can optionally include the raw header and metadata.\n if (options?.includeFormatHeader) {\n metadata.formatHeader = header;\n metadata.formatMetadata = metadata;\n }\n\n return metadata;\n}\n\n/** Extract a MIME type for tiles from vector tile header */\nfunction decodeTileType(\n tileType: pmtiles.TileType\n):\n | 'application/vnd.mapbox-vector-tile'\n | 'image/png'\n | 'image/jpeg'\n | 'image/webp'\n | 'image/avif'\n | 'application/octet-stream' {\n switch (tileType) {\n case TileType.Mvt:\n return 'application/vnd.mapbox-vector-tile';\n case TileType.Png:\n return 'image/png';\n case TileType.Jpeg:\n return 'image/jpeg';\n case TileType.Webp:\n return 'image/webp';\n case TileType.Avif:\n return 'image/avif';\n default:\n return 'application/octet-stream';\n }\n}\n"],"mappings":"AAIA,SAAQA,cAAc,QAAO,iBAAiB;AAE9C,OAAO,KAAKC,OAAO,MAAM,SAAS;AAClC,MAAM;EAACC;AAAQ,CAAC,GAAGD,OAAO;AAmD1B,OAAO,SAASE,kBAAkBA,CAChCC,MAAsB,EACtBC,eAA+C,EAC/CC,OAAyC,EACxB;EAAA,IAAAC,SAAA,EAAAC,UAAA;EAIjB,IAAIC,QAAyB,GAAG,IAAI;EACpC,IAAIJ,eAAe,EAAE;IACnB,IAAI;MAAA,IAAAK,qBAAA;MACF,MAAMC,MAAM,GAAGC,IAAI,CAACC,SAAS,CAACR,eAAe,CAAC;MAC9CI,QAAQ,GAAG,EAAAC,qBAAA,GAAAV,cAAc,CAACc,aAAa,cAAAJ,qBAAA,uBAA5BA,qBAAA,CAAAK,IAAA,CAAAf,cAAc,EAAiBW,MAAM,CAAC,KAAI,IAAI;IAC3D,CAAC,CAAC,OAAOK,KAAK,EAAE;MAEdC,OAAO,CAACC,IAAI,CAAC,uDAAuD,EAAEF,KAAK,CAAC;IAC9E;EACF;EAEA,MAAMG,eAAyC,GAAG,CAAC,CAAC;EAEpD,IAAI,SAAAZ,SAAA,GAAOE,QAAQ,cAAAF,SAAA,uBAARA,SAAA,CAAUa,IAAI,MAAK,QAAQ,EAAE;IACtCD,eAAe,CAACC,IAAI,GAAGX,QAAQ,CAACW,IAAI;EACtC;EAEA,IAAI,SAAAZ,UAAA,GAAOC,QAAQ,cAAAD,UAAA,uBAARA,UAAA,CAAUa,eAAe,MAAK,QAAQ,EAAE;IACjDF,eAAe,CAACG,YAAY,GAAG,CAACb,QAAQ,CAACY,eAAe,CAAC;EAC3D;EAEA,MAAME,QAAyB,GAAG;IAChC,GAAGJ,eAAe;IAClBK,MAAM,EAAE,SAAS;IACjBC,aAAa,EAAErB,MAAM,CAACsB,WAAW;IACjCJ,YAAY,EAAE,EAAE;IAChBK,YAAY,EAAEC,cAAc,CAACxB,MAAM,CAACyB,QAAQ,CAAC;IAC7CC,OAAO,EAAE1B,MAAM,CAAC0B,OAAO;IACvBC,OAAO,EAAE3B,MAAM,CAAC2B,OAAO;IACvBC,WAAW,EAAE,CACX,CAAC5B,MAAM,CAAC6B,MAAM,EAAE7B,MAAM,CAAC8B,MAAM,CAAC,EAC9B,CAAC9B,MAAM,CAAC+B,MAAM,EAAE/B,MAAM,CAACgC,MAAM,CAAC,CAC/B;IACDC,MAAM,EAAE,CAACjC,MAAM,CAACkC,SAAS,EAAElC,MAAM,CAACmC,SAAS,CAAC;IAC5CC,UAAU,EAAEpC,MAAM,CAACoC,UAAU;IAC7BC,IAAI,EAAErC,MAAM,CAACqC;EACf,CAAC;EAED,IAAIhC,QAAQ,EAAE;IACZc,QAAQ,CAACd,QAAQ,GAAGA,QAAQ;EAC9B;EAGA,IAAIH,OAAO,aAAPA,OAAO,eAAPA,OAAO,CAAEoC,mBAAmB,EAAE;IAChCnB,QAAQ,CAACoB,YAAY,GAAGvC,MAAM;IAC9BmB,QAAQ,CAACqB,cAAc,GAAGrB,QAAQ;EACpC;EAEA,OAAOA,QAAQ;AACjB;AAGA,SAASK,cAAcA,CACrBC,QAA0B,EAOG;EAC7B,QAAQA,QAAQ;IACd,KAAK3B,QAAQ,CAAC2C,GAAG;MACf,OAAO,oCAAoC;IAC7C,KAAK3C,QAAQ,CAAC4C,GAAG;MACf,OAAO,WAAW;IACpB,KAAK5C,QAAQ,CAAC6C,IAAI;MAChB,OAAO,YAAY;IACrB,KAAK7C,QAAQ,CAAC8C,IAAI;MAChB,OAAO,YAAY;IACrB,KAAK9C,QAAQ,CAAC+C,IAAI;MAChB,OAAO,YAAY;IACrB;MACE,OAAO,0BAA0B;EACrC;AACF"}
|
package/dist/pmtiles-source.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import type { TileLoadParameters, GetTileParameters } from '@loaders.gl/loader-u
|
|
|
2
2
|
import type { ImageType, DataSourceProps } from '@loaders.gl/loader-utils';
|
|
3
3
|
import type { ImageTileSource, VectorTileSource } from '@loaders.gl/loader-utils';
|
|
4
4
|
import { DataSource } from '@loaders.gl/loader-utils';
|
|
5
|
-
import type { PMTilesMetadata } from './lib/parse-pmtiles';
|
|
6
5
|
import * as pmtiles from 'pmtiles';
|
|
6
|
+
import type { PMTilesMetadata } from './lib/parse-pmtiles';
|
|
7
7
|
export type Service = {
|
|
8
8
|
name: string;
|
|
9
9
|
id: string;
|
|
@@ -23,19 +23,14 @@ export type PMTilesSourceProps = DataSourceProps & {
|
|
|
23
23
|
url: string | Blob;
|
|
24
24
|
attributions?: string[];
|
|
25
25
|
};
|
|
26
|
-
export declare class BlobSource implements pmtiles.Source {
|
|
27
|
-
blob: Blob;
|
|
28
|
-
key: string;
|
|
29
|
-
constructor(blob: Blob, key: string);
|
|
30
|
-
getKey(): any;
|
|
31
|
-
getBytes(offset: number, length: number, signal?: AbortSignal): Promise<pmtiles.RangeResponse>;
|
|
32
|
-
}
|
|
33
26
|
/**
|
|
34
27
|
* A PMTiles data source
|
|
35
28
|
* @note Can be either a raster or vector tile source depending on the contents of the PMTiles file.
|
|
36
29
|
*/
|
|
37
30
|
export declare class PMTilesSource extends DataSource implements ImageTileSource, VectorTileSource {
|
|
31
|
+
data: string | Blob;
|
|
38
32
|
props: PMTilesSourceProps;
|
|
33
|
+
mimeType: string | null;
|
|
39
34
|
pmtiles: pmtiles.PMTiles;
|
|
40
35
|
metadata: Promise<PMTilesMetadata>;
|
|
41
36
|
constructor(props: PMTilesSourceProps);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pmtiles-source.d.ts","sourceRoot":"","sources":["../src/pmtiles-source.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,kBAAkB,EAAE,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AACpF,OAAO,KAAK,EAAC,SAAS,EAAE,eAAe,EAAC,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAC,eAAe,EAAE,gBAAgB,EAAC,MAAM,0BAA0B,CAAC;AAChF,OAAO,EAAC,UAAU,EAAc,MAAM,0BAA0B,CAAC;AAIjE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"pmtiles-source.d.ts","sourceRoot":"","sources":["../src/pmtiles-source.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,kBAAkB,EAAE,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AACpF,OAAO,KAAK,EAAC,SAAS,EAAE,eAAe,EAAC,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAC,eAAe,EAAE,gBAAgB,EAAC,MAAM,0BAA0B,CAAC;AAChF,OAAO,EAAC,UAAU,EAAc,MAAM,0BAA0B,CAAC;AAIjE,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAGnC,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,qBAAqB,CAAC;AAMzD,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAAC,OAAO,EAAE,YAAY,IAAI,OAAO,GAAG;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,YAAY,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC;CAChD,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,iBAAiB,CAAC,aAAa,EAAE,kBAAkB,CAW/E,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,eAAe,GAAG;IACjD,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AAEF;;;GAGG;AACH,qBAAa,aAAc,SAAQ,UAAW,YAAW,eAAe,EAAE,gBAAgB;IACxF,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC/B,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;gBAEvB,KAAK,EAAE,kBAAkB;IAW/B,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC;IAevC,OAAO,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAcnE,WAAW,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAapE,YAAY,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAOtE,aAAa,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;CAc5E"}
|
package/dist/pmtiles-source.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { DataSource, resolvePath } from '@loaders.gl/loader-utils';
|
|
2
2
|
import { ImageLoader } from '@loaders.gl/images';
|
|
3
3
|
import { MVTLoader } from '@loaders.gl/mvt';
|
|
4
|
-
import { parsePMTilesHeader } from "./lib/parse-pmtiles.js";
|
|
5
4
|
import * as pmtiles from 'pmtiles';
|
|
6
5
|
const {
|
|
7
6
|
PMTiles
|
|
8
7
|
} = pmtiles;
|
|
8
|
+
import { parsePMTilesHeader } from "./lib/parse-pmtiles.js";
|
|
9
|
+
import { BlobSource } from "./lib/blob-source.js";
|
|
9
10
|
const VERSION = '1.0.0';
|
|
10
11
|
export const PMTilesService = {
|
|
11
12
|
name: 'PMTiles',
|
|
@@ -19,32 +20,17 @@ export const PMTilesService = {
|
|
|
19
20
|
},
|
|
20
21
|
createSource: props => new PMTilesSource(props)
|
|
21
22
|
};
|
|
22
|
-
export class BlobSource {
|
|
23
|
-
constructor(blob, key) {
|
|
24
|
-
this.blob = void 0;
|
|
25
|
-
this.key = void 0;
|
|
26
|
-
this.blob = blob;
|
|
27
|
-
this.key = key;
|
|
28
|
-
}
|
|
29
|
-
getKey() {
|
|
30
|
-
return this.blob.url || '';
|
|
31
|
-
}
|
|
32
|
-
async getBytes(offset, length, signal) {
|
|
33
|
-
const slice = this.blob.slice(offset, offset + length);
|
|
34
|
-
const data = await slice.arrayBuffer();
|
|
35
|
-
return {
|
|
36
|
-
data
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
23
|
export class PMTilesSource extends DataSource {
|
|
41
24
|
constructor(props) {
|
|
42
25
|
super(props);
|
|
26
|
+
this.data = void 0;
|
|
43
27
|
this.props = void 0;
|
|
28
|
+
this.mimeType = null;
|
|
44
29
|
this.pmtiles = void 0;
|
|
45
30
|
this.metadata = void 0;
|
|
46
31
|
this.props = props;
|
|
47
32
|
const url = typeof props.url === 'string' ? resolvePath(props.url) : new BlobSource(props.url, 'pmtiles');
|
|
33
|
+
this.data = props.url;
|
|
48
34
|
this.pmtiles = new PMTiles(url);
|
|
49
35
|
this.getTileData = this.getTileData.bind(this);
|
|
50
36
|
this.metadata = this.getMetadata();
|
|
@@ -56,6 +42,9 @@ export class PMTilesSource extends DataSource {
|
|
|
56
42
|
if (this.props.attributions) {
|
|
57
43
|
metadata.attributions = [...this.props.attributions, ...(metadata.attributions || [])];
|
|
58
44
|
}
|
|
45
|
+
if (metadata !== null && metadata !== void 0 && metadata.tileMIMEType) {
|
|
46
|
+
this.mimeType = metadata === null || metadata === void 0 ? void 0 : metadata.tileMIMEType;
|
|
47
|
+
}
|
|
59
48
|
return metadata;
|
|
60
49
|
}
|
|
61
50
|
async getTile(tileParams) {
|
|
@@ -78,7 +67,7 @@ export class PMTilesSource extends DataSource {
|
|
|
78
67
|
z
|
|
79
68
|
} = tileParams.index;
|
|
80
69
|
const metadata = await this.metadata;
|
|
81
|
-
switch (metadata.
|
|
70
|
+
switch (metadata.tileMIMEType) {
|
|
82
71
|
case 'application/vnd.mapbox-vector-tile':
|
|
83
72
|
return await this.getVectorTile({
|
|
84
73
|
x,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pmtiles-source.js","names":["DataSource","resolvePath","ImageLoader","MVTLoader","
|
|
1
|
+
{"version":3,"file":"pmtiles-source.js","names":["DataSource","resolvePath","ImageLoader","MVTLoader","pmtiles","PMTiles","parsePMTilesHeader","BlobSource","VERSION","PMTilesService","name","id","module","version","extensions","mimeTypes","options","createSource","props","PMTilesSource","constructor","data","mimeType","metadata","url","getTileData","bind","getMetadata","pmtilesHeader","getHeader","pmtilesMetadata","attributions","tileMIMEType","getTile","tileParams","x","y","zoom","z","rangeResponse","getZxy","arrayBuffer","index","getVectorTile","layers","getImageTile","parse","loadOptions","_this$loadOptions","shape","mvt","coordinates","tileIndex"],"sources":["../src/pmtiles-source.ts"],"sourcesContent":["// loaders.gl, MIT license\n// Copyright (c) vis.gl contributors\n\nimport type {TileLoadParameters, GetTileParameters} from '@loaders.gl/loader-utils';\nimport type {ImageType, DataSourceProps} from '@loaders.gl/loader-utils';\nimport type {ImageTileSource, VectorTileSource} from '@loaders.gl/loader-utils';\nimport {DataSource, resolvePath} from '@loaders.gl/loader-utils';\nimport {ImageLoader} from '@loaders.gl/images';\nimport {MVTLoader, MVTLoaderOptions} from '@loaders.gl/mvt';\n\nimport * as pmtiles from 'pmtiles';\nconst {PMTiles} = pmtiles;\n\nimport type {PMTilesMetadata} from './lib/parse-pmtiles';\nimport {parsePMTilesHeader} from './lib/parse-pmtiles';\nimport {BlobSource} from './lib/blob-source';\n\nconst VERSION = '1.0.0';\n\nexport type Service = {\n name: string;\n id: string;\n module: string;\n version: string;\n extensions: string[];\n mimeTypes: string[];\n options: Record<string, unknown>;\n};\n\nexport type ServiceWithSource<SourceT, SourcePropsT> = Service & {\n _source?: SourceT;\n _sourceProps?: SourcePropsT;\n createSource: (props: SourcePropsT) => SourceT;\n};\n\nexport const PMTilesService: ServiceWithSource<PMTilesSource, PMTilesSourceProps> = {\n name: 'PMTiles',\n id: 'pmtiles',\n module: 'pmtiles',\n version: VERSION,\n extensions: ['pmtiles'],\n mimeTypes: ['application/octet-stream'],\n options: {\n pmtiles: {}\n },\n createSource: (props: PMTilesSourceProps) => new PMTilesSource(props)\n};\n\nexport type PMTilesSourceProps = DataSourceProps & {\n url: string | Blob;\n attributions?: string[];\n};\n\n/**\n * A PMTiles data source\n * @note Can be either a raster or vector tile source depending on the contents of the PMTiles file.\n */\nexport class PMTilesSource extends DataSource implements ImageTileSource, VectorTileSource {\n data: string | Blob;\n props: PMTilesSourceProps;\n mimeType: string | null = null;\n pmtiles: pmtiles.PMTiles;\n metadata: Promise<PMTilesMetadata>;\n\n constructor(props: PMTilesSourceProps) {\n super(props);\n this.props = props;\n const url =\n typeof props.url === 'string' ? resolvePath(props.url) : new BlobSource(props.url, 'pmtiles');\n this.data = props.url;\n this.pmtiles = new PMTiles(url);\n this.getTileData = this.getTileData.bind(this);\n this.metadata = this.getMetadata();\n }\n\n async getMetadata(): Promise<PMTilesMetadata> {\n const pmtilesHeader = await this.pmtiles.getHeader();\n const pmtilesMetadata = await this.pmtiles.getMetadata();\n const metadata: PMTilesMetadata = parsePMTilesHeader(pmtilesHeader, pmtilesMetadata);\n // Add additional attribution if necessary\n if (this.props.attributions) {\n metadata.attributions = [...this.props.attributions, ...(metadata.attributions || [])];\n }\n if (metadata?.tileMIMEType) {\n this.mimeType = metadata?.tileMIMEType;\n }\n // TODO - do we need to allow tileSize to be overridden? Some PMTiles examples seem to suggest it.\n return metadata;\n }\n\n async getTile(tileParams: GetTileParameters): Promise<ArrayBuffer | null> {\n const {x, y, zoom: z} = tileParams;\n const rangeResponse = await this.pmtiles.getZxy(z, x, y);\n const arrayBuffer = rangeResponse?.data;\n if (!arrayBuffer) {\n // console.error('No arrayBuffer', tileParams);\n return null;\n }\n return arrayBuffer;\n }\n\n // Tile Source interface implementation: deck.gl compatible API\n // TODO - currently only handles image tiles, not vector tiles\n\n async getTileData(tileParams: TileLoadParameters): Promise<unknown | null> {\n const {x, y, z} = tileParams.index;\n const metadata = await this.metadata;\n switch (metadata.tileMIMEType) {\n case 'application/vnd.mapbox-vector-tile':\n return await this.getVectorTile({x, y, zoom: z, layers: []});\n default:\n return await this.getImageTile({x, y, zoom: z, layers: []});\n }\n }\n\n // ImageTileSource interface implementation\n\n async getImageTile(tileParams: GetTileParameters): Promise<ImageType | null> {\n const arrayBuffer = await this.getTile(tileParams);\n return arrayBuffer ? await ImageLoader.parse(arrayBuffer, this.loadOptions) : null;\n }\n\n // VectorTileSource interface implementation\n\n async getVectorTile(tileParams: GetTileParameters): Promise<unknown | null> {\n const arrayBuffer = await this.getTile(tileParams);\n const loadOptions: MVTLoaderOptions = {\n shape: 'geojson-table',\n mvt: {\n coordinates: 'wgs84',\n tileIndex: {x: tileParams.x, y: tileParams.y, z: tileParams.zoom},\n ...(this.loadOptions as MVTLoaderOptions)?.mvt\n },\n ...this.loadOptions\n };\n\n return arrayBuffer ? await MVTLoader.parse(arrayBuffer, loadOptions) : null;\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loaders.gl/pmtiles",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "Framework-independent loader for the pmtiles format",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -40,11 +40,11 @@
|
|
|
40
40
|
"build-bundle": "ocular-bundle ./src/index.ts"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@loaders.gl/images": "4.0.
|
|
44
|
-
"@loaders.gl/loader-utils": "4.0.
|
|
45
|
-
"@loaders.gl/mvt": "4.0.
|
|
46
|
-
"@loaders.gl/schema": "4.0.
|
|
43
|
+
"@loaders.gl/images": "4.0.1",
|
|
44
|
+
"@loaders.gl/loader-utils": "4.0.1",
|
|
45
|
+
"@loaders.gl/mvt": "4.0.1",
|
|
46
|
+
"@loaders.gl/schema": "4.0.1",
|
|
47
47
|
"pmtiles": "^2.7.2"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "765e5a26a6bf3f2cc02cabffc4a1e3665ec92a53"
|
|
50
50
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// loaders.gl, MIT license
|
|
2
|
+
// Copyright (c) vis.gl contributors
|
|
3
|
+
|
|
4
|
+
import * as pmtiles from 'pmtiles';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A PMTiles library compatible source that reads from blobs
|
|
8
|
+
* @deprecated TODO - reimplement as ReadableFileSource
|
|
9
|
+
* Use loaders.gl HTTP range requests instead
|
|
10
|
+
*/
|
|
11
|
+
export class BlobSource implements pmtiles.Source {
|
|
12
|
+
blob: Blob;
|
|
13
|
+
key: string;
|
|
14
|
+
|
|
15
|
+
constructor(blob: Blob, key: string) {
|
|
16
|
+
this.blob = blob;
|
|
17
|
+
this.key = key;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// TODO - how is this used?
|
|
21
|
+
getKey() {
|
|
22
|
+
// @ts-expect-error url is only defined on File subclass
|
|
23
|
+
return this.blob.url || '';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async getBytes(
|
|
27
|
+
offset: number,
|
|
28
|
+
length: number,
|
|
29
|
+
signal?: AbortSignal
|
|
30
|
+
): Promise<pmtiles.RangeResponse> {
|
|
31
|
+
const slice = this.blob.slice(offset, offset + length);
|
|
32
|
+
const data = await slice.arrayBuffer();
|
|
33
|
+
return {
|
|
34
|
+
data
|
|
35
|
+
// etag: response.headers.get('ETag') || undefined,
|
|
36
|
+
// cacheControl: response.headers.get('Cache-Control') || undefined,
|
|
37
|
+
// expires: response.headers.get('Expires') || undefined
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
package/src/lib/parse-pmtiles.ts
CHANGED
|
@@ -5,30 +5,28 @@ import type {TileJSON} from '@loaders.gl/mvt';
|
|
|
5
5
|
import {TileJSONLoader} from '@loaders.gl/mvt';
|
|
6
6
|
// import {Source, PMTiles, Header, TileType} from 'pmtiles';
|
|
7
7
|
import * as pmtiles from 'pmtiles';
|
|
8
|
-
const {
|
|
8
|
+
const {TileType} = pmtiles;
|
|
9
9
|
|
|
10
10
|
/** Metadata describing a PMTiles file */
|
|
11
11
|
export type PMTilesMetadata = {
|
|
12
|
-
/** Name of the tileset (extracted from JSON metadata if available) */
|
|
13
|
-
name?: string;
|
|
14
|
-
/** Attribution string (extracted from JSON metadata if available) */
|
|
15
|
-
attributions?: string[];
|
|
16
|
-
|
|
17
12
|
format: 'pmtiles';
|
|
18
13
|
/** Version of pm tiles format used by this tileset */
|
|
19
14
|
formatVersion: number;
|
|
20
|
-
|
|
21
|
-
formatHeader?: pmtiles.Header;
|
|
15
|
+
|
|
22
16
|
/** MIME type for tile contents. Unknown tile types will return 'application/octet-stream */
|
|
23
|
-
|
|
17
|
+
tileMIMEType:
|
|
24
18
|
| 'application/vnd.mapbox-vector-tile'
|
|
25
19
|
| 'image/png'
|
|
26
20
|
| 'image/jpeg'
|
|
27
21
|
| 'image/webp'
|
|
28
22
|
| 'image/avif'
|
|
29
23
|
| 'application/octet-stream';
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
|
|
25
|
+
/** Name of the tileset (extracted from JSON metadata if available) */
|
|
26
|
+
name?: string;
|
|
27
|
+
/** Attribution string (extracted from JSON metadata if available) */
|
|
28
|
+
attributions?: string[];
|
|
29
|
+
|
|
32
30
|
/** Minimal zoom level of tiles in this tileset */
|
|
33
31
|
minZoom: number;
|
|
34
32
|
/** Maximal zoom level of tiles in this tileset */
|
|
@@ -41,60 +39,58 @@ export type PMTilesMetadata = {
|
|
|
41
39
|
centerZoom: number;
|
|
42
40
|
/** Cache tag */
|
|
43
41
|
etag?: string;
|
|
44
|
-
tileJSON?: TileJSON;
|
|
45
|
-
/** Current assumption is that this is a tileJSON style metadata generated by e.g. tippecanoe */
|
|
46
|
-
tilejsonMetadata?: Record<string, unknown>;
|
|
47
|
-
};
|
|
48
42
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
};
|
|
43
|
+
/** Parsed TileJSON/tilestats metadata, if present */
|
|
44
|
+
tilejson?: TileJSON;
|
|
52
45
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
metadata && typeof metadata === 'object' && !Array.isArray(metadata)
|
|
59
|
-
? (metadata as Record<string, unknown>)
|
|
60
|
-
: null;
|
|
61
|
-
return parsePMTilesHeader(header, tilejsonMetadata);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export async function loadPMTile(
|
|
65
|
-
source: pmtiles.Source,
|
|
66
|
-
options: ParsePMTilesOptions
|
|
67
|
-
): Promise<ArrayBuffer | undefined> {
|
|
68
|
-
const pmTiles = new PMTiles(source);
|
|
69
|
-
if (!options.tileZxy) {
|
|
70
|
-
throw new Error('tile zxy missing');
|
|
71
|
-
}
|
|
72
|
-
const [z, x, y] = options.tileZxy;
|
|
73
|
-
const tile = await pmTiles.getZxy(z, x, y);
|
|
74
|
-
return tile?.data;
|
|
75
|
-
}
|
|
46
|
+
/** @deprecated PMTiles format specific header */
|
|
47
|
+
formatHeader?: pmtiles.Header;
|
|
48
|
+
/** @deprecated Unparsed metadata (Assumption metadata generated by e.g. tippecanoe, typically TileJSON) */
|
|
49
|
+
formatMetadata?: Record<string, unknown>;
|
|
50
|
+
};
|
|
76
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Parse PMTiles metdata from a PMTiles file
|
|
54
|
+
* @param header
|
|
55
|
+
* @param tilejsonMetadata
|
|
56
|
+
* @param options
|
|
57
|
+
* @returns
|
|
58
|
+
*/
|
|
77
59
|
export function parsePMTilesHeader(
|
|
78
60
|
header: pmtiles.Header,
|
|
79
|
-
|
|
61
|
+
pmtilesMetadata: Record<string, unknown> | null,
|
|
80
62
|
options?: {includeFormatHeader?: boolean}
|
|
81
63
|
): PMTilesMetadata {
|
|
64
|
+
// Ironically, to use the TileJSON loader we need to stringify the metadata again.
|
|
65
|
+
// This is the price of integrating with the existing pmtiles library.
|
|
66
|
+
// TODO - provide a non-standard TileJSONLoader parsers that accepts a JSON object?
|
|
67
|
+
let tilejson: TileJSON | null = null;
|
|
68
|
+
if (pmtilesMetadata) {
|
|
69
|
+
try {
|
|
70
|
+
const string = JSON.stringify(pmtilesMetadata);
|
|
71
|
+
tilejson = TileJSONLoader.parseTextSync?.(string) || null;
|
|
72
|
+
} catch (error) {
|
|
73
|
+
// eslint-disable-next-line no-console
|
|
74
|
+
console.warn('PMTiles metadata could not be interpreted as TileJSON', error);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
82
78
|
const partialMetadata: Partial<PMTilesMetadata> = {};
|
|
83
79
|
|
|
84
|
-
if (typeof
|
|
85
|
-
partialMetadata.name =
|
|
80
|
+
if (typeof tilejson?.name === 'string') {
|
|
81
|
+
partialMetadata.name = tilejson.name;
|
|
86
82
|
}
|
|
87
83
|
|
|
88
|
-
if (typeof
|
|
89
|
-
partialMetadata.attributions = [
|
|
84
|
+
if (typeof tilejson?.htmlAttribution === 'string') {
|
|
85
|
+
partialMetadata.attributions = [tilejson.htmlAttribution];
|
|
90
86
|
}
|
|
91
87
|
|
|
92
88
|
const metadata: PMTilesMetadata = {
|
|
93
89
|
...partialMetadata,
|
|
94
90
|
format: 'pmtiles',
|
|
95
91
|
formatVersion: header.specVersion,
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
attributions: [],
|
|
93
|
+
tileMIMEType: decodeTileType(header.tileType),
|
|
98
94
|
minZoom: header.minZoom,
|
|
99
95
|
maxZoom: header.maxZoom,
|
|
100
96
|
boundingBox: [
|
|
@@ -106,18 +102,14 @@ export function parsePMTilesHeader(
|
|
|
106
102
|
etag: header.etag
|
|
107
103
|
};
|
|
108
104
|
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
metadata.tileJSON =
|
|
112
|
-
TileJSONLoader.parseTextSync?.(JSON.stringify(tilejsonMetadata)) || undefined;
|
|
113
|
-
} catch (error) {
|
|
114
|
-
// console.warn('PMTiles invalid tilejson metadata', error);
|
|
115
|
-
metadata.tilejsonMetadata = tilejsonMetadata;
|
|
116
|
-
}
|
|
105
|
+
if (tilejson) {
|
|
106
|
+
metadata.tilejson = tilejson;
|
|
117
107
|
}
|
|
118
108
|
|
|
109
|
+
// Application can optionally include the raw header and metadata.
|
|
119
110
|
if (options?.includeFormatHeader) {
|
|
120
111
|
metadata.formatHeader = header;
|
|
112
|
+
metadata.formatMetadata = metadata;
|
|
121
113
|
}
|
|
122
114
|
|
|
123
115
|
return metadata;
|
package/src/pmtiles-source.ts
CHANGED
|
@@ -8,12 +8,13 @@ import {DataSource, resolvePath} from '@loaders.gl/loader-utils';
|
|
|
8
8
|
import {ImageLoader} from '@loaders.gl/images';
|
|
9
9
|
import {MVTLoader, MVTLoaderOptions} from '@loaders.gl/mvt';
|
|
10
10
|
|
|
11
|
-
import type {PMTilesMetadata} from './lib/parse-pmtiles';
|
|
12
|
-
import {parsePMTilesHeader} from './lib/parse-pmtiles';
|
|
13
|
-
|
|
14
11
|
import * as pmtiles from 'pmtiles';
|
|
15
12
|
const {PMTiles} = pmtiles;
|
|
16
13
|
|
|
14
|
+
import type {PMTilesMetadata} from './lib/parse-pmtiles';
|
|
15
|
+
import {parsePMTilesHeader} from './lib/parse-pmtiles';
|
|
16
|
+
import {BlobSource} from './lib/blob-source';
|
|
17
|
+
|
|
17
18
|
const VERSION = '1.0.0';
|
|
18
19
|
|
|
19
20
|
export type Service = {
|
|
@@ -50,42 +51,14 @@ export type PMTilesSourceProps = DataSourceProps & {
|
|
|
50
51
|
attributions?: string[];
|
|
51
52
|
};
|
|
52
53
|
|
|
53
|
-
export class BlobSource implements pmtiles.Source {
|
|
54
|
-
blob: Blob;
|
|
55
|
-
key: string;
|
|
56
|
-
|
|
57
|
-
constructor(blob: Blob, key: string) {
|
|
58
|
-
this.blob = blob;
|
|
59
|
-
this.key = key;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// TODO - how is this used?
|
|
63
|
-
getKey() {
|
|
64
|
-
// @ts-expect-error url is only defined on File subclass
|
|
65
|
-
return this.blob.url || '';
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async getBytes(
|
|
69
|
-
offset: number,
|
|
70
|
-
length: number,
|
|
71
|
-
signal?: AbortSignal
|
|
72
|
-
): Promise<pmtiles.RangeResponse> {
|
|
73
|
-
const slice = this.blob.slice(offset, offset + length);
|
|
74
|
-
const data = await slice.arrayBuffer();
|
|
75
|
-
return {
|
|
76
|
-
data
|
|
77
|
-
// etag: response.headers.get('ETag') || undefined,
|
|
78
|
-
// cacheControl: response.headers.get('Cache-Control') || undefined,
|
|
79
|
-
// expires: response.headers.get('Expires') || undefined
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
54
|
/**
|
|
84
55
|
* A PMTiles data source
|
|
85
56
|
* @note Can be either a raster or vector tile source depending on the contents of the PMTiles file.
|
|
86
57
|
*/
|
|
87
58
|
export class PMTilesSource extends DataSource implements ImageTileSource, VectorTileSource {
|
|
59
|
+
data: string | Blob;
|
|
88
60
|
props: PMTilesSourceProps;
|
|
61
|
+
mimeType: string | null = null;
|
|
89
62
|
pmtiles: pmtiles.PMTiles;
|
|
90
63
|
metadata: Promise<PMTilesMetadata>;
|
|
91
64
|
|
|
@@ -94,6 +67,7 @@ export class PMTilesSource extends DataSource implements ImageTileSource, Vector
|
|
|
94
67
|
this.props = props;
|
|
95
68
|
const url =
|
|
96
69
|
typeof props.url === 'string' ? resolvePath(props.url) : new BlobSource(props.url, 'pmtiles');
|
|
70
|
+
this.data = props.url;
|
|
97
71
|
this.pmtiles = new PMTiles(url);
|
|
98
72
|
this.getTileData = this.getTileData.bind(this);
|
|
99
73
|
this.metadata = this.getMetadata();
|
|
@@ -102,10 +76,15 @@ export class PMTilesSource extends DataSource implements ImageTileSource, Vector
|
|
|
102
76
|
async getMetadata(): Promise<PMTilesMetadata> {
|
|
103
77
|
const pmtilesHeader = await this.pmtiles.getHeader();
|
|
104
78
|
const pmtilesMetadata = await this.pmtiles.getMetadata();
|
|
105
|
-
const metadata = parsePMTilesHeader(pmtilesHeader, pmtilesMetadata);
|
|
79
|
+
const metadata: PMTilesMetadata = parsePMTilesHeader(pmtilesHeader, pmtilesMetadata);
|
|
80
|
+
// Add additional attribution if necessary
|
|
106
81
|
if (this.props.attributions) {
|
|
107
82
|
metadata.attributions = [...this.props.attributions, ...(metadata.attributions || [])];
|
|
108
83
|
}
|
|
84
|
+
if (metadata?.tileMIMEType) {
|
|
85
|
+
this.mimeType = metadata?.tileMIMEType;
|
|
86
|
+
}
|
|
87
|
+
// TODO - do we need to allow tileSize to be overridden? Some PMTiles examples seem to suggest it.
|
|
109
88
|
return metadata;
|
|
110
89
|
}
|
|
111
90
|
|
|
@@ -126,7 +105,7 @@ export class PMTilesSource extends DataSource implements ImageTileSource, Vector
|
|
|
126
105
|
async getTileData(tileParams: TileLoadParameters): Promise<unknown | null> {
|
|
127
106
|
const {x, y, z} = tileParams.index;
|
|
128
107
|
const metadata = await this.metadata;
|
|
129
|
-
switch (metadata.
|
|
108
|
+
switch (metadata.tileMIMEType) {
|
|
130
109
|
case 'application/vnd.mapbox-vector-tile':
|
|
131
110
|
return await this.getVectorTile({x, y, zoom: z, layers: []});
|
|
132
111
|
default:
|