From 44160eceb2dac81b2e50a5c911dce15772bb94d8 Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Mon, 14 Apr 2014 16:19:42 +0300 Subject: [PATCH 01/19] add new style --- debug/site.js | 2 +- debug/style-new.js | 607 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 608 insertions(+), 1 deletion(-) create mode 100644 debug/style-new.js diff --git a/debug/site.js b/debug/site.js index 121ca5ad740..74c6c97ac05 100644 --- a/debug/site.js +++ b/debug/site.js @@ -2,7 +2,7 @@ var llmr = require('../'), route = require('./route'), - style_json = require('./style'); + style_json = require('./style-new'); if (typeof document !== 'undefined') { var map = new llmr.Map({ diff --git a/debug/style-new.js b/debug/style-new.js new file mode 100644 index 00000000000..49bfb33dc27 --- /dev/null +++ b/debug/style-new.js @@ -0,0 +1,607 @@ +module.exports = { + "version": "1", + "buckets": { + "satellite": { + "filter": {"source": "satellite"} + }, + "park": { + "filter": {"source": "mapbox streets", "layer": "landuse", "class": "park"}, + "fill": true + }, + "wood": { + "filter": {"source": "mapbox streets", "layer": "landuse", "class": "wood"}, + "fill": true + }, + "water": { + "filter": {"source": "mapbox streets", "layer": "water"}, + "fill": true + }, + "waterway": { + "filter": {"source": "mapbox streets", "layer": "waterway"}, + "line": true + }, + "tunnel_large": { + "filter": {"source": "mapbox streets", "layer": "tunnel", "class": ["motorway", "main"]}, + "line": true, + "min-zoom": 14 + }, + "tunnel_regular": { + "filter": {"source": "mapbox streets", "layer": "tunnel", "class": ["street", "street_limited"]}, + "line": true, + "min-zoom": 15.5 + }, + "road_large": { + "filter": {"source": "mapbox streets", "layer": "road", "class": ["motorway", "main"]}, + "line": true, + "min-zoom": 13, + "line-cap": "round", + "line-join": "bevel" + }, + "road_regular": { + "filter": {"source": "mapbox streets", "layer": "road", "class": "street"}, + "line": true, + "min-zoom": 15.5, + "line-cap": "round", + "line-join": "bevel" + }, + "road_limited": { + "filter": {"source": "mapbox streets", "layer": "road", "class": "street_limited"}, + "line": true, + "line-cap": "round", + "line-join": "butt", + "line-round-limit": 0.7 + }, + "path": { + "filter": {"source": "mapbox streets", "layer": "road", "class": "path"}, + "line": true, + "line-cap": "round", + "line-join": "bevel" + }, + "rail": { + "filter": {"source": "mapbox streets", "layer": "road", "class": "major_rail"}, + "line": true, + "line-cap": "round", + "line-join": "bevel" + }, + "tunnel_rail": { + "filter": {"source": "mapbox streets", "layer": "tunnel", "class": ["minor_rail", "major_rail"]}, + "line": true + }, + "route": { + "filter": {"source": "geojson"}, + "line": true + }, + "road_markers": { + "filter": {"source": "mapbox streets", "layer": "road", "oneway": 1, "feature_type": "line"}, + "min-zoom": 15.5, + "point": true, + "point-spacing": 200 + }, + "building": { + "filter": {"source": "mapbox streets", "layer": "building"}, + "fill": true + }, + "borders": { + "filter": {"source": "mapbox streets", "layer": "admin"}, + "line": true + }, + "bridge_large": { + "filter": {"source": "mapbox streets", "layer": "bridge", "class": ["motorway", "main"]}, + "line": true, + "min-zoom": 14 + }, + "park_poi": { + "filter": {"source": "mapbox streets", "layer": "poi_label", "maki": "park"}, + "point": true + }, + "restaurant_poi": { + "filter": {"source": "mapbox streets", "layer": "poi_label", "maki": "restaurant"}, + "point": true, + "point-size": [12, 12] + }, + "country_label": { + "filter": {"source": "mapbox streets", "layer": "country_label", "feature_type": "point"}, + "text": true, + "text-field": "name", + "text-font": "Open Sans, Jomolhari, Siyam Rupali, Alef, Arial Unicode MS", + "text-max-size": 16, + "text-path": "horizontal", + "text-padding": 10 + }, + "place_label": { + "filter": {"source": "mapbox streets", "layer": "place_label", "feature_type": "point"}, + "text": true, + "text-field": "name", + "text-font": "Open Sans, Jomolhari, Siyam Rupali, Alef, Arial Unicode MS", + "text-max-size": 18, + "text-path": "horizontal", + "text-always-visible": true + }, + "road_label": { + "filter": {"source": "mapbox streets", "layer": "road_label", "feature_type": "line"}, + "text": true, + "text-field": "name", + "text-font": "Open Sans, Jomolhari, Siyam Rupali, Alef, Arial Unicode MS", + "text-max-size": 12, + "text-path": "curve", + "text-min-dist": 250, + "text-max-angle": 1.04 + } + }, + "layers": [{ + "id": "background" + }, { + "id": "satellite", + "bucket": "satellite" + }, { + "id": "park", + "bucket": "park" + }, { + "id": "wood", + "bucket": "wood" + }, { + "id": "water", + "bucket": "water" + }, { + "id": "waterway", + "bucket": "waterway" + }, { + "id": "roads", + "layers": [{ + "id": "tunnel_large_casing", + "bucket": "tunnel_large" + }, { + "id": "tunnel_regular_casing", + "bucket": "tunnel_regular" + }, { + "id": "tunnel_large", + "bucket": "tunnel_large" + }, { + "id": "tunnel_regular", + "bucket": "tunnel_regular" + }, { + "id": "road_large_casing", + "bucket": "road_large" + }, { + "id": "road_regular_casing", + "bucket": "road_regular" + }, { + "id": "road_limited", + "bucket": "road_limited" + }, { + "id": "road_large", + "bucket": "road_large" + }, { + "id": "road_regular", + "bucket": "road_regular" + }, { + "id": "path", + "bucket": "path" + }, { + "id": "rail", + "bucket": "rail" + }, { + "id": "tunnel_rail", + "bucket": "tunnel_rail" + }] + }, { + "id": "route", + "bucket": "route" + }, { + "id": "road_markers", + "bucket": "road_markers" + }, { + "id": "building", + "bucket": "building" + }, { + "id": "borders", + "bucket": "borders" + }, { + "id": "bridge_large_casing", + "bucket": "bridge_large" + }, { + "id": "bridge_large", + "bucket": "bridge_large" + }, { + "id": "park_poi", + "bucket": "park_poi" + }, { + "id": "restaurant_poi", + "bucket": "restaurant_poi" + }, { + "id": "country_label", + "bucket": "country_label" + }, { + "id": "place_label", + "bucket": "place_label" + }, { + "id": "road_label", + "bucket": "road_label" + }], + "constants": { + "land": "#e8e0d8", + "water": "#73b6e6", + "park": "#c8df9f", + "road": "#fefefe", + "border": "#6d90ab", + "wood": "#33AA66", + "building": "#d9ccbe", + "building_outline": "#d2c6b9", + "text": "#000000", + "satellite_brightness_low": 0, + "satellite_brightness_high": 1, + "satellite_saturation": 0, + "satellite_spin": 0, + "satellite_contrast": 0, + "road_blur": 1, + "stroke_width": 0.25 + }, + "styles": { + "default": { + "route": { + "line-color": "#EC8D8D", + "line-width": { + "fn": "exponential", + "z": 9, + "val": 1, + "slope": 0.21, + "min": 4 + } + }, + "background": { + "fill-color": "land", + "transition-fill-color": { + "duration": 500, + "delay": 0 + } + }, + "park": { + "fill-color": "park" + }, + "wood": { + "fill-color": "wood", + "fill-opacity": 0.08 + }, + "water": { + "fill-color": "water" + }, + "waterway": { + "line-color": "water", + "line-width": { + "fn": "linear", + "z": 9, + "val": 1, + "slope": 0.5, + "min": 0.5 + } + }, + "tunnel_large_casing": { + "line-color": [0, 0, 0, 0.5], + "line-width": 1, + "line-offset": { + "fn": "exponential", + "z": 9, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "tunnel_regular_casing": { + "line-color": [0, 0, 0, 0.5], + "line-width": 1, + "line-offset": { + "fn": "exponential", + "z": 11, + "val": 0.5, + "slope": 0.2, + "min": 1 + } + }, + "tunnel_large": { + "line-color": [1, 1, 1, 0.5], + "line-width": { + "fn": "exponential", + "z": 9, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "tunnel_regular": { + "line-color": [1, 1, 1, 0.5], + "line-width": { + "fn": "exponential", + "z": 11, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "roads": { + "opacity": 1, + "transition-opacity": { + "duration": 500, + "delay": 0 + } + }, + "road_large_casing": { + "line-color": [0.6, 0.6, 0.6, 1], + "line-width": { + "fn": "exponential", + "z": 9, + "val": 1, + "slope": 0.21, + "min": 4 + }, + "line-opacity": { + "fn": "linear", + "z": 14, + "val": 0, + "slope": 1, + "min": 0, + "max": 1 + }, + "transition-line-width": { + "duration": 500, + "delay": 0 + }, + "line-blur": "road_blur" + }, + "road_regular_casing": { + "line-color": [0.6, 0.6, 0.6, 1], + "line-width": { + "fn": "exponential", + "z": 10, + "val": 0.5, + "slope": 0.2, + "min": 1 + }, + "line-opacity": { + "fn": "linear", + "z": 15.5, + "val": 0, + "slope": 1, + "min": 0, + "max": 1 + }, + "line-blur": "road_blur" + }, + "road_limited": { + "line-dasharray": [10, 2], + "line-color": "road", + "line-blur": "road_blur", + "line-width": { + "fn": "exponential", + "z": 10, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "road_large": { + "line-color": "road", + "line-blur": "road_blur", + "line-width": { + "fn": "exponential", + "z": 9, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "road_regular": { + "line-color": "road", + "line-blur": "road_blur", + "line-width": { + "fn": "exponential", + "z": 10, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "path": { + "line-color": [1, 1, 1, 1], + "line-dasharray": [2, 2], + "line-width": 2 + }, + "rail": { + "line-color": [0.3, 0.3, 0.3, 0.8], + "line-dasharray": [2, 1], + "line-width": 3 + }, + "tunnel_rail": { + "line-color": [0.3, 0.3, 0.3, 0.3], + "line-dasharray": [2, 1], + "line-width": 3 + }, + "road_markers": { + "point-alignment": "line", + "point-image": "bicycle-12" + }, + "building": { + "fill-color": "building", + "transition-fill-opacity": { + "duration": 500, + "delay": 500 + }, + "fill-opacity": { + "fn": "linear", + "z": 14, + "val": 0, + "slope": 1, + "min": 0, + "max": 1 + }, + "stroke-color": "building_outline" + }, + "borders": { + "line-color": [0, 0, 0, 0.3], + "line-width": 1 + }, + "bridge_large_casing": { + "line-color": [0, 0, 0, 0.4], + "line-width": { + "fn": "exponential", + "z": 9, + "val": 1.5, + "slope": 0.2, + "min": 1 + } + }, + "bridge_large": { + "line-color": "road", + "line-width": { + "fn": "exponential", + "z": 9, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "park_poi": { + "point-color": "green" + }, + "restaurant_poi": { + "point-image": "restaurant-12" + }, + "country_label": { + "text-halo-color": [1, 1, 1, 0.7], + "text-halo-width": "stroke_width", + "text-color": "text" + }, + "place_label": { + "text-halo-color": [1, 1, 1, 0.7], + "text-halo-width": "stroke_width", + "text-color": "text" + }, + "road_label": { + "text-color": "text", + "text-halo-color": [1, 1, 1, 0.7], + "text-halo-width": "stroke_width", + "text-size": { + "fn": "exponential", + "z": 14, + "val": 8, + "slope": 1, + "min": 8, + "max": 12 + } + } + }, + "satellite": { + "background": { + "transition-fill-color": { + "duration": 500, + "delay": 500 + }, + "fill-opacity": 0, + "fill-color": [1, 0, 0, 0] + }, + "roads": { + "transition-opacity": { + "duration": 500, + "delay": 500 + }, + "opacity": 0.5 + }, + "building": { + "fill-opacity": 0, + "transition-fill-opacity": { + "duration": 500, + "delay": 0 + } + }, + "park": { + "transition-fill-color": { + "duration": 500, + "delay": 0 + }, + "fill-color": [0, 0, 0, 0] + }, + "water": { + "fill-opacity": 0 + }, + "road_large": { + "transition-line-width": { + "duration": 500, + "delay": 1000 + }, + "line-width": { + "fn": "exponential", + "z": 10, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "road_large_casing": { + "line-width": { + "fn": "exponential", + "z": 10, + "val": 1, + "slope": 0.21, + "min": 4 + }, + "transition-line-width": { + "duration": 500, + "delay": 1000 + } + }, + "road_regular_casing": { + "transition-line-width": { + "duration": 500, + "delay": 1000 + }, + "line-width": { + "fn": "exponential", + "z": 11, + "val": 0.5, + "slope": 0.2, + "min": 1 + } + }, + "road_regular": { + "transition-line-width": { + "duration": 500, + "delay": 1000 + }, + "line-width": { + "fn": "exponential", + "z": 11, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "satellite": { + "raster-brightness-low": "satellite_brightness_low", + "raster-brightness-high": "satellite_brightness_high", + "raster-saturation": "satellite_saturation", + "raster-spin": "satellite_spin", + "raster-contrast": "satellite_contrast" + } + }, + "test": { + "road_large_casing": { + "line-width": { + "fn": "exponential", + "z": 8, + "val": 1, + "slope": 0.21, + "min": 4 + }, + "line-color": [1, 0, 0, 1], + "transition-line-width": { + "duration": 500, + "delay": 0 + }, + "transition-line-color": { + "duration": 2000, + "delay": 500 + } + } + } + }, + "sprite": "img/sprite" +} From 9fa6b78a9c697a4a878bd017161c2b202752b000 Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Mon, 14 Apr 2014 16:20:31 +0300 Subject: [PATCH 02/19] update style parsing --- js/style/style.js | 66 +++++++++++----------- js/style/styledeclaration.js | 103 ++++++++++++++++++----------------- 2 files changed, 86 insertions(+), 83 deletions(-) diff --git a/js/style/style.js b/js/style/style.js index 9ae1114f9a8..3de382b3d95 100644 --- a/js/style/style.js +++ b/js/style/style.js @@ -18,7 +18,7 @@ module.exports = Style; */ function Style(stylesheet, animationLoop) { if (typeof stylesheet.buckets !== 'object') console.warn('Stylesheet must have buckets'); - if (!Array.isArray(stylesheet.structure)) console.warn('Stylesheet must have structure array'); + if (!Array.isArray(stylesheet.layers)) console.warn('Stylesheet must have layers'); this.classes = { 'default': true }; this.stylesheet = stylesheet; @@ -55,24 +55,24 @@ Style.prototype.recalculate = function(z) { } // Some properties influence others - if (appliedLayer.opacity && appliedLayer.color) { - appliedLayer.color = appliedLayer.color.slice(); - appliedLayer.color[3] = appliedLayer.opacity; - util.premultiply(appliedLayer.color); - } - - if (appliedLayer.opacity && appliedLayer.stroke) { - appliedLayer.stroke = appliedLayer.stroke.slice(); - appliedLayer.stroke[3] = appliedLayer.opacity; - util.premultiply(appliedLayer.stroke); - } + // if (appliedLayer.opacity && appliedLayer.color) { + // appliedLayer.color = appliedLayer.color.slice(); + // appliedLayer.color[3] = appliedLayer.opacity; + // util.premultiply(appliedLayer.color); + // } + + // if (appliedLayer.opacity && appliedLayer.stroke) { + // appliedLayer.stroke = appliedLayer.stroke.slice(); + // appliedLayer.stroke[3] = appliedLayer.opacity; + // util.premultiply(appliedLayer.stroke); + // } // todo add more checks for width and color if (appliedLayer.opacity === 0) { appliedLayer.hidden = true; } - if (typeof appliedLayer.antialias === 'undefined') { + if (appliedLayer.antialias === undefined) { appliedLayer.antialias = true; } } @@ -81,11 +81,13 @@ Style.prototype.recalculate = function(z) { // so that we can automatically enable/disable them as needed var buckets = this.stylesheet.buckets; var sources = this.sources = {}; - this.layerGroups = groupLayers(this.stylesheet.structure); + + this.layerGroups = groupLayers(this.stylesheet.layers); + // Split the layers into groups of consecutive layers with the same datasource // For each group calculate its dependencies. Its dependencies are composited - // layers that need to be rendered into textures before + // layers that need to be rendered into textures before function groupLayers(layers) { var i = layers.length - 1; @@ -95,8 +97,8 @@ Style.prototype.recalculate = function(z) { while (i >= 0) { var layer = layers[i]; - var bucket = buckets[layer.bucket]; - var source = bucket && bucket.source; + var bucket = buckets[layer.id]; + var source = bucket && bucket.filter.source; var group = []; group.dependencies = {}; @@ -106,25 +108,25 @@ Style.prototype.recalculate = function(z) { // low over layers top down until you reach one from a different datasource while (i >= 0) { layer = layers[i]; - bucket = buckets[layer.bucket]; - source = bucket && bucket.source; + bucket = buckets[layer.id]; + source = bucket && bucket.filter.source; - var style = layerValues[layer.name]; + var style = layerValues[layer.id]; if (!style || style.hidden) { i--; continue; } // if the current layer is in a different source - if (source !== group.source && layer.bucket !== 'background') break; + if (source !== group.source && layer.id !== 'background') break; if (layer.layers) { // TODO if composited layer is opaque just inline the layers - group.dependencies[layer.name] = groupLayers(layer.layers); + group.dependencies[layer.id] = groupLayers(layer.layers); } else { // mark source as used so that tiles are downloaded - if (bucket && bucket.source) sources[bucket.source] = true; + if (source) sources[source] = true; } group.push(layer); @@ -149,24 +151,22 @@ Style.prototype.cascade = function() { var newStyle = {}; var name, prop, layer, declaration; - var sheetClasses = this.stylesheet.classes; + var sheetClasses = this.stylesheet.styles; var transitions = {}; if (!sheetClasses) return; // Recalculate style // Basic cascading - for (var i = 0; i < sheetClasses.length; i++) { - var sheetClass = sheetClasses[i]; - + for (var className in sheetClasses) { // Not enabled - if (!this.classes[sheetClass.name]) continue; + if (!this.classes[className]) continue; - for (name in sheetClass.layers) { - layer = sheetClass.layers[name]; + for (name in sheetClasses[className]) { + layer = sheetClasses[className][name]; - if (typeof newStyle[name] === 'undefined') newStyle[name] = {}; - if (typeof transitions[name] === 'undefined') transitions[name] = {}; + newStyle[name] = newStyle[name] || {}; + transitions[name] = transitions[name] || {}; for (prop in layer) { if (prop.indexOf('transition-') === 0) { @@ -233,7 +233,7 @@ Style.prototype.getDefaultClass = function() { }; Style.prototype.getClass = function(name) { - var classes = this.stylesheet.classes; + var classes = this.stylesheet.styles; for (var i = 0; i < classes.length; i++) { if (classes[i].name === name) { return classes[i]; diff --git a/js/style/styledeclaration.js b/js/style/styledeclaration.js index 983eb1c9771..f3c6a37576f 100644 --- a/js/style/styledeclaration.js +++ b/js/style/styledeclaration.js @@ -34,32 +34,35 @@ StyleDeclaration.prototype.parsers = { hidden: parseFunction, opacity: parseFunction, - color: parseColor, - stroke: parseColor, - - width: parseWidth, - offset: parseWidth, - radius: parseWidth, - blur: parseWidth, - strokeWidth: parseWidth, - size: parseWidth, - rotate: parseWidth, - - dasharray: parseWidthArray, - translate: parseWidthArray, + 'line-color': parseColor, + 'fill-color': parseColor, + 'stroke-color': parseColor, + + 'line-width': parseWidth, + 'line-offset': parseWidth, + 'point-radius': parseWidth, + 'point-blur': parseWidth, + 'point-rotate': parseWidth, + 'text-size': parseWidth, + 'text-halo-width': parseWidth, + + 'line-dasharray': parseWidthArray, + 'line-translate': parseWidthArray, + 'fill-translate': parseWidthArray, + 'text-translate': parseWidthArray, antialias: constant, - image: constant, - invert: constant, - imageSize: constant, - alignment: constant, - pattern: constant, - - spin: constant, - brightness_low: constant, - brightness_high: constant, - saturation: constant, - contrast: constant + 'point-image': constant, + // invert: constant, + 'point-size': constant, + 'point-alignment': constant, + // pattern: constant, + + 'raster-spin': constant, + 'raster-brightness-low': constant, + 'raster-brightness-high': constant, + 'raster-saturation': constant, + 'raster-contrast': constant }; @@ -120,11 +123,11 @@ var functionParsers = StyleDeclaration.functionParsers = { }; function parseFunction(fn) { - if (Array.isArray(fn)) { - if (!functionParsers[fn[0]]) { - throw new Error('The function "' + fn[0] + '" does not exist'); + if (fn.fn) { + if (!functionParsers[fn.fn]) { + throw new Error('The function "' + fn.fn + '" does not exist'); } - return functionParsers[fn[0]].apply(null, fn.slice(1)); + return functionParsers[fn.fn](fn); } else { return fn; } @@ -134,37 +137,37 @@ function parseFunction(fn) { * Function parsers */ -function linear(z_base, val, slope, min, max) { - z_base = +z_base || 0; - val = +val || 0; - slope = +slope || 0; - min = +min || 0; - max = +max || Infinity; +function linear(params) { + var z_base = +params.z_base || 0, + val = +params.val || 0, + slope = +params.slope || 0, + min = +params.min || 0, + max = +params.max || Infinity; return function(z) { return Math.min(Math.max(min, val + (z - z_base) * slope), max); }; } -function exponential(z_base, val, slope, min, max) { - z_base = +z_base || 0; - val = +val || 0; - slope = +slope || 0; - min = +min || 0; - max = +max || Infinity; +function exponential(params) { + var z_base = +params.z_base || 0, + val = +params.val || 0, + slope = +params.slope || 0, + min = +params.min || 0, + max = +params.max || Infinity; return function(z) { return Math.min(Math.max(min, val + Math.pow(1.75, (z - z_base)) * slope), max); }; } -function min(min_z) { - min_z = +min_z || 0; +function min(params) { + var min_z = +params.min || 0; return function(z) { return z >= min_z; }; } -function stopsFn() { - var stops = Array.prototype.slice.call(arguments); +function stopsFn(params) { + var stops = params.stops; return function(z) { z += 1; @@ -173,17 +176,17 @@ function stopsFn() { for (var i = 0; i < stops.length; i++) { var stop = stops[i]; - if (stop.z <= z && (!smaller || smaller.z < stop.z)) smaller = stop; - if (stop.z >= z && (!larger || larger.z > stop.z)) larger = stop; + if (stop[0] <= z && (!smaller || smaller[0] < stop[0])) smaller = stop; + if (stop[0] >= z && (!larger || larger[0] > stop[0])) larger = stop; } if (smaller && larger) { - if (larger.z == smaller.z || larger.val == smaller.val) return smaller.val; - var factor = (z - smaller.z) / (larger.z - smaller.z); + if (larger[0] == smaller[0] || larger[1] == smaller[1]) return smaller[1]; + var factor = (z - smaller[0]) / (larger[0] - smaller[0]); // Linear interpolation if base is 0 - if (smaller.val === 0) return factor * larger.val; + if (smaller[1] === 0) return factor * larger[1]; // Exponential interpolation between the values - return smaller.val * Math.pow(larger.val / smaller.val, factor); + return smaller[1] * Math.pow(larger[1] / smaller[1], factor); } else if (larger || smaller) { // Do not draw a line. return null; From 66d90b5dc32f0efae387759cd349532e3c85550e Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Mon, 14 Apr 2014 16:20:47 +0300 Subject: [PATCH 03/19] update bucket filter parsing --- js/worker/worker.js | 51 ++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/js/worker/worker.js b/js/worker/worker.js index 0b3e6c853d0..312fc92b2a3 100644 --- a/js/worker/worker.js +++ b/js/worker/worker.js @@ -12,35 +12,38 @@ if (typeof self.alert === 'undefined') { }; } -// Builds a function body from the JSON specification. Allows specifying other compare operations. -var comparators = { - '==': function(bucket) { - if (!('field' in bucket)) return; - var value = bucket.value, field = bucket.field; - return 'return ' + (Array.isArray(value) ? value : [value]).map(function(value) { - return 'feature[' + JSON.stringify(field) + '] == ' + JSON.stringify(value); - }).join(' || ') + ';'; +function matchFn(bucket) { + // jshint evil: true + if (!('filter' in bucket)) return; + + var filters = []; + for (var key in bucket.filter) { + if (key === 'source' || key === 'layer') continue; + var value = bucket.filter[key]; + if (Array.isArray(value)) { + filters.push.apply(filters, value.map(function (v) { + return {key: key, value: v}; + })); + } else { + filters.push({key: key, value: value}); + } } -}; + if (!filters.length) return; -/* - * Updates the style to use for this map. - * - * @param {Style} data - */ + var fnCode = 'return ' + filters.map(function(f) { + return 'f[' + JSON.stringify(f.key) + '] == ' + JSON.stringify(f.value); + }).join(' || ') + ';'; + + return new Function('f', fnCode); +} + +// Updates the style to use for this map. self['set buckets'] = function(data) { var buckets = WorkerTile.buckets = data; - for (var name in buckets) { - var bucket = buckets[name]; - var compare = bucket.compare || '=='; - if (compare in comparators) { - var code = comparators[compare](bucket); - if (code) { - /* jshint evil: true */ - bucket.fn = new Function('feature', code); - } - } + + for (var id in buckets) { + buckets[id].fn = matchFn(buckets[id]); } }; From 556c0ebd0b501f3b3647b5ecc20e42e7fc1b8679 Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Mon, 14 Apr 2014 16:46:32 +0300 Subject: [PATCH 04/19] update wokertile style handling --- js/worker/workertile.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/js/worker/workertile.js b/js/worker/workertile.js index 69e7ba3dcff..dc3de426698 100644 --- a/js/worker/workertile.js +++ b/js/worker/workertile.js @@ -193,22 +193,25 @@ WorkerTile.prototype.parse = function(tile, callback) { } // Find all layers that we need to pull information from. - var source_layers = {}; + var sourceLayers = {}, + layerName; + for (var bucket in buckets) { - if (!source_layers[buckets[bucket].layer]) source_layers[buckets[bucket].layer] = {}; - source_layers[buckets[bucket].layer][bucket] = buckets[bucket]; + layerName = buckets[bucket].filter.layer; + if (!sourceLayers[layerName]) sourceLayers[layerName] = {}; + sourceLayers[layerName][bucket] = buckets[bucket]; } - for (var layer_name in source_layers) { - var layer = tile.layers[layer_name]; + for (layerName in sourceLayers) { + var layer = tile.layers[layerName]; if (!layer) continue; - var featuresets = sortFeaturesIntoBuckets(layer, source_layers[layer_name]); + var featuresets = sortFeaturesIntoBuckets(layer, sourceLayers[layerName]); // Build an index of font faces used in this layer. - var face_index = []; + var faceIndex = []; for (var i = 0; i < layer.faces.length; i++) { - face_index[i] = tile.faces[layer.faces[i]]; + faceIndex[i] = tile.faces[layer.faces[i]]; } // All features are sorted into buckets now. Add them to the geometry From b2200a7ec603b340700fceeaa963ff2f59070b7c Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Mon, 14 Apr 2014 16:52:07 +0300 Subject: [PATCH 05/19] update style parsing more --- js/style/styledeclaration.js | 4 ++++ js/style/styletransition.js | 24 ++++++++++++++---------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/js/style/styledeclaration.js b/js/style/styledeclaration.js index f3c6a37576f..14c9717ffd6 100644 --- a/js/style/styledeclaration.js +++ b/js/style/styledeclaration.js @@ -32,7 +32,10 @@ StyleDeclaration.prototype.calculate = function(z) { StyleDeclaration.prototype.parsers = { hidden: parseFunction, + opacity: parseFunction, + 'fill-opacity': parseFunction, + 'line-opacity': parseFunction, 'line-color': parseColor, 'fill-color': parseColor, @@ -40,6 +43,7 @@ StyleDeclaration.prototype.parsers = { 'line-width': parseWidth, 'line-offset': parseWidth, + 'line-blur': parseWidth, 'point-radius': parseWidth, 'point-blur': parseWidth, 'point-rotate': parseWidth, diff --git a/js/style/styletransition.js b/js/style/styletransition.js index 8beb9abf6f3..6ae390f9bff 100644 --- a/js/style/styletransition.js +++ b/js/style/styletransition.js @@ -56,22 +56,26 @@ StyleTransition.prototype.at = function(z, t) { var interpNumber = util.interp; StyleTransition.prototype.interpolators = { + 'fill-opacity': interpNumber, + 'line-opacity': interpNumber, opacity: interpNumber, - color: interpColor, - stroke: interpColor, + 'fill-color': interpColor, + 'line-color': interpColor, + 'stroke-color': interpColor, - width: interpNumber, - offset: interpNumber, - radius: interpNumber, - blur: interpNumber, + 'line-width': interpNumber, + 'line-offset': interpNumber, + 'point-radius': interpNumber, + 'point-blur': interpNumber, + 'line-blur': interpNumber, 'fade-dist': interpNumber, - dasharray: interpNumberArray, + 'line-dasharray': interpNumberArray, - brightness_low: interpNumber, - brightness_high: interpNumber, - saturation: interpNumber + 'raster-brightness-low': interpNumber, + 'raster-brightness-high': interpNumber, + 'raster-saturation': interpNumber }; function interpNumberArray(from, to, t) { From 56346f8484c2fba64fe092f04c55013e2729b42c Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Mon, 14 Apr 2014 17:14:31 +0300 Subject: [PATCH 06/19] fix bucket parsing --- js/geometry/bucket.js | 8 ++++---- js/worker/workertile.js | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/js/geometry/bucket.js b/js/geometry/bucket.js index 7c4c7c160ff..e6b727596e0 100644 --- a/js/geometry/bucket.js +++ b/js/geometry/bucket.js @@ -11,19 +11,19 @@ function Bucket(info, geometry, placement, indices) { this.placement = placement; this.indices = indices; // only used after transfer from worker - if (info.type === 'text') { + if (info.text) { this.addFeature = this.addText; - } else if (info.type == 'point') { + } else if (info.point) { this.addFeature = this.addPoint; this.size = info.size; this.spacing = info.spacing; this.padding = info.padding || 2; - } else if (info.type == 'line') { + } else if (info.line) { this.addFeature = this.addLine; - } else if (info.type == 'fill') { + } else if (info.fill) { this.addFeature = this.addFill; } else { diff --git a/js/worker/workertile.js b/js/worker/workertile.js index dc3de426698..7b852e4c5cb 100644 --- a/js/worker/workertile.js +++ b/js/worker/workertile.js @@ -92,8 +92,8 @@ function sortFeaturesIntoBuckets(layer, mapping) { if (!mapping[key].fn || mapping[key].fn(feature)) { // Only load features that have the same geometry type as the bucket. - var type = mapping[key].feature_type || mapping[key].type; - if (type === VectorTileFeature.mapping[feature._type]) { + var type = VectorTileFeature.mapping[feature._type]; + if (type === mapping[key].filter.feature_type || mapping[key][type]) { if (!(key in buckets)) buckets[key] = []; buckets[key].push(feature); } @@ -222,7 +222,7 @@ WorkerTile.prototype.parse = function(tile, callback) { if (!info) { alert("missing bucket information for bucket " + key); } else { - layers[key] = self.parseBucket(key, features, info, face_index, layer); + layers[key] = self.parseBucket(key, features, info, faceIndex, layer); } } } From add7a46ba9955c5a3b83b6012a6ab2cececcdf1d Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Mon, 14 Apr 2014 20:53:49 +0300 Subject: [PATCH 07/19] fix style functions --- js/style/styledeclaration.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/style/styledeclaration.js b/js/style/styledeclaration.js index 14c9717ffd6..ee9d52a41d0 100644 --- a/js/style/styledeclaration.js +++ b/js/style/styledeclaration.js @@ -142,7 +142,7 @@ function parseFunction(fn) { */ function linear(params) { - var z_base = +params.z_base || 0, + var z_base = +params.z || 0, val = +params.val || 0, slope = +params.slope || 0, min = +params.min || 0, @@ -153,7 +153,7 @@ function linear(params) { } function exponential(params) { - var z_base = +params.z_base || 0, + var z_base = +params.z || 0, val = +params.val || 0, slope = +params.slope || 0, min = +params.min || 0, From 67e272543658ea123dbc79f92b64081b2c131da9 Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Mon, 14 Apr 2014 21:01:35 +0300 Subject: [PATCH 08/19] update painters --- js/render/drawcomposited.js | 4 ++-- js/render/drawfill.js | 10 ++++++---- js/render/drawline.js | 10 +++++----- js/render/drawpoint.js | 14 +++++++------- js/render/painter.js | 20 ++++++++++---------- 5 files changed, 30 insertions(+), 28 deletions(-) diff --git a/js/render/drawcomposited.js b/js/render/drawcomposited.js index b4847acdb9d..e1f0129f5c8 100644 --- a/js/render/drawcomposited.js +++ b/js/render/drawcomposited.js @@ -3,8 +3,8 @@ module.exports = drawComposited; function drawComposited (gl, painter, buckets, layerStyle, params, style, layer) { - var texture = painter.namedRenderTextures[layer.name]; - if (!texture) return console.warn('missing render texture ' + layer.name); + var texture = painter.namedRenderTextures[layer.id]; + if (!texture) return console.warn('missing render texture ' + layer.id); gl.disable(gl.STENCIL_TEST); gl.stencilMask(0x00); diff --git a/js/render/drawfill.js b/js/render/drawfill.js index abf7169a156..2dbf3f0036a 100644 --- a/js/render/drawfill.js +++ b/js/render/drawfill.js @@ -3,9 +3,9 @@ module.exports = drawFill; function drawFill(gl, painter, bucket, layerStyle, params, imageSprite, background) { - if (typeof layerStyle.color !== 'object') console.warn('layer style has a color'); + if (typeof layerStyle['fill-color'] !== 'object') console.warn('layer style has a color'); - var color = layerStyle.color; + var color = layerStyle['fill-color']; // TODO: expose this to the stylesheet. var evenodd = false; @@ -78,7 +78,9 @@ function drawFill(gl, painter, bucket, layerStyle, params, imageSprite, backgrou gl.switchShader(painter.outlineShader, painter.translatedMatrix || painter.tile.posMatrix, painter.tile.exMatrix); gl.lineWidth(2 * window.devicePixelRatio); - if (layerStyle.stroke) { + var strokeColor = layerStyle['stroke-color']; + + if (strokeColor) { // If we defined a different color for the fill outline, we are // going to ignore the bits in 0x3F and just care about the global // clipping mask. @@ -93,7 +95,7 @@ function drawFill(gl, painter, bucket, layerStyle, params, imageSprite, backgrou } gl.uniform2f(painter.outlineShader.u_world, gl.drawingBufferWidth, gl.drawingBufferHeight); - gl.uniform4fv(painter.outlineShader.u_color, layerStyle.stroke ? layerStyle.stroke : color); + gl.uniform4fv(painter.outlineShader.u_color, strokeColor ? strokeColor : color); // Draw all buffers buffer = bucket.indices.fillBufferIndex; diff --git a/js/render/drawline.js b/js/render/drawline.js index b862f33ad04..2e1220a4863 100644 --- a/js/render/drawline.js +++ b/js/render/drawline.js @@ -1,12 +1,12 @@ 'use strict'; module.exports = function drawLine(gl, painter, bucket, layerStyle, params, imageSprite) { - if (typeof layerStyle.color !== 'object') console.warn('layer style has a color'); + if (typeof layerStyle['line-color'] !== 'object') console.warn('layer style has a color'); - var width = layerStyle.width; + var width = layerStyle['line-width']; if (width === null) return; - var offset = (layerStyle.offset || 0) / 2; + var offset = (layerStyle['line-offset'] || 0) / 2; var inset = Math.max(-1, offset - width / 2 - 0.5) + 1; var outset = offset + width / 2 + 0.5; @@ -36,9 +36,9 @@ module.exports = function drawLine(gl, painter, bucket, layerStyle, params, imag gl.uniform2fv(shader.u_linewidth, [ outset, inset ]); gl.uniform1f(shader.u_ratio, tilePixelRatio); gl.uniform1f(shader.u_gamma, window.devicePixelRatio); - gl.uniform1f(shader.u_blur, layerStyle.blur === undefined ? 1 : layerStyle.blur); + gl.uniform1f(shader.u_blur, layerStyle['line-blur'] === undefined ? 1 : layerStyle['line-blur']); - var color = layerStyle.color; + var color = layerStyle['line-color']; if (!params.antialiasing) { color = color.slice(); diff --git a/js/render/drawpoint.js b/js/render/drawpoint.js index 63a62404bf8..94f064915bf 100644 --- a/js/render/drawpoint.js +++ b/js/render/drawpoint.js @@ -12,29 +12,29 @@ module.exports = function drawPoint(gl, painter, bucket, layerStyle, params, ima bucket.geometry.pointVertex.bind(gl); gl.switchShader(shader, painter.translatedMatrix || painter.tile.posMatrix, painter.tile.exMatrix); - gl.uniform4fv(shader.u_color, layerStyle.color || [0, 0, 0, 0]); + gl.uniform4fv(shader.u_color, layerStyle['point-color'] || [0, 0, 0, 0]); if (!imagePos) { - var diameter = (layerStyle.radius * 2.0 || 8.0) * window.devicePixelRatio; + var diameter = (layerStyle['point-radius'] * 2.0 || 8.0) * window.devicePixelRatio; gl.uniform1f(shader.u_size, diameter); - gl.uniform1f(shader.u_blur, (layerStyle.blur || 1.5) / diameter); + gl.uniform1f(shader.u_blur, (layerStyle['point-blur'] || 1.5) / diameter); gl.vertexAttribPointer(shader.a_pos, 4, gl.SHORT, false, 8, 0); gl.drawArrays(gl.POINTS, begin, count); } else { - gl.uniform1i(shader.u_invert, layerStyle.invert); + gl.uniform1i(shader.u_invert, layerStyle['point-invert']); gl.uniform2fv(shader.u_size, imagePos.size); gl.uniform2fv(shader.u_tl, imagePos.tl); gl.uniform2fv(shader.u_br, imagePos.br); gl.uniform1f(shader.u_zoom, (painter.transform.zoom - params.z) * 10.0); - var rotate = layerStyle.alignment && layerStyle.alignment !== 'screen'; + var rotate = layerStyle['point-alignment'] && layerStyle['point-alignment'] !== 'screen'; var rotationMatrix = rotate ? mat2.clone(painter.tile.rotationMatrix) : mat2.create(); - if (layerStyle.rotate) { - mat2.rotate(rotationMatrix, rotationMatrix, layerStyle.rotate); + if (layerStyle['point-rotate']) { + mat2.rotate(rotationMatrix, rotationMatrix, layerStyle['point-rotate']); } gl.uniformMatrix2fv(shader.u_rotationmatrix, false, rotationMatrix); diff --git a/js/render/painter.js b/js/render/painter.js index a2d5def065d..dddd2428ac8 100644 --- a/js/render/painter.js +++ b/js/render/painter.js @@ -291,16 +291,16 @@ GLPainter.prototype.draw = function glPainterDraw(tile, style, layers, params) { GLPainter.prototype.applyStyle = function(layer, style, buckets, params) { var gl = this.gl; - var layerStyle = style.computed[layer.name]; + var layerStyle = style.computed[layer.id]; if (!layerStyle || layerStyle.hidden) return; if (layer.layers) { drawComposited(gl, this, buckets, layerStyle, params, style, layer); - } else if (layer.bucket === 'background') { + } else if (layer.id === 'background') { drawFill(gl, this, undefined, layerStyle, params, style.sprite, true); } else { - var bucket = buckets[layer.bucket]; + var bucket = buckets[layer.id]; // There are no vertices yet for this layer. if (!bucket || !bucket.indices) return; @@ -314,17 +314,17 @@ GLPainter.prototype.applyStyle = function(layer, style, buckets, params) { mat4.translate(this.translatedMatrix, this.tile.posMatrix, translation); } - var type = bucket.info.type, - draw = type === 'text' ? drawText : - type === 'fill' ? drawFill : - type === 'line' ? drawLine : - type === 'point' ? drawPoint : - type === 'raster' ? drawRaster : null; + var info = bucket.info, + draw = info.text ? drawText : + info.fill ? drawFill : + info.line ? drawLine : + info.point ? drawPoint : + info.raster ? drawRaster : null; if (draw) { draw(gl, this, bucket, layerStyle, params, style.sprite); } else { - console.warn('Unknown bucket type ' + type); + console.warn('No bucket type specified'); } if (layerStyle.translate) { From 09cb79b81609724c1cfdb0665da27f12f9031f1b Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Mon, 14 Apr 2014 21:02:02 +0300 Subject: [PATCH 09/19] fix more properties in bucket parsing --- js/geometry/bucket.js | 45 ++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/js/geometry/bucket.js b/js/geometry/bucket.js index e6b727596e0..6792d91c22f 100644 --- a/js/geometry/bucket.js +++ b/js/geometry/bucket.js @@ -16,9 +16,9 @@ function Bucket(info, geometry, placement, indices) { } else if (info.point) { this.addFeature = this.addPoint; - this.size = info.size; - this.spacing = info.spacing; - this.padding = info.padding || 2; + this.size = info['point-size']; + this.spacing = info['point-spacing']; + this.padding = info['point-padding'] || 2; } else if (info.line) { this.addFeature = this.addLine; @@ -27,17 +27,17 @@ function Bucket(info, geometry, placement, indices) { this.addFeature = this.addFill; } else { - console.warn('unrecognized type'); + console.warn('No type specified'); } - var compare = info.compare || '=='; - if (compare in comparators) { - var code = comparators[compare](info); - if (code) { - /* jshint evil: true */ - this.compare = new Function('feature', code); - } - } + // var compare = info.compare || '=='; + // if (compare in comparators) { + // var code = comparators[compare](info); + // if (code) { + // /* jshint evil: true */ + // this.compare = new Function('feature', code); + // } + // } } @@ -87,7 +87,8 @@ Bucket.prototype.toJSON = function() { Bucket.prototype.addLine = function(lines) { var info = this.info; for (var i = 0; i < lines.length; i++) { - this.geometry.addLine(lines[i], info.join, info.cap, info.miterLimit, info.roundLimit); + this.geometry.addLine(lines[i], info['line-join'], info['line-cap'], + info['line-miter-limit'], info['line-round-limit']); } }; @@ -136,12 +137,12 @@ Bucket.prototype.addText = function(lines, faces, shaping) { }; // Builds a function body from the JSON specification. Allows specifying other compare operations. -var comparators = { - '==': function(bucket) { - if (!('field' in bucket)) return; - var value = bucket.value, field = bucket.field; - return 'return ' + (Array.isArray(value) ? value : [value]).map(function(value) { - return 'feature[' + JSON.stringify(field) + '] == ' + JSON.stringify(value); - }).join(' || ') + ';'; - } -}; +// var comparators = { +// '==': function(bucket) { +// if (!('field' in bucket)) return; +// var value = bucket.value, field = bucket.field; +// return 'return ' + (Array.isArray(value) ? value : [value]).map(function(value) { +// return 'feature[' + JSON.stringify(field) + '] == ' + JSON.stringify(value); +// }).join(' || ') + ';'; +// } +// }; From ae37bacae64cb40d248eec80677170895bbd0cd8 Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Mon, 14 Apr 2014 21:48:33 +0300 Subject: [PATCH 10/19] more new style-related fixes --- js/geometry/bucket.js | 4 ++-- js/render/drawtext.js | 24 ++++++++++++------------ js/style/styledeclaration.js | 3 +++ js/text/placement.js | 12 ++++++------ js/ui/map.js | 2 +- js/worker/workertile.js | 2 +- 6 files changed, 25 insertions(+), 22 deletions(-) diff --git a/js/geometry/bucket.js b/js/geometry/bucket.js index 6792d91c22f..9006ef6c67f 100644 --- a/js/geometry/bucket.js +++ b/js/geometry/bucket.js @@ -106,8 +106,8 @@ Bucket.prototype.addPoint = function(lines) { if (this.size) { var ratio = 8, // todo uhardcode tileExtent/tileSize - x = this.size.x / 2 * ratio, - y = this.size.y / 2 * ratio; + x = this.size[0] / 2 * ratio, + y = this.size[1] / 2 * ratio; for (var k = 0; k < points.length; k++) { var point = points[k]; diff --git a/js/render/drawtext.js b/js/render/drawtext.js index efb3d284174..ee7b1e647bc 100644 --- a/js/render/drawtext.js +++ b/js/render/drawtext.js @@ -7,17 +7,17 @@ module.exports = drawText; function drawText(gl, painter, bucket, layerStyle, params) { var exMatrix = mat4.clone(painter.projectionMatrix); - if (bucket.info.path == 'curve') { + if (bucket.info['text-path'] == 'curve') { mat4.rotateZ(exMatrix, exMatrix, painter.transform.angle); } - var rotate = layerStyle.rotate || 0; + var rotate = layerStyle['text-rotate'] || 0; if (rotate) { mat4.rotateZ(exMatrix, exMatrix, rotate); } - // If layerStyle.size > bucket.info.fontSize then labels may collide - var fontSize = layerStyle.size || bucket.info.fontSize; + // If layerStyle.size > bucket.info['text-max-size'] then labels may collide + var fontSize = layerStyle['text-size'] || bucket.info['text-max-size']; mat4.scale(exMatrix, exMatrix, [ fontSize / 24, fontSize / 24, 1 ]); var shader = painter.sdfShader; @@ -42,16 +42,16 @@ function drawText(gl, painter, bucket, layerStyle, params) { gl.vertexAttribPointer(shader.a_rangeend, 1, ubyte, false, 16, 14); gl.vertexAttribPointer(shader.a_rangestart, 1, ubyte, false, 16, 15); - gl.uniform1f(shader.u_gamma, params.antialiasing ? 2.5 / bucket.info.fontSize / window.devicePixelRatio : 0); + gl.uniform1f(shader.u_gamma, params.antialiasing ? 2.5 / bucket.info['text-max-size'] / window.devicePixelRatio : 0); // Convert the -pi..pi to an int8 range. var angle = Math.round((painter.transform.angle + rotate) / Math.PI * 128); // adjust min/max zooms for variable font sies - var zoomAdjust = Math.log(fontSize / bucket.info.fontSize) / Math.LN2; + var zoomAdjust = Math.log(fontSize / bucket.info['text-max-size']) / Math.LN2; gl.uniform1f(shader.u_angle, (angle + 256) % 256); - gl.uniform1f(shader.u_flip, bucket.info.path === 'curve' ? 1 : 0); + gl.uniform1f(shader.u_flip, bucket.info['text-path'] === 'curve' ? 1 : 0); gl.uniform1f(shader.u_zoom, (painter.transform.zoom - zoomAdjust) * 10); // current zoom level // Label fading @@ -96,7 +96,7 @@ function drawText(gl, painter, bucket, layerStyle, params) { gl.uniform1f(shader.u_fadezoom, (painter.transform.zoom + bump) * 10); // Draw text first. - gl.uniform4fv(shader.u_color, layerStyle.color); + gl.uniform4fv(shader.u_color, layerStyle['text-color']); gl.uniform1f(shader.u_buffer, (256 - 64) / 256); var begin = bucket.indices.glyphVertexIndex, @@ -104,11 +104,11 @@ function drawText(gl, painter, bucket, layerStyle, params) { gl.drawArrays(gl.TRIANGLES, begin, len); - if (layerStyle.stroke) { + if (layerStyle['text-halo-color']) { // Draw halo underneath the text. - gl.uniform4fv(shader.u_color, layerStyle.stroke); - gl.uniform1f(shader.u_buffer, layerStyle.strokeWidth === undefined ? - 64 / 256 : layerStyle.strokeWidth); + gl.uniform4fv(shader.u_color, layerStyle['text-halo-color']); + gl.uniform1f(shader.u_buffer, layerStyle['text-halo-width'] === undefined ? + 64 / 256 : layerStyle['text-halo-width']); gl.drawArrays(gl.TRIANGLES, begin, len); } diff --git a/js/style/styledeclaration.js b/js/style/styledeclaration.js index ee9d52a41d0..7272ab797d8 100644 --- a/js/style/styledeclaration.js +++ b/js/style/styledeclaration.js @@ -40,6 +40,9 @@ StyleDeclaration.prototype.parsers = { 'line-color': parseColor, 'fill-color': parseColor, 'stroke-color': parseColor, + 'point-color': parseColor, + 'text-color': parseColor, + 'text-halo-color': parseColor, 'line-width': parseWidth, 'line-offset': parseWidth, diff --git a/js/text/placement.js b/js/text/placement.js index a10cfe95b22..fc429d939d4 100644 --- a/js/text/placement.js +++ b/js/text/placement.js @@ -36,12 +36,12 @@ function byScale(a, b) { Placement.prototype.addFeature = function(line, info, faces, shaping) { - var horizontal = info.path === 'horizontal', - padding = info.padding || 2, - maxAngleDelta = info.maxAngleDelta || Math.PI, - textMinDistance = info.textMinDistance || 250, - rotate = info.rotate || 0, - fontScale = (this.tileExtent / this.tileSize) / (this.glyphSize / info.fontSize), + var horizontal = info['text-path'] === 'horizontal', + padding = info['text-padding'] || 2, + maxAngleDelta = info['text-max-angle'] || Math.PI, + textMinDistance = info['text-min-distance'] || 250, + rotate = info['text-rotate'] || 0, + fontScale = (this.tileExtent / this.tileSize) / (this.glyphSize / info['text-max-size']), advance = this.measureText(faces, shaping), anchors; diff --git a/js/ui/map.js b/js/ui/map.js index 03980d559eb..d07c4989db6 100644 --- a/js/ui/map.js +++ b/js/ui/map.js @@ -327,7 +327,7 @@ util.extend(Map.prototype, { this._renderGroups(this.style.layerGroups); - var bgColor = this.style.computed.background && this.style.computed.background.color; + var bgColor = this.style.computed.background && this.style.computed.background['fill-color']; if (bgColor) { this.painter.drawBackground(bgColor); } diff --git a/js/worker/workertile.js b/js/worker/workertile.js index 7b852e4c5cb..f982171a7ee 100644 --- a/js/worker/workertile.js +++ b/js/worker/workertile.js @@ -111,7 +111,7 @@ WorkerTile.prototype.parseBucket = function(bucket_name, features, info, faces, bucket.start(); - if (info.type === 'text') { + if (info.text) { this.parseTextBucket(features, bucket, info, faces, layer); } else { From 5253a5bc4fe8780e3a1e3489b37f52f16c2fae80 Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Mon, 14 Apr 2014 22:51:48 +0300 Subject: [PATCH 11/19] more new style fixes --- js/render/drawline.js | 2 +- js/text/placement.js | 2 +- js/worker/worker.js | 2 +- js/worker/workertile.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/js/render/drawline.js b/js/render/drawline.js index 2e1220a4863..088155a9948 100644 --- a/js/render/drawline.js +++ b/js/render/drawline.js @@ -28,7 +28,7 @@ module.exports = function drawLine(gl, painter, bucket, layerStyle, params, imag } else { gl.switchShader(painter.lineShader, painter.tile.posMatrix, painter.tile.exMatrix); - gl.uniform2fv(painter.lineShader.u_dasharray, layerStyle.dasharray || [1, -1]); + gl.uniform2fv(painter.lineShader.u_dasharray, layerStyle['line-dasharray'] || [1, -1]); shader = painter.lineShader; } diff --git a/js/text/placement.js b/js/text/placement.js index fc429d939d4..5e7ef729db6 100644 --- a/js/text/placement.js +++ b/js/text/placement.js @@ -63,7 +63,7 @@ Placement.prototype.addFeature = function(line, info, faces, shaping) { var anchor = anchors[j]; var glyphs = getGlyphs(anchor, advance, shaping, faces, fontScale, horizontal, line, maxAngleDelta, rotate); var place = this.collision.place( - glyphs, anchor, anchor.scale, this.maxPlacementScale, padding, horizontal, info.alwaysVisible); + glyphs, anchor, anchor.scale, this.maxPlacementScale, padding, horizontal, info['text-always-visible']); if (place) { this.geometry.addGlyphs(glyphs, place.zoom, place.rotationRange, this.zoom - this.zOffset); diff --git a/js/worker/worker.js b/js/worker/worker.js index 312fc92b2a3..5ec072a44f3 100644 --- a/js/worker/worker.js +++ b/js/worker/worker.js @@ -18,7 +18,7 @@ function matchFn(bucket) { var filters = []; for (var key in bucket.filter) { - if (key === 'source' || key === 'layer') continue; + if (key === 'source' || key === 'layer' || key === 'feature_type') continue; var value = bucket.filter[key]; if (Array.isArray(value)) { filters.push.apply(filters, value.map(function (v) { diff --git a/js/worker/workertile.js b/js/worker/workertile.js index f982171a7ee..94bbdd54834 100644 --- a/js/worker/workertile.js +++ b/js/worker/workertile.js @@ -140,7 +140,7 @@ WorkerTile.prototype.parseTextBucket = function(features, bucket, info, faces, l for (var i = 0; i < features.length; i++) { var feature = features[i]; - var text = feature[info.text_field]; + var text = feature[info['text-field']]; if (!text) continue; var shaping = shapingDB[text]; From 895e1b6b879016b3dfc669dfb9965a0fd4a8ff65 Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Mon, 14 Apr 2014 23:39:39 +0300 Subject: [PATCH 12/19] fix image poi rendering --- js/render/drawpoint.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/render/drawpoint.js b/js/render/drawpoint.js index 94f064915bf..31d1acc86f6 100644 --- a/js/render/drawpoint.js +++ b/js/render/drawpoint.js @@ -4,7 +4,7 @@ var mat2 = require('../lib/glmatrix.js').mat2; module.exports = function drawPoint(gl, painter, bucket, layerStyle, params, imageSprite) { - var imagePos = imageSprite && imageSprite.getPosition(layerStyle.image), + var imagePos = imageSprite && imageSprite.getPosition(layerStyle['point-image']), begin = bucket.indices.pointVertexIndex, count = bucket.indices.pointVertexIndexEnd - begin, shader = imagePos ? painter.pointShader : painter.dotShader; From 999178481fe0269fb0ef29a96c923fade33206f5 Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Mon, 14 Apr 2014 23:43:24 +0300 Subject: [PATCH 13/19] fix build --- test/styledeclaration.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/styledeclaration.test.js b/test/styledeclaration.test.js index 1f6312e9b8a..3f3c9473131 100644 --- a/test/styledeclaration.test.js +++ b/test/styledeclaration.test.js @@ -12,12 +12,12 @@ test('styledeclaration', function(t) { t.deepEqual(color.calculate(10), [1, 0, 0, 1]); */ - var width = new StyleDeclaration('width', 'widthvar', { + var width = new StyleDeclaration('line-width', 'widthvar', { widthvar: 10 }); t.equal(width.calculate(10), 10); - var widthfn = new StyleDeclaration('width', function(z) { + var widthfn = new StyleDeclaration('line-width', function(z) { return Math.pow(z, 2); }); t.equal(widthfn.calculate(10), 100); From 930e89cd62d924d4d859fdb77c4f63cf18f023ce Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Tue, 15 Apr 2014 00:18:45 +0300 Subject: [PATCH 14/19] fix casings and line-image --- js/render/drawline.js | 16 ++++++++-------- js/style/style.js | 5 ++--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/js/render/drawline.js b/js/render/drawline.js index 088155a9948..881b7b99f7d 100644 --- a/js/render/drawline.js +++ b/js/render/drawline.js @@ -10,7 +10,7 @@ module.exports = function drawLine(gl, painter, bucket, layerStyle, params, imag var inset = Math.max(-1, offset - width / 2 - 0.5) + 1; var outset = offset + width / 2 + 0.5; - var imagePos = layerStyle.image && imageSprite.getPosition(layerStyle.image); + var imagePos = layerStyle['line-image'] && imageSprite.getPosition(layerStyle['line-image']); var shader; if (imagePos) { @@ -19,17 +19,17 @@ module.exports = function drawLine(gl, painter, bucket, layerStyle, params, imag imageSprite.bind(gl, true); //factor = Math.pow(2, 4 - painter.transform.tileZoom + params.z); - gl.switchShader(painter.linepatternShader, painter.translatedMatrix || painter.tile.posMatrix, painter.tile.exMatrix); shader = painter.linepatternShader; - gl.uniform2fv(painter.linepatternShader.u_pattern_size, [imagePos.size[0] * factor, imagePos.size[1] ]); - gl.uniform2fv(painter.linepatternShader.u_pattern_tl, imagePos.tl); - gl.uniform2fv(painter.linepatternShader.u_pattern_br, imagePos.br); - gl.uniform1f(painter.linepatternShader.u_fade, painter.transform.zoomFraction); + gl.switchShader(shader, painter.translatedMatrix || painter.tile.posMatrix, painter.tile.exMatrix); + gl.uniform2fv(shader.u_pattern_size, [imagePos.size[0] * factor, imagePos.size[1] ]); + gl.uniform2fv(shader.u_pattern_tl, imagePos.tl); + gl.uniform2fv(shader.u_pattern_br, imagePos.br); + gl.uniform1f(shader.u_fade, painter.transform.zoomFraction); } else { - gl.switchShader(painter.lineShader, painter.tile.posMatrix, painter.tile.exMatrix); - gl.uniform2fv(painter.lineShader.u_dasharray, layerStyle['line-dasharray'] || [1, -1]); shader = painter.lineShader; + gl.switchShader(shader, painter.tile.posMatrix, painter.tile.exMatrix); + gl.uniform2fv(shader.u_dasharray, layerStyle['line-dasharray'] || [1, -1]); } var tilePixelRatio = painter.transform.scale / (1 << params.z) / 8; diff --git a/js/style/style.js b/js/style/style.js index 3de382b3d95..e0a2ded043a 100644 --- a/js/style/style.js +++ b/js/style/style.js @@ -84,7 +84,6 @@ Style.prototype.recalculate = function(z) { this.layerGroups = groupLayers(this.stylesheet.layers); - // Split the layers into groups of consecutive layers with the same datasource // For each group calculate its dependencies. Its dependencies are composited // layers that need to be rendered into textures before @@ -97,7 +96,7 @@ Style.prototype.recalculate = function(z) { while (i >= 0) { var layer = layers[i]; - var bucket = buckets[layer.id]; + var bucket = buckets[layer.bucket]; var source = bucket && bucket.filter.source; var group = []; @@ -108,7 +107,7 @@ Style.prototype.recalculate = function(z) { // low over layers top down until you reach one from a different datasource while (i >= 0) { layer = layers[i]; - bucket = buckets[layer.id]; + bucket = buckets[layer.bucket]; source = bucket && bucket.filter.source; var style = layerValues[layer.id]; From 6b641b56c8c60c5bfb2171158cef61b800250e8b Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Tue, 15 Apr 2014 13:46:36 +0300 Subject: [PATCH 15/19] fix casings again --- js/render/painter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/render/painter.js b/js/render/painter.js index dddd2428ac8..011520477c0 100644 --- a/js/render/painter.js +++ b/js/render/painter.js @@ -300,7 +300,7 @@ GLPainter.prototype.applyStyle = function(layer, style, buckets, params) { drawFill(gl, this, undefined, layerStyle, params, style.sprite, true); } else { - var bucket = buckets[layer.id]; + var bucket = buckets[layer.bucket]; // There are no vertices yet for this layer. if (!bucket || !bucket.indices) return; From d547e8370cea637066534022758711d21396cad4 Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Wed, 16 Apr 2014 15:24:22 +0300 Subject: [PATCH 16/19] fix opacity rendering --- js/style/style.js | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/js/style/style.js b/js/style/style.js index e0a2ded043a..7f394104d6c 100644 --- a/js/style/style.js +++ b/js/style/style.js @@ -55,25 +55,36 @@ Style.prototype.recalculate = function(z) { } // Some properties influence others - // if (appliedLayer.opacity && appliedLayer.color) { - // appliedLayer.color = appliedLayer.color.slice(); - // appliedLayer.color[3] = appliedLayer.opacity; - // util.premultiply(appliedLayer.color); - // } - - // if (appliedLayer.opacity && appliedLayer.stroke) { - // appliedLayer.stroke = appliedLayer.stroke.slice(); - // appliedLayer.stroke[3] = appliedLayer.opacity; - // util.premultiply(appliedLayer.stroke); - // } + + var lineColor = appliedLayer['line-color'], + fillColor = appliedLayer['fill-color'], + strokeColor = appliedLayer['stroke-color'], + + lineOpacity = appliedLayer['line-opacity'], + fillOpacity = appliedLayer['fill-opacity'], + strokeOpacity = appliedLayer['stroke-opacity']; + + if (appliedLayer.antialias === undefined) { + appliedLayer.antialias = true; + } // todo add more checks for width and color - if (appliedLayer.opacity === 0) { + if ((fillColor || lineColor) && (!lineColor || lineOpacity === 0) && (!fillColor || fillOpacity === 0)) { appliedLayer.hidden = true; + continue; } - if (appliedLayer.antialias === undefined) { - appliedLayer.antialias = true; + if (lineColor && lineOpacity) { + appliedLayer['line-color'] = util.premultiply( + [lineColor[0], lineColor[1], lineColor[2], lineOpacity]); + } + if (fillColor && fillOpacity) { + appliedLayer['fill-color'] = util.premultiply( + [fillColor[0], fillColor[1], fillColor[2], fillOpacity]); + } + if (strokeColor && strokeOpacity) { + appliedLayer['stroke-color'] = util.premultiply( + [strokeColor[0], strokeColor[1], strokeColor[2], strokeOpacity]); } } From b9b59d0eb803e5b9b616e9a1c03aa71bc11b94d3 Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Wed, 16 Apr 2014 15:24:35 +0300 Subject: [PATCH 17/19] fix jshint complaining --- js/worker/worker.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/js/worker/worker.js b/js/worker/worker.js index 5ec072a44f3..34eef764d47 100644 --- a/js/worker/worker.js +++ b/js/worker/worker.js @@ -13,17 +13,22 @@ if (typeof self.alert === 'undefined') { } function matchFn(bucket) { - // jshint evil: true if (!('filter' in bucket)) return; + // a JSHint bug + // jshint -W088 + var key; + + function keyValue(v) { + return {key: key, value: v}; + } + var filters = []; - for (var key in bucket.filter) { + for (key in bucket.filter) { if (key === 'source' || key === 'layer' || key === 'feature_type') continue; var value = bucket.filter[key]; if (Array.isArray(value)) { - filters.push.apply(filters, value.map(function (v) { - return {key: key, value: v}; - })); + filters.push.apply(filters, value.map(keyValue)); } else { filters.push({key: key, value: value}); } @@ -35,6 +40,7 @@ function matchFn(bucket) { return 'f[' + JSON.stringify(f.key) + '] == ' + JSON.stringify(f.value); }).join(' || ') + ';'; + // jshint evil: true return new Function('f', fnCode); } From e186cee1473005b501a16a8ccc744f74003ee310 Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Wed, 16 Apr 2014 16:50:46 +0300 Subject: [PATCH 18/19] separate out bucket filtering logic, make GeoJSON work --- js/geometry/bucket.js | 24 +++--------------------- js/style/bucket-filter.js | 34 ++++++++++++++++++++++++++++++++++ js/ui/geojsontile.js | 5 ++--- js/worker/worker.js | 38 ++++---------------------------------- 4 files changed, 43 insertions(+), 58 deletions(-) create mode 100644 js/style/bucket-filter.js diff --git a/js/geometry/bucket.js b/js/geometry/bucket.js index 9006ef6c67f..f83e1a57289 100644 --- a/js/geometry/bucket.js +++ b/js/geometry/bucket.js @@ -2,7 +2,8 @@ module.exports = Bucket; -var interpolate = require('./interpolate.js'); +var interpolate = require('./interpolate.js'), + bucketFilter = require('../style/bucket-filter.js'); function Bucket(info, geometry, placement, indices) { @@ -30,15 +31,7 @@ function Bucket(info, geometry, placement, indices) { console.warn('No type specified'); } - // var compare = info.compare || '=='; - // if (compare in comparators) { - // var code = comparators[compare](info); - // if (code) { - // /* jshint evil: true */ - // this.compare = new Function('feature', code); - // } - // } - + this.compare = bucketFilter(this, ['source', 'feature_type']); } Bucket.prototype.start = function() { @@ -135,14 +128,3 @@ Bucket.prototype.addText = function(lines, faces, shaping) { this.placement.addFeature(lines[i], this.info, faces, shaping); } }; - -// Builds a function body from the JSON specification. Allows specifying other compare operations. -// var comparators = { -// '==': function(bucket) { -// if (!('field' in bucket)) return; -// var value = bucket.value, field = bucket.field; -// return 'return ' + (Array.isArray(value) ? value : [value]).map(function(value) { -// return 'feature[' + JSON.stringify(field) + '] == ' + JSON.stringify(value); -// }).join(' || ') + ';'; -// } -// }; diff --git a/js/style/bucket-filter.js b/js/style/bucket-filter.js new file mode 100644 index 00000000000..59d82080dd4 --- /dev/null +++ b/js/style/bucket-filter.js @@ -0,0 +1,34 @@ +'use strict'; + +module.exports = function (bucket, excludes) { + if (!('filter' in bucket)) return; + + // prevent a false warning (JSHint bug) + // jshint -W088 + + var key, value, + filters = []; + + function keyValue(v) { + return {key: key, value: v}; + } + + for (key in bucket.filter) { + if (excludes && excludes.indexOf(key) !== -1) continue; + + value = bucket.filter[key]; + + if (Array.isArray(value)) { + filters.push.apply(filters, value.map(keyValue)); + } else { + filters.push({key: key, value: value}); + } + } + + if (!filters.length) return; + + // jshint evil: true + return new Function('f', 'return ' + filters.map(function(f) { + return 'f[' + JSON.stringify(f.key) + '] == ' + JSON.stringify(f.value); + }).join(' || ') + ';'); +}; diff --git a/js/ui/geojsontile.js b/js/ui/geojsontile.js index 535dd53f963..38e639c079e 100644 --- a/js/ui/geojsontile.js +++ b/js/ui/geojsontile.js @@ -33,7 +33,7 @@ GeoJSONTile.prototype.sortFeaturesIntoBuckets = function() { var buckets = {}; for (var name in mapping) { - if (mapping[name].source === 'geojson') { + if (mapping[name].filter.source === 'geojson') { buckets[name] = new Bucket(mapping[name], this.geometry, this.placement); buckets[name].features = []; } @@ -45,8 +45,7 @@ GeoJSONTile.prototype.sortFeaturesIntoBuckets = function() { if (!buckets[key].compare || buckets[key].compare(feature.properties)) { - var type = mapping[key].feature_type || mapping[key].type; - if (type === feature.type) { + if (feature.type === mapping[key].filter.feature_type || mapping[key][feature.type]) { buckets[key].features.push(feature); } } diff --git a/js/worker/worker.js b/js/worker/worker.js index 34eef764d47..f70580866d4 100644 --- a/js/worker/worker.js +++ b/js/worker/worker.js @@ -1,6 +1,8 @@ 'use strict'; -var Actor = require('../util/actor.js'); +var Actor = require('../util/actor.js'), + bucketFilter = require('../style/bucket-filter.js'); + module.exports = new Actor(self, self); @@ -12,44 +14,12 @@ if (typeof self.alert === 'undefined') { }; } -function matchFn(bucket) { - if (!('filter' in bucket)) return; - - // a JSHint bug - // jshint -W088 - var key; - - function keyValue(v) { - return {key: key, value: v}; - } - - var filters = []; - for (key in bucket.filter) { - if (key === 'source' || key === 'layer' || key === 'feature_type') continue; - var value = bucket.filter[key]; - if (Array.isArray(value)) { - filters.push.apply(filters, value.map(keyValue)); - } else { - filters.push({key: key, value: value}); - } - } - - if (!filters.length) return; - - var fnCode = 'return ' + filters.map(function(f) { - return 'f[' + JSON.stringify(f.key) + '] == ' + JSON.stringify(f.value); - }).join(' || ') + ';'; - - // jshint evil: true - return new Function('f', fnCode); -} - // Updates the style to use for this map. self['set buckets'] = function(data) { var buckets = WorkerTile.buckets = data; for (var id in buckets) { - buckets[id].fn = matchFn(buckets[id]); + buckets[id].fn = bucketFilter(buckets[id], ['source', 'layer', 'feature_type']); } }; From 04fe4822506692547d23eb21797a942d9c2432a4 Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Wed, 16 Apr 2014 17:02:22 +0300 Subject: [PATCH 19/19] remove old style --- debug/site.js | 2 +- debug/style-new.js | 607 ------------------------- debug/style.js | 1076 ++++++++++++++++++++++++-------------------- 3 files changed, 584 insertions(+), 1101 deletions(-) delete mode 100644 debug/style-new.js diff --git a/debug/site.js b/debug/site.js index 74c6c97ac05..121ca5ad740 100644 --- a/debug/site.js +++ b/debug/site.js @@ -2,7 +2,7 @@ var llmr = require('../'), route = require('./route'), - style_json = require('./style-new'); + style_json = require('./style'); if (typeof document !== 'undefined') { var map = new llmr.Map({ diff --git a/debug/style-new.js b/debug/style-new.js deleted file mode 100644 index 49bfb33dc27..00000000000 --- a/debug/style-new.js +++ /dev/null @@ -1,607 +0,0 @@ -module.exports = { - "version": "1", - "buckets": { - "satellite": { - "filter": {"source": "satellite"} - }, - "park": { - "filter": {"source": "mapbox streets", "layer": "landuse", "class": "park"}, - "fill": true - }, - "wood": { - "filter": {"source": "mapbox streets", "layer": "landuse", "class": "wood"}, - "fill": true - }, - "water": { - "filter": {"source": "mapbox streets", "layer": "water"}, - "fill": true - }, - "waterway": { - "filter": {"source": "mapbox streets", "layer": "waterway"}, - "line": true - }, - "tunnel_large": { - "filter": {"source": "mapbox streets", "layer": "tunnel", "class": ["motorway", "main"]}, - "line": true, - "min-zoom": 14 - }, - "tunnel_regular": { - "filter": {"source": "mapbox streets", "layer": "tunnel", "class": ["street", "street_limited"]}, - "line": true, - "min-zoom": 15.5 - }, - "road_large": { - "filter": {"source": "mapbox streets", "layer": "road", "class": ["motorway", "main"]}, - "line": true, - "min-zoom": 13, - "line-cap": "round", - "line-join": "bevel" - }, - "road_regular": { - "filter": {"source": "mapbox streets", "layer": "road", "class": "street"}, - "line": true, - "min-zoom": 15.5, - "line-cap": "round", - "line-join": "bevel" - }, - "road_limited": { - "filter": {"source": "mapbox streets", "layer": "road", "class": "street_limited"}, - "line": true, - "line-cap": "round", - "line-join": "butt", - "line-round-limit": 0.7 - }, - "path": { - "filter": {"source": "mapbox streets", "layer": "road", "class": "path"}, - "line": true, - "line-cap": "round", - "line-join": "bevel" - }, - "rail": { - "filter": {"source": "mapbox streets", "layer": "road", "class": "major_rail"}, - "line": true, - "line-cap": "round", - "line-join": "bevel" - }, - "tunnel_rail": { - "filter": {"source": "mapbox streets", "layer": "tunnel", "class": ["minor_rail", "major_rail"]}, - "line": true - }, - "route": { - "filter": {"source": "geojson"}, - "line": true - }, - "road_markers": { - "filter": {"source": "mapbox streets", "layer": "road", "oneway": 1, "feature_type": "line"}, - "min-zoom": 15.5, - "point": true, - "point-spacing": 200 - }, - "building": { - "filter": {"source": "mapbox streets", "layer": "building"}, - "fill": true - }, - "borders": { - "filter": {"source": "mapbox streets", "layer": "admin"}, - "line": true - }, - "bridge_large": { - "filter": {"source": "mapbox streets", "layer": "bridge", "class": ["motorway", "main"]}, - "line": true, - "min-zoom": 14 - }, - "park_poi": { - "filter": {"source": "mapbox streets", "layer": "poi_label", "maki": "park"}, - "point": true - }, - "restaurant_poi": { - "filter": {"source": "mapbox streets", "layer": "poi_label", "maki": "restaurant"}, - "point": true, - "point-size": [12, 12] - }, - "country_label": { - "filter": {"source": "mapbox streets", "layer": "country_label", "feature_type": "point"}, - "text": true, - "text-field": "name", - "text-font": "Open Sans, Jomolhari, Siyam Rupali, Alef, Arial Unicode MS", - "text-max-size": 16, - "text-path": "horizontal", - "text-padding": 10 - }, - "place_label": { - "filter": {"source": "mapbox streets", "layer": "place_label", "feature_type": "point"}, - "text": true, - "text-field": "name", - "text-font": "Open Sans, Jomolhari, Siyam Rupali, Alef, Arial Unicode MS", - "text-max-size": 18, - "text-path": "horizontal", - "text-always-visible": true - }, - "road_label": { - "filter": {"source": "mapbox streets", "layer": "road_label", "feature_type": "line"}, - "text": true, - "text-field": "name", - "text-font": "Open Sans, Jomolhari, Siyam Rupali, Alef, Arial Unicode MS", - "text-max-size": 12, - "text-path": "curve", - "text-min-dist": 250, - "text-max-angle": 1.04 - } - }, - "layers": [{ - "id": "background" - }, { - "id": "satellite", - "bucket": "satellite" - }, { - "id": "park", - "bucket": "park" - }, { - "id": "wood", - "bucket": "wood" - }, { - "id": "water", - "bucket": "water" - }, { - "id": "waterway", - "bucket": "waterway" - }, { - "id": "roads", - "layers": [{ - "id": "tunnel_large_casing", - "bucket": "tunnel_large" - }, { - "id": "tunnel_regular_casing", - "bucket": "tunnel_regular" - }, { - "id": "tunnel_large", - "bucket": "tunnel_large" - }, { - "id": "tunnel_regular", - "bucket": "tunnel_regular" - }, { - "id": "road_large_casing", - "bucket": "road_large" - }, { - "id": "road_regular_casing", - "bucket": "road_regular" - }, { - "id": "road_limited", - "bucket": "road_limited" - }, { - "id": "road_large", - "bucket": "road_large" - }, { - "id": "road_regular", - "bucket": "road_regular" - }, { - "id": "path", - "bucket": "path" - }, { - "id": "rail", - "bucket": "rail" - }, { - "id": "tunnel_rail", - "bucket": "tunnel_rail" - }] - }, { - "id": "route", - "bucket": "route" - }, { - "id": "road_markers", - "bucket": "road_markers" - }, { - "id": "building", - "bucket": "building" - }, { - "id": "borders", - "bucket": "borders" - }, { - "id": "bridge_large_casing", - "bucket": "bridge_large" - }, { - "id": "bridge_large", - "bucket": "bridge_large" - }, { - "id": "park_poi", - "bucket": "park_poi" - }, { - "id": "restaurant_poi", - "bucket": "restaurant_poi" - }, { - "id": "country_label", - "bucket": "country_label" - }, { - "id": "place_label", - "bucket": "place_label" - }, { - "id": "road_label", - "bucket": "road_label" - }], - "constants": { - "land": "#e8e0d8", - "water": "#73b6e6", - "park": "#c8df9f", - "road": "#fefefe", - "border": "#6d90ab", - "wood": "#33AA66", - "building": "#d9ccbe", - "building_outline": "#d2c6b9", - "text": "#000000", - "satellite_brightness_low": 0, - "satellite_brightness_high": 1, - "satellite_saturation": 0, - "satellite_spin": 0, - "satellite_contrast": 0, - "road_blur": 1, - "stroke_width": 0.25 - }, - "styles": { - "default": { - "route": { - "line-color": "#EC8D8D", - "line-width": { - "fn": "exponential", - "z": 9, - "val": 1, - "slope": 0.21, - "min": 4 - } - }, - "background": { - "fill-color": "land", - "transition-fill-color": { - "duration": 500, - "delay": 0 - } - }, - "park": { - "fill-color": "park" - }, - "wood": { - "fill-color": "wood", - "fill-opacity": 0.08 - }, - "water": { - "fill-color": "water" - }, - "waterway": { - "line-color": "water", - "line-width": { - "fn": "linear", - "z": 9, - "val": 1, - "slope": 0.5, - "min": 0.5 - } - }, - "tunnel_large_casing": { - "line-color": [0, 0, 0, 0.5], - "line-width": 1, - "line-offset": { - "fn": "exponential", - "z": 9, - "val": -1, - "slope": 0.2, - "min": 1 - } - }, - "tunnel_regular_casing": { - "line-color": [0, 0, 0, 0.5], - "line-width": 1, - "line-offset": { - "fn": "exponential", - "z": 11, - "val": 0.5, - "slope": 0.2, - "min": 1 - } - }, - "tunnel_large": { - "line-color": [1, 1, 1, 0.5], - "line-width": { - "fn": "exponential", - "z": 9, - "val": -1, - "slope": 0.2, - "min": 1 - } - }, - "tunnel_regular": { - "line-color": [1, 1, 1, 0.5], - "line-width": { - "fn": "exponential", - "z": 11, - "val": -1, - "slope": 0.2, - "min": 1 - } - }, - "roads": { - "opacity": 1, - "transition-opacity": { - "duration": 500, - "delay": 0 - } - }, - "road_large_casing": { - "line-color": [0.6, 0.6, 0.6, 1], - "line-width": { - "fn": "exponential", - "z": 9, - "val": 1, - "slope": 0.21, - "min": 4 - }, - "line-opacity": { - "fn": "linear", - "z": 14, - "val": 0, - "slope": 1, - "min": 0, - "max": 1 - }, - "transition-line-width": { - "duration": 500, - "delay": 0 - }, - "line-blur": "road_blur" - }, - "road_regular_casing": { - "line-color": [0.6, 0.6, 0.6, 1], - "line-width": { - "fn": "exponential", - "z": 10, - "val": 0.5, - "slope": 0.2, - "min": 1 - }, - "line-opacity": { - "fn": "linear", - "z": 15.5, - "val": 0, - "slope": 1, - "min": 0, - "max": 1 - }, - "line-blur": "road_blur" - }, - "road_limited": { - "line-dasharray": [10, 2], - "line-color": "road", - "line-blur": "road_blur", - "line-width": { - "fn": "exponential", - "z": 10, - "val": -1, - "slope": 0.2, - "min": 1 - } - }, - "road_large": { - "line-color": "road", - "line-blur": "road_blur", - "line-width": { - "fn": "exponential", - "z": 9, - "val": -1, - "slope": 0.2, - "min": 1 - } - }, - "road_regular": { - "line-color": "road", - "line-blur": "road_blur", - "line-width": { - "fn": "exponential", - "z": 10, - "val": -1, - "slope": 0.2, - "min": 1 - } - }, - "path": { - "line-color": [1, 1, 1, 1], - "line-dasharray": [2, 2], - "line-width": 2 - }, - "rail": { - "line-color": [0.3, 0.3, 0.3, 0.8], - "line-dasharray": [2, 1], - "line-width": 3 - }, - "tunnel_rail": { - "line-color": [0.3, 0.3, 0.3, 0.3], - "line-dasharray": [2, 1], - "line-width": 3 - }, - "road_markers": { - "point-alignment": "line", - "point-image": "bicycle-12" - }, - "building": { - "fill-color": "building", - "transition-fill-opacity": { - "duration": 500, - "delay": 500 - }, - "fill-opacity": { - "fn": "linear", - "z": 14, - "val": 0, - "slope": 1, - "min": 0, - "max": 1 - }, - "stroke-color": "building_outline" - }, - "borders": { - "line-color": [0, 0, 0, 0.3], - "line-width": 1 - }, - "bridge_large_casing": { - "line-color": [0, 0, 0, 0.4], - "line-width": { - "fn": "exponential", - "z": 9, - "val": 1.5, - "slope": 0.2, - "min": 1 - } - }, - "bridge_large": { - "line-color": "road", - "line-width": { - "fn": "exponential", - "z": 9, - "val": -1, - "slope": 0.2, - "min": 1 - } - }, - "park_poi": { - "point-color": "green" - }, - "restaurant_poi": { - "point-image": "restaurant-12" - }, - "country_label": { - "text-halo-color": [1, 1, 1, 0.7], - "text-halo-width": "stroke_width", - "text-color": "text" - }, - "place_label": { - "text-halo-color": [1, 1, 1, 0.7], - "text-halo-width": "stroke_width", - "text-color": "text" - }, - "road_label": { - "text-color": "text", - "text-halo-color": [1, 1, 1, 0.7], - "text-halo-width": "stroke_width", - "text-size": { - "fn": "exponential", - "z": 14, - "val": 8, - "slope": 1, - "min": 8, - "max": 12 - } - } - }, - "satellite": { - "background": { - "transition-fill-color": { - "duration": 500, - "delay": 500 - }, - "fill-opacity": 0, - "fill-color": [1, 0, 0, 0] - }, - "roads": { - "transition-opacity": { - "duration": 500, - "delay": 500 - }, - "opacity": 0.5 - }, - "building": { - "fill-opacity": 0, - "transition-fill-opacity": { - "duration": 500, - "delay": 0 - } - }, - "park": { - "transition-fill-color": { - "duration": 500, - "delay": 0 - }, - "fill-color": [0, 0, 0, 0] - }, - "water": { - "fill-opacity": 0 - }, - "road_large": { - "transition-line-width": { - "duration": 500, - "delay": 1000 - }, - "line-width": { - "fn": "exponential", - "z": 10, - "val": -1, - "slope": 0.2, - "min": 1 - } - }, - "road_large_casing": { - "line-width": { - "fn": "exponential", - "z": 10, - "val": 1, - "slope": 0.21, - "min": 4 - }, - "transition-line-width": { - "duration": 500, - "delay": 1000 - } - }, - "road_regular_casing": { - "transition-line-width": { - "duration": 500, - "delay": 1000 - }, - "line-width": { - "fn": "exponential", - "z": 11, - "val": 0.5, - "slope": 0.2, - "min": 1 - } - }, - "road_regular": { - "transition-line-width": { - "duration": 500, - "delay": 1000 - }, - "line-width": { - "fn": "exponential", - "z": 11, - "val": -1, - "slope": 0.2, - "min": 1 - } - }, - "satellite": { - "raster-brightness-low": "satellite_brightness_low", - "raster-brightness-high": "satellite_brightness_high", - "raster-saturation": "satellite_saturation", - "raster-spin": "satellite_spin", - "raster-contrast": "satellite_contrast" - } - }, - "test": { - "road_large_casing": { - "line-width": { - "fn": "exponential", - "z": 8, - "val": 1, - "slope": 0.21, - "min": 4 - }, - "line-color": [1, 0, 0, 1], - "transition-line-width": { - "duration": 500, - "delay": 0 - }, - "transition-line-color": { - "duration": 2000, - "delay": 500 - } - } - } - }, - "sprite": "img/sprite" -} diff --git a/debug/style.js b/debug/style.js index cf65f0e730a..49bfb33dc27 100644 --- a/debug/style.js +++ b/debug/style.js @@ -1,517 +1,607 @@ -//'use strict'; module.exports = { - "buckets": { - "route": { - "source": "geojson", - "type": "line" - }, - "satellite": { - "source": "satellite", - "type": "raster" - }, - "park": { - "source": "mapbox streets", - "layer": "landuse", "field": "class", "value": "park", - "type": "fill" - }, - "wood": { - "source": "mapbox streets", - "layer": "landuse", "field": "class", "value": "wood", - "type": "fill" - }, - "school": { - "source": "mapbox streets", - "layer": "landuse", "field": "class", "value": "school", - "type": "fill" - }, - "cemetery": { - "source": "mapbox streets", - "layer": "landuse", "field": "class", "value": "cemetery", - "type": "fill" - }, - "industrial": { - "source": "mapbox streets", - "layer": "landuse", "field": "class", "value": "industrial", - "type": "fill" - }, - "water": { - "source": "mapbox streets", - "layer": "water", - "type": "fill" - }, - "waterway": { - "source": "mapbox streets", - "layer": "waterway", - "type": "line" - }, - "tunnel_large": { - "source": "mapbox streets", - "layer": "tunnel", "field": "class", "value": ["motorway", "main"], - "type": "line" - }, - "tunnel_regular": { - "source": "mapbox streets", - "layer": "tunnel", "field": "class", "value": ["street", "street_limited"], - "type": "line" - }, - "tunnel_rail": { - "source": "mapbox streets", - "layer": "tunnel", "field": "class", "value": ["minor_rail", "major_rail"], - "type": "line" - }, - "bridge_large": { - "source": "mapbox streets", - "layer": "bridge", "field": "class", "value": ["motorway", "main"], - "type": "line" - }, - "bridge_regular": { - "source": "mapbox streets", - "layer": "bridge", "field": "class", "value": ["street", "street_limited"], - "type": "line" - }, - "borders": { - "source": "mapbox streets", - "layer": "admin", - "type": "line" - }, - "building": { - "source": "mapbox streets", - "layer": "building", - "type": "fill" - }, - "road_large": { - "source": "mapbox streets", - "layer": "road", "field": "class", "value": ["motorway", "main"], - "type": "line", "cap": "round", "join": "bevel" - }, - "road_regular": { - "source": "mapbox streets", - "layer": "road", "field": "class", "value": "street", - "type": "line", "cap": "round", "join": "bevel" - }, - "road_limited": { - "source": "mapbox streets", - "layer": "road", "field": "class", "value": "street_limited", - "type": "line", "cap": "round", "join": "butt", "roundLimit": 0.7 - }, - "rail": { - "source": "mapbox streets", - "layer": "road", "field": "class", "value": "major_rail", - "type": "line", "cap": "round", "join": "bevel" - }, - "path": { - "source": "mapbox streets", - "layer": "road", "field": "class", "value": "path", - "type": "line", "cap": "round", "join": "bevel" - }, - "country_label": { - "source": "mapbox streets", - "layer": "country_label", - "feature_type": "point", - "padding": 10, - "type": "text", - "text_field": "name", - "path": "horizontal", - "font": "Open Sans, Jomolhari, Siyam Rupali, Alef, Arial Unicode MS", - "fontSize": 16 - }, - "place_label": { - "source": "mapbox streets", - "layer": "place_label", - "feature_type": "point", - "type": "text", - "text_field": "name", - "path": "horizontal", - "font": "Open Sans, Jomolhari, Siyam Rupali, Alef, Arial Unicode MS", - "fontSize": 18, - "alwaysVisible": true - }, - "road_label": { - "source": "mapbox streets", - "layer": "road_label", - "feature_type": "line", - "type": "text", - "text_field": "name", - "path": "curve", - "font": "Open Sans, Jomolhari, Siyam Rupali, Alef, Arial Unicode MS", - "fontSize": 12, - "textMinDistance": 250, - "maxAngleDelta": 1.04, // radians - }, - "embassy_poi": { - "source": "mapbox streets", - "layer": "poi_label", "field": "maki", "value": "embassy", - "type": "point" - }, - "park_poi": { - "source": "mapbox streets", - "layer": "poi_label", "field": "maki", "value": "park", - "type": "point" - }, - "restaurant_poi": { - "source": "mapbox streets", - "layer": "poi_label", "field": "maki", "value": "restaurant", - "size": { "x": 12, "y": 12 }, - "type": "point" - }, - "road_markers": { - "source": "mapbox streets", - "layer": "road", "field": "oneway", "value": 1, - "feature_type": "line", - "type": "point", "spacing": 200 - }, + "version": "1", + "buckets": { + "satellite": { + "filter": {"source": "satellite"} }, - "sprite": "img/sprite", - "constants": { - "land": "#e8e0d8", - "water": "#73b6e6", - "park": "#c8df9f", - "road": "#fefefe", - "border": "#6d90ab", - "wood": "#33AA66", - "building": "#d9ccbe", - "building_outline": "#d2c6b9", - "text": "#000000", - "satellite_brightness_low": 0, - "satellite_brightness_high": 1, - "satellite_saturation": 0.0, - "satellite_spin": 0, - "satellite_contrast": 0, - "road_blur": 1, - "stroke_width": 0.25 + "park": { + "filter": {"source": "mapbox streets", "layer": "landuse", "class": "park"}, + "fill": true }, - "structure": [ - { - "name": "background", - "bucket": "background" + "wood": { + "filter": {"source": "mapbox streets", "layer": "landuse", "class": "wood"}, + "fill": true }, - { - "name": "satellite", - "bucket": "satellite" + "water": { + "filter": {"source": "mapbox streets", "layer": "water"}, + "fill": true }, - { - "name": "park", - "bucket": "park" + "waterway": { + "filter": {"source": "mapbox streets", "layer": "waterway"}, + "line": true }, - { - "name": "wood", - "bucket": "wood", + "tunnel_large": { + "filter": {"source": "mapbox streets", "layer": "tunnel", "class": ["motorway", "main"]}, + "line": true, + "min-zoom": 14 }, - { - "name": "water", - "bucket": "water", + "tunnel_regular": { + "filter": {"source": "mapbox streets", "layer": "tunnel", "class": ["street", "street_limited"]}, + "line": true, + "min-zoom": 15.5 }, - { - "name": "waterway", - "bucket": "waterway", + "road_large": { + "filter": {"source": "mapbox streets", "layer": "road", "class": ["motorway", "main"]}, + "line": true, + "min-zoom": 13, + "line-cap": "round", + "line-join": "bevel" }, - { - "name": "roads", - "layers": [ - { - "name": "tunnel_large_casing", - "bucket": "tunnel_large", - }, - { - "name": "tunnel_regular_casing", - "bucket": "tunnel_regular", - }, - { - "name": "tunnel_large", - "bucket": "tunnel_large", - }, - { - "name": "tunnel_regular", - "bucket": "tunnel_regular", - }, - { - "name": "road_large_casing", - "bucket": "road_large", - }, - { - "name": "road_regular_casing", - "bucket": "road_regular", - }, - { - "name": "road_limited", - "bucket": "road_limited", - }, - { - "name": "road_large", - "bucket": "road_large", - }, - { - "name": "road_regular", - "bucket": "road_regular", - }, - { - "name": "path", - "bucket": "path", - }, - { - "name": "rail", - "bucket": "rail", - }, - { - "name": "tunnel_rail", - "bucket": "tunnel_rail", - }] + "road_regular": { + "filter": {"source": "mapbox streets", "layer": "road", "class": "street"}, + "line": true, + "min-zoom": 15.5, + "line-cap": "round", + "line-join": "bevel" }, - { - "name": "route", - "bucket": "route" + "road_limited": { + "filter": {"source": "mapbox streets", "layer": "road", "class": "street_limited"}, + "line": true, + "line-cap": "round", + "line-join": "butt", + "line-round-limit": 0.7 }, - { - "name": "road_markers", - "bucket": "road_markers", + "path": { + "filter": {"source": "mapbox streets", "layer": "road", "class": "path"}, + "line": true, + "line-cap": "round", + "line-join": "bevel" }, - { - "name": "building", - "bucket": "building", - + "rail": { + "filter": {"source": "mapbox streets", "layer": "road", "class": "major_rail"}, + "line": true, + "line-cap": "round", + "line-join": "bevel" }, - { - "name": "borders", - "bucket": "borders", + "tunnel_rail": { + "filter": {"source": "mapbox streets", "layer": "tunnel", "class": ["minor_rail", "major_rail"]}, + "line": true }, - { - "name": "bridge_large_casing", - "bucket": "bridge_large", + "route": { + "filter": {"source": "geojson"}, + "line": true }, - { - "name": "bridge_large", - "bucket": "bridge_large", + "road_markers": { + "filter": {"source": "mapbox streets", "layer": "road", "oneway": 1, "feature_type": "line"}, + "min-zoom": 15.5, + "point": true, + "point-spacing": 200 }, - { - "name": "park_poi", - "bucket": "park_poi", + "building": { + "filter": {"source": "mapbox streets", "layer": "building"}, + "fill": true }, - { - "name": "restaurant_poi", - "bucket": "restaurant_poi", + "borders": { + "filter": {"source": "mapbox streets", "layer": "admin"}, + "line": true }, - { - "name": "country_label", - "bucket": "country_label", + "bridge_large": { + "filter": {"source": "mapbox streets", "layer": "bridge", "class": ["motorway", "main"]}, + "line": true, + "min-zoom": 14 }, - { - "name": "place_label", - "bucket": "place_label", + "park_poi": { + "filter": {"source": "mapbox streets", "layer": "poi_label", "maki": "park"}, + "point": true }, - { - "name": "road_label", - "bucket": "road_label", + "restaurant_poi": { + "filter": {"source": "mapbox streets", "layer": "poi_label", "maki": "restaurant"}, + "point": true, + "point-size": [12, 12] }, - ], - "classes": [ - { - "name": "default", - "layers": { - "route": { - "color": "#EC8D8D", - "width": ["exponential", 9, 1.0, 0.21, 4], - }, - "background": { - "color": "land", - "transition-color": { "duration": 500, "delay": 0 } - }, - "park": { - "color": "park", - }, - "wood": { - "color": "wood", - "opacity": 0.08, - }, - "water": { - "color": "water", - }, - "waterway": { - "color": "water", - "width": ["linear", 9, 1, 0.5, 0.5] - }, - "tunnel_large_casing": { - "color": [0, 0, 0, 0.5], - "width": 1, - "offset": ["exponential", 9, -1, 0.2, 1], - "enabled": ["min", 14] - }, - "tunnel_regular_casing": { - "color": [0, 0, 0, 0.5], - "width": 1, - "offset": ["exponential", 11, 0.5, 0.2, 1], - "enabled": ["min", 15.5 ] - }, - "tunnel_large": { - "color": [ 1, 1, 1, 0.5], - "width": ["exponential", 9, -1, 0.2, 1] - }, - "tunnel_regular": { - "color": [ 1, 1, 1, 0.5], - "width": ["exponential", 11, -1, 0.2, 1] - }, - "roads": { - "type": "composited", - "opacity": 1, - "transition-opacity": { "duration": 500, "delay": 0 }, - }, - "road_large_casing": { - "color": [0.6, 0.6, 0.6, 1], - "width": ["exponential", 9, 1.0, 0.21, 4], - "enabled": ["min", 13], - "opacity": ["linear", 14, 0, 1, 0, 1], - "transition-width": { "duration": 500, "delay": 0 }, - "blur": "road_blur" - //"transition-width": { "duration": 500, "delay": 2000 }, - //"transition-color": { "duration": 2000, "delay": 0 } - }, - "road_regular_casing": { - "color": [0.6, 0.6, 0.6, 1], - "width": ["exponential", 10, 0.5, 0.2, 1], - "enabled": ["min", 15.5 ], - "opacity": ["linear", 15.5, 0, 1, 0, 1], - "blur": "road_blur", - }, - "road_limited": { - "dasharray": [10, 2], - "color": "road", - "blur": "road_blur", - "width": ["exponential", 10, -1, 0.2, 1], - }, - "road_large": { - "color": "road", - "blur": "road_blur", - "width": ["exponential", 9, -1, 0.2, 1], - }, - "road_regular": { - "color": "road", - "blur": "road_blur", - "width": ["exponential", 10, -1, 0.2, 1], - }, - "path": { - "color": [1,1,1,1], - "dasharray": [2,2], - "width": 2 - }, - "rail": { - "color": [0.3,0.3,0.3,0.8], - "dasharray": [2, 1], - "width" : 3, - "linejoin": "round" - }, - "tunnel_rail": { - "color": [0.3,0.3,0.3,0.3], - "dasharray": [2, 1], - "width" : 3, - "linejoin": "round" - }, - "road_markers": { - "enabled": ["min", 15.5], - "alignment": "line", - "image": "bicycle-12", - }, - "building": { - "color": "building", - "stroke": "building_outline", - "transition-opacity": { "duration": 500, "delay": 500 }, - "opacity": ["linear", 14, 0, 1, 0, 1] - - }, - "borders": { - "color": [0,0,0,0.3], - "width": 1 - }, - "bridge_large_casing": { - "color": [0, 0, 0, 0.4], - "width": ["exponential", 9, 1.5, 0.2, 1], - "enabled": ["min", 14] - }, - "bridge_large": { - "color": "road", - "width": ["exponential", 9, -1, 0.2, 1] - }, - "park_poi": { - "color": "green" - }, - "restaurant_poi": { - "image": "restaurant-12", - "imageSize": 12 - }, - "country_label": { - "stroke": [1,1,1,0.7], - "strokeWidth": "stroke_width", - "color": "text" - }, - "place_label": { - "stroke": [1,1,1,0.7], - "strokeWidth": "stroke_width", - "color": "text" - }, - "road_label": { - "color": "text", - "stroke": [1,1,1,0.7], - "strokeWidth": "stroke_width", - "size": ["exponential", 14, 8, 1, 8, 12] - } - } + "country_label": { + "filter": {"source": "mapbox streets", "layer": "country_label", "feature_type": "point"}, + "text": true, + "text-field": "name", + "text-font": "Open Sans, Jomolhari, Siyam Rupali, Alef, Arial Unicode MS", + "text-max-size": 16, + "text-path": "horizontal", + "text-padding": 10 + }, + "place_label": { + "filter": {"source": "mapbox streets", "layer": "place_label", "feature_type": "point"}, + "text": true, + "text-field": "name", + "text-font": "Open Sans, Jomolhari, Siyam Rupali, Alef, Arial Unicode MS", + "text-max-size": 18, + "text-path": "horizontal", + "text-always-visible": true + }, + "road_label": { + "filter": {"source": "mapbox streets", "layer": "road_label", "feature_type": "line"}, + "text": true, + "text-field": "name", + "text-font": "Open Sans, Jomolhari, Siyam Rupali, Alef, Arial Unicode MS", + "text-max-size": 12, + "text-path": "curve", + "text-min-dist": 250, + "text-max-angle": 1.04 + } + }, + "layers": [{ + "id": "background" + }, { + "id": "satellite", + "bucket": "satellite" + }, { + "id": "park", + "bucket": "park" + }, { + "id": "wood", + "bucket": "wood" + }, { + "id": "water", + "bucket": "water" + }, { + "id": "waterway", + "bucket": "waterway" + }, { + "id": "roads", + "layers": [{ + "id": "tunnel_large_casing", + "bucket": "tunnel_large" }, { - "name": "satellite", - "layers": { - "background": { - "transition-color": { "duration": 500, "delay": 500 }, - "opacity": 0, - "color": [1,0,0,0] - }, - "roads": { - "transition-opacity": { "duration": 500, "delay": 500 }, - "opacity": 0.5 - }, - "building": { - "opacity": 0, - "transition-opacity": { "duration": 500, "delay": 0 }, - }, - "park": { - "transition-color": { "duration": 500, "delay": 0 }, - "color": [0,0,0,0], - }, - "water": { - "opacity": 0 - }, - "place_label": { - //"color": [1,1,1,1] - }, - "road_large": { - "transition-width": { "duration": 500, "delay": 1000 }, - "width": ["exponential", 10, -1, 0.2, 1], - }, - "road_large_casing": { - "width": ["exponential", 10, 1.0, 0.21, 4], - "transition-width": { "duration": 500, "delay": 1000 }, - }, - "road_regular_casing": { - "transition-width": { "duration": 500, "delay": 1000 }, - "width": ["exponential", 11, 0.5, 0.2, 1], - }, - "road_regular": { - "transition-width": { "duration": 500, "delay": 1000 }, - "width": ["exponential", 11, -1, 0.2, 1], - }, - "satellite": { - brightness_low: "satellite_brightness_low", - brightness_high: "satellite_brightness_high", - saturation: "satellite_saturation", - spin: "satellite_spin", - contrast: "satellite_contrast" - } - } + "id": "tunnel_regular_casing", + "bucket": "tunnel_regular" }, { - "name": "test", - "layers": { - "road_large_casing": { - "width": ["exponential", 8, 1.0, 0.21, 4], - "color": [1,0,0,1], - "transition-width": { "duration": 500, "delay": 0 }, - "transition-color": { "duration": 2000, "delay": 500 } - } - } + "id": "tunnel_large", + "bucket": "tunnel_large" + }, { + "id": "tunnel_regular", + "bucket": "tunnel_regular" + }, { + "id": "road_large_casing", + "bucket": "road_large" + }, { + "id": "road_regular_casing", + "bucket": "road_regular" + }, { + "id": "road_limited", + "bucket": "road_limited" + }, { + "id": "road_large", + "bucket": "road_large" + }, { + "id": "road_regular", + "bucket": "road_regular" + }, { + "id": "path", + "bucket": "path" + }, { + "id": "rail", + "bucket": "rail" + }, { + "id": "tunnel_rail", + "bucket": "tunnel_rail" }] -}; + }, { + "id": "route", + "bucket": "route" + }, { + "id": "road_markers", + "bucket": "road_markers" + }, { + "id": "building", + "bucket": "building" + }, { + "id": "borders", + "bucket": "borders" + }, { + "id": "bridge_large_casing", + "bucket": "bridge_large" + }, { + "id": "bridge_large", + "bucket": "bridge_large" + }, { + "id": "park_poi", + "bucket": "park_poi" + }, { + "id": "restaurant_poi", + "bucket": "restaurant_poi" + }, { + "id": "country_label", + "bucket": "country_label" + }, { + "id": "place_label", + "bucket": "place_label" + }, { + "id": "road_label", + "bucket": "road_label" + }], + "constants": { + "land": "#e8e0d8", + "water": "#73b6e6", + "park": "#c8df9f", + "road": "#fefefe", + "border": "#6d90ab", + "wood": "#33AA66", + "building": "#d9ccbe", + "building_outline": "#d2c6b9", + "text": "#000000", + "satellite_brightness_low": 0, + "satellite_brightness_high": 1, + "satellite_saturation": 0, + "satellite_spin": 0, + "satellite_contrast": 0, + "road_blur": 1, + "stroke_width": 0.25 + }, + "styles": { + "default": { + "route": { + "line-color": "#EC8D8D", + "line-width": { + "fn": "exponential", + "z": 9, + "val": 1, + "slope": 0.21, + "min": 4 + } + }, + "background": { + "fill-color": "land", + "transition-fill-color": { + "duration": 500, + "delay": 0 + } + }, + "park": { + "fill-color": "park" + }, + "wood": { + "fill-color": "wood", + "fill-opacity": 0.08 + }, + "water": { + "fill-color": "water" + }, + "waterway": { + "line-color": "water", + "line-width": { + "fn": "linear", + "z": 9, + "val": 1, + "slope": 0.5, + "min": 0.5 + } + }, + "tunnel_large_casing": { + "line-color": [0, 0, 0, 0.5], + "line-width": 1, + "line-offset": { + "fn": "exponential", + "z": 9, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "tunnel_regular_casing": { + "line-color": [0, 0, 0, 0.5], + "line-width": 1, + "line-offset": { + "fn": "exponential", + "z": 11, + "val": 0.5, + "slope": 0.2, + "min": 1 + } + }, + "tunnel_large": { + "line-color": [1, 1, 1, 0.5], + "line-width": { + "fn": "exponential", + "z": 9, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "tunnel_regular": { + "line-color": [1, 1, 1, 0.5], + "line-width": { + "fn": "exponential", + "z": 11, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "roads": { + "opacity": 1, + "transition-opacity": { + "duration": 500, + "delay": 0 + } + }, + "road_large_casing": { + "line-color": [0.6, 0.6, 0.6, 1], + "line-width": { + "fn": "exponential", + "z": 9, + "val": 1, + "slope": 0.21, + "min": 4 + }, + "line-opacity": { + "fn": "linear", + "z": 14, + "val": 0, + "slope": 1, + "min": 0, + "max": 1 + }, + "transition-line-width": { + "duration": 500, + "delay": 0 + }, + "line-blur": "road_blur" + }, + "road_regular_casing": { + "line-color": [0.6, 0.6, 0.6, 1], + "line-width": { + "fn": "exponential", + "z": 10, + "val": 0.5, + "slope": 0.2, + "min": 1 + }, + "line-opacity": { + "fn": "linear", + "z": 15.5, + "val": 0, + "slope": 1, + "min": 0, + "max": 1 + }, + "line-blur": "road_blur" + }, + "road_limited": { + "line-dasharray": [10, 2], + "line-color": "road", + "line-blur": "road_blur", + "line-width": { + "fn": "exponential", + "z": 10, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "road_large": { + "line-color": "road", + "line-blur": "road_blur", + "line-width": { + "fn": "exponential", + "z": 9, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "road_regular": { + "line-color": "road", + "line-blur": "road_blur", + "line-width": { + "fn": "exponential", + "z": 10, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "path": { + "line-color": [1, 1, 1, 1], + "line-dasharray": [2, 2], + "line-width": 2 + }, + "rail": { + "line-color": [0.3, 0.3, 0.3, 0.8], + "line-dasharray": [2, 1], + "line-width": 3 + }, + "tunnel_rail": { + "line-color": [0.3, 0.3, 0.3, 0.3], + "line-dasharray": [2, 1], + "line-width": 3 + }, + "road_markers": { + "point-alignment": "line", + "point-image": "bicycle-12" + }, + "building": { + "fill-color": "building", + "transition-fill-opacity": { + "duration": 500, + "delay": 500 + }, + "fill-opacity": { + "fn": "linear", + "z": 14, + "val": 0, + "slope": 1, + "min": 0, + "max": 1 + }, + "stroke-color": "building_outline" + }, + "borders": { + "line-color": [0, 0, 0, 0.3], + "line-width": 1 + }, + "bridge_large_casing": { + "line-color": [0, 0, 0, 0.4], + "line-width": { + "fn": "exponential", + "z": 9, + "val": 1.5, + "slope": 0.2, + "min": 1 + } + }, + "bridge_large": { + "line-color": "road", + "line-width": { + "fn": "exponential", + "z": 9, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "park_poi": { + "point-color": "green" + }, + "restaurant_poi": { + "point-image": "restaurant-12" + }, + "country_label": { + "text-halo-color": [1, 1, 1, 0.7], + "text-halo-width": "stroke_width", + "text-color": "text" + }, + "place_label": { + "text-halo-color": [1, 1, 1, 0.7], + "text-halo-width": "stroke_width", + "text-color": "text" + }, + "road_label": { + "text-color": "text", + "text-halo-color": [1, 1, 1, 0.7], + "text-halo-width": "stroke_width", + "text-size": { + "fn": "exponential", + "z": 14, + "val": 8, + "slope": 1, + "min": 8, + "max": 12 + } + } + }, + "satellite": { + "background": { + "transition-fill-color": { + "duration": 500, + "delay": 500 + }, + "fill-opacity": 0, + "fill-color": [1, 0, 0, 0] + }, + "roads": { + "transition-opacity": { + "duration": 500, + "delay": 500 + }, + "opacity": 0.5 + }, + "building": { + "fill-opacity": 0, + "transition-fill-opacity": { + "duration": 500, + "delay": 0 + } + }, + "park": { + "transition-fill-color": { + "duration": 500, + "delay": 0 + }, + "fill-color": [0, 0, 0, 0] + }, + "water": { + "fill-opacity": 0 + }, + "road_large": { + "transition-line-width": { + "duration": 500, + "delay": 1000 + }, + "line-width": { + "fn": "exponential", + "z": 10, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "road_large_casing": { + "line-width": { + "fn": "exponential", + "z": 10, + "val": 1, + "slope": 0.21, + "min": 4 + }, + "transition-line-width": { + "duration": 500, + "delay": 1000 + } + }, + "road_regular_casing": { + "transition-line-width": { + "duration": 500, + "delay": 1000 + }, + "line-width": { + "fn": "exponential", + "z": 11, + "val": 0.5, + "slope": 0.2, + "min": 1 + } + }, + "road_regular": { + "transition-line-width": { + "duration": 500, + "delay": 1000 + }, + "line-width": { + "fn": "exponential", + "z": 11, + "val": -1, + "slope": 0.2, + "min": 1 + } + }, + "satellite": { + "raster-brightness-low": "satellite_brightness_low", + "raster-brightness-high": "satellite_brightness_high", + "raster-saturation": "satellite_saturation", + "raster-spin": "satellite_spin", + "raster-contrast": "satellite_contrast" + } + }, + "test": { + "road_large_casing": { + "line-width": { + "fn": "exponential", + "z": 8, + "val": 1, + "slope": 0.21, + "min": 4 + }, + "line-color": [1, 0, 0, 1], + "transition-line-width": { + "duration": 500, + "delay": 0 + }, + "transition-line-color": { + "duration": 2000, + "delay": 500 + } + } + } + }, + "sprite": "img/sprite" +}