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.
Martin Tyberg said: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:
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.
Martin Tyberg said: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
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
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 ..
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?
Hi Martin Tyberg ,
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?
HI Martin,
Martin Tyberg said: 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:
Martin Tyberg said: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).
Martin Tyberg said: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,
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 Tyberg said: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.
Martin Tyberg said: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.
Martin Tyberg said: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.
foreach
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.
Martin Tyberg said: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.
Martin Tyberg said: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.
Martin Tyberg said: 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.