If you originally have Feature Information as DGN Resident but later want to tranfer this information into and ODBC Database such as Access, how can this be done?
Thanks.
Hi. A dgn xfm is best used when in a disconnected workflow. If you prefer to handle your data in a database, you can use the dgn2sdo tool that's delivered with Bentley Map to "transfer" your xfm data into an Oracle Spatial database. From there you can create a new schema and work in a connected mode.
You can also look into the Projectwise connector for Oracle.
Thanks,
Martin
Thanks Martin.
So we can export xfm information to Oracle Spatial but not to other ODBC databases such as Access. Is that correct?
Thank you.
Alan,
The Bentley Map feature model supports the use of RDBMS persisted business properties as well, not just with Oracle Spatial persistence. Database tables and properties can be associated with a feature class using the Bentley Geospatial Administrator application. When associating a feature class with a RDBMS table and business property, the Bentley Geospatial Administrator will automatically generate the necessary DML statements for INSERT, UPDATE and DELETE operations.
While there are no out-of-the-box tools in Bentley Map to transfer XML based business properties directly to a database, you could adapt the following VBA code example for your specific needs. This sample code can be used with the geo_example_designer workspace to INSERT new rows in an existing "BUILDING" table which has a structure that matches the "building" feature class and has an existing entitynum of 100 in the MSCATALOG table. In an actual application you would want to provide the ability to automatically generate DML statements to create the required tables and insert the appropriate entitynum entries in the MSCATALOG table.
Create a new VBA project and using "Tools > References..." add a "Bentley Map XFT Object Library 1.0" reference.
Create a VBA form, add a button and place the following code in the click event of the button.
Private Sub processFeatures_Click() Dim oLocateOp As New locateOp oLocateOp.IncludeOnlyFeatures = True oLocateOp.OnValidateRequiresFeature = True oLocateOp.IncludeFeatureName "Building"
If ActiveDesignFile.Fence.IsDefined = True Then Debug.Print "Processing fence contents..." oLocateOp.Mode = LocateOpMode.locateOpModeFence oLocateOp.AutoAcceptFence = True Else Debug.Print "Processing entire file..." oLocateOp.Mode = LocateOpMode.locateOpModeScan oLocateOp.AutoAcceptScanFile = True End If
CmdMgr.StartLocateOperation oLocateOp, New clsProcessFeatures End Sub
Add a new clsProcessFeatures class and insert the following code:
Implements ILocateOpEvents
Private Sub ILocateOpEvents_OnCleanup() End Sub Private Sub ILocateOpEvents_OnFinished(ByVal locateOp As xft.ILocateOp) Dim fe As FeatureEnumerator Dim oFeature As feature Set fe = locateOp.GetLocatedFeatures Do While fe.MoveNext Set oFeature = fe.Current If Not oFeature.Geometry.HasAnyDatabaseLinks Then insertRow oFeature End If Loop End Sub Private Sub ILocateOpEvents_OnRejected(ByVal RejectedReasonType As xft.LocateOpRejectedReasonType, RejectedReason As String) End Sub Private Sub ILocateOpEvents_OnTerminate() End Sub Private Sub ILocateOpEvents_OnValidate(ByVal RootFeature As xft.IFeature, ByVal element As element, point As Point3d, ByVal View As View, Accepted As Boolean, RejectReason As String) End Sub
Private Sub ILocateOpEvents_OnCleanup()
End Sub
Private Sub ILocateOpEvents_OnFinished(ByVal locateOp As xft.ILocateOp) Dim fe As FeatureEnumerator Dim oFeature As feature Set fe = locateOp.GetLocatedFeatures Do While fe.MoveNext Set oFeature = fe.Current If Not oFeature.Geometry.HasAnyDatabaseLinks Then insertRow oFeature End If Loop End Sub Private Sub ILocateOpEvents_OnRejected(ByVal RejectedReasonType As xft.LocateOpRejectedReasonType, RejectedReason As String)
Private Sub ILocateOpEvents_OnTerminate()
Private Sub ILocateOpEvents_OnValidate(ByVal RootFeature As xft.IFeature, ByVal element As element, point As Point3d, ByVal View As View, Accepted As Boolean, RejectReason As String)
Then add a new module and insert the following code which reads the XFM feature instances and generates the appropriate INSERT statement, performs the INSERT and attaches a new MSLINK to the features geometry.
Declare Function mdlDB_addRowWithMslink Lib "stdrdbms.dll" (ByRef mslink As Long, ByVal tableName As String, ByVal insertStmt As String) As Long Public Function insertRow(ByRef oFeature As feature) Dim pe As PropertyEnumerator Set pe = oFeature.GetPropertyEnumerator Dim dbColumns As String Dim dbValues As String Dim sqlInsertStatement As String Dim oProperty As Property Dim oPropertyDef As PropertyDef Do While pe.MoveNext Set oProperty = pe.Current If UCase(oProperty.Name) <> "VALUE" Then Debug.Print oProperty.Name, oProperty.Value If Len(dbColumns) > 0 Then dbColumns = dbColumns + "," End If If Len(dbValues) > 0 Then dbValues = dbValues + "," End If dbColumns = dbColumns + oProperty.Name Set oPropertyDef = oProperty.GetPropertyDefinition If oPropertyDef.Type = propertyDataTypeString Then dbValues = dbValues + "'" + oProperty.Value + "'" Else dbValues = dbValues + oProperty.Value End If End If Loop sqlInsertStatement = "INSERT INTO " + UCase(oFeature.Name) + " (" + dbColumns + ") VALUES (" + dbValues + ")" 'Debug.Print sqlInsertStatement Dim newMslink As Long Dim status As Long status = mdlDB_addRowWithMslink(newMslink, UCase(oFeature.Name), sqlInsertStatement) Debug.Print newMslink Dim oDatabaseLink As DatabaseLink Set oDatabaseLink = Application.CreateDatabaseLink(newMslink, 100, msdDatabaseLinkageOdbc, False, 0) Dim oElement As element Set oElement = oFeature.Geometry oElement.AddDatabaseLink oDatabaseLink oFeature.Geometry = oElement oFeature.Write False End Function
Declare Function mdlDB_addRowWithMslink Lib "stdrdbms.dll" (ByRef mslink As Long, ByVal tableName As String, ByVal insertStmt As String) As Long
Public Function insertRow(ByRef oFeature As feature) Dim pe As PropertyEnumerator Set pe = oFeature.GetPropertyEnumerator
Dim dbColumns As String Dim dbValues As String Dim sqlInsertStatement As String Dim oProperty As Property Dim oPropertyDef As PropertyDef
Do While pe.MoveNext Set oProperty = pe.Current If UCase(oProperty.Name) <> "VALUE" Then Debug.Print oProperty.Name, oProperty.Value If Len(dbColumns) > 0 Then dbColumns = dbColumns + "," End If If Len(dbValues) > 0 Then dbValues = dbValues + "," End If dbColumns = dbColumns + oProperty.Name Set oPropertyDef = oProperty.GetPropertyDefinition If oPropertyDef.Type = propertyDataTypeString Then dbValues = dbValues + "'" + oProperty.Value + "'" Else dbValues = dbValues + oProperty.Value End If End If Loop sqlInsertStatement = "INSERT INTO " + UCase(oFeature.Name) + " (" + dbColumns + ") VALUES (" + dbValues + ")"
'Debug.Print sqlInsertStatement Dim newMslink As Long Dim status As Long status = mdlDB_addRowWithMslink(newMslink, UCase(oFeature.Name), sqlInsertStatement) Debug.Print newMslink Dim oDatabaseLink As DatabaseLink Set oDatabaseLink = Application.CreateDatabaseLink(newMslink, 100, msdDatabaseLinkageOdbc, False, 0) Dim oElement As element Set oElement = oFeature.Geometry oElement.AddDatabaseLink oDatabaseLink oFeature.Geometry = oElement oFeature.Write False End Function
After attaching the database linkage, you may actually want to write a new element to the design file and delete the feature instance. Regardless I hope this small VBA sample provides you some insight into how one might transfer XFM business properties into any MicroStation supported database.
Regards,
Jeff Bielefeld [Bentley]