diff --git a/js/data/bucket.js b/js/data/bucket.js index 1a484dd979f..7e4b1233401 100644 --- a/js/data/bucket.js +++ b/js/data/bucket.js @@ -53,7 +53,7 @@ function Bucket(options) { this.layer = StyleLayer.create(options.layer); this.layer.recalculate(this.zoom, { lastIntegerZoom: Infinity, lastIntegerZoomTime: 0, lastZoom: 0 }); - this.layers = [this.layer.id]; + this.layerIDs = [this.layer.id]; this.type = this.layer.type; this.features = []; this.id = this.layer.id; diff --git a/js/data/feature_tree.js b/js/data/feature_tree.js index 3091faff8a4..f8c3b5944c8 100644 --- a/js/data/feature_tree.js +++ b/js/data/feature_tree.js @@ -5,25 +5,27 @@ var Point = require('point-geometry'); var vt = require('vector-tile'); var util = require('../util/util'); var loadGeometry = require('./load_geometry'); +var CollisionBox = require('../symbol/collision_box'); var EXTENT = require('./buffer').EXTENT; module.exports = FeatureTree; -function FeatureTree(coord, overscaling) { +function FeatureTree(coord, overscaling, collisionTile) { this.x = coord.x; this.y = coord.y; this.z = coord.z - Math.log(overscaling) / Math.LN2; this.rtree = rbush(9); this.toBeInserted = []; + this.setCollisionTile(collisionTile); } -FeatureTree.prototype.insert = function(bbox, layers, feature) { +FeatureTree.prototype.insert = function(bbox, layerIDs, feature) { var scale = EXTENT / feature.extent; bbox[0] *= scale; bbox[1] *= scale; bbox[2] *= scale; bbox[3] *= scale; - bbox.layers = layers; + bbox.layerIDs = layerIDs; bbox.feature = feature; this.toBeInserted.push(bbox); }; @@ -34,6 +36,10 @@ FeatureTree.prototype._load = function() { this.toBeInserted = []; }; +FeatureTree.prototype.setCollisionTile = function(collisionTile) { + this.collisionTile = collisionTile; +}; + // Finds features in this tile at a particular position. FeatureTree.prototype.query = function(args, callback) { if (this.toBeInserted.length) this._load(); @@ -43,45 +49,59 @@ FeatureTree.prototype.query = function(args, callback) { y = args.y, result = []; - var radius, bounds; + var radius, bounds, symbolQueryBox; if (typeof x !== 'undefined' && typeof y !== 'undefined') { // a point (or point+radius) query - radius = (params.radius || 0) * EXTENT / args.scale; + radius = (params.radius || 0) * EXTENT / args.tileSize / args.scale; bounds = [x - radius, y - radius, x + radius, y + radius]; + symbolQueryBox = new CollisionBox(new Point(x, y), -radius, -radius, radius, radius, args.scale, null); } else { // a rectangle query bounds = [ args.minX, args.minY, args.maxX, args.maxY ]; + symbolQueryBox = new CollisionBox(new Point(args.minX, args.minY), 0, 0, args.maxX - args.minX, args.maxY - args.minY, args.scale, null); } - var matching = this.rtree.search(bounds); - for (var i = 0; i < matching.length; i++) { - var feature = matching[i].feature, - layers = matching[i].layers, - type = vt.VectorTileFeature.types[feature.type]; - + function checkIntersection(feature) { + var type = vt.VectorTileFeature.types[feature.type]; if (params.$type && type !== params.$type) - continue; - if (radius && !geometryContainsPoint(loadGeometry(feature), type, new Point(x, y), radius)) - continue; - else if (!geometryIntersectsBox(loadGeometry(feature), type, bounds)) - continue; + return false; + + return radius ? + geometryContainsPoint(loadGeometry(feature), type, new Point(x, y), radius) : + geometryIntersectsBox(loadGeometry(feature), type, bounds); + } + + function checkSymbolIntersection() { + return true; + } + + this.addFeatures(this.rtree.search(bounds), params, checkIntersection, result); + this.addFeatures(this.collisionTile.getFeaturesAt(symbolQueryBox, args.scale), params, checkSymbolIntersection, result); + + callback(null, result); +}; +FeatureTree.prototype.addFeatures = function(matching, params, checkIntersection, result) { + for (var i = 0; i < matching.length; i++) { + var feature = matching[i].feature, + layerIDs = matching[i].layerIDs; var geoJSON = feature.toGeoJSON(this.x, this.y, this.z); + if (!checkIntersection(feature)) continue; + if (!params.includeGeometry) { geoJSON.geometry = null; } - for (var l = 0; l < layers.length; l++) { - var layer = layers[l]; + for (var l = 0; l < layerIDs.length; l++) { + var layerID = layerIDs[l]; - if (params.layerIds && params.layerIds.indexOf(layer) < 0) + if (params.layerIds && params.layerIds.indexOf(layerID) < 0) continue; - result.push(util.extend({layer: layer}, geoJSON)); + result.push(util.extend({layer: layerID}, geoJSON)); } } - callback(null, result); }; function geometryIntersectsBox(rings, type, bounds) { diff --git a/js/data/symbol_bucket.js b/js/data/symbol_bucket.js index 8e20aa36833..b4e2cb8b485 100644 --- a/js/data/symbol_bucket.js +++ b/js/data/symbol_bucket.js @@ -223,14 +223,14 @@ SymbolBucket.prototype.addFeatures = function(collisionTile, stacks, icons) { } if (shapedText || shapedIcon) { - this.addFeature(geometries[k], shapedText, shapedIcon); + this.addFeature(geometries[k], shapedText, shapedIcon, features[k]); } } this.placeFeatures(collisionTile, this.buffers, this.collisionDebug); }; -SymbolBucket.prototype.addFeature = function(lines, shapedText, shapedIcon) { +SymbolBucket.prototype.addFeature = function(lines, shapedText, shapedIcon, feature) { var layout = this.layer.layout; var glyphSize = 24; @@ -302,7 +302,8 @@ SymbolBucket.prototype.addFeature = function(lines, shapedText, shapedIcon) { // the buffers for both tiles and clipped to tile boundaries at draw time. var addToBuffers = inside || mayOverlap; - this.symbolInstances.push(new SymbolInstance(anchor, line, shapedText, shapedIcon, layout, addToBuffers, this.symbolInstances.length, + this.symbolInstances.push(new SymbolInstance(anchor, line, shapedText, shapedIcon, layout, + addToBuffers, this.symbolInstances.length, feature, this.layerIDs, textBoxScale, textPadding, textAlongLine, iconBoxScale, iconPadding, iconAlongLine)); } @@ -408,18 +409,14 @@ SymbolBucket.prototype.placeFeatures = function(collisionTile, buffers, collisio // Insert final placement into collision tree and add glyphs/icons to buffers if (hasText) { - if (!layout['text-ignore-placement']) { - collisionTile.insertCollisionFeature(symbolInstance.textCollisionFeature, glyphScale); - } + collisionTile.insertCollisionFeature(symbolInstance.textCollisionFeature, glyphScale, layout['text-ignore-placement']); if (glyphScale <= maxScale) { this.addSymbols('glyph', symbolInstance.glyphQuads, glyphScale, layout['text-keep-upright'], textAlongLine, collisionTile.angle); } } if (hasIcon) { - if (!layout['icon-ignore-placement']) { - collisionTile.insertCollisionFeature(symbolInstance.iconCollisionFeature, iconScale); - } + collisionTile.insertCollisionFeature(symbolInstance.iconCollisionFeature, iconScale, layout['icon-ignore-placement']); if (iconScale <= maxScale) { this.addSymbols('icon', symbolInstance.iconQuads, iconScale, layout['icon-keep-upright'], iconAlongLine, collisionTile.angle); } @@ -534,7 +531,7 @@ SymbolBucket.prototype.addToDebugBuffers = function(collisionTile) { } }; -function SymbolInstance(anchor, line, shapedText, shapedIcon, layout, addToBuffers, index, +function SymbolInstance(anchor, line, shapedText, shapedIcon, layout, addToBuffers, index, feature, layerIDs, textBoxScale, textPadding, textAlongLine, iconBoxScale, iconPadding, iconAlongLine) { @@ -546,11 +543,11 @@ function SymbolInstance(anchor, line, shapedText, shapedIcon, layout, addToBuffe if (this.hasText) { this.glyphQuads = addToBuffers ? getGlyphQuads(anchor, shapedText, textBoxScale, line, layout, textAlongLine) : []; - this.textCollisionFeature = new CollisionFeature(line, anchor, shapedText, textBoxScale, textPadding, textAlongLine, false); + this.textCollisionFeature = new CollisionFeature(line, anchor, feature, layerIDs, shapedText, textBoxScale, textPadding, textAlongLine, false); } if (this.hasIcon) { this.iconQuads = addToBuffers ? getIconQuads(anchor, shapedIcon, iconBoxScale, line, layout, iconAlongLine) : []; - this.iconCollisionFeature = new CollisionFeature(line, anchor, shapedIcon, iconBoxScale, iconPadding, iconAlongLine, true); + this.iconCollisionFeature = new CollisionFeature(line, anchor, feature, layerIDs, shapedIcon, iconBoxScale, iconPadding, iconAlongLine, true); } } diff --git a/js/source/source.js b/js/source/source.js index 7659c1091f8..ff624464b7e 100644 --- a/js/source/source.js +++ b/js/source/source.js @@ -81,6 +81,7 @@ exports._vectorFeaturesAt = function(coord, params, callback) { x: result.x, y: result.y, scale: result.scale, + tileSize: result.tileSize, source: this.id, params: params }, callback, result.tile.workerID); diff --git a/js/source/tile_pyramid.js b/js/source/tile_pyramid.js index fbabeaa399c..444df4801d6 100644 --- a/js/source/tile_pyramid.js +++ b/js/source/tile_pyramid.js @@ -368,7 +368,8 @@ TilePyramid.prototype = { tile: tile, x: pos.x, y: pos.y, - scale: this.transform.worldSize / Math.pow(2, tile.coord.z) + scale: Math.pow(2, this.transform.zoom - tile.coord.z), + tileSize: this.tileSize }; } } diff --git a/js/source/worker_tile.js b/js/source/worker_tile.js index cf50d78169a..fefcdceb543 100644 --- a/js/source/worker_tile.js +++ b/js/source/worker_tile.js @@ -22,7 +22,8 @@ WorkerTile.prototype.parse = function(data, layers, actor, callback) { this.status = 'parsing'; - this.featureTree = new FeatureTree(this.coord, this.overscaling); + var collisionTile = new CollisionTile(this.angle, this.pitch); + this.featureTree = new FeatureTree(this.coord, this.overscaling, collisionTile); var stats = { _total: 0 }; @@ -63,7 +64,7 @@ WorkerTile.prototype.parse = function(data, layers, actor, callback) { for (i = 0; i < layers.length; i++) { layer = layers[i]; if (layer.source === this.source && layer.ref && bucketsById[layer.ref]) { - bucketsById[layer.ref].layers.push(layer.id); + bucketsById[layer.ref].layerIDs.push(layer.id); } } @@ -93,8 +94,6 @@ WorkerTile.prototype.parse = function(data, layers, actor, callback) { symbolBuckets = this.symbolBuckets = [], otherBuckets = []; - var collisionTile = new CollisionTile(this.angle, this.pitch); - for (var id in bucketsById) { bucket = bucketsById[id]; if (bucket.features.length === 0) continue; @@ -165,10 +164,10 @@ WorkerTile.prototype.parse = function(data, layers, actor, callback) { bucket.addFeatures(collisionTile, stacks, icons); var time = Date.now() - now; - if (bucket.interactive) { + if (bucket.interactive && bucket.type !== 'symbol') { for (var i = 0; i < bucket.features.length; i++) { var feature = bucket.features[i]; - tile.featureTree.insert(feature.bbox(), bucket.layers, feature); + tile.featureTree.insert(feature.bbox(), bucket.layerIDs, feature); } } @@ -208,6 +207,8 @@ WorkerTile.prototype.redoPlacement = function(angle, pitch, collisionDebug) { var buffers = {}, collisionTile = new CollisionTile(angle, pitch); + this.featureTree.setCollisionTile(collisionTile); + for (var i = this.symbolBuckets.length - 1; i >= 0; i--) { this.symbolBuckets[i].placeFeatures(collisionTile, buffers, collisionDebug); } diff --git a/js/symbol/collision_box.js b/js/symbol/collision_box.js index a38ce06aec1..24cbf654ee3 100644 --- a/js/symbol/collision_box.js +++ b/js/symbol/collision_box.js @@ -41,9 +41,11 @@ module.exports = CollisionBox; * @param {number} x2 The distance from the anchor to the right edge. * @param {number} y2 The distance from the anchor to the bottom edge. * @param {number} maxScale The maximum scale this box can block other boxes at. + * @param {VectorTileFeature} feature The VectorTileFeature that this CollisionBox was created for. + * @param {Array} layerIDs The IDs of the layers that this CollisionBox is a part of. * @private */ -function CollisionBox(anchorPoint, x1, y1, x2, y2, maxScale) { +function CollisionBox(anchorPoint, x1, y1, x2, y2, maxScale, feature, layerIDs) { // the box is centered around the anchor point this.anchorPoint = anchorPoint; @@ -57,6 +59,12 @@ function CollisionBox(anchorPoint, x1, y1, x2, y2, maxScale) { // The box does not block other boxes at scales >= maxScale; this.maxScale = maxScale; + // the index of the feature in the original vectortile + this.feature = feature; + + // the IDs of the layers this feature collision box appears in + this.layerIDs = layerIDs; + // the scale at which the label can first be shown this.placementScale = 0; diff --git a/js/symbol/collision_feature.js b/js/symbol/collision_feature.js index 0455f1b77d4..87e159505c5 100644 --- a/js/symbol/collision_feature.js +++ b/js/symbol/collision_feature.js @@ -14,6 +14,8 @@ module.exports = CollisionFeature; * @class CollisionFeature * @param {Array} line The geometry the label is placed on. * @param {Anchor} anchor The point along the line around which the label is anchored. + * @param {VectorTileFeature} feature The VectorTileFeature that this CollisionFeature was created for. + * @param {Array} layerIDs The IDs of the layers that this CollisionFeature is a part of. * @param {Object} shaped The text or icon shaping results. * @param {number} boxScale A magic number used to convert from glyph metrics units to geometry units. * @param {number} padding The amount of padding to add around the label edges. @@ -21,7 +23,7 @@ module.exports = CollisionFeature; * * @private */ -function CollisionFeature(line, anchor, shaped, boxScale, padding, alignLine, straight) { +function CollisionFeature(line, anchor, feature, IDs, shaped, boxScale, padding, alignLine, straight) { var y1 = shaped.top * boxScale - padding; var y2 = shaped.bottom * boxScale + padding; @@ -44,14 +46,14 @@ function CollisionFeature(line, anchor, shaped, boxScale, padding, alignLine, st // used for icon labels that are aligned with the line, but don't curve along it var vector = line[anchor.segment + 1].sub(line[anchor.segment])._unit()._mult(length); var straightLine = [anchor.sub(vector), anchor.add(vector)]; - this._addLineCollisionBoxes(straightLine, anchor, 0, length, height); + this._addLineCollisionBoxes(straightLine, anchor, 0, length, height, feature, IDs); } else { // used for text labels that curve along a line - this._addLineCollisionBoxes(line, anchor, anchor.segment, length, height); + this._addLineCollisionBoxes(line, anchor, anchor.segment, length, height, feature, IDs); } } else { - this.boxes.push(new CollisionBox(new Point(anchor.x, anchor.y), x1, y1, x2, y2, Infinity)); + this.boxes.push(new CollisionBox(new Point(anchor.x, anchor.y), x1, y1, x2, y2, Infinity, feature, IDs)); } } @@ -61,11 +63,13 @@ function CollisionFeature(line, anchor, shaped, boxScale, padding, alignLine, st * @param {Array} line * @param {Anchor} anchor * @param {number} labelLength The length of the label in geometry units. + * @param {Anchor} anchor The point along the line around which the label is anchored. + * @param {VectorTileFeature} feature The VectorTileFeature that this CollisionFeature was created for. * @param {number} boxSize The size of the collision boxes that will be created. * * @private */ -CollisionFeature.prototype._addLineCollisionBoxes = function(line, anchor, segment, labelLength, boxSize) { +CollisionFeature.prototype._addLineCollisionBoxes = function(line, anchor, segment, labelLength, boxSize, feature, IDs) { var step = boxSize / 2; var nBoxes = Math.floor(labelLength / step); @@ -118,7 +122,7 @@ CollisionFeature.prototype._addLineCollisionBoxes = function(line, anchor, segme var distanceToInnerEdge = Math.max(Math.abs(boxDistanceToAnchor - firstBoxOffset) - step / 2, 0); var maxScale = labelLength / 2 / distanceToInnerEdge; - bboxes.push(new CollisionBox(boxAnchorPoint, -boxSize / 2, -boxSize / 2, boxSize / 2, boxSize / 2, maxScale)); + bboxes.push(new CollisionBox(boxAnchorPoint, -boxSize / 2, -boxSize / 2, boxSize / 2, boxSize / 2, maxScale, feature, IDs)); } return bboxes; diff --git a/js/symbol/collision_tile.js b/js/symbol/collision_tile.js index 1787963aa5d..b317a525531 100644 --- a/js/symbol/collision_tile.js +++ b/js/symbol/collision_tile.js @@ -19,6 +19,7 @@ module.exports = CollisionTile; */ function CollisionTile(angle, pitch) { this.tree = rbush(); + this.ignoredTree = rbush(); this.angle = angle; var sin = Math.sin(angle), @@ -116,6 +117,39 @@ CollisionTile.prototype.placeCollisionFeature = function(collisionFeature, allow return minPlacementScale; }; +CollisionTile.prototype.getFeaturesAt = function(queryBox, scale) { + var features = []; + var result = []; + + var rotationMatrix = this.rotationMatrix; + var anchorPoint = queryBox.anchorPoint.matMult(rotationMatrix); + + var searchBox = [ + anchorPoint.x + queryBox.x1 / scale, + anchorPoint.y + queryBox.y1 / scale * this.yStretch, + anchorPoint.x + queryBox.x2 / scale, + anchorPoint.y + queryBox.y2 / scale * this.yStretch + ]; + + var blockingBoxes = this.tree.search(searchBox).concat(this.ignoredTree.search(searchBox)); + + for (var i = 0; i < blockingBoxes.length; i++) { + var blocking = blockingBoxes[i]; + var blockingAnchorPoint = blocking.anchorPoint.matMult(rotationMatrix); + var minPlacementScale = this.getPlacementScale(this.minScale, anchorPoint, queryBox, blockingAnchorPoint, blocking); + if (minPlacementScale >= scale) { + if (features.indexOf(blocking.feature) < 0) { + features.push(blocking.feature); + result.push({ + feature: blocking.feature, + layerIDs: blocking.layerIDs + }); + } + } + } + + return result; +}; CollisionTile.prototype.getPlacementScale = function(minPlacementScale, anchorPoint, box, blockingAnchorPoint, blocking) { @@ -164,7 +198,7 @@ CollisionTile.prototype.getPlacementScale = function(minPlacementScale, anchorPo * @param {number} minPlacementScale * @private */ -CollisionTile.prototype.insertCollisionFeature = function(collisionFeature, minPlacementScale) { +CollisionTile.prototype.insertCollisionFeature = function(collisionFeature, minPlacementScale, ignorePlacement) { var boxes = collisionFeature.boxes; for (var k = 0; k < boxes.length; k++) { @@ -172,6 +206,10 @@ CollisionTile.prototype.insertCollisionFeature = function(collisionFeature, minP } if (minPlacementScale < this.maxScale) { - this.tree.load(boxes); + if (ignorePlacement) { + this.ignoredTree.load(boxes); + } else { + this.tree.load(boxes); + } } }; diff --git a/test/js/data/feature_tree.test.js b/test/js/data/feature_tree.test.js index 7b5e25002c4..ca40e025d90 100644 --- a/test/js/data/feature_tree.test.js +++ b/test/js/data/feature_tree.test.js @@ -6,6 +6,7 @@ var fs = require('fs'); var Protobuf = require('pbf'); var FeatureTree = require('../../../js/data/feature_tree'); var path = require('path'); +var CollisionTile = require('../../../js/symbol/collision_tile'); test('featuretree', function(t) { var tile = new vt.VectorTile(new Protobuf(new Uint8Array(fs.readFileSync(path.join(__dirname, '/../../fixtures/mbsv5-6-18-23.vector.pbf'))))); @@ -15,12 +16,14 @@ test('featuretree', function(t) { function getGeometry(feature) { return feature.loadGeometry(); } - var ft = new FeatureTree(getGeometry, getType); + var ft = new FeatureTree(getGeometry, getType, new CollisionTile(0, 0)); var feature = tile.layers.road.feature(0); t.ok(feature); t.ok(ft, 'can be created'); ft.insert(feature.bbox(), 'road', feature); ft.query({ + scale: 1, + tileSize: 512, params: { }, x: 0, y: 0 @@ -39,7 +42,7 @@ test('featuretree with args', function(t) { function getGeometry(feature) { return feature.loadGeometry(); } - var ft = new FeatureTree(getGeometry, getType); + var ft = new FeatureTree(getGeometry, getType, new CollisionTile(0, 0)); var feature = tile.layers.road.feature(0); t.ok(feature); t.ok(ft, 'can be created'); @@ -59,7 +62,7 @@ test('featuretree with args', function(t) { test('featuretree point query', function(t) { var tile = new vt.VectorTile(new Protobuf(new Uint8Array(fs.readFileSync(path.join(__dirname, '/../../fixtures/mbsv5-6-18-23.vector.pbf'))))); - var ft = new FeatureTree({ x: 18, y: 23, z: 6 }, 1); + var ft = new FeatureTree({ x: 18, y: 23, z: 6 }, 1, new CollisionTile(0, 0)); for (var i = 0; i < tile.layers.water._features.length; i++) { var feature = tile.layers.water.feature(i); @@ -68,7 +71,8 @@ test('featuretree point query', function(t) { ft.query({ source: "mapbox.mapbox-streets-v5", - scale: 724.0773439350247, + scale: 724.0773439350247 / 512, + tileSize: 512, params: { radius: 30, includeGeometry: true @@ -91,7 +95,7 @@ test('featuretree point query', function(t) { test('featuretree rect query', function(t) { var tile = new vt.VectorTile(new Protobuf(new Uint8Array(fs.readFileSync(path.join(__dirname, '/../../fixtures/mbsv5-6-18-23.vector.pbf'))))); - var ft = new FeatureTree({ x: 18, y: 23, z: 6 }, 1); + var ft = new FeatureTree({ x: 18, y: 23, z: 6 }, 1, new CollisionTile(0, 0)); for (var i = 0; i < tile.layers.water._features.length; i++) { var feature = tile.layers.water.feature(i); @@ -100,7 +104,8 @@ test('featuretree rect query', function(t) { ft.query({ source: "mapbox.mapbox-streets-v5", - scale: 724.0773439350247, + scale: 724.0773439350247 / 512, + tileSize: 512, params: { includeGeometry: true }, @@ -140,7 +145,7 @@ test('featuretree query with layerIds', function(t) { function getGeometry(feature) { return feature.loadGeometry(); } - var ft = new FeatureTree(getGeometry, getType); + var ft = new FeatureTree(getGeometry, getType, new CollisionTile(0, 0)); for (var i = 0; i < tile.layers.water._features.length; i++) { var feature = tile.layers.water.feature(i); @@ -149,7 +154,8 @@ test('featuretree query with layerIds', function(t) { ft.query({ source: "mapbox.mapbox-streets-v5", - scale: 724.0773439350247, + scale: 724.0773439350247 / 512, + tileSize: 512, params: { radius: 30, layerIds: ['water'] @@ -163,7 +169,8 @@ test('featuretree query with layerIds', function(t) { ft.query({ source: "mapbox.mapbox-streets-v5", - scale: 724.0773439350247, + scale: 724.0773439350247 / 512, + tileSize: 512, params: { radius: 30, layerIds: ['none'] diff --git a/test/js/source/tile_pyramid.test.js b/test/js/source/tile_pyramid.test.js index 6cdb5c6f2fd..4383d607e27 100644 --- a/test/js/source/tile_pyramid.test.js +++ b/test/js/source/tile_pyramid.test.js @@ -248,7 +248,7 @@ test('TilePyramid#tileAt', function(t) { var result = pyramid.tileAt(new Coordinate(0, 3, 2)); t.deepEqual(result.tile.coord.id, 65); - t.deepEqual(result.scale, 724.0773439350247); + t.deepEqual(result.scale, 1.4142135623730951); t.deepEqual(result.x, 0); t.deepEqual(result.y, 4096); diff --git a/test/js/symbol/collision_feature.js b/test/js/symbol/collision_feature.js index 2e52e2fe0f1..e5a3270f60f 100644 --- a/test/js/symbol/collision_feature.js +++ b/test/js/symbol/collision_feature.js @@ -14,11 +14,14 @@ test('CollisionFeature', function(t) { bottom: 10 }; + var feature = {}; + var layerIDs = []; + test('point label', function(t) { var point = new Point(500, 0); var anchor = new Anchor(point.x, point.y, 0, undefined); - var cf = new CollisionFeature([point], anchor, shapedText, 1, 0, false); + var cf = new CollisionFeature([point], anchor, feature, layerIDs, shapedText, 1, 0, false); t.equal(cf.boxes.length, 1); var box = cf.boxes[0]; @@ -32,7 +35,7 @@ test('CollisionFeature', function(t) { test('line label', function(t) { var line = [new Point(0, 0), new Point(500, 100), new Point(510, 90), new Point(700, 0)]; var anchor = new Anchor(505, 95, 0, 1); - var cf = new CollisionFeature(line, anchor, shapedText, 1, 0, true); + var cf = new CollisionFeature(line, anchor, feature, layerIDs, shapedText, 1, 0, true); var boxPoints = cf.boxes.map(pluckAnchorPoint); t.deepEqual(boxPoints, [ { x: 467.71052542517856, y: 93.54210508503571 }, @@ -51,7 +54,7 @@ test('CollisionFeature', function(t) { test('vertical line label', function(t) { var line = [new Point(0, 0), new Point(0, 100), new Point(0, 111), new Point(0, 112), new Point(0, 200)]; var anchor = new Anchor(0, 110, 0, 1); - var cf = new CollisionFeature(line, anchor, shapedText, 1, 0, true); + var cf = new CollisionFeature(line, anchor, feature, layerIDs, shapedText, 1, 0, true); var boxPoints = cf.boxes.map(pluckAnchorPoint); t.deepEqual(boxPoints, [ { x: 0, y: 70 }, @@ -77,7 +80,7 @@ test('CollisionFeature', function(t) { var line = [new Point(0, 0), new Point(500, 100), new Point(510, 90), new Point(700, 0)]; var anchor = new Anchor(505, 95, 0, 1); - var cf = new CollisionFeature(line, anchor, shapedText, 1, 0, true); + var cf = new CollisionFeature(line, anchor, feature, layerIDs, shapedText, 1, 0, true); t.equal(cf.boxes.length, 0); t.end(); }); @@ -92,7 +95,7 @@ test('CollisionFeature', function(t) { var line = [new Point(0, 0), new Point(500, 100), new Point(510, 90), new Point(700, 0)]; var anchor = new Anchor(505, 95, 0, 1); - var cf = new CollisionFeature(line, anchor, shapedText, 1, 0, true); + var cf = new CollisionFeature(line, anchor, feature, layerIDs, shapedText, 1, 0, true); t.equal(cf.boxes.length, 0); t.end(); }); @@ -107,7 +110,7 @@ test('CollisionFeature', function(t) { var line = [new Point(0, 0), new Point(500, 100), new Point(510, 90), new Point(700, 0)]; var anchor = new Anchor(505, 95, 0, 1); - var cf = new CollisionFeature(line, anchor, shapedText, 1, 0, true); + var cf = new CollisionFeature(line, anchor, feature, layerIDs, shapedText, 1, 0, true); t.ok(cf.boxes.length < 30); t.end(); }); @@ -116,7 +119,7 @@ test('CollisionFeature', function(t) { var line = [new Point(3103, 4068), new Point(3225.6206896551726, 4096)]; var anchor = new Anchor(3144.5959947505007, 4077.498298013894, 0.22449735614507618, 0); var shaping = { right: 256, left: 0, bottom: 256, top: 0 }; - var cf = new CollisionFeature(line, anchor, shaping, 1, 0, true); + var cf = new CollisionFeature(line, anchor, feature, layerIDs, shaping, 1, 0, true); t.equal(cf.boxes.length, 1); t.end(); });