Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mlt-vector-tile-js #212

Merged
merged 9 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion js/jest.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"transform": {
"^.+\\.ts": "ts-jest"
},
"testRegex": "test/unit/(.*|(\\.|/)(test|spec))\\.(js|ts)$",
"testRegex": "test/unit/.*.spec\\.(js|ts)$",
"moduleFileExtensions": ["ts", "js", "json", "node"],
"workerThreads": true
}
123 changes: 13 additions & 110 deletions js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"@bufbuild/protobuf": "^1.10.0",
"@types/bytebuffer": "^5.0.49",
"bitset": "^5.1.1",
"bytebuffer": "^5.0.1"
"bytebuffer": "^5.0.1",
"geojson": "^0.5.0"
ebrelsford marked this conversation as resolved.
Show resolved Hide resolved
}
}
2 changes: 2 additions & 0 deletions js/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
import * as MltVectorTileJs from './mlt-vector-tile-js/index';
export { MltVectorTileJs };
ebrelsford marked this conversation as resolved.
Show resolved Hide resolved
export { MltDecoder } from './decoder/MltDecoder';
export { TileSetMetadata } from './metadata/mlt_tileset_metadata_pb';
3 changes: 3 additions & 0 deletions js/src/mlt-vector-tile-js/README.md
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).
16 changes: 16 additions & 0 deletions js/src/mlt-vector-tile-js/VectorTile.ts
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 };
42 changes: 42 additions & 0 deletions js/src/mlt-vector-tile-js/VectorTileFeature.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Feature } from 'geojson';
import Point = require("@mapbox/point-geometry");

class VectorTileFeature {
properties: { [key: string]: any } = {};
extent: number;
type: 0|1|2|3 = 0;
id: number;

_raw: any;
_geometry: any;
_keys: string[];
_values: any[];
ebrelsford marked this conversation as resolved.
Show resolved Hide resolved

constructor(feature) {
this.properties = feature.properties;
this.extent = feature.extent;
this._geometry = feature.geometry;
ebrelsford marked this conversation as resolved.
Show resolved Hide resolved
this._raw = feature;
if (feature.id !== null) {
this.id = Number(feature.id);
}
}

loadGeometry(): Point[][] {
ebrelsford marked this conversation as resolved.
Show resolved Hide resolved
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): Feature {
return this._raw.toGeoJSON(x, y, z);
}
}

export { VectorTileFeature };
25 changes: 25 additions & 0 deletions js/src/mlt-vector-tile-js/VectorTileLayer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { VectorTileFeature } from './VectorTileFeature';

class VectorTileLayer {
version: number;
name: string | null;
extent: number;
length: number = 0;

_raw: any;
_keys: string[];
_values: any[];
_features: VectorTileFeature[] = [];

constructor(layer) {
ebrelsford marked this conversation as resolved.
Show resolved Hide resolved
this.name = layer.name;
this._features = layer.features.map((feature) => new VectorTileFeature(feature));
ebrelsford marked this conversation as resolved.
Show resolved Hide resolved
this.length = this._features.length;
}

feature(i: number): VectorTileFeature {
return this._features[i];
}
}

export { VectorTileLayer };
3 changes: 3 additions & 0 deletions js/src/mlt-vector-tile-js/index.ts
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';
14 changes: 14 additions & 0 deletions js/test/unit/mlt-vector-tile-js/LoadMLTTile.ts
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;
11 changes: 11 additions & 0 deletions js/test/unit/mlt-vector-tile-js/LoadMVTTile.ts
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;
38 changes: 38 additions & 0 deletions js/test/unit/mlt-vector-tile-js/VectorTile.spec.ts
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;
});
});
Loading