DynamicLayer Visible Items

Adrien

I am using the dynamic layer approach to display pushpins onto the map.

I need to change a part of the displayed content of the pushpins depending on the exact set of visible pushpins. Example: say the dynamic layer has loaded 3 pushpins, the content of each of them will be different whether only one is visible, or two are visible, or the three of them.

I thus need to refresh the content of the pushpins in any of these events:
i) a small change of the map center, which generally does not cause the dynamic layer to request new data but makes some pushpins appear (resp. disappear) because they were (resp. become) out of the view field
ii) a sufficiently large change of the map center, which does cause the dynamic layer to request new data and displays new pushpins
-- I need to know which exactly pushpins are being visible as some part of the content of the pushpins depends precisely on the current state of the visible pushpins set. --

Thus, my first attempt was to
- add an event handler to the CenterChanged event of the RadMap control to take care of the point (i), using the Map.LocationRect property to know which pushpins are being seen, and update their content consequently.
- directly treat the case (ii) in the ItemsRequest method of the class implementing IMapDynamicSource

However, this second step is problematic as the ItemsRequest method might be called several times if multiple dynamic regions are being seen in the current view field. I cannot update the pushpins content in the ItemsRequest method as other pushpins might arrive in a subsequent method call.
In other words, I need a way to know when a new set of data has been loaded by the dynamic layer and to access this entire set at once.

As far as I know, there is no event such as LayerLoaded in the dynamic layer, which would fire when all the data has been loaded.

Adrien

I already thought about this solution but I think it does not work for the following reason:
Depending on the region (and the level of zoom) one is currently seeing on the map, it might correspond to multiple "ZoomGrid" rectangles. In fact, if the map center is approximately equal to the corner of one ZoomGrid, the dynamic layer will have to load the data from the 3 other visible ZoomGrids. There is thus 4 calls to the ItemRequest method (implementing IMapDynamicSource) as far as I could see.

Making my previous question simpler: how can know when the dynamic layer has finished loading all the data - whatever the number of ZoomGrid currently visible?

Also this is important if I want to block the UI or show a busy indicator while the dynamic layer is loading items: I want the busy state to start on the first data request (<=> first ZoomGrid visible) and stay there until the end of the last request (<=> if there are multiple ZoomGrids visible).

Thank you for your help.

Adrien

Andrey

I think you can use the RadMap.ZoomChanging, ZoomingFinished, CenterChanging and PanningFinished events. The dynamic layer calls ItemsRequest method between pairs of these events.
You can know that the request process is started by the RadMap.ZoomChanging and CenterChanging events.
When one of these events occurs and then the ItemsRequest method is called then you can know that requests are started. When ZoomingFinished and / or PanningFinished event occurs then all requests are called.

Best wishes,
Andrey Murzov
the Telerik team

Browse the videos here>> to help you get started with RadControls for Silverlight

Adrien

Thanks for your answer. However, this is not exactly what I try to determine:

I need to know when all the requests done by the dynamic layer are completed (<=> the data of each request has been received by the client), and -not- when all the requests have been started.

As I wrote in my precedent message, I need to achieve some work on the requested data which can only be done when all the data has arrived. It would be trivial if the method ItemRequests was called exactly once whatever the map view, but as it can be called several times if multiple ZoomGrid are being seen, I need some event to notify me when all the data has arrived, so that I can run the algorithm.

Thanks

Andrey

The dynamic layer does not trace requests.
If you need to check that all requests are complete, then you can do it in the DynamicSource implementation.
Usually each call of ItemsRequest completes request by the CompleteItemsRequest method. I think you can register each request when it starts and then to unregister it when it complete. For example you can use a counter for this purpose (register of request increments it and the unregister operation decrements). If the request is unregistered and the counter contains 0, then it indicates that all requests are complete.
The sample code is below.

Nuno

I'm a Telerik fan and I need your help because I'm having difficulties updating my code to work with the Q3 release. It was working fine with the Q2.
The ItemsRequest method stopped working because its signature has changed (because IMapDynamicSource changed), we don't need the old signature with the Action callback anymore. Why?

One of the things I noticed (after inspecting for a couple hours) is that I couldn't add ZoomGrid instances to the dynamicLayer like this anymore (Q2 way):

this

.dynamicLayer.ZoomGridList.Add(newZoomGrid() { MinZoom = regionsLevelZoom });...
In order to get it calling the ItemsRequest method must be like this:

this

.dynamicLayer.ZoomGridList.Add(newZoomGrid(1, 1, regionsLevelZoom));
...
Also, I'm not using a webservice to request data. This means I can't do this as in the Items Virtualization demo:

It loads my regions ok but when I start zooming in or out it has some odd behavior. Starts shaking and blinking until it gets to the desired zoom level, and when it gets to a very detailed zoom (like city, street) KML layers are not visible anymore. Why is this happening?
(Is there any special reason users can't zoom in/out in the mentioned KmlImport demo??)

Andrey

In version 2010.Q3 we completely redesigned engine of the information layer to increase its panning and zooming performance on large data arrays. Now it can handle up to 1000 locations (compare with 150 in previous version) or map shapes with up to 100000 total points (compare with 10000 in previous version).

The dynamic layer was redesigned also. Currently it hides objects in invisible regions to increase performance. The dynamic layer is oriented to asynchronous data requests. So, at the moment when a data is obtained and the shapes should be passed to the dynamic layer then it should know the parameters which were passed with request (zoom level and region). These parameters are required, because the map environment such as zoom level and region could be changed. So, it will be incorrect to add shapes for example when zoom level has been changed to another according to ZoomGridList. Unfortunately it was impossible with simple callback from the Q2 version.

As a simple migration way you can change the code of dynamic source class to use a code which was designed for Q2 just using new delegate type instead of Action<System.Collections.ICollection> for callback. The sample code is below.

The KML layers are not visible for detailed zoom levels in example, because the Silverlight has some restriction with shapes calculation. In fact it uses the short type values for them. So, if the shape has a size that becomes larger than max short value while zooming then it is calculated wrong.

All the best,
Andrey Murzov
the Telerik team

Let us know about your Windows Phone 7 application built with RadControls and we will help you promote it. Learn more>>

Progress, Telerik, and certain product names used herein are trademarks or registered trademarks of Progress Software Corporation and/or one of its subsidiaries or affiliates in the U.S. and/or other countries. See Trademarks or appropriate markings.