Menu

#84 WMS (Web map service) support

3.0
tracked-on-github
nobody
Feature_Request
2015-08-30
2012-07-18
No

Add support to use templates downloaded from web map services. Suggested by Haavard Tveite.

Related

Tickets (Archive): #126
Tickets (Archive): #172

Discussion

1 2 > >> (Page 1 of 2)
  • Kai Pastor

    Kai Pastor - 2012-09-07
    • labels: --> Templates, Web
    • category: --> Feature_Request
    • milestone: 1.0 --> 3.0
     
  • Jan Dalheimer

    Jan Dalheimer - 2012-11-02

    Here is a first patch implementing this. It's not very good yet, as it integrates into the existing template system you have to open a file (content doesn't matter) with the .asp extension (could be anything else). You then have to specify the server and some other properties.

    Scaling is also not done yet.

    This is the server I have been using to test: http://www2.demis.nl/mapserver/request.asp

    If this is something that will eventually be merged I will continue working on it (don't have to open a dummy file and edit properties after initial load, saving/loading plus some other rough edges)

     
  • Kai Pastor

    Kai Pastor - 2012-11-02

    Jan, maybe you might do a fork of our git repository into a repository in your SF "user project" and use this for collecting your changes? This will give you full version control, and we don't need to keep track of to which revision the patches fit.

     
  • Jan Dalheimer

    Jan Dalheimer - 2012-11-02

    I have never made any more advanced usage of SF/git like that. I will have to look up how easy/hard it would be. (Mainly keeping my repo up to date and merging with the main stream again)

     
  • Thomas Schöps

    Thomas Schöps - 2012-11-03

    The patch itself looks good so far, as far as I can see from a short look at it. One nitpick however is to please respect our coding style (see the wiki), e.g. variables are named for example "server_edit" instead of "m_serverEdit".
    I'd prefer to have it in a working state before merging it into mater, i.e. the downloaded image must be displayed in the correct position at least and it must be possible to save / load the template.

    Maybe it is not so wrong to keep assigning the template with a file even for WMS templates, because this file can be used to cache the downloaded image. Then an internet connection is only neccessary when the template area is changed. Compared to embedding the image in the map file for caching it, this has the advantage that the map file can still be easily sent via e.g. email as the file size does not grow heavily.

    But the way of creating the template should be changed. Instead of selecting a template file to open, there should be for example another action "Create template" with sub-actions for the template type to create (WMS, or even normal blank images for using them with the "draw on template" functionality). Then the user would select a file to save the template to, instead of opening one. There is still a currently permanently disabled button "Create..." in the template setup dock which was intended for exactly that.
    Second, the template system must know that for this kind of template it is okay if the template file doesn't exist, otherwise it will be marked as missing when re-loading the map.

     
  • Kai Pastor

    Kai Pastor - 2012-11-04

    The cache will most likely be at directory, not a file. The menu item should be "Add template" with a submenu consisting of "File", "WMS", "OSM" etc.

    (BTW, I just looked at JOSM. They use the term "Background". "Template" has a different meaning in JOSM.)

     
  • Jan Dalheimer

    Jan Dalheimer - 2012-11-04

    So, I have forked oomapper here:
    https://sourceforge.net/u/jandalheimer/oorienteering/

    I have worked more on the WMS fetching there, could you take a look and tell me what is left to be done before a merge?

    It also includes creating of a blank template, this has not been tested much yet though.

    Two things that will need more work are sizing and georeferencing. The first is only approximately right now, I would have to take a look at the proj library for that, and on the second I would need some guiding on how georeferencing works in code.

    Jan

     
  • Kai Pastor

    Kai Pastor - 2012-11-05

    This fork seems to be a good tool for sharing your work at the moment. It is easy to browse your commits.

    On the georeferencing: As I understand WMS, you will get georeferenced images ("tiles"). Thomas recently added support for image file georeferencing by world files. This could give you some hint how to align your tiles. (You might save the tile and generate a world files for testing.)

    When the WMS does not use/support the geographic or projected CRS used by the OpenO map you will at least need to convert the coordinates (using proj).

    To further reduce distortions, it might become necessary to convert the images. This could be handled by gdal. (gdalwarp is an executable for that purpose.) But this is really not needed at the moment.

     
  • Jan Dalheimer

    Jan Dalheimer - 2012-11-05

    I already looked at the world file parts, but that didn't really help me.

    I've started to look at proj for the conversion, at least it seams like proj supports the EPSG:4326 projection used by most WMS servers.

    I don't exactly get georeferenced tiles, I request one tile of a size and with the coordinate extent I want. Here is a nice explanation of how it works: http://www.demis.nl/home/pages/wms/docs/opengiswms.htm

     
  • Anonymous

    Anonymous - 2012-11-05

    Before I continue looking at proj, is there any wrapper class or similar already used elsewhere?

     

    Last edit: Jan Dalheimer 2012-11-05
  • Kai Pastor

    Kai Pastor - 2012-11-05

    Did you look at georeferencing.h/.cpp? This where it is used and wrapped. georeferencing_dialog.cpp is using that API.

     
  • Jan Dalheimer

    Jan Dalheimer - 2012-11-05

    Is it as easy as this?:

    Georeferencing referencing;
    referencing.setProjectedCRS("", "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs");
    painter->drawImage(QRectF(referencing.toMapCoordF(LatLon(m_bb_rect.top(), m_bb_rect.left())).toQPointF(), m_image.size()), m_image);

    I don't really know how to check if it is right.

     
  • Thomas Schöps

    Thomas Schöps - 2012-11-05

    No, it's not as easy. The georeferencing stuff relates two or three coordinate systems to each other, but in your code you specify only one. In addition, you'd need to transform at least two corners of the image to map coordinates to get correct positioning (ideally every pixel would be transformed individually).

    Maybe the best solution would be to reuse ImageTemplate's positioning code, for example by calculating a "world file" for the image.

     
  • Jan Dalheimer

    Jan Dalheimer - 2012-11-06

    I've actually thought about making use of the TemplateImage code. I don't want to use it directly, as you may want to change parameters for the WMS map, but I will take a look at the TemplateImage code.

    Are these world files some standard?

     
  • Kai Pastor

    Kai Pastor - 2012-11-06

    Am 06.11.2012 07:08, schrieb Jan Dalheimer:

    Are these world files some standard?

    Did you google for "world file"?

    Kai.

     
  • Jan Dalheimer

    Jan Dalheimer - 2012-11-06

    Ups, didn't think about that...

    Ok, before I continue working on WMS templates:
    Should I merge WMS and normal image templates? The pros of that would be less code, the cons would be harder to update an already downloaded map.
    What do you think?

    If doing that: I can't find any reference to saving of world files. Is the data saved in the map file?

    Jan

     
  • Kai Pastor

    Kai Pastor - 2012-11-06

    No, don't merge WMS and image. Image is working and well understood. I'm not sure if we really understand how complex the WMS implementation can get, how different it will look like, and when it will be ready. If we find similar code, we can refactor later.

     
  • Jan Dalheimer

    Jan Dalheimer - 2012-11-06

    I don't think it will be so complex, but ok.

    I think it's wrong to go the intermediate step via a world file, as I then would have to take the code to reads the world file, and add that to the WMS template.

    I read through the template_image.cpp file, and found lines like this:
    MapCoordF top_left = map->getGeoreferencing().toMapCoordF(georef.data(), MapCoordF(-0.5, -0.5), &ok);

    From that I created this code:
    Georeferencing referencing;
    referencing.setProjectedCRS("", "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs");
    MapCoordF topleft_mapcoords = referencing.toMapCoordF(LatLon(m_bb_rect.top(), m_bb_rect.left()));
    MapCoordF mapcoord = map->getGeoreferencing().toMapCoordF(&referencing, topleft_mapcoords);
    painter->drawImage(QRectF(mapcoord.toQPointF(), m_image.size()), m_image);

    I think that might be more like it.

    Jan

     
  • Kai Pastor

    Kai Pastor - 2012-11-07

    The code example doesn't get it right. The GeoReferencing relates three coordinate systems for a georeferenced map:

    1. The Geographic CRS uses latitude and longitude (decimal degrees) relative to the datum WGS84. This is fixed in our GeoReferencing implemenentation at the moment.

    2. To put the world's surface on a plane, a projection and a cartesian coordinate system is used. This is what the the projected CRS is about. UTM serves a global standard here, but with regard to local base maps or aerial imagery, you might prefer another projected CRS. The projected CRS for the map is set (and cannot easily be changed) in map->getGeoreferencing().

    3. The map is a section of that plane, using yet another coordinate system measured in units of paper size.

    While conversion between 2 and 3 is simple (scale, reference point, rotation),
    the conversion between geographic and projected coordinates is complex - and delegated to proj. If you want to convert geographic coordinates to map coordinates then you can can simply use the map's GeoReferencing to get from LatLon to MapCoordF.

    When you ask for a flat image from a WMS, it will use some projection. If this projection is not the same projection which is used by map, you would have to reproject the image (as gdalwarp does). A simple transformation derived from the image corners will put many pixel in the wrong place.

    Even for geographic coordinates, you need to pay attention to the datum. Local data may use geographic coordinates based on another datum (such as "Potsdam" in Germany).

    The georeferencing dialog help page has some links which I found useful to learn about this topic.

     
  • Jan Dalheimer

    Jan Dalheimer - 2012-11-07

    Ok, seams like I took a topic a bit to high for me...

    Quote: If you want to convert geographic coordinates to map coordinates then you can can simply use the map's GeoReferencing to get from LatLon to MapCoordF.

    Does this mean I can use the function toMapCoordF(LatLon....... from the class Georeferencing from the object in the map object? Probably not, right?

    All WMS services seam to support EPSG:4326, and from what I found out, the following is the proj string for it:
    +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs

    Does it happen that this is exactly like the projection used for the map? A long shoot, but might save a lot of work.

     
  • Thomas Schöps

    Thomas Schöps - 2012-11-07

    You actually can use the map's georeferencing object like you wrote.

    It doesn't seem like all WMS servers would be strictly required to support EPSG:4326. Quote from the standard:

    "A WMS must support at least one CRS, and maps from multiple servers may be overlaid only if all the selected servers have at least one CRS in common. This International Standard does not mandate support for any particular Layer CRS(s). Instead, it only defines how CRSs are identified and discusses several optional Layer CRSs, in this clause and in Annex B. Map providers may support the CRSs that are most useful and appropriate to their geographic locale or information community. To maximize interoperability among servers, providers should also support geographic coordinates by geocentric coordinate systems such as “CRS:84” (see 6.7.3.2), “EPSG:4326” (see 6.7.3.3) or other ITRF-based systems."

    I don't know how the situation is in practice however.

     
  • Jan Dalheimer

    Jan Dalheimer - 2012-11-07

    I can?! Sounds nice, I'm going to try later today.

    I have used 4-5 servers for testing up till now, and they all supported EPSG:4326, and none other.

     
  • Jan Dalheimer

    Jan Dalheimer - 2012-11-07

    So is this all that is needed:
    MapCoordF mapcoord = map->getGeoreferencing().toMapCoordF(LatLon(m_bb_rect.top(), m_bb_rect.left());

    If yet, taking that for four corners and using that to transform the image should be rather easy.

     
  • Kai Pastor

    Kai Pastor - 2012-11-07

    The GeoReferencing class is indeed to make converting coordinates simple. You may select any of the three coordinate systems for the pointer position display.

    I really recommend studying the pages linked in the GeoReferencing dialog help page.

    The best strategy would be to ask the WMS for the same projected CRS that the map uses.

    EPSG:4326 is not really a projected CRS suitable for mapping, but the standard geographic CRS (latitude and longitude) with WGS84 datum and ellipsoid. In that regard it is not really surprising that this CRS is widely supported by WMS.

    If you simply interprete latitude and longitude as cartesian coordinates, distances are wrong (depending on direction), and shapes will be distorted. Cf. http://openlayers-buch.de/beispiele/chapter-07/compare_4326_31467.html. If you transform the corner points then the corner points will be right but most other points will still be wrong. Maybe the mistake is not significant for an orienteering map but I cannot tell. The smaller the tiles, the better.

     
  • Jan Dalheimer

    Jan Dalheimer - 2012-11-08

    I'm going to read through the links you recommended on Sunday afternoon (in plane then).

    As most WMS seam to exclusively support EPSG:4326, it will probably limit the amount of servers that can be used if we would choose to not support it.

    If transforming the corner points, the rest of the image would be sheared. Except if Mapper will be used for really large maps (probably not) I think normal shearing will be good enough.

     
1 2 > >> (Page 1 of 2)
Auth0 Logo