ThinkGeo.com    |     Documentation    |     Premium Support

Append Shape File Data to Personal GeoDatabase

Hi,


Is it possible to manipulate the personal Geodatabase crated by ArcGIS using ThinkGEO? For example, append the data from a shapefile (ArcGIS) to the existing personal (Access) Geodatabase.


Thanks,


Wilson Jiang



 


Hi, Wilson
If you want to know what data formats MapSuite supports, please refer to the link below to get more detailed information about it.
wiki.thinkgeo.com/wiki/Map_S...rmat_Guide
Also we have provided one LoadGeoDatabaseFeatureLayer sample in the “Extending MapSuite” folder of our installed samples. Please have a look at it.
If you still have problems then please let us know.
 
Thanks,
 
Khalil

Yes. I knew how to use the personal geodatabase in ThinkGeo. The question is "Can we manipulate the data in database and save them?" 
 Thanks, Wilson

Wilson, 
  
 Our MapSuite provides an EditTools in all FeatureLayer(such as ShapeFileFeatureLayer, MsSqlserver2008FeatureLayer…) that can let users manipulate data, such as add, update and delete, however PersonalGeoDatabaseFeatureLayer is not editable. But you can easy to implement it by yourself, first your create a custom PersonalGeoDatabaseFeatureLayer and set the property IsEditable to true, PersonalGeoDatabaseFeatureLayer contains a FeatureSource, you also create a custom PersonalGeoDatabaseFeatureSource assign to custom layer, only need to do is implement CommitTransactionCore method, and then you can use every method in EditTools. 
  
 Thanks 
 James 


Hi James, 
  
 The custom PersonalGeoDatabaseFeatureLayer can not extends from either FdoFeatureLayer or PersonalGeoDatabaseFeatureLayer. Do I have do similar work in FdoFeatureLayer and ThinkGeo PersonalGeoDatabaseFeatureLayer? I could not follow the steps you described. Do you have any sample codes for reference? 
  
 Thanks, 
  
 Wilson

 


Hi, Wilson
 
Sorry for making you confused. Please refer to the codes below. All you need to do is to override the CommitTransactionCore method and add your own logic for adding, deleting, updating features from PersonalGeoDatabase.
 
 
using System;
using System.Web.UI;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.WebEdition;
 
namespace CSSamples.Samples.Extending_MapSuite
{
    public partial class LoadGeoDatabaseFeatureLayer : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                Map1.MapUnit = GeographyUnit.Meter;
                Map1.CurrentExtent = new RectangleShape(2149408.38465815, 246471.365609125, 2204046.63635703, 213231.081162168);
                Map1.MapBackground.BackgroundBrush = new GeoSolidBrush(GeoColor.FromHtml("#E5E3DF"));
 
                CustomPersonalGeoDatabaseFeatureLayer worldLayer = new CustomPersonalGeoDatabaseFeatureLayer(MapPath("~/SampleData/world/JORWD6gdb.mdb"), null, null, "Mains");
                worldLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.LocalRoad2;
                worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
 
                worldLayer.Open();
                worldLayer.FeatureSource.BeginTransaction();
                worldLayer.FeatureSource.AddFeature(new Feature(new PointShape(0, 0)));
                worldLayer.FeatureSource.CommitTransaction();
 
                Map1.StaticOverlay.Layers.Add("WorldLayer", worldLayer);
            }
        }
    }
 
    public class CustomPersonalGeoDatabaseFeatureLayer : PersonalGeoDatabaseFeatureLayer
    {
        public CustomPersonalGeoDatabaseFeatureLayer(string pathFilename, string idColumnName, string featureSchemaName, string featureClassName)
            : this(pathFilename, idColumnName, featureSchemaName, featureClassName, null)
        { }
 
        public CustomPersonalGeoDatabaseFeatureLayer(string pathFilename, string idColumnName, string featureSchemaName, string featureClassName, string geometryColumnName)
            : base(pathFilename, idColumnName, featureSchemaName, featureClassName, geometryColumnName)
        {
            FeatureSource = new CustomPersonalGeoDatabaseFeatureSource(pathFilename, idColumnName, featureSchemaName, featureClassName, geometryColumnName);
        }
    }
 
    public class CustomPersonalGeoDatabaseFeatureSource : PersonalGeoDatabaseFeatureSource
    {
        public CustomPersonalGeoDatabaseFeatureSource(string pathFilename, string idColumnName, string featureSchemaName, string featureClassName, string geometryColumnName)
            : base(pathFilename, idColumnName, featureSchemaName, featureClassName, geometryColumnName)
        {
 
        }
 
        public override bool IsEditable
        {
            get
            {
                return true;
            }
        }
 
        protected override TransactionResult CommitTransactionCore(TransactionBuffer transactions)
        {
            // Write your own logic for add, delete, update features.
            return base.CommitTransactionCore(transactions);
        }
    }
}
 
Thanks,
 

Khalil



I tried to implement the CommitTransactionCore method. But the data from shape file are not appended the geodatabase. Do I miss anything? Thanks, Wilson 
  
 P.S. I split the one geodatabase table (7 records) into two geodatabase tables (one for first 5 records and another one for the last two records). Then export the second table into shape file. Tried to add the two records from shapefile to the first table to get 7 records. 
  
     protected override TransactionResult CommitTransactionCore( TransactionBuffer transactions ) 
       { 
          // Write your own logic for add, delete, update features.   
          TransactionResult result = new TransactionResult(); 
          result.TransactionResultStatus = TransactionResultStatus.Success; 
          //Collection<Feature> allFeatures =  this.GetAllFeatures( ReturningColumnsType.AllColumns ); 
          try 
          { 
             Dictionary<string, Feature> addedBuffer = transactions.AddBuffer; 
  
             foreach ( KeyValuePair<string, Feature> pair in addedBuffer ) 
             { 
                Feature f = ( Feature )pair.Value; 
                this.GetAllFeatures( ReturningColumnsType.AllColumns ).Add( f ); 
             } 
          } 
          catch ( Exception e ) 
          { 
             result.TransactionResultStatus = TransactionResultStatus.Failure; 
             this.RollbackTransaction(); 
          } 
          return result; 
       } 
  
 aspx.cs file: 
  
       PersonalGeoDbFeatureLayer sdzLayer = new PersonalGeoDbFeatureLayer( @"C:\GIS\DATA\GISDATA\training_area.mdb", null, null, "SDZ" ); 
       ShapeFileFeatureLayer sdzShapeFileLayer = new ShapeFileFeatureLayer( @"C:\GIS\DATA\GISDATA\sdz67.shp" ); 
       sdzShapeFileLayer.RequireIndex = false; 
       sdzShapeFileLayer.Open(); 
       FeatureSource shapeFS = sdzShapeFileLayer.FeatureSource; 
       Collection<Feature> allShapeFeatures = shapeFS.GetAllFeatures( ReturningColumnsType.AllColumns ); 
       sdzShapeFileLayer.Close(); 
       sdzLayer.Open(); 
       PersonalGeoDbFeatureSource fs = (PersonalGeoDbFeatureSource)sdzLayer.FeatureSource; 
       fs.Open(); 
       fs.BeginTransaction();  
       foreach ( Feature f in allShapeFeatures ) 
       { 
          fs.AddFeature( f ); 
       } 
       fs.CommitTransaction(); 
       fs.Close();

Wilson,


I think the reason is that the implementation of CommitTransaction is incorrect, as I imagine, the code below is that you want to add feature from shp file to the features collection of geodatabase, but GetAllFeatures is a method not propety that it only returns a copy of features, if you modify it, the original data will keep the same.


this.GetAllFeatures( ReturningColumnsType.AllColumns ).Add( f ); 

So I suggest you can use OldDb to access the .mdb file and execute insert statement to add feature to geodatabase. Even that, I still not sure it works for you, because we support geodatabase depends on a thrid part assembly FDO, we will try to implement Edit function by ourself in the future. For right now, maybe find a free tool to convert data is best choice.


Let me know if you make it.


Thanks


James



Do you have a timeframe to implement the Edit function? We have to programmatically add/update/delete the data in geodatabase. Thanks, Wilson

Hi Wilson, 
  
 As James mentioned, to override CommitTransaction method has several ways, such as using OLEDb, parsing binary or other database bridge etc. We currently don’t have a best solution for this operation. So we don’t have a timeframe at this stage. We need carefully consider this issue in order to avoid further issue on our side. Sorry for the inconvenience. 
  
 On the other hand, when you get the modify buffers such as “AddBuffer”, the implementation is to add the buffered features into the Geodatabase directly; please choose the way you are familiar with. 
  
 Thanks and feel free to let us know if you have more queries. 
 Howard 


I tried to use OleDb to insert the feature from shape file to Access DB. Those records were inserted into database. But the shape (Polygon) is not displayed on the screen. How do I insert the shape into table and retrieve it correctly? Attached is what I did. 
  
 //Feature f is from Shape file 
    private void AddRecordIntoAccess( Feature f ) 
    { 
       OleDbConnection conn = null; 
       try 
       { 
          conn = new OleDbConnection( 
              “Provider=Microsoft.Jet.OLEDB.4.0; " + 
              “Data Source=C:\GIS\DATA\GISDATA\training_area.mdb;Password=&#34;&#34;;User ID=Admin;” ); 
          conn.Open(); 
          Dictionary<string, string> nameValue = f.ColumnValues; 
          foreach ( KeyValuePair<string, string> pair in nameValue ) 
          { 
             string name = pair.Key; 
             string value = pair.Value; 
          } 
          string sql = “INSERT INTO sdz67 (Shape, ID, FAC_COPY, FAC_ID, Shape_Length, Shape_Area)” 
               + " VALUES ( ?,” + nameValue[ “ID” ] + “,’” + nameValue[ “FAC_COPY” ] + “’,’” + nameValue[ “FAC_ID” ] + “’,” + nameValue[ “Shape_Leng” ] + “,” + nameValue[ “Shape_Area” ] + “)”; 
          OleDbCommand cmd = 
              new OleDbCommand( sql, conn ); 
          OleDbParameter param = new OleDbParameter( “@Shape”, OleDbType.LongVarBinary, 
          f.GetShape().GetWellKnownBinary().Length ); 
          param.Value = f.GetShape().GetWellKnownBinary(); 
          cmd.Parameters.Add( param ); 
          cmd.ExecuteNonQuery(); 
       } 
       catch ( Exception e ) 
       { 
       } 
       finally 
       { 
          if ( conn != null ) conn.Close(); 
       } 
    }

Wilson, 
  
 The sample code is for lineshape, however you may append polygon shape to geo database, so you need to set AreaStyle when you initilize layer. 
  
 Let me know if it still can not display. 
  
 Thanks 
 James

My scenario: "I use Mapsuite Tools to draw some shapes on Map. I want to insert them into Oracle Spatial DB."


Please show me some examples.


PS: I have stored them without Oracle Spatial DB. The solution is: I stored them as a WellKnownText.


 



duong, 
  
 The best way to insert data to Orable Spatial DB is using a free tool to import shp file to Oracle, 
 you can download from 
 oracle.com/technetwork/database/enterprise-edition/downloads/xplatformsoft-089238.html 
 oracle.com/ocom/groups/public/@otn/documents/webcontent/158114.zip 
  and then you can use our OracleFeatureLayer to display them on the map. You can find the example at our HowDoI sample "LoadAnOracleFeatureLayer" under the "Data Providers" category. 
  
 Thanks 
 James 
  


Hi James, 
  
 Could you please point or attach the sample code for lineshape? Thanks, Wilson

Wilson,


The sample for lineshape is already post by Khalil above at 11-17-2010 04:41 AM, I think you need to sample for polygonshape


 
// the map unit maybe DecimalDegree, you can try
Map1.MapUnit = GeographyUnit.Meter;
                Map1.MapBackground.BackgroundBrush = new GeoSolidBrush(GeoColor.FromHtml("#E5E3DF"));
 
                CustomPersonalGeoDatabaseFeatureLayer worldLayer = new CustomPersonalGeoDatabaseFeatureLayer(MapPath("~/SampleData/world/polygon.mdb"), null, null, "Mains");
                worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1;
                worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
 
                worldLayer.Open();
                Map1.CurrentExtent = worldLayer.GetBoundingBox();
  worldLayer.Close();

                Map1.StaticOverlay.Layers.Add("WorldLayer", worldLayer);

Thanks


James 



 Posted By James on 12-30-2010 04:28 AM 

duong, 



The best way to insert data to Orable Spatial DB is using a free tool to import shp file to Oracle, 

you can download from 

oracle.com/technetwork/database/enterprise-edition/downloads/xplatformsoft-089238.html 

oracle.com/ocom/groups/public/@otn/documents/webcontent/158114.zip 

and then you can use our OracleFeatureLayer to display them on the map. You can find the example at our HowDoI sample “LoadAnOracleFeatureLayer” under the “Data Providers” category. 



Thanks 

James 




Dear James,


I 've used this way to convert shape file into spatial db. But the main problem is: I want to store some shapes, which I draw into spatial db. Ex: I use map tool to draw a polygon Shape, and I want to store it into spatial db. In the next time, when I load map, I also load it from db. 


Hope you understand my problem.


Thanks alot.



duong, 
  
 I think Wilson has implemented the edit function for GeoDatabaseFeatureSource, you can use the same logic to implement edit functions(Add, Update,Delete) for OracleFeatureSource, let me know if your override method can not work and provide your sample code. 
  
 Thanks 
 James

Hi James, 
  
 There is no any problem for me to display the records from GeoDatabase. The original records in GeoDatabase are displayed correctly on the screen. But the newly inserted ones are not dislayed. Please help to check the implementation to insert the record from shape file to the Geodatabase. I am not sure how to insert the "shape" into database and how to retrieve it for displaying. I thinkDuong has the same problem. 
  
 Thanks, 
  
 Wilson

Wilson, 
  
 You can do following test, first you read one record from GeoDatabase, such as GetFeatureById to return a feature, and then use CommitTransaction to add this feature back to GeoDatabase, at this time, two records should be the same, if you find any field not the same, you probably know what happened and you will know how to modify your code to make it correct. 
  
 Thanks 
 James