ThinkGeo.com    |     Documentation    |     Premium Support

Can NTS be exposed?

I am a strong proponent of the Net Topology Suite (NTS) and applaud that you use it internally within MapSuite.  We use NTS objects in our custom data sources.   When your renders request a feature collection, we are currently using our geometry object to export WKB, and instantiating your Feature with that WKB.   So we end up with each of us holding a Geometry object for which one is just a copy of the other.


Is there any way that you can consider letting us create your Features, using our existing geometry objects, rather than copying them?   I can appreciate any hesitancy to introduce a dependency upon objects with you do not control, but in our case where we are rendering 50,000 cells, it sure doesn't feel very good to create an exact copy of those 50,000 objects.    They create fast but you sure hope the garbage collector is working well when we are done with them :)


By the same token, if we do map queries, and operate upon a layer, would we be able to get the underlying NTS object associated with a feature?   


I saw something in your developer blog on building an RTree for an in-memory featuresource that indicated the NTS and GeoAPI dll's had to be referenced.   I should go back and look at that, as that must have indicated there was some way to get to the NTS objects in your features.


Any chance you would ever move to an IFeature interface that we could implement directly onto a DataSet row, and not have to copy ANY of our data?


There is a new build of NTS that has a lot of improvements that we funded.  I hope your testing proves out for you to be able to include it soon.


Thanks.



Ted, 
  
   This is interesting and would like to understand a bit more. 
  
   Our Feature is a structure and it holds very little data, mainly just a few reference pointers.  At its heart it is an array of bytes that represent the WKB of the geometry.  If you already have WKB and create  a feature using a constructor that takes a byte array then we would just have a reference to your data and no new data is created except for a super small structure overhead.   
  
   I guess another way is that we could look at what we could do to allow you to create a Feature and have at its heart whatever object you wanted.  I am not sure off the top of my head what kind of inheritance type stuff works with structures but I am willing to see if you are interested in this. 
  
   We stayed away from interfaces in our framework.  The reason is that it is a very limiting privative, it doesn’t support adding new members.  To extend it you are forces into making more and more interfaces and object quickly get decorated up to crazy levels.  It also doesn’t support any concept of virtual implementations which really help developers get things right if they are unsure about how to implement something.  It is like having every member abstract, how crazy. 
  
   Ok, gotta get off my soapbox.  If you are interested I can check on what we can do with structures as far as extending them.  To make sure I understand what you wanted to do can you step me though how you would build your feature source at a high level? 
  
 On the integration with the latest NTS.  I think this will be done this week however I am going to be heading to Hong Kong on Friday and not be getting back until Wednesday.  I usually coordinate these kinds of request and will try to stay on top of it but you know how traveling is. 
  
 David

My feature source is a .Net DataSet.   One of the properties of my GISFeatureRow (a row in my Feature table), is an NTS geometry object.   When I build up a Feature collection for MapSuite, I am using the WKB exported from my geometry object as the constructor to your Feature class.   So you are indicating that you aren’t “copying” these bytes into an alternative geometry object… and that you only hold a reference to the array that I give to you? 
  
 Unfortunately, as you are aware, the NTS objects create “copy” of the WKB when you use that AsBinary() method.  As such, I do end up with two copies of this data.  The one in my GISFeatureRow, and the exported WKB array to which you hold a reference.    I wonder if the NTS boys have a way of exposing the WKB of a geometry object as a reference.   I sense that they likely have a WKB for the primitives… point, ring, etc… and build the WKB for the complex objects on the fly. 
  
 You really surprise me when you indicate that you operate from the WKB, rather than an object. 
  
 Maybe I can modify my GISFeatureRow to carry the WKB as the default storage format, and only go to an object when requested.   That would avoid multiple copies of the data. 
  
 I’m not sure why you indicate that interfaces are less extensible than objects.  We add new properties and methods to our interfaces all the time.   I guess the issue is that anyone implementing that interface must make the changes, too?    Yeah, I can see that as an issue when you deal outside your own organization.   I don’t like the idea of converting numeric data to a string to place it in your Feature objects colleciton, and then converting it back to a double in the theme.   Was hoping that if I could implement my own Feature object, that I might be able to avoid that. 
  
 Just brainstorming… 
  
  
  


Ted, 
  
   If you were able to get the WKB directly from the geometry then that would be really efficient.  You are correct that we do not copy the WBK.  An array is a reference type even though the bytes are value types.  Because if this when you pass us an array we only get the reference to the array.  If you already had byte arrays of WBK then we would just get the copy. 
  
 The interface issue is exactly how you described as the user you have to add the new item and re-compile.  This prevents binary computability.  I look back now and kind wish I made Feature and class and not a structure as then you could inherit from it.  I did a little research and we cannot inherit  from a structure.  We can however enhance it further if necessary. 
  
   When you said you were surprised we used WKB was that a good or bad surprise?  We did this because the bytes are pretty efficient and we needed some kind of primitive and WKB is a popular format  to store data in spatial databases…   
  
   If you really don’t like to convert your types to string then one possible solution is for us to add a UntypedColumnValues  dictionary like the column values on but the type of these are object so you can store whatever you want.  Actually I am not sure about this as it might cause boxing.  If we did something like this it would be your responsibility to populate these in your feature source and your responsibility to consume them in your style or elsewhere.  The rest of the system would have no knowledge.  Maybe we could add a kind of custom property that is type object.  You can do with that anything you wanted.  Kind of a back door…   
  
 Just brainstorming as well.  Also do you think converting to and from string takes all that long?  You many want to test with 50,000 and see.  One thing I know will slow you down is we do allot of parameter checking.  Maybe we could do a conditional compile and turn all parameter validation off.  I bet you would get some increase from that. 
  
 David

Having time to think on it some, I’m pleased that you are working directly from the WKB.   I think it is a very good definition. 
  
 I confess I have not converted 50,000 doubles to and from strings.   I will shut up on this issue until I have tested things at this low level and verified that this is or is not an issue.    I do know that I can create the 50K Feature objects relatively fast.  
  
 I’m working with your UI features now (capturing a user drawn query area, user drawn zoom rectangle, etc), and assuming that your current implementation and our custom feature sources, layers, overlays, and styles will get us a demonstrable product with minimum effort.  When the entire app has been converted, we can profile for any low hanging performance improvements.

Ted, 
  
   When you get back to your performance testing let us know.  I will be happy to help you identify any bottlenecks.  We will do whatever we can to get the performance you need. 
  
 David