ThinkGeo.com    |     Documentation    |     Premium Support

WMSRasterLayer TIle Size

Hi Dennis,

It looks the four parts merge to the tile image you need.

I think the reason should be because zoomlevel is not the same between client side and server side, for render the target scale, the target size is not enough to cover all map, so it require four parts from deeper scale and merge them into one image and resize it.

So I think you can check the zoomlevel set to see whether the client side is the same as server side. and maybe you can try to require bigger size to see whether it can avoid sent multiply request.

Regards,

Ethan

hi Ethan,

What you’ve explained sort of makes sense. However, how is the ZoomLevel on the WMS Server made the same as on the client?

I’ve tried various zoom levels on the client and it does not change the number of requests. I also changed the TileSize on the client to 4096 x 4096 and it still makes two requests and takes 90 seconds to render.

What is confusing is that it is the client sending in the four URL’s and the Local WMS Server simply sends those same requests on to the Remote WMS Server. So it is the client that generates the requests. What controls the number of requests being sent by the client?

Thanks,
Dennis
OriStar Mapping, Inc.

Hi Dennis,

I think about more about this, because it’s a WMS layer, so your client side should get the capability from server side, and the capability should contains the target zoomlevels information.

In fact I am not clear about how you implement your client side, but the request number should be controlled by the client JS library, and I think if the JS library found the tile size is not enough for cover all map, it will cut it and sent multiply request. That’s why when you set 4096 x 4096 the tile number reduce to 2 from 4. So I think maybe you can did some research about the JS library to see whether it contains some property about set request number or close some possible feature which support map render more area than render requirement.

Regards,

Ethan

Ethan,

The client is WpfDesktopEdition using WmsRasterLayer. You might recall that I have a local WMS Server that then passed the request to a remote WMS Server. The GetCapabilites from the local WMS Server does not contain ZoomLevel’s.

Does the JS Library apply to WpfDesktopEdition? If so where is that library located?

Do you have any code snippets that demonstrate how any of this is accomplished?

Thanks,
Dennis

Hi Dennis,

Thanks for your remind, I thought you are using web forms as client side.

If that’s wpf edition, I will take some time to looks into the code and see whether I can find where is the problem.

Please wait my later reply.

Regards,

Ethan

Hi Dennis,

I build a simple sample, and found when you set the layerOverlay.TileType = TileType.SingleTile it only sent one request.

9124.zip (101.2 KB)

If you cannot set the tile mode equal single tile, I think you can try to modify the sample to reproduce that and we can discuss how to solve it.

Regards,

Ethan

hi Ethan,

Setting TileType=Single does indeed result in a single request to the WMS Servers. After seeing it in operation I now understand why there are multiple requests when TileType=MultipleTile. MultipleTile is multi-threaded resulting in multiple requests to the WMS Servers, which allows the rendering to begin immediately and take place a section at a time.

There is a side-effect with TileType=Single, which is that the map does not begin to render immediately. It only renders after the entire extent is composed, which is single-threaded. I much prefer TileType=Single, but it takes 3-4 seconds for the extent to be rendered which is slow to the users.

The WmsRasterLayer is contained within its own LayerOverlay. The remaining local layers are in another LayerOverlay. With the LayerOverlay WmsRasterLayer TileType=Single and the LayerOverlay for remaining layers TileType=MultipleTile the entire rendering is single-threaded. I was hoping that only the LayerOverlay used for WmsRasterLayer would be single-threaded, but that’s not the case.

One of our customers, with only 50% of their workstations in production, generates 300,000 WMS Server requests per day. Once deployment is 100% there may be as many as 500,000 WMS requests per day. This is putting a strain on our third-party WMS Provider.

I’d like to find a solution so that only one WMS Server request is sent with the other LayerOverlay’s rendered by multi-thread. I would like to work with you to find a solution to this dilemma.

At some point I’d like to engage ThinkGeo about how to get better response times for TileType=Single.

Thanks for your help.
Dennis
OriStar Mapping, Inc.

Hi Dennis,

The problem is, even if we find a way to make multi-thread only sent one request, that also means the multi-thread only have one thread, and it’s in fact the single tile mode. Because one request need to wait the same time from server side.

The solution should be find a way to make the response speed too faster, so it’s a problem between server side and client side.

I remembered you used cache in server side, so if multi-thread is faster than single tile mode, that means maybe it’s not a network problem, please double check your server side logic to make sure whether the cache works.

Regards,

Ethan

hi Ethan,

I’ve proven that if any LayerOverlay is set to SingleTile then all LayerOverlays operate as SingleTile.

When I set the LayerOverlay to SingleTile there is only one URL request sent to the WMS Servers.

The production network is 1GB and the Internet connection to our third-party WMS Provider is very large so we are not faced with a network issue.

Caching is not used because the third-party WMS Provider can install new imagery at any time and we don’t have to be aware or do anything special. If caching were being used the system would use old cached images instead of new imagery.

I actually prefer SingleTile mode since the extent displays all at the same time. The problem is that it takes 4 seconds to render and that is too long. I’d really like to see the render time as 1-2 seconds.

Dennis

Hi Dennis,

Just like I mentioned, one tile for multiply mode equal single mode.

It looks the performance bottleneck is in your server side, I remembered it’s a traffic station.

So maybe you want to do enhancement like this, your client side choose single mode, you add some logic in your server side, split the request to some part for example split one extent to four parts, sent them to the really web service multiply thread, merge them in your server side and sent that back to client side.

It looks a little complex, so that’s just a suggestion.

Regards,

Ethan

Ethan,

The local WMS Server is actually not a bottleneck. The issue is sending four requests to the remote WMS Server for each extent.

The goal is to send only one request per extent (based on TileBuffer of course).

What I realized today is that of the four requests being sent each has a size of 1680x1050. This really does not make sense to me if four requests are being sent. It would make sense to me that each of the four requests would have a size that corresponds to the area of the extent that they each are going to render. Seems to me a lot of extraneous requests are being sent. Why can’t one request be sent of 1680x1050? This is a real issue for customers that have high traffic systems.

Thanks,
Dennis

Hi Dennis,

It looks this problem is a little confused, let’s think about the scenario again and found where is the problem.

Please let me know if I missed any point.

  1. Your scenario is 3 parts, the A part is client side, it’s a WPF application, the B part is your server side, it get the request from A and sent that to C, the C part is 3rd part WMS server, you cannot control it.

  2. Now the A sent multiply request, for example 4 requests to B, and B sent also 4 requests to C, you want to reduce the number of requests from B to C.

  3. If you choose single mode in A, the speed is about double than multiply mode. You think the A to B is not the bottleneck.

So your requirement is, reduce the request number from B to C, and keep the render time in A.

If that’s correct, it’s not easy to solve. Because I think why the multiply mode is faster than single mode, that’s because it’s multi-threaded when sent request from B to C(A to B without bottleneck which means multi-threaded or not cannot save time in this process), if you want to reduce the request number from B to C, that means the using time have to increase. So this contradiction cannot be solved, more requests get faster and less requests get slower between B to C.

In fact single tile mode still get faster, because it save some area which is not in current extent.

So if your A is not a single user, I still suggest you create a cache system in B, if different A user request the same part, B don’t need to get from C again. If the data from C keep get changed, you can make the cache expired in fixed time period, so it make the B looks like a cache server of C.

Wish I hadn’t miss any important information.

Regards,

Ethan

hi Ethan,

My goal was to reduce the number of request coming out of the client as that then reduces the number of requests down stream. However, unless ThinkGeo rethinks rendering and allows both single and multiple LayerOverlays to operate independently this is not a path to follow.

As you’ve seen from my other post I’m going to implement caching and that will solve a good deal of the problem. But reducing the number of requests out of the client would also be a benefit for caching.

I’d like to see ThinkGeo allow different Tile Types to co-exist and would also like ThinkGeo to address rendering times in both Single & Multiple Tile.

Regards,
Dennis
OriStar Mapping, Inc.

Hi Dennis,

I understand what’s your problem, but I think your test result maybe incorrect about single tile and multiply tile.

I build a sample here, you can see the single tile works well with multiply tile just like it is designed.

And here is the sample:

 private void map_Loaded(object sender, RoutedEventArgs e)
    {
        map.MapUnit = GeographyUnit.DecimalDegree;

        LayerOverlay overlay1 = new LayerOverlay();
        overlay1.TileType = TileType.SingleTile;
        WmsRasterLayer layer1 = new WmsRasterLayer(new Uri("http://howdoiwms.thinkgeo.com/WmsServer.aspx"));
        layer1.SendingWebRequest += layer1_SendingWebRequest;
        layer1.ActiveLayerNames.Add("COUNTRIES02");
        layer1.ActiveStyleNames.Add("Simple");
        layer1.Crs = "EPSG:4326";
        layer1.OutputFormat = "image/png";

        overlay1.Layers.Add(layer1);
        map.Overlays.Add(overlay1);

        LayerOverlay overlay2 = new LayerOverlay();
        overlay2.TileType = TileType.MultipleTile;
        WmsRasterLayer layer2 = new WmsRasterLayer(new Uri("http://howdoiwms.thinkgeo.com/WmsServer.aspx"));
        layer2.SendingWebRequest += Layer2_SendingWebRequest;
        layer2.ActiveLayerNames.Add("COUNTRIES02");
        layer2.ActiveStyleNames.Add("Simple");
        layer2.Crs = "EPSG:4326";
        layer2.OutputFormat = "image/png";

        overlay2.Layers.Add(layer2);
        map.Overlays.Add(overlay2);
        
        map.CurrentExtent = new RectangleShape(-227.109375, 125.1321105, 48.515625, -72.4460145);
        map.Refresh();
    }

    private void layer1_SendingWebRequest(object sender, SendingWebRequestEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("Single Tile: " + e.WebRequest.RequestUri.ToString());
    }

    private void Layer2_SendingWebRequest(object sender, SendingWebRequestEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("Multiple Tile:" + e.WebRequest.RequestUri.ToString());
    }

Please let me know if your code have some different with the test scenario.

Regards,

Ethan

hi Ethan,

I’ve done more testing with the WmsRasterLayer LayerOverlay set to SingleTile and the other LayerOverlay’s set to MultipleTile.

The SingleTile and MultipleTile LayerOverlay’s do indeed render independently. However, when a request is made to move from one extent to another the MultipleTile LayerOverlay does not begin to render under the SingleTile LayerOverlay also renders so a delay of 2-3 seconds occurs and then the entire map is rendered all at once.

When a pan is performed it appears the MultipleTile LayerOverlay renders first, but is bogged down so to speak by the SingleTile LayerOverlay and again the panned-to section of the map is then rendered all at once.

I’m going to first implement caching and then come back to this issue and see if it is still a problem area.

Thanks for all of your assistance on this.

Dennis
OriStar Mapping, Inc.

Hi Dennis,

OK let’s talk about it after cache problem, in fact I hadn’t watched it in my simple sample, maybe we need more detail information about how to reproduce it and see whether it’s a bug.

Regards,

Ethan

MapSuite Team,

This topic was never resolved at the time, and it is rearing its ugly head once again as the condition persists.

Has there been any more thought by ThinkGeo on this issue?

Thanks,
Dennis

Hey @Dennis,

Can you expand on what exactly is still happening here? There were various topics discussing this thread about this. One was about the multple requests to the WMS, another about slow loads on SingleTile mode and another about caching. Can you expand on the issue a bit more? I know were were talking in another thread about the bottleneck to your WMS provider due to no load balancing. Is that still related?

Thanks,
Kyle

hi Kyle,

There was really only one issue in this thread. That being the client, running with TileType=MultipleTile, will send anywhere from two to four WmsRasterLayer requests to the local server for each move to a new extent. Each of those requests are then sent on to our WMS Provider.

It would be nice if the design was such that one request was sent and when the client received the response divide it up into the two or four individual extents and then pass those to the rendering process.

SingleTile Mode sends only one request, but then the rendering takes much longer, which is too slow for our users.

I am still working with our WMS Provider on resolving the bottleneck. I have added code to set WebRequest.Timeout to 20 seconds, where the default was 10 seconds. It’s been running for 24hours without reaching 100% on IIS Worker Process. Our provider is going to change their system from a minimum of 8 replicas to 16. I don’t know what a “replica” is, but doubling it sounds good.

If WmsRasterLayer can be changed to send one request in MultipleTile Mode, that would make the whole process much more efficient.

Thanks,
Dennis

Hey @Dennis,

For WMS, it requires that you specify a bounding box of the area that you want in the GetMap request.

In SingleTile mode, this is accomplished by taking the map’s newly changed bounding box and sending that to the GetMap request. Unfortunately, this means that the image that we get back is highly dependent on the size of your map. So if the map was fullscreen 1080p, it would request a full 1080p image. Likewise, a 4k map size would need a 4k image. This isn’t entirely efficient because if the user perfectly pans to the West by 10%, we still get the entire map’s extent and send that off to the remote server. This also increases the workload of the server proportionate to the size of your map, which is often why it is slow for users. You could override this behavior and instead request the difference area between the old and new bounding box, which would just be a tall vertical strip. The problem comes when the user pans the map diagonally. Even if just by one pixel, the difference area between the old and new bounding box would result in a request bounding box that would be the exact same as the new bounding box. If there was a way to provide the WMS an area rather than the bounding box of the area, then it might be more efficient. Unfortunately, this is not the case. An additional problem comes in when the user becomes impatient waiting for a result and keeps panning the map around, causing even more map requests to fire each time for a large image.

In MultipleTile mode, some of the inefficiencies of SingleTile mode get resolved at the expense of an increased number of requests to the WMS server. The map gets sliced up into a grid of 256x256 tiles and when the user pans the map to where a tile hasn’t been requested yet, we request a small image from the remote server. Because of this, it would be fairly difficult for this mode to make just one request. That said, this method resolves the issue with a map at 4k size. Rather than requesting a full 4k image, it requests several smaller images of only the newly exposed smaller tiles with the total dimensions not getting anywhere close to the full 4k map size. This also resolves issues pertaining to the user panning in small increments since it takes panning a full 256 pixels before requesting new tiles from the server.

So with those two methods described, there might be a bit of a hybrid approach that you could take, but it would take some engineering to get working properly. On the client side, set the TileType to SingleTile and also tack on an additional query parameter of the map’s previous bounding box. On your proxy server, use the incoming bounding box and the additional previous bounding box to get the vertical difference and the horizontal difference between the two. Then your proxy would make two requests to the remote WMS, one for the vertical and one for the horizontal. Once you get both results, stitch the two together and send it back to the client. This would simulate the perfect panning I described in the SingleTile section but with removing the need to get the full bounding box. An issue you would be met with would be the client only displaying the newest image because I believe it flushes the canvas, but you should be able to preserve it or store the previous canvas result while waiting for a response back. The downside of the user panning in small increments still exists in this method, however. And not to mention, this would be a fairly custom implementation that might require maintaining down the line.

Unfortunately, a perfect solution doesn’t really exist in this situation. A lot of issues might be resolved if your provider had a WMTS server, which uses that MultipleTile solution and also makes it really easy to cache the tiles on their side so that they don’t have to constantly query their backend imagery data every request, which is what I imagine is holding up a lot of those requests. And maybe by increasing the number of concurrent replicas will help resolve the issue already, but that largely depends on the volume of requests coming in.

Thanks,
Kyle