/// <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;
            }
        }
Exemplo n.º 2
0
        /// <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));
 }