How to Use Map Tools in 2.0?

Topics: SharpMap v0.9 / v1.x, SharpMap v2.0
Dec 15, 2007 at 5:51 PM
In 0.9, I found that the various map tools (i.e. zoom, query, pan, etc.) were pretty obvious to use. A week or two ago when I attempted to migrate our application to 2.0 (using the last stable build in google source control), I had enourmous difficulty figuring out how to use the map tools; either A) the API isn't obvious, or B) I don't have any samples to work with, or C) the code is in some transitional state.

I have two questions:
1. Is the API for map tools completed, or is there more work to do?
2. If the API is complete, is there a code snippet somewhere for performing a query?

I spent about four hours getting something that sort of worked, but it wasn't nearly as clean as 0.9 and I felt like I was probably doing it wrong.
Dec 24, 2007 at 9:56 PM
Any answers? I'd be happy to document my experiences with 2.0 if someone will give me a hand getting things running.
Dec 29, 2007 at 4:11 PM
Hi. The Tools structure has been implemented. It is quite straightforward to use. You can choose to use some of the built-in tools or create your own tool to do what you want. In the former case, you...
Eg
using SharpMap.Tools;
mapImage.SelectedTool = StandardMapTools2D.Pan;

In the latter case, you have to define 4 methods that will be delegated to your MapTool. These functions are called on Query (don't know what that does), Begin, Continue and End of your MapTool. Eg

MapTool<IMapView2D, Point2D> ZoomIn;

ZoomIn = new MapTool<IMapView2D, Point2D>("ZoomIn", QueryZoomIn, BeginZoomIn, ContinueZoomIn, EndZoomIn);

void BeginZoomIn(ActionContext<IMapView2D, Point2D> context)
{
//do when mouse first touches down on control
}

void ContinueZoomIn(ActionContext<IMapView2D, Point2D> context)
{
//do while mouse is still down and being dragged
}

void EndZoomIn(ActionContext<IMapView2D, Point2D> context)
{
//do when MouseUp occurs

}

Quite straightforward. You can create your own ZoomIn or use the built in one. I am trying to build my own as the built in one has some strange behaviour.


Aug 27, 2008 at 8:57 AM
Edited Aug 27, 2008 at 11:27 AM
Hi guys i'm new to Sharp Map v2 but i  tried to use this code

source:


private void Form2_Load(object sender, EventArgs e)
{
string pop = "D:\\-=PROJECTS=-\\SharpMap2\\SharpMap\\TestData\\BCROADS.SHP";
SharpMap.Map myMap = new SharpMap.Map(MapFactories.GeometryFactory);

SharpMap.Data.Providers.ShapeFile.ShapeFileProvider prov = new SharpMap.Data.Providers.ShapeFile.ShapeFileProvider(pop, MapFactories.GeometryFactory, MapFactories.CoordinateSystemFactory);

SharpMap.Layers.GeometryLayer gl = new SharpMap.Layers.GeometryLayer(String.Format("GL_{0}", prov.ConnectionId), prov);
gl.Style.AreFeaturesSelectable = true;
gl.Style.Enabled = true;
gl.Style.EnableOutline = true;
gl.Style.Fill = new SharpMap.Styles.SolidStyleBrush(SharpMap.Styles.StyleColor.Black);
gl.Style.Line = new SharpMap.Styles.StylePen( new SharpMap.Styles.SolidStyleBrush(SharpMap.Styles.StyleColor.Aqua), 3);
gl.Style.Outline = new SharpMap.Styles.StylePen( new SharpMap.Styles.SolidStyleBrush(SharpMap.Styles.StyleColor.Aquamarine), 1);

mapViewControl1.BackColor = Color.White;
myMap.AddLayer(gl);
mapViewControl1.Map = myMap;

prov.Open();
mapViewControl1.ZoomToExtents();
mapViewControl1.Map.ActiveTool = StandardMapView2DMapTools.ZoomIn;
mapViewControl1.Refresh();
}

The map is load and shown with no problems. When i try to click or drag  the map i recieved this error message:

An unhandled exception of type 'SharpMap.Data.Providers.ShapeFile.ShapeFileInvalidOperationException' occurred in SharpMap.dll
Additional information: Can't open another ShapeFileDataReader on this ShapeFile, since another reader is already active.

Call stack :

SharpMap.dll!SharpMap.Data.Providers.AsyncResult.EndInvoke() Line 106 C#
SharpMap.dll!SharpMap:ata:roviders::AsyncResult::EndInvoke() Line 38 + 0x7 bytes C++
SharpMap.dll!SharpMap.Data.Providers.AsyncFeatureProviderAdapter.EndExecuteQuery(System.IAsyncResult asyncResult = {SharpMap.Data.Providers.AsyncResult<SharpMap.Data.IFeatureDataReader>}) Line 69 + 0x9 bytes C#
SharpMap.dll!SharpMap.Layers.Layer.LoadLayerData(SharpMap.Expressions.QueryExpression query = {SharpMap.Expressions.FeatureQueryExpression}) Line 555 + 0x12 bytes C#
SharpMap.dll!SharpMap.Layers.FeatureLayer.handleFeaturesSelectRequested(object sender = {}, SharpMap.Data.SelectRequestedEventArgs e = {SharpMap.Data.SelectRequestedEventArgs}) Line 305 + 0x9 bytes C#
SharpMap.dll!SharpMap.Data.FeatureDataTable.OnSelectRequested(SharpMap.Expressions.FeatureQueryExpression query = {SharpMap.Expressions.FeatureQueryExpression}) Line 785 + 0xf bytes C#
SharpMap.dll!SharpMap.Data.FeatureDataTable.Select(SharpMap.Expressions.SpatialBinaryExpression query = {SharpMap.Expressions.SpatialBinaryExpression}) Line 692 + 0x3c bytes C#
SharpMap.dll!SharpMap.Presentation.Presenters.MapPresenter2D.RenderFeatureLayer(SharpMap.Layers.IFeatureLayer layer = {GL_D:\-=PROJECTS=-\SharpMap2\SharpMap\TestData\BCROADS.SHP}, SharpMap.Presentation.RenderPhase phase = Normal) Line 932 + 0x5a bytes C#
SharpMap.Presentation.WinForms.dll!SharpMap.Presentation.WinForms.MapPresenter.RenderFeatureLayer(SharpMap.Layers.IFeatureLayer layer = {GL_D:\-=PROJECTS=-\SharpMap2\SharpMap\TestData\BCROADS.SHP}, SharpMap.Presentation.RenderPhase phase = Normal) Line 103 + 0xa bytes C#
SharpMap.dll!SharpMap.Presentation.Presenters.MapPresenter2D.RenderLayer(SharpMap.Layers.ILayer layer = {GL_D:\-=PROJECTS=-\SharpMap2\SharpMap\TestData\BCROADS.SHP}, SharpMap.Presentation.RenderPhase phase = Normal) Line 878 + 0x1f bytes C#
SharpMap.dll!SharpMap.Presentation.Presenters.MapPresenter2D.RenderAllLayers(SharpMap.Presentation.RenderPhase phase = Normal) Line 845 + 0x35 bytes C#
SharpMap.dll!SharpMap.Presentation.Presenters.MapPresenter2D.RenderAllLayers() Line 822 + 0xc bytes C#
SharpMap.dll!SharpMap.Presentation.Presenters.MapPresenter2D.setViewMetricsInternal(SharpMap.Rendering.Rendering2D.Size2D newViewSize = {Width: 760, Height: 400}, GeoAPI.Coordinates.ICoordinate newCenter = {(7441937,05276661, 308206,396871155)}, double newWorldWidth = 267245.49473422515) Line 1385 + 0x7 bytes C#
SharpMap.dll!SharpMap.Presentation.Presenters.MapPresenter2D.setViewEnvelopeInternal(GeoAPI.Geometries.IExtents2D newEnvelope = {Extents [7308314,3053995 - 7575559,80013372, 237878,635098991 - 378534,15864332]}) Line 1302 + 0x5e bytes C#
SharpMap.dll!SharpMap.Presentation.Presenters.MapPresenter2D.ZoomToViewBoundsInternal(SharpMap.Rendering.Rendering2D.Rectangle2D viewBounds = {[Rectangle2D] Left: 79,167; Top: 64,167; Right: 712,500; Bottom: 397,500; IsEmpty: False}) Line 589 + 0xa bytes C#
SharpMap.dll!SharpMap.Presentation.Presenters.MapPresenter2D.handleViewZoomToViewBoundsRequested(object sender = {SharpMap.Presentation.WinForms.MapViewControl}, SharpMap.Presentation.MapViewPropertyChangeEventArgs<SharpMap.Rendering.Rendering2D.Rectangle2D> e = {SharpMap.Presentation.MapViewPropertyChangeEventArgs<SharpMap.Rendering.Rendering2D.Rectangle2D>}) Line 1141 + 0x51 bytes C#
SharpMap.Presentation.WinForms.dll!SharpMap.Presentation.WinForms.MapViewControl.onRequestZoomToViewBounds(SharpMap.Rendering.Rendering2D.Rectangle2D viewBounds = {[Rectangle2D] Left: 79,167; Top: 64,167; Right: 712,500; Bottom: 397,500; IsEmpty: False}) Line 1027 + 0xf bytes C#
SharpMap.Presentation.WinForms.dll!SharpMap.Presentation.WinForms.MapViewControl.ZoomToViewBounds(SharpMap.Rendering.Rendering2D.Rectangle2D viewBounds = {[Rectangle2D] Left: 79,167; Top: 64,167; Right: 712,500; Bottom: 397,500; IsEmpty: False}) Line 395 + 0x42 bytes C#
SharpMap.dll!SharpMap.Tools.StandardMapView2DMapTools.zoomByFactor(SharpMap.Tools.ActionContext<SharpMap.Presentation.Views.IMapView2D,SharpMap.Rendering.Rendering2D.Point2D> context = {SharpMap.Tools.ActionContext<SharpMap.Presentation.Views.IMapView2D,SharpMap.Rendering.Rendering2D.Point2D>}, double zoomFactor = 0.83333333333333337) Line 419 + 0x46 bytes C#
SharpMap.dll!SharpMap.Tools.StandardMapView2DMapTools.EndZoomIn(SharpMap.Tools.ActionContext<SharpMap.Presentation.Views.IMapView2D,SharpMap.Rendering.Rendering2D.Point2D> context = {SharpMap.Tools.ActionContext<SharpMap.Presentation.Views.IMapView2D,SharpMap.Rendering.Rendering2D.Point2D>}) Line 168 + 0x3d bytes C#
SharpMap.dll!SharpMap.Presentation.Presenters.MapPresenter2D.handleViewEndAction(object sender = {SharpMap.Presentation.WinForms.MapViewControl}, SharpMap.Presentation.MapActionEventArgs<SharpMap.Rendering.Rendering2D.Point2D> e = {SharpMap.Presentation.WinForms.GdiMapActionEventArgs}) Line 1075 + 0x5a bytes C#
SharpMap.Presentation.WinForms.dll!SharpMap.Presentation.WinForms.MapViewControl.onEndAction(SharpMap.Rendering.Rendering2D.Point2D actionLocation = {[Point2D] (475,000, 277,000)}) Line 890 + 0xf bytes C#
SharpMap.Presentation.WinForms.dll!SharpMap.Presentation.WinForms.MapViewControl.OnMouseUp(System.Windows.Forms.MouseEventArgs e = {X = 475 Y = 277 Button = Left}) Line 517 + 0x52 bytes C#



Could you tell me what's wrong?

Thank you in advance Faxy.
Coordinator
Aug 27, 2008 at 11:43 AM
I had the same problem. For me it helped changing the Read-function of the ShapeFileDataReader class to this:

public Boolean Read()
{
    checkDisposed();

    Boolean reading = _objectEnumerator.MoveNext();

    if (reading)
    {
        _currentFeature = _shapeFile.GetFeatureByOid(_objectEnumerator.Current);
    }
    else
    {
        Dispose(false);
    }

    return reading;
}

HTH
FObermaier

Aug 27, 2008 at 12:21 PM
The patch helped
Thank you very much :)