Hi agelo, I progressed it a bit further, it is not solid but it will return polygons (though they are not guaranteed to be valid) and it should work with net 2 ;). It needs further work as it silently drops groups of edges which it cannot orientate hth jd
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using BenTools.Mathematics;
using SharpMap.Data;
using SharpMap.Geometries;
namespace SharpMapVoronoi
{
public static class VoronoiExtensions
{
public static VoronoiGraph ComputeVoronoiGraph(IEnumerable<FeatureDataRow> points)
{
return ComputeVoronoiGraph(L.Select(points, delegate(FeatureDataRow o) { return o.Geometry as Point; }));
}
public static VoronoiGraph ComputeVoronoiGraph(IEnumerable<Point> points)
{
return
Fortune.ComputeVoronoiGraph(
L.Select(
L.Where(
points
, delegate(Point o) { return o != null; })
, delegate(Point o) { return new Vector(new[] { o.X, o.Y }) { Tag = o }; }));
}
public static IEnumerable<Geometry> GeometriesFromVoronoiGraph(VoronoiGraph graph, IEnumerable<Point> dataPoints)
{
IList<Point> points = L.ToList(dataPoints);
Dictionary<Point, List<VoronoiEdge>> storage = new Dictionary<Point, List<VoronoiEdge>>();
foreach (Point p in points)
{
foreach (VoronoiEdge e in graph.Edges)
if (e.LeftData.Tag == p || e.RightData.Tag == p)
{
if (!storage.ContainsKey(p))
storage.Add(p, new List<VoronoiEdge>());
storage[p].Add(e);
}
}
foreach (List<VoronoiEdge> edges in storage.Values)
{
Geometry g = EdgesToPolygon(edges);
if (g != null)
yield return g;
}
}
private static Geometry EdgesToPolygon(List<VoronoiEdge> edges)
{
Collection<Point> pts = new Collection<Point>();
IEnumerable<VoronoiEdge> orientatedEdges = OrientateEdges(edges);
if (orientatedEdges == null)
return null;
foreach (VoronoiEdge edge in orientatedEdges)
{
if (pts.Count == 0)
pts.Add(new Point(edge.VVertexA[0], edge.VVertexA[1]));
pts.Add(new Point(edge.VVertexB[0], edge.VVertexB[1]));
}
return new Polygon(new LinearRing(pts));
}
//TODO:This method is incomplete and silently drops groups which it cannot orientate
private static IEnumerable<VoronoiEdge> OrientateEdges(IEnumerable<VoronoiEdge> edges)
{
IList<VoronoiEdge> workingSet = new List<VoronoiEdge>(edges);
IList<VoronoiEdge> result = new List<VoronoiEdge>();
result.Add(workingSet[0]);
workingSet.RemoveAt(0);
while (workingSet.Count > 0)
{
int count = workingSet.Count;
for (int i = workingSet.Count - 1; i > -1; i--)
{
VoronoiEdge curr = workingSet[i];
bool found = false;
if (Equals(L.Last(result).VVertexB, curr.VVertexA))
{
found = true;
result.Add(workingSet[i]);
}
else if (Equals(L.Last(result).VVertexB, curr.VVertexB))
{
found = true;
result.Add(new VoronoiEdge { VVertexA = workingSet[i].VVertexB, VVertexB = workingSet[i].VVertexA });
}
else if (Equals(L.First(result).VVertexA, curr.VVertexB))
{
found = true;
result.Insert(0, workingSet[i]);
}
else if (Equals(L.First(result).VVertexA, curr.VVertexA))
{
found = true;
result.Insert(0,
new VoronoiEdge { VVertexA = workingSet[i].VVertexB, VVertexB = workingSet[i].VVertexA });
}
if (found)
workingSet.RemoveAt(i);
}
if (workingSet.Count == count)//we didn't manage to orientate the list
{
//throw new ApplicationException("Unable to orientate edges");//throw exception
return null;//silently drop
}
}
return result;
}
public static bool Equals(Vector a, Vector b)
{
if (a.Dim == b.Dim)
{
for (int i = 0; i < a.Dim; i++)
if (a[i] != b[i])
return false;
return true;
}
return false;
}
public static IEnumerable<Geometry> VoronoiGeometriesFromFeatureDataTable(FeatureDataTable pointsTable)
{
return
VoronoiGeometriesFromPoints(
L.Select(L.EnumerateFeatureDataRows(pointsTable),
delegate(FeatureDataRow o) { return o.Geometry as Point; }));
}
public static IEnumerable<Geometry> VoronoiGeometriesFromPoints(IEnumerable<Point> points)
{
return GeometriesFromVoronoiGraph(ComputeVoronoiGraph(points), points);
}
}
public static class L
{
public delegate U LFunc<T, U>(T o);
public static T First<T>(IEnumerable<T> input)
{
foreach (T val in input)
{
return val;
}
return default(T);
}
public static T Last<T>(IEnumerable<T> input)
{
var lst = input as IList<T>;
if (lst != null)
{
if (lst.Count > 0)
return lst[lst.Count - 1];
}
T curr = default(T);
foreach (T c in input)
curr = c;
return curr;
}
public static IList<T> ToList<T>(IEnumerable<T> input)
{
IList<T> ls = new List<T>();
foreach (T li in input)
ls.Add(li);
return ls;
}
public static IEnumerable<T> Where<T>(IEnumerable<T> input, LFunc<T, bool> predicate)
{
foreach (T val in input)
if (predicate(val))
yield return val;
}
public static IEnumerable<U> Select<T, U>(IEnumerable<T> input, LFunc<T, U> conv)
{
foreach (T val in input)
yield return conv(val);
}
public static IEnumerable<FeatureDataRow> EnumerateFeatureDataRows(FeatureDataTable dt)
{
foreach (FeatureDataRow r in dt.Rows)
yield return r;
}
}
}