Skip to content

Commit

Permalink
Never join coincident start/end points of LineStrings
Browse files Browse the repository at this point in the history
  • Loading branch information
jfirebaugh committed Mar 13, 2017
1 parent c258306 commit f07f5a5
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 25 deletions.
29 changes: 13 additions & 16 deletions src/data/bucket/line_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const createVertexArrayType = require('../vertex_array_type');
const createElementArrayType = require('../element_array_type');
const loadGeometry = require('../load_geometry');
const EXTENT = require('../extent');
const VectorTileFeature = require('vector-tile').VectorTileFeature;

// NOTE ON EXTRUDE SCALE:
// scale the extrusion vector so that the normal length is this value.
Expand Down Expand Up @@ -88,55 +89,51 @@ class LineBucket extends Bucket {
const roundLimit = layout['line-round-limit'];

for (const line of loadGeometry(feature, LINE_DISTANCE_BUFFER_BITS)) {
this.addLine(line, feature.properties, join, cap, miterLimit, roundLimit);
this.addLine(line, feature, join, cap, miterLimit, roundLimit);
}
}

addLine(vertices, featureProperties, join, cap, miterLimit, roundLimit) {
addLine(vertices, feature, join, cap, miterLimit, roundLimit) {
const featureProperties = feature.properties;
const isPolygon = VectorTileFeature.types[feature.type] === 'Polygon';

let len = vertices.length;
// If the line has duplicate vertices at the end, adjust length to remove them.
while (len > 2 && vertices[len - 1].equals(vertices[len - 2])) {
let len = vertices.length;
while (len >= 2 && vertices[len - 1].equals(vertices[len - 2])) {
len--;
}

// a line must have at least two vertices
if (vertices.length < 2) return;
// Ignore invalid geometry.
if (len < (isPolygon ? 3 : 2)) return;

if (join === 'bevel') miterLimit = 1.05;

const sharpCornerOffset = SHARP_CORNER_OFFSET * (EXTENT / (512 * this.overscaling));

const firstVertex = vertices[0],
lastVertex = vertices[len - 1],
closed = firstVertex.equals(lastVertex);

const firstVertex = vertices[0];
const arrays = this.arrays;

// we could be more precise, but it would only save a negligible amount of space
const segment = arrays.prepareSegment(len * 10);

// a line may not have coincident points
if (len === 2 && closed) return;

this.distance = 0;

const beginCap = cap,
endCap = closed ? 'butt' : cap;
endCap = isPolygon ? 'butt' : cap;
let startOfLine = true;
let currentVertex, prevVertex, nextVertex, prevNormal, nextNormal, offsetA, offsetB;

// the last three vertices added
this.e1 = this.e2 = this.e3 = -1;

if (closed) {
if (isPolygon) {
currentVertex = vertices[len - 2];
nextNormal = firstVertex.sub(currentVertex)._unit()._perp();
}

for (let i = 0; i < len; i++) {

nextVertex = closed && i === len - 1 ?
nextVertex = isPolygon && i === len - 1 ?
vertices[1] : // if the line is closed, we treat the last vertex like the first
vertices[i + 1]; // just the next vertex

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{
"version": 8,
"metadata": {
"test": {
"width": 256,
"height": 256
}
},
"zoom": 1,
"center": [
-60,
-50
],
"sources": {
"LineStrings": {
"type": "geojson",
"data": {
"type": "GeometryCollection",
"geometries": [
{
"type": "LineString",
"coordinates": [
[-60, -60],
[-60, 60],
[60, 60],
[60, -60],
[-60, -60]
]
},
{
"type": "LineString",
"coordinates": [
[-90, -50],
[-90, -40],
[-70, -40],
[-70, -50],
[-90, -50]
]
}
]
}
},
"Polygons": {
"type": "geojson",
"data": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Polygon",
"coordinates": [[
[-50, -50],
[-50, 70],
[70, 70],
[70, -50],
[-50, -50]
]]
},
{
"type": "Polygon",
"coordinates": [[
[-90, -65],
[-90, -55],
[-70, -55],
[-70, -65],
[-90, -65]
]]
}
]
}
}
},
"layers": [
{
"id": "LineString",
"type": "line",
"source": "LineStrings",
"paint": {
"line-width": 20,
"line-opacity": 0.5,
"line-color": "green"
}
},
{
"id": "Polygon",
"type": "line",
"source": "Polygons",
"paint": {
"line-width": 20,
"line-opacity": 0.5,
"line-color": "blue"
}
}
]
}
56 changes: 47 additions & 9 deletions test/unit/data/line_bucket.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,33 +34,71 @@ test('LineBucket', (t) => {
const layer = new StyleLayer({ id: 'test', type: 'line' });
const bucket = new LineBucket({ layers: [layer] });

const pointWithScale = new Point(0, 0);
pointWithScale.scale = 10;
const line = {
type: 2,
properties: {}
};

const polygon = {
type: 3,
properties: {}
};

bucket.addLine([
new Point(0, 0)
], line);

bucket.addLine([
new Point(0, 0)
], polygon);

bucket.addLine([
new Point(0, 0),
new Point(0, 0)
], line);

// should throw in the future?
bucket.addLine([
new Point(0, 0),
new Point(0, 0)
], {});
], polygon);

// should also throw in the future?
// this is a closed single-segment line
bucket.addLine([
new Point(0, 0),
new Point(10, 10),
new Point(0, 0)
], {});
], line);

bucket.addLine([
new Point(0, 0),
new Point(10, 10),
new Point(0, 0)
], polygon);

bucket.addLine([
new Point(0, 0),
new Point(10, 10),
new Point(10, 20)
], {});
], line);

bucket.addLine([
new Point(0, 0),
new Point(10, 10),
new Point(10, 20)
], polygon);

bucket.addLine([
new Point(0, 0),
new Point(10, 10),
new Point(10, 20),
new Point(0, 0)
], line);

bucket.addLine([
new Point(0, 0),
new Point(10, 10),
new Point(10, 20),
new Point(0, 0)
], {});
], polygon);

bucket.addFeature(feature);

Expand Down

0 comments on commit f07f5a5

Please sign in to comment.