Merge pull request #184 from UDST/feature/outline-layering-fix

Fix layering issues with outlines
feature/threejs-update
Robin Hawkes 2016-10-06 13:20:42 +01:00 zatwierdzone przez GitHub
commit 69381a361f
9 zmienionych plików z 183 dodań i 24 usunięć

Wyświetl plik

@ -0,0 +1,18 @@
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">
<title>Web Workers Outlines ViziCities Example</title>
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="../../dist/vizicities.css">
</head>
<body>
<div id="world"></div>
<script src="../vendor/three.min.js"></script>
<script src="../vendor/TweenMax.min.js"></script>
<script src="../../dist/vizicities.min.js"></script>
<script src="main.js"></script>
</body>
</html>

Wyświetl plik

@ -0,0 +1,4 @@
* { margin: 0; padding: 0; }
html, body { height: 100%; overflow: hidden;}
#world { height: 100%; }

Wyświetl plik

@ -0,0 +1,49 @@
// Manhattan
var coords = [40.739940, -73.988801];
var world = VIZI.world('world', {
skybox: false,
postProcessing: false
}).setView(coords);
// Add controls
VIZI.Controls.orbit().addTo(world);
// Leave a single CPU for the main browser thread
world.createWorkers(7).then(() => {
console.log('Workers ready');
// CartoDB basemap
VIZI.imageTileLayer('http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="http://cartodb.com/attributions">CartoDB</a>'
}).addTo(world).then(() => {
console.log('Added image tile layer to world');
});
// Buildings from Mapzen
VIZI.topoJSONTileLayer('https://vector.mapzen.com/osm/buildings/{z}/{x}/{y}.topojson?api_key=vector-tiles-NT5Emiw', {
workers: true,
interactive: false,
maxLOD: 17,
style: function(feature) {
return {
color: Math.random() * 0xffffff,
outline: true,
outlineColor: '#000000',
// Uncomment to create a thicker outlines that appears below the
// polygon layer, sort of creating an outline around city blocks and
// adjacent buildings
// outlineRenderOrder: 0,
// outlineWidth: 2
}
},
filter: function(feature) {
// Don't show points
return feature.geometry.type !== 'Point';
},
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="http://whosonfirst.mapzen.com#License">Who\'s On First</a>.'
}).addTo(world).then(() => {
console.log('Added TopoJSON layer to world');
});
});

Wyświetl plik

@ -0,0 +1,61 @@
importScripts('../vendor/three.min.js');
// Special version of ViziCities without controls (no DOM errors)
importScripts('../../dist/vizicities-worker.min.js');
const DEBUG = false;
if (DEBUG) { console.log('Worker started', performance.now()); }
// Send startup message to main thread
postMessage({
type: 'startup',
payload: performance.now()
});
// Recieve message from main thread
onmessage = (event) => {
if (!event.data.method) {
postMessage({
type: 'error',
payload: 'No method provided'
});
return;
}
var time = performance.now();
if (DEBUG) { console.log('Message received from main thread', time, event.data); }
// if (DEBUG) console.log('Time to receive message', time - event.data);
// Run method
// if (!methods[event.data.method]) {
// postMessage({
// type: 'error',
// payload: 'Method not found'
// });
// return;
// }
var methods = event.data.method.split('.');
var _method = VIZI[methods[0]];
if (methods.length > 1) {
for (var i = 1; i < methods.length; i++) {
_method = _method[methods[i]];
}
}
// Call method with given arguments
_method.apply(this, event.data.args).then((result) => {
console.log('Message sent from worker', performance.now());
// Return results
postMessage({
type: 'result',
payload: result.data
}, result.transferrables);
});
};

Wyświetl plik

@ -232,6 +232,8 @@ class GeoJSONLayer extends LayerGroup {
}
});
var style;
if (polygonAttributes.length > 0) {
var mergedPolygonAttributes = Buffer.mergeAttributes(polygonAttributes);
@ -240,12 +242,28 @@ class GeoJSONLayer extends LayerGroup {
mergedPolygonOutlineAttributes = Buffer.mergeAttributes(polygonOutlineAttributes);
}
this._setPolygonMesh(mergedPolygonAttributes, polygonAttributeLengths, polygonFlat).then((result) => {
style = (typeof this._options.style === 'function') ? this._options.style(this._geojson.features[0]) : this._options.style;
style = extend({}, GeoJSON.defaultStyle, style);
this._setPolygonMesh(mergedPolygonAttributes, polygonAttributeLengths, style, polygonFlat).then((result) => {
this._polygonMesh = result.mesh;
this.add(this._polygonMesh);
if (mergedPolygonOutlineAttributes) {
this._setPolylineMesh(mergedPolygonOutlineAttributes, polylineAttributeLengths, true).then((result) => {
style = (typeof this._options.style === 'function') ? this._options.style(this._geojson.features[0]) : this._options.style;
style = extend({}, GeoJSON.defaultStyle, style);
if (style.outlineRenderOrder !== undefined) {
style.lineRenderOrder = style.outlineRenderOrder;
} else {
style.lineRenderOrder = (style.renderOrder) ? style.renderOrder + 1 : 2;
}
if (style.outlineWidth) {
style.lineWidth = style.outlineWidth;
}
this._setPolylineMesh(mergedPolygonOutlineAttributes, polylineAttributeLengths, style, true).then((result) => {
this.add(result.mesh);
});
}
@ -258,7 +276,11 @@ class GeoJSONLayer extends LayerGroup {
if (polylineAttributes.length > 0) {
var mergedPolylineAttributes = Buffer.mergeAttributes(polylineAttributes);
this._setPolylineMesh(mergedPolylineAttributes, polylineAttributeLengths, polylineFlat).then((result) => {
style = (typeof this._options.style === 'function') ? this._options.style(this._geojson.features[0]) : this._options.style;
style = extend({}, GeoJSON.defaultStyle, style);
this._setPolylineMesh(mergedPolylineAttributes, polylineAttributeLengths, style, polylineFlat).then((result) => {
this._polylineMesh = result.mesh;
this.add(this._polylineMesh);
@ -270,7 +292,11 @@ class GeoJSONLayer extends LayerGroup {
if (pointAttributes.length > 0) {
var mergedPointAttributes = Buffer.mergeAttributes(pointAttributes);
this._setPointMesh(mergedPointAttributes, pointAttributeLengths, pointFlat).then((result) => {
style = (typeof this._options.style === 'function') ? this._options.style(this._geojson.features[0]) : this._options.style;
style = extend({}, GeoJSON.defaultStyle, style);
this._setPointMesh(mergedPointAttributes, pointAttributeLengths, style, pointFlat).then((result) => {
this._pointMesh = result.mesh;
this.add(this._pointMesh);
@ -297,27 +323,15 @@ class GeoJSONLayer extends LayerGroup {
// Create and store mesh from buffer attributes
//
// TODO: Probably remove this and call static method directly as it's just a proxy
_setPolygonMesh(attributes, attributeLengths, flat) {
// TODO: Make this work when style is a function per feature
var style = (typeof this._options.style === 'function') ? this._options.style(this._geojson.features[0]) : this._options.style;
style = extend({}, GeoJSON.defaultStyle, style);
_setPolygonMesh(attributes, attributeLengths, style, flat) {
return PolygonLayer.SetMesh(attributes, attributeLengths, flat, style, this._options, this._world._environment._skybox);
}
_setPolylineMesh(attributes, attributeLengths, flat) {
// TODO: Make this work when style is a function per feature
var style = (typeof this._options.style === 'function') ? this._options.style(this._geojson.features[0]) : this._options.style;
style = extend({}, GeoJSON.defaultStyle, style);
_setPolylineMesh(attributes, attributeLengths, style, flat) {
return PolylineLayer.SetMesh(attributes, attributeLengths, flat, style, this._options);
}
_setPointMesh(attributes, attributeLengths, flat) {
// TODO: Make this work when style is a function per feature
var style = (typeof this._options.style === 'function') ? this._options.style(this._geojson.features[0]) : this._options.style;
style = extend({}, GeoJSON.defaultStyle, style);
_setPointMesh(attributes, attributeLengths, style, flat) {
return PointLayer.SetMesh(attributes, attributeLengths, flat, style, this._options);
}

Wyświetl plik

@ -283,11 +283,13 @@ class GeoJSONWorkerLayer extends Layer {
var outputPromises = [];
var style;
if (polygonAttributes.length > 0) {
var mergedPolygonAttributes = Buffer.mergeAttributes(polygonAttributes);
// TODO: Make this work when style is a function per feature
var style = (typeof this._options.style === 'function') ? this._options.style(objects[0]) : this._options.style;
style = (typeof this._options.style === 'function') ? this._options.style(objects[0]) : this._options.style;
style = extend({}, GeoJSON.defaultStyle, style);
outputPromises.push(this._setPolygonMesh(mergedPolygonAttributes, polygonAttributeLengths, style, polygonFlat));
@ -296,9 +298,19 @@ 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 = (typeof this._options.style === 'function') ? this._options.style(objects[0]) : this._options.style;
style = extend({}, GeoJSON.defaultStyle, style);
if (style.outlineRenderOrder !== undefined) {
style.lineRenderOrder = style.outlineRenderOrder;
} else {
style.lineRenderOrder = (style.renderOrder) ? style.renderOrder + 1 : 2;
}
if (style.outlineWidth) {
style.lineWidth = style.outlineWidth;
}
outputPromises.push(this._setPolylineMesh(mergedPolygonOutlineAttributes, polygonOutlineAttributeLengths, style, true));
}

Wyświetl plik

@ -404,7 +404,7 @@ class PolygonLayer extends Layer {
if (flat) {
material.depthWrite = false;
mesh.renderOrder = 1;
mesh.renderOrder = style.renderOrder || 1;
}
if (options.interactive) {

Wyświetl plik

@ -69,9 +69,10 @@ class ImageTile extends Tile {
localMesh.rotation.x = -90 * Math.PI / 180;
localMesh.receiveShadow = true;
localMesh.renderOrder = 0;
mesh.add(localMesh);
mesh.renderOrder = 0.1;
mesh.renderOrder = 0;
mesh.position.x = this._center[0];
mesh.position.z = this._center[1];

Wyświetl plik

@ -83,7 +83,7 @@ class ImageTileLayer extends TileLayer {
}
var mesh = new THREE.Mesh(geom, baseMaterial);
mesh.renderOrder = 0;
mesh.renderOrder = -1;
mesh.rotation.x = -90 * Math.PI / 180;
// TODO: It might be overkill to receive a shadow on the base layer as it's