Skip to main content
2 of 3
edited tags
nmtoken
  • 13.6k
  • 5
  • 38
  • 89

How do I calculate the map scale in WGS84

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?

Paul
  • 475
  • 2
  • 7