ThinkGeo.com    |     Documentation    |     Premium Support

WmsOverlay ScaleMin/ScaleMax and useless requests to the server

Hello,


To avoid useless web requests sent to a WMS Server, is there a way to limit the view of a WmsOverlay to a specific range of scale?


ScaleMin and Max are set in the WMS Server itself and can be obtain using a GetCapabilities request, but it seems that MapSuite doesn't use those informations.


In fact, it seems that no GetCapabilities request is done by MapSuite. So, useless requests are also sent when the viewing BoundingBox is out of the WMS Layer BoundingBox.


Thanks


Nicolas



 


Hi, Nicolas
WMSOverlay is an overlay that implements the GETMAP interface for WMS Server in the purpose of displaying maps and simplifying tile handling. So, if you want to control the behavior of this overlay as you said, to limit the BoudingBox of the overlay inside of the WMS Layer BoudingBox , you have to implement the GETCAPABILITIES request generating and response handling yourself, in this way , you can retrieve all the information of WMS Layers available on the WMS Server.
In fact, MapSuiteCore has done the job in TiledWmsLayer, unfortunately, as MapSuiteCore is not built against Silverlight runtime, we cannot reference MapSuiteCore in the Silverlight client program, we have to find another way out, like I mentioned in above.
Thanks for your information, any further question please let us know.

James



Thank you James, 
 Do you have some recommendations to implement this? 
 I guess I have to inherit the WmsOverlay class, use a GetCapabilities request while initializing an abject of this new class, and trap the requests sent to the WMS server.  
  
 Am I correct? 
  
 Thank you 
 Nicolas

Nicolas, 
  
 Yes, you are right. Just follow that way to implement a CustomWmsOverlay, when you complete if you want to us to integrate your code to our Silverlight control we can do it. Before you complete if you encounter any problem or if you want to us provide sample code to you please let me know. 
  
 Thanks, 
 James 


Hello,


I can't find the correct method to override to trap the requests before they are submited to the server.


Do you have some samples of this?


Thank you


Nicolas



 


Hi Nicolas,
I’ll provide you a very simple sample at the end of this post, by using the CustomWmsOverlay, you can trap the request just inside the BoundingBox of the WMS Layer. In fact, it’s just the Draw method you need to override to implement the trapping. You can apply the class to the HowDoI Samples, UseWMSOverlay sample, replace WmsOverlay with this CustomWmsOverly, and see if it works.
public class CustomWMSOverlay : WmsOverlay
    {
        RectangleShape layerBoudingBox;
 
        public CustomWMSOverlay()
            : base()
        {
            GetCapabilities();
        }
 
        private void GetCapabilities()
        {
            //To be implemented.
        }
 
        public RectangleShape LayerBoudingBox
        {
            get
            {
                if (layerBoudingBox == null)
                {
                    //Actually this part is not necessary because we will initialize the BoundingBox in the consturctor, this is just for test
                    layerBoudingBox = new RectangleShape(-180, 90, 180, -90);
                }
                return layerBoudingBox;
            }
        }
 
        public override void Draw(RectangleShape worldExtent, OverlayDrawType overlayDrawType)
        {
            //trap the request inside the BoundingBox,if the requested BoundingBox goes outside of the Layer, we do nothing.
            if (!(LayerBoudingBox.Contains(worldExtent)))
           {
                base.Draw(worldExtent, OverlayDrawType.DoNotDraw);
            }
            else
            {
                base.Draw(worldExtent, OverlayDrawType.Draw);
            }
        }
}
 
 
Any further questions please feel free to let me know.
Thanks.
James

Hi James, 
 I tried your solution using the HowDoI samples and a more testable BoundingBox (RectangleShape(-180, 90, 0, -90)).  
 It’s not working: 
 - the draw method is not called for each tile, but only one time per interaction, 
 - WMS requests are always submited to the server, when I zoom on UnitedSates (MinX and MaxX < 0) or when I zoom on CentralEurope (MinX and MaxX > 0)  
  
 Thanks 
 Nicolas

 


Hi Nicolas,
Let me make it clear that the code sample we provided is just for the purpose of showing how to override the Draw method of CustomWmsOverlay and control the request submitting in certain condition. It’s just a prototype of the CustomWMSOverlay, and you should have your own implementation of the overridden Draw method, in order to restrict the requested extend or accomplish other tasks.
In the sample class, the process of the Draw method is more like a single tile way, once the requested extend is not inside of the LayerBoundingBox, no WMS request will be submitted to server. If you want to handle the WMS requests tile by tile, you’ll have to override the DrawCore method, and that’s totally a different case from the sample.
For your first concern, it’s correct that the Draw method will be called just once, because it’s the DrawCore method that deals with tiles, not the Draw method.
It’s a strange case, as you described in your post, that zoom on CentralEurope there will still be WMS requests submitted to the server, but I’m not sure about that, because I can’t see what exactly the world extend is passed in the draw method when performing the zooming on central Europe. If the program goes into the base.Draw(worldExtent, OverlayDrawType.DoNotDraw) branch there will be no request. So I’m guessing that maybe the center point of zooming is very close to the edge of the BoudingBox. In fact, you can restrict this kind of request by adding some other condition judgments in the overridden Draw method to make sure the program will go to the DoNowDraw branch.
Still you can have a try overriding the DrawCore method; there you can control the requests tile by tile.
Thanks you very much.
James
 

Hi James,


thank you for the explanations. I though indeed that the Draw method was used for each tile. For this I will try to override the DrawCore method.


About the Draw or DoNotDraw branch, I have just set the layerBoundingBox to (-180,90,0,90), and added a System.Diagnostics.Debug.WriteLine to the Draw method.


Here is the ouput when I zoom in the united states (which is in the BBox), and then in central europe (which is not in the BBox)



DoNotDraw worldExtent: (-147, 90, 125, -59) // Initial load of the World map

DoNotDraw worldExtent: (-147, 90, 125, -59) // Requested BBox os outside the

Draw worldExtent: (-97, 36, -80, 26) // When I zoom on the UnitedStates (Draw is normal branch)

DoNotDraw worldExtent: (11, 50, 28, 41) // When I Zoom on Central Europe (DoNotDraw is normal branch)



Bellow are the corresponding requests send to the WMS server. As you can see requests are always sent to server, even if we are in Draw branch or in the DoNotDraw branch.


 


wmssamples.thinkgeo.com/WmsServer.aspx?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&EXCEPTIONS=application/vnd.ogc.se_inimage&FORMAT=image/jpeg&SRS=900913&PAGENAME=&EXTRA=&LAYERS=Countries02&STYLES=SIMPLE&BBOX=-180,0,-90,90&WIDTH=256&HEIGHT=256&UNIT=DecimalDegree&SCALE=147647947.5

...

wmssamples.thinkgeo.com/WmsServer.aspx?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&EXCEPTIONS=application/vnd.ogc.se_inimage&FORMAT=image/jpeg&SRS=900913&PAGENAME=&EXTRA=&LAYERS=Countries02&STYLES=SIMPLE&BBOX=90,-90,180,0&WIDTH=256&HEIGHT=256&UNIT=DecimalDegree&SCALE=147647947.5


Then when zoom on UnitedStates (BBox of the Map is fully inside the LayerBoundingBox)


wmssamples.thinkgeo.com/WmsServer.aspx?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&EXCEPTIONS=application/vnd.ogc.se_inimage&FORMAT=image/jpeg&SRS=900913&PAGENAME=&EXTRA=&LAYERS=Countries02&STYLES=SIMPLE&BBOX=-101.25,33.75,-95.625,39.375&WIDTH=256&HEIGHT=256&UNIT=DecimalDegree&SCALE=9227996.71875

...

wmssamples.thinkgeo.com/WmsServer.aspx?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&EXCEPTIONS=application/vnd.ogc.se_inimage&FORMAT=image/jpeg&SRS=900913&PAGENAME=&EXTRA=&LAYERS=Countries02&STYLES=SIMPLE&BBOX=-84.375,22.5,-78.75,28.125&WIDTH=256&HEIGHT=256&UNIT=DecimalDegree&SCALE=9227996.71875


 And when zooming on CentralEurope (BBox of the Map is fully outside the LayerBoudingBox)


wmssamples.thinkgeo.com/WmsServer.aspx?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&EXCEPTIONS=application/vnd.ogc.se_inimage&FORMAT=image/jpeg&SRS=900913&PAGENAME=&EXTRA=&LAYERS=Countries02&STYLES=SIMPLE&BBOX=11.25,45,16.875,50.625&WIDTH=256&HEIGHT=256&UNIT=DecimalDegree&SCALE=9227996.71875

...

wmssamples.thinkgeo.com/WmsServer.aspx?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&EXCEPTIONS=application/vnd.ogc.se_inimage&FORMAT=image/jpeg&SRS=900913&PAGENAME=&EXTRA=&LAYERS=Countries02&STYLES=SIMPLE&BBOX=22.5,39.375,28.125,45&WIDTH=256&HEIGHT=256&UNIT=DecimalDegree&SCALE=9227996.71875


Nicolas



Hi James, 
  
 I tried to override the DrawCore method and she is also called only one time and not for each tile.  
 For my mind, as the tile decomposition logic seems to be behind the DrawCore method, it seems that it is not possible to trap individual requests. 
  
 Thank you 
 Nicolas

James, 
  
 I tried to use an overriden version of the GetTileUri in my CustomWmsOverlay. It’s not very academic, but it seems to work fine. 
 What’s your feeling about this? 
 
        protected override Uri GetTileUri(Uri serverUri, RectangleShape tileExtent, int row, int column, int tileWidth, int tileHeight, double scale)
        {
            // Check if the tile BoundingBox is in the LayerBoundingBox
            if (LayerBoudingBox.Contains(tileExtent))
            {
                return base.GetTileUri(serverUri, tileExtent, row, column, tileWidth, tileHeight, scale);
            }
            else
            {
                return null;
            }
        }


Of course, using this method, it’s possible to check also the scale.

Nicolas, 
  
 I think it’s working with you indeed, I am glad you found solution by yourself.  
  
 Feel free to let us know if you have more questions. 
  
 Thanks, 
 James