diff --git a/bench.js b/bench.js index e28f702..ee43993 100644 --- a/bench.js +++ b/bench.js @@ -65,6 +65,12 @@ new Benchmark.Suite() .add('pointToTileFraction#tile2', function () { tilebelt.pointToTileFraction(558004.8, 363898.8, 20); }) + .add('getNeighbors#tile1', function () { + tilebelt.getNeighbors(tile1); + }) + .add('getNeighbors#tile2', function () { + tilebelt.getNeighbors(tile2); + }) .on('error', function (event) { console.log(event.target.error); }) diff --git a/index.js b/index.js index eaeee9e..4dfe490 100644 --- a/index.js +++ b/index.js @@ -280,6 +280,66 @@ function pointToTileFraction(lon, lat, z) { return [x, y, z]; } +/** + * Get the 8 neighbors surrounding a tile + * + * @name getNeighbors + * @param {Array} tile + * @returns {Array>} tiles + * @example + * var tiles = getNeighbors([5, 10, 10]) + * //=tiles + */ +function getNeighbors(tile) { + const x = tile[0]; + const y = tile[1]; + const z = tile[2]; + + return [ + [x - 1, y - 1, z], // NW + [x, y - 1, z], // N + [x + 1, y - 1, z], // NE + [x + 1, y, z], // E + [x + 1, y + 1, z], // SE + [x, y + 1, z], // S + [x - 1, y + 1, z], //SW + [x - 1, y, z], // W + ]; +} + +/** + * Generates the GeoJSON FeatureCollection from an array or tiles + * + * @name tilesToFeatureCollection + * @param {Array>} tiles + * @returns {FeatureCollection} featureCollection + * var tiles = [ + * [0, 0, 5], + * [0, 1, 5], + * [1, 1, 5], + * [1, 0, 5] + * ] + * var featureCollection = tilesToFeatureCollection(tiles) + * //=featureCollection + */ +function tilesToFeatureCollection(tiles) { + const collection = { + type: "FeatureCollection", + features: [] + }; + + for (let i = 0; i < tiles.length; i++) { + const geometry = tileToGeoJSON(tiles[i]); + collection.features.push({ + type: "Feature", + geometry: geometry, + properties: null + }) + } + + return collection; +} + module.exports = { tileToGeoJSON: tileToGeoJSON, tileToBBOX: tileToBBOX, @@ -293,5 +353,7 @@ module.exports = { quadkeyToTile: quadkeyToTile, pointToTile: pointToTile, bboxToTile: bboxToTile, - pointToTileFraction: pointToTileFraction + pointToTileFraction: pointToTileFraction, + getNeighbors: getNeighbors, + tilesToFeatureCollection: tilesToFeatureCollection }; diff --git a/package.json b/package.json index e35c03c..cfff047 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ }, "homepage": "https://github.com/mapbox/tilebelt", "devDependencies": { + "@types/geojson": "^7946.0.7", "benchmark": "~2.1.4", "eslint": "^7.8.1", "eslint-config-mourner": "~2.0.3", diff --git a/types.d.ts b/types.d.ts new file mode 100644 index 0000000..8e339af --- /dev/null +++ b/types.d.ts @@ -0,0 +1,191 @@ +declare module '@mapbox/tilebelt' { + import { BBox, FeatureCollection, Geometry } from "geojson"; + + export type Tile = [number, number, number]; // [x, y, z] + + /** + * Get the bbox of a tile + * + * @name tileToBBOX + * @param {Array} tile + * @returns {Array} bbox + * @example + * var bbox = tileToBBOX([5, 10, 10]) + * //=bbox + */ + export function tileToBBOX(time: Tile): BBox; + + /** + * Get a geojson representation of a tile + * + * @name tileToGeoJSON + * @param {Array} tile + * @returns {Feature} + * @example + * var poly = tileToGeoJSON([5, 10, 10]) + * //=poly + */ + export function tileToGeoJSON(tile: Tile): Geometry; + + /** + * Get the tile for a point at a specified zoom level + * + * @name pointToTile + * @param {number} lon + * @param {number} lat + * @param {number} z + * @returns {Array} tile + * @example + * var tile = pointToTile(1, 1, 20) + * //=tile + */ + export function pointToTile(lon: number, lat: number, zoom: number): Tile; + + /** + * Get the 4 tiles one zoom level higher + * + * @name getChildren + * @param {Array} tile + * @returns {Array>} tiles + * @example + * var tiles = getChildren([5, 10, 10]) + * //=tiles + */ + export function getChildren(tile: Tile): Tile[]; + + /** + * Get the tile one zoom level lower + * + * @name getParent + * @param {Array} tile + * @returns {Array} tile + * @example + * var tile = getParent([5, 10, 10]) + * //=tile + */ + export function getParent(tile: Tile): Tile; + + /** + * Get the 3 sibling tiles for a tile + * + * @name getSiblings + * @param {Array} tile + * @returns {Array>} tiles + * @example + * var tiles = getSiblings([5, 10, 10]) + * //=tiles + */ + export function hasSiblings(tiles: Tile[], tile: Tile): boolean; + + /** get the 3 sibling tiles for a tile */ + export function getSiblings(tile: Tile): Tile[]; + + /** + * Check to see if an array of tiles contains a particular tile + * + * @name hasTile + * @param {Array>} tiles + * @param {Array} tile + * @returns {boolean} + * @example + * var tiles = [ + * [0, 0, 5], + * [0, 1, 5], + * [1, 1, 5], + * [1, 0, 5] + * ] + * hasTile(tiles, [0, 0, 5]) + * //=boolean + */ + export function hasTile(tiles: Tile[], tile: Tile): boolean; + + /** + * Check to see if two tiles are the same + * + * @name tilesEqual + * @param {Array} tile1 + * @param {Array} tile2 + * @returns {boolean} + * @example + * tilesEqual([0, 1, 5], [0, 0, 5]) + * //=boolean + */ + export function tilesEqual(tile1: Tile, tile2: Tile): boolean; + + /** + * Get the quadkey for a tile + * + * @name tileToQuadkey + * @param {Array} tile + * @returns {string} quadkey + * @example + * var quadkey = tileToQuadkey([0, 1, 5]) + * //=quadkey + */ + export function tileToQuadkey(tile: Tile): string; + + /** + * Get the tile for a quadkey + * + * @name quadkeyToTile + * @param {string} quadkey + * @returns {Array} tile + * @example + * var tile = quadkeyToTile('00001033') + * //=tile + */ + export function quadkeyToTile(quadkey: string): Tile; + + /** + * Get the smallest tile to cover a bbox + * + * @name bboxToTile + * @param {Array} bbox + * @returns {Array} tile + * @example + * var tile = bboxToTile([ -178, 84, -177, 85 ]) + * //=tile + */ + export function bboxToTile(bbox: BBox): Tile; + + /** + * Get the precise fractional tile location for a point at a zoom level + * + * @name pointToTileFraction + * @param {number} lon + * @param {number} lat + * @param {number} z + * @returns {Array} tile fraction + * var tile = pointToTileFraction(30.5, 50.5, 15) + * //=tile + */ + export function pointToTileFraction(lon: number, lat: number, zoom: number): Tile; + + /** + * Get the 8 neighbors surrounding a tile + * + * @name getNeighbors + * @param {Array} tile + * @returns {Array>} tiles + * var tiles = getNeighbors([5, 10, 10]) + * //=tiles + */ + export function getNeighbors(tile: Tile): Tile[] + + /** + * Generates the GeoJSON FeatureCollection from an array or tiles + * + * @name tilesToFeatureCollection + * @param {Array>} tiles + * @returns {FeatureCollection} featureCollection + * var tiles = [ + * [0, 0, 5], + * [0, 1, 5], + * [1, 1, 5], + * [1, 0, 5] + * ] + * var featureCollection = tilesToFeatureCollection(tiles) + * //=featureCollection + */ + export function tilesToFeatureCollection(tiles: Tile[]): FeatureCollection +}