ThinkGeo.com    |     Documentation    |     Premium Support

Create shape file from _mapControl.TrackOverlay.TrackShapeLayer

We want to allow users to use the drawing tools and make marks on a map and save that as a shape file.



The problem I am having is the TrackShapeLayer that the users mark up is on does not have any ColumnValues for the features and the shape file generation fails saying the database columns should have at least one value.



Below is the code I was using, I also tried creating dummy values for the columns but it did not work. I have verified that a polyline exists on the layer when testing. 




private void PrintToNewShapeFile(string shapeName)
        {
            InMemoryFeatureLayer layer = _mapControl.TrackOverlay.TrackShapeLayer;
 
            WellKnownType shapeType = WellKnownType.Point;
            ShapeFileType shapeFileType = (ShapeFileType)shapeType;
 
            layer.Open();
             
            InMemoryFeatureLayer inMemoryFeatureLayer = (InMemoryFeatureLayer)layer;
            Collection<Feature> allFeatures = inMemoryFeatureLayer.FeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns);
 
            //foreach (Feature feature in allFeatures)
            //{
            //    feature.ColumnValues.Add(Guid.NewGuid().ToString(), "Key");
            //}
             
            Collection<FeatureSourceColumn> allColumns = inMemoryFeatureLayer.QueryTools.GetColumns();
 
            //if (allColumns == null || !allColumns.Any())
            //{
            //    foreach (Feature allFeature in allFeatures)
            //    {
            //        if (allColumns == null)
            //        {
            //            allColumns = new Collection<FeatureSourceColumn>();
            //        }
            //        var columnValue = new FeatureSourceColumn(allFeature.ColumnValues.First().Value, "String", 250);
            //        allColumns.Add(columnValue);
            //    }
            //}
 
 
            Collection<DbfColumn> dbfColumns = new Collection<DbfColumn>();
            foreach (FeatureSourceColumn featureSourceColumn in allColumns)
            {
                DbfColumn col = GetDbfColumnFromFeatureSourceColumn(featureSourceColumn);
                if (col != null)
                {
                    dbfColumns.Add(col);
                }                                  
            }
 
            ShapeFileFeatureSource.CreateShapeFile(shapeFileType,
             shapeName, dbfColumns, Encoding.ASCII, OverwriteMode.Overwrite);
            ShapeFileFeatureSource shapeFileLayer = new ShapeFileFeatureSource(
                shapeName, ShapeFileReadWriteMode.ReadWrite);
 
            shapeFileLayer.Open();
 
            foreach (Feature feature in allFeatures)
            {
                Dictionary<stringstring> shapeColumnValues = new Dictionary<stringstring>();
                BaseShape baseShape = feature.GetShape();
 
                // Loop through all columns and add their values
                foreach (FeatureSourceColumn column in allColumns)
                {
                    string featureColumnValue = feature.ColumnValues[column.ColumnName].ToString();
                    shapeColumnValues.Add(column.ColumnName, featureColumnValue);
                }
 
  
                    Feature newf = new Feature(baseShape, shapeColumnValues);
                    shapeFileLayer.BeginTransaction();
                    shapeFileLayer.AddFeature(newf);
                    TransactionResult result = shapeFileLayer.CommitTransaction();
                    Console.WriteLine(result.TransactionResultStatus);
                 
            }
 
            shapeFileLayer.Close();
            layer.Close();
 
            
        }
 
        private static DbfColumn GetDbfColumnFromFeatureSourceColumn(FeatureSourceColumn featureSourceColumn)
        {
            switch (featureSourceColumn.TypeName)
            {
                case "String":
                    return new DbfColumn(featureSourceColumn.ColumnName, DbfColumnType.String, featureSourceColumn.MaxLength, 0);
                case "Memo":
                    return new DbfColumn(featureSourceColumn.ColumnName, DbfColumnType.Memo, featureSourceColumn.MaxLength, 0);
                case "Integer":
                    return new DbfColumn(featureSourceColumn.ColumnName, DbfColumnType.Integer, featureSourceColumn.MaxLength, 0);
                case "Logical":
                    return new DbfColumn(featureSourceColumn.ColumnName, DbfColumnType.Logical, featureSourceColumn.MaxLength, 0);
                case "Double":
                    return new DbfColumn(featureSourceColumn.ColumnName, DbfColumnType.Double, 0, featureSourceColumn.MaxLength);
                case "Date":
                    return new DbfColumn(featureSourceColumn.ColumnName, DbfColumnType.Date, featureSourceColumn.MaxLength, 0);
                default:
                    return null;
            }
        }


Hi Scott,



Based on the shape file specification from Esri, at least one dbf column is required. So, we did a few modifications to skip this issue based on your codes. we can get the shape file successfully, please try the below codes:




. . . . . .
foreach (FeatureSourceColumn featureSourceColumn in allColumns)
{
    DbfColumn col = GetDbfColumnFromFeatureSourceColumn(featureSourceColumn);
    if (col != null)
    {
        dbfColumns.Add(col);
    }
}
if (dbfColumns.Count == 0)
{
    dbfColumns.Add(new DbfColumn("ID", DbfColumnType.String, 100, 0));
}
. . . . . . 

Hope it helps.

Johnny

Thank you for your reply. A shape file is created now, but nothing shows on the map when it is loaded. I have other shape files that were created with other programs loading so I know the loading code works. I also noticed that a couple shape files prefixed with a TMP are also created. I used another program to check the shape file created and it appears to be blank except for a tiny dot that I cannot zoom in on as it never gets any bigger. Any ideas? Am I maybe missing another step to finish building the shape file?

Hi Scott, 
  
 would you mind to use the MapSuiteExplorer tool to load the shape file? as I am not sure if there is anything missing in your loading codes like not do the projection conversion. For example, if the created shape file is based on decimal degree and your loading codes is based on mocator, then we should only can see a very small dot nearby the Africa. 
  
 If the issue persists, would you mind to send us the created shape file or any codes? 
  
 Regards, 
 Johnny