Skip to content

Introduce PseudoMercatorUtils for accurate Web Mercator handling#3981

Merged
sebr72 merged 27 commits intomasterfrom
fix/scalebar-wmts-epsg-3857
Feb 13, 2026
Merged

Introduce PseudoMercatorUtils for accurate Web Mercator handling#3981
sebr72 merged 27 commits intomasterfrom
fix/scalebar-wmts-epsg-3857

Conversation

@sbrunner
Copy link
Member

@sbrunner sbrunner commented Feb 11, 2026

Replace #3827 to be able to finalize the pull request

See JIRA issue: EPSG-3857.

@sbrunner sbrunner marked this pull request as ready for review February 11, 2026 08:28
Copilot AI review requested due to automatic review settings February 11, 2026 08:28
@sbrunner sbrunner force-pushed the fix/scalebar-wmts-epsg-3857 branch from e5f2808 to f941e76 Compare February 11, 2026 08:31

This comment was marked as outdated.

@sbrunner sbrunner changed the title Introduce EPSG3857Utils for accurate Web Mercator handling Introduce PseudoMercatorUtils for accurate Web Mercator handling Feb 11, 2026
This commit introduces the useGeodeticCalculations parameter for maps.
When set to true for Pseudo-Mercator projections, it ensures more accurate scale and bounding box computations by accounting for Mercator projection distortions, especially away from the equator.

This change affects map bounds, scale calculation, and WMTS layer scaling. It also includes new unit tests and an example to demonstrate the feature.
@sbrunner sbrunner force-pushed the fix/scalebar-wmts-epsg-3857 branch from 849a62f to f419745 Compare February 11, 2026 10:28
From the artifact of the previous workflow run
@sbrunner
Copy link
Member Author

@copilot can you fix this error?

ClusteredMapPrinterServletTest > testCreateReport_Failure() STANDARD_OUT
10:40:19.282 [Test worker] INFO o.m.p.s.ServletMapPrinterFactory - Configuration file modified. Reloading...
10:40:19.282 [Test worker] INFO o.m.p.s.ServletMapPrinterFactory - Loading configuration file: file:/src/core/build/resources/test/org/mapfish/print/servlet/config.yaml
10:40:19.297 [Test worker] INFO o.m.p.s.j.impl.ThreadPoolJobManager - Submitted print job c96eee58-6e88-4a2d-a7eb-8958cb9f3342@88cd7ab2-fbbc-41c2-bec5-d1794d404e37
10:40:19.308 [Test worker] WARN o.m.print.servlet.BaseMapServlet - Error while processing request: Report has not yet completed processing
10:40:19.752 [PrintJobManager-1] INFO o.mapfish.print.servlet.job.PrintJob - Starting print application default, job c96eee58-6e88-4a2d-a7eb-8958cb9f3342@88cd7ab2-fbbc-41c2-bec5-d1794d404e37
10:40:19.754 [PrintJobManager-1] WARN o.mapfish.print.servlet.job.PrintJob - Error executing print job spec:
{"layout":"A4 Landscape","app":"default","outputFilename":"test\nreport-${yyyy}","attributes":{"requestHeaders":{"requestHeaders":{}}},"outputFormat":"png"}
c96eee58-6e88-4a2d-a7eb-8958cb9f3342@88cd7ab2-fbbc-41c2-bec5-d1794d404e37
org.mapfish.print.output.AttributeParsingException: An error occurred when creating a value from the 'geojsonMap' attribute for the 'A4 Landscape' template.

The JSON is: 
spec.attributes:
	{"requestHeaders":{"requestHeaders":{}}}
org.locationtech.jts.util.AssertionFailedException: Expected 0 but encountered 284: 
Errors were detected when analyzing the @OneOf dependencies of 'mapAttribute': 

	* The OneOf choice: MapBounds was not satisfied.  One (and only one) of the following fields is required in the request data: org.mapfish.print.attribute.map.ZoomToFeatures zoomToFeatures, org.mapfish.print.attribute.map.AreaOfInterest areaOfInterest, double[] bbox, double[] center
	at org.mapfish.print.output.Values.populateFromAttributes(Values.java:255)
	at org.mapfish.print.output.Values.<init>(Values.java:173)
	at org.mapfish.print.output.Values.<init>(Values.java:108)
	at org.mapfish.print.output.AbstractJasperReportOutputFormat.getJasperPrint(AbstractJasperReportOutputFormat.java:153)
	at org.mapfish.print.output.AbstractJasperReportOutputFormat.print(AbstractJasperReportOutputFormat.java:98)
	at org.mapfish.print.MapPrinter.print(MapPrinter.java:133)
	at org.mapfish.print.servlet.job.PrintJob.lambda$call$0(PrintJob.java:148)
	at org.mapfish.print.servlet.job.PrintJob.withOpenOutputStream(PrintJob.java:110)
	at org.mapfish.print.servlet.job.PrintJob.call(PrintJob.java:146)
	at org.mapfish.print.servlet.job.PrintJob.call(PrintJob.java:52)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: org.locationtech.jts.util.AssertionFailedException: Expected 0 but encountered 284: 
Errors were detected when analyzing the @OneOf dependencies of 'mapAttribute': 

	* The OneOf choice: MapBounds was not satisfied.  One (and only one) of the following fields is required in the request data: org.mapfish.print.attribute.map.ZoomToFeatures zoomToFeatures, org.mapfish.print.attribute.map.AreaOfInterest areaOfInterest, double[] bbox, double[] center
	at org.locationtech.jts.util.Assert.equals(Assert.java:75)
	at org.mapfish.print.parser.OneOfTracker.checkAllGroupsSatisfied(OneOfTracker.java:101)
	at org.mapfish.print.parser.MapfishParser.parse(MapfishParser.java:134)
	at org.mapfish.print.attribute.ReflectiveAttribute.getValue(ReflectiveAttribute.java:444)
	at org.mapfish.print.output.Values.populateFromAttributes(Values.java:225)
	... 13 common frames omitted
10:40:19.813 [Test worker] WARN  o.m.print.servlet.BaseMapServlet - Error while processing request: Report has not yet completed processing
10:40:20.317 [Test worker] WARN  o.m.print.servlet.BaseMapServlet - Error while processing request: org.locationtech.jts.util.AssertionFailedException: Expected 0 but encountered 284: 
Errors were detected when analyzing the @OneOf dependencies of 'mapAttribute': 

	* The OneOf choice: MapBounds was not satisfied.  One (and only one) of the following fields is required in the request data: org.mapfish.print.attribute.map.ZoomToFeatures zoomToFeatures, org.mapfish.print.attribute.map.AreaOfInterest areaOfInterest, double[] bbox, double[] center

Copy link

Copilot AI commented Feb 11, 2026

@sbrunner I've opened a new pull request, #3984, to work on those changes. Once the pull request is ready, I'll request review from you.

@sbrunner
Copy link
Member Author

sbrunner commented Feb 12, 2026

@sebr72 Now I think that this pull request is ready to be reviewed and merge (squash) :-)

@sbrunner sbrunner marked this pull request as ready for review February 12, 2026 11:13
Copilot AI and others added 11 commits February 12, 2026 12:14
When an attribute is missing from the request and has an empty default value,
throw ObjectMissingException instead of trying to parse with empty object.
This prevents OneOf validation errors on missing required attributes.

Co-authored-by: sbrunner <353872+sbrunner@users.noreply.github.com>
- Fix BBoxMapBounds.zoomToScale to propagate useGeodeticCalculations flag
- Fix WMTS computeExtraScalingFactor to use geographic CRS and map center
- Fix spelling errors in comments (degrees, geoWidth)
- Fix test name typo (Widthout → Without)
- Fix computeGeodeticBBoxInPseudoMercator to use destination positions
- Fix computeGeodeticWidthInInches to match calculator CRS with coordinates
- Fix isPseudoMercator to handle missing identifiers and be case-insensitive

Co-authored-by: sbrunner <353872+sbrunner@users.noreply.github.com>
Add detailed comment explaining why ObjectMissingException is thrown for
empty default values, clarifying the rationale for the framework.

Co-authored-by: sbrunner <353872+sbrunner@users.noreply.github.com>
From the artifact of the previous workflow run
Cast requestJsonAttributes to PElement as required by ObjectMissingException
constructor. All PObject implementations extend PAbstractObject which extends
PElement, so the cast is safe.

Co-authored-by: sbrunner <353872+sbrunner@users.noreply.github.com>
- Only throw ObjectMissingException for attributes with OneOf constraints
- Update test expectations for geodetic Y coordinates after fixing
  computeGeodeticBBoxInPseudoMercator to use getDestinationPosition()
- Update GenericMapAttributeTest to expect 17 fields (added useGeodeticCalculations)

Co-authored-by: sbrunner <353872+sbrunner@users.noreply.github.com>
From the artifact of the previous workflow run
The improved geodetic calculations produce slightly different results due to
more accurate destination position calculations. Increased tolerance from
0.00001 to 0.001 to account for acceptable rounding differences in geodetic
coordinate transformations.

Co-authored-by: sbrunner <353872+sbrunner@users.noreply.github.com>
@sbrunner sbrunner force-pushed the fix/scalebar-wmts-epsg-3857 branch from f4a5c06 to cbc524f Compare February 12, 2026 11:14
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.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 8 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

sbrunner and others added 3 commits February 12, 2026 15:12
…_EPSG_3857/requestData-test.json

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…_EPSG_3857/requestData-test_withoutBaseLayer.json

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…_EPSG_3857/requestData-test-useNearestScale.json

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@sbrunner
Copy link
Member Author

@sebr72 finally I finish this pull request :-)

@sbrunner
Copy link
Member Author

Except the unit test...

@sebr72 sebr72 force-pushed the fix/scalebar-wmts-epsg-3857 branch from 5313832 to e10f4c4 Compare February 13, 2026 21:28
@sebr72 sebr72 force-pushed the fix/scalebar-wmts-epsg-3857 branch from e10f4c4 to baca7bd Compare February 13, 2026 22:00
Copy link
Contributor

@sebr72 sebr72 left a comment

Choose a reason for hiding this comment

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

Great thanks

@sebr72 sebr72 merged commit b243efc into master Feb 13, 2026
15 checks passed
@sebr72 sebr72 deleted the fix/scalebar-wmts-epsg-3857 branch February 13, 2026 23:02
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.

4 participants