jxmapviewer2 icon indicating copy to clipboard operation
jxmapviewer2 copied to clipboard

Using a WMS with other CRS/SRS (other then WGS84 EPSG:4326):

Open Ulathar opened this issue 4 years ago • 2 comments

Hello,

thanks for this great library. I was able to successfully use different OSM TileFactorys as well as placing Waypoints over the Map at the correct places (using the JXMapViewer). I also was able to use other public (not OSM based) WMS that are using WGS84 with the same Code as well (just had to add a different TileFactoryInfo for that).

But now I am confronted with a WMS that is not capable of WGS84 and thus forcing me to use EPSG:4647 (UTM32N) for ... reasons ... and I struggle to get this working with JXMapViewer. I tried to implement another TileFactoryInfo Class based on the examples in the library but obviously just giving another crs/srs (depending on WMS spec) is not enough.

I have three main problems right now:

  1. the calculations of the tiles to request (URLs) is wrong (obviously because the WGS84 transformation between display coordinate and real world coordinate is different to UTM)
  2. same applys to Waypoint Overlays which are placed wrong in the JXMapViewer because of the same reasons (Waypoint Coodinates are UTM32N, too and i guess the transformation to display coordinates is based on WGS84 as well?)
  3. i noticed that the requested tiles (no matter if wrong or right) are stored in a strange cache structure like: .../.tile_cache/<url_of_wms>/<wms_name>/WMS/<long_list_of_url_parameters>/<very_long_file_name_with_even_more_url_parameters> without .png ending (this could be because of to long windows file paths) instead of the expected structure: .../.tile_cache/tile.openstreetmap.org/0/0/0.png, etc.

Is there any example on how to do this kind of things right that I can look at?

Already though about including GeoTools in order to transform the UTM coordinates to WGS84 on the fly before giving them to the JXMapViewer but that would bloat up the program quite a lot (in size). Is this really necessary or is there a better way?

Here is a snipped from my current Test TileFactoryInfo that is obviously still based upon WGS84 transformations:

// Testing...
@Override
public String getTileUrl(int x, int y, int zoom) {
    int tileSize = getTileSize(zoom);
    zoom = getTotalMapZoom() - zoom;
    int z = (int) Math.pow(2, (double) zoom - 1);

    int m = x - z;
    int n = z - 1 - y;
    
    int tilesPerDimension = (int) Math.pow(2, zoom);

    double radius = (tileSize * tilesPerDimension) / (2 * Math.PI);
    double xmin = MercatorUtils.xToLong(m * tileSize, radius);
    double ymin = MercatorUtils.yToLat(n * tileSize, radius);
    double xmax = MercatorUtils.xToLong((m + 1) * tileSize, radius);
    double ymax = MercatorUtils.yToLat((n + 1) * tileSize, radius);

    if (xmax < xmin) {
        xmax = -xmax;
    }

    String bbox =  "";

    if (flippedAxis && version.equals("1.3.0")) {
        bbox = ymin + "," + xmin + "," + ymax + "," + xmax;
    } else {
        bbox = xmin + "," + ymin + "," + xmax + "," + ymax;
    }

    String url = getBaseURL()
        + "?SERVICE=WMS"
	+ "&VERSION=" + version
	+ "&REQUEST=GetMap"
	+ "&LAYERS=" + this.getLayers()
	+ "&FORMAT=" + this.getTileFormat()
	+ "&BBOX=" + bbox
	+ "&WIDTH=" + tileSize
	+ "&HEIGHT=" + tileSize
	+ (version.equals("1.3.0") ? "&CRS=" + this.getSrs() : "&SRS=" + this.getSrs())
	+ "&STYLES=" + this.getStyles()
	+ (this.getTileBgColor() == null ? "" : "&BGCOLOR=" + this.getTileBgColor())
	+ (this.getTransparent() == null ? "" : "&TRANSPARENT=" + this.getTileBgColor())
	+ (customParameters == null ? "" : customParameters);

	return url;
}

Ulathar avatar Sep 22 '20 10:09 Ulathar

Sorry for the late response. I will have a look, but I would be much easier if I could reproduce the problem. Which source are you using? Can you post the URL?

msteiger avatar Oct 15 '20 11:10 msteiger

Hey there no problem, thanks for the response! Used the time to find a "workaround" as well as upgrading to your latest v2.6 which required some unexpected minor refactoring on my side as well ;-).

For now I circumvented my original problem by using a GeoServer between the Client and the real WMS. That way I can use the posted variant above with EPSG:4326 coordinates and the GeoServer takes care of the on the fly reprojection of the foreign WMS that is not capable of handling EPSG:4326. So the scenario is now like this: -> Client using JXMapViewer2 (EPSG:4326) ---> GeoServer (EPSG:4326 -> EPSG:4647 reprojection using the Real WMS as Source) ------> Real WMS (EPSG:4647)

That works for now but if you have the time and motivation to look into the "non WGS84 stuff" I would be very interested ;-).

Maybe I am doing something wrong. That's why a little example on how to do things like this with your lib would be nice. Sadly I can't provide you the WMS link because it is an internal system that is not reachable in the internet.

Ulathar avatar Oct 15 '20 13:10 Ulathar