mirror of
https://github.com/rastapasta/mapscii.git
synced 2024-11-25 01:23:58 +01:00
🎨 adding simplify-js to readme, adapting canvas
This commit is contained in:
parent
ae65f95e24
commit
2d7cff71eb
@ -58,10 +58,9 @@ If your terminal supports mouse events you can drag the map and use your scroll
|
||||
|
||||
#### Juggling the vectors and numbers
|
||||
* [`earcut`](https://github.com/mapbox/earcut) for polygon triangulation
|
||||
* [`rbush`](https://github.com/mourner/rbush) for 2D spatial indexing based label and mouse collision detection
|
||||
* [`breseham`](https://github.com/madbence/node-bresenham) for line calculations
|
||||
* [`sphericalmercator`](https://github.com/mapbox/node-sphericalmercator) for [EPSG:3857](http://spatialreference.org/ref/sr-org/6864/) <> [WGS84](http://spatialreference.org/ref/epsg/wgs-84/) conversions
|
||||
* [`tilebelt`](https://github.com/mapbox/tilebelt) for some [slippy map tilename](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames) calculations
|
||||
* [`rbush`](https://github.com/mourner/rbush) for 2D spatial indexing of geo and label data
|
||||
* [`breseham`](https://github.com/madbence/node-bresenham) for line point calculations
|
||||
* [`simplify-js`](https://github.com/mourner/simplify-js) for polyline simplifications
|
||||
|
||||
#### Handling the flow
|
||||
* [`bluebird`](https://github.com/petkaantonov/bluebird) for all the asynchronous [Promise](https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise) magic
|
||||
|
@ -35,9 +35,8 @@
|
||||
"rbush": "^2.0.1",
|
||||
"request": "^2.76.0",
|
||||
"request-promise": "^4.1.1",
|
||||
"sphericalmercator": "^1.0.5",
|
||||
"simplify-js": "^1.2.1",
|
||||
"term-mouse": "^0.1.1",
|
||||
"tilebelt": "^1.0.1",
|
||||
"userhome": "^1.0.0",
|
||||
"vector-tile": "^1.3.0",
|
||||
"x256": "0.0.2"
|
||||
|
@ -12,6 +12,8 @@
|
||||
###
|
||||
|
||||
bresenham = require 'bresenham'
|
||||
simplify = require 'simplify-js'
|
||||
|
||||
earcut = require 'earcut'
|
||||
BrailleBuffer = require './BrailleBuffer'
|
||||
utils = require './utils'
|
||||
@ -32,11 +34,11 @@ module.exports = class Canvas
|
||||
@buffer.writeText text, x, y, color, center
|
||||
|
||||
line: (from, to, color, width = 1) ->
|
||||
@_line from, to, color, width
|
||||
@_line from.x, from.y, to.x, to.y, color, width
|
||||
|
||||
polyline: (points, color, width = 1) ->
|
||||
for i in [1...points.length]
|
||||
@_line points[i-1], points[i], width, color
|
||||
@_line points[i-1].x, points[i-1].y, points[i].x, points[i].y, width, color
|
||||
|
||||
setBackground: (color) ->
|
||||
@buffer.setGlobalBackground color
|
||||
@ -53,37 +55,38 @@ module.exports = class Canvas
|
||||
continue if ring.length < 3
|
||||
holes.push vertices.length/2
|
||||
else
|
||||
return if ring.length < 3
|
||||
return false if ring.length < 3
|
||||
|
||||
for point in ring
|
||||
vertices = vertices.concat point
|
||||
vertices.push point.x
|
||||
vertices.push point.y
|
||||
|
||||
try
|
||||
triangles = earcut vertices, holes
|
||||
catch e
|
||||
return false
|
||||
|
||||
extract = (pointId) ->
|
||||
[vertices[pointId*2], vertices[pointId*2+1]]
|
||||
|
||||
for i in [0...triangles.length] by 3
|
||||
pa = extract(triangles[i])
|
||||
pb = extract(triangles[i+1])
|
||||
pc = extract(triangles[i+2])
|
||||
pa = @_polygonExtract vertices, triangles[i]
|
||||
pb = @_polygonExtract vertices, triangles[i+1]
|
||||
pc = @_polygonExtract vertices, triangles[i+2]
|
||||
|
||||
@_filledTriangle pa, pb, pc, color
|
||||
|
||||
true
|
||||
|
||||
_polygonExtract: (vertices, pointId) ->
|
||||
[vertices[pointId*2], vertices[pointId*2+1]]
|
||||
|
||||
# Inspired by Alois Zingl's "The Beauty of Bresenham's Algorithm"
|
||||
# -> http://members.chello.at/~easyfilter/bresenham.html
|
||||
_line: (pointA, pointB, width, color) ->
|
||||
_line: (x0, y0, x1, y1, width, color) ->
|
||||
|
||||
# Fall back to width-less bresenham algorithm if we dont have a width
|
||||
unless width = Math.max 0, width-1
|
||||
return bresenham pointA[0], pointA[1], pointB[0], pointB[1],
|
||||
return bresenham x0, y0, x1, y1,
|
||||
(x, y) => @buffer.setPixel x, y, color
|
||||
|
||||
[x0, y0] = pointA
|
||||
[x1, y1] = pointB
|
||||
dx = Math.abs x1-x0
|
||||
sx = if x0 < x1 then 1 else -1
|
||||
dy = Math.abs y1-y0
|
||||
@ -138,16 +141,9 @@ module.exports = class Canvas
|
||||
b = @_bresenham pointA, pointC
|
||||
c = @_bresenham pointA, pointB
|
||||
|
||||
# Filter out any points outside of the visible area
|
||||
# TODO: benchmark - is it more effective to filter double points, or does
|
||||
# it req more computing time than actually setting points multiple times?
|
||||
last = null
|
||||
points = a.concat(b).concat(c)
|
||||
.filter (point) => 0 <= point.y < @height
|
||||
.sort (a, b) -> if a.y is b.y then a.x - b.x else a.y-b.y
|
||||
.filter (point) ->
|
||||
[lastPoint, last] = [last, point]
|
||||
not lastPoint or lastPoint.x isnt point.x or lastPoint.y isnt point.y
|
||||
|
||||
for i in [0...points.length]
|
||||
point = points[i]
|
||||
@ -155,8 +151,8 @@ module.exports = class Canvas
|
||||
|
||||
if point.y is next?.y
|
||||
left = Math.max 0, point.x
|
||||
right = Math.min @width, next.x
|
||||
if left and right
|
||||
right = Math.min @width-1, next.x
|
||||
if left >= 0 and right <= @width
|
||||
@buffer.setPixel x, point.y, color for x in [left..right]
|
||||
|
||||
else
|
||||
|
@ -4,8 +4,6 @@
|
||||
|
||||
methods used all around
|
||||
###
|
||||
mercator = new (require('sphericalmercator'))()
|
||||
|
||||
constants =
|
||||
RADIUS: 6378137
|
||||
|
||||
@ -13,29 +11,14 @@ utils =
|
||||
clamp: (num, min, max) ->
|
||||
if num <= min then min else if num >= max then max else num
|
||||
|
||||
# Based on W. Randolph Franklin (WRF)'s Point Inclusion in Polygon Test
|
||||
# https://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
|
||||
pointInPolygon: (polygon, point) ->
|
||||
inside = false
|
||||
j = polygon.length-1
|
||||
for i in [0...polygon.length]
|
||||
if (polygon[i][1]>point[1]) isnt (polygon[j][1]>point[1]) and
|
||||
point[0] < (polygon[j][0]-polygon[i][0]) * (point[1]-polygon[i][1]) / (polygon[j][1]-polygon[i][1]) + polygon[i][0]
|
||||
inside = !inside
|
||||
j = i
|
||||
inside
|
||||
|
||||
ll2xy: (lon, lat) ->
|
||||
[
|
||||
utils.deg2rad(lon)*constants.RADIUS,
|
||||
Math.log(Math.tan(Math.PI/4 + utils.deg2rad(lat)/2)) * constants.RADIUS
|
||||
]
|
||||
deg2rad: (angle) ->
|
||||
# (angle / 180) * Math.PI
|
||||
angle * 0.017453292519943295
|
||||
|
||||
ll2tile: (lon, lat, zoom) ->
|
||||
[
|
||||
Math.floor (lon+180)/360*Math.pow(2, zoom)
|
||||
Math.floor (1-Math.log(Math.tan(lat*Math.PI/180)+1/Math.cos(lat*Math.PI/180))/Math.PI)/2*Math.pow(2, zoom)
|
||||
]
|
||||
x: (lon+180)/360*Math.pow(2, zoom)
|
||||
y: (1-Math.log(Math.tan(lat*Math.PI/180)+1/Math.cos(lat*Math.PI/180))/Math.PI)/2*Math.pow(2, zoom)
|
||||
z: zoom
|
||||
|
||||
tile2ll: (x, y, zoom) ->
|
||||
n = Math.PI - 2*Math.PI*y/Math.pow(2, zoom)
|
||||
@ -43,32 +26,9 @@ utils =
|
||||
lon: x/Math.pow(2, zoom)*360-180
|
||||
lat: 180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n)))
|
||||
|
||||
geoBBox: (center, zoom, width, height) ->
|
||||
[x, y] = utils.ll2xy center.lon, center.lat
|
||||
meterPerPixel = utils.metersPerPixel zoom, center.lat
|
||||
|
||||
width *= meterPerPixel
|
||||
height *= meterPerPixel
|
||||
|
||||
west = x - width*.5
|
||||
east = x + width*.5
|
||||
south = y + height*.5
|
||||
north = y - height*.5
|
||||
|
||||
box = mercator
|
||||
.inverse([west+1, south])
|
||||
.concat mercator.inverse([east-1, north])
|
||||
|
||||
metersPerPixel: (zoom, lat = 0) ->
|
||||
(Math.cos(lat * Math.PI/180) * 2 * Math.PI * constants.RADIUS) / (256 * Math.pow(2, zoom))
|
||||
|
||||
deg2rad: (angle) ->
|
||||
# (angle / 180) * Math.PI
|
||||
angle * 0.017453292519943295
|
||||
|
||||
rad2deg: (angle) ->
|
||||
angle / Math.PI * 180
|
||||
|
||||
hex2rgb: (color) ->
|
||||
return [255, 0, 0] unless color?.match
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user