ThinkGeo.com    |     Documentation    |     Premium Support

Getting data from WMS servers

Hi.


I'm currently checking out Map Suite WPF-controls, aiming to show raster data from WMS-servers.


I started out with the "LoadAWmsImage" from the HowDoISamples, wich seems to work fine.


I'm having some problems though, using other WMS services than the one in the sample (wmssamples.thinkgeo.com/WmsServer.aspx)


At the moment I'm using this free WMS for testing: wms.jpl.nasa.gov/wms.cgi?, but I've encountered similar problems on many other WMS's.


Here is some sample code:


        private void ShowEarthMap()

        {

            string url = "onearth.jpl.nasa.gov/wms.cgi";

            MyMap.MapUnit = GeographyUnit.DecimalDegree;

            WmsRasterLayer wmsImageLayer = new WmsRasterLayer(new Uri(url));

            wmsImageLayer.UpperThreshold = double.MaxValue;

            wmsImageLayer.LowerThreshold = 0;

            wmsImageLayer.Open();



            RectangleShape bb = wmsImageLayer.GetBoundingBox();

            MyMap.CurrentExtent = bb;



            wmsImageLayer.ActiveLayerNames.Add("modis");

            wmsImageLayer.Crs = "EPSG:4326";



            wmsImageLayer.OutputFormat = "IMAGE/PNG";



            LayerOverlay staticOverlay = new LayerOverlay();

            staticOverlay.Layers.Add("wmsImageLayer", wmsImageLayer);

            MyMap.Overlays.Add(staticOverlay);



            // GetRequestUrl for debug

            string requestUrl = wmsImageLayer.GetRequestUrl(MyMap.CurrentExtent, (int)MyMap.Width, (int)MyMap.Height);

            Debug.WriteLine(requestUrl);

            wmsImageLayer.Close();



            this.Status.Text = requestUrl;

            MyMap.Refresh();

        }


Problem 1: Invalid Bounding Box.


Running the above code, the server responds with "Bounding box has an invalid area".


Examining the requesturl I see that it contains BBOX=-260.15625,-185.625,260.15625,185.625 while wimsImageLayer.GetBoundingBox() returns -180,90,180,-90.


Question 1:What can I do to avoid generating a request for non-existing bounding box?


 


Problem 2: Invalid format


A quick hack to solve P1 is to divide all coordinates of the bbox with 2, and then forcing a valid area in the requesturl.


Now, the server complains that: "The format "IMAGE/PNG" is invalid".


Fiddling with the requesturl in a browser, I can get a map shown if the format is changed to "image/png" (just lowercasing the format), but doing the same trick in my sample, I now get an exception from GetRequestUrl(..):  "This image format is not supported in the Wms server".


This, I think, is because the WmsRasterLayer does some validation of the parameters before the requesturl is generated. When examining the output of WmsRasterLayer.GetServerOutputFormats(), I see that this list contains the upper-case format, but not the lowercase format.


Question 2: Can I force case-insensitive validation or something else to get resolve this issue?


 


Problem 3: Invalid Crs


Failing to use the WMS from P1 and P2, I now tried another:


string url = "129.206.229.147/ors-tilecache/tilecache.py?";


wmsImageLayer.ActiveLayerNames.Add("ors-osm");


wmsImageLayer.OutputFormat = "IMAGE/PNG";


This gives me an exception when calling GetRequestUrl: "This CRS is not supported in the Wms server:"


Digging in to this problem I found out that wmsImageLayer.GetServerCrss returns an empty collection, so I guess that this is similar to P2: GetRequestUrl does some validation to the parameters, wich fails.


Question 3: Is there any way to bypass this validation. The WMS in question has several valid Crss?


 


I've tried with a few other available services but nevertheless I have not succeeded in displaying maps from other servers than the one available at: wmssamples.thinkgeo.com/WmsServer.aspx


Do you know of any other WMS services that works with WmsRasterLayer?





Thomas,


Thanks for your post and questions, hope my following answer can give you some hints.
                                                                                                     
1) About the bounding box sent to the server side.
When we set the CurrentExtent to the map control, we will do some judgment according to the Map Width and Height. The APIs can be found easily in the helper class ExtentHelper. For example:
ExtentHelper.GetDrawingExtent(extent, mapWidth, mapHeight);
 
2) About the Problem 2 and Problem 3, I think they belong to the same problem. As you know, the OGC set up a standards for the WMS. And we coding against very strictly according to the standards, and we set up a standard server which apply the standards very strictly.
 
Interesting enough though, I did some investigations on the open wms server provided by the OGC, and found that we also failed to support it. Following is the code:

 

WmsRasterLayer wmsImageLayer = new WmsRasterLayer(new Uri("labs.metacarta.com/wms/vmap0?"));
wmsImageLayer.UpperThreshold = double.MaxValue;
wmsImageLayer.LowerThreshold = 0;
wmsImageLayer.ActiveLayerNames.Add("basic");
wmsImageLayer.Open();            
Debug.WriteLine(wmsImageLayer.GetRequestUrl(winformsMap1.CurrentExtent, winformsMap1.Width, winformsMap1.Height));


Then I dig out the reason is that its OnlineResource set did not match its url which make the final string sent to the server is wrong. See following snap shot.  So it seems so strict WMS server is very rare.
 
 
 
Any more questions just feel free to let me know.
 
Thanks.
 
Yale
 

Q1: 
 OK, I’ve succeeded to calculate a usable scale ratio on the rectangle returned by GetDrawingExtent(…) and display some maps from the ThinkGeo WMS. 
  
 Q2+Q3: 
 Hmm. I’m then about to conclude that since there obviously are only very few standards-compliant Web Map Services, the Map Suite controls have very limited use if the only access you have to map-data is through a WMS. 
 That is a pity. 
 Do you have any plans to change the implementation of WmsRasterLayer, so that it can be used in environments where a standards-compliant WMS is not available? 
 One way could be to not trust the output of GetCapabilities and let the user configure the options. 
  
 /Thomas

Thomas, 
  
 Thanks for your input and suggestions.  
  
 Personally I agree with your suggestions, it seems too rigid to get all the information from the capabilities. We will consider this carefully and see if we can handle this in future. 
  
 Any more questions just feel free to let me know. 
  
 Thanks. 
  
 Yale 


I had hoped that the WmsRasterLayer was more mature than it currently is. I’ll take a look at it again later to see if things have changed, but for now it is unusable for our needs. 
  
 Thank you for your time. 
  
 Thomas

Thomas, 
  
 Thanks for your input and suggestions. 
  
 I think currently it seems the WmsRasterLayers can only be utilized when the WMS server is implemented in very strict standards, like our WorldMapKit Wms server. Hope we can get it enhanced in future. 
  
 Thanks. 
  
 Yale