ThinkGeo.com    |     Documentation    |     Premium Support

Null Reference calling GetFeaturesByColumnValue on custom InMemoryFeatureSource

Hi,


I created a custom in memory feature source and layer to wrap my own layer objects from a custom spatial storage system.  I have no problems displaying the layer in a map control and using styles/labels that access the attributes of the features.


But when I tried to call FeatureSource.GetFeaturesByColumnValue I get a NullReferenceException


System.NullReferenceException occurred

  Message="Object reference not set to an instance of an object."

  Source="MapSuiteCore"

  StackTrace:

       at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesByColumnValueCore(String columnName, String columnValue)

       at ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesByColumnValue(String columnName, String columnValue)

       at Tcc.Expresso.UI.RecEngine.VRAExportControl.listViewPrevew_SelectionChanged(Object sender, SelectionChangedEventArgs e) in C:\TFSSource\Expresso\Tcc.Expresso.UI\RecEngine\VRAExportControl.xaml.cs:line 273

  InnerException: 

 


In my custom feature source I did provide it with the List of FeatureSourceColumn and set the attribute dictionary of each feature.  I assume that I have not set something I need to, any pointer in the right direction would be great!


Thanks


Brian



Brian,


I tried to recreate the issue by simply write MyInMemoryFeatureSource but failed.




private void button1_Click(object sender, EventArgs e)
{
    MyInMemoryFeatureSource source = new MyInMemoryFeatureSource();
    source.Open();
    Feature feature = source.GetFeaturesByColumnValue("Name", "A");
}

public class MyInMemoryFeatureSource : InMemoryFeatureSource
{
    public MyInMemoryFeatureSource()
     : base(new List<FeatureSourceColumn>())
    {
    }
}


Could you provide some code to help on recreating this issue, it will be great if there is a demo about it.


Thanks,

ThinkGeo Support 

 



Hi Lee,


I've included the code for my custom Feature Source so you can see what I'm doing, I can probably put together a simple app if needed also a little later.


Brian


 



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ThinkGeo.MapSuite.Core;
using Tcc.SpatialStorage;

namespace Tcc.Gis.ThinkGeoSupport
{
    public class TccFeatureSource : InMemoryFeatureSource
    {
        #region Construct/Initialize

        public TccFeatureSource(ITccFeatureLayer layerToWrap):
            base(CreateFeatureSourceColumnsForITccFeatureLayer(layerToWrap))
        {
            this.OpenedFeatureSource += new EventHandler<OpenedFeatureSourceEventArgs>(TccFeatureSource_OpenedFeatureSource);
            this.WrappedLayer = layerToWrap;
        }

        private void TccFeatureSource_OpenedFeatureSource(object sender, OpenedFeatureSourceEventArgs e)
        {
            AddTccFeaturesToInMemoryFeatures();
        }


        #endregion

        #region Public Properties

        public ITccFeatureLayer WrappedLayer { get; private set; }

        #endregion

        #region Private Methods

        private void AddTccFeaturesToInMemoryFeatures()
        {
            //We need to remove any projection while we are adding features
            //Otherwise the lat/lon tcc feature WKB will be un-projected incorrectly
            var tempProjection = Projection;
            Projection = null;

            this.BeginTransaction();
            foreach( ITccFeature tccFeature in WrappedLayer.TccFeatures )
            {
                var attributeDictionary = new Dictionary<string, string>();
                foreach( ILayerColumn layerColumn in WrappedLayer.Columns )
                    attributeDictionary.Add(layerColumn.Name, tccFeature.GetAttribute(layerColumn).ToString());

                var thinkGeoFeature = new Feature(tccFeature.WellKnownBinary, tccFeature.Index.ToString(), attributeDictionary);
                AddFeature(thinkGeoFeature);
            }
            this.CommitTransaction();

            //Now that the transaction had been committed, we can set the projection again
            Projection = tempProjection;
        }

        #endregion

        #region Static Methods

        public static List<FeatureSourceColumn> CreateFeatureSourceColumnsForITccFeatureLayer(ITccFeatureLayer layer)
        {
            var outlist = new List<FeatureSourceColumn>();

            foreach( ILayerColumn tccColumn in layer.Columns )
                outlist.Add(new FeatureSourceColumn(tccColumn.Name, tccColumn.DataType.ToString(), tccColumn.Length));

            return outlist;
        }

        #endregion
    }
}



Brian,


I have recreated it and this is an issue in our system, we have added it to our tracking system and it will be fixed it in the upcoming version which will be release around next week.


For now you can override GetFeaturesByColumnValueCore  method to avoid this issue for now.




protected override Collection<Feature> GetFeaturesByColumnValueCore(string columnName, string columnValue)
{
    Collection<Feature> returnFeatures = new Collection<Feature>();

    Collection<Feature> features = GetAllFeatures(new string[] { columnName });
    for (int i = 0; i < features.Count; i++)
    {
        if (features[i].GetWellKnownBinary() != null && String.CompareOrdinal(features[i].ColumnValues[columnName], columnValue) == 0)
        {
            returnFeatures.Add(features[i]);
        }
    }
return returnFeatures;
}


ThinkGeo Support