I use the mapViewer from the example of https://docs.geotools.org/latest/userguide/tutorial/map/style.html
I would like to present the current scale (it's works ok in projected CRS), when I set WGS 84 in as map window CRS I'm calculating the scale with the distance in meters that I get from this (QGIS) function:
private static double calculateGeographicDistance( ReferencedEnvelope mapRectangle) {
// need to calculate the x distance in meters
// We'll use the middle latitude for the calculation
// Note this is an approximation (although very close) but calculating scale
// for geographic data over large extents is quasi-meaningless
// The distance between two points on a sphere can be estimated
// using the Haversine formula. This gives the shortest distance
// between two points on the sphere. However, what we're after is
// the distance from the left of the given extent and the right of
// it. This is not necessarily the shortest distance between two
// points on a sphere.
//
// The code below uses the Haversine formula, but with some changes
// to cope with the above problem, and also to deal with the extent
// possibly extending beyond +/-180 degrees:
//
// - Use the Halversine formula to calculate the distance from -90 to
// +90 degrees at the mean latitude.
// - Scale this distance by the number of degrees between
// mapRectangle.xMinimum() and mapRectangle.xMaximum();
// - For a slight improvement, allow for the ellipsoid shape of earth.
// For a longitude change of 180 degrees
double lat = (mapRectangle.getMaxY() + mapRectangle.getMinY()) * 0.5;
double rads = (4.0 * Math.atan(1.0)) / 180.0;
double a = Math.pow(Math.cos(lat * rads), 2);
double c = 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1.0 - a));
double ra = 6378000; // [m]
// The eccentricity. This comes from sqrt(1.0 - rb*rb/(ra*ra)) with rb set
// to 6357000 m.
double e = 0.0810820288;
double radius = ra * (1.0 - e * e) / Math.pow(1.0 - e * e * Math.sin(lat * rads) *
Math.sin(lat * rads), 1.5);
double meters = (mapRectangle.getMaxX() - mapRectangle.getMinX()) / 180.0 * radius * c;
return meters;
}
Then when I set the Rule of a layer that it should be shown from scale 1:1 to 1:100 000 it works fine when the map window is defined in UTM 33N. When I set WGS84 as the CRS for the map window, the layer turns on/off at the scale (my calculated scale, that I'm presenting) 1:30 000.
Somewere the map application is calculating the map scale since it turns on/off the layer when the scale reaches 1:100 000 (some internal scale calculated by the map application), but when this threshold is reached I'm calculating the scale to 1:30 000.
Shall I calculate the scale (for presentation) in another way? How is the scale calculated internally in the map application, and can I get the hold of this "internal" scale?