IMapLabelLayer - help needed

Jan 11, 2011 at 9:26 AM
Edited Jan 13, 2011 at 6:45 PM

From the code in developers corner, I tried to figure out how to ad a label layer, based on a shape file with label as attributes, but didn’t succeed.

 

FeatureSet fs = new FeatureSet();
fs.Open(fileName);
fs.Projection = KnownCoordinateSystems.Geographic.World.WGS1984;
IMapFeatureLayer myLayer = map1.Layers.Add(fs);
IMapLabelLayer labelLayer = new MapLabelLayer();
ILabelCategory category = labelLayer.Symbology.Categories[0];
category.Expression = "[VEJNAVN]";
category.Symbolizer.Orientation = ContentAlignment.MiddleCenter;
myLayer.LabelLayer = labelLayer;
myLayer.ShowLabels = true;
 
System.NullReferenceException was unhandled
  Message=Object reference not set to an instance of an object.
  Source=DotSpatial.Data
  StackTrace:
       at DotSpatial.Data.FeatureSet.SelectIndices(Extent region) in c:\Dev\DotSpatial\DotSpatial.Data\DotSpatial.Data\FeatureSet.cs:line 1145
       at DotSpatial.Controls.MapLabelLayer.DrawRegions(MapArgs args, List`1 regions) in c:\Dev\DotSpatial\DotSpatial.Controls\DotSpatial.Controls\MapLabelLayer.cs:line 161
       at DotSpatial.Controls.MapFrame.InitializeLabels(List`1 regions, MapArgs args, IRenderable layer) in c:\Dev\DotSpatial\DotSpatial.Controls\DotSpatial.Controls\MapFrame.cs:line 442
       at DotSpatial.Controls.MapFrame.Initialize(List`1 regions) in c:\Dev\DotSpatial\DotSpatial.Controls\DotSpatial.Controls\MapFrame.cs:line 402
       at DotSpatial.Controls.MapFrame.Initialize() in c:\Dev\DotSpatial\DotSpatial.Controls\DotSpatial.Controls\MapFrame.cs:line 455
       at DotSpatial.Controls.MapFrame.LayerCollection_MembersChanged(Object sender, EventArgs e) in c:\Dev\DotSpatial\DotSpatial.Controls\DotSpatial.Controls\MapFrame.cs:line 1200
       at System.EventHandler.Invoke(Object sender, EventArgs e)
       at DotSpatial.Data.ChangeEventList`1.OnItemChanged(Object sender) in c:\Dev\DotSpatial\DotSpatial.Data\DotSpatial.Data\ChangeEventList.cs:line 349
       at DotSpatial.Data.ChangeEventList`1.ItemItemChanged(Object sender, EventArgs e) in c:\Dev\DotSpatial\DotSpatial.Data\DotSpatial.Data\ChangeEventList.cs:line 332
       at DotSpatial.Symbology.LegendItem.OnItemChanged(Object sender) in c:\Dev\DotSpatial\DotSpatial.Symbology\DotSpatial.Symbology\LegendItem.cs:line 472
       at DotSpatial.Symbology.LegendItem.OnItemChanged() in c:\Dev\DotSpatial\DotSpatial.Symbology\DotSpatial.Symbology\LegendItem.cs:line 456
       at DotSpatial.Symbology.FeatureLayer.set_ShowLabels(Boolean value) in c:\Dev\DotSpatial\DotSpatial.Symbology\DotSpatial.Symbology\FeatureLayer.cs:line 1522
       at EnvidanBil.frmMain40.showLabels(String fileName) in C:\Udvikling\EnvidanPortal.root\EnvidanPortal\EnvidanBil\frmMain40.cs:line 1223
       at EnvidanBil.frmMain40.UpdateMaps(Boolean forceRedrawAll) in C:\Udvikling\EnvidanPortal.root\EnvidanPortal\EnvidanBil\frmMain40.cs:line 1410
       at EnvidanBil.frmMain40.checkForAlertsEvent() in C:\Udvikling\EnvidanPortal.root\EnvidanPortal\EnvidanBil\frmMain40.cs:line 546
       at EnvidanBil.frmMain40.SetupTimers() in C:\Udvikling\EnvidanPortal.root\EnvidanPortal\EnvidanBil\frmMain40.cs:line 494
       at EnvidanBil.frmMain40..ctor() in C:\Udvikling\EnvidanPortal.root\EnvidanPortal\EnvidanBil\frmMain40.cs:line 228
       at EnvidanBil.Program.Main() in C:\Udvikling\EnvidanPortal.root\EnvidanPortal\EnvidanBil\Program.cs:line 46
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel)
       at System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()
       at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
       at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext)
       at System.Activator.CreateInstance(ActivationContext activationContext)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:
 
This code works in mapwindow 4x

vejNavnHandle = handle;
legend1.Map.set_LayerName(vejNavnHandle, "VejNavn");
axMap1.set_LayerLabelsVisible(vejNavnHandle, true);
axMap1.LayerFont(vejNavnHandle, "Verdana", 10);
axMap1.set_ShapeLayerPointColor(vejNavnHandle, (UInt32)(System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Transparent)));
axMap1.set_ShapeLayerPointSize(vejNavnHandle, 0);

UInt32 col = (UInt32)(System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black));

int numFields = sf.NumFields;
int index = 0;
for (int i = 0; i < numFields; i++)
{
    if (sf.get_Field(i).Name == "VEJNAVN")
        index = i;
}

for (int i = 0; i < sf.NumShapes; i++)
{
    string text = sf.get_CellValue(index, i).ToString();
    axMap1.AddLabelEx(vejNavnHandle, text, col, sf.get_Shape(i).get_Point(0).x, sf.get_Shape(i).get_Point(0).y, MapWinGIS.tkHJustification.hjLeft, 45);
}

Jan 17, 2011 at 10:05 PM

Does anybody know if there is a bug, or if I am doing something wrong?
Is the any sample code, with labels available?

Developer
Jan 17, 2011 at 10:10 PM

You don't have to pass in the FeatureSet or FeatureLayer into the constructor of the label layer?  It's been a while since I worked with it, but I thought you had to identify the attributes that would be used for the expression to work by passing something like that in with the constructor or setting it as a property.  Not sure if that's it or it's a more general bug though.

Ted

 

Jan 18, 2011 at 6:04 AM

Tried also this

FeatureSet fs = new FeatureSet();
fs.Open(fileName);
fs.Projection = KnownCoordinateSystems.Geographic.World.WGS1984;
IFeatureLayer myLayer = map1.Layers.Add(fs) as IMapPointLayer;
LabelSymbolizer symbolizer = new LabelSymbolizer();
symbolizer.Orientation = ContentAlignment.MiddleCenter;
map1.AddLabels(myLayer, "[VEJNAVN]", "", symbolizer, double.MaxValue);

And
 
FeatureSet fs = new FeatureSet();
fs.Open(fileName);
fs.Projection = KnownCoordinateSystems.Geographic.World.WGS1984;
IFeatureLayer myLayer = map1.Layers.Add(fs) as IMapPointLayer;
IMapLabelLayer labelLayer = new MapLabelLayer();
myLayer.LabelLayer = labelLayer;
myLayer.ShowLabels = true;
labelLayer.Symbology.Categories[0].Expression = "[" + myLayer.DataSet.DataTable.Columns[0].ColumnName + "]";
labelLayer.Symbolizer.Orientation = ContentAlignment.TopCenter;
map1.Refresh();

 But no luck!

Jan 18, 2011 at 6:52 PM

I am having the same problems with labeling and have tried a number of things.  I was receiving the same error you were as "Object reference not set to an instance of an object".  I happened to track that down and and discovered that the shapeIndices property was not be set.  I fixed this error by calling FeatureSet.InitializeVertices().  Now I am getting a different error: "Index was out of range."  Here is my code and the stack trace.

        //'========================================================
        //' PRIVATE VARIABLES
        //'========================================================

        private IMapFeatureLayer mFeatureLayer;
        private FeatureSet mFeatureSet = new FeatureSet();

        //'---------------------------------------------------------
        //' EVENT HANDLER:                                        
        //'---------------------------------------------------------

        private void frmMain_Load(object sender, EventArgs e)
        {
            //'-------------------------------------------------
            //' Add shapefile to DotSpatial control
            //'-------------------------------------------------

            string shapefile = ConfigurationManager.AppSettings["shapefile"];
           
            mFeatureSet.Open(shapefile);
            mFeatureSet.InitializeVertices();
            mFeatureSet.Projection = KnownCoordinateSystems.Geographic.World.WGS1984;
          
            mFeatureLayer = map1.Layers.Add(mFeatureSet);

            //' Symbolize the polygons, this will not work unless you run FillAttrubutes first.
            //' My guess is that it needs this to load all the attribute values up so it can
            //' create the categories

            mFeatureSet.FillAttributes();
            this.SymbolizePolygons();

            //IFeatureSet newFeatureSet = new FeatureSet();
            //mFeatureSet.CopyFeatures(newFeatureSet, true);

            this.LabelPolygons(mFeatureSet);

            //' Activate the graves control
            cmdGraves_Click(this, e);
        }

        //'---------------------------------------------------------
        //' METHOD:                                        
        //'---------------------------------------------------------

        private void LabelPolygons(IFeatureSet pFeatureSet)
        {
            //' Label the plots with the plot number
            IMapLabelLayer labelLayer = new MapLabelLayer(pFeatureSet);
            //labelLayer.Symbology.Categories.Clear();
      
            //ILabelCategory category = labelLayer.Symbology.AddCategory();
            ILabelCategory category = labelLayer.Symbology.Categories[0];
            category.Expression = "[plot_nbr]";
            category.Symbolizer.Orientation = ContentAlignment.MiddleCenter;
            category.Name = "id";

            mFeatureLayer.LabelLayer = labelLayer;
            mFeatureLayer.ShowLabels = true;    //' ERROR HERE
        }

System.ArgumentOutOfRangeException was unhandled
  Message=Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
  Source=mscorlib
  ParamName=index
  StackTrace:
       at System.ThrowHelper.ThrowArgumentOutOfRangeException()
       at System.Collections.Generic.List`1.get_Item(Int32 index)
       at DotSpatial.Data.FeatureSet.SelectIndices(Extent region) in C:\Dev\DotSpatial\DotSpatial.Data\DotSpatial.Data\FeatureSet.cs:line 1141
       at DotSpatial.Controls.MapLabelLayer.DrawRegions(MapArgs args, List`1 regions) in C:\Dev\DotSpatial\DotSpatial.Controls\DotSpatial.Controls\MapLabelLayer.cs:line 161
       at DotSpatial.Controls.MapFrame.InitializeLabels(List`1 regions, MapArgs args, IRenderable layer) in C:\Dev\DotSpatial\DotSpatial.Controls\DotSpatial.Controls\MapFrame.cs:line 442
       at DotSpatial.Controls.MapFrame.Initialize(List`1 regions) in C:\Dev\DotSpatial\DotSpatial.Controls\DotSpatial.Controls\MapFrame.cs:line 402
       at DotSpatial.Controls.MapFrame.Initialize() in C:\Dev\DotSpatial\DotSpatial.Controls\DotSpatial.Controls\MapFrame.cs:line 455
       at DotSpatial.Controls.MapFrame.LayerCollection_MembersChanged(Object sender, EventArgs e) in C:\Dev\DotSpatial\DotSpatial.Controls\DotSpatial.Controls\MapFrame.cs:line 1200
       at System.EventHandler.Invoke(Object sender, EventArgs e)
       at DotSpatial.Data.ChangeEventList`1.OnItemChanged(Object sender) in C:\Dev\DotSpatial\DotSpatial.Data\DotSpatial.Data\ChangeEventList.cs:line 349
       at DotSpatial.Data.ChangeEventList`1.ItemItemChanged(Object sender, EventArgs e) in C:\Dev\DotSpatial\DotSpatial.Data\DotSpatial.Data\ChangeEventList.cs:line 332
       at DotSpatial.Symbology.LegendItem.OnItemChanged(Object sender) in C:\Dev\DotSpatial\DotSpatial.Symbology\DotSpatial.Symbology\LegendItem.cs:line 472
       at DotSpatial.Symbology.LegendItem.OnItemChanged() in C:\Dev\DotSpatial\DotSpatial.Symbology\DotSpatial.Symbology\LegendItem.cs:line 456
       at DotSpatial.Symbology.FeatureLayer.set_ShowLabels(Boolean value) in C:\Dev\DotSpatial\DotSpatial.Symbology\DotSpatial.Symbology\FeatureLayer.cs:line 1522
       at graves.frmMain.LabelPolygons(IFeatureSet pFeatureSet) in F:\Data\projects\Cemetary District\data\graves\graves\frmMain.cs:line 193
       at graves.frmMain.frmMain_Load(Object sender, EventArgs e) in F:\Data\projects\Cemetary District\data\graves\graves\frmMain.cs:line 101
       at System.Windows.Forms.Form.OnLoad(EventArgs e)
       at System.Windows.Forms.Form.OnCreateControl()
       at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
       at System.Windows.Forms.Control.CreateControl()
       at System.Windows.Forms.Control.WmShowWindow(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       at System.Windows.Forms.Form.WmShowWindow(Message& m)
       at System.Windows.Forms.Form.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, Int32 wParam, Int32 lParam)
       at System.Windows.Forms.Form.SetVisibleCore(Boolean value)
       at System.Windows.Forms.Control.set_Visible(Boolean value)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at graves.Program.Main() in F:\Data\projects\Cemetary District\data\graves\graves\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:

 

Developer
Jan 20, 2011 at 5:45 PM

This issue should be fixed as of f54850b94f58.  On line 1144 of FeatureSet, it was incorrectly testing the private variable "_shapeIndices" instead of the local "shapes" variable.  The local variable uses the public accessor, which is smart enough to check internal featuresets.  The local variable can be null depending on the architecture.

Ted

 

Feb 24, 2011 at 10:42 AM
Edited Feb 26, 2011 at 1:16 PM

Hi,

I'm encountering the same problem but with VB .Net. 

Thanks and congratulations for this project that I discovered recently and that I find very exciting.

Olivier

PS : For the one who are newbies like I, I found that you can install C# together with VB, download and unzip solution from source code tab, open dotspatial.sln in this main folder, right click/properties, add the downloaded  folder to property/common properties/sources files, close and then generate. Hope it's correct.

Mar 29, 2011 at 3:11 PM

Hi Ted

--> it was incorrectly testing the private variable "_shapeIndices" instead of the local "shapes" variable.......

This is still not changed in the source code, why?

Regards Claus

Coordinator
Mar 29, 2011 at 4:56 PM

Hi all. Tevaganthan is going to create a labeling tutorial which will appear on the documentation page as Tutorial #7. He will also try to address this bug if it is really still there. - Dan

Mar 24, 2013 at 7:45 AM
Did Tutorial #7 ever happen? I need to be able to plot points and a label which I extract from a database. It seems I am not alone in needing this sort of capability and it also seems that few, if any, people are able to figure it out.

DotSpatial is very powerful with all kinds of capabilities. I just don't believe it cannot be used to plot points with a label. That would be one of the first functions almost anybody working with a database would be wanting.

I have been able to plot database points, using a Symbology Blue Star on a layer than can be enabled or disabled using the Legend, but for the life of me I cannot get a simple label to print near that Star.