ThinkGeo.com    |     Documentation    |     Premium Support

New guy wondering how best to approach this?

Hi all,


I am new to the Map Suite & World Map Kit components and am using it in a Vehicle location application I am writing.  I've now reached the "techncial questions" phase of evalutation, and am hoping I can run a few questions by you guys here.


I believe what I am trying to do to be simple enough considering all of the capabilities this kit provides, but since are a lot of options & this kind of mapping kit is new to me, it's not entirely clear to me which features I need start with to best accomplish what I'm trying to do.   


Here's what I'm trying to do:
  * I need to display a number of points points on the map representing from 1 to 100 vehicles as they drive around town, showing their current position which is updated frequently. 

*Each vehicle will have an icon, potentially a different icon for each vehicle, w/ some text, such as an ID.

* I'd like to display all points then have it zoom out to an extent that'll show all specified points.

* Vehicle positions will change frequently and I need pointers on making this happen in the fastest possible way.  The example "Efficiently move an image that represents a car" is pretty close to this, but on my PC it refreshing takes 1.5 to 2 seconds & with a lot of vehicles constantly updating their positions, the map would pretty much be in a constant state of rendering.   What would the recommended solution/approach be?
   

 

Thanks!



Would there perhaps be a way to determine if a given coordinate is w/in the current view , convert that that to a screen coordinate, and draw the icon on the conceptual equivelant of a "WindowLayer" such that it's a transparent window that's being updated w/ vehicle positions & not redrawing the entire map?






 


Wes,


Welcome to the community, hope you enjoy sharing and learning here!


Here is a sample in which I added 2 points and rendered them with different icons. Also you can see how to render the ID as text on it, and how to get the extent which includes all the truck points. Please have a look at the codes and hope that helps.




 private void EfficientlyMoveACarImage_Load(object sender, EventArgs e)
        {
            winformsMap1.MapUnit = GeographyUnit.DecimalDegree;
            winformsMap1.MapBackground.BackgroundBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean);

            // Setup the shapefile layer.
            ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer(@"..\..\SampleData\Data\Countries02.shp");
            worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1;
            worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            winformsMap1.StaticOverlay.Layers.Add("WorldLayer", worldLayer);

            InMemoryFeatureLayer truckLayer = GetInMemoryFeatureLayer();
            winformsMap1.DynamicOverlay.Layers.Add("TruckLayer", truckLayer);

            truckLayer.Open();
            // Get the extent which includes all the truck points.
            winformsMap1.CurrentExtent = truckLayer.GetBoundingBox();
            winformsMap1.CurrentExtent.ScaleUp(20);
            truckLayer.Close();
            winformsMap1.Refresh();
        }

    private InMemoryFeatureLayer GetInMemoryFeatureLayer()
        {
            // Set the columns of the inMemoryFeatureLayer
            InMemoryFeatureLayer inMemoryFeatureLayer = new InMemoryFeatureLayer();
            inMemoryFeatureLayer.Columns.Add(new FeatureSourceColumn("IconType", "string", 10));
            inMemoryFeatureLayer.Columns.Add(new FeatureSourceColumn("ID", "string", 10));

            // Set up the 2 features
            Feature truck = new Feature(0, 0);
            truck.ColumnValues.Add("IconType", "Truck");
            truck.ColumnValues.Add("ID", "1");

            Feature semiTruck = new Feature(100, 0);
            semiTruck.ColumnValues.Add("IconType", "SemiTruck");
            semiTruck.ColumnValues.Add("ID", "2");

            // Add the 2 features into the feature layer
            inMemoryFeatureLayer.InternalFeatures.Add("truck", truck);
            inMemoryFeatureLayer.InternalFeatures.Add("semiTruck", semiTruck);

            // Add the value style to render the point with different icons
            ValueStyle valueStyle = new ValueStyle();
            valueStyle.ColumnName = "IconType";
            valueStyle.ValueItems.Add(new ValueItem("Truck", new PointStyle(new GeoImage(@"C:\Program Files\ThinkGeo\Map Suite Desktop Evaluation Edition 3.0 (BETA)\Samples\SampleData\Data\Truck.gif"))));
            valueStyle.ValueItems.Add(new ValueItem("SemiTruck", new PointStyle(new GeoImage(@"C:\Program Files\ThinkGeo\Map Suite Desktop Evaluation Edition 3.0 (BETA)\Samples\SampleData\Data\Semi Truck.png"))));
            inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(valueStyle);

            // Add the text style to render the IDs
            TextStyle textStyle = new TextStyle("ID", new GeoFont("Arial", 20, DrawingFontStyles.Bold), new GeoSolidBrush(GeoColor.SimpleColors.Black));
            textStyle.YOffsetInPixel = 10;
            inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(textStyle);
            
            inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            return inMemoryFeatureLayer;
        }


About the performance issue, can you let me know how you update the features and did you use the method  Map.RefreshDynamic() to only redraw the dynamic overlay?


Our feature layer does the same way as you described. For example there are 10 points in a layer, if 6 of them are out of the current view, only the rest 4 in the view will be converted to a screen coordinate and drawn on the map.  So just added the feature to our feature layer, we will do all the dirty work for you.


Let me know if you have any issues.


Thanks,


Ben






Thanks for the sample, I’ll be working on this over the next few days, time permitting & I’ll be sure to test w/ 100 points to see how it performs.  
 The performance I mentioned earlier was as-is from the demo was using an InMemoryFeatureLayer w/ RefreshDynamic, which is pretty similar to this demo.  I’ll keep you posted on my results… 
 Thanks!

Thanks again for the pointer, this’ll work just fine. The demo seemed really slow & I worried about that, but in my test app it’s perfectly 
 fast enough, w/ a 200ish millisecond refresh time for 100 feature/points, and about 7.8 seconds for 10,000. 





 


Wes,


That's great it's fast enough. In fact, InMemoryFeatureLayer does not have index built-in and not supposed to have a high performance. Here we introduced the IndexedInMemoryFeatureLayer which will improve the performance a lot. Please have a look at the following posts and see if that can be helpful for you. 


Developer Blog:


gis.thinkgeo.com/Support/Dis...fault.aspx


Related post


gis.thinkgeo.com/Support/Dis...fault.aspx


Thanks,


Ben




I used the above code but when I test it for 800 features (points) it took 4 minutes to render. 
 Wes, what did you do to render 10,000 so quickly? 
  
 Could it not be possible to specify an icon in each PointShape when you create a ShapeFile then you could use the ShapeFileFeatureLayer?

Alta, 
  
 You cannot specify an icon for each shape record, but you can specify an Icon Type column, add different Icon Types for each feature when creating the shape file and use ValueStyle to render it,  like what shows in the above codes. Or another way is to add an IconPath column in the shape file and create your own PointStyle to render every record based on that IconPath, it’s not difficult as well. 
  
 Four minutes for 800 points, something must be wrong. Do you mind to share some of the codes so we can have a look what the problem is? 
  
 Thanks, 
  
 Ben

Thanks Ben for the quick answer. After a good night’s sleep I decided to have a look at the MapSuite examples  ;-) and DrawFeaturesBasedOnValues works perfectly for me. I define my own icon when I add the new ValueItem and I use ShapeFileFeatureLayer. Rendering for 1,600 features takes about 2 seconds.  
 valueStyle.ValueItems.Add(New ValueItem(“U”, New PointStyle(New GeoImage(“C:\uparrow.png”)))) 
 Kind regards 
 Alta

Good sleep is very important, Alta.  :-). Let me know if anything else I can help. 
  
 Thanks, 
  
 Ben