ThinkGeo.com    |     Documentation    |     Premium Support

Correct use of InMemoryFeatureLayer V3.1.299?

After upgrading to version 3.1.299 i get warnings when using InMemoryFeatureLayer


Warning 29 'ThinkGeo.MapSuite.Core.InMemoryFeatureLayer.InternalFeatures' is obsolete: 'You are bypassing the automatic spatial indexing if the modify, add or delete. You need to call BuildIndex method later.


The way i use the layer:


   InMemoryFeatureLayer pointLayer = (InMemoryFeatureLayer)winMap.FindFeatureLayer(GetLayerName(LayerNameEnum.WindFarms));




         winMap.Overlays[GetLayerName(LayerNameEnum.WindFarms)].Lock.EnterWriteLock();

     try

     {

      InMemoryFeatureLayer pointLayer = (InMemoryFeatureLayer)winMap.FindFeatureLayer(GetLayerName(LayerNameEnum.WindFarms));




      foreach (WindFarmItem item in e.Items)

      {

       GeoCoordinate gc = ConvertFromDecimalDegreeToMeters(item.Longitude, item.Latitude);

       Feature feature = new Feature(gc.Longitude, gc.Latitude, item.GetHashCode().ToString());

                            

       pointLayer.InternalFeatures.Add(item.GetHashCode().ToString(), feature);

      }

     }

     finally

     {

      winMap.Overlays[GetLayerName(LayerNameEnum.WindFarms)].Lock.ExitWriteLock();

     }


     winMap.Refresh();


 



Lars, 
  
   This warning is not that it is obsolete, the only way we have to communicate to you though a warning is an obsolete one.  What we are trying to do is to warn you that if you add directly to the internal features property then you bypass the auto building of the in memory spatial index.   
  
   What was happening was that people were loading hundreds of thousands of complex shapes into the InMemoryFeatureLayer using the internal features.  They found after adding many of them the performance of drawing or querying was very slow.  The reason was that each time we tried to find which features were in the extent we had to analyze the entire shape and for complex polygons that take allot of time.  Based on this feedback we added the ability to use an in memory spatial index.  The problem was that if you inserted and deleted directly into the InternalFeatures we could not keep track of what you were doing so we could not keep the index up to date.  To fix this we did a few things.  First we supported the automatic building of the index if you used the EditTools methods such as BeginTransaction then AddFeature etc followed by CommitTransaction.  In this way we know exactly what you are doing and can update the spatial index in turn.  If you wanted to use the InternalFeatures we added a new method called BuildIndex where you could manually rebuild the index.  If you use the InternalFeatures and want an in memory index for speed then we suggest you call the BuildIndex after you modify the InternalFeatures collection.  The warning is just a reminder to let you know the better way is t use the edit tools if you want the index maintained automaticly and if you use the InternalFeatures you need to call the BuildIndex after you modify it IF you want the spatial index. 
  
 In your case if the speed is good and you don’t have many features in there then you don’t need to call the BuildIndex if you don’t want too.  For us, the component developers, we have very few ways to communicate tricks and tips to you and we are trying the warnings system.   
  
 David

Thanks for the explanation, i’m not sure that the warning is the right way, 
 if you project has many warnings you overlook the importent ones, and adding the 
 buildindex to the layer, dosent remove the warning!.

Lars, 
  
   I am starting to agree.  We do it very infrequently.  In the future we want to add a sort of MapSuiteCop like FXCop where we can make suggestions without using the warnings.   
  
   The warning is still there becasue we can only raise it when you use the InternalFeatures method, we cannot do anything complex like linking it to other properties. :-(  The good news is that we can remove it at any time as removing the warning is not a breaking change. 
  
 David

Well until then, maybe at property on the control to switch off the optimize warnings would be nice. 
  
 /Lars

Lars, 
  
 Thanks for your suggestions. We will keep in mind on this when we want to do enhancement on it. 
  
 Thanks. 
  
 Yale 


I have a couple questions on this. I’m happy to move over to using the edit tools, but I can’t find what seems like a complete example. Before, the examples showed something like: 
 if (!layer.internalFeatures.contains(featureKey)) 
 layer.internalFeatures.Add(featureKey, feature); 
  
 I remember having issues if I only passed in the feature without the featureKey. If I’m adding through the edit tools, do I need to check if a feature with the key already exists first like I did before? What happens if that key does exist? Also, are there any known issues with not passing in the key separately from the feature? I wish I remembered exactly what issues I had with that, but I guess I don’t. It doesn’t look like there is an option to pass in the feature and the key, only the feature.

Kimberly,


Thanks for your questions.


When you add features to the InmemoryLayer, the key is optional. The difference is that if you do not pass in a key, we will asign a random guid as its key, then it is impossible for you to select out the specified feature out. While if you pass in key when you add it, it is very easily to get it by key.


When you use EditTools to add features to key, in the CommitTransaction itself we will check the keys, if some keys already exists, we will report it in the TransactionResult which is the return value of CommitTransation.


So,typically, we suggest checking the TransactionResult carefully everytime. While honestly speaking in our how do I sample, we did a bad leading:).

TransactionResult result = inMemoryLayer.EditTools.CommitTransaction();


Any more quesitons just feel free to let  me know.


Thanks.


Yale

 



Thanks for the explanation.  Please remove this warning ASAP.   
  
 As Lars mentioned earlier.  Most developers try to eliminate all warnings in their software, because a cluttered compiler output window will cause you to overlook import issues.  I know some software developers who configure their build tools to treat warnings as a Fatal Condition. 
  
 Using warnings to document behavior changes within your API is very poor software development practice.  Most library vendors communicate this sort information in other ways:  Release Notes, Help Documents, Product Web Site, Message Boards, etc. 
  
 By the way, the EditTools are not as convenient to use as the InternalFeatures.  It would be nice if the EditTools had a public method for clearing all features.

Nate, 
  
   I appreciate your views on this.  We will take it under consideration. 
  
   I think that companies who treat warning as fatal need to consider what a warning is and what fatal is, I mean that is why they have two levels in the first place.  It is like having a level high and showstopper and then treating high as showstopper, I mean what is the point?  Microsoft has giving us two levels, warning and fatal and we work within those…  I think the warning is quite correct in this instance as we are warning you that your usages of this API in the way you are using it may not be what you want and you may not be taking advantage of the feature.  As to documentation though release notes and etc there are quite good statistics, from Microsoft, that 80% of developers never read them.  In practice we found a large number of users suffer performance issues by not using the index feature of the InMemoryFeatureLayer and with this warning the number if incidents has dramatically dropped.  I think the proof is in the pudding in this case.  The inconvenience of a warning might be the price to pay.  The warning can be avoided by using the edit tools API and thus removing the warning and .  
  
 David

Hi David,


Sorry I'm going to agree with Nate here.


Whilst I take the point that developers seldom read the documentation, warning a developer that a property/method is obsolete when it is not, is not the right thing to do.


We have a set of rules here which says you can't release software whilst there are compilation warnings.


In porting a seriously large application over to TG3 we now have an output window stuffed full of dozens of warnings none of which are genuine!


John



From what I can tell, this problem could have been avoided with a slightly modified API architecture:   
  
 If ThinkGeo were to expose the InMemoryFeatureLayer.InternalFeatures as a custom data-type, rather than a simple .Net generic container,  then you guys could have silently changed the behavior of the Add/Insertion methods to rebuild the index, when necessary. 
  
 Changing it now, might break some of your customer’s code by causing compiler errors wherever the InternalFeatures were assigned to a local variable.  Although I wouldn’t mind, because I’d rather fix a few compiler errors, than live with all of these non-sense warning, scattered throughout my code-base.

Guys, 
  
   I am going to have to agree with you on this, you make some good arguments.  We are going to remove all of the warnings that are not 100% real obsolete APIs.  
  
 The better thing would be to really obsolete the InternalFeatures method as it is now what we want people to do in the future and move people to using the edit tools.  This would be much cleaner and would allow us to build the index for the user.  We could also add a method to easily delete all the records from the layer which is what one person commented on is hard to do with the current EditTools.  Of course you could all continue to use it but it would be a warning but a valid one as it would really be obsolete.  Would anyone argue that this is not a fair use of obsolete and not a good idea?  I am not saying we would do it but I am looking for your opinions. 
  
 Nate:  We actually do use our own type which is a GeoCollection as a generic type.  We could get the events however it wouldn’t work as you would not want to re-build on every add statement etc.  It is also possible to change the feature by reference and the collection wold never know about it.   The original intention was not to have tons of shapes in the Layer and that I think is the fatal flaw.  The thing was meant to be a handful of points or polygons etc.  The class was designed to be easy to get a point into and not for tons of data, our short sightedness. 
  
 David

Hi David,


Thanks for the update, that will make life considerably easier.


I would put in one plea though.


There are occasions where using the InternalFeatures is the most direct and quickest way, especially if you have one, two or three feaures, which we often do.  Going through EditTools and building indexes seems pointless if the numbers are really small.


...ShapesLayer.InternalFeatures.Clear();


...ShapesLayer.InternalFeatures.Add(2_cents);


John



John,  
  
   I agree we need to make it easier when you just want to add a few items.  One thing we could do is create a few new Apis to add update ad edit in an implicit transaction.  It will be easy for small numbers of shapes.  Slow for lots of shapes bit then you use the transaction instead.  Just an idea. 
  
 David

Hi David, 
  
 Good idea, that would do it. 
  
 John

John, 
  
 Thanks for your suggestions.I will do these changes after detailed discussion with David.  
  
 Any more questions just feel free to let me know. 
  
 Thanks. 
  
 Yale