Dynamics layers

Jun 25, 2010 at 5:09 PM
Hi, It is the first time I'm using Deep Earth for a GIS project and I want to thanks for the great job done. My project use a combination of statics and dynamics layers, generated by the GWC and WMS Geoserver services. Means that dynamics layer's data sources are changing in time and those new values must be refreshed continously on the map. I used the RefreshSource() function but doesn't refresh the map so I'm trying to do it recreating some objects and none works out. Geoserver is working as I expect, new tiles are served fine by WMS service to the map. The problem is that I don't find a way to avoid that Deep Zoom cache the tiles loaded or tell it that forget o invalidate the ones that has been loaded. The best I get now is that the map show the new tiles after zoom in, for example, but if I come to the last zoom view, the map shows the old ones, with the old unchanged data. I'm quite far experienced with silverlight and "Deeps" controls and need some adviced on how can get this works. Thanks in advanced from Barcelona, José Angel.
Developer
Jun 26, 2010 at 8:04 AM

Isn't Geoserver Geo Web Cache (GWC) caching the tiles? Try to have a look with Fiddler and you see the requests being made  to your GeoServer.

Jun 27, 2010 at 9:14 AM
Edited Jun 27, 2010 at 9:15 AM

I've started receiving reports of this behaviour from my users of my DeepEarth application (www.synectics-tc.com/demo) when viewed using the SL4 runtime - but strangely it works as desired with the SL3 runtime. Using Fiddler confirms that it's the MSI control that is caching URLs. I did discover this post (http://betaforums.silverlight.net/forums/p/154151/345758.aspx) which suggested using MultiScaleTileSource.InvalidateTileLayer() to force the MSI control to flush it's cache.

I've managed to integrate those recommendations into DeepEarth by modifying TileSource.cs and ITileSource.cs. So whenever you wish to change the overlay layers collection, just call the new RefreshSource method on the TileSource i.e. MapInstance.BaseLayer.Source.RefreshSource(). You can download the changes I made at : http://maps.synectics-tc.com/downloads/TileSource.zip

The only down side is that if you're zoomed in and you call RefreshSource, you really notice the MSI progressively rendering all the lower zoom levels. According to MSDN, it should be possible to avoid this - http://msdn.microsoft.com/en-us/library/system.windows.media.multiscaletilesource.invalidatetilelayer(VS.95).aspx

"The InvalidateTileLayer method can be used to change the URIs returned for a tile layer. For example, if you have an implementation of a map and you want to zoom straight to street level, normally Deep Zoom would blend all the levels from 0 to 19. Instead, you can implement a MultiScaleTileSource class that returns null for all layers 18 and below. When a user starts to zoom out, you invalidate all the layers through 18, and return the proper URLs for the tiles instead."

I've not had chance to make these changes yet but its clearly possible because Bing Maps does it on http://www.bing.com/maps/explore. Any takers for adding this to DeepEarth ?

Jun 28, 2010 at 2:54 PM
Edited Jun 28, 2010 at 2:58 PM

Thank you for your reply and solution to fix the refreshing problem. And as you said, will be better if after refreshing the MSI doesn't render all the lower zoom levels, but this is less importat thing.

Just want to add some observations I've made about a pair of problems found in the control. I really don't know if, this functions I belived were incorrects, simply I'm not understanding it.

In TileSource.cs's function GetTileLayers there is a conditional I belived has no sense because _MapInstance.Layers is a enumerator of ILayer interface and there is no inheritance relationship between both interfaces; so the program never enter in the condition and the tiles from layers others than the base one, never get be loaded. I just replace ITileSource by TileLayer (ILayer doesn't have the 'Source' property) and get the Layers shown in the map.

if (_MapInstance.Layers != null && _MapInstance.Layers.Count > 0)
                {
                    foreach (ILayer me in _MapInstance.Layers)
                    {
                        //if (me is ITileSource)
      if (me is TileLayer)
                        {
                            //Add additional images sources if available
                            //Uri uri = (me as ITileSource).GetTile(tileLevel, tilePositionX, tilePositionY);
                            Uri uri = (me as TileLayer).Source.GetTile(tileLevel, tilePositionX, tilePositionY);
                            if (uri != null) tileSources.Add(uri);
                        }
                    }
                }

In other hand I got problems with 'TileColor' in WMS tile sources for layers (_MapInstance.Layers). If I don't want to add them as overlays of base layer the color must be transparent if I want see the layers behind.

Because we are using a different culture format for number representación in Spain, where dots are thousands separator and comma is the decimal separator, I had implicity to pass the US culture info parameter in the format string function.

Once again, thank you for your great job and help.

 

Developer
Jun 28, 2010 at 7:19 PM

when you use a TileSource, 

If you override GetTileLayers(int tileLevel, int tilePositionX, int tilePositionY, IList<object> tileSources)

then as you said you need to manually add any extra layer Uri's your self


if you override GetTile(int tileLevel, int tilePositionX, int tilePositionY)

then any TileSources you added to the "Overlays" will get loaded,

the example below, the overlay will automatically load, because in the NearMapTileSource class, the GetTile(int tileLevel, int tilePositionX, int tilePositionY) override is used

_mapInstance.BaseLayer.Source = new NearMapTileSource(NearMapModes.PhotoMap); 

_mapInstance.BaseLayer.Overlays.Add(new NearMapTileSource(NearMapModes.StreetMapOverlay));

thats if I understood what your saying in your post correctly?

 

Jun 29, 2010 at 8:31 AM

I'm using Map.Layers property for add new tilesources to the Map because I need a organized structure for the application. Then, when I expected to view the whole map in the screen, only the base layer were shown. Just after I made the change posted above, it starts to work.

But I think it's another problem. Is GetTileLayers called on every TileSource for the sames tiles coordinates level,X,Y? Then is it posible that exist duplicated tiles in the map?

Jul 20, 2010 at 9:39 AM
andrew_blake wrote:

The only down side is that if you're zoomed in and you call RefreshSource, you really notice the MSI progressively rendering all the lower zoom levels. According to MSDN, it should be possible to avoid this - http://msdn.microsoft.com/en-us/library/system.windows.media.multiscaletilesource.invalidatetilelayer(VS.95).aspx

"The InvalidateTileLayer method can be used to change the URIs returned for a tile layer. For example, if you have an implementation of a map and you want to zoom straight to street level, normally Deep Zoom would blend all the levels from 0 to 19. Instead, you can implement a MultiScaleTileSource class that returns null for all layers 18 and below. When a user starts to zoom out, you invalidate all the layers through 18, and return the proper URLs for the tiles instead."

I've not had chance to make these changes yet but its clearly possible because Bing Maps does it on http://www.bing.com/maps/explore. Any takers for adding this to DeepEarth ?

 Hi,

I made the changes to avoid the progresive rendering and want to show it and maybe propose the solution for DeepEarth. My understanding in DeepZoom functionality is not quite wide, probably there is a better one solution.

https://docs.google.com/leaf?id=0B2tjiWrYahyAMzQ3ZjgxZmUtNmQxOS00OWFiLThlZWUtMGRlMDViYWYyZDMx&hl=en&authkey=CP_c26IC

greetings

José Angel