Intersection Queries on VectorLabels

Topics: Algorithms, Data Access, SharpMap v0.9 / v1.x, WinForms Controls
May 30, 2008 at 5:54 PM
Edited May 30, 2008 at 5:55 PM
Hello,

First let me say thank you a million times over for SharpMap! It's brilliant so far. I've used these forums loads for answering questions of my own but I'm stuck:

I want to perform an Intersection test on a bunch of labels.  I do this for vector layers:


SharpMap.Layers.VectorLayer vectorLayer;
SharpMap.Data.FeatureDataSet filteredDataSet;

 

vectorLayer =

new SharpMap.Layers.VectorLayer("Inland Water - Rivers");
vectorLayer.DataSource =
new SharpMap.Data.Providers.ShapeFile(".\\data\\geodata\\eu_water_courseways.shp");
filteredDataSet =
new SharpMap.Data.FeatureDataSet();
vectorLayer.DataSource.Open();
vectorLayer.DataSource.ExecuteIntersectionQuery(_vectorLayers[(
int)eLayerGeom.LANDMASS].Envelope, filteredDataSet);
vectorLayer.DataSource.Close();
vectorLayer.DataSource =
new SharpMap.Data.Providers.GeometryProvider(filteredDataSet.Tables[0]);




However, the same does not work for LabelLayers:


#region Urban Labels
labelLayer =
new SharpMap.Layers.LabelLayer("Urban Population Points");
labelLayer.DataSource =
new SharpMap.Data.Providers.ShapeFile(".\\data\\geodata\\eu_urban_area.shp");
filteredDataSet =
new SharpMap.Data.FeatureDataSet();
labelLayer.DataSource.Open();
labelLayer.DataSource.ExecuteIntersectionQuery(_vectorLayers[(
int)eLayerGeom.LANDMASS].Envelope, filteredDataSet);
labelLayer.DataSource.Close();
//labelLayer.DataSource = new SharpMap.Data.Providers.GeometryProvider(filteredDataSet.Tables[0]);
labelLayer.LabelColumn = "NAM";
labelLayer.Style.CollisionBuffer =
new SizeF(20, 20);
labelLayer.Style.CollisionDetection =
true;
labelLayer.Style.Font =
new Font("Microsoft Sans Serif", 8, FontStyle.Italic);
_labelLayers.Insert((
int)eLayerLabel.URBAN, labelLayer);
#endregion

Assigning the Label layer's Data source to be a Geometry Provider throws an System.NotSupported exception:
"Attribute data is not supported by the Geometry Provider".

Can someone elaborate on this please, and point me in the right direction?

Thanks

Jun 1, 2008 at 11:19 PM
Any ideas anyone?

Simply put- my problem is that I have a massive list of labels for places in Europe and Asia, and I only want to render an area of labels, based on a box.
Coordinator
Jun 2, 2008 at 9:43 AM
Hi strikky, the GeometryProvider will only return the geometry not the associated attributes. You should be able to accomplish what you want with the GeometryFeatureProvider using the constructor that takes a FeatureDataTable hth jd
Coordinator
Jun 2, 2008 at 3:07 PM
Hi strikky -

I'm a bit interested in more of the reason why you want to do this - do you want to show a larger map with only labels on parts of it? The reason I ask is that I'm trying to come up with a list of scenarios supported by SharpMap v2.0.

Another way to do this is to use a custom theme on the layer and change the visibility of the feature depending on whether it intersects the box. This might make it easier to code, but John's method will result in more efficient use of memory.
Jun 2, 2008 at 8:52 PM
Thank you John - that did the trick. I hadn't seen that provider as I was using the "main" release 0.9 on the webpage, however once I downloaded the more up-to-date source code I saw this and it does exactly what I want. Perfect.

Codekaizen - Exactly that.  and I am quite new to GIS and I have a large data set that I am trialling from a known distributor with data spanning the world split up into the major continents, however I am only working on a specific country. I have been unable to find a way to manually alter the source shapefile and database file so that I am using only the required area. So I am just loading the whole whack into memory, selecting what I need, and unloading what isn't needed. Not very efficient but it's only once during start up and this is for a demo.

Again can I just say that the job you are doing is wonderful, your efforts are sincerely greatly appreciated.