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