Releases: tangrams/tangram
Releases · tangrams/tangram
v0.22.0
What's Changed
- Limit number of rings in polygons to 500 by @bcamper in #810 (fixes #773)
- Fix source with transform reloads by @wangxingkai in #789
- Fix external fonts by @bcamper in 6743110 (fixes #771)
- Fix
scene.setDataSource()
withdata
property in Firefox by @bcamper in #772 (fixes #772) - Update npm / build dependencies by @bcamper in #811
Full Changelog: v0.21.1...v0.22.0
v0.21.1
Bugfixes
v0.21.0
New Features + Improvements
- Add support for text highlight boxes + underlines on point labels #761 #724 #723
- Add an optional box behind text labels via the following parameters in a new
font.background
block:font.background.color
: text box fill colorfont.background.alpha
: optionally modify box fill alphafont.background.stroke.color
: text box stroke colorfont.background.stroke.alpha
: optionally modify box stroke alphafont.background.stroke.width
: text box stroke width (defaults to1px
)
- Optional underline for text labels via new parameter
font.underline
underline: true
to enable text underline
- Text box fill, stroke, and underline are independent options which can be mixed and matched as desired. Example with all 3:
draw: text: font: ... background: color: white stroke: color: red width: 2px underline: true
- Add an optional box behind text labels via the following parameters in a new
- Support variable font weight ranges + JS function weights #757
- Variable fonts allow multiple variants of a font to be stored in a single file. Supporting these can streamline the Tangram font definition, reduces network requests, and introduces new cartographic flexibility for dynamically-driven font weights.
- Example supporting font weights of 200 through 800:
fonts: Open Sans: url: fonts/Open Sans.woff2 weight: 200 800
- Example of JS function-based font
weight
, e.g. mapping font weight to building heights:weight: | function() { return (feature.height||0) * 2 + 400; }
- Automatically add Leaflet attribution controls based on data source property #763
- Adds a new
attribution
property on data sources, which when present will add a Leaflet attribution control. Thanks @bdon! - Example:
sources: tilezen: type: MVT url: https://tile.nextzen.org/tilezen/vector/v1/512/all/{z}/{x}/{y}.mvt attribution: Tiles by <a href="https://www.nextzen.org/" target="_blank">Nextzen</a> ...
- Adds a new
- Improved proxy tile handling for better coverage when zooming in/out (thanks @bdon!) #762
- Support for MultiPoint geometries in MVT data sources 8554c27
Bug Fixes / Internal
v0.20.1
New Functionality
- Wireframe mode for debugging #745
- Use debug option
wireframe: true
to draw geometry in a wireframe mode, helpful for seeing how Tangram converts feature geometries into renderable GL triangles, and debugging issues with such - Example of enabling wireframe mode when the Tangram layer is created:
const layer = Tangram.leafletLayer({ scene: 'scene.yaml', debug: { wireframe: true // enable for wireframe rendering mode } });
- Use debug option
Bug Fixes
- Fix inconsistencies in handling of line dash colors and alpha #741 #742
- Alpha of dash foreground and background colors should not affect each other
- More consistent handling of alpha cutout behavior for
opaque
blending
- Remove spurious errors when an untiled data source is drawn with the
all_layers
flag set #747 77b9edb
Internal
- Upgrade
geojson-vt
to v3.2.1
v0.20.0
New Functionality
- Custom attributes for styles #739
- Styles can now define custom vertex attributes/varyings for use in GLSL shader code. This simplifies existing uses of per-feature property data in shaders (which have usually been "smuggled" into the shader by encoding non-color values in the color parameter), moving these values to semantic-appropriate attributes, and enabling more advanced forms of custom shader visualizations by allowing for multiple attributes to be defined.
- In a
style
declaration, theshaders
block can now contain a new entry calledattributes
-- a mapping of names to properties of custom vertex attributes. Those new attributes are given values indraw
groups by assigning a value to the attribute's name in a newattributes
block, and are then available inside shaderblocks
. All together, the new syntax looks like this:buildings: base: polygons shaders: attributes: height: type: float blocks: color: | // Use the custom attribute's varying to shade by height color.rgb = vec3(min(height / 100., 1.), 0., 0.); draw: # use default draw parameters to set the height attribute value from the height feature property attributes: height: function() { return feature.height; }
- The above example uses default draw parameters (inside the style definition) to assign the attribute values, which is convenient if the attribute is always tied a specific feature property. However, these attributes can also be set in any
draw
group withinlayers
, as with all other draw parameters. - Attribute values can be set as a JS function (e.g. to tie a numeric feature property to an attribute of the same name, likely the most common case for this functionality:
custom: function(){ return feature.custom; }
), a single value (custom: 5
), or zoom-interpolated values (custom: [[14, 50], [15, 150], [16, 300]]
). - Only 32-bit floating point values (defined as
type: float
in the attribute definition) are supported at this time (other attribute types may be supported in the future). - See #739 for full syntax.
- Alpha parameter for draw groups #740
- A new
alpha
parameter insidedraw
groups allows the scene author to set only the alpha channel of a color, independently of the RGB channels. This is useful for cases such as:- Modifying the alpha for named CSS colors
- Modifying the alpha channel in a sub-layer
- Using a feature property to set the color, but then modifying only the alpha
- In
draw
groups where analpha
parameter is present, its value will override the alpha channel set by the corresponding color parameter. For example:translucent_polygons: color: red alpha: 0.5 # red polygon with 50% opacity
- The
alpha
parameter is available forpolygons
(fillcolor
),lines
(inline and outlinecolor
), points (fill and outlinecolor
),text
(fontfill
and strokecolor
), andraster
(color
). alpha
values can be set as a single value (alpha: 0.5
), zoom-interpolated values (alpha: [[14, 0.5], [16, 1]]
), or JS function (alpha: function(){ return feature.height/200; }
)- See #740 for full syntax.
- A new
- Add
raster
-based styles to blend/base default styles 4609a89- An oversight when these new built-in style combinations were added in v0.19.0
Bug Fixes
- Fix mesh variant cache for line outlines 4fc6b91
- Fix event subscription notifications for style compilation errors e76e4fd
- Fixes Tangram Play inline shader compile errors
Internal
- Avoid polluting user-defined styles (
scene.config.styles
) with blend/base default styles 824ec12
v0.19.1
Improvements
- Support HTTP 204 response #734
- Adds support for HTTP 204 (No Content) responses in tile requests. These tiles will be considered to have loaded successfully, but will simply be empty. Previously these requests would cause warnings.
- Updates to built-in demo UX and scene examples.
Bug Fixes
v0.19.0
New Features
- Add new built-in rendering
styles
for all combinations ofblend
andbase
#719- This feature eases another common pain point with blend modes, as a follow-up to enabling
blend_order
to be set at thedraw
level in v0.18.0. - New built-in rendering
styles
are now included, to make it easier to use the differentblend
modes without having to write boilerplate styles. For each combination ofblend
mode (opaque
,overlay
, etc.) and stylebase
(polygons
,lines
, etc.), a style is automatically created at scene load-time with the naming schemeblend_base
, e.g.translucent_polygons
,overlay_lines
, etc. Each of these is a minimal style definition, such as (if expressed in YAML):
translucent_polygons: base: polygons blend: translucent
- To maintain backwards compatibility, any of these new "bootstrapped" styles is skipped if the user has already defined one with the same name in their scene.
- This feature eases another common pain point with blend modes, as a follow-up to enabling
- Add support for parsing MVT feature properties as JSON #715
- Some MVT data sources include properties with a richer object format than just strings or numbers -- e.g. arrays, nested objects, etc. The MVT spec doesn't prescribe explicit behavior for these cases, but notes that common tools such as Tippecanoe and Mapnik will encode these properties as stringified JSON.
- Client-side support for parsing these fields is added through a new
parse_json
property:- If
parse_json
istrue
, then each property will be checked to see if it "looks like" stringified JSON (defined as a string with first character being{
or[
); if so, it is parsed as JSON (withJSON.parse
). - If
parse_json
is an array of property names, only those specific properties are checked for JSON parsing. This is preferred to the above, because it limits the parsing impact to only the fields that need it. - If
parse_json
is undefined/null/false, no special parsing of properties is done (e.g. the current behavior).
- If
- Example usage:
sources: tiles: type: MVT url: https://... parse_json: [prop_a, prop_b] # treat feature properties 'prop_a' and 'prop_b' as stringified JSON
- Add native
filter
syntax for accessing nested feature properties #715- Dot notation with
.
can be used to access nested feature properties (these properties could have been encoded in a GeoJSON/TopoJSON source, or parsed from MVT stringified JSON properties with the feature introduced above). Previously, these properties could only be accessed through custom JSfilter
functions. - Given a feature property
a: { b: { c: 'test' } }
, this filter will match:filter: { a.b.c: test }
- Feature property names that include a
.
can be escaped with\.
, e.g. a feature property named'd.e.f': 'escaped'
will match with:filter: { d\.e\.f: escaped }
- These could be mixed, e.g. a property
{ 'a.b': { c: 'mixed' }
would match with:filter: { a\.b.c: mixed }
- Dot notation with
- Add native
filter
syntax for array-to-array operations #715- As part of the new support for "complex" property values that may be arrays, we can expand our
filter
syntax to support querying these fields more easily. Two keywords are added for this, extending the same filter object pattern we use formin/max
range filter syntax. includes_any
: check if an arraya
contains one or more of the valuesp
,q
,r
:filter: { a: { includes_any: [p, q, r] } }
includes_all
: check if an arraya
contains the valuesp
,q
, ANDr
:filter: { a: { includes_all: [p, q, r] } }
- As part of the new support for "complex" property values that may be arrays, we can expand our
- Add
all_layers: true
wildcard for data source layer matching #713- Introduces a "wildcard" syntax for the source
layer
in thedata
block inlayers
. When the parameterall_layers: true
is included, it will match ALL layers in the data source. This is useful for easily creating wireframe-like views, without knowing or needing to specify all the layers in the data source.
- Introduces a "wildcard" syntax for the source
Improvements
- More robust support for
feature.id
#720- All data formats supported by Tangram have a
feature.id
property (at the topfeature
level, outsidefeature.properties
; some data sets may separately include an id or similar property withinfeature.properties
), but we haven't had full support for it. This version fixes that. - Ensures
feature.id
persists wherever features are internally copied/synthesized/etc. internally - Provides access to
feature.id
in user-authored JS scene functions with a new$id
variable - Includes
feature.id
in feature object results returned fromscene.queryFeatures()
- Includes
feature.id
in the default uniqueness check forscene.queryFeatures()
, with$id
syntax used if specifying a list of properties to uniqueify on (see #720 for details).
- All data formats supported by Tangram have a
- More intuitive default
repeat_distance
for point feature labels #718- The default
repeat_distance
for labels has always been256px
across the board. This is a sensible default for cases such as street labels (the original use case for repeat label culling) and road shields, but can generate unexpected results particularly when applied to point labels. For example, when labelling data with a property that has a finite set of values, such as category names ("bar", "restaurant", "hardware store", etc.) or numeric values, it's often surprising/undesirable that only a few labels are plotted. - This version changes this behavior such that:
- For labels generated from point features, the default
repeat_distance
is0px
. - For all other labels, including those generated from line or polygon features (e.g. street names, road shields, park names, etc.), the default
repeat_distance
continues to be256px
. Note that in these examples, the labels themselves may still be point labels -- it is the underlying geometry type that matters, e.g. road shields are point labels generated from line geometries.
- For labels generated from point features, the default
- See #718 for example.
- The default
Bug Fixes
- Handle tiles with no data in
scene.queryFeatures()
7946554 - Workaround for obscure bug seen with small (<28px) SVG images encoded as data URLs e1f2869
Performance/Internal
- Add a collision grid for better performance of high density point/label scenes #722
- Adds a simple collision grid system to drastically reduce the number of collisions performed for dense data sets. In a collision grid, the labels are divided (in this case in screen-space) into a grid of a given size; each label is added to the one or more grid cells that it intersects. When we need to know which labels a given label intersects, we only need to test the "local" labels that are in the same grid cells. See #722 for details.
- Default to WebGL "high performance" mode #721
- Defaults to using
high-performance
for WebGL'spowerPreference
setting. This will ask for use of the discrete GPU where possible. The user can override this default, as with other GL context options:
const layer = Tangram.leafletLayer({ scene, { webGLContextOptions: { powerPreference: 'low-power' } } });
- Defaults to using
v0.18.2
Improvements
- More efficient filters for checking value in array (e.g.
kind_detail: [park, aerodrome, university]
) bcd6754 - Run collision immediately on view change to reduce label crowding on zoom out 6d40cd9
Bug Fixes
- Don't overflow line texture
u
coordinates f2b4957 - Namespace "private" shader variables with
_
to reduce collisions with user-defined styles a3ab5d4 - Fix label tile breach test 2a6fc6c
Demo
- Add support for loading custom scene URLs with
scene
query param - Upgrade Refill version and use MVT tiles for default demo
v0.18.1
Improvements
- Avoid redundant
view_complete
events while scene is updating. 593c312 8bc21d5 - Improved build time for points and labels through decreased garbage collection (by avoiding memory allocation for temporary objects). Improves build time of dense point datasets by up to 33%. e0e99e6 9d772cd af89f8e f4905ff 482eada c5ed335 e2f0ab9 d55a9c5
- Improved memory usage / garbage collection for collision detection through OBB (oriented bounding box) optimizations. ee9a0e5 5ae018d 11fd782 f0f9b41
Bug Fixes
v0.18.0
New Features
- More layer matching control with
priority
andexclusive
#705priority
controls the order in which sub-layers at the same level are matched, and which one "wins" when multiple matching layers are merged.exclusive
ensures that the layer is mutually exclusive, and no other sub-layers at the same level will match.- Used together,
if/else if/else
filter patterns can be expressed with these new keywords, e.g.:layers: layerA: # if matches layerA... filter: ... priority: 1 exclusive: true draw: ... layerB: # else if matches layerB... filter: ... priority: 2 exclusive: true draw: ...
- Data sources can define specific zoom levels at which tiles are loaded #702
- In some cases it may be unnecessary or undesirable to load new tile data at every zoom level. The new
zooms
parameter allows for control over which map view zoom levels load new tiles, with tiles overzoomed when viewing zooms in between. For example, to only load new tile data at every other zoom level:sources: tilezen: type: MVT url: ... zooms: [0, 2, 4, 6, 8, 10, 12, 14, 16] # only load tiles every 2 zooms
- If both
zooms
andmax_zoom
is present, the last zoom listed inzooms
takes precedence, and overrides themax_zoom
parameter. Themin_display_zoom
also automatically defaults to the first entry in thezooms
list.
- In some cases it may be unnecessary or undesirable to load new tile data at every zoom level. The new
- Enable setting of
blend_order
at thedraw
group level #703- Rather than requiring the
blend_order
to be set at thestyles
level (which has led to an unwieldy pattern of several "template" styles that vary only byblend_order
), this change enablesblend_order
to be set within adraw
group. This allows for much more flexibleblend_order
expressions, and a semantic use that aligns with theorder
parameter used for geometry world order ofopaque
-rendered features. For example, for a style withoverlay
blending:layers: overlays: draw: polygons-overlay: blend_order: 3 ...
- Rather than requiring the
- Quadkey support for tile URL templates #701
- Support for the quadkey tile URL scheme is now available with the
{q}
token (as an alternative to the{x}
/{y}
/{z}
URL pattern). For example, a Microsoft aerial imagery raster layer:sources: msft-aerial: type: Raster url: https://ecn.t3.tiles.virtualearth.net/tiles/a{q}.jpeg?g=587
- Support for the quadkey tile URL scheme is now available with the
Improvements
- Improved label collision when zooming #709
- Remove compounding alpha flicker artifacts when zooming non-
opaque
features #704
Bug Fixes
- Fix force disable of Vertex Array Objects (for dev/debugging) f4235db