Skip to content

feat: Add auto_webmercator to COG#1893

Closed
sharkAndshark wants to merge 10 commits intomaplibre:mainfrom
sharkAndshark:cog_web_5
Closed

feat: Add auto_webmercator to COG#1893
sharkAndshark wants to merge 10 commits intomaplibre:mainfrom
sharkAndshark:cog_web_5

Conversation

@sharkAndshark
Copy link
Copy Markdown
Collaborator

To fix #1820 .

@sharkAndshark
Copy link
Copy Markdown
Collaborator Author

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

@sharkAndshark
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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;
}
}

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

fn new_sources_with_config(
Copy link
Copy Markdown
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)

@@ -13,6 +13,11 @@ use crate::{MartinResult, TileInfoSource};
pub struct CogConfig {
Copy link
Copy Markdown
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

@Auspicus
Copy link
Copy Markdown
Contributor

@CommanderStorm / @sharkAndshark what's the current status of this one? Is there anything I can do to help take it over the line?

@sharkAndshark
Copy link
Copy Markdown
Collaborator Author

sharkAndshark commented Jan 13, 2026

I had a new full time job that have no too much time on this project this year.

It was almost there but the structure of Martin has been changed.

  1. The first step should be following the new code structure , (just copy and paste should be enough)
  2. Update some default configuration in this PR based on talking above
  3. And update tests.
  4. Update doc either if you changed the configuration etc

You could PR to my branch or just add a new PR, I'd love to review ❤️ @Auspicus

@CommanderStorm
Copy link
Copy Markdown
Member

The first step should be following the new code structure

I already have done that part, I think.
Just the hard part of integrating it is left.

@sharkAndshark
Copy link
Copy Markdown
Collaborator Author

sharkAndshark commented Jan 16, 2026

I've picked this one. And have reset to the latest main branch. A fresh start would be more easier as it's too far away from the latest changes.

@sharkAndshark sharkAndshark reopened this Jan 16, 2026
@socket-security
Copy link
Copy Markdown

socket-security bot commented Jan 16, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedcargo/​imageproc@​0.25.010010093100100

View full report

@sharkAndshark sharkAndshark changed the title Add auto_webmercator to COG feat: Add auto_webmercator to COG Jan 16, 2026
@CommanderStorm
Copy link
Copy Markdown
Member

Lets focus on #2510 instead, which seems much farther along.
Actually, I think that PR could be merged as-is

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

4 participants