VBA - Bentley MAP detach XFM Feature record from graphical element.

Since Bentley Map has no !! way to transfer the XFM data in an ordinary database, I had to write me a VBA application.

The VBA Macro creates a database attachement with the XFM Feature data. The the XFM block should be deleted.

In the MAP Help I havn't found any command to resolve this.

...........

Set oDatabaseLink = Application.CreateDatabaseLink(glMslinkOld, gnEntityNum, msdDatabaseLinkageOdbc, False, 0)


If oElement.IsGraphical Then
oElement.AddDatabaseLink oDatabaseLink
??? remove XFM ????
oElement.Rewrite
gnCount = gnCount + 1

......

Parents
  • Hi GRJ,

    I have no simple answer for your (sorry), but I'd like to ask what exactly do you want to achieve if talking about "no !! way to transfer the XFM data in an ordinary database"? Do you want to:

    • Make a one-step export of XFM data attached to XFM elements to some relation database.
    • Convert "XFM project with data stored in DGN file" to "XFM project using mslink to store data in a database".
    • Drop anything related to XFM from elements and design file and to convert existing XFM DGN file into old style DGN file with mslinks (including data transfer)?

    With regards,

     Jan

  • Hi Jan,

    I want to import cadastral shape areas ( files in SHP and DBF format) in Microstation how you said as "old style DGN with mslink".
    For this I import the SHP/DBF files in bentley map, then I want to export the XFM data record to the odbc database connected with MSLINK to the graphical element .

    With regards,
    Josef
  • Hi Josef,

    so the complete workflow is:

    1. There are some shape files with the same structure (cadastral map areas).
    2. There is XFM project designed based on SHP files structure. (Note: It's possible to import SHP file both with and without XFM project, so it's the reason of this question)
    3. You use MapInteroperability tool in Bentley Map to import SHP file
    4. You want to convert such file into "mslink style", which includes:
      1. To move properties from XFM to database
      2. To establish mslinkg to this newle created record
      3. To drop XFM element into normal MicroStation element

    Is it correct?

    With regards,

     Jan

  • Hi Jan,

    I use Bentley Map only for import SHP Files, no XFM project.

    Command:

    >File >Import >Gis Data Types >Imports >New Import >Add File >Import

    With regards,

    Josef

    Attached my MVBA script.

    dbXFM2DB.mvba

  • Hi Josef,

    I have had not enough time to check your code (but for the first sight it looks not bad, even if talking about its structure). I did some quick testing and in my opinion this code should work:

    Dim ftEnum As FeatureEnumerator
    Set ftEnum = locateOp.GetLocatedFeatures
    
    Do While ftEnum.MoveNext
    	Dim currentFeature As feature
    	Set currentFeature = ftEnum.Current
    	
    	Dim pureElement As element
    	Set pureElement = xft.FeatureMgr.RemoveFeatureLinkages(currentFeature.Geometry)
    	
    	'Do whatever you need with the new element
    	pureElement.Level = ActiveDesignFile.Levels.Find("Default")
    	
    	pureElement.Rewrite
    Loop

    I guess you should add it to your process feature class to OnFinished method.

    With regards,

     Jan

  • Hi Jan,
    First thank you for your effort!

    If I understand you correctly, then I have to work through all selected features and not like my approach through the selected elements.
    My basic code is (was):
    Dim ee As ElementEnumerator
    Set ee = locateOp.GetLocatedElements
    ShowPrompt "Elements: " & CStr(locateOp.LocatedElementsCount)
    Do While ee.MoveNext

    Set ele = ee.Current
    ele.Redraw msdDrawingModeHilite
    If Not ele.HasAnyDatabaseLinks Then
    insertRow ele ' convert xfm data to ODBC record an attach to element
    End If
    Loop

    I must substitute this approach with your code.
    Is this correct?

    With regards,
    Josef R.
  • Hi Josef,

    Unknown said:
    f I understand you correctly, then I have to work through all selected features and not like my approach through the selected elements.

    My experience with Bentley Map XFT API is not good enough to say if you have to and if it's the only way, but it's the approach that seems to work ;-)

    If I understand BM API approach right, the feature is the core, not element (which representing the feature geometry and is not mandatory for some feature types like collections or data). This is in parallel with GIS approach as used in e.g. OGC and presented in many APIs (GeoTools, PostGIS etc.). So if you want to "defeaturize" a particular object, you have to enumerate features, not plain elements. Maybe your approach to work with elements directly can work also, but XFT API is quite high level, so there is a limited freedom to define what exactly will happen automatically and what not.

    In my opinion you can use my code to receive a plain MicroStation element (this is not a new element, but the original element representing the feature geometry and now it's "defeaturized") and to add mslink to this element using already existing your code.

    Unknown said:
    I must substitute this approach with your code.

    I assume it should not be a huge effort. Fortunately it's still about the same Locate class and OnFinished method. The only important thing is that you have to drop XFM feature data from an element after you migrate XFM attributes to a database, because after the element is "defeaturized", it's not possible to receive any XFM data anymore. Something like (enumerating features step by step):

    1. Read XFM properties from a feature
    2. Store the properties in a database (you will receive mslink)
    3. Remove XFM linkages from the feature
    4. Rewrite the element
    5. Add mslink to the element

    With regards,

     Jan

Reply
  • Hi Josef,

    Unknown said:
    f I understand you correctly, then I have to work through all selected features and not like my approach through the selected elements.

    My experience with Bentley Map XFT API is not good enough to say if you have to and if it's the only way, but it's the approach that seems to work ;-)

    If I understand BM API approach right, the feature is the core, not element (which representing the feature geometry and is not mandatory for some feature types like collections or data). This is in parallel with GIS approach as used in e.g. OGC and presented in many APIs (GeoTools, PostGIS etc.). So if you want to "defeaturize" a particular object, you have to enumerate features, not plain elements. Maybe your approach to work with elements directly can work also, but XFT API is quite high level, so there is a limited freedom to define what exactly will happen automatically and what not.

    In my opinion you can use my code to receive a plain MicroStation element (this is not a new element, but the original element representing the feature geometry and now it's "defeaturized") and to add mslink to this element using already existing your code.

    Unknown said:
    I must substitute this approach with your code.

    I assume it should not be a huge effort. Fortunately it's still about the same Locate class and OnFinished method. The only important thing is that you have to drop XFM feature data from an element after you migrate XFM attributes to a database, because after the element is "defeaturized", it's not possible to receive any XFM data anymore. Something like (enumerating features step by step):

    1. Read XFM properties from a feature
    2. Store the properties in a database (you will receive mslink)
    3. Remove XFM linkages from the feature
    4. Rewrite the element
    5. Add mslink to the element

    With regards,

     Jan

Children
  • Hi Jan,

    the only trouble is that the command ...RemoveFeatureLinkages... in line no. 9  in my version of Bentley Map 08.11.07.113 does not exist.

    Regards,

    Josef

  • Unknown said:
    in my version of Bentley Map 08.11.07.113 does not exist.

    Hmmm ... that's bad. But not surprising, V8i (SELECTseries 1) is quite old version and API is enhanced in every release.

    But a workaround still can be implemented in my opinion and should be not extremely difficult: I assume, because the source data are SHP files, the imported geometry is a simple one, so it's point, line string and polygon (I am aware e.g. polygons can be imported as collection sometimes, but don't make it too complex for now ;-). Every feature has Geometry and GeometryType property. You can implement "element factory" that will take the source data and will create a new element based on the data. Because there should be 3 geometry types only, we are talking about 3 quite simple functions (create point, line string and shape).

    I recall (long time ago) I tried to use Geometry.Clone() method to receive new clean element, but I guess it does not work as expected. But it's something I recommend to try in the first step as it's very simple approach.

    With regards,

      Jan

  • Hy Jan,

    I have checked how Bentle Map stores the Elements, attached a schema that illustrates the file positions.

    To eliminate all unnecessary data, I want to attach the MSLINK link at the element following the "Associative Region" - element.

    How can I do it?

    With regards,

    Josef R.

    Dim ftEnum As FeatureEnumerator
    Set ftEnum = locateOp.GetLocatedFeatures

    Do While ftEnum.MoveNext
    Dim currentFeature As feature
    Set currentFeature = ftEnum.Current

    Dim pureElement As element
    ' Set pureElement = xft.FeatureMgr.RemoveFeatureLinkages(currentFeature.Geometry)
    Set pureElement = currentFeature.GetRelatedRegionElement
    Debug.Print pureElement.FilePosition

    ' ???? How select the element subsequent to pureElement (first member of RegionElement)

    SET pureElement = ??????

             processFeatureEelement currentFeature, pureElement

    Loop

    x626_x.dgn

  • Hi Josef,

    Unknown said:
    I have checked how Bentle Map stores the Elements, attached a schema that illustrates the file positions.

    Forget file position information. It's true it can help in similar discussions, but the file position is evil even in my opinion. Not only in a plain MicroStation (the last time it made sense to work with FP was MicroStation/J), but especially in Bentley Map, where features are implemented is some way, that is not very important ... and changed in V8i (SELECTseries 2) in the case of associative elements and can change anytime again.

    Unknown said:
    To eliminate all unnecessary data, I want to attach the MSLINK link

    If I understand your requirement right, this sentece has no sense. There is no relation between mslink attachment and "defeaturizing" (removing XFM data) and these two tasks have to be discussed separately.

    Unknown said:
    to attach the MSLINK link at the element following the "Associative Region" - element.

    There is no MicroStation element called "Associative Region", it's more a mental concept. In this old XFM version to implement this concept, a cell is used. So if there is a polygon with hole, all polygons are encapsulated into a cell (in fact into two cells).

    Because "polygon with hole(s)" is implemented differently in Bentley Map and MicroStation, I guess you will have to recreate the geometry in your code. In newer Bentley Map I assume it's also ensure by RemoveFeatureLinkages method ... but I am not sure.

    Unknown said:
    How select the element subsequent to pureElement (first member of RegionElement)

    • GetRelatedRegionElement returns top level cell header (outmost element)
    • SubFeatureCount return a number of subfeatures (2 at your case)
    • GetSubFeature(0) returns the 1st polygon, which I guess by implementation will be the outmost polygon
    • GetSubFeature(1) returns the 1st hole in the polygon

    As you can see, there is "a gap" between Bentley Map feature model (there feature and subfeatures) and MicroStation implementation (cell > cell > 2 shapes).

    Without any testing, I think you should take geometry from 1st and 2nd subfeature and to create plain MicroStation "grouped hole" element (see "References an Element from its Cache" example in MicroStation VBA help) and when this new cell will be created, to attach mslink to it.

    With regards,

      Jan

  • Dear Jan,

    now the macro works, MSLINK is attached to the right graphical element, not like before where just all elements was linked to ODBC Database., the program takes a little longer, but that's no problem.

    The strip of XFM Data for now is not working, in the dgn file remains a lot of unnecessary data, at the moment I can at least be productive.

    Thank you for your help.

    With regards

    Josef R.

    Attached the macro,  maybe someone has the same problem and can improve it.

    5305.dbXFM2DB.mvba