ThinkGeo.com    |     Documentation    |     Premium Support

Overlay redraw question

Good evening,


This question may have been answered, but when I search the forum with my keywords I get a huge number of matches and none so far are related to my question.  Here's what I'm doing:


(1) A single shapefile loaded into an overlay; it contains municipal boundaries.


(2) A single InMemoryFeatureSource loaded into another overlay.  This layer has one point in it.


(3) Using code as shown in the "MoveAFeature" (TranslateByOffset) I move the position of the point 100 meters


(4) I then refresh JUST the overlay.


(5) I'm trapping the OverlayDrawn event and find that just moving the feature in the memory layer is resulting in what appears to be a redraw of BOTH layers.


This is a significant issue because when I have all my layers present in the first overlay on lower-end machines this redraw causes 100% CPU spikes and reported redraw times in excess of five seconds each time the GPS position is moved.  Can anyone explain to me why the "background" overlay is redrawing when nothing changes?  Is there some setting to suppress this?


Thanks!


Allen Huber



Ooops…in step (4) I mean I just refresh the overlay with the InMemoryFeatureSource.

Ooops…in step (4) I mean I just refresh the overlay with the InMemoryFeatureSource.

Ooops…in step (4) I mean I just refresh the overlay with the InMemoryFeatureSource.

Ooops…in step (4) I mean I just refresh the overlay with the InMemoryFeatureSource.

Ooops…in step (4) I mean I just refresh the overlay with the InMemoryFeatureSource.

Ooops…in step (4) I mean I just refresh the overlay with the InMemoryFeatureSource.

Allen, 
  
 The OverlayDrawn event will throw for each overlay, some overlay is drawn by image cache(shape overlay) , some overlay is drawn by really render logic(inmemory overlay), draw shape overlay from cache is very quick but it is needed because the two overlays like two papers, you must draw each one by order and then you can get result, if you only draw the one which is change, and then you only can see that overlay. 
  
 There are two ways to make you satisfied: 
 1. Raise event only when the overlay really draw. 
 2. Add a property to event args to let user know which type of draw. 
  
 Let me know if you have better idea. 
  
 Thanks 
 James

James, 
  
 Thanks for the response.  Everything you say makes sense.  I believe I didn’t quite put into writing what I was really questioning.  It was getting late and I’m mentally getting ready for a few days off.  We are looking at the time the OverlayDrawn event returns for performance tuning purposes.  For our production application (where there is a overlay of something like 20 or 30  unchanging layers–municipalities, highways, parks, etc.–that I call the “static overlay”) when I move a point in the memory layer and the “static overlay” OverlayDrawn event fires, it’s reporting times of several seconds, which, if the image is coming from a cache, makes no sense.   
  
 I believe the CPU spikes might be caused by something else which I am going to try to track down today. 
  
 So that brings me to two questions: 
  
 (1) Does OverlayDrawn accurately report a draw time if the overlay is drawn from the cache?  If it reports two or three seconds when the map is panned or zoomed (our production data comes from SQL Server, so we know that won’t be quite as fast as shapefiles) I can believe that, but this type of draw time (or worse) is reported even when I’m just manipulating and refreshing the memory layer, so if the shape overlay is coming from cache I don’t think it shouldn’t take several seconds, and don’t think it actually is.  I’m watching the process (outside of Visual Studio) in Perfmon and simply don’t see that kind of CPU load either on the program or SQL Server, so it doesn’t appear to be accurate. 
  
 (2) I looked and didn’t see this…is there anything in OverlayDrawnWinformsMapEventArgs that tells me if that overlay was completely redrawn as opposed to loaded from cache?  We’ve discussed this in the office here and we believe the event is returning the timing from the last time it really had to grab the data, instead of redrawing from cache.  If I knew the redraw was coming from cache, we could ignore the draw time. 
  
 Hopefully that makes more sense…I think the accuracy of the overlay draw time coming back from the OverlayDrawn event (especially if redrawn from cache) is leading us to the incorrect conclusion that the unchanged base overlay is being reloaded from SQL Server. 
  
 Whew!  Thanks! 
 Allen 
  


Sorry James, after rereading your original post for a second time, I think your suggestions are very close to my ideas.  I believe I would always want to know when the overlay is redrawn, be it from the database or cache, but knowing which–along with accurate overlay draw times if redrawn from cache–would be about all we could expect.  (I know the OverlayDrawnWinformsMapEventArgs also returns draw times for all the layers in the overlay.  I don’t know if it would be technically possible for them to be accuate as well, but if we knew the redraw was from cache these times would probably be of little or no value.) 
  
 Allen

Allen,


  I have not participated to this thread so far and I am not as familiar with it as James who helped you from the beginning but I would interject into the conversation. From reading your first post with the different steps that you are trying to do, it sounds to me that this is something pretty common. If I understand well, your basic concern is to redraw only the moving vehicle at each new position without having to refresh the entire map. We have a number of Code Commuity sample apps dealing with this scenario. They all show something different but they all respect that principle of drawing only what is necessary. I propose you take a look at those samples wiki.thinkgeo.com/wiki/Map_Suite_De...ng_Samples



Hi Val, 
  
 You are correct in what I’m trying to do, and it’s working. No problem there.  Eventually I got to the actual point. We are looking at the overlay draw time reported by the OverlayDrawn event.  When I move a single feature in a memory layer, the “background” overlay reports very large redraw times (two to five seconds, even more on low-end machines, depending on various things, which is typical of loading the data right from SQL Server) that simply don’t sound right if the data is being cached.  What it all comes down to is (1) if the overlay is being drawn from cache, why is the draw time being reported by MapSuite so large? and (2) it would be nice to know if an overlay is being drawn from cache or actual data retrieval, in which case I could ignore the overlay draw times if the event was telling me the redraw was coming from cache.  So…what I’m being told (and have to reason to doubt it) is that the background overlay is being drawn from cache, yet the OverlayDrawn event reports draw times equivalent to non-cached updates.  ANYWAY, the holiday is here and I’m hoping to shut down until Tuesday.  Catch everyone then, and enjoy Jan 1. 
  
 Allen

Allen,


Thanks for your post and efforts.
As far as I understand, the performance difference between cached case and uncased case will be very huge, especially for the large sized data overlay.
1) How many layers contained in the target overlay you are testing against? I guess it is 20~30 layers, right?
2) What kinds of cache system are you using against? It is FileBitmapTileCache?
I will do some tests and I think it would be more convenient if we can discussed based on some given sample.
Any more questions or concerns please feel free to let me know.
Thanks.
Yale

Hi Yale, 
  
 Our production application currently has five overlays.   
      1) The base mapping overlay contains all “display” mapping data that never changes; there are perhaps 30 layers, although in many instances some are empty (parking lots, land use, etc. are not available for all counties) while some, like roads, buildings, etc., have a lot of data.   
      2) There is a “dynamic” overlay which contains about a half dozen InMemoryFeatureLayers and MapShapeLayers containing stuff that changes, such as a GPS track, although most of the time they’re empty. 
      3) There is  a debug overlay that will probably not be in the production release. 
      4) There is an overlay containing two MapShapeLayers which use the ability to apply individual styles to each shape; no layer has a huge number of features. 
      5) There is an overlay containing just an InMemoryLayer that hold a symbol showing the GPS position. 
  
 One thing the boss has asked me to reinforce…we are pulling all of our data from SQL Server.  When the event for the base overlay fires but only a single overlay is refreshed, it reports back multi-second draw times, but we do not see any SQL Server activity, so it’s confusing to us as to where this large redraw time is coming from.  And we don’t know if the time being reported is just what it takes to get the map drawn or to also go out and get the data itsefl from SQL Server. 
  
 Your question about caching is interesting…I’m not doing anything explicitly, so perhaps that’s where the problem is.  The last time I got involved with MapSuite caching was probably 1-1/2 years ago (version 2?) and how it worked was never clear to me.  HOWEVER, I see there is a cache example installed and I will take a look at that right now. 
  
 OK, enough of this…I want to be out of the office by noon! 
 Thanks, 
 Allen 
  


Just to recap what Allen is working on: 
  
 If you zoom to a "new area" we get map draw times like: 
 1. Static overlay: 1.5 seconds 
 2. GPS overlay: 0.2 seconds 
  
 Then, move the GPS position on the GPS overlay and redraw just the GPS overlay, we get draw times as above.  
  
 When the map is redrawn we do know that Map Suite is not going back to the data to render the Static overlay. We know this because all the data is in MS SQL Server and we see no activity in SQL like we see during a map pan, or centering the map on a new position. 
  
 Our assumption is the GPS overlay is being redrawn when the position is moved and the Static overlay is "restored". Therefore the redrawn time for the Static overlay should be very small. But it is not. 
  
 Is our assumption on how the redraw is working correct (Static overlay is restored from memory and not rendered again)? 
  
 Should the draw time for the Static overlay be very small?

Allen,


Hope you have a great New Year holiday.
 
I want to remind 2 things which you may already have known:
1) I learnt from John that the performance will be greatly affected by indexing in SQL server. See more details in following post, it definitely a great finding.
gis.thinkgeo.com/Support/Dis...fault.aspx
 
2) I know that the performance will be greatly improved by setting the TileCache to the Overlay which is always take a long time to draw, please take a try against it and let me know if you have any questions about it.
 
Any more questions or concerns please feel free to let me know.
 
Thanks.
 
Yale

John, 
  
 Thanks for your joining on the discussion on this issue. 
  
 Normally the total time spent on the layer drawn consists of two parts: fetching data time and draw time.  Normally speaking, if you move from one given Lat/Long position to a very far away new area, the layer should go back to the data server (SQL Server) to fetch data needed, so I guess the “new area” you mentioned should be a place very near to the original Lat/Long position, in this way the data is cached, I remembered we have some posts talked about this issue before. 
  
 Even if the data is restored as we guessed, the other part for the time is the drawing time, this part cannot be ignored unless we cached the tile images into memory or disk files, and this part will always depends on the data size and data complexity, so I cannot say the 1.5 seconds you mentioned is too slow or not. 
  
 Any feedbacks or questions would be welcome. 
  
 Thanks. 
  
 Yale 


Let's back up a little.


Our question is this: Is the overlay drawn time the actual draw time, each time the map is redrawn?


In our example, the draw time for the "Static" overlay never changes even though the "first" draw would have to include fetching data. Each successive redraw (since the GPS overlay has change) does not include the fetch and therefore we think the time should be shorter instead of the same.


In regards to tile caching, etc. Since we will be adding map rotation in some scenerios, we assume the caching would not work. Can you confirm this too?



We created a video screen capture of problem we are experiencing. Hopefully this illustrates our question(s): 
  
 The video (17MB) is at: 
 ironcompass.com/media/Video_2011-01-04_141433.wmv 
  
 This is a live screen capture while using a program we created called “JustGPS” made with Map Suite 4.5x. 
  
 The video shows a moving green arrow that is in the “GPS” overlay. The rest of the map is in the “Static” overlay. The draw times for all the overlays can be viewed in a box at the lower right corner of the app. 
  
 Windows Task Manager is visible and shows 20MB swings in memory usage and CPU usage runs flat at 45% (+/-) for the “JustGPS” app. 
  
 As the “GPS” overlay draws, the draw time is updated along with the draw times of all overlays. We do not understand why the draw time for the “Static” overlay does not decrease after a redraw of the entire map, but while the GPS moves. 
  
 The “unlicensed” label on the “Static” overlay does not change positions when the “GPS” overlay is redrawn (the “unlicensed” label does move on the "GPS overlay as the "GPS overlay is redrawn). We have found this label to be helpful during debugging. 
  
 So, more questions:  
 1. Why is the “Static” overlay time not changing although it appears the layer is not being rendered again? 
 2. Why such memory swings and high CPU usage when we use the translate offset to move one single GPS coordinate on the map? 
  
 We so close to getting our app ready for alpha, this is the last piece and we can’t move forward until this is solved. Any help would be appreciated. 
  
 Thanks. 
  
 John 
  
  


John.  I’m a customer and I want to thank you for carrying the weight of this problematic issue.   Your documentation and description has been excellent.  I also look forward to the resolution. 
  
 In our app, we have 10 to 20 overlays.   Like yours, the “bottom” five to 10 overlays are “static”.  The data never changes.   We will often change the rendering style on something like the 15th overlay.   When we do that, we do an explicit Refresh on just that overlay, thinking that we will not need to render the entire map again.    But in most cases, we find that the lower layers are getting rendered again.    
  
 We are NOT using any tile caches.   When we started building the app, they were not stable, and we haven’t had time to stick our toe back into that water.  We use custom layers for almost all of our layers, though.  So I have an implementation of DrawCore in those layers.   I’ve instrumented that function to write diagnostics of the rendering time, layer name, etc and that displays in the output window.   So, like you, I know that we are rendering overlays that are on the “bottom” of the map as a function of refreshing an overlay that is on the top of the map, w/o changing the map extent. 
  
 I have not seen what the level of detail is on your “static” layer.  But in cases where we are rendering data from the WorldMapKit… road features, etc, it is not uncommon for the renderer to take the amount of time you are describing… without actually going back to the underlying data source for a data refresh. 
  
 My hope was that when refreshing a single overlay, MapSuite would be capable of using overlay-specific cached images to rebuild the “static” layers lying under the dynamic layer.    Seems that this should be possible w/o using the tile caching solution.    If it is the intent that this should happen, then I hope this thread helps track down the reason it is not behaving this way. 
  
 Thanks again for your efforts here.