ThinkGeo.com    |     Documentation    |     Premium Support

Bypassing WmsRasterLayer internal validation?

I am using WmsRasterLayer to connect to user-configurable WMS sources (i.e.: user configures the WmsRasterLayer connection parameters).  In testing, I've seen that WmsRasterLayer seems to be performing an internal validation of at least some connection parameters against the capabilities published by the WMS source.  For example, if the map projection is not explicitly included in the CRS list published in the WMS capabilities, I see an exception like the following, apparently before any attempt is made to actually use the map CRS to retrieve a map from the WMS:




System.ArgumentException occurred
  Message=This CRS is not supported in the Wms server: <WMS server ULR>
  Source=MapSuiteCore
  StackTrace:
       at mBQ=.Qzw=.Pz0=(String QD0=, Collection`1 QT0=, String Qj0=)
  InnerException:



In theory, this would be fine.  However, we're also seeing that some WMS products are reporting either oddly formatted or incomplete CRS lists, and the validation is preventing request of map images that could actually be retrieved successfully.  Is there any way to bypass this validation in WmsRasterLayer (e.g.: via a property, event, or a virtual method)?  If not, is the only option to re-implement WmsRasterLayer from scratch?


Thanks,

Nicole



 Nicole,


Thanks for your post!


Can you use the following code to your application:


wmsImageLayer.DrawingExceptionMode = DrawingExceptionMode.DrawException;


This means we will catch the exception and draw it to show error happens, while you cannot catch it any more. If it won't meet your requirements, can you use WMSOverlay to instead of the WMSRasterLayer? For WMSOverlay it needs you to join the parameters for requesting the WMS image. If you set the incorrect projection SRID, it just returns the red X images and you will avoid the validation exception.


Any more questions please let me know,


Thanks,


Scott,



Scott, 
  
 Unfortunately, DrawingExceptionMode won’t help here since it doesn’t allow the call to the WMS server to proceed in the case of a CRS mismatch. 
  
 I wouldn’t mind trying WmsOverlay, but I can’t find it in any of the assemblies included in the MapSuite Desktop Edition. 
  
 Nicole

After a bit more Reflector spelunking, I suspect that I might be able to avoid the verification by overriding GetImageCore and GetRequestUrlCore in WmsRasterSource.  Unfortunately, even this works, it will mean re-implementing quite a bit of the WmsRasterSource logic…

 Nicole,


Sorry for the inconvenience, in the Desktop Edition you should use the TiledWmsOverlay, WmsOverlay object is in the Web Edition, you can refer the following code:


 



 Map1.MapUnit = GeographyUnit.DecimalDegree;
            Map1.CurrentExtent = new RectangleShape(-155.733, 95.60, 104.42, -81.9);

            //WorldMapKitWmsWpfOverlay worldOverlay = new WorldMapKitWmsWpfOverlay();

            TiledWmsOverlay overlay = new TiledWmsOverlay(new Uri("localhost:59387/WmsHandler.axd"));
            overlay.TileCache = null;
            overlay.Parameters.Add("Layers", "Display A Simple Map");
            overlay.Parameters.Add("Styles", "DEFAULT");

            Map1.Overlays.Add(overlay);

            Map1.Refresh();
  That's just a code snippet for you, it cannot be ran properly, please use the actual WMS url to replace the current one, also you need to join the special parameters for that WMS service. 


In addition, as you mentioned if you want to bypass the internal validation, you have to override the methods to implement it, I suggest you to use the TiledWmsOverlay first, if it cannot meet your requirements, then we can back to focus on the WmsRasterLayer. Do you think so?


Any more questions please let me know,


Thanks,


Scott,



Scott, 



Unfortunately, TiledWmsOverlay is pretty much useless for my scenario since it doesn't offer capability parsing. If I'm going to re-create capability parsing from scratch, I might as well implement my own version of WmsRasterLayer. If WmsRasterSource exposed more of its discovered capabilities to callers and/or inheritors, either approach would be considerably simpler. Unfortunately, given that much of the necessary capability information is only available via private, obfuscation-renamed members, it's not exactly useable. 



That said, I do have a kludgy solution based on a WmsRasterLayer subclass with GetImageCore and GetRequestUrlCore overrides. Unfortunately, it involves substituting the CRS so that it passes the validation. However, this could cause fairly serious problems given that WmsRasterLayer doesn't actually appear to use the CRS for adjusting either the bounds coordinates passed to the server or the results received from the server. i.e.: It looks like WmsRasterLayer will return incorrect results if the map coordinate system doesn't match the CRS transmitted to the WMS. If I'm wrong about this, then using any CRS should be fine, and the only potential problem with my CRS substitution approach would relate to performance. Could you please let me know if WmsRasterLayer is supposed to be performing the coordinate system conversions? 



Also, it would still be very useful to be able to bypass the CRS pre-validation. Might you consider moving this validation (the call to mBQ=.4zw=.3z0=(string, Collection<string></string>, string) in the obfuscated 4.0.34.0 MapSuiteCore assembly) into a separate virtual method in WmsRasterSource that is invoked from both GetImageCore and GetRequestUrlCore? This would a WmsRasterSource subclass to change/bypass the pre-validation behaviour without requiring rewriting of large portions of the WmsRasterSource code. 



Thanks, 

Nicole



Nicole, 
  
 I talked to our development team and discussed it deeply we think that’s an incorrect validation for the CRS. We just fixed this issue, however you should wait for the new package of development’s DailyBuild, so please get the latest version tomorrow.   
  
 Thanks, 
  
 Scott,

Scott, 
  
 In version 5.0.43.0, the CRS validation seems to have been removed from WmsRasterSource.GetImageCore but not from WmsRasterSource.GetRequestUrlCore.  Since GetImageCore invokes GetRequestUrl to determine the URL from which to retrieve the map image, the same exception is still raised.  Is this the intended behaviour after the fix? 
  
 Thanks, 
 Nicole

Nicole, 
  
 Sorry for the inconvenience, we missed the GetRequestUrlCore method when removing the invalid validate,  now I checked the whole WmsRasterSource file and the validate for wms crs all has been removed. Please get the new daily build from the development branch tomorrow, 
  
 Thanks, 
  
 Scott,

I’ve tested it on 5.0.47.0, and the CRS validation checks are indeed completely gone. 
  
 Thanks, 
 Nicole

Nicole, 
  
 We are glad it’s working with you. 
  
 Let us know if you have more questions. 
  
 Thanks, 
 James