ThinkGeo.com    |     Documentation    |     Premium Support

SQLite Issues

I have a WPF application that has been using shapefiles as it’s storage. I am transitioning us to SQLite and have successfully loaded everything into the database and the features show up on the map. However , after a few operations, I get the following error: 





Could not find any resources appropriate for the specified culture or the neutral culture.  Make sure “ThinkGeo.MapSuite.Core.ExceptionDescription.resources” was correctly embedded or linked into assembly “SQLiteExtension” at compile time, or that all the satellite assemblies required are loadable and fully signed.
A first chance exception of type ‘System.Resources.MissingManifestResourceException’ occurred in mscorlib.dll



Any help would be much appreciated. I apologize if this is not enough information, this is my first post to this forum.



-Josh

Also, running the following:

   selectedFeatures = targetFeatureLayer.QueryTools.GetFeaturesIntersecting(identifyShape, ReturningColumnsType.AllColumns)



is returning duplicates only for SQLiteFeatureLayers (not ShapeFileFeatureLayers)



Thanks!


Hi Joshua, 



Sorry that I can’t recreate these issues. The following is the tests I did on my side. 



#1, To make sure that the Build Action of ExceptionDescription.res is embedded resource. 

#2, Load *.sqlite file by using SqliteFeatureLayer, it worked well and not encountered the exception of type ‘System.Resources.MissingManifestResourceException’. 



#3, Use the following code to test the duplicate records and it still worked well: 




private void wpfMap1_MapClick(object sender, MapClickWpfMapEventArgs e)
       {
           var location = e.WorldLocation.Buffer(double.Parse(tolerance.Text), wpfMap1.MapUnit, DistanceUnit.Meter);
           var featureLayer = (wpfMap1.Overlays[0] as LayerOverlay).Layers[0] as FeatureLayer;
           featureLayer.Open();
           var features = featureLayer.QueryTools.GetFeaturesIntersecting(location, ReturningColumnsType.AllColumns);
           var filterFeaturesCount = features.Distinct(new FeatureComparer((x, y) => x.Id == y.Id)).Count();
            
           Debug.Assert(filterFeaturesCount == features.Count, “Failed”);
       }





Please append more information about these issues, I just outline them as following: 




        
  1. What’s the Culture of your application uses? 

  2.     
  3. How does the Exception “System.Resources.MissingManifestResourceException” occurred? 

  4.     
  5. Which version of the SQLiteExtension is referenced in your WPF application?




Could you please append some code snippets here? A simple sample would be better. 



If something misunderstood here please let me know.



Thanks, 

Peter

Peter,



      Thank you for the timely response. I was able to figure out how to get around both issues. For the first issue, an exception was getting thrown by SQLiteExtension because unlike the ShapeFileFeatureLayer, the SQLiteFeatureLayer seems to be case sensitive with column names. It seems that if an exception is thrown by SQLiteExtension, that is what was causing the System.Resources.MissingManifestResourceException. 

I am not too familiar with Cultures, but from what I can tell it is using en-US? The version of SQLiteExtension is 1.0.0.0.



Could you be a little more specific about what this means "To make sure that the Build Action of ExceptionDescription.res is embedded resource. " Where would I get that res file?



Here is a code snippet for the GetFeaturesIntersection function:




Public Shared Function SelectFeatures(ByVal identifyShape As BaseShape, ByRef targetShapefile As FeatureLayer) As ObjectModel.Collection(Of Feature)
        ‘collection to store the features
        Dim selectedFeatures As New ObjectModel.Collection(Of Feature)
        ‘find the shapetype of the targetShapefile to determine how we are selecting features
        If Not targetShapefile.IsOpen() Then targetShapefile.Open()
        targetShapefile.FeatureSource.Open()
        selectedFeatures = targetShapefile.QueryTools.GetFeaturesIntersecting(identifyShape, ReturningColumnsType.AllColumns)
        ‘’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’
        ‘’’’’’’’’ FOR SOME REASON THIS IS GENERATING DUPLICATES FOR THE SQLITE LAYERS, SO WE MUST REMOVE THEM
        ‘’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’
        If TypeOf targetShapefile Is WorkLayer Then
            Dim distinctFeatures As New ObjectModel.Collection(Of Feature)
            Dim previousFeature As Feature = Nothing
            For Each feat As Feature In selectedFeatures
                If Not previousFeature Is Nothing Then
                    If Not previousFeature.ColumnValues.Item(“UNIQUEID”) = feat.ColumnValues.Item(“UNIQUEID”) Then
                        distinctFeatures.Add(feat)
                    End If
                Else
                    distinctFeatures.Add(feat)
                End If
                previousFeature = feat
            Next
            Return distinctFeatures
        End If
        Return selectedFeatures
    End Function



     
You can see where I added the code to remove the duplicates. Thanks for the help!





Hi Joshua, 
  
 Thanks for the further information. I guess the reason of the issue is the different version of SQLiteExtension. Please download the latest SQLiteExtension.dll at ap.thinkgeo.com:5001/fbsharing/4HnY4kYL (Note: it will be expired in a week). 
  
 The "To make sure that the Build Action of ExceptionDescription.res is embedded resource." means that I checked the resource file in our project and make sure that the build action of resource file is correct. 
  
  
 Any questions please let me know. 
  
 Regards, 
 Peter

Peter,



      Thanks for the link. Those issues I was experiencing seem to be resolved. However, I have another question for you. As I am transitioning our storage from shapefiles to sqlite, we would like to be able to export each table from the sqlite database into a shapefile. I have successfully moved our shapefiles into the sqlite database using the following code:
                Dim shapeSource As New ShapeFileFeatureSource(file.FullName, ShapeFileReadWriteMode.[ReadOnly])
                shapeSource.Open()
                Dim columnsToInsert = (From column In shapeSource.GetDbfColumns() Where column.ColumnName.ToLower() <> "id" And column.ColumnName.ToLower() <> "geometry" Select column.ColumnName).Aggregate(Function(current, [next]) current + " TEXT, " + [next]) + " TEXT"



                Dim createTableSQL As String = String.Format("CREATE TABLE {0} (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, geometry BLOB, {1})", file.Name.Replace(".shp", ""), columnsToInsert)
                Console.WriteLine(createTableSQL)
                Dim createTableCommand As New SQLiteCommand(createTableSQL, sqliteConnection)
                createTableCommand.ExecuteNonQuery()



                Dim createIndexSQL As String = String.Format("CREATE VIRTUAL TABLE idx_{0}_geometry USING rtree(id, minx, maxx, miny, maxy)", file.Name.Replace(".shp", ""))
                Dim createIndexCmd As New SQLiteCommand(createIndexSQL, sqliteConnection)
                createIndexCmd.ExecuteNonQuery()
                Dim sqliteFeatureSource As New SqliteFeatureSource(String.Format("Data Source={0};Version=3;PRAGMA synchronous=OFF;PRAGMA cache_size=20000; PRAGMA page_size=32768", Path), file.Name.Replace(".shp", ""), "id", "geometry")
                sqliteFeatureSource.Open()
                sqliteFeatureSource.BeginTransaction()
                Dim allFeatures As Collection(Of Feature) = shapeSource.GetAllFeatures(ReturningColumnsType.AllColumns)



                Console.WriteLine(String.Format("Adding {0} features to the table", allFeatures.Count))



                For Each feat As Feature In allFeatures
                    sqliteFeatureSource.AddFeature(feat)
                Next
                sqliteFeatureSource.CommitTransaction()
                sqliteFeatureSource.Close()
                shapeSource.Close()

Now I would like to do the reverse and export the tables to shapfiles. Here is what I have so far:







Dim sffs As ShapeFileFeatureSource = New ShapeFileFeatureSource(Directory.GetCurrentDirectory() + "&#34; + currentFile.Name)




                    Dim sqliteFeatureSource As New SqliteFeatureSource(String.Format("Data Source={0};Version=3;PRAGMA synchronous=OFF;PRAGMA cache_size=20000; PRAGMA page_size=32768", Directory.GetCurrentDirectory() + "\layers.sqlite"), currentFile.Name.Replace(".shp", ""), "id", "geometry")



                    sqliteFeatureSource.Open()



                    Dim allFeatures As Collection(Of Feature) = sqliteFeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns)



                    sffs.ReadWriteMode = ShapeFileReadWriteMode.ReadWrite



                    sffs.Open()



                    sffs.BeginTransaction()



                    For Each feat As Feature In allFeatures



                    sffs.AddFeature(New Feature(feat.GetWellKnownBinary, feat.Id, feat.ColumnValues)))



                    Next



                    sffs.CommitTransaction()



                    sffs.Close()



                    sqliteFeatureSource.Close()



The only files that do not seem to get populated are the dbf files. Again, Thanks for the assistance.




Hi Josh,  
  
 I guess the reason is that the features is too many to commit in one transaction. Please try committing transactions for each 500 rows. 
 There is the code snippet: 
 
            Dim totalCount As Integer = 0
            For Each feature As ThinkGeo.MapSuite.Core.Feature In allFeatures
                totalCount = totalCount + 1
                sffs.AddFeature(feature)
                If (totalCount Mod 500 = 0) Then
                    sffs.CommitTransaction()
                    sffs.BeginTransaction()
                End If
            Next
            sffs.CommitTransaction()
            sffs.BeginTransaction()
 
  
  
 Thanks, 
 Peter