How to retrieve imported shapefile attribute values that are shown as Item Type properties but no item type library is created by the import?

HI - I have imported a shapefile into Microstation and I can see its attribute values under an Item Type whose name is the same as the imported shapefile. However, this Item Type is not shown under any Item Type library in the Item Types dialog. How do I read an element's imported attribute values in this scenario using the C# API?

Thanks,

Martin

  • Hi Martin,

    at first, please follow the best practices and specify exactly a product and its version exactly. Quite often answer is different when V8i or CE product is discussed.

    However, this Item Type is not shown under any Item Type library in the Item Types dialog

    I think used terminology must be corrected at first, because Item and Item Type represent different things:

    • As Items are in Explorer dialog (and also in Properties, with no explicit "Item" naming) displayed any EC data, attached to an element.
    • Item Types are Items, that can be defined / created / attached by a user. Technically Item Types are a subset (or can be said "specially created") of EC data.

    So, when talking about data, created from SHP files, they are EC data, not Item Types defined by user, so they are displayed as Items, but no Item Type library is displayed.

    How do I read an element's imported attribute values in this scenario using the C# API?

    Because you want to access EC data, I recommend to start with blog "EC CRUD Operations With Native And Managed DgnEC APIs".

    With regards,

      Jan

  • Hi Jan,

    I'm new to this forum so thank you for pointing me to the best practices page. Thanks for clarifying the various terms for me and pointing me to the EC data blog entry - I'll start digging in ..

    Martin

  • Hi Jan,

    The DgnECManagedCRUDExample distributed with the MicroStation SDK and the "EC CRUD Operations With Native And Managed DgnEC APIs" blog page both assume that one's ECSchema is stored in a standalone xml file based on the need to use ECObjects.LocateSchema() and SearchPathSchemaFileLocater() to obtain an IECSchema instance. It's not clear from the API docs how to load a schema that is stored in a dgn file and how to enumerate the schemas in a dgn file as ecx schema list does. Is there an example somewhere that might illuminate this? 

    Thanks,

    Martin

  • Hi  ,

    Consider using "SDKSEARCH" available within the MicroStation Developer Shell.

    Simply provide (1) search term and it provides (optimized towards migration and implementation needs) search results across all SDK files and Product (e.g. MicroStation ascii and binary files - when using "verbose" option) and will even prompt you after looking locally to search across all Bentley Communities listing the most recent posts (recommendations, solutions, "known issues", etc.) first for highest level of usefulness.

    e.g. Typing: SDKSEARCH SearchPathSchemaFileLocater

    1. Local Search Results: 

    2. Internet Search Results:

    Search - Bentley Communities

    From this example we find there are (4) Example source code files and (2) Header/Include files and on the Internet Search (6) results (including this most recent discussed) of interest available for review.

    HTH,
    Bob



  • Hi Bob,

    Thanks for the info. I went to this page   MicroStation CONNECT Developer Shell Overview 

    to learn how to open the developer shell however the page mentions exploring how to do so but then I see no elaboration on how to do it. Can you please describe from where the dev shell can be opened?

    Thanks,

    Martin

  • HI Martin,

    It's not clear from the API docs how to load a schema

    It is true EC Framework documentation is not available as one comprehensive document, but fragmented into chm files, blogs and presentations.

    Generally I recommend:

    • To search this forum for similar discussions (e.g. where DgnECManager is mentioned)
    • Search this community (especially Files section) for Power Points and other supplemental documents about EC Framework and EC API.
    and how to enumerate the schemas in a dgn file as ecx schema list does

    Key-in "ecs schema list" does not list all EC schemas, but only schemas already stored in DGN file.

    In the discussed case, you do not need locate any external schema, because EC schema, describing SHP data, is created and stored automatically in DGN file when SHP file is imported (it makes no sense to create external schema, because data becomes inaccessible when such DGN is moved to another PC).

    how to load a schema that is stored in a dgn file

    When EC schema is stored in DGN file, you do not need to do much.

    Did you check what DgnECManager does and what methods it offers? Because you do not need any special Query, you can use a shortcut and to use GetElementProperties() method and to filter SHP data you are interested in.

    Regards,

      Jan

  • Hi Jan,

    Thanks. Using DgnECManager with:

    IEnumerable<string> schemas = DgnECManager.Manager.DiscoverSchemas(activeDgnFile, ReferencedModelScopeOption.None, false);
    
    

    I was able to retrieve the same list as ecx list schema so that gave me some confidence. Further, the following enabled me to navigate the shapefile's imported dbf schema:

    FindInstancesScope scope = FindInstancesScope.CreateFileScope(Session.Instance.GetActiveDgnFile(), new FindInstancesScopeOption(DgnECHostType.File));
    IECSchema schema = DgnECManager.Manager.LocateSchemaInScope(scope, "rds2_shp_BDF07229C0A7445D812B94BDAACC4C9A3818EC68", 1, 0, SchemaMatchType.Latest);
    IECClass[] classes = schema.GetClasses();
    int numProperties = classes[1].CountProperties();
    IEnumerator<IECProperty> properties = classes[1].GetEnumerator();
    while(properties.MoveNext())
    {
        IECProperty property = properties.Current;
    }
    
    

    Finally, the following enabled me to get the ECInstances of each shapefile element:

    DgnECInstanceCollection ecInstanceColleciton = DgnECManager.Manager.GetElementProperties(element, ECQueryProcessFlags.SearchAllExtrinsic);
    IEnumerator<IDgnECInstance> dgnECInstances = ecInstanceColleciton.GetEnumerator();
    while(dgnECInstances.MoveNext())
    {
        IDgnECInstance ecInstance = dgnECInstances.Current;
        IEnumerator<IECPropertyValue> propertyValues = ecInstance.GetEnumerator();
        while(propertyValues.MoveNext())
        {
            IECPropertyValue propertyValue = propertyValues.Current;
        }
    }
    
    

    Interestingly, retrieving the ECInstances from each element is pretty slow as compared to retrieving every coordinate from each graphic element.

    Martin

  • Hi Martin,

    Finally, the following enabled me to get the ECInstances of each shapefile element:

    The code queries all EC properties of all EC classes, so potentially more than necessary. Probably not issue in your code, but generally the code processes everything extrinsic, now specifically EC data coming from SHP file.

    Interestingly, retrieving the ECInstances from each element is pretty slow as compared to retrieving every coordinate from each graphic element.

    What is interesting here?

    Coordinates are native data, stored as part of element in DGN file. So it is one from "core element feature", always available for all displayable elements.

    EC data must be queried and found in XAttributes data, which - if I remember right - are stored in DGN file in separate stream. So it is always slower, because requires some extra operations.

    On the other hand: My experience is that when access to EC data is "slow", the problem is primarily in code structure and used algorithms. When performance is the priority, it often requires to think in detail how EC data and ECQuery works and design the whole code accordingly.

    the following

    Not directly related to the discussion topic, but:

    while(dgnECInstances.MoveNext())

    ... does this code come from VBA? To enumerate collections, to use foreach is C# standard construction, simpler and easier to be read.

    With regards,

      Jan

  • Hi Jan,

    The posted code is retrieving all ECInstances on each element as instructional/experimental code; however, I did notice that each imported element only has one ECInstance anyway (except for 1 element for some reason) where each ECInstance contains values from a DBF row.

    The slowed performance is interesting only because it was proportionally much slower which I didn't expect since the shapefile is small but thank you for informing me about the separate stream that could explain the difference in speed. I'll read more about how EC Data is structured in the file.  I won't need to read every ECProperty, just the ones specified by a user to construct a set of labels that are dynamically placed on the screen as the user pans; however, I noticed that just getting the ECInstance is "time consuming".

    The code isn't from VBA - I wrote it in C# - yes that's true, it could be written in that concise fashion.

    Thanks,

    Martin

  • Hi Martin,

    however, I did notice that each imported element only has one ECInstance anyway (except for 1 element for some reason) where each ECInstance contains values from a DBF row.

    Yes, but it is not common situation, only specific for your DGN file(s). When any other extrinsic EC data is attached (like Item Type is attached by a user, or application like ORD attach own EC data...), GetElementProperties returns collection with all these data.

    The slowed performance is interesting only because it was proportionally much slower which I didn't expect since the shapefile is small

    Even when there are technical reason, why the access to EC data is slower, usually it should not be visible for a user. Good example is Properties dialog, which is completely "EC data based" and is, when one element is selected, pretty quick.

    So if you encounter substantial slow down, I recommend to check the code efficiency and maybe to do a benchmark to see what causes the slowness.

    however, I noticed that just getting the ECInstance is "time consuming".

    As I wrote above, sometimes it makes sense to think about the best approach. Maybe in the discussed case, to search for EC instances, representing SHP data, without iterating elements and querying EC data for every individual element, would be faster. But it's just a thought.

    With regards,

      Jan