Better way to query?

Topics: General Topics, Algorithms, SharpMap v0.9 / v1.x
Sep 18, 2007 at 3:16 PM
Hi All,

I've got some data from a shape file source. The shape file consists of a set of PolyLines (linestrings), some of which are quite long. I want to be able to deduce which shape was clicked on when a user clicks.

The ExecuteIntersectionQuery method returns rows for shapes which intersect with a bounding box, ie the box of the clicked point.

Problem is, where I have long polylines (particularly ones which run diagonally), their polyline's bounding box is enormous and thus gets returned in the query.

Visually my user can be clicking on one road, yet the ExecuteIntersectionQuery results give 40 shapes, some of which are actually serveral kilometres away.

Does anyone know of a way that I can improve on this? I'd need some code that has an understanding of what a linestring actually it, rather than just it's bounding box.

Any ideas or pointers are much appreciated.


Sep 19, 2007 at 1:03 AM
This is a known limitation of SharpMap, which you can use the NetTopologySuite Data Provider to work around.

SharpMap v2.0 Beta 2 will incorporate NTS geometries as the standard geometry model, and this will cease being a problem then.
Sep 19, 2007 at 3:35 AM
Yes,you can use NTS(NetTopologySuite Data Provider). I can give you a segment code: You need import references: NetTopologySuite.dll, GeoAPI.dll and SharpMap.dll:
-pos: mouse click point.
-layer: layer which you want to query
-amountGrow: grow bounding box to chose Geomertry intersection in bouding box of Point.
-return a record in database include nearlest geomertry (the_geom column)
public SharpMap.Data.FeatureDataRow FindGeoNearPoint(SharpMap.Geometries.Point pos, SharpMap.Layers.VectorLayer layer,double amountGrow)
SharpMap.Geometries.BoundingBox bbox = pos.GetBoundingBox().Grow(amountGrow);
SharpMap.Data.FeatureDataSet ds = new SharpMap.Data.FeatureDataSet();
layer.DataSource.ExecuteIntersectionQuery(bbox, ds);
DataTable tbl = ds.Tables0 as SharpMap.Data.FeatureDataTable;
GisSharpBlog.NetTopologySuite.IO.WKTReader reader = new GisSharpBlog.NetTopologySuite.IO.WKTReader();
GeoAPI.Geometries.IGeometry point = reader.Read(pos.ToString());
if (tbl.Rows.Count == 0)
return null;

double distance = point.Distance(reader.Read((tbl.Rows0 as SharpMap.Data.FeatureDataRow).Geometry.ToString()));
SharpMap.Data.FeatureDataRow selectedFeature = tbl.Rows0 as SharpMap.Data.FeatureDataRow;

if (tbl.Rows.Count > 1)
for (int i = 1; i < tbl.Rows.Count; i++)
GeoAPI.Geometries.IGeometry line = reader.Read((tbl.Rowsi as SharpMap.Data.FeatureDataRow).Geometry.ToString());
if (point.Distance(line) < distance)
distance = point.Distance(line);
selectedFeature = tbl.Rowsi as SharpMap.Data.FeatureDataRow;
return selectedFeature;
Sep 19, 2007 at 9:05 AM
Thanks to both of your for your help.

v2.0 looks very interesting, i'm greatly looking forward to it's release.