Added 2D outline support for polygons

feature/threejs-update
Robin Hawkes 2016-09-13 11:09:01 +01:00
rodzic ba2a16dcd5
commit 3e9d7fc352
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 1EC4C2D6765FA8CF
6 zmienionych plików z 180 dodań i 9 usunięć

Wyświetl plik

@ -19,6 +19,8 @@ VIZI.geoJSONLayer('http://vector.mapzen.com/osm/roads,pois,buildings/14/4824/615
output: true,
style: {
color: '#ff0000',
outline: true,
outlineColor: '#580000',
lineColor: '#0000ff',
lineRenderOrder: 1,
pointColor: '#00cc00'

Wyświetl plik

@ -23,6 +23,8 @@ world.createWorkers(7).then(() => {
output: true,
style: {
color: '#ff0000',
outline: true,
outlineColor: '#580000',
lineColor: '#0000ff',
lineRenderOrder: 1,
pointColor: '#00cc00'

Wyświetl plik

@ -170,6 +170,7 @@ class GeoJSONLayer extends LayerGroup {
// From here on we can assume that we want to merge the layers
var polygonAttributes = [];
var polygonOutlineAttributes = [];
var polygonAttributeLengths = {
positions: 3,
normals: 3,
@ -196,6 +197,11 @@ class GeoJSONLayer extends LayerGroup {
if (layer instanceof PolygonLayer) {
polygonAttributes.push(layer.getBufferAttributes());
var outlineBufferAttributes = layer.getOutlineBufferAttributes();
if (outlineBufferAttributes) {
polygonOutlineAttributes.push(outlineBufferAttributes);
}
if (polygonFlat && !layer.isFlat()) {
polygonFlat = false;
}
@ -228,10 +234,22 @@ class GeoJSONLayer extends LayerGroup {
if (polygonAttributes.length > 0) {
var mergedPolygonAttributes = Buffer.mergeAttributes(polygonAttributes);
var mergedPolygonOutlineAttributes;
if (polygonOutlineAttributes.length > 0) {
mergedPolygonOutlineAttributes = Buffer.mergeAttributes(polygonOutlineAttributes);
}
this._setPolygonMesh(mergedPolygonAttributes, polygonAttributeLengths, polygonFlat).then((result) => {
this._polygonMesh = result.mesh;
this.add(this._polygonMesh);
if (mergedPolygonOutlineAttributes) {
this._setPolylineMesh(mergedPolygonOutlineAttributes, polylineAttributeLengths, true).then((result) => {
this.add(result.mesh);
});
}
if (result.pickingMesh) {
this._pickingMesh.add(result.pickingMesh);
}

Wyświetl plik

@ -141,6 +141,14 @@ class GeoJSONWorkerLayer extends Layer {
var splitNormals = Buffer.splitFloat32Array(results.attributes.normals);
var splitColors = Buffer.splitFloat32Array(results.attributes.colors);
var splitOutlinePositions;
var splitOutlineColors;
if (results.outlineAttributes) {
splitOutlinePositions = Buffer.splitFloat32Array(results.outlineAttributes.positions);
splitOutlineColors = Buffer.splitFloat32Array(results.outlineAttributes.colors);
}
var splitProperties;
if (results.properties) {
splitProperties = Buffer.splitUint8Array(results.properties);
@ -149,6 +157,8 @@ class GeoJSONWorkerLayer extends Layer {
var flats = results.flats;
var objects = [];
var outlineObjects = [];
var obj;
var pickingId;
var pickingIds;
@ -160,6 +170,11 @@ class GeoJSONWorkerLayer extends Layer {
colors: 3
};
var polygonOutlineAttributeLengths = {
positions: 3,
colors: 3
};
for (var i = 0; i < splitPositions.length; i++) {
if (splitProperties && splitProperties[i]) {
properties = JSON.parse(Buffer.uint8ArrayToString(splitProperties[i]));
@ -208,7 +223,20 @@ class GeoJSONWorkerLayer extends Layer {
objects.push(obj);
}
for (var i = 0; i < splitOutlinePositions.length; i++) {
obj = {
attributes: [{
positions: splitOutlinePositions[i],
colors: splitOutlineColors[i]
}],
flat: true
};
outlineObjects.push(obj);
}
var polygonAttributes = [];
var polygonOutlineAttributes = [];
var polygonFlat = true;
@ -224,6 +252,13 @@ class GeoJSONWorkerLayer extends Layer {
polygonAttributes.push(bufferAttributes);
};
for (var i = 0; i < outlineObjects.length; i++) {
obj = outlineObjects[i];
var bufferAttributes = Buffer.mergeAttributes(obj.attributes);
polygonOutlineAttributes.push(bufferAttributes);
};
if (polygonAttributes.length > 0) {
var mergedPolygonAttributes = Buffer.mergeAttributes(polygonAttributes);
@ -240,6 +275,17 @@ class GeoJSONWorkerLayer extends Layer {
}
});
}
if (polygonOutlineAttributes.length > 0) {
var mergedPolygonOutlineAttributes = Buffer.mergeAttributes(polygonOutlineAttributes);
var style = (typeof this._options.style === 'function') ? this._options.style(objects[0]) : this._options.style;
style = extend({}, GeoJSON.defaultStyle, style);
this._setPolylineMesh(mergedPolygonOutlineAttributes, polygonOutlineAttributeLengths, style, true).then((result) => {
this.add(result.mesh);
});
}
}
// TODO: Dedupe with polygon method
@ -683,6 +729,9 @@ class GeoJSONWorkerLayer extends Layer {
var normals = [];
var colors = [];
var outlinePositions = [];
var outlineColors = [];
var properties = [];
var flats = [];
@ -713,6 +762,14 @@ class GeoJSONWorkerLayer extends Layer {
properties.push(Buffer.stringToUint8Array(JSON.stringify(polygon.properties)));
}
};
var outlineAttributes;
for (var j = 0; j < result.outlineAttributes.length; j++) {
outlineAttributes = result.outlineAttributes[j];
outlinePositions.push(outlineAttributes.positions);
outlineColors.push(outlineAttributes.colors);
};
};
var mergedAttributes = {
@ -721,6 +778,11 @@ class GeoJSONWorkerLayer extends Layer {
colors: Buffer.mergeFloat32Arrays(colors)
};
var mergedOutlineAttributes = {
positions: Buffer.mergeFloat32Arrays(outlinePositions),
colors: Buffer.mergeFloat32Arrays(outlineColors)
};
transferrables.push(mergedAttributes.positions[0].buffer);
transferrables.push(mergedAttributes.positions[1].buffer);
@ -730,6 +792,12 @@ class GeoJSONWorkerLayer extends Layer {
transferrables.push(mergedAttributes.colors[0].buffer);
transferrables.push(mergedAttributes.colors[1].buffer);
transferrables.push(mergedOutlineAttributes.positions[0].buffer);
transferrables.push(mergedOutlineAttributes.positions[1].buffer);
transferrables.push(mergedOutlineAttributes.colors[0].buffer);
transferrables.push(mergedOutlineAttributes.colors[1].buffer);
var mergedProperties;
if (_properties) {
mergedProperties = Buffer.mergeUint8Arrays(properties);
@ -740,6 +808,7 @@ class GeoJSONWorkerLayer extends Layer {
var output = {
attributes: mergedAttributes,
outlineAttributes: mergedOutlineAttributes,
flats: flats
};

Wyświetl plik

@ -76,19 +76,24 @@ class PolygonLayer extends Layer {
PolygonLayer.SetBufferAttributes(this._projectedCoordinates, this._options).then((result) => {
this._bufferAttributes = Buffer.mergeAttributes(result.attributes);
this._flat = result.flat;
var attributeLengths = {
positions: 3,
normals: 3,
colors: 3
};
if (this._options.interactive) {
attributeLengths.pickingIds = 1;
if (result.outlineAttributes.length > 0) {
this._outlineBufferAttributes = Buffer.mergeAttributes(result.outlineAttributes);
}
this._flat = result.flat;
if (this.isOutput()) {
var attributeLengths = {
positions: 3,
normals: 3,
colors: 3
};
if (this._options.interactive) {
attributeLengths.pickingIds = 1;
}
var style = this._options.style;
// Set mesh if not merging elsewhere
@ -103,6 +108,7 @@ class PolygonLayer extends Layer {
}
result.attributes = null;
result.outlineAttributes = null;
result = null;
resolve(this);
@ -158,6 +164,8 @@ class PolygonLayer extends Layer {
var flat = true;
var outlineAttributes = [];
// For each polygon
var attributes = coordinates.map(_coordinates => {
// Convert coordinates to earcut format
@ -230,6 +238,13 @@ class PolygonLayer extends Layer {
facesCount: _faces.length
};
if (options.style.outline) {
var outlineColour = new THREE.Color();
outlineColour.set(options.style.outlineColor || 0x000000);
outlineAttributes.push(PolygonLayer.Set2DOutline(_coordinates, outlineColour));
}
if (options.interactive && options.pickingId) {
// Inject picking ID
polygon.pickingId = options.pickingId;
@ -241,6 +256,7 @@ class PolygonLayer extends Layer {
resolve({
attributes: attributes,
outlineAttributes: outlineAttributes,
flat: flat
});
});
@ -250,6 +266,10 @@ class PolygonLayer extends Layer {
return this._bufferAttributes;
}
getOutlineBufferAttributes() {
return this._outlineBufferAttributes;
}
// Used by external components to clear some memory when the attributes
// are no longer required to be stored in this layer
//
@ -257,6 +277,64 @@ class PolygonLayer extends Layer {
// using something like the GeoJSONLayer
clearBufferAttributes() {
this._bufferAttributes = null;
this._outlineBufferAttributes = null;
}
// Threshold angle is currently in rads
static Set2DOutline(coordinates, colour) {
var _vertices = [];
coordinates.forEach((ring) => {
var _ring = ring.map((coordinate) => {
return [coordinate.x, 0, coordinate.y];
});
// Add in duplicate vertices for line segments to work
var verticeCount = _ring.length;
var first = true;
while (--verticeCount) {
if (first || verticeCount === 0) {
first = false;
continue;
}
_ring.splice(verticeCount + 1, 0, _ring[verticeCount]);
}
_vertices = _vertices.concat(_ring);
});
_colour = [colour.r, colour.g, colour.b];
var vertices = new Float32Array(_vertices.length * 3);
var colours = new Float32Array(_vertices.length * 3);
var lastIndex = 0;
for (var i = 0; i < _vertices.length; i++) {
var ax = _vertices[i][0];
var ay = _vertices[i][1];
var az = _vertices[i][2];
var c1 = _colour;
vertices[lastIndex * 3 + 0] = ax;
vertices[lastIndex * 3 + 1] = ay;
vertices[lastIndex * 3 + 2] = az;
colours[lastIndex * 3 + 0] = c1[0];
colours[lastIndex * 3 + 1] = c1[1];
colours[lastIndex * 3 + 2] = c1[2];
lastIndex++;
}
var attributes = {
positions: vertices,
colors: colours
};
return attributes;
}
// Used by external components to clear some memory when the coordinates

Wyświetl plik

@ -23,6 +23,8 @@ var shadow = new THREE.Color(0x666666);
var GeoJSON = (function() {
var defaultStyle = {
color: '#ffffff',
outline: false,
outlineColor: '#000000',
transparent: false,
opacity: 1,
blending: THREE.NormalBlending,