mirror of
https://github.com/rastapasta/mapscii.git
synced 2024-11-21 23:53:08 +01:00
Suggest Bun and Deno 2; Upgrade most packages; Remove babel, ESLint and jest as dependencies
This commit is contained in:
parent
81a7fdea12
commit
ec0877830a
@ -1,6 +1,6 @@
|
|||||||
# MapSCII - The Whole World In Your Console. [![Build Status](https://travis-ci.com/rastapasta/mapscii.svg?branch=master)](https://travis-ci.com/rastapasta/mapscii)
|
# MapSCII - The Whole World In Your Console.
|
||||||
|
|
||||||
A node.js based [Vector Tile](http://wiki.openstreetmap.org/wiki/Vector_tiles) to [Braille](http://www.fileformat.info/info/unicode/block/braille_patterns/utf8test.htm) and [ASCII](https://de.wikipedia.org/wiki/American_Standard_Code_for_Information_Interchange) renderer for [xterm](https://en.wikipedia.org/wiki/Xterm)-compatible terminals.
|
A TypeScript-based [Vector Tile](http://wiki.openstreetmap.org/wiki/Vector_tiles) to [Braille](http://www.fileformat.info/info/unicode/block/braille_patterns/utf8test.htm) and [ASCII](https://de.wikipedia.org/wiki/American_Standard_Code_for_Information_Interchange) renderer for [xterm](https://en.wikipedia.org/wiki/Xterm)-compatible terminals.
|
||||||
|
|
||||||
<a href="https://asciinema.org/a/117813?autoplay=1" target="_blank">![asciicast](https://cloud.githubusercontent.com/assets/1259904/25480718/497a64e2-2b4a-11e7-9cf0-ed52ee0b89c0.png)</a>
|
<a href="https://asciinema.org/a/117813?autoplay=1" target="_blank">![asciicast](https://cloud.githubusercontent.com/assets/1259904/25480718/497a64e2-2b4a-11e7-9cf0-ed52ee0b89c0.png)</a>
|
||||||
|
|
||||||
@ -22,7 +22,6 @@ If you're on Windows, use the open source telnet client [PuTTY](https://www.chia
|
|||||||
* Work offline and discover local [VectorTile](https://github.com/mapbox/vector-tile-spec)/[MBTiles](https://github.com/mapbox/mbtiles-spec)
|
* Work offline and discover local [VectorTile](https://github.com/mapbox/vector-tile-spec)/[MBTiles](https://github.com/mapbox/mbtiles-spec)
|
||||||
* Compatible with most Linux and OSX terminals
|
* Compatible with most Linux and OSX terminals
|
||||||
* Highly optimized algorithms for a smooth experience
|
* Highly optimized algorithms for a smooth experience
|
||||||
* 100% pure JavaScript! :sunglasses:
|
|
||||||
|
|
||||||
## How to run it locally
|
## How to run it locally
|
||||||
|
|
||||||
@ -36,7 +35,7 @@ npx mapscii
|
|||||||
|
|
||||||
### With npm
|
### With npm
|
||||||
|
|
||||||
If you haven't already got Node.js >= version 10, then [go get it](http://nodejs.org/).
|
If you haven't already got Bun or Deno 2, then [go get it](https://deno.com/).
|
||||||
|
|
||||||
```
|
```
|
||||||
npm install -g mapscii
|
npm install -g mapscii
|
||||||
|
4920
package-lock.json
generated
4920
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
29
package.json
29
package.json
@ -2,12 +2,11 @@
|
|||||||
"name": "mapscii",
|
"name": "mapscii",
|
||||||
"version": "0.3.1",
|
"version": "0.3.1",
|
||||||
"description": "MapSCII is a Braille & ASCII world map renderer for your console, based on OpenStreetMap",
|
"description": "MapSCII is a Braille & ASCII world map renderer for your console, based on OpenStreetMap",
|
||||||
"main": "main.js",
|
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint src",
|
"lint": "deno lint",
|
||||||
"start": "node main",
|
"start": "deno --allow-all main.ts",
|
||||||
"test": "jest"
|
"test": "deno test"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -16,9 +15,6 @@
|
|||||||
"bin": {
|
"bin": {
|
||||||
"mapscii": "./bin/mapscii.sh"
|
"mapscii": "./bin/mapscii.sh"
|
||||||
},
|
},
|
||||||
"engines": {
|
|
||||||
"node": ">=20"
|
|
||||||
},
|
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"map",
|
"map",
|
||||||
"console",
|
"console",
|
||||||
@ -32,24 +28,19 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mapbox/mbtiles": "^0.12.1",
|
"@mapbox/mbtiles": "^0.12.1",
|
||||||
"@mapbox/vector-tile": "^1.3.1",
|
"@mapbox/vector-tile": "^2.0.3",
|
||||||
|
"@types/rbush": "^4.0.0",
|
||||||
"bresenham": "0.0.4",
|
"bresenham": "0.0.4",
|
||||||
"earcut": "^2.2.2",
|
"earcut": "^3.0.0",
|
||||||
"env-paths": "^2.2.0",
|
"env-paths": "^3.0.0",
|
||||||
"keypress": "^0.2.1",
|
"keypress": "^0.2.1",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^3.3.2",
|
||||||
"pbf": "^3.2.1",
|
"pbf": "^4.0.1",
|
||||||
"rbush": "^4.0.1",
|
"rbush": "^4.0.1",
|
||||||
"simplify-js": "^1.2.4",
|
"simplify-js": "^1.2.4",
|
||||||
"string-width": "^4.2.0",
|
"string-width": "^7.2.0",
|
||||||
"term-mouse": "^0.2.2",
|
"term-mouse": "^0.2.2",
|
||||||
"x256": "0.0.2",
|
"x256": "0.0.2",
|
||||||
"yargs": "^17.7.2"
|
"yargs": "^17.7.2"
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@babel/preset-typescript": "^7.25.7",
|
|
||||||
"eslint": "^7.8.1",
|
|
||||||
"eslint-plugin-jest": "^24.0.0",
|
|
||||||
"jest": "^29.7.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,13 +89,13 @@ class Canvas {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_polygonExtract(vertices, pointId) {
|
private _polygonExtract(vertices, pointId) {
|
||||||
return [vertices[pointId * 2], vertices[pointId * 2 + 1]];
|
return [vertices[pointId * 2], vertices[pointId * 2 + 1]];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inspired by Alois Zingl's "The Beauty of Bresenham's Algorithm"
|
// Inspired by Alois Zingl's "The Beauty of Bresenham's Algorithm"
|
||||||
// -> http://members.chello.at/~easyfilter/bresenham.html
|
// -> http://members.chello.at/~easyfilter/bresenham.html
|
||||||
_line(x0, y0, x1, y1, width, color) {
|
private _line(x0, y0, x1, y1, width, color) {
|
||||||
// Fall back to width-less bresenham algorithm if we dont have a width
|
// Fall back to width-less bresenham algorithm if we dont have a width
|
||||||
if (!(width = Math.max(0, width - 1))) {
|
if (!(width = Math.max(0, width - 1))) {
|
||||||
return bresenham(x0, y0, x1, y1, (x, y) => {
|
return bresenham(x0, y0, x1, y1, (x, y) => {
|
||||||
@ -149,7 +149,7 @@ class Canvas {
|
|||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
}
|
}
|
||||||
|
|
||||||
_filledRectangle(x, y, width, height, color) {
|
private _filledRectangle(x, y, width, height, color) {
|
||||||
const pointA = [x, y];
|
const pointA = [x, y];
|
||||||
const pointB = [x + width, y];
|
const pointB = [x + width, y];
|
||||||
const pointC = [x, y + height];
|
const pointC = [x, y + height];
|
||||||
@ -158,12 +158,12 @@ class Canvas {
|
|||||||
this._filledTriangle(pointC, pointB, pointD, color);
|
this._filledTriangle(pointC, pointB, pointD, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
_bresenham(pointA, pointB) {
|
private _bresenham(pointA, pointB) {
|
||||||
return bresenham(pointA[0], pointA[1], pointB[0], pointB[1]);
|
return bresenham(pointA[0], pointA[1], pointB[0], pointB[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draws a filled triangle
|
// Draws a filled triangle
|
||||||
_filledTriangle(pointA, pointB, pointC, color) {
|
private _filledTriangle(pointA, pointB, pointC, color) {
|
||||||
const a = this._bresenham(pointB, pointC);
|
const a = this._bresenham(pointB, pointC);
|
||||||
const b = this._bresenham(pointA, pointC);
|
const b = this._bresenham(pointA, pointC);
|
||||||
const c = this._bresenham(pointA, pointB);
|
const c = this._bresenham(pointA, pointB);
|
||||||
|
@ -7,9 +7,16 @@
|
|||||||
*/
|
*/
|
||||||
import RBush from 'rbush';
|
import RBush from 'rbush';
|
||||||
import stringWidth from 'string-width';
|
import stringWidth from 'string-width';
|
||||||
|
import { Feature } from './Renderer.ts';
|
||||||
|
|
||||||
export default class LabelBuffer {
|
export default class LabelBuffer {
|
||||||
private tree: RBush;
|
private tree: RBush<{
|
||||||
|
minX: number,
|
||||||
|
minY: number,
|
||||||
|
maxX: number,
|
||||||
|
maxY: number,
|
||||||
|
feature: Feature,
|
||||||
|
}>;
|
||||||
private margin: number;
|
private margin: number;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -31,29 +38,30 @@ export default class LabelBuffer {
|
|||||||
const point = this.project(x, y);
|
const point = this.project(x, y);
|
||||||
|
|
||||||
if (this._hasSpace(text, point[0], point[1])) {
|
if (this._hasSpace(text, point[0], point[1])) {
|
||||||
return this.tree.insert({
|
this.tree.insert({
|
||||||
...this._calculateArea(text, point[0], point[1], margin),
|
...this._calculateArea(text, point[0], point[1], margin),
|
||||||
feature,
|
feature,
|
||||||
});
|
});
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
featuresAt(x: number, y: number): void {
|
// featuresAt(x: number, y: number) {
|
||||||
this.tree.search({minX: x, maxX: x, minY: y, maxY: y});
|
// return this.tree.search({minX: x, maxX: x, minY: y, maxY: y});
|
||||||
}
|
// }
|
||||||
|
|
||||||
_hasSpace(text: string, x: number, y: number): boolean {
|
private _hasSpace(text: string, x: number, y: number): boolean {
|
||||||
return !this.tree.collides(this._calculateArea(text, x, y));
|
return !this.tree.collides(this._calculateArea(text, x, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
_calculateArea(text: string, x: number, y: number, margin = 0) {
|
private _calculateArea(text: string, x: number, y: number, margin = 0) {
|
||||||
return {
|
return {
|
||||||
minX: x-margin,
|
minX: x - margin,
|
||||||
minY: y-margin / 2,
|
minY: y - margin / 2,
|
||||||
maxX: x+margin + stringWidth(text),
|
maxX: x + margin + stringWidth(text),
|
||||||
maxY: y+margin / 2,
|
maxY: y + margin / 2,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -75,12 +75,12 @@ class Mapscii {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_initTileSource() {
|
private _initTileSource() {
|
||||||
this.tileSource = new TileSource();
|
this.tileSource = new TileSource();
|
||||||
this.tileSource.init(config.source);
|
this.tileSource.init(config.source);
|
||||||
}
|
}
|
||||||
|
|
||||||
_initKeyboard() {
|
private _initKeyboard() {
|
||||||
keypress(config.input);
|
keypress(config.input);
|
||||||
if (config.input.setRawMode) {
|
if (config.input.setRawMode) {
|
||||||
config.input.setRawMode(true);
|
config.input.setRawMode(true);
|
||||||
@ -90,7 +90,7 @@ class Mapscii {
|
|||||||
config.input.on('keypress', (_ch, key) => this._onKey(key));
|
config.input.on('keypress', (_ch, key) => this._onKey(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
_initMouse() {
|
private _initMouse() {
|
||||||
this.mouse = TermMouse({
|
this.mouse = TermMouse({
|
||||||
input: config.input,
|
input: config.input,
|
||||||
output: config.output,
|
output: config.output,
|
||||||
@ -102,7 +102,7 @@ class Mapscii {
|
|||||||
this.mouse.on('move', (event) => this._onMouseMove(event));
|
this.mouse.on('move', (event) => this._onMouseMove(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
_initRenderer() {
|
private _initRenderer() {
|
||||||
const style = JSON.parse(fs.readFileSync(config.styleFile, 'utf8'));
|
const style = JSON.parse(fs.readFileSync(config.styleFile, 'utf8'));
|
||||||
this.renderer = new Renderer(config.output, this.tileSource, style);
|
this.renderer = new Renderer(config.output, this.tileSource, style);
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ class Mapscii {
|
|||||||
this.zoom = (config.initialZoom !== null) ? config.initialZoom : this.minZoom;
|
this.zoom = (config.initialZoom !== null) ? config.initialZoom : this.minZoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
_resizeRenderer() {
|
private _resizeRenderer() {
|
||||||
this.width = config.size && config.size.width ? config.size.width * 2 : config.output.columns >> 1 << 2;
|
this.width = config.size && config.size.width ? config.size.width * 2 : config.output.columns >> 1 << 2;
|
||||||
this.height = config.size && config.size.height ? config.size.height * 4 : config.output.rows * 4 - 4;
|
this.height = config.size && config.size.height ? config.size.height * 4 : config.output.rows * 4 - 4;
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ class Mapscii {
|
|||||||
this.renderer.setSize(this.width, this.height);
|
this.renderer.setSize(this.width, this.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
_colrow2ll(x: number, y: number): {lat: number, lon: number} {
|
private _colrow2ll(x: number, y: number): {lat: number, lon: number} {
|
||||||
const projected = {
|
const projected = {
|
||||||
x: (x-0.5)*2,
|
x: (x-0.5)*2,
|
||||||
y: (y-0.5)*4,
|
y: (y-0.5)*4,
|
||||||
@ -139,11 +139,11 @@ class Mapscii {
|
|||||||
return utils.normalize(utils.tile2ll(center.x + (dx / size), center.y + (dy / size), z));
|
return utils.normalize(utils.tile2ll(center.x + (dx / size), center.y + (dy / size), z));
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateMousePosition(event: {x: number, y: number}): void {
|
private _updateMousePosition(event: {x: number, y: number}): void {
|
||||||
this.mousePosition = this._colrow2ll(event.x, event.y);
|
this.mousePosition = this._colrow2ll(event.x, event.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onClick(event) {
|
private _onClick(event) {
|
||||||
if (event.x < 0 || event.x > this.width / 2 || event.y < 0 || event.y > this.height / 4) {
|
if (event.x < 0 || event.x > this.width / 2 || event.y < 0 || event.y > this.height / 4) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -158,7 +158,7 @@ class Mapscii {
|
|||||||
this._draw();
|
this._draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onMouseScroll(event) {
|
private _onMouseScroll(event) {
|
||||||
this._updateMousePosition(event);
|
this._updateMousePosition(event);
|
||||||
|
|
||||||
// the location of the pointer, where we want to zoom toward
|
// the location of the pointer, where we want to zoom toward
|
||||||
@ -190,7 +190,7 @@ class Mapscii {
|
|||||||
this._draw();
|
this._draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onMouseMove(event: {button: string, x: number, y: number}) {
|
private _onMouseMove(event: {button: string, x: number, y: number}) {
|
||||||
if (event.x < 0 || event.x > this.width / 2 || event.y < 0 || event.y > this.height / 4) {
|
if (event.x < 0 || event.x > this.width / 2 || event.y < 0 || event.y > this.height / 4) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -229,7 +229,7 @@ class Mapscii {
|
|||||||
this.notify(this._getFooter());
|
this.notify(this._getFooter());
|
||||||
}
|
}
|
||||||
|
|
||||||
_onKey(key) {
|
private _onKey(key) {
|
||||||
if (config.keyCallback && !config.keyCallback(key)) return;
|
if (config.keyCallback && !config.keyCallback(key)) return;
|
||||||
if (!key || !key.name) return;
|
if (!key || !key.name) return;
|
||||||
|
|
||||||
@ -278,7 +278,7 @@ class Mapscii {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_draw() {
|
private _draw() {
|
||||||
this.renderer?.draw(this.center, this.zoom).then((frame) => {
|
this.renderer?.draw(this.center, this.zoom).then((frame) => {
|
||||||
this._write(frame);
|
this._write(frame);
|
||||||
this.notify(this._getFooter());
|
this.notify(this._getFooter());
|
||||||
@ -287,7 +287,7 @@ class Mapscii {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_getFooter() {
|
private _getFooter() {
|
||||||
// tile = utils.ll2tile(this.center.lon, this.center.lat, this.zoom);
|
// tile = utils.ll2tile(this.center.lon, this.center.lat, this.zoom);
|
||||||
// `tile: ${utils.digits(tile.x, 3)}, ${utils.digits(tile.x, 3)} `+
|
// `tile: ${utils.digits(tile.x, 3)}, ${utils.digits(tile.x, 3)} `+
|
||||||
|
|
||||||
@ -306,7 +306,7 @@ class Mapscii {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_write(output): void {
|
private _write(output): void {
|
||||||
config.output.write(output);
|
config.output.write(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,12 +17,26 @@ import TileSource from './TileSource.ts';
|
|||||||
import Tile from './Tile.ts';
|
import Tile from './Tile.ts';
|
||||||
|
|
||||||
export type Layer = {
|
export type Layer = {
|
||||||
extent: unknown,
|
extent?: unknown,
|
||||||
tree: RBush,
|
tree?: RBush<{
|
||||||
|
minX: number,
|
||||||
|
minY: number,
|
||||||
|
maxX: number,
|
||||||
|
maxY: number,
|
||||||
|
feature: Feature,
|
||||||
|
}>,
|
||||||
|
scale?: number,
|
||||||
|
features?: Feature[],
|
||||||
};
|
};
|
||||||
export type Layers = Record<string, Layer>;
|
export type Layers = Record<string, Layer>;
|
||||||
export type Feature = {
|
export type Feature = {
|
||||||
properties: Record<string, unknown>,
|
properties: Record<string, unknown>,
|
||||||
|
// TODO `style` is likely incomplete and incorrect
|
||||||
|
style: {
|
||||||
|
type?: string,
|
||||||
|
},
|
||||||
|
sort: number,
|
||||||
|
sorty: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Renderer {
|
class Renderer {
|
||||||
@ -86,15 +100,15 @@ class Renderer {
|
|||||||
}));
|
}));
|
||||||
await this._renderTiles(tiles);
|
await this._renderTiles(tiles);
|
||||||
return this._getFrame();
|
return this._getFrame();
|
||||||
} catch(e) {
|
} catch (err) {
|
||||||
console.error(e);
|
console.error(err);
|
||||||
} finally {
|
} finally {
|
||||||
this.isDrawing = false;
|
this.isDrawing = false;
|
||||||
this.lastDrawAt = Date.now();
|
this.lastDrawAt = Date.now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_visibleTiles(center, zoom) {
|
private _visibleTiles(center, zoom) {
|
||||||
const z = utils.baseZoom(zoom);
|
const z = utils.baseZoom(zoom);
|
||||||
center = utils.ll2tile(center.lon, center.lat, z);
|
center = utils.ll2tile(center.lon, center.lat, z);
|
||||||
|
|
||||||
@ -137,9 +151,9 @@ class Renderer {
|
|||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
_getTileFeatures(tile: Tile, zoom: number): Tile {
|
private _getTileFeatures(tile: Tile, zoom: number): Tile {
|
||||||
const position = tile.position;
|
const position = tile.position;
|
||||||
const layers = {};
|
const layers: Layers = {};
|
||||||
const drawOrder = this._generateDrawOrder(zoom);
|
const drawOrder = this._generateDrawOrder(zoom);
|
||||||
for (const layerId of drawOrder) {
|
for (const layerId of drawOrder) {
|
||||||
const layer = (tile.data.layers || {})[layerId];
|
const layer = (tile.data.layers || {})[layerId];
|
||||||
@ -149,12 +163,12 @@ class Renderer {
|
|||||||
|
|
||||||
const scale = layer.extent / utils.tilesizeAtZoom(zoom);
|
const scale = layer.extent / utils.tilesizeAtZoom(zoom);
|
||||||
layers[layerId] = {
|
layers[layerId] = {
|
||||||
scale: scale,
|
scale,
|
||||||
features: layer.tree.search({
|
features: layer.tree.search({
|
||||||
minX: -position.x * scale,
|
minX: -position.x * scale,
|
||||||
minY: -position.y * scale,
|
minY: -position.y * scale,
|
||||||
maxX: (this.width - position.x) * scale,
|
maxX: (this.width - position.x) * scale,
|
||||||
maxY: (this.height - position.y) * scale
|
maxY: (this.height - position.y) * scale,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -162,11 +176,11 @@ class Renderer {
|
|||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderTiles(tiles) {
|
private _renderTiles(tiles) {
|
||||||
const labels: {
|
const labels: {
|
||||||
tile: Tile,
|
tile: Tile,
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
scale: unknown,
|
scale: number,
|
||||||
}[] = [];
|
}[] = [];
|
||||||
if (tiles.length === 0) return;
|
if (tiles.length === 0) return;
|
||||||
|
|
||||||
@ -200,7 +214,10 @@ class Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_getFrame() {
|
private _getFrame(): string {
|
||||||
|
if (!this.canvas) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
let frame = '';
|
let frame = '';
|
||||||
if (!this.lastDrawAt) {
|
if (!this.lastDrawAt) {
|
||||||
frame += this.terminal.CLEAR;
|
frame += this.terminal.CLEAR;
|
||||||
@ -210,11 +227,14 @@ class Renderer {
|
|||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
featuresAt(x: number, y: number): Feature[] {
|
// featuresAt(x: number, y: number) {
|
||||||
return this.labelBuffer.featuresAt(x, y);
|
// return this.labelBuffer.featuresAt(x, y);
|
||||||
}
|
// }
|
||||||
|
|
||||||
_drawFeature(tile, feature, scale: number): boolean {
|
private _drawFeature(tile: Tile, feature, scale: number): boolean {
|
||||||
|
if (!this.canvas) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
let points, placed;
|
let points, placed;
|
||||||
if (feature.style.minzoom && tile.zoom < feature.style.minzoom) {
|
if (feature.style.minzoom && tile.zoom < feature.style.minzoom) {
|
||||||
return false;
|
return false;
|
||||||
@ -278,7 +298,7 @@ class Renderer {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_scaleAndReduce(tile: Tile, feature: Feature, points: {x: number, y: number}[], scale: number, filter = true) {
|
private _scaleAndReduce(tile: Tile, feature: Feature, points: {x: number, y: number}[], scale: number, filter = true) {
|
||||||
let lastX;
|
let lastX;
|
||||||
let lastY;
|
let lastY;
|
||||||
let outside;
|
let outside;
|
||||||
@ -326,7 +346,7 @@ class Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_generateDrawOrder(zoom) {
|
private _generateDrawOrder(zoom) {
|
||||||
if (zoom < 2) {
|
if (zoom < 2) {
|
||||||
return [
|
return [
|
||||||
'admin',
|
'admin',
|
||||||
|
@ -60,7 +60,7 @@ class Styler {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_replaceConstants(constants, tree: RBush): void {
|
private _replaceConstants(constants, tree: RBush): void {
|
||||||
for (const id in tree) {
|
for (const id in tree) {
|
||||||
const node = tree[id];
|
const node = tree[id];
|
||||||
switch (typeof node) {
|
switch (typeof node) {
|
||||||
@ -79,7 +79,7 @@ class Styler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO Better translation of the long cases.
|
//TODO Better translation of the long cases.
|
||||||
_compileFilter(filter): (feature: Feature) => boolean {
|
private _compileFilter(filter): (feature: Feature) => boolean {
|
||||||
let filters;
|
let filters;
|
||||||
switch (filter != null ? filter[0] : void 0) {
|
switch (filter != null ? filter[0] : void 0) {
|
||||||
case 'all':
|
case 'all':
|
||||||
|
52
src/Tile.ts
52
src/Tile.ts
@ -14,10 +14,10 @@ import x256 from 'x256';
|
|||||||
import config from './config.ts';
|
import config from './config.ts';
|
||||||
import utils from './utils.ts';
|
import utils from './utils.ts';
|
||||||
import Styler from './Styler.ts';
|
import Styler from './Styler.ts';
|
||||||
import { Feature, Layers } from './Renderer.ts';
|
import { Layers } from './Renderer.ts';
|
||||||
|
|
||||||
class Tile {
|
class Tile {
|
||||||
public layers: Layers;
|
public layers: Layers = {};
|
||||||
private styler: Styler;
|
private styler: Styler;
|
||||||
private tile: VectorTile;
|
private tile: VectorTile;
|
||||||
|
|
||||||
@ -32,7 +32,9 @@ class Tile {
|
|||||||
z: number,
|
z: number,
|
||||||
};
|
};
|
||||||
public zoom: number;
|
public zoom: number;
|
||||||
public data: unknown;
|
public data: {
|
||||||
|
layers: unknown;
|
||||||
|
};
|
||||||
|
|
||||||
constructor(styler: Styler) {
|
constructor(styler: Styler) {
|
||||||
this.styler = styler;
|
this.styler = styler;
|
||||||
@ -76,7 +78,7 @@ class Tile {
|
|||||||
const colorCache: Record<string, string> = {};
|
const colorCache: Record<string, string> = {};
|
||||||
for (const name in this.tile.layers) {
|
for (const name in this.tile.layers) {
|
||||||
const layer = this.tile.layers[name];
|
const layer = this.tile.layers[name];
|
||||||
const nodes = [];
|
const nodes: unknown[] = [];
|
||||||
//continue if name is 'water'
|
//continue if name is 'water'
|
||||||
for (let i = 0; i < layer.length; i++) {
|
for (let i = 0; i < layer.length; i++) {
|
||||||
// TODO: caching of similar attributes to avoid looking up the style each time
|
// TODO: caching of similar attributes to avoid looking up the style each time
|
||||||
@ -159,28 +161,26 @@ class Tile {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _reduceGeometry(feature: Feature, factor: number): {x: number, y: number}[][] {
|
// private _reduceGeometry(feature: Feature, factor: number): {x: number, y: number}[][] {
|
||||||
const results: {x: number, y: number}[][] = [];
|
// const results: {x: number, y: number}[][] = [];
|
||||||
const geometries = feature.loadGeometry();
|
// const geometries = feature.loadGeometry();
|
||||||
for (const points of geometries) {
|
// for (const points of geometries) {
|
||||||
const reduced: {x: number, y: number}[] = [];
|
// const reduced: {x: number, y: number}[] = [];
|
||||||
let last;
|
// let last;
|
||||||
for (const point of points) {
|
// for (const point of points) {
|
||||||
const p = {
|
// const p = {
|
||||||
x: Math.floor(point.x / factor),
|
// x: Math.floor(point.x / factor),
|
||||||
y: Math.floor(point.y / factor)
|
// y: Math.floor(point.y / factor)
|
||||||
};
|
// };
|
||||||
if (last && last.x === p.x && last.y === p.y) {
|
// if (last && last.x === p.x && last.y === p.y) {
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
reduced.push(last = p);
|
// reduced.push(last = p);
|
||||||
}
|
// }
|
||||||
results.push(reduced);
|
// results.push(reduced);
|
||||||
}
|
// }
|
||||||
return results;
|
// return results;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
Tile.prototype.layers = {};
|
|
||||||
|
|
||||||
export default Tile;
|
export default Tile;
|
||||||
|
Loading…
Reference in New Issue
Block a user