Geodan / i3dm.export

Export 3D Instanced Tiles from PostGIS table
MIT License
38 stars 20 forks source link

Plans for Cesium compatibility #17

Closed fnicollet closed 2 years ago

fnicollet commented 3 years ago

Hello,

This is a follow-up on this ticket: https://github.com/Geodan/i3dm.export/issues/15 Mostly to explain where I'm at and start a conversation about it :)

With a few modifications in the source code, I managed to create i3dm tiles compatible with a Cesium viewer. Here is a demonstration: https://sandcastle.cesium.com/#c=dVPBbtswDP0VIaesaCQMvWVpMDQrukOHFWvWXnyRLSbhJksZKTtrh/37aMtB06TzRTDf4yP5KLWWVAWMTb0EIovhjmKLDkhdqkUf1xWBTfAYybuBM373oQitZIL3uOWI7jQ5wG4vcP0fVi+ThVqE3XHaQx8bF6Pc3yKGJMlAxehc/SmCkq+0DLf2CegOq59AU5WogfMOswFrmzCGqVpZzznIFQT4Eh3s6S9Qwhq8qB/G1hArIb/ibWINV01Kr4WDbXHdl/sMfnuKK7VqvGdxEsIpSvCrAU7fIEixrr08RxH+7n3uGxd3sk26/x2ghB4Y0mvr8nHxaZnB8WBXQ36qitEmpS1PjXHQ6rJhmZp5IsOuya6w0lWsTel+Ty7cxNlkDV642lgqCXiSV2GGovoHxyDryOrGHOmT3ek1pk0jRYAq2R+E1Mvn/m7ujdTotSZs662cpracgPYF2AwTPIrMUty7Qu/LaMnxaQ9FMme5Ewdls77fxN1VbILDsH6Ivqnh4HoMnEX0kfAZ+iqncCdxA7LxRFhdE0V6m/O9mzuvrEhnZr+4g2XpLWGNCVtgbZ0bD80f0J5jrJfxBRidj2acnjzMczGlPmK9jZS6LY61NgnEMXmYbMpGbrMYy9zpddSZOUydOWwVuss3XpKqvGUWpLuf9+JEMZrPjPBPUn20nZNfWyBvnzra5v38Nge11jMjv29nphh9aelI+R8

The dataset is about 31K trees, the same that i used in the mapbox-gl-js viewer: image

Here are the modifications i did in the source code to make it work:

All these would be "breaking changes" for you as they wouldn't be compatible with the code you created to load i3dm in mapbox-gl-js (https://github.com/Geodan/mapbox-3dtiles), so I don't know if you really want this in your codebase and if you want to maintain it. It would also need some more work so make it really compatible with both systems (for instance, the tile size should be calculated in number of tiles, not in units).

For usage in our software, I will probably have to rewrite all this C# code to something more "multi-platform" (python or java) so contributing to this repo won't be very beneficial for me either, but it might be for other people willing to use Cesium.

As you are the only maintainer of this repo, i would like to hear your thoughts about this :)

Thanks, Fabien

bertt commented 3 years ago

Great work!

Adding Cesium support is low on our priority list, because we only use MapBox GL JS as client. But it would be nice to get the tileset also working in Cesium. Required changes should be non-breaking and have low maintenance. Ideally like adding an extra optional format = cesium parameter.

Some more remarks:

fnicollet commented 3 years ago

Thanks for the feedback :)

For now, i'll keep my fork locally, creating a "clean PR" with a new parameter and no hard-coded values would take me too much time.

So i'll keep this issue opened, and if someone else gets interested in the future, i'll make an effort to clean and share the work

Thanks for your quick help on this! Fabien

MortezaYaqubkhani commented 3 years ago

Hi, I'm pretty new to Cesium and the concept of the 3D tileset. So some of my questions might look a little bit unrelated to the purpose of this topic, My apologies ... I am starting a new project and the objective is to map millions of trees with Cesium. I found your work one of the few related works to my project. I have few questions about the work you've done and a few general questions about Cesium:

bertt commented 3 years ago

Hi,

Some answers:

MortezaYaqubkhani commented 3 years ago

Thanks for the reply!

MortezaYaqubkhani commented 3 years ago

Hi,

Some answers:

  • Samples: in this repository, there are sample i3dm MapBox viewers and i3dm tiles. The i3dm's are created using this tool (i3dm-export). The tool takes a glTF model and instance positions/scales/rotations (from PostGIS) as input basically.
  • If you have different types you have to create multiple i3dm's, with a unique glTF model as input. These tiles can be combined in a composite (cmpt) tile (also from 3D Tiles spec).
  • Cesium Ion is an alternative method, you have to check on their site.

Hi, While I am looking for ways to use Cesium ION for my project (tree visualization), I've decided to try open-source solutions as well, and creating 3d tiles for Mapbox (same as what you have done) seems like a good start. So I started to use this repository. However, I faced some issues ( I suppose it is because of my limited knowledge on . Net) following your steps. After installing .NET 5.0 SDK , and cloning this repository to my machine when I run the command "dotnet tool install -g i3dm.export" I face the following error:

error NU1100: Unable to resolve 'i3dm.export (>= 0.0.0)' for 'net5.0'.
error NU1100: Unable to resolve 'i3dm.export (>= 0.0.0)' for 'net5.0/any'.
The tool package could not be restored.
Tool 'i3dm.export' failed to install. This failure may have been caused by:
* You are attempting to install a preview release and did not use the --version option to specify the version.
* A package by this name was found, but it was not a .NET tool.
* The required NuGet feed cannot be accessed, perhaps because of an Internet connection problem.
* You mistyped the name of the tool.
For more reasons, including package naming enforcement, visit https://aka.ms/failure-installing-tool

Could you please give me a hint on what's the problem here?! Thanks

bertt commented 3 years ago

Hi, command 'dotnet tool install -g i3dm.export' should work, what do you get with 'dotnet --version' ? What with 'dotnet nuget list source'? Note: you don't have to clone the source code when installing this tool.

MortezaYaqubkhani commented 3 years ago

Hi again, dotnet --version: 5.0.202 dotnet nuget list source: No source found

bertt commented 3 years ago

run 'dotnet nuget add source https://api.nuget.org/v3/index.json -n nuget.org' and try again

MortezaYaqubkhani commented 3 years ago

Tool 'i3dm.export' (version '1.8.0') was successfully installed.

Many Thanks

MortezaYaqubkhani commented 3 years ago

Hello,

This is a follow-up on this ticket:

15

Mostly to explain where I'm at and start a conversation about it :)

With a few modifications in the source code, I managed to create i3dm tiles compatible with a Cesium viewer. Here is a demonstration: https://sandcastle.cesium.com/#c=dVPBbtswDP0VIaesaCQMvWVpMDQrukOHFWvWXnyRLSbhJksZKTtrh/37aMtB06TzRTDf4yP5KLWWVAWMTb0EIovhjmKLDkhdqkUf1xWBTfAYybuBM373oQitZIL3uOWI7jQ5wG4vcP0fVi+ThVqE3XHaQx8bF6Pc3yKGJMlAxehc/SmCkq+0DLf2CegOq59AU5WogfMOswFrmzCGqVpZzznIFQT4Eh3s6S9Qwhq8qB/G1hArIb/ibWINV01Kr4WDbXHdl/sMfnuKK7VqvGdxEsIpSvCrAU7fIEixrr08RxH+7n3uGxd3sk26/x2ghB4Y0mvr8nHxaZnB8WBXQ36qitEmpS1PjXHQ6rJhmZp5IsOuya6w0lWsTel+Ty7cxNlkDV642lgqCXiSV2GGovoHxyDryOrGHOmT3ek1pk0jRYAq2R+E1Mvn/m7ujdTotSZs662cpracgPYF2AwTPIrMUty7Qu/LaMnxaQ9FMme5Ewdls77fxN1VbILDsH6Ivqnh4HoMnEX0kfAZ+iqncCdxA7LxRFhdE0V6m/O9mzuvrEhnZr+4g2XpLWGNCVtgbZ0bD80f0J5jrJfxBRidj2acnjzMczGlPmK9jZS6LY61NgnEMXmYbMpGbrMYy9zpddSZOUydOWwVuss3XpKqvGUWpLuf9+JEMZrPjPBPUn20nZNfWyBvnzra5v38Nge11jMjv29nphh9aelI+R8

The dataset is about 31K trees, the same that i used in the mapbox-gl-js viewer: image

Here are the modifications i did in the source code to make it work:

  • Moved away from your "transform+box" (https://github.com/CesiumGS/3d-tiles/tree/master/specification#box) bounding volume to a "region" one (https://github.com/CesiumGS/3d-tiles/tree/master/specification#region). It makes the generated tileset.json a lot clearer and easier to debug. Not sure why you used transform+box in the first place in your code ? Compatibility with code you already had for 3D tiles?
  • Used radians instead of degrees as stated in the format specifications (lost a good 2 hours on that one ...)
  • For instance positions, use "Cartesian3" (https://cesium.com/docs/cesiumjs-ref-doc/Cartesian3.html) coordinates instead of 3857. Had to convert some of the Cesium JS code to C# to be able to convert lat/lng to these coordinates
  • Used some hard-coded values for the "rotation" vector as I couldn't really figure out what the specification expects (and I want my trees to point mostly up, so that's fine :) )
  • Don't reproject geometries to 3857 and keep everything in 4326 (I don't know if that's what made a difference, but the process was 20 minutes before and now it's about 3 seconds)
  • Changed the -s and -e values in my command line to much smaller values as these are now degrees.

All these would be "breaking changes" for you as they wouldn't be compatible with the code you created to load i3dm in mapbox-gl-js (https://github.com/Geodan/mapbox-3dtiles), so I don't know if you really want this in your codebase and if you want to maintain it. It would also need some more work so make it really compatible with both systems (for instance, the tile size should be calculated in number of tiles, not in units).

For usage in our software, I will probably have to rewrite all this C# code to something more "multi-platform" (python or java) so contributing to this repo won't be very beneficial for me either, but it might be for other people willing to use Cesium.

As you are the only maintainer of this repo, i would like to hear your thoughts about this :)

Thanks, Fabien

Hi Fabien, I want to do the same thing as you and create 3Dtilesets to use in Cesium. I was able to produce some results with i3dm.export to use in Maobix-GL. I want to start to modify the original codes and follow your method. However, it is a bit unclear to me. To start, could you please share tileset.json files and .i3dm files so I can make a comparison between the two. regards

fnicollet commented 3 years ago

Hello,

Here is the tileset.json (you can see it in the Sandcastle example i shared): https://dev.business-geografic.com/bdx-3d-data/i3dm/arbres-cesium/tileset.json In the tileset.json file, you will find the path to hte i3dm files, such as: https://dev.business-geografic.com/bdx-3d-data/i3dm/arbres-cesium/tiles/0_0_6_2.i3dm

Hope it helps, Fabien

MortezaYaqubkhani commented 3 years ago

Hello,

Here is the tileset.json (you can see it in the Sandcastle example i shared): https://dev.business-geografic.com/bdx-3d-data/i3dm/arbres-cesium/tileset.json In the tileset.json file, you will find the path to hte i3dm files, such as: https://dev.business-geografic.com/bdx-3d-data/i3dm/arbres-cesium/tiles/0_0_6_2.i3dm

Hope it helps, Fabien

Thanks for the answer. I don't know if it is me doing something wrong or what? It's been a while I am trying to run your Sandcastle example, but it seems that nothing is loaded on the page (I can not see any trees!) except the base map. I even tried to import your tileset and .i3dm files in Cesium Ion, but it shows only a white frame on the map. Could you please take a look and see what's the problem!

Thanks, Morteza

fnicollet commented 3 years ago

The dataset is only visible when you zoom in, on that location: image

As for importing i3dm files in Cesium ION, I don't think it's a supported format unfortunately: https://cesium.com/docs/tutorials/uploading/

MortezaYaqubkhani commented 3 years ago

Thanks for the reply. I have seen it. By the way, if you upload the tileset.json file with corresponding .i3dm files into Cesuim ION, you won't face any problem and your 3d tileset will be hosted by Cesium. I did the same thing with your tileset files and it worked. image

Thanks again for your help!

fnicollet commented 3 years ago

ah that's good to know, thank you !

On Mon, Apr 26, 2021 at 6:03 PM MortezaYaqubkhani @.***> wrote:

Thanks for the reply. I have seen it. By the way, if you upload the tileset.json file with corresponding .i3dm files into Cesuim ION, you won't face any problem and your 3d tileset will be hosted by Cesium. I did the same thing with your tileset files and it worked. [image: image] https://user-images.githubusercontent.com/61637189/116114040-4d3dfa00-a6b9-11eb-9b76-5f5bb59f3694.png

Thanks again for your help!

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Geodan/i3dm.export/issues/17#issuecomment-826956724, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAJO3IMTFZ7UXBD3UBLGJZTTKWFE3ANCNFSM4WNRI2RA .

MortezaYaqubkhani commented 3 years ago

Hello,

This is a follow-up on this ticket:

15

Mostly to explain where I'm at and start a conversation about it :)

With a few modifications in the source code, I managed to create i3dm tiles compatible with a Cesium viewer. Here is a demonstration: https://sandcastle.cesium.com/#c=dVPBbtswDP0VIaesaCQMvWVpMDQrukOHFWvWXnyRLSbhJksZKTtrh/37aMtB06TzRTDf4yP5KLWWVAWMTb0EIovhjmKLDkhdqkUf1xWBTfAYybuBM373oQitZIL3uOWI7jQ5wG4vcP0fVi+ThVqE3XHaQx8bF6Pc3yKGJMlAxehc/SmCkq+0DLf2CegOq59AU5WogfMOswFrmzCGqVpZzznIFQT4Eh3s6S9Qwhq8qB/G1hArIb/ibWINV01Kr4WDbXHdl/sMfnuKK7VqvGdxEsIpSvCrAU7fIEixrr08RxH+7n3uGxd3sk26/x2ghB4Y0mvr8nHxaZnB8WBXQ36qitEmpS1PjXHQ6rJhmZp5IsOuya6w0lWsTel+Ty7cxNlkDV642lgqCXiSV2GGovoHxyDryOrGHOmT3ek1pk0jRYAq2R+E1Mvn/m7ujdTotSZs662cpracgPYF2AwTPIrMUty7Qu/LaMnxaQ9FMme5Ewdls77fxN1VbILDsH6Ivqnh4HoMnEX0kfAZ+iqncCdxA7LxRFhdE0V6m/O9mzuvrEhnZr+4g2XpLWGNCVtgbZ0bD80f0J5jrJfxBRidj2acnjzMczGlPmK9jZS6LY61NgnEMXmYbMpGbrMYy9zpddSZOUydOWwVuss3XpKqvGUWpLuf9+JEMZrPjPBPUn20nZNfWyBvnzra5v38Nge11jMjv29nphh9aelI+R8

The dataset is about 31K trees, the same that i used in the mapbox-gl-js viewer: image

Here are the modifications i did in the source code to make it work:

  • Moved away from your "transform+box" (https://github.com/CesiumGS/3d-tiles/tree/master/specification#box) bounding volume to a "region" one (https://github.com/CesiumGS/3d-tiles/tree/master/specification#region). It makes the generated tileset.json a lot clearer and easier to debug. Not sure why you used transform+box in the first place in your code ? Compatibility with code you already had for 3D tiles?
  • Used radians instead of degrees as stated in the format specifications (lost a good 2 hours on that one ...)
  • For instance positions, use "Cartesian3" (https://cesium.com/docs/cesiumjs-ref-doc/Cartesian3.html) coordinates instead of 3857. Had to convert some of the Cesium JS code to C# to be able to convert lat/lng to these coordinates
  • Used some hard-coded values for the "rotation" vector as I couldn't really figure out what the specification expects (and I want my trees to point mostly up, so that's fine :) )
  • Don't reproject geometries to 3857 and keep everything in 4326 (I don't know if that's what made a difference, but the process was 20 minutes before and now it's about 3 seconds)
  • Changed the -s and -e values in my command line to much smaller values as these are now degrees.

All these would be "breaking changes" for you as they wouldn't be compatible with the code you created to load i3dm in mapbox-gl-js (https://github.com/Geodan/mapbox-3dtiles), so I don't know if you really want this in your codebase and if you want to maintain it. It would also need some more work so make it really compatible with both systems (for instance, the tile size should be calculated in number of tiles, not in units).

For usage in our software, I will probably have to rewrite all this C# code to something more "multi-platform" (python or java) so contributing to this repo won't be very beneficial for me either, but it might be for other people willing to use Cesium.

As you are the only maintainer of this repo, i would like to hear your thoughts about this :)

Thanks, Fabien

Hey Fabien,

I just have another question regarding Cesium compatibility. Have you made the above changes to the source code or manually to the results (.json files)? For example, when you are talking about changing bounding volume from "box" to office!

Thanks Morteza

fnicollet commented 3 years ago

Yes, i've made several changes to the source code so that the output could be loaded in Cesium. At the moment, the code is not shared or in a Pull Request, and there are still some bugs regarding the 3D models orientation (rotations). It was the point of this github issue, wether @bertt wanted to support it "officially" or not (see his answer in this thread)

Fabien

tebben commented 3 years ago

I gave Cesium support a try, it can be found in this branch: https://github.com/Geodan/i3dm.export/tree/feature/cesium-support

Run i3dm.export with the --cesium parameter to export a Cesium compatible tileset.

CMPT tiles don't seem to work yet, Cesium throws the following error: Error: start offset of Float32Array should be a multiple of 4

image

jailln commented 3 years ago

I gave Cesium support a try, it can be found in this branch: https://github.com/Geodan/i3dm.export/tree/feature/cesium-support

Run i3dm.export with the --cesium parameter to export a Cesium compatible tileset.

* BoundingBox3D in epsg 3857 is still used for tile calculations but gets converted using PostGIS to 4979 for the JSON export so no messing around is needed for the -s and -e parameters.

* For --cesium a region BoundingVolume is used instead of box

* Model positions are transformed from 4326 to 4978 (ECEF) so that they are compatible with Cesium.

* Added GetLocalEnuCesium to calculate the correct rotation for a model at a certain position on the Globe.

CMPT tiles don't seem to work yet, Cesium throws the following error: Error: start offset of Float32Array should be a multiple of 4

image

Thanks for this contribution! :)

I gave it a try with the following dataset: https://data.grandlyon.com/jeux-de-donnees/arbres-alignement-metropole-lyon/telechargements

I ran into the following error: MessageText: GetProj4StringSPI: Cannot find SRID (4979) in spatial_ref_sys so I added 4979 to the spatial_ref_sys table (c.f. https://spatialreference.org/ref/epsg/4979/postgis/ but change 94979 to 4979). It resolved the error and the 3D Tiles gets created. The tileset.json file is loaded in Cesium but tiles seems to be inside the globe and the .i3dm files never gets loaded.

Do you have any idea why? In which SRID should be the input data ? 3857 or 4326 ? In addition, if I'm not mistaken, Cesium is in 4978, why do you need 4979 then?

Cheers

tebben commented 3 years ago

Input data epsg requirement hasn't changed so it should be in 4326. 4979 is needed for the bounding volume region, see https://github.com/CesiumGS/3d-tiles/tree/main/specification#region

I didn't had to do anything to my PostGIS installation to get it working so i'm not sure why 4979 isn't there on your installation. I do remember having to change to last Geometric error in the output JSON from 0 to a higher number to load the tiles.

I will have a go tomorrow on the dataset you posted.

tebben commented 3 years ago

In my test there was no supertileset generated, the bounds for the supertileset weren't converted which resulted in a wrong location and the i3dm tiles not loading. I pushed an update.

Loaded GeoJSON into PostGIS

 ogr2ogr -f "PostgreSQL" PG:"host=myhost dbname=mydb user=myuser password=mypassword" -nln i3dm.arbres abr_arbres_alignement.abrarbre.json

Added needed columns for i3dm.export

-- rename geometry column to expected geom
ALTER TABLE i3dm.arbres RENAME COLUMN wkb_geometry TO geom;

-- add tags column
ALTER TABLE i3dm.arbres ADD tags varchar;

-- add rotation column
ALTER TABLE i3dm.arbres ADD rotation int;

-- set random rotation
UPDATE i3dm.arbres SET rotation = (random()*360)::int;

-- add model column
ALTER TABLE i3dm.arbres ADD model varchar(255);

-- set url to external model
UPDATE i3dm.arbres SET model = 'https://myhost/i3dm/models/tree_6.glb';

-- add scale column
ALTER TABLE i3dm.arbres ADD scale numeric;

-- set scale based on hauteurtotale_m, 7.8 is the model height in meters
UPDATE i3dm.arbres SET scale = round(CAST(hauteurtotale_m/7.8 as numeric),2)::float WHERE hauteurtotale_m != 0;

-- set random scale between 5 and 20 meters where the tree height is unknown
UPDATE i3dm.arbres SET scale = round(CAST(floor(random() * (5 - 20) + 20)/7.8 as numeric),2)::float WHERE hauteurtotale_m = 0;

image

jailln commented 3 years ago

Thanks! It works like charm.

Do you consider opening a PR ?

bertt commented 3 years ago

I did a quick test with the getting started data (https://github.com/Geodan/i3dm.export/blob/main/docs/getting_started.md) and adding extra --cesium parameter.

Results:

INSERT into spatial_ref_sys (srid, auth_name, auth_srid, proj4text, srtext) values ( 4979, 'epsg', 4979, '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ', 'GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137.0,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0.0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943295],AXIS["Geodetic latitude",NORTH],AXIS["Geodetic longitude",EAST],AXIS["Ellipsoidal height",UP],AUTHORITY["EPSG","4979"]]');
bertt commented 3 years ago

Got it fixed by not using the terrain in the Cesium client:

From

    var viewer = new Cesium.Viewer('cesiumContainer', {
    terrainProvider : Cesium.createWorldTerrain()
    });

to:

    var viewer = new Cesium.Viewer('cesiumContainer', {
    // terrainProvider : Cesium.createWorldTerrain()
    });

Live demo: https://bertt.github.io/cesium_3dtiles_samples/samples/instanced/traffic_lights/

bertt commented 3 years ago

Show batch table information is also working

image

tebben commented 3 years ago

Maybe epsg 4979 can be changed to 4326 so no changes are needed to PostGIS, the only difference is that 4979 is 3D and 4326 2D but the heights for boundingVolume.region are in meters above or below WGS 84 ellipsoid anyway.

It does look like that there is a slight offset on the rotation, I can see it in your demo but also in my tests with cars, street lights and trees. I need to look into this.

We also should look into cmpt tiles before creating a PR, I think the problem sits in the i3dm.tile library.

edit: Just tested with converting the tilebounds to 4326 (radians) instead of 4979 (radians) and seems to work just fine.

bertt commented 2 years ago

Updated code with Cesium support is in branch feature/cesium-support (will be merged soon). Also the Getting started document is updated with Cesium https://github.com/Geodan/i3dm.export/blob/feature/cesium-support/docs/getting_started.md

So closing this issue.