Added layer click event and re-implemented feature styling

master
Robin Hawkes 2016-03-08 08:59:09 +00:00
rodzic 6d2ceba4d0
commit 2e0579bf4b
6 zmienionych plików z 157 dodań i 22 usunięć

83
dist/vizicities.js vendored
Wyświetl plik

@ -16344,11 +16344,20 @@ return /******/ (function(modules) { // webpackBootstrap
var defaults = {
output: false,
interactive: false,
topojson: false
topojson: false,
filter: null,
onEachFeature: null,
style: _utilGeoJSON2['default'].defaultStyle
};
var _options = (0, _lodashAssign2['default'])({}, defaults, options);
if (typeof options.style === 'function') {
_options.style = options.style;
} else {
_options.style = (0, _lodashAssign2['default'])({}, defaults.style, options.style);
}
_get(Object.getPrototypeOf(GeoJSONLayer2.prototype), 'constructor', this).call(this, _options);
this._geojson = geojson;
@ -16411,17 +16420,21 @@ return /******/ (function(modules) { // webpackBootstrap
}
var defaults = {};
var style = this._options.style;
var options;
features.forEach(function (feature) {
// Get style object, if provided
if (typeof _this2._options.style === 'function') {
style = (0, _lodashAssign2['default'])(_utilGeoJSON2['default'].defaultStyle, _this2._options.style(feature));
}
options = (0, _lodashAssign2['default'])({}, defaults, {
// If merging feature layers, stop them outputting themselves
// If not, let feature layers output themselves to the world
output: !_this2.isOutput(),
interactive: _this2._options.interactive,
style: {
color: '#ff0000'
}
style: style
});
var layer = _this2._featureToLayer(feature, options);
@ -16432,14 +16445,24 @@ return /******/ (function(modules) { // webpackBootstrap
layer.feature = feature;
// If defined, call a function for each feature
//
// This is commonly used for adding event listeners from the user script
if (_this2._options.onEachFeature) {
_this2._options.onEachFeature(feature, layer);
}
_this2.addLayer(layer);
});
// If merging layers do that now, otherwise skip
// If merging layers do that now, otherwise skip as the geometry layers
// should have already outputted themselves
if (!this.isOutput()) {
return;
}
// From here on we can assume that we want to merge the layers
var attributes = [];
var flat = true;
@ -16451,8 +16474,6 @@ return /******/ (function(modules) { // webpackBootstrap
}
});
// From here on we can assume that we want to merge the layers
var mergedAttributes = _utilBuffer2['default'].mergeAttributes(attributes);
this._setMesh(mergedAttributes, flat);
@ -16516,6 +16537,8 @@ return /******/ (function(modules) { // webpackBootstrap
this._mesh = mesh;
}
// TODO: Support all GeoJSON geometry types
}, {
key: '_featureToLayer',
value: function _featureToLayer(feature, options) {
@ -16530,11 +16553,32 @@ return /******/ (function(modules) { // webpackBootstrap
return (0, _geometryPolygonLayer.polygonLayer)(coordinates, options);
}
}
}, {
key: '_abortRequest',
value: function _abortRequest() {
if (!this._request) {
return;
}
this._request.abort();
}
// Destroy the layers and remove them from the scene and memory
}, {
key: 'destroy',
value: function destroy() {
// Cancel any pending requests
this._abortRequest();
// Clear request reference
this._request = null;
if (this._pickingMesh) {
// TODO: Properly dispose of picking mesh
this._pickingMesh = null;
}
// Run common destruction logic from parent
_get(Object.getPrototypeOf(GeoJSONLayer2.prototype), 'destroy', this).call(this);
}
}]);
@ -16743,19 +16787,27 @@ return /******/ (function(modules) { // webpackBootstrap
}
// Return center of polygon as a LatLon
//
// TODO: Implement getCenter()
}, {
key: 'getCenter',
value: function getCenter() {}
// Return polygon bounds in geographic coordinates
//
// TODO: Implement getBounds()
}, {
key: 'getBounds',
value: function getBounds() {}
// Get ID for picking interaction
}, {
key: '_setPickingId',
value: function _setPickingId() {
this._pickingId = this.getPickingId();
}
// Set up and re-emit interaction events
}, {
key: '_addPickingEvents',
value: function _addPickingEvents() {
@ -16763,7 +16815,8 @@ return /******/ (function(modules) { // webpackBootstrap
// TODO: Find a way to properly remove this listener on destroy
this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) {
console.log(_this, point2d, point3d, intersects);
// Re-emit click event from the layer
_this.emit('click', _this, point2d, point3d, intersects);
});
}
@ -16773,6 +16826,7 @@ return /******/ (function(modules) { // webpackBootstrap
value: function _setBufferAttributes() {
var height = 0;
// Convert height into world units
if (this._options.style.height && this._options.style.height !== 0) {
height = this._world.metresToWorld(this._options.style.height, this._pointScale);
}
@ -16927,6 +16981,8 @@ return /******/ (function(modules) { // webpackBootstrap
}
// Convert and project coordinates
//
// TODO: Calculate bounds
}, {
key: '_setCoordinates',
value: function _setCoordinates() {
@ -16940,6 +16996,8 @@ return /******/ (function(modules) { // webpackBootstrap
// Recursively convert input coordinates into LatLon objects
//
// Calculate geographic bounds at the same time
//
// TODO: Calculate geographic bounds
}, {
key: '_convertCoordinates',
value: function _convertCoordinates(coordinates) {
@ -16953,6 +17011,8 @@ return /******/ (function(modules) { // webpackBootstrap
// Recursively project coordinates into world positions
//
// Calculate world bounds, offset and pointScale at the same time
//
// TODO: Calculate world bounds
}, {
key: '_projectCoordinates',
value: function _projectCoordinates() {
@ -17000,6 +17060,8 @@ return /******/ (function(modules) { // webpackBootstrap
return result;
}
// Triangulate earcut-based input using earcut
}, {
key: '_triangulate',
value: function _triangulate(contour, holes, dim) {
@ -17016,6 +17078,9 @@ return /******/ (function(modules) { // webpackBootstrap
return result;
}
// Transform polygon representation into attribute arrays that can be used by
// THREE.BufferGeometry
}, {
key: '_toAttributes',
value: function _toAttributes(polygon) {
@ -17149,6 +17214,8 @@ return /******/ (function(modules) { // webpackBootstrap
return attributes;
}
// Returns true if the polygon is flat (has no height)
}, {
key: 'isFlat',
value: function isFlat() {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -22,8 +22,16 @@ VIZI.Controls.orbit().addTo(world);
// }).addTo(world);
var layer = VIZI.geoJSONLayer2('http://vector.mapzen.com/osm/buildings/13/4088/2722.json', {
output: false,
interactive: true
output: true,
interactive: true,
style: {
color: '#ff0000'
},
onEachFeature: function(feature, layer) {
layer.on('click', function(layer, point2d, point3d, intersects) {
console.log(layer, point2d, point3d, intersects);
});
}
}).addTo(world);
// // Building and roads from Mapzen (polygons and linestrings)

Wyświetl plik

@ -11,11 +11,20 @@ class GeoJSONLayer2 extends LayerGroup {
var defaults = {
output: false,
interactive: false,
topojson: false
topojson: false,
filter: null,
onEachFeature: null,
style: GeoJSON.defaultStyle
};
var _options = extend({}, defaults, options);
if (typeof options.style === 'function') {
_options.style = options.style;
} else {
_options.style = extend({}, defaults.style, options.style);
}
super(_options);
this._geojson = geojson;
@ -70,17 +79,21 @@ class GeoJSONLayer2 extends LayerGroup {
}
var defaults = {};
var style = this._options.style;
var options;
features.forEach(feature => {
// Get style object, if provided
if (typeof this._options.style === 'function') {
style = extend(GeoJSON.defaultStyle, this._options.style(feature));
}
options = extend({}, defaults, {
// If merging feature layers, stop them outputting themselves
// If not, let feature layers output themselves to the world
output: !this.isOutput(),
interactive: this._options.interactive,
style: {
color: '#ff0000'
}
style: style
});
var layer = this._featureToLayer(feature, options);
@ -91,14 +104,24 @@ class GeoJSONLayer2 extends LayerGroup {
layer.feature = feature;
// If defined, call a function for each feature
//
// This is commonly used for adding event listeners from the user script
if (this._options.onEachFeature) {
this._options.onEachFeature(feature, layer);
}
this.addLayer(layer);
});
// If merging layers do that now, otherwise skip
// If merging layers do that now, otherwise skip as the geometry layers
// should have already outputted themselves
if (!this.isOutput()) {
return;
}
// From here on we can assume that we want to merge the layers
var attributes = [];
var flat = true;
@ -110,8 +133,6 @@ class GeoJSONLayer2 extends LayerGroup {
}
});
// From here on we can assume that we want to merge the layers
var mergedAttributes = Buffer.mergeAttributes(attributes);
this._setMesh(mergedAttributes, flat);
@ -174,6 +195,7 @@ class GeoJSONLayer2 extends LayerGroup {
this._mesh = mesh;
}
// TODO: Support all GeoJSON geometry types
_featureToLayer(feature, options) {
var geometry = feature.geometry;
var coordinates = (geometry.coordinates) ? geometry.coordinates : null;
@ -187,8 +209,28 @@ class GeoJSONLayer2 extends LayerGroup {
}
}
_abortRequest() {
if (!this._request) {
return;
}
this._request.abort();
}
// Destroy the layers and remove them from the scene and memory
destroy() {
// Cancel any pending requests
this._abortRequest();
// Clear request reference
this._request = null;
if (this._pickingMesh) {
// TODO: Properly dispose of picking mesh
this._pickingMesh = null;
}
// Run common destruction logic from parent
super.destroy();
}
}

Wyświetl plik

@ -58,19 +58,26 @@ class PolygonLayer extends Layer {
}
// Return center of polygon as a LatLon
//
// TODO: Implement getCenter()
getCenter() {}
// Return polygon bounds in geographic coordinates
//
// TODO: Implement getBounds()
getBounds() {}
// Get ID for picking interaction
_setPickingId() {
this._pickingId = this.getPickingId();
}
// Set up and re-emit interaction events
_addPickingEvents() {
// TODO: Find a way to properly remove this listener on destroy
this._world.on('pick-' + this._pickingId, (point2d, point3d, intersects) => {
console.log(this, point2d, point3d, intersects);
// Re-emit click event from the layer
this.emit('click', this, point2d, point3d, intersects);
});
}
@ -78,6 +85,7 @@ class PolygonLayer extends Layer {
_setBufferAttributes() {
var height = 0;
// Convert height into world units
if (this._options.style.height && this._options.style.height !== 0) {
height = this._world.metresToWorld(this._options.style.height, this._pointScale);
}
@ -229,6 +237,8 @@ class PolygonLayer extends Layer {
}
// Convert and project coordinates
//
// TODO: Calculate bounds
_setCoordinates() {
this._bounds = [];
this._coordinates = this._convertCoordinates(this._coordinates);
@ -240,6 +250,8 @@ class PolygonLayer extends Layer {
// Recursively convert input coordinates into LatLon objects
//
// Calculate geographic bounds at the same time
//
// TODO: Calculate geographic bounds
_convertCoordinates(coordinates) {
return coordinates.map(ring => {
return ring.map(coordinate => {
@ -251,6 +263,8 @@ class PolygonLayer extends Layer {
// Recursively project coordinates into world positions
//
// Calculate world bounds, offset and pointScale at the same time
//
// TODO: Calculate world bounds
_projectCoordinates() {
var point;
return this._coordinates.map(ring => {
@ -293,6 +307,7 @@ class PolygonLayer extends Layer {
return result;
}
// Triangulate earcut-based input using earcut
_triangulate(contour, holes, dim) {
// console.time('earcut');
@ -308,6 +323,8 @@ class PolygonLayer extends Layer {
return result;
}
// Transform polygon representation into attribute arrays that can be used by
// THREE.BufferGeometry
_toAttributes(polygon) {
// Three components per vertex per face (3 x 3 = 9)
var vertices = new Float32Array(polygon.facesCount * 9);
@ -440,6 +457,7 @@ class PolygonLayer extends Layer {
return attributes;
}
// Returns true if the polygon is flat (has no height)
isFlat() {
return this._flat;
}