/// <summary> /// Computes the result of the operation. /// </summary> protected override void ComputeResult() { switch (_dimension) { case 0: foreach (IGraphVertex vertex in Source.Vertices) { _points.Add(_factory.CreatePoint(vertex.Coordinate, _metadataPreservation ? vertex.Metadata : null)); } break; case 1: foreach (IGraphVertex vertex in Source.Vertices) { _points.Add(_factory.CreatePoint(vertex.Coordinate, _metadataPreservation ? vertex.Metadata : null)); } foreach (IGraphVertex vertex in Source.Vertices) { foreach (IGraphEdge edge in Source.OutEdges(vertex)) { if (edge.Source.Coordinate.Equals(edge.Target.Coordinate)) { continue; } _points.Remove(_factory.CreatePoint(edge.Source.Coordinate)); _points.Remove(_factory.CreatePoint(edge.Target.Coordinate)); _lines.Add(_factory.CreateLine(edge.Source.Coordinate, edge.Target.Coordinate, _metadataPreservation ? edge.Metadata : null)); } } break; case 2: // source: Jiang, X. Y., Bunke, H.: An optimal algorithm for extracting the regions of a plane graph (1993) List <Coordinate> coordinates = new List <Coordinate>(); // find all wedges List <AngularEdge> edges = new List <AngularEdge>(); foreach (IGraphVertex vertex in Source.Vertices) { Coordinate sourceCoordinate = vertex.Coordinate; Coordinate baseCoordinate = vertex.Coordinate - new CoordinateVector(1, 0); IEnumerable <IGraphEdge> outEdges = Source.OutEdges(vertex); if (outEdges.Count() == 0) { coordinates.Add(vertex.Coordinate); continue; } foreach (IGraphEdge edge in outEdges) { Coordinate target = edge.Target.Coordinate; edges.Add(new AngularEdge(sourceCoordinate, target, Coordinate.Orientation(sourceCoordinate, baseCoordinate, target) == Orientation.CounterClockwise ? Coordinate.Angle(sourceCoordinate, baseCoordinate, target) : Math.PI - Coordinate.Angle(sourceCoordinate, baseCoordinate, target))); } } edges.Sort(new AngularEdgeComparer()); IEnumerable <IGrouping <Coordinate, AngularEdge> > groups = edges.GroupBy(angularEdge => angularEdge.Source); List <Wedge> wedges = new List <Wedge>(); foreach (IGrouping <Coordinate, AngularEdge> group in groups) { AngularEdge[] groupEdges = group.ToArray(); for (Int32 i = 0; i < groupEdges.Length - 1; i++) { wedges.Add(new Wedge(groupEdges[i + 1].Target, groupEdges[i].Source, groupEdges[i].Target)); } wedges.Add(new Wedge(groupEdges[0].Target, groupEdges[0].Source, groupEdges[groupEdges.Length - 1].Target)); } // grouping wedges to regions List <List <Wedge> > faces = new List <List <Wedge> >(); List <List <Wedge> > leftOverEdges = new List <List <Wedge> >(); for (Int32 i = 0; i < wedges.Count; i++) { List <Wedge> wedgeSeries = new List <Wedge>(); Wedge currentWedge = wedges[i]; do { wedges.Remove(currentWedge); wedgeSeries.Add(currentWedge); currentWedge = wedges.FirstOrDefault(wedge => wedge.First.Equals(currentWedge.Second) && wedge.Second.Equals(currentWedge.Third)); }while (currentWedge != null); if (wedgeSeries[0].First.Equals(wedgeSeries[wedgeSeries.Count - 1].Second) && wedgeSeries[0].Second.Equals(wedgeSeries[wedgeSeries.Count - 1].Third)) { faces.Add(wedgeSeries); } else { leftOverEdges.Add(wedgeSeries); } } for (Int32 i = 0; i < faces.Count; i++) { List <Coordinate> shell = faces[i].Select(wedge => wedge.First).ToList(); shell.Add(shell[0]); if (PolygonAlgorithms.Orientation(shell) == Orientation.CounterClockwise) { Dictionary <String, Object> metadata = null; if (_metadataPreservation) { metadata = new Dictionary <String, Object>(); foreach (IMetadataCollection collection in shell.Select(coordinate => Source.GetVertex(coordinate).Metadata)) { foreach (String key in collection.Keys) { metadata[key] = collection[key]; } } } _polygons.Add(_factory.CreatePolygon(shell, metadata)); } } for (Int32 i = 0; i < leftOverEdges.Count; i++) { for (Int32 j = 0; j < leftOverEdges[i].Count; j++) { _lines.Add(_factory.CreateLine(leftOverEdges[i][j].First, leftOverEdges[i][j].Second, _metadataPreservation ? Source.GetEdge(leftOverEdges[i][j].First, leftOverEdges[i][j].Second).Metadata : null)); } } foreach (Coordinate coordinate in coordinates) { _points.Add(_factory.CreatePoint(coordinate, _metadataPreservation ? Source.GetVertex(coordinate).Metadata : null)); } break; } }
/// <summary> /// Creates a new line object in Mapinfo. /// Returns a <see cref="T:MapinfoWrapper.Geometries.Lines.Line"/> which can be inserted into a /// <see cref="T:MapinfoWrapper.DataAccess.Table"/> /// <para>This function will create a new object variable in Mapinfo with a modified GUID as its name.</para> /// </summary> /// <param name="start">The <see cref="T:MapinfoWrapper.Geometries.Coordinate"/> for the start of the line.</param> /// <param name="end">The <see cref="T:MapinfoWrapper.Geometries.Coordinate"/> for the end of the line.</param></param> /// <returns>A new <see cref="T:MapinfoWrapper.Geometries.Lines.ILine"/>.</returns> public static Line CreateLine(Coordinate start, Coordinate end) { IGeometryFactory geofactory = ServiceLocator.GetInstance <IFactoryBuilder>().BuildGeomtryFactory(); return((Line)geofactory.CreateLine(start, end)); }
/// <summary> /// Computes the transformation of the source geometry. /// </summary> /// <param name="source">The source geometry.</param> /// <returns>The geometry in the specified reference system.</returns> private ILine Compute(ILine source) { return(_factory.CreateLine(Compute(source.StartCoordinate), Compute(source.EndCoordinate), _metadataPreservation ? source.Metadata : null)); }