ThinkGeo.com    |     Documentation    |     Premium Support

Best Approach for Displaying Radar Data in Near Real Time

As the subject states, I'm looking into ways to show radar tracks with ThinkGeo.  The tracks aren't currently in a database, instead they come to me in groups every second or so via a TCP connection.  I need to show different shapes/colors for tracks depending on criteria I receieve with the track locations.  Not every track is updated every second and I need to draw history trails for each track.  The history length is configurable.  I will also need the ability to let the user click on a track to view amplifying info.  There can be anywhere from 0 to 10,000 tracks visible at once, but we usually only see about 500 or so.


I'm not looking for a full code dump here, as I would expect it to take some time to generate.  What I'd be happy with is some direction in how to handle this.  I've been experimenting with inMemoryFeatureLayers and using a valueStyle to draw points with different pointStyleTypes which I like because I can change colors and sizes with code instead of drawing them in Fireworks or the like.  I'm trying to figure the best way to keep moving forward though, since drawing trails, for example, means moving a point and drawing a line from the last point to the current point.  Would I be better off putting every track with its trail in it's own layer and then just clear and redraw that layer when I get an update for that track?


We're trying to move to MapSuite from FransonTools where I just cleared and redrew all of the tracks and trails every time I got a track update.  This works surprisingly well even for say, 300 tracks each with 100 history points trailing them.  It's just the lack of continued development and some other limitations that are making us want to move to something more robust but still easy to use.


If I left some details out, please let me know...



Nate, 
  
   Interesting, just the kind thing we like to work on around here.  I have a few questions / clarification as you might have guessed I would.  I also, based on little knowledge, have an idea that you may find interesting as well. 
  
 Can you describe a little more about what a track is.  I will try and mirror back what I think you said.  A track is a group of points with lines between them.  Each point represents some data value at a point in time.  When the track gets updated then we plot a new point and connect the point with the old point with a line.  A track could look something like ‘0---------0------0—0–0’, pardon the crudity. 
 You receive updates to various tracks on small intervals.  You might have 500 tracks and of them ever few seconds you may get a new updated point for 10 of them.  Could you give me an idea of how many points come in every x seconds.  I am looking to get a rate of change. 
 Could you provide a screen shot?  If the data is sensitive you can e-mail it to support@thinkgeo.com and ask them to forward it to David & Ben. 
 When a point comes in and gets drawn I assume it has a color and style.  Does that color and style change at all as new points come in.  I mean does an existing point, already drawn, on the screen change?  This is a critical part because it determines how much image caching we can do. 
 What refresh rate do you want for the map itself?  You could get data in ever second however it might not mean anything to refresh every second.  There is only so quickly someone can analyze the information.  Depending on our method we could update sub second, so this is just a general question. 
  
 Ok, having asked a bunch of question here is my initial idea.  This idea assumes that points and lines already drawn do not change, or at least do not change often.  What I would consider is creating a custom overlay, this overlay would be the one refreshed all the time.  In the overlay I would have an in memory feature source of all of the data coming in off of the TCP/IP port.  You are going to need to be careful to get the data on a different thread than the UI to keep it responsive but that is another story. 
  
   This Overlay would work a little different than typical overlays.  What we would do is to create an in memory cache of bitmap tiles that represent the layer of tracks.  When new data comes in we determine which of the bitmap tiles it needs to draw on then we fetch it and draw the new data.  When the Overlay needs to refresh and draw it just gets the bitmap tiles for the screen area and draws the images directly on the map.  In this way each refresh you do not need to re-draw all of the tracks.  The tracks are already drawn on the in-memory tiles.  When you get a new batch of data from your tcp port then you only need to draw a few points and new lines on the bitmap tiles. 
  
   You can also write a clear method on the overlay to clear out the bitmap cache and force it to re-draw from the in-memory feature layer.  In this way you always have the complete data to re-draw from if necessary.  You may need to change a style of a track based on the user doing something etc.  My point is to only draw when you need to and to cache images when possible.  If you need to change the history for some reason when re-draw from scratch but that should be an exceptional case.  If we are able to get this method to work the refresh speed will be fast as heck and with little cpu overhead. 
  
 This is of course off the cuff and without knowing how all of the requirements.  This is really interesting though.  Thanks for posting this as it makes me think about other places we could use this kind of thing.  If you are brand new to Map Suite then welcome!  You will find out framework very extensible and easy to extend and customize. 
  
 David

I sent a screenshot to you as requested. 



This might seem haphazard, but I'll try to answer your questions... 



We don't show a point for each trail vertex location currently, but we do have a case where we need to.  For example, we might want to show a track with a trail that shows different shapes, sizes and colors describing what the data looked like for that time along the history.  I'd even like to take advantage of the transparency level to have the trail fade out to invisible at the oldest history point. 



It looks like we get about 10 to 100 track updates a second on an average run while we are tracking about 500 total. 



We currently update the entire map once a second as long as new data is coming in.  The data comes in on a separate thread and we use a simple timer to update the UI. 



I'm still trying to wrap my head around your suggestions as I'm a MapSuite newbie, but I just wanted to try to answer some of your questions before I went too far.



Nate, 
  
   Thanks for the picture!  Let me clarify some of my assumptions.  Each trail on the map seems to have some sort of head on it like a rectangle that is labeled.  Is this current location?  I want to make sure the trail are the dots.   
  
 Ok, let me explain a bit more about my idea.  This is assuming you want the optimum performance with the minimum overhead.   
  
 Break the rendering into two different layer.  The first layer is used for the trails.  This will be a bit fancy.  What we plan to do for that one is to create a kind of “add only” layer.  What I mean by that is normally a layer is re-drawn whenever it is displayed.  In your case 99% of the trail will be the same except for maybe adding a few new points to the ends of the trails.  To optimize this we can keep a bitmap cache of what was already drawn and then just add the new points to that.  This prevents us from having to draw all of the points in the track over and over on every refresh. 
  
 The second layer will be for the heads and labels of the trails.  These do change all the time however there are not many of them so dynamically drawing them is going to be very fast. 
  
 I think I have an idea of what you want and am itching to try this out.  I think the idea of a cached “add only” type of layer is really cool.  It is really useful for things that get updates but you need to display historic things as well.  Vehicle tracking could also take great advantage of this as well.  
  
 Do you mind if I code something up?  I know I don’t have all the requirements however I think you will be able to see what I mean when you see the code and how it works. 
  
 David

Yes.  Each trail has a head that marks the last known location for that track.  The trails look like dots in some areas, but are really made up of lines between historical locations as you drew earlier []---o--o-o---o---o (Just without a shape to mark the points).  I only used squares because I can't draw diamonds with FransonTools :D.


Your idea sounds perfect!  My only concern is whether will this let us remove the oldest points from the trail as the trail gets really long.  Right now, I keep adding to the trail until I have, say, 50 history points and then I remove one from the end every time I add one to the beginning.  To add even more complication, when a track is selected by the user, I then highlight the track (turn it white) and then expand the history trail to 500 or so.  These features can come later as long as the methodology we adopt now can handle it.


Thanks so much for the enthusiasm and help!



Nate, 
  
 If the history points still need to be upgraded, I’m afraid you also need to refresh the trail layer. The key point of the 2-layer method is to avoid keeping refreshing the constant data (trails in this case), for the varying data, we need to redraw to make the changes visible. 
  
 Although the oldest point need to be removed in every refresh, there are still a lot of constant trail points keeping the same. So maybe we can keep a bitmap cache for the major part of trails, and only refresh the change parts. For example, we cached the 11th to 50th points to 4 bitmaps (11th to 20th to bitmap1, 21st to 30th to bitmap2,…) and keep the 1st to 10th  points in memory, whenever we need to add the next point, we can remove the 1st point and add the 51st one to the memory. In this way we do not need to draw the 11th to 50th points until we draw the 61st point, when we need to remove the 11st to 20th points cache bitmap and create another one for 51th to 60th points.  
  
 To highlight the track and expand the history trail, I think you can create an inMemory layer for the trails and draw it on top of the other layers. 
  
 We will implement this trail layer ourselves when have time and see if it works fine, I think it will though. 
  
 Hope that helps, let me know if you have any issues. 
  
 Thanks, 
  
 Ben

Sure sounds reasonable enough to me.  I wouldn’t know how to do that yet, but I am still trying to make sense of the API and hopefully I will be able to fully understand your idea soon enough. 
  
 I definitely appreciate your time and will accept any help you can provide. 
  
 Thanks again.

You are always welcome, Nate :)