iTowns / itowns

A Three.js-based framework written in Javascript/WebGL for visualizing 3D geospatial data
http://www.itowns-project.org
Other
1.09k stars 293 forks source link

adding a featureGeometry to a featureCollection #1747

Open ftoromanoff opened 2 years ago

ftoromanoff commented 2 years ago

We need to extract a feature from a ColorLayer to add it to a new ColorLayer (or GeometryLayer).

Thus we used view.pickFeatureAt() which send a featureGeometry. But to create a new (Color/Geometry)Layer a featureCollection is needed and it seems there is no easy way to transforme a featureGeometry into a featureCollection.

Possible Cause/Fix/Solution

        const layerTest = view.getLayerById(editing.alertLayerName);

        const features = view.pickFeaturesAt(ev, 5, layerTest.id);

        const featureCollec = await layerTest.source.loadData(undefined, layerTest);
        const newFeatureCollec = new itowns.FeatureCollection(layerTest);

        const featureGeometry = features[layerTest.id][0].geometry;

        const feature = featureCollec.requestFeatureByType(features[layerTest.id][0].type);
        const newFeature = newFeatureCollec.requestFeatureByType(features[layerTest.id][0].type);
        const newFeatureGeometry = newFeature.bindNewGeometry();

        const coord = new itowns.Coordinates(newFeatureCollec.crs, 0, 0, 0);

        const vector = new THREE.Vector2();
        const vector3 = new THREE.Vector3();
        const { count, offset } = featureGeometry.indices[0];

        newFeatureGeometry.startSubGeometry(count, newFeature);
        const { vertices } = feature;
        for (let v = offset * 2; v < (offset + count) * 2; v += 2) {
          vector.fromArray(vertices, v);
          vector3.copy(vector).setZ(0).applyMatrix4(featureCollec.matrixWorld);
          coord.x = vector3.x;
          coord.y = vector3.y;
          newFeatureGeometry.pushCoordinates(coord, newFeature);
        }
        newFeatureGeometry.updateExtent();

        const newLayer = new itowns.ColorLayer('newLayer', {
          // Use a FileSource to load a single file once
          source: new itowns.FileSource({
              features: newFeatureCollec,
          }),
          transparent: true,
          opacity: 0.7,
          // zoom: { min: 10 },
          style: new itowns.Style({
            fill: {
              color: '#bbffbb',
              // base_altitude: 10,
            },
          }),
        });

        view.addLayer(newLayer);
jailln commented 1 year ago

Related to #1923