How to show only some labels

Topics: General Topics, SharpMap v2.0
Mar 26, 2013 at 5:33 AM
Hi,

I am new to Sharpmap and GIS. Going through the sample code and building simple programs for better understanding. I have a water bodies layer. I want to display only a particular river. I used CustomTheme. How to show label for only this river.

To display a river (named Ganga), I have written following code.
SharpMap.Data.Providers.ShapeFile shapeFileProvider = new SharpMap.Data.Providers.ShapeFile(@"C:\water.shp", false);
SharpMap.Layers.VectorLayer waterLayer = new SharpMap.Layers.VectorLayer("Water", shapeFileProvider);

SharpMap.Rendering.Thematics.CustomTheme waterTheme = new SharpMap.Rendering.Thematics.CustomTheme(GetWaterStyle);
waterLayer.Theme = waterTheme;
mapBox1.Map.Layers.Add(waterLayer);
The GetWaterStyle method:
private SharpMap.Styles.VectorStyle GetWaterStyle(SharpMap.Data.FeatureDataRow row)
{
    SharpMap.Styles.VectorStyle style = new SharpMap.Styles.VectorStyle();
    if (row["NAME"].ToString().Equals("Ganga"))
    {
        style.Fill = Brushes.Aqua;
        return style;
    }
    else
        return null;
}
Now I want to show a label "Ganga" (the river name) as well. How to approach?

Please help.

Thanks and regards,
Abhi
Coordinator
Mar 26, 2013 at 3:10 PM
Hi,

You should add another layer of type LabelLayer with a datasource that filters out the only river you want to label..

Something like this..
SharpMap.Data.Providers.ShapeFile shapeFileProvider = new SharpMap.Data.Providers.ShapeFile(@"C:\water.shp", false);

            //Proivder for labels only fetching one river
            SharpMap.Data.Providers.ShapeFile shapeFileProviderLabels = new SharpMap.Data.Providers.ShapeFile(@"C:\water.shp", false);
            shapeFileProviderLabels.FilterDelegate += new SharpMap.Data.Providers.FilterProvider.FilterMethod(delegate(FeatureDataRow row) { return row["NAME"] as string == "Ganga"; });
            
            SharpMap.Layers.VectorLayer waterLayer = new SharpMap.Layers.VectorLayer("Water", shapeFileProvider);

            //Layer for labels
            SharpMap.Layers.LabelLayer waterLabels = new SharpMap.Layers.LabelLayer("Water_Labels");
            waterLabels.DataSource = shapeFileProviderLabels;

            SharpMap.Rendering.Thematics.CustomTheme waterTheme = new SharpMap.Rendering.Thematics.CustomTheme(GetWaterStyle);
            waterLayer.Theme = waterTheme;
            
            mapBox1.Map.Layers.Add(waterLayer);
            mapBox1.Map.Layers.Add(waterLabels);
Mar 27, 2013 at 6:58 AM
I am getting the following exception:
System.ArgumentNullException was unhandled
Message='name' argument cannot be null.
Parameter name: name
  Source=System.Data
  ParamName=name
  StackTrace:
   at System.Data.DataColumnCollection.get_Item(String name)
   at System.Data.DataRow.GetDataColumn(String columnName)
   at System.Data.DataRow.get_Item(String columnName)
   at SharpMap.Layers.LabelLayer.Render(Graphics g, Map map) in C:\Projekt\opensource\sharpmap-svn\SharpMap\Layers\LabelLayer.cs:line 474
   at SharpMap.Map.RenderMap(Graphics g, LayerCollectionType layerCollectionType, Boolean drawMapDecorations) in C:\Projekt\opensource\sharpmap-svn\SharpMap\Map\Map.cs:line 522
   at SharpMap.Forms.MapBox.GetMap(Map map, LayerCollection layers, LayerCollectionType layerCollectionType, BoundingBox extent) in C:\Projekt\opensource\sharpmap-svn\SharpMap.UI\Forms\MapBox.cs:line 730
   at SharpMap.Forms.MapBox.GetImagesAsync(BoundingBox extent, Int32 imageGeneration) in C:\Projekt\opensource\sharpmap-svn\SharpMap.UI\Forms\MapBox.cs:line 761
   at SharpMap.Forms.MapBox.<>c__DisplayClass13.<UpdateImage>b__10(Object ) in C:\Projekt\opensource\sharpmap-svn\SharpMap.UI\Forms\MapBox.cs:line 951
   at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
InnerException:


When I add following line to the above code:
waterLabels.LabelColumn = "NAME";
I don't get the exception, but all the labels are shown. Is it compulsary to add LabelColumn for the label layer? If yes, what column should I provide in case of FilterDelegate?

Thanks and regards,
Abhi
Coordinator
Mar 27, 2013 at 7:55 AM
I run this code now that works as expected..

SharpMap.Data.Providers.ShapeFile shapeFileProvider = new SharpMap.Data.Providers.ShapeFile(@"rivers.shp", false);
        //Proivder for labels only fetching one river
        SharpMap.Data.Providers.ShapeFile shapeFileProviderLabels = new SharpMap.Data.Providers.ShapeFile(@"rivers.shp", false);
        shapeFileProviderLabels.FilterDelegate += new SharpMap.Data.Providers.FilterProvider.FilterMethod(delegate(FeatureDataRow row) { return row["NAME"] as string == "Ganga"; });
        int cnt = shapeFileProviderLabels.GetFeatureCount();

        SharpMap.Layers.VectorLayer waterLayer = new SharpMap.Layers.VectorLayer("Water", shapeFileProvider);

        //Layer for labels
        SharpMap.Layers.LabelLayer waterLabels = new SharpMap.Layers.LabelLayer("Water_Labels");
        waterLabels.LabelColumn = "NAME";
        waterLabels.DataSource = shapeFileProviderLabels;

        mapBox1.Map.Layers.Add(waterLayer);
        mapBox1.Map.Layers.Add(waterLabels);
Mar 27, 2013 at 8:41 AM
I am getting the following exception:
System.ArgumentNullException was unhandled
Message='name' argument cannot be null.
Parameter name: name
  Source=System.Data
  ParamName=name
  StackTrace:
   at System.Data.DataColumnCollection.get_Item(String name)
   at System.Data.DataRow.GetDataColumn(String columnName)
   at System.Data.DataRow.get_Item(String columnName)
   at SharpMap.Layers.LabelLayer.Render(Graphics g, Map map) in C:\Projekt\opensource\sharpmap-svn\SharpMap\Layers\LabelLayer.cs:line 474
   at SharpMap.Map.RenderMap(Graphics g, LayerCollectionType layerCollectionType, Boolean drawMapDecorations) in C:\Projekt\opensource\sharpmap-svn\SharpMap\Map\Map.cs:line 522
   at SharpMap.Forms.MapBox.GetMap(Map map, LayerCollection layers, LayerCollectionType layerCollectionType, BoundingBox extent) in C:\Projekt\opensource\sharpmap-svn\SharpMap.UI\Forms\MapBox.cs:line 730
   at SharpMap.Forms.MapBox.GetImagesAsync(BoundingBox extent, Int32 imageGeneration) in C:\Projekt\opensource\sharpmap-svn\SharpMap.UI\Forms\MapBox.cs:line 761
   at SharpMap.Forms.MapBox.<>c__DisplayClass13.<UpdateImage>b__10(Object ) in C:\Projekt\opensource\sharpmap-svn\SharpMap.UI\Forms\MapBox.cs:line 951
   at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
InnerException:


When I add following line to the above code:
waterLabels.LabelColumn = "NAME";
I don't get the exception, but all the labels are shown. Is it compulsary to add LabelColumn for the label layer? If yes, what column should I provide in case of FilterDelegate?

Thanks and regards,
Abhi
Mar 27, 2013 at 9:01 AM
I am getting the following exception:
System.ArgumentNullException was unhandled
Message='name' argument cannot be null.
Parameter name: name
  Source=System.Data
  ParamName=name
  StackTrace:
   at System.Data.DataColumnCollection.get_Item(String name)
   at System.Data.DataRow.GetDataColumn(String columnName)
   at System.Data.DataRow.get_Item(String columnName)
   at SharpMap.Layers.LabelLayer.Render(Graphics g, Map map) in C:\Projekt\opensource\sharpmap-svn\SharpMap\Layers\LabelLayer.cs:line 474
   at SharpMap.Map.RenderMap(Graphics g, LayerCollectionType layerCollectionType, Boolean drawMapDecorations) in C:\Projekt\opensource\sharpmap-svn\SharpMap\Map\Map.cs:line 522
   at SharpMap.Forms.MapBox.GetMap(Map map, LayerCollection layers, LayerCollectionType layerCollectionType, BoundingBox extent) in C:\Projekt\opensource\sharpmap-svn\SharpMap.UI\Forms\MapBox.cs:line 730
   at SharpMap.Forms.MapBox.GetImagesAsync(BoundingBox extent, Int32 imageGeneration) in C:\Projekt\opensource\sharpmap-svn\SharpMap.UI\Forms\MapBox.cs:line 761
   at SharpMap.Forms.MapBox.<>c__DisplayClass13.<UpdateImage>b__10(Object ) in C:\Projekt\opensource\sharpmap-svn\SharpMap.UI\Forms\MapBox.cs:line 951
   at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
InnerException:


When I add following line to the above code:
waterLabels.LabelColumn = "NAME";
I don't get the exception, but all the labels are shown. Is it compulsary to add LabelColumn for the label layer? If yes, what column should I provide in case of FilterDelegate?

Thanks and regards,
Abhi
Mar 27, 2013 at 9:02 AM
I am getting the following exception:
System.ArgumentNullException was unhandled
Message='name' argument cannot be null.
Parameter name: name
  Source=System.Data
  ParamName=name
  StackTrace:
   at System.Data.DataColumnCollection.get_Item(String name)
   at System.Data.DataRow.GetDataColumn(String columnName)
   at System.Data.DataRow.get_Item(String columnName)
   at SharpMap.Layers.LabelLayer.Render(Graphics g, Map map) in C:\Projekt\opensource\sharpmap-svn\SharpMap\Layers\LabelLayer.cs:line 474
   at SharpMap.Map.RenderMap(Graphics g, LayerCollectionType layerCollectionType, Boolean drawMapDecorations) in C:\Projekt\opensource\sharpmap-svn\SharpMap\Map\Map.cs:line 522
   at SharpMap.Forms.MapBox.GetMap(Map map, LayerCollection layers, LayerCollectionType layerCollectionType, BoundingBox extent) in C:\Projekt\opensource\sharpmap-svn\SharpMap.UI\Forms\MapBox.cs:line 730
   at SharpMap.Forms.MapBox.GetImagesAsync(BoundingBox extent, Int32 imageGeneration) in C:\Projekt\opensource\sharpmap-svn\SharpMap.UI\Forms\MapBox.cs:line 761
   at SharpMap.Forms.MapBox.<>c__DisplayClass13.<UpdateImage>b__10(Object ) in C:\Projekt\opensource\sharpmap-svn\SharpMap.UI\Forms\MapBox.cs:line 951
   at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
InnerException:


When I add following line to the above code:
waterLabels.LabelColumn = "NAME";
I don't get the exception, but all the labels are shown. Is it compulsary to add LabelColumn for the label layer? If yes, what column should I provide in case of FilterDelegate?

Thanks and regards,
Abhi
Mar 27, 2013 at 9:16 AM
Why my post is being added so many times? Appreciate your help but need a bit more.

Please see this screenshot of my output:

Image

As you can see, Son, Taalab, Gandak, Ghangara and Ganga five rivers are being shown.

I want only Ganga label.

Thank
Mar 27, 2013 at 9:56 AM
I never receive control inside the filter function. I checked by putting a breakpoint at the statement
return row["NAME"] as string == "Ganga";
But I could never get the control here. Should I have to do some configuration to make this work? The FilterDelegate is not working I guess.

Thanks and regards,
Abhi
Coordinator
Mar 27, 2013 at 2:17 PM
Things come back to me... I remember that there has been an bug/issue with the FilterDelegate of ShapeFile provider, this is fixed and included in SharpMap 1.0 RC1 that will be released as soon as CodePlex fixes an error that makes it impossible to release the new version...
Coordinator
Mar 27, 2013 at 5:55 PM
Please try your example with the newly release 1.0RC SharpMap instead.
Mar 28, 2013 at 5:19 AM
Thanks a lot. I will give it a try.
Mar 28, 2013 at 5:53 AM
Thanks man!! It worked.