Adding editing functionality to SharpMap

Sep 1, 2006 at 7:53 AM

Currently we're researching the possibility to add basic GIS functionality to an existing application in the company I work for. Note that this hasn't been given the go ahead, and is just at an early step before we decide to go for this or not. However our application is already based on .NET, so SharpMap seems like a perfect fit for us.

What we need that isn't in SharpMap currently is some editing functionality. Very basic things, like adding a point and moving the vertices on some lines. We've used PostGIS with great success before, so we'll probably want to base it around that, but it would be a great bonus for us if the integration work could somehow be synchronized with the rest of the SharpMap development, so for instance interfaces and such would stay in synch. We don't want to create a fork, but try as much as possible to let this become an integral part of the running project.

I see others on the discussion list are already doing work to make shapefiles editable. Have there been worked out a general interface for providers that also allow editing of data? If not, how about adding an iStorage interface for this? That way the application that is using the library can query if the datasource of a layer implements this interface, and therefore it can decide if the layer is read-only or not. Does this sound like a good idea?

Here's a quick sketch of how I've figured editing could be implemented:

1. The user adds layers to the map. Some from providers that implements the iStorage interface.
2. The user decides to edit a layer. He/she marks the layer, and clicks a "start editing" button.
3. The application grabs the layer, and gets its DataSource.
4. The application examines if the DataSource implements the iStorage interface, and if it does it allows the operation to continue.
5. The layer that is currently being edited is disabled in the Map object, so that the editor control can handle the drawing of the layer that is being edited.
6. The editor uses the typical "give me all objects inside the views extents" calls, like the Map control does internally, but the data is instead drawn like editable vector graphics.
7. A couple of arrays are kept, for instance for objects that have been edited since the session started, have been deleted, etc. That way the editor can filter out these objects, and draw them seperately in their edited form, while all other objects are drawn as they are in the DataSource.
8. When the user stops editing, all the changes are written back to the provider through a series of CRUD calls (create, remove, update, delete). Probably need to do some integrity checks here, to for instance check that objects haven't been changed by other users while we did our editing, etc etc.

Does it sound it sound like a good way to implement this, or do you already have other ideas how this would be best implemented? Maybe an interface directly on the Map object would be better, to keep as much as possible of the functionality as an integral part of the SharpMap project?

Best regards,
Helge Elvik
Sep 1, 2006 at 10:19 AM
Actually, what you are asking for is two separate pieces, both of which require some good amount of work.

First is the concept of an updatable provider. I have almost completed a first version of this (finishing unit testing now) for the Shapefile provider. The way this is implemented is by creating a new interface - IUpdatableProvider - and implementing it on the Shapefile provider. It has methods to save features (both new and existing) and delete features. Other providers would just implement this interface to allow updatable data sources. This could be more of a challenge than it first appears, since the current version makes assumptions about a read-only state, and read/write state management is often much harder to accomplish.

Secondly, it appears you are wanting the user interface available in Sharpmap to directly edit maps. This would require some significant retooling of the rendering system to allow for updates. I am working on a DirectX implementation of the rendering system (which will take a redo of the rendering system to allow for different models), and it will need to eventually support updates for my own purposes. Updates on the rendering surface will of course translate to update operations on the provider, through some kind of transform pipeline, which could take into account any reprojection, encoding, caching and recovery models.

You interested in helping code this?
Sep 1, 2006 at 12:45 PM
I do realize that this probably will influence more than one part of the library itself. For now I've only been able to get a somewhat limited overview of how the library is built up. Do you have any code available that would show off how you've designed the IUpdatableProvider? I guess we've thought more or less the same way, only I named the interface iStorage. :) When it comes to read/write state management, I'd think this is less of a problem when it comes to managing a purely database oriented data provider, but I might be wrong in thinking so?

When it comes to the user interface to edit map objects, I guess you're thinking a bit more in depth when it comes to the library than me. Like I said, our use for the editing functionality would be very basic. For instance we won't need any dynamic reprojection capabilities when we're drawing since all layers and the viewport will be in the same projection. Couldn't we for instance, as a start, require both the editable layer and the viewport to be in the same projection? This could make the communication between the data provider, and the editing vector system much simpler. Maybe as a start one could throw an exception if the two projections differed, and then the dynamic reprojection capabilities could be implemented at a later date?

You also say that the current rendering system isn't well suited for updatable maps. I guess I should look more into this. But as a start I think we could use the current map rendering system to render a static backdrop of all the other layers except the one that is being edited. Then one would only need to implement a basic rendering component for the current layer being edited. It would be rendered seperately on top of the others, and when changes were saved and stored, it would go back to being rendered in the normal way together with the other layers.

I'll look more into this when I get a chance. Like I said, it hasn't been decided completely yet if we're going to go for this, but as it looks now SharpMap would be our closest solution if we decide to implement this in our application.

Thanks for your response. :)

Helge Elvik
Sep 1, 2006 at 2:20 PM
I hope to have the code complete this week (today!). I'm not sure, though, how to handle checking in the code to CodePlex... It is a fairly significant change, and although I've added unit tests and run the existing tests, I'm not comfortable just posting it without a bit more of a safety net and set of double-checks. I'll have to get with the project coord to figure this out...

I appreciate where you are going with the updateability in the UI/rendering... keep it as simple as possible while allowing some edit to take place. I'm curious, as far as rendering, how would you go about allowing an edit on the drawing surface? The resulting map is an image, which doesn't really have any UI. The Windows Forms Map control could be used, and perhaps even do the drawing and manage all the update semantics itself, but now were making that control pretty complex, and much of this behavior should probably be factored out. If you urgently needed to make SharpMap do updates, though, this is where you might find yourself adding the needed functionality, as you indicate.

However, thinking about the scenarios further, it's a bit more complicated than a casual consideration would lead us to believe, as far as I can tell. Ignoring, for the moment, the web side of things, and sticking with the nice, rich Windows Forms environment, how would the render of, say, moving or transforming a shape, or placing a point on the layer, look? It would have to be a system which allows real-time drawing on the surface, which would need to translate user interaction into layer coordinates/features. Even if we consider just one type of layer - a point layer - where clicking places a new point (feature), there would have to be a mechanism to translate the X, Y coordinate of that click to become a feature in the underlying data layer. This would have to go through not only the transformation from screen to layer coordinates (taking into account the projection, since this isn't hard), but also a consideration if the point is valid topologically (does it make sense to put it there according to what else is on the map?), what the attributes are (are any required?), and what happens if the point can't be put there? An exception, maybe, but then that has to be handled. Then there are more complex layer types, like multipoints, lines, polygons, etc. What does it mean to add a point to one of them? Is it a new feature, or a new point in an existing feature? What about moving or changing a feature? The scenarios compound quickly.

Much of the groundwork for the answers to these questions could be layed with a good architecture of a rendering engine. It could employ a Model-View-Controller or a Model-View-Presenter pattern to allow the scenarios to be covered iteratively as SharpMap matures, and if done with a set of well-conceived interfaces, new UI/rendering technologies like SVG or XAML can be developed and plugged into the map creation/update pipeline and provide the same behavior, and gracefully degrade where it can't.

Sep 1, 2006 at 3:57 PM
Regarding the editing interface, SharpMap has from the beginning been designed as a map renderer, and hasn't dealt with UI at all (I know there is a UI namespace, but that is just to get people started). But that doesn't mean the current API will prevent you from creating an editor.

I have done shape-editing stuff with SharpMap as the engine before. Doing real vector-graphics on a winform will at some point come down to rasterizing the vectors anyway (and in my case I used GDI+). What I did was checking in the mouse-move event whether the mouse was above an object in the editable layer (I had an in-memory list of the current editable objects in the active view). This worked very well and the redrawing speed was fast enough to go unnoticed (I was only redrawing the editable layer and reused the background-map in each redraw).
You might want to check with Bob Powells GDI+ faq ( He has several good examples on how to do mouse/graphicspath intersection tests and other nice examples that can come in handy for this task.

CodeKaizen: Could you contact me via email? (use if you don't already have my email). As I can understand you have a couple of questions with your new additions.
Sep 1, 2006 at 9:19 PM

I'm very interested in you rendering implementation using DirectX and I would like to help you testing it, finding bugs, adding features, etc...

There's a way you can "seudo-checkin" your changes to TFS without touching the main development branch and share them with other developers for code review: "shelvesets" ( see )

Sep 4, 2006 at 11:51 AM
It definitely sounds like this could be possible. As far as I understand from SharpGIS' post, he/she has even done this already for shapefiles? When I get the time I'll look some more at the code. If in-memory lists of features within the current view provide adequate performance, I think we have what we need. Like SharpGIS said, all layers except the one currently being edited would be rendered as a static backdrop that would only be updated whenever the viewport changes. That would mean that one would do some sort of bitmap-blitting operation, and then just use the GDI+ framework to draw the currently edited layer on top of that backdrop. This will of course mean that layers that should normally obscure parts of that layer wouldn't get rendered correctly while in editing mode, but I think this is of minor importance.

I think with a bit of smart thinking it should be possible to make maybe a seperate editing renderer. Or maybe even an EditableMap object that extends the normal Map object. It could use the original rendering function to render the backdrop, but in addition also handle caching and drawing of the VectorFeatures for the editable layer. It could be event driven, so the outside application would only send in different mouse events and the object would react accordingly, and trigger a re-render when needed.

SharpGIS, you mentioned that you had already used SharpMap to do shape-editing stuff. Is this code you'd be willing to share? Also, would any of you be interested in helping to figure out a good architecture for this? The way I see it the biggest challenge at first will be to design this so that most of the functionality will be kept inside the library itself, instead of in a bloated editing control of some sort.
Sep 4, 2006 at 1:01 PM
No it wasn't editing of shapefiles but data stored in a database.
The code was something I made for my previous employer and belongs to them, but it was just a proof-of-concept application used for demos and wasn't finished. It was just to tell you that the approach of drawing the geometry using GDI+ and then do intersection-tests at the mousemove events works just fine.
Sep 5, 2006 at 4:29 PM
Ah, I didn't know shelvesets were shareable.

The problem with them, I see, however, is that, like any branch, they need to track the main development, and incorporate those changes. This isn't a big deal unless there is a lot of different work being done in branches and the lack of a coherent roadmap. Has a new project coord emerged? I missed the dev meeting this morning....
Dec 13, 2007 at 7:06 AM
hi all,

This my first post here. First up thanks for the great project. I've been working with it over the last few months and have really appreciated this resource. Over time I will endeavour to feed some of my work back into the project.

Back to business, has anybody advanced the editing capabilities? I'm approaching this area of functionality in my project real soon and am looking at the IO and the UI aspects like that which was discussed above. For the UI editing tools, feedback / feature graphics stuff I was thinking along the lines of something similar to the JHotDraw graphics as a starting point (but need to be very careful with the license and copyright issues). Googling for a few hours didnt yield much in the way of a .net ui graphic objects library.

Does anybody have any further ideas on the above, tips to the contrary, or pointers to useful resources that I may have overlooked? I should point out here that all my work is compiled against the 0.9 release. In the fullness of time I will migrate to 2.0. For that reason I havent scrutinized the 2.0 repository (yet).