kopia lustrzana https://github.com/robhawkes/vizicities
Working PolylineLayer implementation
rodzic
eaa9759acc
commit
cb4f9ba19a
|
@ -96,7 +96,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
|
||||
var _layerGeoJSONLayer23 = _interopRequireDefault(_layerGeoJSONLayer22);
|
||||
|
||||
var _layerTopoJSONLayer = __webpack_require__(79);
|
||||
var _layerTopoJSONLayer = __webpack_require__(80);
|
||||
|
||||
var _layerTopoJSONLayer2 = _interopRequireDefault(_layerTopoJSONLayer);
|
||||
|
||||
|
@ -104,6 +104,10 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
|
||||
var _layerGeometryPolygonLayer2 = _interopRequireDefault(_layerGeometryPolygonLayer);
|
||||
|
||||
var _layerGeometryPolylineLayer = __webpack_require__(79);
|
||||
|
||||
var _layerGeometryPolylineLayer2 = _interopRequireDefault(_layerGeometryPolylineLayer);
|
||||
|
||||
var _geoPoint = __webpack_require__(11);
|
||||
|
||||
var _geoPoint2 = _interopRequireDefault(_geoPoint);
|
||||
|
@ -137,6 +141,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
topoJSONLayer: _layerTopoJSONLayer.topoJSONLayer,
|
||||
PolygonLayer: _layerGeometryPolygonLayer2['default'],
|
||||
polygonLayer: _layerGeometryPolygonLayer.polygonLayer,
|
||||
PolylineLayer: _layerGeometryPolylineLayer2['default'],
|
||||
polylineLayer: _layerGeometryPolylineLayer.polylineLayer,
|
||||
Point: _geoPoint2['default'],
|
||||
point: _geoPoint.point,
|
||||
LatLon: _geoLatLon2['default'],
|
||||
|
@ -16337,6 +16343,10 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
|
||||
var _geometryPolygonLayer2 = _interopRequireDefault(_geometryPolygonLayer);
|
||||
|
||||
var _geometryPolylineLayer = __webpack_require__(79);
|
||||
|
||||
var _geometryPolylineLayer2 = _interopRequireDefault(_geometryPolylineLayer);
|
||||
|
||||
var GeoJSONLayer2 = (function (_LayerGroup) {
|
||||
_inherits(GeoJSONLayer2, _LayerGroup);
|
||||
|
||||
|
@ -16473,6 +16483,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
var polygonAttributes = [];
|
||||
var polygonFlat = true;
|
||||
|
||||
var polylineAttributes = [];
|
||||
|
||||
this._layers.forEach(function (layer) {
|
||||
if (layer instanceof _geometryPolygonLayer2['default']) {
|
||||
polygonAttributes.push(layer.getBufferAttributes());
|
||||
|
@ -16480,13 +16492,19 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
if (polygonFlat && !layer.isFlat()) {
|
||||
polygonFlat = false;
|
||||
}
|
||||
} else if (layer instanceof _geometryPolylineLayer2['default']) {
|
||||
polylineAttributes.push(layer.getBufferAttributes());
|
||||
}
|
||||
});
|
||||
|
||||
var mergedPolygonAttributes = _utilBuffer2['default'].mergeAttributes(polygonAttributes);
|
||||
var mergedPolylineAttributes = _utilBuffer2['default'].mergeAttributes(polylineAttributes);
|
||||
|
||||
this._setPolygonMesh(mergedPolygonAttributes, polygonFlat);
|
||||
this.add(this._mesh);
|
||||
this.add(this._polygonMesh);
|
||||
|
||||
this._setPolylineMesh(mergedPolylineAttributes);
|
||||
this.add(this._polylineMesh);
|
||||
}
|
||||
|
||||
// Create and store mesh from buffer attributes
|
||||
|
@ -16544,7 +16562,55 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
this._pickingMesh.add(pickingMesh);
|
||||
}
|
||||
|
||||
this._mesh = mesh;
|
||||
this._polygonMesh = mesh;
|
||||
}
|
||||
}, {
|
||||
key: '_setPolylineMesh',
|
||||
value: function _setPolylineMesh(attributes) {
|
||||
var geometry = new THREE.BufferGeometry();
|
||||
|
||||
// itemSize = 3 because there are 3 values (components) per vertex
|
||||
geometry.addAttribute('position', new THREE.BufferAttribute(attributes.vertices, 3));
|
||||
geometry.addAttribute('color', new THREE.BufferAttribute(attributes.colours, 3));
|
||||
|
||||
if (attributes.pickingIds) {
|
||||
geometry.addAttribute('pickingId', new THREE.BufferAttribute(attributes.pickingIds, 1));
|
||||
}
|
||||
|
||||
geometry.computeBoundingBox();
|
||||
|
||||
// TODO: Make this work when style is a function per feature
|
||||
var style = this._options.style;
|
||||
var material = new THREE.LineBasicMaterial({
|
||||
vertexColors: THREE.VertexColors,
|
||||
linewidth: style.lineWidth,
|
||||
transparent: style.lineTransparent,
|
||||
opacity: style.lineOpacity,
|
||||
blending: style.lineBlending
|
||||
});
|
||||
|
||||
var mesh = new THREE.LineSegments(geometry, material);
|
||||
|
||||
if (style.lineRenderOrder !== undefined) {
|
||||
material.depthWrite = false;
|
||||
mesh.renderOrder = style.lineRenderOrder;
|
||||
}
|
||||
|
||||
// TODO: Can a line cast a shadow?
|
||||
// mesh.castShadow = true;
|
||||
|
||||
if (this._options.interactive && this._pickingMesh) {
|
||||
material = new _enginePickingMaterial2['default']();
|
||||
material.side = THREE.BackSide;
|
||||
|
||||
// Make the line wider / easier to pick
|
||||
material.linewidth = style.lineWidth + material.linePadding;
|
||||
|
||||
var pickingMesh = new THREE.LineSegments(geometry, material);
|
||||
this._pickingMesh.add(pickingMesh);
|
||||
}
|
||||
|
||||
this._polylineMesh = mesh;
|
||||
}
|
||||
|
||||
// TODO: Support all GeoJSON geometry types
|
||||
|
@ -16558,12 +16624,12 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
return;
|
||||
}
|
||||
|
||||
if (geometry.type === 'Polygon') {
|
||||
if (geometry.type === 'Polygon' || geometry.type === 'MultiPolygon') {
|
||||
return new _geometryPolygonLayer2['default'](coordinates, options);
|
||||
}
|
||||
|
||||
if (geometry.type === 'LineString' || geometry.type === 'MultiLineString') {
|
||||
return new PolylineLayer(coordinates, options);
|
||||
return new _geometryPolylineLayer2['default'](coordinates, options);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
|
@ -16715,7 +16781,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||
|
||||
// TODO: Fire click event when this feature is picked
|
||||
// TODO: Move duplicated logic between geometry layrs into GeometryLayer
|
||||
|
||||
var _Layer2 = __webpack_require__(37);
|
||||
|
||||
|
@ -16725,6 +16791,10 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
|
||||
var _lodashAssign2 = _interopRequireDefault(_lodashAssign);
|
||||
|
||||
var _three = __webpack_require__(24);
|
||||
|
||||
var _three2 = _interopRequireDefault(_three);
|
||||
|
||||
var _geoLatLon = __webpack_require__(10);
|
||||
|
||||
var _geoPoint = __webpack_require__(11);
|
||||
|
@ -16782,7 +16852,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
// Otherwise, assume another component will eventually add a mesh to
|
||||
// the picking scene
|
||||
if (this.isOutput()) {
|
||||
this._pickingMesh = new THREE.Object3D();
|
||||
this._pickingMesh = new _three2['default'].Object3D();
|
||||
this.addToPicking(this._pickingMesh);
|
||||
}
|
||||
|
||||
|
@ -16811,7 +16881,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
}, {
|
||||
key: 'getCenter',
|
||||
value: function getCenter() {
|
||||
return this._coordinates[0][0];
|
||||
return this._coordinates[0][0][0];
|
||||
}
|
||||
|
||||
// Return polygon bounds in geographic coordinates
|
||||
|
@ -16854,12 +16924,12 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
height = this._world.metresToWorld(this._options.style.height, this._pointScale);
|
||||
}
|
||||
|
||||
var colour = new THREE.Color();
|
||||
var colour = new _three2['default'].Color();
|
||||
colour.set(this._options.style.color);
|
||||
|
||||
// Light and dark colours used for poor-mans AO gradient on object sides
|
||||
var light = new THREE.Color(0xffffff);
|
||||
var shadow = new THREE.Color(0x666666);
|
||||
var light = new _three2['default'].Color(0xffffff);
|
||||
var shadow = new _three2['default'].Color(0x666666);
|
||||
|
||||
// For each polygon
|
||||
var attributes = this._projectedCoordinates.map(function (_projectedCoordinates) {
|
||||
|
@ -16958,29 +17028,29 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
}, {
|
||||
key: '_setMesh',
|
||||
value: function _setMesh(attributes) {
|
||||
var geometry = new THREE.BufferGeometry();
|
||||
var geometry = new _three2['default'].BufferGeometry();
|
||||
|
||||
// itemSize = 3 because there are 3 values (components) per vertex
|
||||
geometry.addAttribute('position', new THREE.BufferAttribute(attributes.vertices, 3));
|
||||
geometry.addAttribute('normal', new THREE.BufferAttribute(attributes.normals, 3));
|
||||
geometry.addAttribute('color', new THREE.BufferAttribute(attributes.colours, 3));
|
||||
geometry.addAttribute('position', new _three2['default'].BufferAttribute(attributes.vertices, 3));
|
||||
geometry.addAttribute('normal', new _three2['default'].BufferAttribute(attributes.normals, 3));
|
||||
geometry.addAttribute('color', new _three2['default'].BufferAttribute(attributes.colours, 3));
|
||||
|
||||
if (attributes.pickingIds) {
|
||||
geometry.addAttribute('pickingId', new THREE.BufferAttribute(attributes.pickingIds, 1));
|
||||
geometry.addAttribute('pickingId', new _three2['default'].BufferAttribute(attributes.pickingIds, 1));
|
||||
}
|
||||
|
||||
geometry.computeBoundingBox();
|
||||
|
||||
var material;
|
||||
if (!this._world._environment._skybox) {
|
||||
material = new THREE.MeshPhongMaterial({
|
||||
vertexColors: THREE.VertexColors,
|
||||
side: THREE.BackSide
|
||||
material = new _three2['default'].MeshPhongMaterial({
|
||||
vertexColors: _three2['default'].VertexColors,
|
||||
side: _three2['default'].BackSide
|
||||
});
|
||||
} else {
|
||||
material = new THREE.MeshStandardMaterial({
|
||||
vertexColors: THREE.VertexColors,
|
||||
side: THREE.BackSide
|
||||
material = new _three2['default'].MeshStandardMaterial({
|
||||
vertexColors: _three2['default'].VertexColors,
|
||||
side: _three2['default'].BackSide
|
||||
});
|
||||
material.roughness = 1;
|
||||
material.metalness = 0.1;
|
||||
|
@ -16988,7 +17058,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
material.envMap = this._world._environment._skybox.getRenderTarget();
|
||||
}
|
||||
|
||||
mesh = new THREE.Mesh(geometry, material);
|
||||
var mesh = new _three2['default'].Mesh(geometry, material);
|
||||
|
||||
mesh.castShadow = true;
|
||||
mesh.receiveShadow = true;
|
||||
|
@ -17000,9 +17070,9 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
|
||||
if (this._options.interactive && this._pickingMesh) {
|
||||
material = new _enginePickingMaterial2['default']();
|
||||
material.side = THREE.BackSide;
|
||||
material.side = _three2['default'].BackSide;
|
||||
|
||||
var pickingMesh = new THREE.Mesh(geometry, material);
|
||||
var pickingMesh = new _three2['default'].Mesh(geometry, material);
|
||||
this._pickingMesh.add(pickingMesh);
|
||||
}
|
||||
|
||||
|
@ -17130,12 +17200,12 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
pickingIds = new Float32Array(polygon.facesCount * 3);
|
||||
}
|
||||
|
||||
var pA = new THREE.Vector3();
|
||||
var pB = new THREE.Vector3();
|
||||
var pC = new THREE.Vector3();
|
||||
var pA = new _three2['default'].Vector3();
|
||||
var pB = new _three2['default'].Vector3();
|
||||
var pC = new _three2['default'].Vector3();
|
||||
|
||||
var cb = new THREE.Vector3();
|
||||
var ab = new THREE.Vector3();
|
||||
var cb = new _three2['default'].Vector3();
|
||||
var ab = new _three2['default'].Vector3();
|
||||
|
||||
var index;
|
||||
|
||||
|
@ -17297,6 +17367,419 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
value: true
|
||||
});
|
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||
|
||||
// TODO: Move duplicated logic between geometry layrs into GeometryLayer
|
||||
|
||||
var _Layer2 = __webpack_require__(37);
|
||||
|
||||
var _Layer3 = _interopRequireDefault(_Layer2);
|
||||
|
||||
var _lodashAssign = __webpack_require__(3);
|
||||
|
||||
var _lodashAssign2 = _interopRequireDefault(_lodashAssign);
|
||||
|
||||
var _three = __webpack_require__(24);
|
||||
|
||||
var _three2 = _interopRequireDefault(_three);
|
||||
|
||||
var _geoLatLon = __webpack_require__(10);
|
||||
|
||||
var _geoPoint = __webpack_require__(11);
|
||||
|
||||
var _enginePickingMaterial = __webpack_require__(72);
|
||||
|
||||
var _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);
|
||||
|
||||
var _utilBuffer = __webpack_require__(71);
|
||||
|
||||
var _utilBuffer2 = _interopRequireDefault(_utilBuffer);
|
||||
|
||||
var PolylineLayer = (function (_Layer) {
|
||||
_inherits(PolylineLayer, _Layer);
|
||||
|
||||
function PolylineLayer(coordinates, options) {
|
||||
_classCallCheck(this, PolylineLayer);
|
||||
|
||||
var defaults = {
|
||||
output: true,
|
||||
interactive: false,
|
||||
// This default style is separate to Util.GeoJSON.defaultStyle
|
||||
style: {
|
||||
lineOpacity: 1,
|
||||
lineTransparent: false,
|
||||
lineColor: '#ffffff',
|
||||
lineWidth: 1,
|
||||
lineBlending: _three2['default'].NormalBlending
|
||||
}
|
||||
};
|
||||
|
||||
var _options = (0, _lodashAssign2['default'])({}, defaults, options);
|
||||
|
||||
_get(Object.getPrototypeOf(PolylineLayer.prototype), 'constructor', this).call(this, _options);
|
||||
|
||||
// Return coordinates as arrays of lines so it's easy to support
|
||||
// MultiLineString features (a single line would be a MultiLineString with a
|
||||
// single line in the array)
|
||||
this._coordinates = PolylineLayer.isSingle(coordinates) ? [coordinates] : coordinates;
|
||||
|
||||
// Polyline features are always flat (for now at least)
|
||||
this._flat = true;
|
||||
}
|
||||
|
||||
_createClass(PolylineLayer, [{
|
||||
key: '_onAdd',
|
||||
value: function _onAdd(world) {
|
||||
this._setCoordinates();
|
||||
|
||||
if (this._options.interactive) {
|
||||
// Only add to picking mesh if this layer is controlling output
|
||||
//
|
||||
// Otherwise, assume another component will eventually add a mesh to
|
||||
// the picking scene
|
||||
if (this.isOutput()) {
|
||||
this._pickingMesh = new _three2['default'].Object3D();
|
||||
this.addToPicking(this._pickingMesh);
|
||||
}
|
||||
|
||||
this._setPickingId();
|
||||
this._addPickingEvents();
|
||||
}
|
||||
|
||||
// Store geometry representation as instances of THREE.BufferAttribute
|
||||
this._setBufferAttributes();
|
||||
|
||||
if (this.isOutput()) {
|
||||
// Set mesh if not merging elsewhere
|
||||
this._setMesh(this._bufferAttributes);
|
||||
|
||||
// Output mesh
|
||||
this.add(this._mesh);
|
||||
}
|
||||
}
|
||||
|
||||
// Return center of polyline as a LatLon
|
||||
//
|
||||
// This is used for things like placing popups / UI elements on the layer
|
||||
//
|
||||
// TODO: Find proper center position instead of returning first coordinate
|
||||
// SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polyline.js#L59
|
||||
}, {
|
||||
key: 'getCenter',
|
||||
value: function getCenter() {
|
||||
return this._coordinates[0][0];
|
||||
}
|
||||
|
||||
// Return line bounds in geographic coordinates
|
||||
//
|
||||
// TODO: Implement getBounds()
|
||||
}, {
|
||||
key: 'getBounds',
|
||||
value: function getBounds() {}
|
||||
|
||||
// Get unique 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() {
|
||||
var _this = this;
|
||||
|
||||
// TODO: Find a way to properly remove this listener on destroy
|
||||
this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) {
|
||||
// Re-emit click event from the layer
|
||||
_this.emit('click', _this, point2d, point3d, intersects);
|
||||
});
|
||||
}
|
||||
|
||||
// Create and store reference to THREE.BufferAttribute data for this layer
|
||||
}, {
|
||||
key: '_setBufferAttributes',
|
||||
value: function _setBufferAttributes() {
|
||||
var _this2 = this;
|
||||
|
||||
var height = 0;
|
||||
|
||||
// Convert height into world units
|
||||
if (this._options.style.lineHeight) {
|
||||
height = this._world.metresToWorld(this._options.style.lineHeight, this._pointScale);
|
||||
}
|
||||
|
||||
var colour = new _three2['default'].Color();
|
||||
colour.set(this._options.style.color);
|
||||
|
||||
// For each line
|
||||
var attributes = this._projectedCoordinates.map(function (_projectedCoordinates) {
|
||||
var _vertices = [];
|
||||
var _colours = [];
|
||||
|
||||
// Connect coordinate with the next to make a pair
|
||||
//
|
||||
// LineSegments requires pairs of vertices so repeat the last point if
|
||||
// there's an odd number of vertices
|
||||
var nextCoord;
|
||||
_projectedCoordinates.forEach(function (coordinate, index) {
|
||||
_colours.push([colour.r, colour.g, colour.b]);
|
||||
_vertices.push([coordinate.x, height, coordinate.y]);
|
||||
|
||||
nextCoord = _projectedCoordinates[index + 1] ? _projectedCoordinates[index + 1] : coordinate;
|
||||
|
||||
_colours.push([colour.r, colour.g, colour.b]);
|
||||
_vertices.push([nextCoord.x, height, nextCoord.y]);
|
||||
});
|
||||
|
||||
var line = {
|
||||
vertices: _vertices,
|
||||
colours: _colours,
|
||||
verticesCount: _vertices.length
|
||||
};
|
||||
|
||||
if (_this2._options.interactive && _this2._pickingId) {
|
||||
// Inject picking ID
|
||||
line.pickingId = _this2._pickingId;
|
||||
}
|
||||
|
||||
// Convert line representation to proper attribute arrays
|
||||
return _this2._toAttributes(line);
|
||||
});
|
||||
|
||||
this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(attributes);
|
||||
}
|
||||
}, {
|
||||
key: 'getBufferAttributes',
|
||||
value: function getBufferAttributes() {
|
||||
return this._bufferAttributes;
|
||||
}
|
||||
|
||||
// Create and store mesh from buffer attributes
|
||||
//
|
||||
// This is only called if the layer is controlling its own output
|
||||
}, {
|
||||
key: '_setMesh',
|
||||
value: function _setMesh(attributes) {
|
||||
var geometry = new _three2['default'].BufferGeometry();
|
||||
|
||||
// itemSize = 3 because there are 3 values (components) per vertex
|
||||
geometry.addAttribute('position', new _three2['default'].BufferAttribute(attributes.vertices, 3));
|
||||
geometry.addAttribute('color', new _three2['default'].BufferAttribute(attributes.colours, 3));
|
||||
|
||||
if (attributes.pickingIds) {
|
||||
geometry.addAttribute('pickingId', new _three2['default'].BufferAttribute(attributes.pickingIds, 1));
|
||||
}
|
||||
|
||||
geometry.computeBoundingBox();
|
||||
|
||||
var style = this._options.style;
|
||||
var material = new _three2['default'].LineBasicMaterial({
|
||||
vertexColors: _three2['default'].VertexColors,
|
||||
linewidth: style.lineWidth,
|
||||
transparent: style.lineTransparent,
|
||||
opacity: style.lineOpacity,
|
||||
blending: style.lineBlending
|
||||
});
|
||||
|
||||
var mesh = new _three2['default'].LineSegments(geometry, material);
|
||||
|
||||
if (style.lineRenderOrder !== undefined) {
|
||||
material.depthWrite = false;
|
||||
mesh.renderOrder = style.lineRenderOrder;
|
||||
}
|
||||
|
||||
// TODO: Can a line cast a shadow?
|
||||
// mesh.castShadow = true;
|
||||
|
||||
if (this._options.interactive && this._pickingMesh) {
|
||||
material = new _enginePickingMaterial2['default']();
|
||||
material.side = _three2['default'].BackSide;
|
||||
|
||||
// Make the line wider / easier to pick
|
||||
material.linewidth = style.lineWidth + material.linePadding;
|
||||
|
||||
var pickingMesh = new _three2['default'].LineSegments(geometry, material);
|
||||
this._pickingMesh.add(pickingMesh);
|
||||
}
|
||||
|
||||
this._mesh = mesh;
|
||||
}
|
||||
|
||||
// Convert and project coordinates
|
||||
//
|
||||
// TODO: Calculate bounds
|
||||
}, {
|
||||
key: '_setCoordinates',
|
||||
value: function _setCoordinates() {
|
||||
this._bounds = [];
|
||||
this._coordinates = this._convertCoordinates(this._coordinates);
|
||||
|
||||
this._projectedBounds = [];
|
||||
this._projectedCoordinates = this._projectCoordinates();
|
||||
}
|
||||
|
||||
// Recursively convert input coordinates into LatLon objects
|
||||
//
|
||||
// Calculate geographic bounds at the same time
|
||||
//
|
||||
// TODO: Calculate geographic bounds
|
||||
}, {
|
||||
key: '_convertCoordinates',
|
||||
value: function _convertCoordinates(coordinates) {
|
||||
return coordinates.map(function (_coordinates) {
|
||||
return _coordinates.map(function (coordinate) {
|
||||
return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 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() {
|
||||
var _this3 = this;
|
||||
|
||||
var point;
|
||||
return this._coordinates.map(function (_coordinates) {
|
||||
return _coordinates.map(function (latlon) {
|
||||
point = _this3._world.latLonToPoint(latlon);
|
||||
|
||||
// TODO: Is offset ever being used or needed?
|
||||
if (!_this3._offset) {
|
||||
_this3._offset = (0, _geoPoint.point)(0, 0);
|
||||
_this3._offset.x = -1 * point.x;
|
||||
_this3._offset.y = -1 * point.y;
|
||||
|
||||
_this3._pointScale = _this3._world.pointScale(latlon);
|
||||
}
|
||||
|
||||
return point;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Transform line representation into attribute arrays that can be used by
|
||||
// THREE.BufferGeometry
|
||||
//
|
||||
// TODO: Can this be simplified? It's messy and huge
|
||||
}, {
|
||||
key: '_toAttributes',
|
||||
value: function _toAttributes(line) {
|
||||
// Three components per vertex
|
||||
var vertices = new Float32Array(line.verticesCount * 3);
|
||||
var colours = new Float32Array(line.verticesCount * 3);
|
||||
|
||||
var pickingIds;
|
||||
if (line.pickingId) {
|
||||
// One component per vertex
|
||||
pickingIds = new Float32Array(line.verticesCount);
|
||||
}
|
||||
|
||||
var _vertices = line.vertices;
|
||||
var _colour = line.colours;
|
||||
|
||||
var _pickingId;
|
||||
if (pickingIds) {
|
||||
_pickingId = line.pickingId;
|
||||
}
|
||||
|
||||
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[i];
|
||||
|
||||
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];
|
||||
|
||||
if (pickingIds) {
|
||||
pickingIds[lastIndex] = _pickingId;
|
||||
}
|
||||
|
||||
lastIndex++;
|
||||
}
|
||||
|
||||
var attributes = {
|
||||
vertices: vertices,
|
||||
colours: colours
|
||||
};
|
||||
|
||||
if (pickingIds) {
|
||||
attributes.pickingIds = pickingIds;
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
// Returns true if the line is flat (has no height)
|
||||
}, {
|
||||
key: 'isFlat',
|
||||
value: function isFlat() {
|
||||
return this._flat;
|
||||
}
|
||||
|
||||
// Returns true if coordinates refer to a single geometry
|
||||
//
|
||||
// For example, coordinates for a MultiLineString GeoJSON feature
|
||||
}, {
|
||||
key: 'destroy',
|
||||
value: function destroy() {
|
||||
if (this._pickingMesh) {
|
||||
// TODO: Properly dispose of picking mesh
|
||||
this._pickingMesh = null;
|
||||
}
|
||||
|
||||
// Run common destruction logic from parent
|
||||
_get(Object.getPrototypeOf(PolylineLayer.prototype), 'destroy', this).call(this);
|
||||
}
|
||||
}], [{
|
||||
key: 'isSingle',
|
||||
value: function isSingle(coordinates) {
|
||||
return !Array.isArray(coordinates[0][0]);
|
||||
}
|
||||
}]);
|
||||
|
||||
return PolylineLayer;
|
||||
})(_Layer3['default']);
|
||||
|
||||
exports['default'] = PolylineLayer;
|
||||
|
||||
var noNew = function noNew(coordinates, options) {
|
||||
return new PolylineLayer(coordinates, options);
|
||||
};
|
||||
|
||||
exports.polylineLayer = noNew;
|
||||
|
||||
/***/ },
|
||||
/* 80 */
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
Object.defineProperty(exports, '__esModule', {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -21,7 +21,7 @@ VIZI.Controls.orbit().addTo(world);
|
|||
// }
|
||||
// }).addTo(world);
|
||||
|
||||
var layer = VIZI.geoJSONLayer2('http://vector.mapzen.com/osm/buildings/13/4088/2722.json', {
|
||||
var layer = VIZI.geoJSONLayer2('http://vector.mapzen.com/osm/buildings,roads/13/4088/2722.json', {
|
||||
output: true,
|
||||
interactive: true,
|
||||
style: {
|
||||
|
|
|
@ -5,6 +5,7 @@ import GeoJSON from '../util/GeoJSON';
|
|||
import Buffer from '../util/Buffer';
|
||||
import PickingMaterial from '../engine/PickingMaterial';
|
||||
import PolygonLayer from './geometry/PolygonLayer';
|
||||
import PolylineLayer from './geometry/PolylineLayer';
|
||||
|
||||
class GeoJSONLayer2 extends LayerGroup {
|
||||
constructor(geojson, options) {
|
||||
|
@ -130,6 +131,8 @@ class GeoJSONLayer2 extends LayerGroup {
|
|||
var polygonAttributes = [];
|
||||
var polygonFlat = true;
|
||||
|
||||
var polylineAttributes = [];
|
||||
|
||||
this._layers.forEach(layer => {
|
||||
if (layer instanceof PolygonLayer) {
|
||||
polygonAttributes.push(layer.getBufferAttributes());
|
||||
|
@ -137,13 +140,19 @@ class GeoJSONLayer2 extends LayerGroup {
|
|||
if (polygonFlat && !layer.isFlat()) {
|
||||
polygonFlat = false;
|
||||
}
|
||||
} else if (layer instanceof PolylineLayer) {
|
||||
polylineAttributes.push(layer.getBufferAttributes());
|
||||
}
|
||||
});
|
||||
|
||||
var mergedPolygonAttributes = Buffer.mergeAttributes(polygonAttributes);
|
||||
var mergedPolylineAttributes = Buffer.mergeAttributes(polylineAttributes);
|
||||
|
||||
this._setPolygonMesh(mergedPolygonAttributes, polygonFlat);
|
||||
this.add(this._mesh);
|
||||
this.add(this._polygonMesh);
|
||||
|
||||
this._setPolylineMesh(mergedPolylineAttributes);
|
||||
this.add(this._polylineMesh);
|
||||
}
|
||||
|
||||
// Create and store mesh from buffer attributes
|
||||
|
@ -199,7 +208,54 @@ class GeoJSONLayer2 extends LayerGroup {
|
|||
this._pickingMesh.add(pickingMesh);
|
||||
}
|
||||
|
||||
this._mesh = mesh;
|
||||
this._polygonMesh = mesh;
|
||||
}
|
||||
|
||||
_setPolylineMesh(attributes) {
|
||||
var geometry = new THREE.BufferGeometry();
|
||||
|
||||
// itemSize = 3 because there are 3 values (components) per vertex
|
||||
geometry.addAttribute('position', new THREE.BufferAttribute(attributes.vertices, 3));
|
||||
geometry.addAttribute('color', new THREE.BufferAttribute(attributes.colours, 3));
|
||||
|
||||
if (attributes.pickingIds) {
|
||||
geometry.addAttribute('pickingId', new THREE.BufferAttribute(attributes.pickingIds, 1));
|
||||
}
|
||||
|
||||
geometry.computeBoundingBox();
|
||||
|
||||
// TODO: Make this work when style is a function per feature
|
||||
var style = this._options.style;
|
||||
var material = new THREE.LineBasicMaterial({
|
||||
vertexColors: THREE.VertexColors,
|
||||
linewidth: style.lineWidth,
|
||||
transparent: style.lineTransparent,
|
||||
opacity: style.lineOpacity,
|
||||
blending: style.lineBlending
|
||||
});
|
||||
|
||||
var mesh = new THREE.LineSegments(geometry, material);
|
||||
|
||||
if (style.lineRenderOrder !== undefined) {
|
||||
material.depthWrite = false;
|
||||
mesh.renderOrder = style.lineRenderOrder;
|
||||
}
|
||||
|
||||
// TODO: Can a line cast a shadow?
|
||||
// mesh.castShadow = true;
|
||||
|
||||
if (this._options.interactive && this._pickingMesh) {
|
||||
material = new PickingMaterial();
|
||||
material.side = THREE.BackSide;
|
||||
|
||||
// Make the line wider / easier to pick
|
||||
material.linewidth = style.lineWidth + material.linePadding;
|
||||
|
||||
var pickingMesh = new THREE.LineSegments(geometry, material);
|
||||
this._pickingMesh.add(pickingMesh);
|
||||
}
|
||||
|
||||
this._polylineMesh = mesh;
|
||||
}
|
||||
|
||||
// TODO: Support all GeoJSON geometry types
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
// TODO: Fire click event when this feature is picked
|
||||
// TODO: Move duplicated logic between geometry layrs into GeometryLayer
|
||||
|
||||
// TODO: Look at ways to drop unneeded references to array buffers, etc to
|
||||
// reduce memory footprint
|
||||
|
||||
import Layer from '../Layer';
|
||||
import extend from 'lodash.assign';
|
||||
import THREE from 'three';
|
||||
import {latLon as LatLon} from '../../geo/LatLon';
|
||||
import {point as Point} from '../../geo/Point';
|
||||
import earcut from 'earcut';
|
||||
|
@ -67,7 +71,7 @@ class PolygonLayer extends Layer {
|
|||
// TODO: Find proper center position instead of returning first coordinate
|
||||
// SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polygon.js#L15
|
||||
getCenter() {
|
||||
return this._coordinates[0][0];
|
||||
return this._coordinates[0][0][0];
|
||||
}
|
||||
|
||||
// Return polygon bounds in geographic coordinates
|
||||
|
@ -229,7 +233,7 @@ class PolygonLayer extends Layer {
|
|||
material.envMap = this._world._environment._skybox.getRenderTarget();
|
||||
}
|
||||
|
||||
mesh = new THREE.Mesh(geometry, material);
|
||||
var mesh = new THREE.Mesh(geometry, material);
|
||||
|
||||
mesh.castShadow = true;
|
||||
mesh.receiveShadow = true;
|
||||
|
|
|
@ -0,0 +1,340 @@
|
|||
// TODO: Move duplicated logic between geometry layrs into GeometryLayer
|
||||
|
||||
// TODO: Look at ways to drop unneeded references to array buffers, etc to
|
||||
// reduce memory footprint
|
||||
|
||||
import Layer from '../Layer';
|
||||
import extend from 'lodash.assign';
|
||||
import THREE from 'three';
|
||||
import {latLon as LatLon} from '../../geo/LatLon';
|
||||
import {point as Point} from '../../geo/Point';
|
||||
import PickingMaterial from '../../engine/PickingMaterial';
|
||||
import Buffer from '../../util/Buffer';
|
||||
|
||||
class PolylineLayer extends Layer {
|
||||
constructor(coordinates, options) {
|
||||
var defaults = {
|
||||
output: true,
|
||||
interactive: false,
|
||||
// This default style is separate to Util.GeoJSON.defaultStyle
|
||||
style: {
|
||||
lineOpacity: 1,
|
||||
lineTransparent: false,
|
||||
lineColor: '#ffffff',
|
||||
lineWidth: 1,
|
||||
lineBlending: THREE.NormalBlending
|
||||
}
|
||||
};
|
||||
|
||||
var _options = extend({}, defaults, options);
|
||||
|
||||
super(_options);
|
||||
|
||||
// Return coordinates as arrays of lines so it's easy to support
|
||||
// MultiLineString features (a single line would be a MultiLineString with a
|
||||
// single line in the array)
|
||||
this._coordinates = (PolylineLayer.isSingle(coordinates)) ? [coordinates] : coordinates;
|
||||
|
||||
// Polyline features are always flat (for now at least)
|
||||
this._flat = true;
|
||||
}
|
||||
|
||||
_onAdd(world) {
|
||||
this._setCoordinates();
|
||||
|
||||
if (this._options.interactive) {
|
||||
// Only add to picking mesh if this layer is controlling output
|
||||
//
|
||||
// Otherwise, assume another component will eventually add a mesh to
|
||||
// the picking scene
|
||||
if (this.isOutput()) {
|
||||
this._pickingMesh = new THREE.Object3D();
|
||||
this.addToPicking(this._pickingMesh);
|
||||
}
|
||||
|
||||
this._setPickingId();
|
||||
this._addPickingEvents();
|
||||
}
|
||||
|
||||
// Store geometry representation as instances of THREE.BufferAttribute
|
||||
this._setBufferAttributes();
|
||||
|
||||
if (this.isOutput()) {
|
||||
// Set mesh if not merging elsewhere
|
||||
this._setMesh(this._bufferAttributes);
|
||||
|
||||
// Output mesh
|
||||
this.add(this._mesh);
|
||||
}
|
||||
}
|
||||
|
||||
// Return center of polyline as a LatLon
|
||||
//
|
||||
// This is used for things like placing popups / UI elements on the layer
|
||||
//
|
||||
// TODO: Find proper center position instead of returning first coordinate
|
||||
// SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polyline.js#L59
|
||||
getCenter() {
|
||||
return this._coordinates[0][0];
|
||||
}
|
||||
|
||||
// Return line bounds in geographic coordinates
|
||||
//
|
||||
// TODO: Implement getBounds()
|
||||
getBounds() {}
|
||||
|
||||
// Get unique 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) => {
|
||||
// Re-emit click event from the layer
|
||||
this.emit('click', this, point2d, point3d, intersects);
|
||||
});
|
||||
}
|
||||
|
||||
// Create and store reference to THREE.BufferAttribute data for this layer
|
||||
_setBufferAttributes() {
|
||||
var height = 0;
|
||||
|
||||
// Convert height into world units
|
||||
if (this._options.style.lineHeight) {
|
||||
height = this._world.metresToWorld(this._options.style.lineHeight, this._pointScale);
|
||||
}
|
||||
|
||||
var colour = new THREE.Color();
|
||||
colour.set(this._options.style.color);
|
||||
|
||||
// For each line
|
||||
var attributes = this._projectedCoordinates.map(_projectedCoordinates => {
|
||||
var _vertices = [];
|
||||
var _colours = [];
|
||||
|
||||
// Connect coordinate with the next to make a pair
|
||||
//
|
||||
// LineSegments requires pairs of vertices so repeat the last point if
|
||||
// there's an odd number of vertices
|
||||
var nextCoord;
|
||||
_projectedCoordinates.forEach((coordinate, index) => {
|
||||
_colours.push([colour.r, colour.g, colour.b]);
|
||||
_vertices.push([coordinate.x, height, coordinate.y]);
|
||||
|
||||
nextCoord = (_projectedCoordinates[index + 1]) ? _projectedCoordinates[index + 1] : coordinate;
|
||||
|
||||
_colours.push([colour.r, colour.g, colour.b]);
|
||||
_vertices.push([nextCoord.x, height, nextCoord.y]);
|
||||
});
|
||||
|
||||
var line = {
|
||||
vertices: _vertices,
|
||||
colours: _colours,
|
||||
verticesCount: _vertices.length
|
||||
};
|
||||
|
||||
if (this._options.interactive && this._pickingId) {
|
||||
// Inject picking ID
|
||||
line.pickingId = this._pickingId;
|
||||
}
|
||||
|
||||
// Convert line representation to proper attribute arrays
|
||||
return this._toAttributes(line);
|
||||
});
|
||||
|
||||
this._bufferAttributes = Buffer.mergeAttributes(attributes);
|
||||
}
|
||||
|
||||
getBufferAttributes() {
|
||||
return this._bufferAttributes;
|
||||
}
|
||||
|
||||
// Create and store mesh from buffer attributes
|
||||
//
|
||||
// This is only called if the layer is controlling its own output
|
||||
_setMesh(attributes) {
|
||||
var geometry = new THREE.BufferGeometry();
|
||||
|
||||
// itemSize = 3 because there are 3 values (components) per vertex
|
||||
geometry.addAttribute('position', new THREE.BufferAttribute(attributes.vertices, 3));
|
||||
geometry.addAttribute('color', new THREE.BufferAttribute(attributes.colours, 3));
|
||||
|
||||
if (attributes.pickingIds) {
|
||||
geometry.addAttribute('pickingId', new THREE.BufferAttribute(attributes.pickingIds, 1));
|
||||
}
|
||||
|
||||
geometry.computeBoundingBox();
|
||||
|
||||
var style = this._options.style;
|
||||
var material = new THREE.LineBasicMaterial({
|
||||
vertexColors: THREE.VertexColors,
|
||||
linewidth: style.lineWidth,
|
||||
transparent: style.lineTransparent,
|
||||
opacity: style.lineOpacity,
|
||||
blending: style.lineBlending
|
||||
});
|
||||
|
||||
var mesh = new THREE.LineSegments(geometry, material);
|
||||
|
||||
if (style.lineRenderOrder !== undefined) {
|
||||
material.depthWrite = false;
|
||||
mesh.renderOrder = style.lineRenderOrder;
|
||||
}
|
||||
|
||||
// TODO: Can a line cast a shadow?
|
||||
// mesh.castShadow = true;
|
||||
|
||||
if (this._options.interactive && this._pickingMesh) {
|
||||
material = new PickingMaterial();
|
||||
material.side = THREE.BackSide;
|
||||
|
||||
// Make the line wider / easier to pick
|
||||
material.linewidth = style.lineWidth + material.linePadding;
|
||||
|
||||
var pickingMesh = new THREE.LineSegments(geometry, material);
|
||||
this._pickingMesh.add(pickingMesh);
|
||||
}
|
||||
|
||||
this._mesh = mesh;
|
||||
}
|
||||
|
||||
// Convert and project coordinates
|
||||
//
|
||||
// TODO: Calculate bounds
|
||||
_setCoordinates() {
|
||||
this._bounds = [];
|
||||
this._coordinates = this._convertCoordinates(this._coordinates);
|
||||
|
||||
this._projectedBounds = [];
|
||||
this._projectedCoordinates = this._projectCoordinates();
|
||||
}
|
||||
|
||||
// Recursively convert input coordinates into LatLon objects
|
||||
//
|
||||
// Calculate geographic bounds at the same time
|
||||
//
|
||||
// TODO: Calculate geographic bounds
|
||||
_convertCoordinates(coordinates) {
|
||||
return coordinates.map(_coordinates => {
|
||||
return _coordinates.map(coordinate => {
|
||||
return LatLon(coordinate[1], coordinate[0]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 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(_coordinates => {
|
||||
return _coordinates.map(latlon => {
|
||||
point = this._world.latLonToPoint(latlon);
|
||||
|
||||
// TODO: Is offset ever being used or needed?
|
||||
if (!this._offset) {
|
||||
this._offset = Point(0, 0);
|
||||
this._offset.x = -1 * point.x;
|
||||
this._offset.y = -1 * point.y;
|
||||
|
||||
this._pointScale = this._world.pointScale(latlon);
|
||||
}
|
||||
|
||||
return point;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Transform line representation into attribute arrays that can be used by
|
||||
// THREE.BufferGeometry
|
||||
//
|
||||
// TODO: Can this be simplified? It's messy and huge
|
||||
_toAttributes(line) {
|
||||
// Three components per vertex
|
||||
var vertices = new Float32Array(line.verticesCount * 3);
|
||||
var colours = new Float32Array(line.verticesCount * 3);
|
||||
|
||||
var pickingIds;
|
||||
if (line.pickingId) {
|
||||
// One component per vertex
|
||||
pickingIds = new Float32Array(line.verticesCount);
|
||||
}
|
||||
|
||||
var _vertices = line.vertices;
|
||||
var _colour = line.colours;
|
||||
|
||||
var _pickingId;
|
||||
if (pickingIds) {
|
||||
_pickingId = line.pickingId;
|
||||
}
|
||||
|
||||
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[i];
|
||||
|
||||
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];
|
||||
|
||||
if (pickingIds) {
|
||||
pickingIds[lastIndex] = _pickingId;
|
||||
}
|
||||
|
||||
lastIndex++;
|
||||
}
|
||||
|
||||
var attributes = {
|
||||
vertices: vertices,
|
||||
colours: colours
|
||||
};
|
||||
|
||||
if (pickingIds) {
|
||||
attributes.pickingIds = pickingIds;
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
// Returns true if the line is flat (has no height)
|
||||
isFlat() {
|
||||
return this._flat;
|
||||
}
|
||||
|
||||
// Returns true if coordinates refer to a single geometry
|
||||
//
|
||||
// For example, coordinates for a MultiLineString GeoJSON feature
|
||||
static isSingle(coordinates) {
|
||||
return !Array.isArray(coordinates[0][0]);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
if (this._pickingMesh) {
|
||||
// TODO: Properly dispose of picking mesh
|
||||
this._pickingMesh = null;
|
||||
}
|
||||
|
||||
// Run common destruction logic from parent
|
||||
super.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
export default PolylineLayer;
|
||||
|
||||
var noNew = function(coordinates, options) {
|
||||
return new PolylineLayer(coordinates, options);
|
||||
};
|
||||
|
||||
export {noNew as polylineLayer};
|
|
@ -10,6 +10,7 @@ import GeoJSONLayer, {geoJSONLayer} from './layer/GeoJSONLayer';
|
|||
import GeoJSONLayer2, {geoJSONLayer2} from './layer/GeoJSONLayer2';
|
||||
import TopoJSONLayer, {topoJSONLayer} from './layer/TopoJSONLayer';
|
||||
import PolygonLayer, {polygonLayer} from './layer/geometry/PolygonLayer';
|
||||
import PolylineLayer, {polylineLayer} from './layer/geometry/PolylineLayer';
|
||||
|
||||
import Point, {point} from './geo/Point';
|
||||
import LatLon, {latLon} from './geo/LatLon';
|
||||
|
@ -39,6 +40,8 @@ const VIZI = {
|
|||
topoJSONLayer: topoJSONLayer,
|
||||
PolygonLayer: PolygonLayer,
|
||||
polygonLayer: polygonLayer,
|
||||
PolylineLayer: PolylineLayer,
|
||||
polylineLayer: polylineLayer,
|
||||
Point: Point,
|
||||
point: point,
|
||||
LatLon: LatLon,
|
||||
|
|
Ładowanie…
Reference in New Issue