ThinkGeo.com    |     Documentation    |     Premium Support

Shapefile ID's

I have two newbie questions.  Hopefully they will be easy to answer. 


The MSSQL2008 layer requires that you specify which column is the ID column.  For Shapefile layers though, it appears that ID's are automatically assigned.  Is this correct?  If yes, and if I wanted to do something like find the feature(s) based on a particular column value, how would I do that?  If I knew the associated ID's, it would be easy.  I could issue a sql query against the data and pass the ID's to the the GetFeature(s)byID(s) method.  But if ID's are auto-assigned and not retrievable via a query, would I have to spin through all of the features in the layer and query the column's value to get the right feature(s)? 


It appears there are two methods to accomplish the same task.  They are the ShapeFileLayer.QueryTools.GetFeatureByID method and the ShapeFileLayer.FeatureSource.GetFeatureByID method.  Is there a difference between the two?  Is one preferrable to the other? 


Thank you,


Binu



Binu, 



Thanks for the post. 



For your first question, David has provided the solution in our discussion forum. You can see his answer here

In Short: That is an old problem with shape files. ShapeFiles records are numberd from 1 to the number of records, we don’t have choice on this. The records in the DBF rows correspond to the position of the record in the shape file itself. This means that the third record in the shape file is the third row in the DBF. The problem is that SQL by nature doesn’t return the absolute record position in the table so you never know what record to fetch. What you need to is add a new column to the DBF and sequentially number it from 1 to n number of records. That way when you do the SQL query you can return that row as well. With this record number you can use the QueryById method on the QueryTools to quickly find the shape. You have to make sure that whenever you edit the shapefile and either add, edit or delete the records that you rebuild the record ID using the method below. 



We will add the API BuildRecID() in the next Beta which will be released around the middle of November. For now you can write your own BuildRecID() method with David’s code. Also here is the VB.NET code in case C# is not your preferable language. 



Private Sub BuildRecId(shapeFileName As String, recIdColumnName As String) 
    Dim featureSource As ShapeFileFeatureSource = Nothing 
    
    Try 
        ' Open the shape file 
        featureSource = New ShapeFileFeatureSource(shapeFileName, ShapeFileReadWriteMode.ReadWrite) 
        featureSource.Open() 
        
        ' Check to see if the RecId column exists 
        Dim columns As Collection = featureSource.GetColumns() 
        Dim foundRecIdColumn As Boolean = False 
        For Each column As FeatureSourceColumn In columns 
            If String.Compare(column.ColumnName, recIdColumnName, True) = 0 Then 
                foundRecIdColumn = True 
                Exit For 
            End If 
        Next 
        
        ' If the RecId column is not found then we need to add it. 
        If Not foundRecIdColumn Then 
            featureSource.AddColumnInteger(recIdColumnName.ToUpperInvariant(), 7) 
        End If 
        
        ' Loop through all of the records and update RecId column 
        Dim recordCount As Integer = featureSource.GetCount() 
        For i As Integer = 0 To recordCount - 1 
            featureSource.UpdateDbfData(i.ToString(), recIdColumnName.ToUpperInvariant(), (i + 1).ToString()) 
        Next 
    Finally 
        If featureSource IsNot Nothing AndAlso featureSource.IsOpen Then 
            featureSource.Close() 
        End If 
    End Try 
End Sub 


ShapeFileLayer.QueryTools.GetFeatureByID is just a wrapper for ShapeFileLayer.FeatureSource.GetFeatureByID, making it easier for users to find the method in the layer level. Having said that we prefer that you use the QueryTools version. The reason we expose the FeatureSource property on the FeatureLayer is that for many layers the FeatureSource may have additional properties that the Layer does not have. For example if you create a ShapFileFeatureLayer and then cast its FeatureSource to a ShapeFileFeatureSource you will find some cool methods and properties that are specific to the ShapeFile. We didn’t expose them though the ShapeFileFeatureLayer as we didn’t want to messy up the API for mainstream cases. 



Ben 

 



Thank you for the timely and detailed response.

It’s our pleasure. Hope you have a great app with Map Suite.