Skip to content

Commit 0961787

Browse files
committed
feature(Layer): add FeatureGeometryLayer.
1 parent f632308 commit 0961787

9 files changed

+80
-49
lines changed

examples/js/plugins/DragNDrop.js

+24-20
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,20 @@ var DragNDrop = (function _() {
6666
data = new window.DOMParser().parseFromString(data, 'text/xml');
6767
}
6868

69+
var crs = extension.mode == _GEOMETRY ? _view.referenceCrs : _view.tileLayer.extent.crs;
70+
6971
extension.parser(data, {
7072
in: {
7173
crs: 'EPSG:4326',
7274
},
7375
out: {
74-
crs: (extension.mode == _GEOMETRY ? _view.referenceCrs : _view.tileLayer.extent.crs),
76+
crs: crs,
7577
buildExtent: true,
7678
mergeFeatures: true,
7779
structure: (extension.mode == _GEOMETRY ? '3d' : '2d'),
80+
forcedExtentCrs: crs != 'EPSG:4978' ? crs : 'EPSG:4326',
7881
},
7982
}).then(function _(features) {
80-
var dimensions = features.extent.dimensions();
81-
8283
var source = new itowns.FileSource({
8384
features: features,
8485
crs: 'EPSG:4326',
@@ -102,29 +103,32 @@ var DragNDrop = (function _() {
102103
source: source,
103104
});
104105
} else if (extension.mode == _GEOMETRY) {
105-
layer = new itowns.GeometryLayer(file.name, new itowns.THREE.Group(), {
106-
update: itowns.FeatureProcessing.update,
107-
convert: itowns.Feature2Mesh.convert({
108-
color: new itowns.THREE.Color(randomColor),
109-
// Set the extrusion according to the size of
110-
// the extent containing the data; this quick
111-
// formula is totally arbitrary.
112-
extrude: dimensions.x * dimensions.y / 1e6,
113-
}),
114-
source: source,
115-
opacity: 0.7,
116-
});
106+
layer = new itowns.FeatureGeometryLayer(
107+
file.name,
108+
{
109+
style: new itowns.Style({
110+
fill: {
111+
color: 'red',
112+
extrusion_height: 200,
113+
},
114+
}),
115+
source: source,
116+
opacity: 0.7,
117+
});
117118
} else {
118119
throw new Error('Mode of file not supported, please add it using DragNDrop.register');
119120
}
120121

121122
_view.addLayer(layer);
122123

123-
// Move the camera to the first vertex
124-
itowns.CameraUtils.animateCameraToLookAtTarget(_view, _view.camera.camera3D, {
125-
coord: new itowns.Coordinates(features.crs, features.features[0].vertices),
126-
range: dimensions.x * dimensions.y * 1e6,
127-
});
124+
var extent = features.extent.clone();
125+
// Transform local extent to data.crs projection.
126+
if (extent.crs == features.crs) {
127+
extent.applyMatrix4(features.matrixWorld);
128+
}
129+
130+
// Move the camera
131+
itowns.CameraUtils.transformCameraToLookAtTarget(_view, _view.camera.camera3D, extent);
128132
});
129133
};
130134

examples/js/plugins/FeatureToolTip.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* view.addLayer(wfsLayer);
1616
*
1717
* var fileSource = new itowns.FileSource(...);
18-
* var fileLayer = new itowns.GeometryLayer('id_myFile', { source: fileSource});
18+
* var fileLayer = new itowns.GeometryLayer('id_myFile', new THREE.Group(), { source: fileSource });
1919
* view.addLayer(fileLayer);
2020
*
2121
* FeatureToolTip.addLayer(wfsLayer);

examples/source_file_geojson_3d.html

+1-3
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,13 @@
4747
itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
4848

4949
// Add a geometry layer, which will contain the multipolygon to display
50-
var marne = new itowns.GeometryLayer('Marne', new itowns.THREE.Group(), {
50+
var marne = new itowns.FeatureGeometryLayer('Marne', {
5151
// Use a FileSource to load a single file once
5252
source: new itowns.FileSource({
5353
url: 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/multipolygon.geojson',
5454
crs: 'EPSG:4326',
5555
format: 'application/json',
5656
}),
57-
update: itowns.FeatureProcessing.update,
58-
convert: itowns.Feature2Mesh.convert(),
5957
transparent: true,
6058
opacity: 0.7,
6159
zoom: { min: 10 },

examples/source_stream_wfs_25d.html

+3-8
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,7 @@
147147
format: 'geojson',
148148
});
149149

150-
var lyonTclBusLayer = new itowns.GeometryLayer('lyon_tcl_bus', new itowns.THREE.Group(), {
151-
update: itowns.FeatureProcessing.update,
152-
convert: itowns.Feature2Mesh.convert(),
150+
var lyonTclBusLayer = new itowns.FeatureGeometryLayer('lyon_tcl_bus', {
153151
filter: acceptFeatureBus,
154152
source: lyonTclBusSource,
155153
zoom: { min: 2 },
@@ -219,17 +217,14 @@
219217
},
220218
});
221219

222-
var wfsBuildingLayer = new itowns.GeometryLayer('wfsBuilding', new itowns.THREE.Group(), {
223-
update: itowns.FeatureProcessing.update,
224-
convert: itowns.Feature2Mesh.convert({
225-
batchId: function (property, featureId) { return featureId; }
226-
}),
220+
var wfsBuildingLayer = new itowns.FeatureGeometryLayer('wfsBuilding', {
227221
onMeshCreated: function scaleZ(mesh) {
228222
mesh.children.forEach(c => {
229223
c.scale.z = 0.01;
230224
meshes.push(c);
231225
})
232226
},
227+
batchId: function (property, featureId) { return featureId; },
233228
filter: acceptFeature,
234229
crs: 'EPSG:3946',
235230
source: wfsBuildingSource,

examples/source_stream_wfs_3d.html

+3-8
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,8 @@
110110
format: 'geojson',
111111
});
112112

113-
var lyonTclBusLayer = new itowns.GeometryLayer('WFS Bus lines', new itowns.THREE.Group(), {
113+
var lyonTclBusLayer = new itowns.FeatureGeometryLayer('WFS Bus lines',{
114114
name: 'lyon_tcl_bus',
115-
update: itowns.FeatureProcessing.update,
116-
convert: itowns.Feature2Mesh.convert(),
117115
filter: acceptFeatureBus,
118116
source: lyonTclBusSource,
119117
zoom: { min: 9 },
@@ -183,11 +181,8 @@
183181
},
184182
});
185183

186-
var wfsBuildingLayer = new itowns.GeometryLayer('WFS Building', new itowns.THREE.Group(), {
187-
update: itowns.FeatureProcessing.update,
188-
convert: itowns.Feature2Mesh.convert({
189-
batchId: function (property, featureId) { return featureId; },
190-
}),
184+
var wfsBuildingLayer = new itowns.FeatureGeometryLayer('WFS Building',{
185+
batchId: function (property, featureId) { return featureId; },
191186
onMeshCreated: function scaleZ(mesh) {
192187
mesh.children.forEach(c => {
193188
c.scale.z = 0.01;

examples/view_immersive.html

+1-3
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,7 @@
133133
});
134134

135135
// create geometry layer for the buildings
136-
var wfsBuildingLayer = new itowns.GeometryLayer('Buildings', new itowns.THREE.Group(), {
137-
update: itowns.FeatureProcessing.update,
138-
convert: itowns.Feature2Mesh.convert(),
136+
var wfsBuildingLayer = new itowns.FeatureGeometryLayer('Buildings', {
139137
style: new itowns.Style({
140138
fill: {
141139
base_altitude: altitudeBuildings,

src/Layer/FeatureGeometryLayer.js

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { Group } from 'three';
2+
3+
import GeometryLayer from 'Layer/GeometryLayer';
4+
import FeatureProcessing from 'Process/FeatureProcessing';
5+
import Feature2Mesh from 'Converter/Feature2Mesh';
6+
7+
/**
8+
* `FeatureGeometryLayer` displays geographic vector data (geojson, kml...) in object 3D.
9+
* `FeatureGeometryLayer` is a pre-configured `GeometryLayer` to load and convert vector data.
10+
* In deed, `GeometryLayer` allows customizing data loading (`update` method)
11+
* and their conversion (`convert` method),
12+
*
13+
* @property {boolean} isFeatureGeometryLayer - Used to checkout whether this layer is
14+
* a FeatureGeometryLayer. Default is true. You should not change this, as it is used
15+
* internally for optimisation.
16+
*/
17+
class FeatureGeometryLayer extends GeometryLayer {
18+
/**
19+
* @constructor
20+
* @extends GeometryLayer
21+
*
22+
* @param {string} id - The id of the layer, that should be unique. It is
23+
* not mandatory, but an error will be emitted if this layer is added a
24+
* {@link View} that already has a layer going by that id.
25+
* @param {Object} [config] - Optional configuration, all elements in it
26+
* will be merged as is in the layer.
27+
* @param {function} [options.batchId] - optional function to create batchId attribute.
28+
* It is passed the feature property and the feature index.
29+
* As the batchId is using an unsigned int structure on 32 bits, the batchId could be between 0 and 4,294,967,295.
30+
* @param {THREE.Object3D} [config.object3d=new THREE.Group()] root object3d layer.
31+
*
32+
*/
33+
constructor(id, config = {}) {
34+
config.update = FeatureProcessing.update;
35+
config.convert = Feature2Mesh.convert({
36+
batchId: config.batchId,
37+
},
38+
);
39+
super(id, config.object3d || new Group(), config);
40+
this.isFeatureGeometryLayer = true;
41+
}
42+
}
43+
44+
export default FeatureGeometryLayer;

src/Main.js

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export { default as Layer, ImageryLayers } from 'Layer/Layer';
4848
export { default as ColorLayer } from 'Layer/ColorLayer';
4949
export { default as ElevationLayer } from 'Layer/ElevationLayer';
5050
export { default as GeometryLayer } from 'Layer/GeometryLayer';
51+
export { default as FeatureGeometryLayer } from 'Layer/FeatureGeometryLayer';
5152
export { default as PointCloudLayer } from 'Layer/PointCloudLayer';
5253
export { default as PotreeLayer } from 'Layer/PotreeLayer';
5354
export { default as C3DTilesLayer } from 'Layer/C3DTilesLayer';

test/unit/featureprocess.js test/unit/featuregeometrylayer.js

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import * as THREE from 'three';
22
import assert from 'assert';
33
import GlobeView from 'Core/Prefab/GlobeView';
4-
import FeatureProcessing from 'Process/FeatureProcessing';
5-
import Feature2Mesh from 'Converter/Feature2Mesh';
6-
import GeometryLayer from 'Layer/GeometryLayer';
4+
import FeatureGeometryLayer from 'Layer/FeatureGeometryLayer';
75
import FileSource from 'Source/FileSource';
86
import HttpsProxyAgent from 'https-proxy-agent';
97
import Extent from 'Core/Geographic/Extent';
@@ -26,7 +24,7 @@ describe('Layer with Feature process', function () {
2624
networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {},
2725
});
2826

29-
const ariege = new GeometryLayer('ariege', new THREE.Group(), {
27+
const ariege = new FeatureGeometryLayer('ariege', {
3028
source,
3129
style: new Style({
3230
fill: {
@@ -35,8 +33,6 @@ describe('Layer with Feature process', function () {
3533
},
3634
}),
3735
zoom: { min: 7 },
38-
update: FeatureProcessing.update,
39-
convert: Feature2Mesh.convert(),
4036
});
4137

4238
const context = {

0 commit comments

Comments
 (0)