maplibre adapter: use header to return appropriate empty response based on tile type, improve type defs [#83]

This commit is contained in:
Brandon Liu
2022-10-24 11:57:37 +08:00
parent 4cf368a599
commit 748c2f65cc

View File

@@ -1,5 +1,5 @@
declare const L: any; declare const L: any;
import { PMTiles, Source } from "./index"; import { PMTiles, Source, TileType } from "./index";
export const leafletRasterLayer = (source: PMTiles, options: any) => { export const leafletRasterLayer = (source: PMTiles, options: any) => {
const cls = L.GridLayer.extend({ const cls = L.GridLayer.extend({
@@ -51,6 +51,28 @@ export const leafletRasterLayer = (source: PMTiles, options: any) => {
return new cls(options); return new cls(options);
}; };
// copied from MapLibre /util/ajax.ts
type RequestParameters = {
url: string;
headers?: any;
method?: "GET" | "POST" | "PUT";
body?: string;
type?: "string" | "json" | "arrayBuffer";
credentials?: "same-origin" | "include";
collectResourceTiming?: boolean;
};
type ResponseCallback = (
error?: Error | null,
data?: any | null,
cacheControl?: string | null,
expires?: string | null
) => void;
type Cancelable = {
cancel: () => void;
};
export class Protocol { export class Protocol {
tiles: Map<string, PMTiles>; tiles: Map<string, PMTiles>;
@@ -66,7 +88,10 @@ export class Protocol {
return this.tiles.get(url); return this.tiles.get(url);
} }
tile = (params: any, callback: any) => { tile = (
params: RequestParameters,
callback: ResponseCallback
): Cancelable => {
if (params.type == "json") { if (params.type == "json") {
const pmtiles_url = params.url.substr(10); const pmtiles_url = params.url.substr(10);
let instance = this.tiles.get(pmtiles_url); let instance = this.tiles.get(pmtiles_url);
@@ -75,6 +100,8 @@ export class Protocol {
this.tiles.set(pmtiles_url, instance); this.tiles.set(pmtiles_url, instance);
} }
// TODO: create vector_layers if present to return valid TileJSON
instance.getHeader().then((h) => { instance.getHeader().then((h) => {
const tilejson = { const tilejson = {
tiles: [params.url + "/{z}/{x}/{y}"], tiles: [params.url + "/{z}/{x}/{y}"],
@@ -83,13 +110,18 @@ export class Protocol {
}; };
callback(null, tilejson, null, null); callback(null, tilejson, null, null);
}); });
return { return {
cancel: () => {}, cancel: () => {},
}; };
} else { } else {
const re = new RegExp(/pmtiles:\/\/(.+)\/(\d+)\/(\d+)\/(\d+)/); const re = new RegExp(/pmtiles:\/\/(.+)\/(\d+)\/(\d+)\/(\d+)/);
const result = params.url.match(re); const result = params.url.match(re);
if (!result) {
throw new Error("Invalid PMTiles protocol URL");
return {
cancel: () => {},
};
}
const pmtiles_url = result[1]; const pmtiles_url = result[1];
let instance = this.tiles.get(pmtiles_url); let instance = this.tiles.get(pmtiles_url);
@@ -107,7 +139,8 @@ export class Protocol {
controller.abort(); controller.abort();
}; };
instance instance.getHeader().then((header) => {
instance!
.getZxy(+z, +x, +y, signal) .getZxy(+z, +x, +y, signal)
.then((resp) => { .then((resp) => {
if (resp) { if (resp) {
@@ -118,14 +151,19 @@ export class Protocol {
resp.expires resp.expires
); );
} else { } else {
if (header.tileType == TileType.Mvt) {
callback(null, new Uint8Array(), null, null); callback(null, new Uint8Array(), null, null);
} else {
callback(null, null, null, null);
}
} }
}) })
.catch((e) => { .catch((e) => {
if (e.name !== "AbortError") { if ((e as Error).name !== "AbortError") {
throw e; throw e;
} }
}); });
});
return { return {
cancel: cancel, cancel: cancel,
}; };