Skip to content

Conversation

@sharkAndshark
Copy link
Collaborator

To fix #1820 .

@sharkAndshark
Copy link
Collaborator Author

During a very intensive project deadline these days, would be back ASAP!

@sharkAndshark
Copy link
Collaborator Author

sharkAndshark commented Aug 16, 2025

Almost there and a quick verification:

This tiff file is from openlayers examples:

curl -o tci_original.tif https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/36/Q/WD/2020/7/S2A_36QWD_20200701_0_L2A/TCI.tif
gdalwarp -t_srs EPSG:3857 tci_original.tif tci_3857.tif
gdal_translate -of COG -co TILING_SCHEME=GoogleMapsCompatible tci_3857.tif tci.tif 
---
# Connection keep alive timeout [default: 75]
keep_alive: 75

# The socket address to bind [default: 0.0.0.0:3000]
listen_addresses: '0.0.0.0:3000'

# Number of web server workers
worker_processes: 8

# Amount of memory (in MB) to use for caching tiles [default: 512, 0 to disable]
cache_size_mb: 8

cog:
  auto_web: true
  sources:
    tci: /home/shark/repos/martin/.vscode/cog_auto_web/tci.tif
npm create ol-app my-app
cd my-app

Update the main.js in my-app:

import './style.css';
import {Map, View} from 'ol';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
import XYZ from 'ol/source/XYZ';

const map = new Map({
  target: 'map',
  layers: [
    new TileLayer({
      source: new OSM()
    }),
    new TileLayer({
      source: new XYZ({
        url: 'http://localhost:3000/tci/{z}/{x}/{y}',
        tileSize: 512
      })
    })
  ],
  view: new View({
    center: [3732694, 1882165],
    zoom: 14 
  })
});
image


/// Convert min/max XYZ tile coordinates to a bounding box values in Web Mercator.
#[must_use]
pub fn xyz_to_bbox_webmercator(
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have already a xyz_to_bbox actually but its result is not in 3857

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add it here?

Copy link
Member

@CommanderStorm CommanderStorm Aug 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, comparing in the doc string the two seems sensible.

Moreover, we should likely use xyz_to_bbox_webmercator in xyz_to_bbox (instead of copy and paste) and rename it to xyz_to_bbox_wgs84

Comment on lines -23 to -28
# Configured with a directory containing `*.tif` or `*.tiff` TIFF files.
martin /with/tiff/dir1 /with/tiff/dir2
# Configured with dedicated TIFF file
martin /path/to/target1.tif /path/to/target2.tiff
# Configured with a combination of directories and dedicated TIFF files.
martin /with/tiff/files /path/to/target1.tif /path/to/target2.tiff
Copy link
Collaborator Author

@sharkAndshark sharkAndshark Aug 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enable auto-web in CLI Next PR.

@CommanderStorm
Copy link
Member

Two comments (I am not sure if you want a review yet, but think getting these out of the way is nice)

  • I don't think auto_web is quite self-explanatory.
    How about convert_to_web_mercator_quad or something like tiling_scheme: web_mercator_quad?
  • Would be true by default not be a better call? I think this is what users most likely want..

@sharkAndshark sharkAndshark marked this pull request as ready for review August 26, 2025 05:32
Copilot AI review requested due to automatic review settings August 26, 2025 05:32
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@CommanderStorm CommanderStorm changed the title Add auto_webmercator to COG Add auto_webmercator to COG Aug 26, 2025
Copy link
Member

@CommanderStorm CommanderStorm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am really happy to see progress on this.

I have left a few comments below, but the three where we need to align on are:

  • I don't think auto_web is not quite self-explanatory.
    How about convert_to_web_mercator_quad or something like tiling_scheme: WebMercatorQuad?
  • Would be true by default not be a better call? I think this is what users most likely want and this would match the default of maplibre…
  • Do we need this setting to be per-source configurable, or would this being a global setting be sufficient?

- /path/to/target1.tif
- /path/to/target2.tiff
# Default false
# If enabled, martin will automatically serve COG as a [WebMercatorQuad](https://docs.ogc.org/is/17-083r2/17-083r2.html#72) service, the tiles will be cliped and merged internally to be aligned with the Web Mercator grid.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# If enabled, martin will automatically serve COG as a [WebMercatorQuad](https://docs.ogc.org/is/17-083r2/17-083r2.html#72) service, the tiles will be cliped and merged internally to be aligned with the Web Mercator grid.
# If enabled, martin will automatically serve COG as a [WebMercatorQuad](https://docs.ogc.org/is/17-083r2/17-083r2.html#72) service.
# The tiles will be cliped/merged internally to be aligned with the Web Mercator grid.

- /path/to/target2.tiff
# Default false
# If enabled, martin will automatically serve COG as a [WebMercatorQuad](https://docs.ogc.org/is/17-083r2/17-083r2.html#72) service, the tiles will be cliped and merged internally to be aligned with the Web Mercator grid.
# Note: Just work for COG files with a Web Mercator CRS (EPSG:3857).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you clarify this comment?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Welcome any better description!
That's said martin would make the output tiles aligned with the WebMercatoQuad so clients no need to set the customized tilegrid. I would try to make it better again, and any suggestion? I'm pain in English 😂

nodata,
tilejson,
tileinfo,
web_friendly: auto_web,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets use the same name across the whole api ^^

Copy link
Collaborator Author

@sharkAndshark sharkAndshark Aug 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought I have fix this lolll still left one here..... And let's discuss which is better?

  • auto_web
  • web_friendly
  • convert_to_web_mercator_quad
  • WebMercatorQuad
  • Other suggestion? Maybe @nyurik have a better idea?

Comment on lines 176 to 190
/// find a zoom level of google web mercator that is closest to the given resolution
fn nearest_web_mercator_zoom(resolution: (f64, f64), tile_size: (u32, u32)) -> u8 {
let tile_width_in_model = resolution.0 * f64::from(tile_size.0);
let mut nearest_zoom = 0u8;
let mut min_diff = f64::INFINITY;

for google_zoom in 0..30 {
let tile_length = EARTH_CIRCUMFERENCE / f64::from(1_u32 << google_zoom);
let current_diff = (tile_width_in_model - tile_length).abs();

if current_diff < min_diff {
min_diff = current_diff;
nearest_zoom = google_zoom;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the only place where google is mentioned

Suggested change
/// find a zoom level of google web mercator that is closest to the given resolution
fn nearest_web_mercator_zoom(resolution: (f64, f64), tile_size: (u32, u32)) -> u8 {
let tile_width_in_model = resolution.0 * f64::from(tile_size.0);
let mut nearest_zoom = 0u8;
let mut min_diff = f64::INFINITY;
for google_zoom in 0..30 {
let tile_length = EARTH_CIRCUMFERENCE / f64::from(1_u32 << google_zoom);
let current_diff = (tile_width_in_model - tile_length).abs();
if current_diff < min_diff {
min_diff = current_diff;
nearest_zoom = google_zoom;
}
}
/// Find the closest web mercator zoom level for the given resolution
fn nearest_web_mercator_zoom(resolution: (f64, f64), tile_size: (u32, u32)) -> u8 {
let tile_width_in_model = resolution.0 * f64::from(tile_size.0);
let mut nearest_zoom = 0u8;
let mut min_diff = f64::INFINITY;
for zoom in 0..30 {
let tile_length = EARTH_CIRCUMFERENCE / f64::from(1_u32 << zoom);
let current_diff = (tile_width_in_model - tile_length).abs();
if current_diff < min_diff {
min_diff = current_diff;
nearest_zoom = zoom;
}
}

let mut nearest_zoom = 0u8;
let mut min_diff = f64::INFINITY;

for google_zoom in 0..30 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we use our MAX_ZOOM-constant instead?

path: PathBuf,
) -> impl Future<Output = MartinResult<TileInfoSource>> + Send;

fn new_sources_with_config(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets add a doc comment what this trait-fn does allow to do (per source configurable sources)

use crate::{MartinResult, TileInfoSource};

#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct CogConfig {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should not serialize auto_web if None => add the serde_with marker

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make COG web friendly

2 participants