From f20f6dc4b8f049e25d89123c44f0fd859b0ed52c Mon Sep 17 00:00:00 2001 From: Ranier Montalbo Date: Wed, 12 May 2021 18:58:41 +0800 Subject: [PATCH] Add #92 - Generate exact single tile --- src/index.js | 30 +- test/fixtures/single-tile.json | 707 +++++++++++++++++++++++++++++++++ test/test-get-single-tile.js | 41 ++ 3 files changed, 773 insertions(+), 5 deletions(-) create mode 100644 test/fixtures/single-tile.json create mode 100644 test/test-get-single-tile.js diff --git a/src/index.js b/src/index.js index f96e63c..0040efe 100644 --- a/src/index.js +++ b/src/index.js @@ -5,18 +5,21 @@ import wrap from './wrap.js'; // date line processing import transform from './transform.js'; // coordinate transformation import createTile from './tile.js'; // final simplified tile generation -const defaultOptions = { +const defaultTileOptions = { maxZoom: 14, // max zoom to preserve detail on - indexMaxZoom: 5, // max zoom in the tile index - indexMaxPoints: 100000, // max number of points per tile in the tile index tolerance: 3, // simplification tolerance (higher means simpler) extent: 4096, // tile extent buffer: 64, // tile buffer on each side - lineMetrics: false, // whether to calculate line metrics + lineMetrics: false // whether to calculate line metrics +}; + +const defaultOptions = extend(Object.create(defaultTileOptions), { + indexMaxZoom: 5, // max zoom in the tile index + indexMaxPoints: 100000, // max number of points per tile in the tile index promoteId: null, // name of a feature property to be promoted to feature.id generateId: false, // whether to generate feature ids. Cannot be used with promoteId debug: 0 // logging level (0, 1 or 2) -}; +}); class GeoJSONVT { constructor(data, options) { @@ -214,3 +217,20 @@ function extend(dest, src) { export default function geojsonvt(data, options) { return new GeoJSONVT(data, options); } + +export function geoJSONToTile(data, z, x, y, options, shouldWrap = false, shouldClip = false) { + options = extend(Object.create(defaultTileOptions), options); + + let features = convert(data, options); + if (shouldWrap) { + features = wrap(features, options); + } + if (shouldClip || options.lineMetrics) { + const pow2 = 1 << z; + const buffer = options.buffer / options.extent; + const left = clip(features, pow2, (x - buffer), (x + 1 + buffer), 0, -1, 2, options); + features = clip(left || [], pow2, (y - buffer), (y + 1 + buffer), 1, -1, 2, options); + } + + return features ? transform(createTile(features, z, x, y, options), options.extent) : null; +} diff --git a/test/fixtures/single-tile.json b/test/fixtures/single-tile.json new file mode 100644 index 0000000..de71d19 --- /dev/null +++ b/test/fixtures/single-tile.json @@ -0,0 +1,707 @@ +{ + "type": "Feature", + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -77.066104, + 38.910203 + ], + [ + -77.066106, + 38.910321 + ], + [ + -77.066112, + 38.910758 + ], + [ + -77.065249, + 38.910775 + ], + [ + -77.065178, + 38.910793 + ], + [ + -77.065139, + 38.910804 + ], + [ + -77.064904, + 38.91036 + ], + [ + -77.064855, + 38.910268 + ], + [ + -77.064621, + 38.909825 + ], + [ + -77.06459, + 38.909766 + ], + [ + -77.064342, + 38.909298 + ], + [ + -77.064281, + 38.909182 + ], + [ + -77.064201, + 38.909226 + ], + [ + -77.064175, + 38.909235 + ], + [ + -77.064149, + 38.909241 + ], + [ + -77.064122, + 38.909244 + ], + [ + -77.06336, + 38.90926 + ], + [ + -77.061442, + 38.909288 + ], + [ + -77.060801, + 38.909297 + ], + [ + -77.059237, + 38.909315 + ], + [ + -77.058186, + 38.90933 + ], + [ + -77.057113, + 38.909343 + ], + [ + -77.055623, + 38.909368 + ], + [ + -77.054762, + 38.909377 + ], + [ + -77.053951, + 38.909389 + ], + [ + -77.053904, + 38.909393 + ], + [ + -77.053858, + 38.909399 + ], + [ + -77.053813, + 38.909408 + ], + [ + -77.052833, + 38.909635 + ], + [ + -77.052799, + 38.909642 + ], + [ + -77.052772, + 38.909645 + ], + [ + -77.052692, + 38.90965 + ], + [ + -77.052443, + 38.909649 + ], + [ + -77.05096, + 38.909639 + ], + [ + -77.050327, + 38.909634 + ], + [ + -77.049545, + 38.909631 + ], + [ + -77.049533, + 38.909635 + ], + [ + -77.049341, + 38.909635 + ], + [ + -77.048903, + 38.909635 + ], + [ + -77.048797, + 38.909634 + ], + [ + -77.04773, + 38.909639 + ], + [ + -77.046632, + 38.90964 + ], + [ + -77.045758, + 38.909641 + ], + [ + -77.044877, + 38.909643 + ], + [ + -77.044578, + 38.909641 + ], + [ + -77.044493, + 38.909635 + ], + [ + -77.04442, + 38.909626 + ], + [ + -77.044345, + 38.909608 + ], + [ + -77.044283, + 38.909578 + ], + [ + -77.044249, + 38.909541 + ], + [ + -77.044212, + 38.909496 + ], + [ + -77.044199, + 38.909458 + ], + [ + -77.044182, + 38.909421 + ], + [ + -77.044162, + 38.909385 + ], + [ + -77.04414, + 38.90935 + ], + [ + -77.044113, + 38.909313 + ], + [ + -77.044083, + 38.90928 + ], + [ + -77.044051, + 38.909247 + ], + [ + -77.044018, + 38.909165 + ], + [ + -77.044018, + 38.909117 + ], + [ + -77.044029, + 38.909071 + ], + [ + -77.044037, + 38.909038 + ], + [ + -77.044058, + 38.908981 + ], + [ + -77.043996, + 38.909021 + ], + [ + -77.043919, + 38.909052 + ], + [ + -77.043854, + 38.909067 + ], + [ + -77.043798, + 38.909073 + ], + [ + -77.043755, + 38.909075 + ], + [ + -77.043689, + 38.909056 + ], + [ + -77.043656, + 38.909048 + ], + [ + -77.04359, + 38.909036 + ], + [ + -77.043527, + 38.909028 + ], + [ + -77.043486, + 38.909026 + ], + [ + -77.043444, + 38.909025 + ], + [ + -77.043402, + 38.909026 + ], + [ + -77.043344, + 38.909029 + ], + [ + -77.043286, + 38.909037 + ], + [ + -77.043263, + 38.909041 + ], + [ + -77.04323, + 38.909047 + ], + [ + -77.043194, + 38.909056 + ], + [ + -77.043022, + 38.909118 + ], + [ + -77.042995, + 38.909132 + ], + [ + -77.04296, + 38.909151 + ], + [ + -77.042938, + 38.909165 + ], + [ + -77.042915, + 38.90918 + ], + [ + -77.042875, + 38.909209 + ], + [ + -77.04284, + 38.909239 + ], + [ + -77.042823, + 38.909255 + ], + [ + -77.042791, + 38.909288 + ], + [ + -77.042774, + 38.909307 + ], + [ + -77.042712, + 38.909315 + ], + [ + -77.042637, + 38.909322 + ], + [ + -77.042551, + 38.909317 + ], + [ + -77.042422, + 38.909299 + ], + [ + -77.041676, + 38.90903 + ], + [ + -77.039935, + 38.908425 + ], + [ + -77.038503, + 38.907925 + ], + [ + -77.037656, + 38.907632 + ], + [ + -77.037477, + 38.907534 + ], + [ + -77.037317, + 38.907438 + ], + [ + -77.037238, + 38.90739 + ], + [ + -77.037121, + 38.907315 + ], + [ + -77.036997, + 38.907233 + ], + [ + -77.036875, + 38.907137 + ], + [ + -77.036833, + 38.907094 + ], + [ + -77.036817, + 38.907081 + ], + [ + -77.036795, + 38.907068 + ], + [ + -77.036774, + 38.907058 + ], + [ + -77.036767, + 38.907052 + ], + [ + -77.036712, + 38.907034 + ], + [ + -77.03669, + 38.907028 + ], + [ + -77.036643, + 38.907022 + ], + [ + -77.03661, + 38.907021 + ], + [ + -77.03653, + 38.907021 + ], + [ + -77.036474, + 38.907021 + ], + [ + -77.03643, + 38.907025 + ], + [ + -77.03639, + 38.907033 + ], + [ + -77.036295, + 38.907058 + ], + [ + -77.036005, + 38.906995 + ], + [ + -77.035439, + 38.906869 + ], + [ + -77.035142, + 38.906757 + ], + [ + -77.035049, + 38.906725 + ], + [ + -77.0348, + 38.906641 + ], + [ + -77.034673, + 38.906594 + ], + [ + -77.034568, + 38.906558 + ], + [ + -77.034059, + 38.906382 + ], + [ + -77.033931, + 38.906338 + ], + [ + -77.032623, + 38.905883 + ], + [ + -77.03129, + 38.905426 + ], + [ + -77.030031, + 38.904982 + ], + [ + -77.029623, + 38.904835 + ], + [ + -77.028082, + 38.904304 + ], + [ + -77.027679, + 38.904167 + ], + [ + -77.02705, + 38.903949 + ], + [ + -77.026409, + 38.903729 + ], + [ + -77.025984, + 38.903579 + ], + [ + -77.024321, + 38.902997 + ], + [ + -77.024139, + 38.902954 + ], + [ + -77.023952, + 38.902954 + ], + [ + -77.023188, + 38.902956 + ], + [ + -77.022699, + 38.902958 + ], + [ + -77.021917, + 38.90296 + ], + [ + -77.021918, + 38.902902 + ], + [ + -77.021918, + 38.902521 + ], + [ + -77.019907, + 38.902521 + ], + [ + -77.018928, + 38.902521 + ], + [ + -77.016176, + 38.902519 + ], + [ + -77.015177, + 38.902518 + ], + [ + -77.013722, + 38.902514 + ], + [ + -77.012171, + 38.902516 + ], + [ + -77.011237, + 38.902516 + ], + [ + -77.009846, + 38.902515 + ], + [ + -77.009117, + 38.902514 + ], + [ + -77.009126, + 38.901346 + ], + [ + -77.00912, + 38.900203 + ], + [ + -77.009062, + 38.900203 + ], + [ + -77.008975, + 38.900203 + ], + [ + -77.008004, + 38.900198 + ], + [ + -77.00631, + 38.900193 + ], + [ + -77.005531, + 38.900197 + ], + [ + -77.002929, + 38.9002 + ], + [ + -77.002038, + 38.900203 + ], + [ + -77.001892, + 38.900203 + ], + [ + -77.000571, + 38.900205 + ], + [ + -76.999507, + 38.900204 + ], + [ + -76.998442, + 38.900204 + ], + [ + -76.998369, + 38.900204 + ], + [ + -76.996167, + 38.900205 + ], + [ + -76.994961, + 38.900203 + ], + [ + -76.994962, + 38.899748 + ], + [ + -76.994961, + 38.899626 + ], + [ + -76.994961, + 38.899367 + ], + [ + -76.994961, + 38.898908 + ], + [ + -76.994962, + 38.898447 + ] + ] + }, + "properties": { + "name": "P Street Northwest - Massachusetts Avenue Northwest" + } +} \ No newline at end of file diff --git a/test/test-get-single-tile.js b/test/test-get-single-tile.js new file mode 100644 index 0000000..d433a2a --- /dev/null +++ b/test/test-get-single-tile.js @@ -0,0 +1,41 @@ +import test from 'tape'; +import fs from 'fs'; +import path from 'path'; +import {geoJSONToTile} from '../src/index.js'; + +const square = [{ + geometry: [[[4160, -64], [4160, 4160], [-64, 4160], [-64, -64], [4160, -64]]], + type: 3, + tags: {name: 'Pennsylvania', density: 284.3}, + id: '42' +}]; + +test('geoJSONToTile: converts all geometries to a single vector tile', (t) => { + const geojson = getJSON('single-tile.json'); + const tile = geoJSONToTile(geojson, 12, 1171, 1566); + + t.equal(tile.features.length, 1, 'z12-1171-1577'); + t.equal(tile.features[0].tags.name, 'P Street Northwest - Massachusetts Avenue Northwest'); + + t.end(); +}); + +test('geoJSONToTile: clips geometries outside the tile', (t) => { + const geojson = getJSON('us-states.json'); + + const tile1 = geoJSONToTile(geojson, 7, 37, 48, {}, false, true); + t.same(tile1.features, getJSON('us-states-z7-37-48.json'), 'z7-37-48'); + + const tile2 = geoJSONToTile(geojson, 9, 148, 192, {}, false, true); + t.same(tile2.features, square, 'z9-148-192 (clipped square)'); + + t.equal(geoJSONToTile(geojson, 11, 800, 400, {}, false, true), null, 'non-existing tile'); + t.equal(geoJSONToTile(geojson, -5, 123.25, 400.25, {}, false, true), null, 'invalid tile'); + t.equal(geoJSONToTile(geojson, 25, 200, 200, {}, false, true), null, 'invalid tile'); + + t.end(); +}); + +function getJSON(name) { + return JSON.parse(fs.readFileSync(path.join(__dirname, `/fixtures/${ name}`))); +}