In the samples getting started -> trackandeditshapes, i see that it is convenient to add/edit/delete different shapes on client side. How do i save and retrieve those shapes in the database?
Sace/retrieve shapes in TrackOverlay
Ric,
this is completely missing from the sample… here is the code:
Overlay.Lock.EntryLockWrite()
try
{
layer.Open();
layer.EditTools.BeginTransaction();
BaseShape b = theMap.EditOverlay.EditShapesLayer.InternalFeatures[0].GetShape();
// if you are editing:
b.Id = m_SelectedFeature.Id;
layer.EditTools.Update(b);
// if you are inserting:
layer.EditTools.Insert(b);
layer.EditTools.CommitTransaction();
layer.Close();
}
finally
{
Overlay.Lock.ExitLockWrite();
}
thanks Patrick. But when there are many shapes, how do you store all of them in databases like SQL? when the user exits, it saves all shapes (including their geographical locations), so when the program is run again, all shapes are loaded from database and redrawn on their original locations?
Ric, my code works for shapefile … sorry I misunderstood your request.
I leave the answer to Yale as I don’t know myself.
Patrick.
Patrick thanks for your sharing!
Ric,
I think the solution provided is very similar to Patrick’ solution. Only difference we can save all the tracked features to a MsSqlFeatureSource or any other type of DB source.
Following code is used to save it to DB:
MsSql2008FeatureSource featureSource = new MsSql2008FeatureSource(connectString, tableId, featureId);
featureSource.Open();
featureSource.BeginTransaction();
GeoCollection<Feature> features = winformsMap1.TrackOverlay.TrackShapeLayer.InternalFeatures;
foreach (Feature feature in features)
{
featureSource.AddFeature(feature);
}
TransactionResult result = featureSource.CommitTransaction();
featureSource.Close();
Following code is used to fetch data from DB:
MsSql2008FeatureSource featureSource = new MsSql2008FeatureSource(connectString, tableId, featureId);
featureSource.Open();
Collection<Feature> allFeatures = featureSource.GetAllFeatures(ReturningColumnsType.AllColumns);
featureSource.Close();
winformsMap1.TrackOverlay.Lock.EnterWriteLock();
try
{
foreach (Feature feature in allFeatures)
{
winformsMap1.TrackOverlay.TrackShapeLayer.InternalFeatures.Add(feature);
}
}
finally
{
winformsMap1.TrackOverlay.Lock.ExitWriteLock();
}
winformsMap1.Refresh();
Any more questions just let me know.
Thanks.
Yale
Thanks Yale. Forgive my shallow knowledge, i dont have any idea on how MapSuite works with databases, in my case, SQL. i know there are 3 parameters to MsSql2008FeatureLayer: connection string, table name and name of the column that holds the unique feature ID. i do not know how to prepare the table that MapSuite writes to, or retrieves from.
I created a table names "MyTable", added a column named "FeatureID":
MsSql2008FeatureSource featureSource = new MsSql2008FeatureSource(conString, "MyTable", "FeatureID");
when i execute featureSource.Open(), the error is: "can not find the geometry column". Obviously i need to create some more fields so MapSuite can store information of features. Can you show me how to prepare a table to store and retrieve shapes?
Ric,
That is a good question!
There are 2 ways you can follow to create a Table which can be used in MapSuite component:
1) Create a empty tool from Sqlserver2008 Management studio. One important thing is you have to create a field which type is “Geometry” or “Geography”. Following is the screenshots.
2) Use a tool “Shape2Sql.exe” to import your shape file data into sql server 2008. For more information you can see following post:
gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/21/aft/4903/afv/topic/afpgj/1/Default.aspx#8960
Let me know if you have more questions!
Thanks.
Yale
Yale,
i created a field with type "Geometry", shapes were saved successfully, be it a point, line, rectangle or ellipse. But when i load from database, error occured "An item with the same key has already been added." on this line:
Collection<feature> allFeatures = featureSource.GetAllFeatures(ReturningColumnsType.AllColumns);
It happens when database has many rows or only 1 row. Connection string, table name and column name are exactly the same when saving or retrieving. I can't figure out what was wrong...
Ric,
Thanks for your post!
I think the reason for this is that we DIDNOT clear the original TrackShape when we load from DB of the shapes, so when we save the shapes again, we will have multiple features with same key exists.
Try adding one statement in the fetch data from DB procedure as following:
MsSql2008FeatureSource featureSource = new MsSql2008FeatureSource(connectString, tableName, featureId);
featureSource.Open();
Collection<Feature> allFeatures = featureSource.GetAllFeatures(ReturningColumnsType.AllColumns);
featureSource.Close();
winformsMap1.TrackOverlay.Lock.EnterWriteLock();
try
{
// Here clear the orignal tracked shapes.
winformsMap1.TrackOverlay.TrackShapeLayer.InternalFeatures.Clear();
foreach (Feature feature in allFeatures)
{
winformsMap1.TrackOverlay.TrackShapeLayer.InternalFeatures.Add(feature);
}
}
finally
{
winformsMap1.TrackOverlay.Lock.ExitWriteLock();
}
winformsMap1.Refresh();
Let me know if you have any other questions.
Thanks.
Yale
Yale,
The execution did not reach Try block, error occured on line 3:
Collection<Feature> allFeatures = featureSource.GetAllFeatures(ReturningColumnsType.AllColumns);
Error says "An item with the same key has already been added.". My test database only have 1 column names "FeatureID" of type Geometry, and has only 1 row of record, which is a saved Polygon.
Ric,
I am sorry I still recreate the problem again after adding the line of code.
Can you try my test demo codes as following db structure to see this problem will still be happening?
One thing I want to make sure is in the table, we marked the “Rect” column as “Identity increment” to mark it Identifiable.
Let me know if you have any more questions.
Thanks.
Yale
943-PostDemo.zip (11.6 KB)
Hi Yale,
Sorry for not closing this thread yet, the saving/retrieving of shapes into SQL is an important aspect for us, i have to get it right. I tried your code, added all shapes for testing to make it complete, and found some problems when saving shapes. Everytime i test, i empty the database to have a clean start. i found a problem when saving rectangle and square. For example, try draw only 1 sqaure and save it, it says "1 failed", the database is still empty. Try draw 2 squares, it says "2 failed". Rectangles are same with square, always failed. But when you draw all other shapes, they all saved and loaded without problem.
When you mix different shapes, as long as there are rectangles or squares, they will cause errors. For example, when you have 50 other shapes with 3 squares and 5 rectangles, a total of 58, "8 failed" when you try to save them all.
Maybe there are some errors in MsSql2008FeatureSource class?
Ric,
I am sorry to say that I tested against the latest public release 3.0.362, it works fine no matter I save Rectangles or Squares or mixed shapes.
Can you let me know which version you are using?
Any more information would be appreciated.
Thanks.
Yale
Yale,
You’re right, they all worked well. Sorry, maybe i made a mistake somewhere. Today i tested it again, all shapes were drawn, saved and retrieved without problems.
Thank you for your help.
Ric
Ric, you are always welcome!
Any questions just let me know.
Thanks.
Yale