4

I have looked around to find an example of how to take a polyline and create a buffer around it so I end up with a polygon.

So far I found out I need Minkowskis Sums to do so, but I can't get my head around to raw algorithm and translate that in to code.

I would prefer an example in C# or a walkthrough of the algorithm.

eNepper
  • 1,889
  • 2
  • 13
  • 12

3 Answers3

4

You could use the OffsetPolygons() function in the Clipper library, but first you'd need to convert the polyline into a polygon. Do this by appending to the polyline a reverse copy of the polyline. But since duplicate vertices aren't allowed the reverse copy must exclude the first and last vertices: v1,v2,...,vn, v(n-1),...,v2.

enter image description here

Angus Johnson
  • 4,565
  • 2
  • 26
  • 28
  • It looks like Clipper only takes int values as the coordinates, but my coordinates is double values eg. (56.30174). Or am I missing some thing? – eNepper Nov 22 '11 at 13:16
  • Regarding int values, see the FAQ in the documentation here: http://www.angusj.com/delphi/clipper/documentation/Docs/Overview/FAQ.htm – Angus Johnson Nov 22 '11 at 13:18
  • Do you know if the delta is divided by 2 or? because I'm polygon is as wide as my delta, and not double the width. – eNepper Nov 24 '11 at 09:09
  • If the polyline is converted to a polygon as suggested above, then delta will be the amount the polygon expands on both sides of the original polyline. Therefore, the 'width' of your newly converted and expanded polyline will be twice delta. – Angus Johnson Nov 25 '11 at 23:08
3

Here's a sample way to do something like this with the 2D objects already available with the .NET Framework, based off of this link

http://www.charlespetzold.com/blog/2008/04/Rounded-Graphics-in-WPF.html

  // ...
  StreamGeometry geom = new StreamGeometry();

  DrawLines(geom);

  Pen p = new Pen(Brushes.Black, 10);
  p.LineJoin = PenLineJoin.Round;
  p.EndLineCap = PenLineCap.Round;
  p.StartLineCap = PenLineCap.Round;


  PathGeometry pathGeomWide = geom.GetWidenedPathGeometry(p);
  PathGeometry pathGeom = pathGeomWide.GetOutlinedPathGeometry();

  Path myPath = new Path();
  myPath.Stroke = Brushes.Black;
  myPath.Data = pathGeom;
  myCanvas.Children.Add(myPath);
  // ...

private static void DrawLines(StreamGeometry geom)
{
  using (var context = geom.Open())
  {
    context.BeginFigure(new Point(20, 20), false, true);
    context.LineTo(new Point(100, 20), true, true);
    context.LineTo(new Point(100, 100), true, true);
    context.LineTo(new Point(200, 100), true, true);
  }
}

enter image description here

PeskyGnat
  • 2,454
  • 19
  • 22
1

Have you tried using the 'Dot Spatial' library from Codeplex?

http://dotspatial.codeplex.com/

That uses Geos & Proj4 internally, which already contain all the functionality you need (Most of the worlds GIS servers & Products are built on these 2 code-bases!)

Failing that, you could use SQlite:

http://sqlite.phxsoftware.com/

and Spatialite:

http://www.gaia-gis.it/spatialite/

Then using ADO.NET code in C# you can use simple GIS SQL Queries to perform your processing EG:

SELECT AsText(ST_Buffer(polyline,0.25),4326)

WHich will return a string something like:

MULTIPOLYGON((x y, x y, x y, x y......))

That you can then just parse.

No need to re-invent the wheel, when everything you need is readily available.

shawty
  • 5,729
  • 2
  • 37
  • 71