diff --git a/scripts/cleanStyle.coffee b/scripts/cleanStyle.coffee new file mode 100644 index 0000000..3fa6ec2 --- /dev/null +++ b/scripts/cleanStyle.coffee @@ -0,0 +1,46 @@ +### + termap - Terminal Map Viewer + by Michael Strassburger + + 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 " +else + cleanStyle process.argv[2] diff --git a/src/Canvas.coffee b/src/Canvas.coffee new file mode 100644 index 0000000..23f36b2 --- /dev/null +++ b/src/Canvas.coffee @@ -0,0 +1,11 @@ +### + termap - Terminal Map Viewer + by Michael Strassburger + + 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 diff --git a/src/LabelBuffer.coffee b/src/LabelBuffer.coffee index 73d3290..a8fc693 100644 --- a/src/LabelBuffer.coffee +++ b/src/LabelBuffer.coffee @@ -1,3 +1,11 @@ +### + termap - Terminal Map Viewer + by Michael Strassburger + + Using 2D spatial indexing to avoid overlapping labels and markers + Future: to detect collision on mouse interaction +### + rbush = require 'rbush' module.exports = class LabelBuffer diff --git a/src/Styler.coffee b/src/Styler.coffee index 166fcf5..a2c8ed0 100644 --- a/src/Styler.coffee +++ b/src/Styler.coffee @@ -1,8 +1,15 @@ -fs = require 'fs' -# 'text-field' +### + termap - Terminal Map Viewer + by Michael Strassburger -# Verrrrry MVP implementation -# TODO: should be optimized by compiling the json to method&cb based filters + Minimalistic parser and compiler for Mapbox (Studio) Map Style files + 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 styleById: {} @@ -56,37 +63,3 @@ module.exports = class Styler for value in filter[2..] return false if feature.properties[field] is value 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, ' ' - ### diff --git a/src/utils.coffee b/src/utils.coffee new file mode 100644 index 0000000..f0ea4c6 --- /dev/null +++ b/src/utils.coffee @@ -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 diff --git a/termap.coffee b/termap.coffee index 64a62de..e8105f2 100644 --- a/termap.coffee +++ b/termap.coffee @@ -1,4 +1,8 @@ -Canvas = require '../drawille-canvas-blessed-contrib' +### + termap - Terminal Map Viewer + by Michael Strassburger +### + keypress = require 'keypress' TermMouse = require 'term-mouse' x256 = require 'x256' @@ -10,69 +14,38 @@ zlib = require 'zlib' mercator = new (require('sphericalmercator'))() triangulator = new (require('pnltri')).Triangulator() +Canvas = require __dirname+'/src/Canvas' LabelBuffer = require __dirname+'/src/LabelBuffer' Styler = require __dirname+'/src/Styler' - -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)) - +utils = require __dirname+'/src/utils' class Termap config: styleFile: __dirname+"/styles/bright.json" fillPolygons: true - zoomStep: 0.5 + zoomStep: 0.4 - # landuse "poi_label" - drawOrder: ["admin", "water", "building", "road", "housenum_label"] + drawOrder: ["admin", "water", "building", "road", "poi_label", "city_label", "housenum_label"] icons: car: "🚗" - school: "🏫" + school: "S" #{}"🏫" marker: "⭐" - 'art-gallery': "🎨" + 'art-gallery': "A" #"🎨" attraction: "❕" stadium: "🏈" toilet: "🚽" cafe: "☕" laundry: "👚" bus: "🚌" - restaurant: "🍛" - lodging: "🛏." + restaurant: "R" #🍛" + lodging: "B" #🛏" 'fire-station': "🚒" shop: "🛍" pharmacy: "💊" - beer: "🍺" - cinema: "🎦" + beer: "H" #"🍺" + cinema: "C" #"🎦" layers: housenum_label: @@ -195,9 +168,9 @@ class Termap if draw @_draw() - else - # display debug info for unhandled keys - @notify JSON.stringify key + # else + # # display debug info for unhandled keys + # @notify JSON.stringify key _parseTile: (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]) _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(',')}]" notify: (text) ->