Skip to content

Commit

Permalink
Reimplement ref layer support in featuresAt (#847)
Browse files Browse the repository at this point in the history
This is a blend of #901 and #939.

The format for featuresAt results changed again. Instead of
result-per-geometry-cross-layer, each result has a `layers`
array with all layers that contain the feature. Thus avoiding
duplication of geometry and properties in the result set.
  • Loading branch information
jfirebaugh committed Jan 21, 2015
1 parent 081a26a commit 0dee48f
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 43 deletions.
8 changes: 4 additions & 4 deletions js/data/feature_tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ function FeatureTree(getGeometry, getType) {
this.toBeInserted = [];
}

FeatureTree.prototype.insert = function(bbox, layer, feature) {
bbox.layer = layer;
FeatureTree.prototype.insert = function(bbox, layers, feature) {
bbox.layers = layers;
bbox.feature = feature;
this.toBeInserted.push(bbox);
};
Expand All @@ -42,7 +42,7 @@ FeatureTree.prototype.query = function(args, callback) {
var type = this.getType(feature);
var geometry = this.getGeometry(feature);

if (params.layer && matching[i].layer.id !== params.layer.id)
if (params.layer && matching[i].layers.indexOf(params.layer.id) < 0)
continue;
if (params.$type && type !== params.$type)
continue;
Expand All @@ -52,7 +52,7 @@ FeatureTree.prototype.query = function(args, callback) {
var props = {
$type: type,
properties: matching[i].feature.properties,
layer: matching[i].layer
layers: matching[i].layers
};

if (params.geometry) {
Expand Down
16 changes: 15 additions & 1 deletion js/source/worker_tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ WorkerTile.prototype.parse = function(data, layers, actor, callback) {
continue;

bucket = createBucket(layer, buffers, collision);
bucket.layers = [layer.id];

buckets[bucket.id] = bucket;
bucketsInOrder.push(bucket);
Expand All @@ -72,6 +73,19 @@ WorkerTile.prototype.parse = function(data, layers, actor, callback) {
}
}

// Index ref layers.
for (i = 0; i < layers.length; i++) {
layer = layers[i];

if (layer.source !== this.source)
continue;

if (!layer.ref)
continue;

buckets[layer.ref].layers.push(layer.id);
}

// read each layer, and sort its features into buckets
if (data.layers) {
// vectortile
Expand Down Expand Up @@ -150,7 +164,7 @@ WorkerTile.prototype.parse = function(data, layers, actor, callback) {
if (bucket.interactive) {
for (var i = 0; i < bucket.features.length; i++) {
var feature = bucket.features[i];
tile.featureTree.insert(feature.bbox(), {id: bucket.id}, feature);
tile.featureTree.insert(feature.bbox(), bucket.layers, feature);
}
}
if (typeof self !== 'undefined') {
Expand Down
10 changes: 4 additions & 6 deletions js/style/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ Style.prototype = util.inherit(Evented, {
for (id in this._layers) {
layer = this._layers[id];

ordered.push(layer.transferable());
ordered.push(layer.json());

if (layer.nested)
continue;
Expand Down Expand Up @@ -241,11 +241,9 @@ Style.prototype = util.inherit(Evented, {
}, () => {
if (error) return callback(error);

features.forEach((feature) => {
var layer = this._layers[feature.layer.id];
util.extend(feature.layer, layer._layer, {
paint: layer.paint,
layout: layer.layout
features.forEach(feature => {
feature.layers = feature.layers.map(id => {
return this._layers[id].json();
});
});

Expand Down
26 changes: 14 additions & 12 deletions js/style/style_layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,6 @@ function StyleLayer(layer) {
}

StyleLayer.prototype = {
assign(layer) {
this.type = layer.type;
this.source = layer.source;
this['source-layer'] = layer['source-layer'];
this.minzoom = layer.minzoom;
this.maxzoom = layer.maxzoom;
this.filter = layer.filter;
this.layout = layer.layout;
},

resolveLayout(layers, constants) {
if (!this.ref) {
this.layout = new LayoutProperties[this.type](
Expand Down Expand Up @@ -144,8 +134,20 @@ StyleLayer.prototype = {
return !this.hidden;
},

transferable() {
return util.extend({}, this._layer, {layout: this.layout});
assign(layer) {
util.extend(this, util.pick(layer,
'type', 'source', 'source-layer',
'minzoom', 'maxzoom', 'filter',
'layout'));
},

json() {
return util.extend({},
this._layer,
util.pick(this,
'type', 'source', 'source-layer',
'minzoom', 'maxzoom', 'filter',
'layout', 'paint'));
}
};

Expand Down
5 changes: 2 additions & 3 deletions test/js/data/feature_tree.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ test('featuretree query', function(t) {

for (var i=0; i<tile.layers.water._features.length; i++) {
var feature = tile.layers.water.feature(i);
ft.insert(feature.bbox(), {id: 'water'}, feature);
ft.insert(feature.bbox(), ['water'], feature);
}

ft.query({
Expand All @@ -86,8 +86,7 @@ test('featuretree query', function(t) {
t.notEqual(features.length, 0, 'non-empty results for queryFeatures');
features.forEach(function(f) {
t.ok(f.$type, 'result has $type');
t.ok(f.layer, 'result has layer');
t.equal(f.layer.id, 'water');
t.deepEqual(f.layers, ['water']);
t.ok(f.properties, 'result has properties');
t.notEqual(f.properties.osm_id, undefined, 'properties has osm_id by default');
});
Expand Down
24 changes: 7 additions & 17 deletions test/js/style/style.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,20 +261,10 @@ test('Style#featuresAt', function(t) {
style.sources.mapbox.featuresAt = function(position, params, callback) {
callback(null, [{
$type: 'Polygon',
layer: {
id: 'land',
type: 'line'
}
layers: ['land']
}, {
$type: 'Polygon',
layer: {
id: 'landref',
ref: 'land',
type: 'line',
paint: {
'line-color': 'blue'
}
}
layers: ['land', 'landref']
}]);
};

Expand All @@ -290,7 +280,7 @@ test('Style#featuresAt', function(t) {
style.featuresAt([256, 256], {}, function(err, results) {
t.error(err);

var layout = results[0].layer.layout;
var layout = results[0].layers[0].layout;
t.deepEqual(layout, {'line-cap': 'round'});
t.deepEqual(
Object.getPrototypeOf(layout),
Expand All @@ -304,7 +294,7 @@ test('Style#featuresAt', function(t) {
style.featuresAt([256, 256], {}, function(err, results) {
t.error(err);

var paint = results[0].layer.paint;
var paint = results[0].layers[0].paint;
t.deepEqual(paint, {'line-color': [ 1, 0, 0, 1 ]});
t.deepEqual(
Object.getPrototypeOf(paint),
Expand All @@ -318,8 +308,8 @@ test('Style#featuresAt', function(t) {
style.featuresAt([256, 256], {}, function(err, results) {
t.error(err);

var layer = results[0].layer;
var refLayer = results[1].layer;
var layer = results[1].layers[0];
var refLayer = results[1].layers[1];
t.deepEqual(layer.layout, refLayer.layout);
t.deepEqual(layer.type, refLayer.type);
t.deepEqual(layer.id, refLayer.ref);
Expand All @@ -333,7 +323,7 @@ test('Style#featuresAt', function(t) {
style.featuresAt([256, 256], {}, function(err, results) {
t.error(err);

var layer = results[0].layer;
var layer = results[0].layers[0];
t.equal(layer.something, 'else');

t.end();
Expand Down

0 comments on commit 0dee48f

Please sign in to comment.