ThinkGeo.com    |     Documentation    |     Premium Support

Layer.GetBoundingBox question

I have a custom layer that derives from a FeatureLayer.   I need to get the bounding box for this layer.   I was expecting the following to work:


GrowerLayer.Open();


 


RectangleShape r = GrowerLayer.GetBoundingBox();


GrowerLayer.Close();


 


However, this throws an exception on the GetBoundingBox call, indicating that there is no bounding box for the layer.


I can execute the following, though, and I'm fine:


GrowerLayer.FeatureSource.Open();


RectangleShape r = GrowerLayer.FeatureSource.GetBoundingBox();


GrowerLayer.FeatureSource.Close();


I can override the Layer.GetBoundingBoxCore() method, but I was expecting the base FeatureLayer implementation to open my FeatureSource and get teh BoundingBox automatically. 


Maybe the issue (if there is one) is in the HasBoundingBox implementation instead?   I assume that's used inside the GetBoundingBox function, to determine if an error should be thrown.


Can you confirm that 1) I have an error in my implementation, 2) that this is behavior as designed, or 3) it is a bug that will be addressed?


Thanks!



More info: 
  
 I must override the Layer.HasBoundingBoxCore method in order to get past the Layer.GetBoundingBox check to determine that a bounding box  is present.   And, after doing that and overriding the Layer.GetBoundingBoxCore method, I get the expected results.    If I don’t override the Layer.GetBoundingBoxCore method, then I get an error about the Layer not being open when I call GetBoundingBox.   
  
 I’m not sure how it is all supposed to work, but I don’t think it is working write.    It is not a show-stopper, though.   
  
 And, be aware that I’m using the updated DLL’s from last week.

Ted, 
  
   I am pretty sure what you are seeing is designed behavior, at least as per your first post.  The reason is that there are some FeatureSources where it is not possible to calculate the bounding box or calculating it would take along time.  Because of this we did not make the GetBoundingBoxCore a required abstract method.  We did however want to note which FeatureSources do have this ability so we can take advantage of it in our drawing routines.  
  
  The pattern we use for optional Core methods that we want to support but not force you to implement is to have a concrete method like GetBoudningBox which checks another method like HasBoundingBox.  The default for HasBoundingBox is false but it its getter is virtual and can be overridden.  This gives you a way to check if the functionality is implemented before you try and call it.  This is the same pattern that they use for Stream when they added Async Streams.  It is a Microsoft pattern usually used when adding new functions to existing abstract classes where you do not want to break compatibility, or where you want the functionality to be optional. 
  
 More to the point if you have a layer or feature source that you want to support the bounding box then you need to override the GetBoundigBoxCore and also the HasBoundingBox and have it return true otherwise we throw the error.   The error is to let you know that this is not supported and to check the HasBoundingBox property. 
  
 In the case you just mentioned where you override the HasBoundingBox and not the GetBoundignBoxCode then I am sure it was going to throw an error but not sure the error you reported was the right one.  You need to override them in pairs. 
  
 David

Ahhhhhh…   So Has* is not a test of whether a specific instance of data has the specified content… it is an indication of whether the impmlementation supports the function.    That is a piece of info that will be very useful to know moving forward :) 
  
 Thanks!

Ted, 
  
  Yea we try and use ‘Has’ where it makes sense for properties and ‘Can’ for methods.  GetBoudingBox is a strange one because it should usually be a property because a bounding box is an attribute of a FeatureSource however there is a rule to never make properties something that will ever take longer than a field access.  This mean if you have to do any heavy computing then this should never be a property.  Properties should return lightning fast and it is what people expect.  If you have something that needs calculation that could take some time then it is recommended you use a method and put ‘Get’ in front of the name you would have used if it were a property.  The ‘Get’ part makes it like a verb so it fits as a method, you know action type of things.  If it were a straight method then we would have used ‘Can’ as the prefix.  Maybe that is what is should have been, we were caught in a strange spot that the rules didn’t cover so we went with the property style since it is in spirit a property type thing.   
  
 David

Ted, 
  
   We actually discussed ‘Supports’ as a prefix and had a big argument about it.  The reason we didn’t go with it was we could not find any Microsoft examples of it.  On the flip side we could find lots of Has and Can examples.  Maybe Microsoft got this wrong. :-) 
  
 I will tell you that designing an extensible API is a really tough job.  There are a mountain of rules and I can tell you every API in the Core has a purpose and was designed to be in compliance with the design guidelines as to the best of our abilities.  That is not to say we didn’t screw some things up but I personally sat through more reviews where we just went over API guidelines then I care to remember.  What is crazy is that even on the 50th review you can always find something.  It is very hard to enforce a huge number of rules on a large API.  Ok, I will get of my soap box now. 
  
 David