This project has moved and is read-only. For the latest updates, please go here.

Query & symbolize linestring vertices

Topics: Algorithms, SharpMap v0.9 / v1.x
Jun 23, 2011 at 11:48 PM

Hi All!

I have some linestrings on my map. This linestrings are created dynamically from code based on some incoming data and are shown on a vector variable layer. It works great.

My problems are:

  • I'd like to symbolize the vertices of the line (e.g. as point markers). Does it have a trivial way or do I have to add vertices to a layer as point geometries?
  • When the user moves mouse on the line I'd like to query tha data of the nearest vertice point. (I use Geometry.UserData porperty to store some own data). How can I do that? Is there a trivial way? Or should I also use a point layer I mentioned in my previous question to make these queries?
  • Is it possible to symbolize any point geometry by Windows Font? Or is it possible only by image?

Thanks in advance!


Jun 24, 2011 at 10:13 PM

Hello Tamas,

For your first problem, I'd go and derive my own layer from VectorLayer that takes care of rendering the linestring and afterwards marking the vertices. That is a common approach.

For your second problem, you need to subscribe to MapBox.MouseHover event. Since this event only passes standard EventArgs, you need to calculate mouse geo location yourself with the help of Control.MousePosition, Control.PointToClient and Map.ImageToWorld. Once you have that, you can call ExecuteFeatureQuery on your layer's datasource.

For your third problem, there is a workitem around ( that I have been wanting to apply for quite some time now.

Hth FObermaier

Jun 24, 2011 at 10:20 PM

Thx a lot!

For the 1st, its OK, I'll do that, for the 3rd I'll try.

For the 2nd: I know the way, I do it on my point layers. My question was about queriing vertices, but I wonder it should be queried via the points you mentioned in answer 1st.

Jun 24, 2011 at 11:12 PM

You may want to perform the executeintersectionquery function on your base geometry type (LineString) and use functionality from NetToplogySuite's LinearReferencing namespace to get nearest points.
Btw., there are newer versions of NTS available on We are currently working on 1.10. You should be able to adopt it in your project with a fairly decent amount of work.

Hth FObermaier

Jun 25, 2011 at 1:34 AM
Edited Jun 25, 2011 at 1:36 AM

For NTS operations the most effective way is to use 0.9.5-DeltaShell branch for this time, am I right? It has the geometry conversion features I need (GeoAPI -> SharpMap).

For now I have a hacked - but working - solution: I made a vector layer, when adding a line to it I also store its vertex points + attributes in a GeometryFeatureProvider property and I make intersection queries on that.  I'll try to improve this solution by NTS as I'll have time.


Jun 25, 2011 at 8:22 AM

If you do not want to use v0.9.5 deltashell branch, you can use SharpMap.Extensions project and use its NTSConverter. This is what I had in mind when I said it should be manageable

Jun 25, 2011 at 2:13 PM
Edited Jun 25, 2011 at 2:19 PM

So, my solution to problem nr2:

GisSharpBlog.NetTopologySuite.Geometries.GeometryFactory geometryFactory = 
               new GisSharpBlog.NetTopologySuite.Geometries.GeometryFactory();
var ntsLineString = 
                (GisSharpBlog.NetTopologySuite.Geometries.LineString)SharpMap.Converters.NTS.GeometryConverter.ToNTSGeometry(lineString, geometryFactory);
var geoapiLineString = (GeoAPI.Geometries.ILineString)ntsLineString;
var ntsCoordinate = new GisSharpBlog.NetTopologySuite.Geometries.Coordinate(point.X, point.Y);
var geoapiCoordinate = (GeoAPI.Geometries.ICoordinate)ntsCoordinate;

var linearRefQueryRes = GisSharpBlog.NetTopologySuite.LinearReferencing.LocationIndexOfPoint.IndexOf(geoapiLineString, geoapiCoordinate);
var vertice = lineString.Vertices[linearRefQueryRes.SegmentIndex];

lineString: a sharpmap linestring geometry; point: a sharpmap point geometry.

It works, I hope it is a good one and can help others who face with this problem.

Jun 25, 2011 at 7:44 PM

That's the way I had in mind :)