-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This PR adds a way to wrap MLT tiles in a similar API to [mapbox/vector-tile-js](https://github.com/mapbox/vector-tile-js/), which makes it possible to use MLTs in MapLibre GL JS. Eventually we would expect this to be a separate package but since this is experimental and the MLT API is changing we think it's reasonable to incubate this here for now.
- Loading branch information
1 parent
7436314
commit 97af75b
Showing
12 changed files
with
235 additions
and
100 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# mlt-vector-tile-js | ||
|
||
This directory contains an API that is intended to mirror [mapbox/vector-tile-js](https://github.com/mapbox/vector-tile-js/) for MLTs to make it easier to use MLTs where the vector-tile-js API is expected (such as MapLibre GL JS). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { MltDecoder } from '../../src/decoder/MltDecoder'; | ||
import { VectorTileLayer } from './VectorTileLayer'; | ||
|
||
class VectorTile { | ||
layers: { [_: string]: VectorTileLayer } = {}; | ||
|
||
constructor(data: Uint8Array, featureTables: any) { | ||
const decoded = MltDecoder.decodeMlTile(data, featureTables); | ||
|
||
for (const layerName of Object.keys(decoded.layers)) { | ||
this.layers[layerName] = new VectorTileLayer(decoded.layers[layerName]); | ||
} | ||
} | ||
} | ||
|
||
export { VectorTile }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import Point = require("@mapbox/point-geometry"); | ||
|
||
class VectorTileFeature { | ||
properties: { [key: string]: any } = {}; | ||
extent: number; | ||
type: 0|1|2|3 = 0; | ||
id: number; | ||
|
||
_raw: any; | ||
|
||
constructor(feature) { | ||
this.properties = feature.properties; | ||
this.extent = feature.extent; | ||
this._raw = feature; | ||
if (feature.id !== null) { | ||
this.id = Number(feature.id); | ||
} | ||
} | ||
|
||
loadGeometry(): Point[][] { | ||
// TODO: optimize to avoid needing this deep copy | ||
const newGeometry = []; | ||
const oldGeometry = this._raw.loadGeometry(); | ||
for (let i = 0; i < oldGeometry.length; i++) { | ||
newGeometry[i] = []; | ||
for (let j = 0; j < oldGeometry[i].length; j++) { | ||
newGeometry[i][j] = new Point(oldGeometry[i][j].x, oldGeometry[i][j].y); | ||
} | ||
} | ||
return newGeometry; | ||
} | ||
|
||
toGeoJSON(x: Number, y: Number, z: Number): any { | ||
return this._raw.toGeoJSON(x, y, z); | ||
} | ||
} | ||
|
||
export { VectorTileFeature }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { Layer } from '../data/Layer'; | ||
import { VectorTileFeature } from './VectorTileFeature'; | ||
|
||
class VectorTileLayer { | ||
version: number; | ||
name: string | null; | ||
extent: number; | ||
length: number = 0; | ||
|
||
_raw: Layer; | ||
|
||
constructor(layer: Layer) { | ||
this.name = layer.name; | ||
this._raw = layer; | ||
this.length = layer.features.length; | ||
} | ||
|
||
feature(i: number): VectorTileFeature { | ||
return new VectorTileFeature(this._raw.features[i]); | ||
} | ||
} | ||
|
||
export { VectorTileLayer }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export { VectorTile } from './VectorTile'; | ||
export { VectorTileLayer } from './VectorTileLayer'; | ||
export { VectorTileFeature } from './VectorTileFeature'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import * as fs from 'fs'; | ||
|
||
import { MltDecoder, TileSetMetadata } from '../../../src/index'; | ||
import * as vt from '../../../src/mlt-vector-tile-js/index'; | ||
|
||
const loadTile = (tilePath, metadataPath) : vt.VectorTile => { | ||
const data : Buffer = fs.readFileSync(tilePath); | ||
const metadata : Buffer = fs.readFileSync(metadataPath); | ||
const tilesetMetadata = TileSetMetadata.fromBinary(metadata); | ||
const tile : vt.VectorTile = new vt.VectorTile(data, tilesetMetadata); | ||
return tile; | ||
}; | ||
|
||
export default loadTile; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import * as fs from 'fs'; | ||
|
||
import { VectorTile } from '@mapbox/vector-tile'; | ||
import Protobuf from 'pbf'; | ||
|
||
const loadTile = (tilePath) => { | ||
const data : Buffer = fs.readFileSync(tilePath); | ||
return new VectorTile(new Protobuf(data)); | ||
}; | ||
|
||
export default loadTile; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import * as fs from 'fs'; | ||
|
||
import type { VectorTile as MvtVectorTile } from '@mapbox/vector-tile'; | ||
import * as vt from '../../../src/mlt-vector-tile-js/index'; | ||
import loadTile from './LoadMLTTile'; | ||
|
||
describe("VectorTile", () => { | ||
it("should have all layers", () => { | ||
const tile: vt.VectorTile = loadTile('../test/expected/bing/4-13-6.mlt', '../test/expected/bing/4-13-6.mlt.meta.pbf'); | ||
|
||
expect(Object.keys(tile.layers)).toEqual([ | ||
"water_feature", | ||
"road", | ||
"land_cover_grass", | ||
"country_region", | ||
"land_cover_forest", | ||
"road_hd", | ||
"vector_background", | ||
"populated_place", | ||
"admin_division1", | ||
]); | ||
}) | ||
|
||
it("should return valid GeoJSON for a feature", () => { | ||
const tile: vt.VectorTile = loadTile('../test/expected/bing/4-13-6.mlt', '../test/expected/bing/4-13-6.mlt.meta.pbf'); | ||
|
||
const geojson = tile.layers['road'].feature(0).toGeoJSON(13, 6, 4); | ||
|
||
expect(geojson.type).toEqual('Feature'); | ||
expect(geojson.geometry.type).toEqual('MultiLineString'); | ||
}) | ||
|
||
it("should be equivalent to MVT VectorTile", () => { | ||
const tile: vt.VectorTile = loadTile('../test/expected/bing/4-13-6.mlt', '../test/expected/bing/4-13-6.mlt.meta.pbf'); | ||
|
||
const mvtType : MvtVectorTile = tile; | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import * as fs from 'fs'; | ||
|
||
import { MltDecoder, TileSetMetadata } from '../../../src/index'; | ||
import * as vt from '../../../src/mlt-vector-tile-js/index'; | ||
import type { VectorTileFeature as MvtVectorTileFeature } from '@mapbox/vector-tile'; | ||
import loadTile from './LoadMLTTile'; | ||
import { default as loadMvtTile } from './LoadMVTTile'; | ||
|
||
describe("VectorTileFeature", () => { | ||
it("should be assignable to MVT VectorTileFeature", () => { | ||
const tile: vt.VectorTile = loadTile('../test/expected/bing/4-13-6.mlt', '../test/expected/bing/4-13-6.mlt.meta.pbf'); | ||
const feature : vt.VectorTileFeature = tile.layers['road'].feature(0); | ||
const mvtFeature : MvtVectorTileFeature = feature; | ||
}); | ||
|
||
it("should return valid GeoJSON for a feature", () => { | ||
const tile: vt.VectorTile = loadTile('../test/expected/bing/4-13-6.mlt', '../test/expected/bing/4-13-6.mlt.meta.pbf'); | ||
|
||
const feature = tile.layers['road'].feature(0); | ||
const geojsonFeature: any = feature.toGeoJSON(13, 6, 4); | ||
const geometry: any = geojsonFeature.geometry; | ||
expect(geometry.coordinates[0][0][0]).not.toBe(undefined); | ||
}); | ||
|
||
it("should load geometry", () => { | ||
const tile: vt.VectorTile = loadTile('../test/expected/bing/4-13-6.mlt', '../test/expected/bing/4-13-6.mlt.meta.pbf'); | ||
const feature = tile.layers['road'].feature(0); | ||
expect(feature.loadGeometry()[0][0].x).not.toBe(undefined); | ||
}); | ||
|
||
it("should have a valid extent", () => { | ||
const tile: vt.VectorTile = loadTile('../test/expected/bing/4-13-6.mlt', '../test/expected/bing/4-13-6.mlt.meta.pbf'); | ||
expect(tile.layers['road'].feature(0).extent).not.toBe(undefined); | ||
}); | ||
|
||
it("should have same loadGeometry output as MVT", () => { | ||
const tile: vt.VectorTile = loadTile('../test/expected/bing/4-13-6.mlt', '../test/expected/bing/4-13-6.mlt.meta.pbf'); | ||
|
||
const mvtTile = loadMvtTile('../test/fixtures/bing/4-13-6.mvt'); | ||
|
||
for (let i = 0; i < tile.layers['country_region'].length; i++) { | ||
const mltFeature = tile.layers['country_region'].feature(i); | ||
const mvtFeature = mvtTile.layers['country_region'].feature(i); | ||
expect(mltFeature.loadGeometry()).toEqual(mvtFeature.loadGeometry()); | ||
} | ||
}); | ||
|
||
it.skip("should have same type output as MVT", () => { | ||
const tile: vt.VectorTile = loadTile('../test/expected/bing/4-13-6.mlt', '../test/expected/bing/4-13-6.mlt.meta.pbf'); | ||
|
||
const mvtTile = loadMvtTile('../test/fixtures/bing/4-13-6.mvt'); | ||
|
||
for (let i = 0; i < tile.layers['land_cover_grass'].length; i++) { | ||
const mltFeature = tile.layers['land_cover_grass'].feature(i); | ||
const mvtFeature = mvtTile.layers['land_cover_grass'].feature(i); | ||
expect(mltFeature.type).toEqual(mvtFeature.type); | ||
} | ||
}); | ||
}); |
Oops, something went wrong.