Are there any good forum threads or help topics that talk about the GeoCanvas, or the .Draw methods on the styles and layers? For instance, I have no clue what the drawing level is. And I don't know the significance of the "LabelsInThisLayer" vs "LabelsInAllLayers" parameters etc.
Graphically Editing Shapes
Ted,
I found this post and pulled out the important parts for you on DrawingLevel.
Drawing Level Full Post:
gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/21/aft/5273/afv/topic/Default.aspx
Inside of the Style’s Draw method is where we make calls the GeoCanvas to draw everything. When we make the call like GeoCanvas.DrawLine we have a parameter that is called drawing level, it is an enumeration and I think we have five of them. What happens is for every drawing level used we create a temporary bitmap. When you draw a simple line then it draws on level one by default. If you have a complex line like a street that you might want to display as a solid thick black line with a thinner white line inside then what we do is draw the thick black like on level 1 and then the thinner white line on level 2.
When we are done with drawing that layer and the GeoCanvas.Flush or EndDrawing is called we composite the bitmaps in layer drawing order and it create the final bitmap. There are a number of reasons why do that. First is that if we were to draw the black and white line in order by feature the effect would not look very good because of the caps at the end of the lines. The white area would not seamlessly merge into an adjoining line correctly. You would get bad looking artefacts of where the black line would intersect the white line a little bit. The other method we had in 2.x would be to draw all the black lines first, then loop through the features again and draw the white lines. The problem with that is at any moment if you wanted to interrupt the drawing process then you would get a picture of all black lines with some white lines but not all of them. The other reason is that it makes the code in the GeoCanvas much more elegant and avoids caching a bunch of future drawing requests. In our system we draw the each record for every style once and no need for extra looping.
LabelsInThisLayer & LabelsInAllLayers:
These two collection contain labeling information. We use this to communicate from one layer to another where labels have already been drawn. If we have a stack of three label layers and we want to draw them so the labels do not overlap then we need this. The first layer will start to render and the LabelsInThisLayer and LabelsInAllLayers will both be empty. The first layer will draw its labels and add where it drew them to both collection. When the next layer goes to draw the LabelsInThisLayer will be empty again but the LabelsInAllLayers will contain all of the labels from the first layer. When the second layer is drawing labels it will make sure not to overlap labels from previous layers. It will also add its labels to both collections. The LabelsInThisLayer is not really used much but there for some far out cases where you want to know just the new labels that were added. As you can see if you are doing your own drawing and not labeling you can always pass in empty collection and there will not be any issues. Like I said the purpose for them is to allow some communication between layers on where labels are so they do no collide.
David
This helps a lot. The levels is a new concept to me, but seems quite powerful. Resultant questions:
1) Just confirming: The compositing of the bitmaps is done at the layer level? It does not cross layers, right?
2) There was prior discussion about the need to have a second layer for labels. Can we not use a level for the labels, and draw labels at the same time as we draw the other feature styles? This would keep the second polygon in a layer from overlying the label written for an adjoining small first polygon, right?
3) Do you drawing routines detect and optimize for label collision within or across layers?
Ted,
1.This is sort of correct. I mean when the Desktop draws etc then this is the case. After each layer we call the GeoCanvas.Flush which combines them all and then we start the next layer. At the same time this does not have to be the case if you control everything. If you instantiate a GdiPlusGeoCanvas, call the BeginDraw and then pass it into two layers, one after another, then it will span layers. This is because you have to control and tell the GeoCanvas when it will combine them. You see what I mean.
On interesting side effect of this is that if we expanded the drawing level then it would be possible in theory to draw the labels at the same time the regular shapes draw in one layer but place it at a really high level and not flush it. I think there may be an interesting way to draw labels and shapes in one layer. I need to think about this some more. Thanks for asking this question. :-)
2.I didn’t even read your second point before I answered the first. I think this may be possible however I need to consider this very carefully. I think they may be something here but there are many scenarios to consider. One thing that we vowed when thinking up the 3.x framework is that we did not want to make labels special. We wanted them to fit into the same overall framework that everything else did. In 2.x the code got really messy because there was all kinds of custom logic to wedge labeling in and we didn’t like that at all. This doesn’t mean we wont do this, we just need to make sure it fits in right and we don’t try and wedge it in.
3.We do a bunch of label collision stuff. If you check out the methods on TextStyle you will see there are quite a few controls over how this is processed. We also have some nice Core methods for people to enhance and create special purpose labelers without having to do everything from scratch. We have had a few customers build their own labelers for custom applications. We do collision detection across layers as well which is what that LabelsInAllLayers collection is about, it passes the labels already drawn to the next layer so they can be avoided.
On a side note, I saw some of the new editing APIs for the Desktop Edition and man are they sweet! The whole editing system will be so flexible and be able to handle all kinds of complex scenarios and custom editing requirements.
David
Hi David,
Quote>On a side note, I saw some of the new editing APIs for the Desktop Edition and man are they sweet! The whole editing system will be so flexible and be able to handle all kinds of complex scenarios and custom editing requirements.<EndQuote
So long as there is support for deleting a vertex in the editor it gets my vote, Ben kind of hinted that this is not there at present, it does need to be there. Just try running Word or Visual Studio and doing without the backspace or delete keys!
Regards
John
John,
I can tell you with certainty that delete will be there. What the guys are hashing out now is a better way to add new vertices. Currently we place new points at the midpoint of the line. This doesn’t work so well for many applications. I think the plan is to be able to add a vertex wherever you click. The add and delete might be right mouse click items but not 100% sure. We hate to do that as developers like to use the right click for their stuff.
You use the delete key in Visual Studio? If I make a mistake I just add more code to fix it. :-)
David
Hi David,
Sounds good, the right click sounds like an very bad move. The convention in Windows for the right click is the pop-up menu…
Double ckicking on a vertex would be one way of signalling you wish to delete a it and what’s wrong with mouse down on a line/side and then moving the mouse inserts a vertex and starts to drag it?
John
Here is how the vertex editor works in our system, for reference:
1) Left click close to a vertex, and drag it to a new location.
2) Left click somewhere on a line (away from a vertex) and that adds the vertex onto the line at the mouse location, and lets you drag it.
3) Right click near a vertex and it deletes it.
This really works slick. I can do a huge amount of vertex editing with very few mouse clicks. No insert, move, or delete takes more than one down click and optional drag. I can capture a video of it, if it would help. (not that I’m lobbying hard for this behavior :))
John / Ted,
I meant that a right click would bring up a menu to add or delete a vertex depending on where you were. I do like the idea of staying away from context menus and having a quick and easy way to do the editing with minimal steps.
On thing with the click on a line and then draw is that we also wanted for pan functionality to work as well. If you wanted to pan and accidentally mouse downed next to line then you would get a new point and start moving it. Of course you could always delete it though. What about some sort of undo functionality? What would you like to see there?
John – What do you think about Ted’s suggestions? If you guys hash out a way I can bring it to the development team and push it. Now is the time to get me your feedback.
David
Hi David,
Appreciate the logic but we are still dead against anything on the RMB. There are an accepted set of guidelines in the Windows world about what ‘should’ happen when the users right click in a Windows app and whilst using the RMB for other purposes does not mean your app will fail acceptance tests you generally get warned about it.
We have a fairly complex dynamic menu tied to the right mouse button on the map control. Users are going to expect to be able to right click and get access to properties, charts and all sorts of other things. The use of the editor is almost seamless so far as users are concerned.
If you must use a menu why not do a couple of things:-
1. Provide the methods that insert and delete, they could be added to the any existing right click menu or
2. If there is no right click menu assigned to the map control then bring up your own or
3. Allow the developer to add things to the right click menu you have in the editor in order to maintain a consistent UI.
Of the three options I would favour the first.
If you don’t use the RMB, I appreciate your concerns about panning, but here you are assuming that the LMB down and move will always pan the map. This is currently a huge ‘show stopper’ for us, V3 is the only GIS control I have seen where you have no control over what happens when the user holds the ANY mouse button down and moves the mouse, as it is at present, the map pans and there is no way of stopping it.
Hope this does not sound terribly negative; it’s just our point of view.
John
John,
I understand your points on the right click. I think we can safely rule that out. As far as the Ted’s suggestion up till the right click part?
1. Drag Existing Vertex: Left click close to a vertex, and drag it to a new location.
2. Add New Vertex: Left click somewhere on a line (away from a vertex) and that adds the vertex onto the line at the mouse location, and lets you drag it.
3. Delete Vertex: Double click on existing vertex?
Of course we will set this up so that you can override all of this functionality. The way it is setup I believe is that in the EditOverlay there are virtual methods like Click, Double Click, Drag and Drop. The methods are only called when there are shapes in the edit overlay. You can override them so you can add code on a double click to find a existing control point and do whatever you want with it.
One thing that is critical is that the users be able to pan, zoom in and out while editing. I think there will also be some undo capability as well.
I don’t your comments are negative at all. I am not sure what you are suggesting though. We could add a way to turn off panning and I think we have for the Web Edition. To just add some mapping to what the right and left mouse does isn’t so easy as there is allot of context to consider.
I want to make sure we get this right. If you have more suggests then let me know. The product is in beta so now is the time to get this all off your chest!
I will talk with the developers about all of this feedback and report back to you.
David
Guys,
What I am going to do is get the API from the developers for the EditOverlay and post it to the Developers Blog forum with a writeup on how it works. In this way you can review it, ask questions and make suggestions. We can see if it can handle all of your requirements and get more from the community. At this point the topic of this message is ‘Drawing Stuff’ and people might not know we are discussion editing. This seems to be a pretty hot topic and I want to make sure we get allot of input and feedback.
David