MapStore2 icon indicating copy to clipboard operation
MapStore2 copied to clipboard

BIL Terrain layer improvements or alternatives

Open allyoucanmap opened this issue 3 years ago • 3 comments

Description

This is a list of improvements or alternatives that we could investigate:

  • investigate on caching server side of BIL terrain
  • investigate the use of images instead of buffer array (see Mapbox Terrain-DEM v1)
  • serve terrain with static quantized-mesh tiles (see https://github.com/tum-gis/cesium-terrain-builder-docker)

Other useful information

allyoucanmap avatar Oct 05 '22 07:10 allyoucanmap

@set-reminder Wednesday

simboss avatar Oct 05 '22 15:10 simboss

Reminder Wednesday, November 9, 2022 12:00 AM (GMT+01:00)

octo-reminder[bot] avatar Nov 04 '22 01:11 octo-reminder[bot]

🔔 @simboss

octo-reminder[bot] avatar Nov 08 '22 23:11 octo-reminder[bot]

Test with cesium-terrain-builder-docker

Followed the steps described in the readme under the Cesium Terrain Builder usage section changing only the mounted data folder location. Main issues I found while testing this library are:

  • the .tif file needed to be adjusted by converting the -32767 values to 0 to avoid glitchy cliffs (maybe there is a better approach)
  • once the tiles are generated they have the .terrain extension. The server hosting the terrain tiles needs to add the header Content-Encoding equal to gzip to all the .terrain file responses in this way the Cesium library is able to read them correctly. If this header is missing the terrain is not rendered by the client (below a simple test server example)

Additional information

  • area image

  • tools:

  • static server demo application that provides the correct header to the .terrain files

app/
├─ statics/
│  ├─ terrain-folder
├─ server.js

// server.js file

const express = require('express');
const app = express();
const cors = require('cors')
const port = 3000;

app.use(cors());

app.use(express.static('./statics', {
    setHeaders: (res, path, stat) => {
        if(/\.terrain$/.test(path)) {
            res.setHeader("Content-Encoding", "gzip");
        }
    }
}));

app.listen(port, () => {
    console.log("app is listening on port 3000");
});
  • layer configuration in mapstore
{
    "type": "terrain",
    "provider": "cesium",
    "url": "http://localhost:3000/terrain-folder",
    "visibility": true
}
  • test in mapstore v2023.01.00

https://user-images.githubusercontent.com/19175505/231393957-eb743e75-85d8-4499-af05-f35a133e8098.mp4

allyoucanmap avatar Apr 12 '23 08:04 allyoucanmap

@allyoucanmap let's proceed moving processed tiles into our server to start evaluating performances and to be able to evaluate further steps. @randomorder we will need your support for this eg:

  1. Where we can put processed tiles

  2. The setting of the header for served tiles as specified above by @allyoucanmap

once the tiles are generated they have the .terrain extension. The server hosting the terrain tiles needs to add the header Content-Encoding equal to gzip to all the .terrain file responses in this way the Cesium library is able to read them correctly. If this header is missing the terrain is not rendered by the client (below a simple test server example)

tdipisa avatar Jun 15 '23 09:06 tdipisa

Is there private / sensitive data in these tiles @allyoucanmap ? I need to understand if it's feasible to put the tiles in an S3 bucket. If private -> it will require authentication

randomorder avatar Jul 10 '23 10:07 randomorder

@set-reminder July 24, 2023

randomorder avatar Jul 10 '23 10:07 randomorder

Reminder Tuesday, July 24, 2023 12:00 AM (GMT+02:00)

octo-reminder[bot] avatar Jul 10 '23 10:07 octo-reminder[bot]

Is there private / sensitive data in these tiles @allyoucanmap ? I need to understand if it's feasible to put the tiles in an S3 bucket. If private -> it will require authentication

@randomorder I think we need also @tdipisa to answer this. Anyway I would like to start with just a bucket without authentication just to test the requests performances on a small subset of tiles. Probably we will need to work more on the client if the authentication is required. Just a though: it will be possible to restrict the use of this bucket to specific urls?

allyoucanmap avatar Jul 10 '23 12:07 allyoucanmap

I don't hink it's possible better to wait for tobia to be back

randomorder avatar Jul 10 '23 16:07 randomorder

🔔 @randomorder

octo-reminder[bot] avatar Jul 10 '23 22:07 octo-reminder[bot]

Reminder Monday, July 24, 2023 12:00 AM (GMT+02:00)

octo-reminder[bot] avatar Jul 12 '23 08:07 octo-reminder[bot]

I had a quick test. The content encoding header seems to be doable:

$ aws s3 cp  ./ s3://gs-terrain/  --content-encoding="gzip" --recursive
upload: 1\2\1.terrain to s3://gs-terrain/1/2/1.terrain
upload: 8\269\190.terrain to s3://gs-terrain/8/269/190.terrain
upload: 8\268\190.terrain to s3://gs-terrain/8/268/190.terrain
upload: 9\536\381.terrain to s3://gs-terrain/9/536/381.terrain
upload: 7\134\95.terrain to s3://gs-terrain/7/134/95.terrain
upload: 5\33\23.terrain to s3://gs-terrain/5/33/23.terrain
upload: 8\269\191.terrain to s3://gs-terrain/8/269/191.terrain
upload: 8\268\191.terrain to s3://gs-terrain/8/268/191.terrain
upload: 6\67\47.terrain to s3://gs-terrain/6/67/47.terrain
upload: 4\16\11.terrain to s3://gs-terrain/4/16/11.terrain
upload: 9\536\382.terrain to s3://gs-terrain/9/536/382.terrain
upload: 9\536\383.terrain to s3://gs-terrain/9/536/383.terrain
upload: 9\537\381.terrain to s3://gs-terrain/9/537/381.terrain
upload: 9\537\383.terrain to s3://gs-terrain/9/537/383.terrain
upload: 9\538\381.terrain to s3://gs-terrain/9/538/381.terrain
upload: 9\537\382.terrain to s3://gs-terrain/9/537/382.terrain
upload: 9\538\383.terrain to s3://gs-terrain/9/538/383.terrain
upload: 9\539\382.terrain to s3://gs-terrain/9/539/382.terrain
upload: 9\539\381.terrain to s3://gs-terrain/9/539/381.terrain
upload: 9\538\382.terrain to s3://gs-terrain/9/538/382.terrain
upload: 9\539\383.terrain to s3://gs-terrain/9/539/383.terrain
upload: .\layer.json to s3://gs-terrain/layer.json
upload: 0\0\0.terrain to s3://gs-terrain/0/0/0.terrain
upload: 2\4\2.terrain to s3://gs-terrain/2/4/2.terrain
upload: 3\8\5.terrain to s3://gs-terrain/3/8/5.terrain
upload: 0\1\0.terrain to s3://gs-terrain/0/1/0.terrain

$aws s3 cp  ./layer.json s3://gs-terrain/

Quick CURL test

$ curl -v https://gs-terrain.s3.eu-central-1.amazonaws.com/0/0/0.terrain -o ./0.terrain
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 52.219.47.140:443...
* Connected to gs-terrain.s3.eu-central-1.amazonaws.com (52.219.47.140) port 443 (#0)
...
< Content-Encoding: gzip
...

For reference this is the bucket policy that allows public access

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AddPerm",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::gs-terrain/*"
        }
    ]

This is the CORS policy applied to both the buckets

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]

@allyoucanmap please install AWSCLI : https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html

Then run aws configure using the provided Access Key and Secret:

$ aws configure
AWS Access Key ID [****************TX7C]:
AWS Secret Access Key [****************dVX6]:
Default region name [eu-west-1]:
Default output format [json]:

The command used for the upload is the one at the top of this comment

randomorder avatar Jul 12 '23 16:07 randomorder

Also created another bucket called "3d-layers" in the same region with same configuration. CORS confirmed working

@allyoucanmap ws able to autonomously update the content on both buckets

randomorder avatar Jul 13 '23 08:07 randomorder

Suggested improvement for the future @tdipisa:

  1. Use a custom domain *..geosolutionsgroup.com that requires enabling Web site hosting on the bucket, condfiguring SSL Certs and so on. it would take about 1 hour
  2. Look for performance improvements by changing the bucket configuration and adding a caching layer on top. Client side and Server side

randomorder avatar Jul 13 '23 08:07 randomorder

During my absence, reach out to @boukandouramhamed for assistance

randomorder avatar Jul 13 '23 08:07 randomorder

Upload steps (we are assuming a bucket with a terrain folder):

  • navigate to the local folder with the terrain tiles
cd ./<name-of-terrain>/
  • run the upload command
aws s3 cp  ./ s3://<bucket-name>/terrain/<name-of-terrain>  --content-encoding="gzip" --recursive
  • replace the layer.json file to get the correct content encoding
aws s3 cp  ./layer.json s3://<bucket-name>/terrain/<name-of-terrain>/

allyoucanmap avatar Jul 13 '23 08:07 allyoucanmap

🔔 @randomorder

octo-reminder[bot] avatar Jul 23 '23 22:07 octo-reminder[bot]

Results obtained using cesium quantized meshes are satisfying and the issue can be closed. A new dedicated issue will be created for this.

tdipisa avatar Sep 08 '23 09:09 tdipisa