Geodan / pg2b3dm

Tool for creating 3D Tiles from PostGIS geometries
MIT License
349 stars 64 forks source link

Mismatch between FeatureCount and Feature Attribute #176

Closed alexaac closed 2 months ago

alexaac commented 2 months ago

Problem Description When generating 3D tiles from large files, I get the 'Mismatch between FeatureCount (462) and Feature Attribute (463)' exception, even if I run repair geometry in QGIS and I check the number of unique ids is the same as the number of records. Thanks Steps to Reproduce the Problem I assign z values to lines from a raster file using QGIS(drape), export them to a GeoPackage file, import them to a PostgreSQL database, create spatial index, create a field for radius and update it, then run the pg2b3dm script with those options: pg2b3dm -h localhost -U postgis_test -c geom -d postgis_db -t somename --radiuscolumn radius --default_color '#20908d' -a fid --output /some/output/ Expected Behavior The script should output the 3D tiles folder and files Observed Behavior After an hour I get the error and the script stops

Screenshot from 2024-06-26 17-39-54 Screenshot from 2024-06-26 17-39-34

bertt commented 2 months ago

Hi never seen this one, what happens when you omit -a ? As a workaround you can use create_gltf = false option (b3dm’s instead of glb’s are created)

bertt commented 2 months ago

another thing to look for: maybe there are invalid geometries (like geometries with 0 area or duplicate vertices), that get filtered away (because the number of geometries (462) is less than the number of attributes (463)).

alexaac commented 2 months ago

Hi never seen this one, what happens when you omit -a ? As a workaround you can use create_gltf = false option (b3dm’s instead of glb’s are created)

If I omit -a it works fine, but I need the attribute.

alexaac commented 2 months ago

another thing to look for: maybe there are invalid geometries (like geometries with 0 area or duplicate vertices), that get filtered away (because the number of geometries (462) is less than the number of attributes (463)).

Yes, this must be the issue. It's just that I've repaired the geometries in QGIS using 'Fix geometries', so there should not be any invalid geometries. I've even exported to shapefile, ran 'Repair Shapefile', and back to gpkg. :)

I suppose something went wrong in QGIS, and the GeoPackage file was not cleaned before exporting to PostgreSQL. Most probably it's not a pg2b3dm issue.

Thanks. I appreciate the time and effort you put into pg2b3dm and the many valuable examples. 👍

alexaac commented 2 months ago

I have re-exported the data from QGIS after running 'Fix geometries' and 'Remove null geometries' again, and this time it worked. I guess it was not a pg2b3dm issue. Thanks

alexaac commented 2 months ago

Hi @bertt, this question is a bit off-topic, so please tell me if I should post it somewhere else.

Is there an easy way to access the object properties exported with "--attributes|-a", besides using Mapbox or Cesium?

I'm trying to query the 3D tiles using the Raycaster in Three.js. Is this info in the BufferGeometry of each tile object, in buffer attributes? I've exported a field named fid and I can't find it anywhere.

Thanks Screenshot from 2024-07-03 12-11-29

bertt commented 2 months ago

Hi, this is not so easy... But the approach for 3D Tiles 1.1 is something like:

the id of each feature is stored in the primitive vertex attributes (attribute _FEATURE_ID_0). This is part of glTF extension EXT_mesh_features (https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_mesh_features)

Maybe you can get some inspiration from https://github.com/Geodan/mapbox-3dtiles/blob/master/Mapbox3DTiles.mjs#L719 (this is for 3D Tiles 1.0)

For 3D Tiles 1.0 (with b3dm's) all the attribute information can be found in the b3dm header.

For more discussion about 3D Tiles see https://community.cesium.com/

alexaac commented 2 months ago

Hi, this is not so easy... But the approach for 3D Tiles 1.1 is something like:

* In the raycaster find the Feature ID

the id of each feature is stored in the primitive vertex attributes (attribute _FEATURE_ID_0). This is part of glTF extension EXT_mesh_features (https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_mesh_features)

Maybe you can get some inspiration from https://github.com/Geodan/mapbox-3dtiles/blob/master/Mapbox3DTiles.mjs#L719 (this is for 3D Tiles 1.0)

* Find the Id of the propertyTable - normally this is '0' (this is part of glTF extension EXT_structural_metadata (https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_structural_metadata)

* In the propertyTable there are the various properties defined, with pointers to the actual values.

* The actual values are stored  in BufferViews. Note for example for string properties there are 2 bufferViews in use: one for the string lengths and one for the strings.

For 3D Tiles 1.0 (with b3dm's) all the attribute information can be found in the b3dm header.

For more discussion about 3D Tiles see https://community.cesium.com/

Thank you very much for the info and resources. 🙏