refactoring into separate modules, extending Canvas

This commit is contained in:
Michael Straßburger 2016-09-21 14:57:43 +02:00
parent 51f3078fac
commit 241f9f7ef6
6 changed files with 127 additions and 84 deletions

46
scripts/cleanStyle.coffee Normal file
View File

@ -0,0 +1,46 @@
###
termap - Terminal Map Viewer
by Michael Strassburger <codepoet@cpan.org>
just a tool to make development easier
Input: Mapbox Studio map style file
Output: Reduced map style file (only supported attributes are kept)
###
fs = require 'fs'
cleanStyle = (file) ->
json = JSON.parse fs.readFileSync(file).toString()
cleanedStyle =
name: json.name
layers: []
for layer in json.layers
continue if layer.ref
cleanLayer =
type: layer.type
id: layer.id
paint: {}
'source-layer': layer['source-layer']
for key in ['filter', 'minzoom']
cleanLayer[key] = layer[key] if layer[key]
if layer.layout?['text-size']
cleanLayer.layout = 'text-size': layer.layout?['text-size']
for key in ['fill-color', 'line-color', 'text-color', 'background-color']
cleanLayer.paint[key] = layer.paint[key] if layer.paint?[key]
if Object.keys(cleanLayer.paint).length
cleanedStyle.layers.push cleanLayer
JSON.stringify cleanedStyle, null, ' '
console.log unless process.argv[2]
"usage: coffee cleanStyle.coffee <inputJSON>"
else
cleanStyle process.argv[2]

11
src/Canvas.coffee Normal file
View File

@ -0,0 +1,11 @@
###
termap - Terminal Map Viewer
by Michael Strassburger <codepoet@cpan.org>
Extends drawille-canvas to add additional drawing functions.
To be PRed up the tree at some point.
###
BlessedCanvas = require 'drawille-canvas-blessed-contrib'
module.exports = class Canvas extends BlessedCanvas

View File

@ -1,3 +1,11 @@
###
termap - Terminal Map Viewer
by Michael Strassburger <codepoet@cpan.org>
Using 2D spatial indexing to avoid overlapping labels and markers
Future: to detect collision on mouse interaction
###
rbush = require 'rbush' rbush = require 'rbush'
module.exports = class LabelBuffer module.exports = class LabelBuffer

View File

@ -1,8 +1,15 @@
fs = require 'fs' ###
# 'text-field' termap - Terminal Map Viewer
by Michael Strassburger <codepoet@cpan.org>
# Verrrrry MVP implementation Minimalistic parser and compiler for Mapbox (Studio) Map Style files
# TODO: should be optimized by compiling the json to method&cb based filters See: https://www.mapbox.com/mapbox-gl-style-spec/
Verrrrry MVP implementation
TODO: should be optimized by compiling the json to method&cb based filters
###
fs = require 'fs'
module.exports = class Styler module.exports = class Styler
styleById: {} styleById: {}
@ -56,37 +63,3 @@ module.exports = class Styler
for value in filter[2..] for value in filter[2..]
return false if feature.properties[field] is value return false if feature.properties[field] is value
true true
###
cleanStyle: (file) ->
json = JSON.parse fs.readFileSync(file).toString()
cleanedStyle =
name: json.name
layers: []
for layer in json.layers
continue if layer.ref
cleanLayer =
type: layer.type
id: layer.id
paint: {}
'source-layer': layer['source-layer']
for key in ['filter', 'minzoom']
cleanLayer[key] = layer[key] if layer[key]
if layer.layout?['text-size']
cleanLayer.layout = 'text-size': layer.layout?['text-size']
# TODO: opacity
for key in ['fill-color', 'line-color', 'text-color', 'background-color']
cleanLayer.paint[key] = layer.paint[key] if layer.paint?[key]
if Object.keys(cleanLayer.paint).length
cleanedStyle.layers.push cleanLayer
console.log JSON.stringify cleanedStyle, null, ' '
###

32
src/utils.coffee Normal file
View File

@ -0,0 +1,32 @@
utils =
deg2rad: (angle) ->
# (angle / 180) * Math.PI
angle * 0.017453292519943295
rad2deg: (angle) ->
angle / Math.PI * 180
hex2rgb: (color) ->
if not color.match
console.log color
process.exit()
return [255, 0, 0] unless color?.match
unless color.match /^#[a-fA-F0-9]{3,6}$/
throw new Error "#{color} isn\'t a supported hex color"
color = color.substr 1
decimal = parseInt color, 16
if color.length is 3
rgb = [decimal>>8, (decimal>>4)&15, decimal&15]
rgb.map (c) => c + (c<<4)
else
[(decimal>>16)&255, (decimal>>8)&255, decimal&255]
digits: (number, digits) ->
Math.floor(number*Math.pow(10, digits))/Math.pow(10, digits)
metersPerPixel: (zoom, lat = 0) ->
utils.rad2deg(40075017*Math.cos(utils.deg2rad(lat))/Math.pow(2, zoom+8))
module.exports = utils

View File

@ -1,4 +1,8 @@
Canvas = require '../drawille-canvas-blessed-contrib' ###
termap - Terminal Map Viewer
by Michael Strassburger <codepoet@cpan.org>
###
keypress = require 'keypress' keypress = require 'keypress'
TermMouse = require 'term-mouse' TermMouse = require 'term-mouse'
x256 = require 'x256' x256 = require 'x256'
@ -10,69 +14,38 @@ zlib = require 'zlib'
mercator = new (require('sphericalmercator'))() mercator = new (require('sphericalmercator'))()
triangulator = new (require('pnltri')).Triangulator() triangulator = new (require('pnltri')).Triangulator()
Canvas = require __dirname+'/src/Canvas'
LabelBuffer = require __dirname+'/src/LabelBuffer' LabelBuffer = require __dirname+'/src/LabelBuffer'
Styler = require __dirname+'/src/Styler' Styler = require __dirname+'/src/Styler'
utils = require __dirname+'/src/utils'
utils =
deg2rad: (angle) ->
# (angle / 180) * Math.PI
angle * 0.017453292519943295
rad2deg: (angle) ->
angle / Math.PI * 180
hex2rgb: (color) ->
if not color.match
console.log color
process.exit()
return [255, 0, 0] unless color?.match
unless color.match /^#[a-fA-F0-9]{3,6}$/
throw new Error "#{color} isn\'t a supported hex color"
color = color.substr 1
decimal = parseInt color, 16
if color.length is 3
rgb = [decimal>>8, (decimal>>4)&15, decimal&15]
rgb.map (c) => c + (c<<4)
else
[(decimal>>16)&255, (decimal>>8)&255, decimal&255]
digits: (number, digits) ->
Math.floor(number*Math.pow(10, digits))/Math.pow(10, digits)
metersPerPixel: (zoom, lat = 0) ->
utils.rad2deg(40075017*Math.cos(utils.deg2rad(lat))/Math.pow(2, zoom+8))
class Termap class Termap
config: config:
styleFile: __dirname+"/styles/bright.json" styleFile: __dirname+"/styles/bright.json"
fillPolygons: true fillPolygons: true
zoomStep: 0.5 zoomStep: 0.4
# landuse "poi_label" drawOrder: ["admin", "water", "building", "road", "poi_label", "city_label", "housenum_label"]
drawOrder: ["admin", "water", "building", "road", "housenum_label"]
icons: icons:
car: "🚗" car: "🚗"
school: "🏫" school: "S" #{}"🏫"
marker: "" marker: ""
'art-gallery': "🎨" 'art-gallery': "A" #"🎨"
attraction: "" attraction: ""
stadium: "🏈" stadium: "🏈"
toilet: "🚽" toilet: "🚽"
cafe: "" cafe: ""
laundry: "👚" laundry: "👚"
bus: "🚌" bus: "🚌"
restaurant: "🍛" restaurant: "R" #🍛"
lodging: "🛏." lodging: "B" #🛏"
'fire-station': "🚒" 'fire-station': "🚒"
shop: "🛍" shop: "🛍"
pharmacy: "💊" pharmacy: "💊"
beer: "🍺" beer: "H" #"🍺"
cinema: "🎦" cinema: "C" #"🎦"
layers: layers:
housenum_label: housenum_label:
@ -195,9 +168,9 @@ class Termap
if draw if draw
@_draw() @_draw()
else # else
# display debug info for unhandled keys # # display debug info for unhandled keys
@notify JSON.stringify key # @notify JSON.stringify key
_parseTile: (buffer) -> _parseTile: (buffer) ->
# extract, decode and parse a given tile buffer # extract, decode and parse a given tile buffer
@ -364,7 +337,7 @@ class Termap
mercator.inverse([x - width/2, y + width/2]).concat mercator.inverse([x + width/2, y - width/2]) mercator.inverse([x - width/2, y + width/2]).concat mercator.inverse([x + width/2, y - width/2])
_getFooter: -> _getFooter: ->
"center: [#{utils.digits @center.lat, 2}, #{utils.digits @center.lng, 2}] zoom: #{@zoom}" "center: [#{utils.digits @center.lat, 2}, #{utils.digits @center.lng, 2}] zoom: #{utils.digits @zoom, 2}"
# bbox: [#{@_getBBox().map((z) -> utils.digits(z, 2)).join(',')}]" # bbox: [#{@_getBBox().map((z) -> utils.digits(z, 2)).join(',')}]"
notify: (text) -> notify: (text) ->