Interesting/Simple DataSource Problem

Topics: General Topics
May 30, 2007 at 12:29 PM
I have two Layers:

SharpMap.Layers.VectorLayer vLayer;
SharpMap.Layers.LabelLayer lLayer;

I added 3 layers to vLayer. I want to display Attribute Info Layer for the layer 2 in vLayer, but I don't seem to find any method to associate them. How can I do it?

I am using the following code to display Attribute Info Layer.
SharpMap.Layers.LabelLayer lLayer = new SharpMap.Layers.LabelLayer("lLayer");
lLayer.DataSource = vLayer.DataSource;
lLayer.Enabled = true;
lLayer.LabelColumn = strLayerName;
lLayer.Style = new SharpMap.Styles.LabelStyle();
lLayer.Style.Font = new Font(FontFamily.GenericSerif, 10);
lLayer.Style.HorizontalAlignment = SharpMap.Styles.LabelStyle.HorizontalAlignmentEnum.Center;
How do I connect vLayer datasource for the layer 2 to lLayer?
May 30, 2007 at 3:23 PM
Uhm... I don't understood clearly your problem, but if you want to dispaly more than 1 attribute ina label layer, you can't, since you need 2 different label layers... same if you want to use 1 label layer to show 2 or more attributes... 1 label layer displays 1 attribute of 1 vector layer... maybe I misunderstood btw :P
May 31, 2007 at 10:13 AM
I thought of several other wordings to put the question, but, I was sure it is not easy to understand the question, unless you see the problem.

I'll tell you the scenario here:

Say, I add a map “Layer1”; then I add its attribute info label layer (for the attribute, say “StateName”) using the above code, then the attribute information is showing up correctly.

Meaning lLayer.DataSource = vLayer.DataSource;
is working fine and vLayer with “Layer1”’s data source is assigned to lLayer’s data source.

But when I add “Layer1” and add another map “Layer2” and then, when I try to attempt to show the first map “Layer1”’s attribute info, the application bombs out with an exception saying “Column ‘StateName’ does not belong to table”.

Because, vLayer is now holding the information of “Layer2” map.

So, what I am asking is, how do I assign different layer’s index as a data source to the label layer.
Like: lLayer.DataSource = mapBox1.Map.Layers1.DataSource;
But, Layer1.DataSource is not available. So, is there a work around for this?

I hope I explained it. If not, I’ll try again later.
May 31, 2007 at 2:57 PM
Edited May 31, 2007 at 2:59 PM
Well... not so clear unfortunally... but I'll try to post an example about how to show different labels from the same datasource...
VectorLayer vectLayer = new VectorLayer("vec", ANY_PROVIDER_HERE);
LabelLayer label1 = new LabelLayer("label1");
label1.DataSource = vectLayer.DataSource;
LabelLayer label2 = new LabelLayer("label2");
label2.DataSource = vectLayer.DataSource;

The exception you're having means that your are asking to match the label layer to an invalid column of the vector layer... I fear you're trying to use the same LabelLayer to show more than 1 column... you can't.... every column must be associated to a layer and to a specific (and valid) column.
Obviusly you could change at runtime the binding of your label layer, like
VectorLayer vectLayer1 = new VectorLayer("vec", ANY_PROVIDER_HERE);
VectorLayer vectLayer2 = new VectorLayer("vec", ANY_PROVIDER_HERE);
LabelLayer label1 = new LabelLayer("label1");
label1.DataSource = vectLayer1.DataSource;
//Somewhere else
label1.DataSource = vectLayer2.DataSource;
label1.LabelColumn = ANY_VALID_COLUMN_NAME_FROM_VECT2;    //<--- Here you need to specify a valid vect2 column

The last sentence you wrote is the most obscure to me... obviusly you can do
LabelLayer labelLayer=new LabelLayer("label");
labelLayer.Datasource = mapBox1.Map.Layers[1];
labelLayer.LabelColumn = VALID_LAYERS_1_COLUMN_NAME;
why you shoudn't access such information?
Jun 1, 2007 at 5:48 AM
You gave me a good hint here.

But you can not assign labelLayer.Datasource = mapBox1.Map.Layers1;
You will get:
Cannot implicitly convert type 'SharpMap.Layers.ILayer' to 'SharpMap.Data.Providers.IProvider'. An explicit conversion exists (are you missing a cast?)

So, what I have done is searched for the my layer again and created a vector layer again as you said. Here is the code:
SharpMap.Layers.VectorLayer infoLayer = null;
foreach (SharpMap.Layers.VectorLayer layer in mapBox1.Map.Layers)
    if (layer.LayerName == strLayerName)
        infoLayer = layer;
layLabel.DataSource = infoLayer.DataSource;

Thanks for your help.

Jun 1, 2007 at 7:35 AM
Edited Jun 1, 2007 at 7:38 AM
Ouch, sorry, you're right, I forgot to complete the code... you of course can't do
labelLayer.Datasource = mapBox1.Map.Layers[1];
but you can do
labelLayer.Datasource = mapBox1.Map.Layers[1].Datasource;
Jun 1, 2007 at 10:02 AM
Nope, mapBox1.Map.Layers1. does not have a method/property Datasource.

Are you using 0.9 version or something else?
Jun 4, 2007 at 7:24 AM
You're right, since the Layers property is an array of ILayer objects, obviusly you can't find the Datasource property... the only way is to cast the layer in the proper object, like
VectorLayer vec = (VectorLayer)mapBox1.Map.Layers[1];
obviusly is more than 1 kind of Layer is added to the map (like LabelLayer etc), you should check before casting
if(mapBox1.Map.Layers[1] is VectorLayer)
    VectorLayer vec = (VectorLayer)mapBox1.Map.Layers[1];
else if(mapBox1.Map.Layers[1] is LabelLayer)
    LabelLayer label= (LabelLayer)mapBox1.Map.Layers[1];
else ...
Jun 4, 2007 at 10:05 AM
Correct, thats the way to go. Actually that's the kind of answer that I was looking for. "Casting" did not hit brain. Thanks!