Hi - I'm looking to build an addin that can register with a view window to be notified when its extent changes due to a user panning or zooming. Upon catching this event, I need to read the graphic elements that are shown in the view window after the extent change has occurred. From what I've been reading, it appears that if this can be done, it's likely only possible in C++ so I can switch to that language if that's the case.
Thanks,
Martin
Hi Martin,
Martin Tyberg said:Does Microstation broadcast a view window extent change event that can be subscribed to?
For sure it does. Before asking, I recommend to search MicroStation C++ API documentation: Sometimes it can be hard to find the right information, but it builds general API knowledge (including NET API, because it closely copies native API). In this specific case "view update" search returns right results.
There are couple of "view update callbacks" available in C++. Maybe similar functionality is available in NET API too (I am not sure), but to interact with a view is performance sensitive task, so to use C++ is recommended (even when it is possible to implement the same in NET).
Martin Tyberg said:Upon catching this event, I need to read the graphic elements that are shown in the view window after the extent change has occurred.
Is it really necessary? Any view can be updated many (tens, hundreds?) times every second. All hooks must be processed asap, but to scan what elements are displayed is probably not quick (in terms of how fast a view update must be).
I guess it can be done, but I assume it requires low-level optimization, maybe async approach or some type of observer pattern. But it is hard to say without knowing context.
With regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
HI Jan,
Sorry, to be more specific, I'm interested in knowing that the view extent has changed only after the user has lifted the mouse button and completed the pan or zoom operation. At this point, I will read the graphic elements in the view and their EC data, feed that data into our dynamic label placement engine to perform a label placement, and draw the placed labels as transients on the view.
Thanks for the API hints - I will dig some more into the view update callbacks.
Hi Martin Tyberg ,
Do you mind describing the overall workflow that you are attempting to achieve?
It is often helpful to have an idea of Inputs (User and Data/Types), Outputs and (anticipated) Processing inbetween to help provide best input/recommendations towards a proper solution. Often times not knowing this information could lead to very poor user performance and experience situations that could otherwise be avoided if known/discussed early on.
Thank you and HTH,Bob
Martin Tyberg said:only after the user has lifted the mouse button and completed the pan or zoom operation.
No such event exists ... because no such can be identified (because cannot be specified) ;-)
Does "completed" means there is no action for 0.1 seconds? Or is there any other condition?
Usually these situations lead to some reactive mechanism, based on async observer concepts, when new event stops existing running one. And it!s not simple to implement in not thread safe MicroStation synchronous environment. Can be done, but can be complex task.
Martin Tyberg said:At this point, I will read the graphic elements in the view and their EC data, feed that data into our dynamic label placement engine to perform a label placement
It sounds like extensive task.
I implemented something similar long time ago in V8i, and it was not simple even when we worked with simple, exactly defined DGN data (because generated from other system), so we optimize code only for specific scenarios. And personally I was not happy with the result, but time and budget were limited.
Martin Tyberg said:Thanks for the API hints - I will dig some more into the view update callbacks.
As Robert Hook wrote: It is crucial to know complete context and workflow, and to evaluate it with knowledge how MicroStation works internally and what API offers.
In the discussed case, I think to use view update monitoring is wrong decision. Maybe to use SetSubstituteElemFunction is better, because it does not require to check all displayed elements every time a view is updated. But still, I can imagine some kind of caching is required (and to use caching means you fail as a programmer ;-), because to access EC data is incomparable with view update performance
Hi Bob,
Sure no problem. We have previously incorporated our automated labeling engine into other GIS systems and also into Microstation 7/8 20 yrs ago using MDL C but that implementation was outputting static text elements at the time. In this case, I am building a prototype to explore feasibility of repeating what was done in other GIS systems here in MicroStation Connect and see how that can tie in initially with OpenCities Map and potentially other Bentley verticals.
So our workflow is for the user to first open our Label Manager dialog that is populated with spatial layer names. For this prototype, I am interpreting the level names as layer names (as inspired by how the Microstation shapefile importer imports shapefiles into dgn). For each layer in the Label Manager, the user specifies whether the features (graphic elements in dgn language) are to serve as obstacles (objects to be avoided from being overlapped by text), and creates one or more labels to be placed for features in that layer. The label is built from an expression based on attribute names. In this case, I will pull the attribute names from an element's EC Property data. Also for a layer is built a placement rule based on point, line, or area placement rules. Once the user configures the layers in the Label Manager, this information is stored in the GIS (in this case, I would store the serialized LM data as something in the dgn file, maybe as EC data).
The user would then click another button that turns on a listener for view extent changes. Each time the view extent has changed after the user releases the mouse, the handler would do the following:
Hi Jan,
I think it depends on how the GIS/CAD system defines "view extent has changed". In another GIS system, I would catch the mouse up event in a view and in the handler check if the current view extent is different than what it was the last time the handler was called. This worked fine until eventually the GIS system introduced a "view extent change" event which was better.
That's true - it's not a small task but I'm hoping as a prototype, not a huge one either :)
Yes, as mentioned in my previous post, I also did something similar for Microstation 7/V8i many years ago but in MDL C for targeting static label placement for map makers using Microstation and treating each dgn file as a spatial layer that when combined produced a map. In that scenario, we supported retrieving attribute information from tags and external relational databases to build label content.
Ok, I'll look at SetSubstituteElemFunction and see what's ultimately possible.
I think mdlWindow_setFunction is what you want. This function can monitor all windows (all dialogs and views) events as below:
enum WindowModifyType { WINDOW_SHOWEVENT = 1, WINDOW_HIDEEVENT = 2, WINDOW_ORDEREVENT = 3, WINDOW_MOVEEVENT = 4, WINDOW_CHANGESCREENEVENT = 5, WINDOW_MINIMIZEEVENT = 6, };
Hi Yongan,
Thank you for the thought. However, I think that function is used for detecting changes to the Microsoft Window itself as opposed to a change in what portion of the model is shown in the view window as a result of the user performing a pan/zoom action in the view window.
Martin Tyberg said:I would catch the mouse up event in a view and in the handler check if the current view extent is different than what it was the last time the handler was called.
In MicroStation plenty of events can be monitored, so to track "view changed" (because of panning, zooming etc.) is not complicated. How such event is processed is performance sensitive. And to query EC data can slow down the process too much.
Martin Tyberg said: I also did something similar for Microstation 7/V8i many years ago but in MDL C for targeting static label placement for map makers using Microstation
What worked in V8i should work in CE too, at least in terms of concept (and the code is probably similar).
But as usually, MicroStation offers different ways, how to reach similar (or even the same) result :-)
Another decision is how to build the labels: You mentioned transient elements, which is old concept used in V8i, treated a bit obsolete now, but still supported. MicroStation CE offers new ways, how to decorate view with extra graphics, both vector and rasters (sprites).
Thanks for the outlined considerations as I proceed. The term transient is one that an internal Bentley expert mentioned, I thought generically. I've never actually created a transient, just static text elements when I worked in Microstation v8i. Thanks for the heads-up regarding new ways to add temporary text graphics to the view - I'll look for it.