ThinkGeo.com    |     Documentation    |     Premium Support

Difference between using a layer's internal features vs featuresource

Hello, could I have some clarity on the difference between adding/editing/removing an InMemoryFeatureLayer’s feature via its InternalFeatures vs using its FeatureSource’s transaction methods?

I’m seeing some discrepancies between the two when projections are involved. All the data that I have entering the map (as well as any I want to export) will always have features’ vertices in Decimal Degrees. The two projections I use are WGS84 (4326) and Web Mercator (3857).

If I recall, a few years ago I read on here that using InternalFeatures is faster. But if the map is in mercator and I update a feature in the InternalFeatures using a decimal degree value, it does not work obviously because all the values are being projected in 3857. So there are a lot of checks for which projection the map is currently in and reprojecting features when they are added/updated which is cumbersome.

A typical use case is rapidly updating a feature’s position and/or adding/removing vertices from lines/polygons.

Another use case is drawing a feature using the TrackShapeLayer. If the map is in mercator when I draw a feature, and then I want to edit its vertices, I have to check what projection the map is in first, and if its in mercator I have to project the shape to WGS84 first before displaying the vertices. Is this the correct way of doing it?

Thanks!

Hi @Dan_Weaver,

This is really a great question and one we should have better documented. I’ll try to do a blog post in the next week or two that explains the differences in detail.

But to answer your question here, there are a few differences between using the InMemoryFeatureLayer.InternalFeatures property vs. the FeatureSource.AddFeature() and the corresponding BeginTransaction() and CommitTransaction():

  1. When using the FeatureSource and AddFeature, the layer’s spatial index is automatically rebuilt for you. However if you add a feature using the InMemoryFeatureSource.InternalFeatures, it simply adds the feature to the collection, and if you were to do a spatial query such as InMemoryFeatureSource.GetFeaturesInsideBoundingBox(), the newly added feature will not be included. So, after calling InMemoryFeatureSource.InternalFeatures(feature), you should typically do an inMemoryFeatureSource.BuildIndex() to rebuild the spatial index - unless you’re just wanting to render the new features.
  2. The FeatureSource’s AddFeature method will take care the projection for you. If a FeatureSource has a ProjectionConverter with its internal projection 3857 and external 4326, and you use AddFeature, the features you add will be in 4326. Also, the features returned from a query like GetAllFeatures() will be in 4326. So you don’t need to worry about the internal projection at all. However InMemoryFeatureSource.InternalFeatures property, the features are in the internal 3857 projection, meaning we need to add a new 3857 feature to InternalFeatures.
  3. While all Layers with a FeatureSource will allow the AddFeature(), only the InMemoryFeatureLayer will allow you to set InternalFeatures property.

So, unless you need every bit of performance, it’s recommended that you just use the FeatureSource.AddFeature() and the corresponding BeginTransaction() and CommitTransaction()

Thanks,
John

Thanks John! That clears things up. Appreciate it.

No problem. Good luck and let us know if you run into any other questions!