ThinkGeo.com    |     Documentation    |     Premium Support

Saving InMemoryLayer as New Shapefile

In below function I sent some rows' ID and it creates for me new shape file based on the IDs:


 


 



        public static void SaveSomeRowsofLayerAsShapeFile(Collection<string> featureIDs, FeatureLayer ParentLayer, string DestinationFolder, string ShapeFileName)
        {
            try
            {
                ShapeFileName = ShapeFileName.ToLower().Replace(".shp", "") + ".shp";
                string DestinationPath = DestinationFolder + ShapeFileName;

                ParentLayer.Open();
                Collection<FeatureSourceColumn> allColumns = ParentLayer.QueryTools.GetColumns();
                Collection<ThinkGeo.MapSuite.Core.Feature> allFeatures = ParentLayer.QueryTools.GetFeaturesByIds(featureIDs, new string[0]);
                ShapeFileType ParentShapeFileType = ((ShapeFileFeatureLayer)ParentLayer).GetShapeFileType();
                ParentLayer.Close();

                Collection<DbfColumn> dbfColumns = new Collection<DbfColumn>();

                foreach (FeatureSourceColumn featureSourceColumn in allColumns)
                {
                    DbfColumn dbfColumn = new DbfColumn(featureSourceColumn.ColumnName, DbfColumnType.String, 50, 0);

                    dbfColumns.Add(dbfColumn);
                }

                ShapeFileFeatureLayer.CreateShapeFile(ParentShapeFileType, DestinationPath, dbfColumns, System.Text.Encoding.UTF8, OverwriteMode.Overwrite);

                ShapeFileFeatureLayer tmpShapeFileLayer = (new Basemap.DataAccess.DataProvider.ShapeFile()).Load(DestinationPath, ShapeFileReadWriteMode.ReadWrite);

                tmpShapeFileLayer.Open();
                tmpShapeFileLayer.EditTools.BeginTransaction();
                foreach (ThinkGeo.MapSuite.Core.Feature feature in allFeatures) tmpShapeFileLayer.EditTools.Add(feature);
                TransactionResult result = tmpShapeFileLayer.EditTools.CommitTransaction();
                tmpShapeFileLayer.Close();

                if (result.TotalFailureCount > 0)
                {
                    throw new Exception(string.Format("{0} failed", result.TotalFailureCount));
                }
            }
            catch
            { throw; }
        }



it create a new shape file and I can open.


the Problem is that in the new shapefile the relevant DBF file is empty.



Ben,


Thanks for your post.
 
The problem is when you get the features, you did not get the columns information.Try to replace the following code:
 

ParentLayer.Open();
Collection<FeatureSourceColumn> allColumns = ParentLayer.QueryTools.GetColumns();
 
///Here, featureName will be exacted
string[] featureName = new string[allColumns.Count];
for (int i = 0; i < allColumns.Count; i++)
{
      featureName[i] = allColumns[i].ColumnName;
}
 
Collection<string> ColumnValues = new Collection<string>();
/// Use featureName instead of new string[0]
Collection<ThinkGeo.MapSuite.Core.Feature> allFeatures = ParentLayer.QueryTools.GetFeaturesByIds(featureIDs, featureName);

 
Any more questions just feel free to let us know.
 
Thanks.
 
Yale

Many thanks for your answer,


I did the things that you said, now I can open the new shape file in MapSuitExplorer and in our application (using the WPF control),and the dbf file has rows but I have another problem with the dbf file,


I can run query over it on MapSuitExplorer but i can not run query over it using QueryTools.ExecuteQuery (the error it returns is Object reference not set to an instance of an object.) and i can not open the new dbf file in excel or other dbf readers.


this is my code to run SQL Query:



ShapeFileFeatureLayer x = (ShapeFileFeatureLayer)wpfMap1.FindFeatureLayer("Road");

DataTable dt = x.QueryTools.ExecuteQuery(" Select top 10 * from road ");

second line return the error, I atteched the result shape file for you too.


Regards,


Ben



2092-road.zip (48.9 KB)

Ben,


Thanks for your input.
 
I think the problem is probally you should call the x.Open first before calling the queries. I did the following test with the data attached and it works fine: 

 

string shapeFile = @"..\road.shp";
ShapeFileFeatureLayer shapeFileLayer = new ShapeFileFeatureLayer(shapeFile, ShapeFileReadWriteMode.ReadOnly);
shapeFileLayer.Open();
DataTable dataTable = shapeFileLayer.QueryTools.ExecuteQuery("Select top 10 * from road ");
shapeFileLayer.Close();
 
int count = dataTable.Rows.Count;


Any more questions just feel free to let me know.
 
Thanks.
 
Yale

It seems that the new DBF file has problem and if I add below code after saving , the problem will be solved! 
  
 ShapeFileFeatureLayer.BuildRecordIdColumn(shapeFile, "ID", BuildRecordIdMode.Rebuild); 
  
 Many thanks 


Ben, 
  
 Thanks for your feedback and sharing, I am glad you are making progress. 
  
 Any more questions just feel free to let me know. 
  
 Thanks. 
  
 Yale