Clustering of pins and shapes

Jun 3, 2009 at 10:48 AM

I went through the discussions about clustering pins. In our solution weI display events and tracking of mobile units. As such it is difficult to pre-define parent pushpins for clustering. What I have done in other systems is to override onRender to recalculate an equivalent of parent pushpins based on intersections.

Again, without modifying your VeMap control, is  there any event or override I can use to do this? I would obviously have to have the new extent of my view.

Alternatively, I saw that Ve Api's expose a VEShapeLayer which can be confgured for clustering. Could this mechanism somehow be used.

Thanks again for any suggestions

 

Coordinator
Jun 3, 2009 at 3:03 PM

Take a look at VEPushPin.UpdatePosition().  This contains the logic for animating in and out of the visible range (defined as between MinAltitude and MaxAltitude.)  The visible range is used in clustering as well, as when a PushPin is animating out of the MaxAltitude, if ParentPushPin is set, it will also animate the location towards the ParentPushPin.

You could subclass VEPushPin and override UpdatePosition to use a dynamic function to get the ParentPushPin for the current zone.

Yes VEShapeLayer has some clustering features, but those are all only for the Virtual Earth PushPins like you see on the web, not the WPF-based VEPushPin.

Jun 4, 2009 at 12:11 PM

 

Have had a look into UpdatePosition(), but haven't made progress on the clustering.

On the other hand I'm surprised to see that UpdatePosition is constantly called, even when no action is done on the map (pan, zoom,etc...)  It seems to me that changes in the pin properties should call for a refresh? Could you explain the logic behind this, please.

Also, I have bound the ItemsSource property of VEMap to an observableCollection<VEPushPin>. Adding pins to the collection is ok. But removing them or clearing the collection has no effect - I have to manually call veMap.RemoveRegisteredPosition(). - this actually also the case when using veMap.Items.Remoe(pin). As veMap is an itemsControl, shouldn't there be a listener handling this in the control itself.

Jun 4, 2009 at 3:38 PM

Continuing on this issue, if  I have a collection of say 100 pushPins, the app already becomes VERY slow and this with only 3-4 visible pins.

Even when no action is done on the vemap control, the app continually uses about 10% CPU and memory usage keeps increasing.

Thanks for having a look at this issue.

Coordinator
Jun 4, 2009 at 4:17 PM

UpdatePosition updates the screen position of the pushpins and is called for each pushpin every time Virtual Earth renders a frame, which runs about 30 fps.  It does this because there are many things that can cause the map to move, including pan, zoom, each update of a cinematic FlyTo, or the control itself being resized or moved, which the control may not even know about.  Each time these happen, the PushPins need to translate their Lat/Long into screen coordinates and update their positions.

I'll check on removing pushpins when I get a chance.  This previously worked fine but I may not have checked that again since I added the registered position code. 

About hidden pushpins, are you using the VEPushPin.PinVisible property?  The actual Visible property is used in the UpdatePosition() function when hiding pushpins, but it checks with PinVisible to see if you want it hidden regardless.

Jun 4, 2009 at 6:03 PM

What I meant by hidden is that they weren't visible in the viewed area - I was letting UpdatePosition calculate isVisible.. But even so, I now have a collection of a 100 pins on which I've set PinVisible = false, and the app is very slow.

Jun 4, 2009 at 6:17 PM

Sorry previous text went off too quickly. I wanted to add that I'm still not understanding why Virtual Earth would render frames at a rate of 30fps if I just leave the app running on the screen without any kind of interaction. When you say Virtual Earth, do you mean the MS GlobeControl?

Coordinator
Jun 4, 2009 at 9:21 PM

Yes, the MS GlobeControl is Virtual Earth.  It uses Direct3D and redraws itself at approximately 30 fps.  This control grabs those frames and copies them into a buffer used by a D3DImage, which shows Direct3D buffers within WPF.  At the same time the pushpins are updated.

I have deployed apps with this control using a fairly large number of PushPins (> 500) using clustering without slowdown.  The number of visible pushpins is what matters.  I believe performance starts to slow down at around 50-100 on screen pushpins, depending upon computer specifications.  If you are getting bad performance with no pushpins visible, I would recheck your other assumptions about the application.  Try with zero pushpins, or try replacing VEMap with a some other simple itemscontrol and put the pushpins in there.

Coordinator
Jun 4, 2009 at 9:21 PM

BTW I haven't tried hosting VEPushPins outside of the VEMap so I don't know for sure what will happen, but it should work.

Jun 18, 2009 at 11:32 AM

Here's what I've come up with:

I have created a class called ProximityClustering that uses regions and intersections to find overlapping pins and dynamically create parent pushpins.

I have subclassed veMap to override RaiseViewChanged (maybe I marked it as virtual, can't remember)

 

 

<font size="2">

 

</font>

 

protected override void RaiseViewChanged() {<font size="2">

 

</font>

 

base.RaiseViewChanged();<font size="2">

 

</font>

 

ProximityClustering.Cluster(this); }

Finally I have overridden UpdatePosition of the VePushPin where I simply ignore the altevent ( I did cheat a little though marking some properties of the VEPushPin as virtual ) and also added a PushPinType enum to distinguish parentPins from other pins.

At first glance it all works well, except that the parentPushPins are sometimes a little slow at apearing.

Let me know if you're interested in the ProximityClustering class. I'll clean up and upload as patch.

 

Coordinator
Jun 18, 2009 at 2:49 PM

That would be a helpful addition.  I'll create an issue linked to this thread.  Follow the link to the issue and upload there and I'll see about integrating it into the next release.

One problem with distinguishing a pushpin as either parent or not parent is that you can have multiple layers of clustering.  For example, in one of our apps, when zoomed all the way out you have one pushpin for a particular city, then when zoomed to the city it expands to pushpins for various neighborhoods.  When zoomed to the neighborhood level, it expands to individual addresses.  So conceptually each pushpin could be a parent and a child and must be treated both ways.

Coordinator
Jun 18, 2009 at 2:51 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.