Skip to content

Commit

Permalink
Don't wait for pattern images to layout layers no -pattern property set
Browse files Browse the repository at this point in the history
bonus: remove limitation on non-deterministic expression outputs for pattern properties and reliance on `possibleOutputs()` state
  • Loading branch information
Molly Lloyd committed Aug 17, 2018
1 parent fb233d7 commit 3cd1985
Show file tree
Hide file tree
Showing 13 changed files with 172 additions and 75 deletions.
4 changes: 3 additions & 1 deletion src/data/bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ export type BucketFeature = {|
geometry: Array<Array<Point>>,
properties: Object,
type: 1 | 2 | 3,
id?: any
id?: any,
+patterns: {[string]: {"min": string, "mid": string, "max": string}}
|};

/**
Expand Down Expand Up @@ -66,6 +67,7 @@ export type BucketFeature = {|
*/
export interface Bucket {
layerIds: Array<string>;
hasPattern: boolean;
+layers: Array<any>;
+stateDependentLayers: Array<any>;

Expand Down
2 changes: 2 additions & 0 deletions src/data/bucket/circle_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class CircleBucket<Layer: CircleStyleLayer | HeatmapStyleLayer> implements Bucke
indexArray: TriangleIndexArray;
indexBuffer: IndexBuffer;

hasPattern: boolean;
programConfigurations: ProgramConfigurationSet<Layer>;
segments: SegmentVector;
uploaded: boolean;
Expand All @@ -65,6 +66,7 @@ class CircleBucket<Layer: CircleStyleLayer | HeatmapStyleLayer> implements Bucke
this.layers = options.layers;
this.layerIds = this.layers.map(layer => layer.id);
this.index = options.index;
this.hasPattern = false;

this.layoutVertexArray = new CircleLayoutArray();
this.indexArray = new TriangleIndexArray();
Expand Down
71 changes: 51 additions & 20 deletions src/data/bucket/fill_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class FillBucket implements Bucket {
indexArray2: LineIndexArray;
indexBuffer2: IndexBuffer;

hasPattern: boolean;
programConfigurations: ProgramConfigurationSet<FillStyleLayer>;
segments: SegmentVector;
segments2: SegmentVector;
Expand All @@ -58,6 +59,7 @@ class FillBucket implements Bucket {
this.layers = options.layers;
this.layerIds = this.layers.map(layer => layer.id);
this.index = options.index;
this.hasPattern = false;

this.layoutVertexArray = new FillLayoutArray();
this.indexArray = new TriangleIndexArray();
Expand All @@ -72,32 +74,61 @@ class FillBucket implements Bucket {
this.features = [];

for (const layer of this.layers) {
const fillPattern = layer.paint.get('fill-pattern');
const images = fillPattern.property.getPossibleOutputs();
for (const image of images) {
patterns[image] = true;
const patternProperty = layer.paint.get('fill-pattern');
if (!patternProperty.isConstant()) {
this.hasPattern = true;
}

const constantPattern = patternProperty.constantOr(null);
if (constantPattern) {
this.hasPattern = true;
patterns[constantPattern.to] = true;
patterns[constantPattern.from] = true;
}
}

for (const {feature, index, sourceLayerIndex} of features) {
if (this.layers[0]._featureFilter(new EvaluationParameters(this.zoom), feature)) {

const geometry = loadGeometry(feature);
const fillFeature: BucketFeature = {
sourceLayerIndex: sourceLayerIndex,
index: index,
geometry: geometry,
properties: feature.properties,
type: feature.type
};

if (typeof feature.id !== 'undefined') {
fillFeature.id = feature.id;
}
if (!this.layers[0]._featureFilter(new EvaluationParameters(this.zoom), feature)) continue;

const geometry = loadGeometry(feature);

const bucketFeature: BucketFeature = {
sourceLayerIndex: sourceLayerIndex,
index: index,
geometry: geometry,
properties: feature.properties,
type: feature.type,
patterns: {}
};

this.features.push(fillFeature);
options.featureIndex.insert(feature, geometry, index, sourceLayerIndex, this.index);
if (typeof feature.id !== 'undefined') {
bucketFeature.id = feature.id;
}

if (this.hasPattern) {
for (const layer of this.layers) {
const patternProperty = layer.paint.get('fill-pattern');

const patternPropertyValue = patternProperty.value;
if (patternPropertyValue.kind !== "constant") {
const min = patternPropertyValue.evaluate({zoom: this.zoom - 1}, feature, {});
const mid = patternPropertyValue.evaluate({zoom: this.zoom}, feature, {});
const max = patternPropertyValue.evaluate({zoom: this.zoom + 1}, feature, {});
// add to patternDependencies
patterns[min] = true;
patterns[mid] = true;
patterns[max] = true;

// save for layout
bucketFeature.patterns[layer.id] = { min, mid, max };
}
}
this.features.push(bucketFeature);
} else {
this.addFeature(bucketFeature, geometry, index, {});
}

options.featureIndex.insert(feature, geometry, index, sourceLayerIndex, this.index);
}
}

Expand Down
74 changes: 53 additions & 21 deletions src/data/bucket/fill_extrusion_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type {
IndexedFeature,
PopulateParameters
} from '../bucket';

import type FillExtrusionStyleLayer from '../../style/style_layer/fill_extrusion_style_layer';
import type Context from '../../gl/context';
import type IndexBuffer from '../../gl/index_buffer';
Expand Down Expand Up @@ -62,6 +63,7 @@ class FillExtrusionBucket implements Bucket {
indexArray: TriangleIndexArray;
indexBuffer: IndexBuffer;

hasPattern: boolean;
programConfigurations: ProgramConfigurationSet<FillExtrusionStyleLayer>;
segments: SegmentVector;
uploaded: boolean;
Expand All @@ -73,6 +75,7 @@ class FillExtrusionBucket implements Bucket {
this.layers = options.layers;
this.layerIds = this.layers.map(layer => layer.id);
this.index = options.index;
this.hasPattern = false;

this.layoutVertexArray = new FillExtrusionLayoutArray();
this.indexArray = new TriangleIndexArray();
Expand All @@ -84,33 +87,62 @@ class FillExtrusionBucket implements Bucket {
const patterns = options.patternDependencies;
this.features = [];

for (let i = 0; i < this.layers.length; i++) {
const layer = this.layers[i];
const fillExtrusionPattern = layer.paint.get('fill-extrusion-pattern');
const images = fillExtrusionPattern.property.getPossibleOutputs();
for (const image of images) {
patterns[image] = true;
for (const layer of this.layers) {
const patternProperty = layer.paint.get('fill-extrusion-pattern');
if (!patternProperty.isConstant()) {
this.hasPattern = true;
}
}

const constantPattern = patternProperty.constantOr(null);
if (constantPattern) {
this.hasPattern = true;
patterns[constantPattern.to] = true;
patterns[constantPattern.from] = true;
}
}

for (const {feature, index, sourceLayerIndex} of features) {
if (this.layers[0]._featureFilter(new EvaluationParameters(this.zoom), feature)) {
const geometry = loadGeometry(feature);
const fillExtrusionFeature: BucketFeature = {
sourceLayerIndex: sourceLayerIndex,
index: index,
geometry: geometry,
properties: feature.properties,
type: feature.type
};

if (typeof feature.id !== 'undefined') {
fillExtrusionFeature.id = feature.id;
if (!this.layers[0]._featureFilter(new EvaluationParameters(this.zoom), feature)) continue;

const geometry = loadGeometry(feature);

const bucketFeature: BucketFeature = {
sourceLayerIndex: sourceLayerIndex,
index: index,
geometry: geometry,
properties: feature.properties,
type: feature.type,
patterns: {}
};

if (typeof feature.id !== 'undefined') {
bucketFeature.id = feature.id;
}

if (this.hasPattern) {
for (const layer of this.layers) {
const patternProperty = layer.paint.get('fill-extrusion-pattern');

const patternPropertyValue = patternProperty.value;
if (patternPropertyValue.kind !== "constant") {
const min = patternPropertyValue.evaluate({zoom: this.zoom - 1}, feature, {});
const mid = patternPropertyValue.evaluate({zoom: this.zoom}, feature, {});
const max = patternPropertyValue.evaluate({zoom: this.zoom + 1}, feature, {});
// add to patternDependencies
patterns[min] = true;
patterns[mid] = true;
patterns[max] = true;

// save for layout
bucketFeature.patterns[layer.id] = { min, mid, max };
}
}
this.features.push(fillExtrusionFeature);
options.featureIndex.insert(feature, geometry, index, sourceLayerIndex, this.index);
this.features.push(bucketFeature);
} else {
this.addFeature(bucketFeature, geometry, index, {});
}

options.featureIndex.insert(feature, geometry, index, sourceLayerIndex, this.index);
}
}

Expand Down
48 changes: 40 additions & 8 deletions src/data/bucket/line_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class LineBucket implements Bucket {
indexArray: TriangleIndexArray;
indexBuffer: IndexBuffer;

hasPattern: boolean;
programConfigurations: ProgramConfigurationSet<LineStyleLayer>;
segments: SegmentVector;
uploaded: boolean;
Expand All @@ -117,6 +118,7 @@ class LineBucket implements Bucket {
this.layerIds = this.layers.map(layer => layer.id);
this.index = options.index;
this.features = [];
this.hasPattern = false;

this.layoutVertexArray = new LineLayoutArray();
this.indexArray = new TriangleIndexArray();
Expand All @@ -129,30 +131,60 @@ class LineBucket implements Bucket {
this.features = [];

for (const layer of this.layers) {
const linePattern = layer.paint.get('line-pattern');
const images = linePattern.property.getPossibleOutputs();
for (const image of images) {
patterns[image] = true;
const patternProperty = layer.paint.get('line-pattern');
if (!patternProperty.isConstant()) {
this.hasPattern = true;
}

const constantPattern = patternProperty.constantOr(null);
if (constantPattern) {
this.hasPattern = true;
patterns[constantPattern.to] = true;
patterns[constantPattern.from] = true;
}
}

for (const {feature, index, sourceLayerIndex} of features) {
if (!this.layers[0]._featureFilter(new EvaluationParameters(this.zoom), feature)) continue;

const geometry = loadGeometry(feature);
const lineFeature: BucketFeature = {

const bucketFeature: BucketFeature = {
sourceLayerIndex: sourceLayerIndex,
index: index,
geometry: geometry,
properties: feature.properties,
type: feature.type
type: feature.type,
patterns: {}
};

if (typeof feature.id !== 'undefined') {
lineFeature.id = feature.id;
bucketFeature.id = feature.id;
}

if (this.hasPattern) {
for (const layer of this.layers) {
const patternProperty = layer.paint.get('line-pattern');

const patternPropertyValue = patternProperty.value;
if (patternPropertyValue.kind !== "constant") {
const min = patternPropertyValue.evaluate({zoom: this.zoom - 1}, feature, {});
const mid = patternPropertyValue.evaluate({zoom: this.zoom}, feature, {});
const max = patternPropertyValue.evaluate({zoom: this.zoom + 1}, feature, {});
// add to patternDependencies
patterns[min] = true;
patterns[mid] = true;
patterns[max] = true;

// save for layout
bucketFeature.patterns[layer.id] = { min, mid, max };
}
}
this.features.push(bucketFeature);
} else {
this.addFeature(bucketFeature, geometry, index, {});
}

this.features.push(lineFeature);
options.featureIndex.insert(feature, geometry, index, sourceLayerIndex, this.index);
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/data/bucket/symbol_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ class SymbolBucket implements Bucket {
iconsNeedLinear: boolean;
bucketInstanceId: number;
justReloaded: boolean;
hasPattern: boolean;

textSizeData: SizeData;
iconSizeData: SizeData;
Expand Down Expand Up @@ -302,6 +303,7 @@ class SymbolBucket implements Bucket {
this.index = options.index;
this.pixelRatio = options.pixelRatio;
this.sourceLayerIndex = options.sourceLayerIndex;
this.hasPattern = false;

const layer = this.layers[0];
const unevaluatedLayoutValues = layer._unevaluatedLayout._values;
Expand Down
Loading

0 comments on commit 3cd1985

Please sign in to comment.