Skip to content

Commit

Permalink
feat(mvt): TableTileSource refactor, improved typing
Browse files Browse the repository at this point in the history
chore: tile recator
  • Loading branch information
ibgreen committed May 5, 2024
1 parent 08950dc commit c83c708
Show file tree
Hide file tree
Showing 12 changed files with 278 additions and 231 deletions.
2 changes: 1 addition & 1 deletion modules/mvt/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export {TileJSONLoader} from './tilejson-loader';

export {MVTSource} from './mvt-source';

// TableTileSource
// ProtoTileSource

export type {TableTileSourceProps} from './table-tile-source';
export {TableTileSource} from './table-tile-source';
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
// Copyright (c) vis.gl contributors
// Forked from https://github.com/mapbox/geojson-vt under compatible ISC license

import type {TableTileFeature} from './tile';
import {createFeature} from './feature';
import type {ProtoFeature} from './proto-tile';
import {createProtoFeature} from './proto-feature';

/* eslint-disable no-continue */

Expand All @@ -20,16 +20,16 @@ import {createFeature} from './feature';
* @param minAll and maxAll: minimum and maximum coordinate value for all features
*/
// eslint-disable-next-line max-params, complexity, max-statements
export function clip(
features: TableTileFeature[],
export function clipFeatures(
features: ProtoFeature[],
scale: number,
k1: number,
k2: number,
axis,
minAll: number,
maxAll: number,
options: {lineMetrics: boolean}
): TableTileFeature[] | null {
): ProtoFeature[] | null {
k1 /= scale;
k2 /= scale;

Expand All @@ -41,7 +41,7 @@ export function clip(
return null; // trivial reject
}

const clipped: TableTileFeature[] = [];
const clipped: ProtoFeature[] = [];

for (const feature of features) {
const geometry = feature.geometry;
Expand Down Expand Up @@ -82,7 +82,7 @@ export function clip(
if (newGeometry.length) {
if (options.lineMetrics && type === 'LineString') {
for (const line of newGeometry) {
clipped.push(createFeature(feature.id, type, line, feature.tags));
clipped.push(createProtoFeature(feature.id, type, line, feature.tags));
}
continue;
}
Expand All @@ -100,7 +100,7 @@ export function clip(
type = newGeometry.length === 3 ? 'Point' : 'MultiPoint';
}

clipped.push(createFeature(feature.id, type, newGeometry, feature.tags));
clipped.push(createProtoFeature(feature.id, type, newGeometry, feature.tags));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,29 @@
// @ts-nocheck

import type {Feature, FeatureCollection} from '@loaders.gl/schema';
import type {TableTileFeature} from './tile';

import type {ProtoFeature} from './proto-tile';
import {createProtoFeature} from './proto-feature';
import {simplify} from './simplify';
import {createFeature} from './feature';

export type ConvertFeatureOptions = {
/** max zoom to preserve detail on */
maxZoom?: number;
/** simplification tolerance (higher means simpler) */
tolerance?: number;
/** tile extent */
extent?: number;
/** whether to calculate line metrics */
lineMetrics?: boolean;
};

/**
* converts a GeoJSON feature into an intermediate projected JSON vector format
* with simplification data
*/
export function convert(data: Feature | FeatureCollection, options): TableTileFeature[] {
export function convertFeatureToProtoFeature(
data: Feature | FeatureCollection,
options: ConvertFeatureOptions
): ProtoFeature[] {
const features = [];
if (data.type === 'FeatureCollection') {
for (let i = 0; i < data.features.length; i++) {
Expand All @@ -32,27 +45,17 @@ export function convert(data: Feature | FeatureCollection, options): TableTileFe
return features;
}

export type ConvertFeatureOptions = {
/** max zoom to preserve detail on */
maxZoom?: number;
/** simplification tolerance (higher means simpler) */
tolerance?: number;
/** tile extent */
extent?: number;
/** whether to calculate line metrics */
lineMetrics?: boolean;
};

/**
* converts a GeoJSON feature into an intermediate projected JSON vector format
* with simplification data
*/
function convertFeature(
features: TableTileFeature[],
geojson: Feature,
features: ProtoFeature[],
options: ConvertFeatureOptions,
index: number
): void {
// GeoJSON geometries can be null, but no vector tile will include them.
if (!geojson.geometry) {
return;
}
Expand Down Expand Up @@ -81,7 +84,7 @@ function convertFeature(
for (const line of coords) {
geometry = [];
convertLine(line, geometry, tolerance, false);
features.push(createFeature(id, 'LineString', geometry, geojson.properties));
features.push(createProtoFeature(id, 'LineString', geometry, geojson.properties));
}
return;
} else {
Expand Down Expand Up @@ -113,7 +116,7 @@ function convertFeature(
throw new Error('Input data is not a valid GeoJSON object.');
}

features.push(createFeature(id, type, geometry, geojson.properties));
features.push(createProtoFeature(id, type, geometry, geojson.properties));
}

function convertPoint(coords, out): void {
Expand Down
47 changes: 0 additions & 47 deletions modules/mvt/src/lib/geojsonvt/feature.ts

This file was deleted.

64 changes: 64 additions & 0 deletions modules/mvt/src/lib/geojsonvt/proto-feature.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// loaders.gl
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors
// Forked from https://github.com/mapbox/geojson-vt under compatible ISC license

import {ProtoFeature} from './proto-tile';

export function createProtoFeature(
id: any,
type: 'Point' | 'MultiPoint' | 'LineString' | 'MultiLineString' | 'Polygon' | 'MultiPolygon',
geometry: any[],
tags
): ProtoFeature {
const feature: ProtoFeature = {
// eslint-disable-next-line
id: id == null ? null : id,
type,
simplifiedType: undefined!, // TODO
geometry,
tags,
minX: Infinity,
minY: Infinity,
maxX: -Infinity,
maxY: -Infinity
};

// TODO break out into separate function
switch (type) {

Check warning on line 28 in modules/mvt/src/lib/geojsonvt/proto-feature.ts

View workflow job for this annotation

GitHub Actions / test (20)

Expected a default case
case 'Point':
case 'MultiPoint':
case 'LineString':
calcLineBBox(feature, geometry);
break;

case 'MultiLineString':
for (const line of geometry) {
calcLineBBox(feature, line);
}
break;

case 'Polygon':
// the outer ring (ie [0]) contains all inner rings
calcLineBBox(feature, geometry[0]);
break;

case 'MultiPolygon':
for (const polygon of geometry) {
// the outer ring (ie [0]) contains all inner rings
calcLineBBox(feature, polygon[0]);
}
break;
}

return feature;
}

function calcLineBBox(feature, geometry) {
for (let i = 0; i < geometry.length; i += 3) {
feature.minX = Math.min(feature.minX, geometry[i]);
feature.minY = Math.min(feature.minY, geometry[i + 1]);
feature.maxX = Math.max(feature.maxX, geometry[i]);
feature.maxY = Math.max(feature.maxY, geometry[i + 1]);
}
}
Loading

0 comments on commit c83c708

Please sign in to comment.