Exemple #1
0
        /// <summary>
        /// Tries to merge ways to closed polygons. The ordering of waynodes is preserved during the merge process.
        /// </summary>
        /// <param name="ways">
        ///            An array of ways that should be merged. Ways may be given in any order and may already be closed. </param>
        internal virtual void mergePolygons(TDWay[] ways)
        {
            this.polygons = new List <>();
            this.dangling = new List <>();
            this.illegal  = new List <>();

            Deque <TDWay> ungroupedWays = new ArrayDeque <TDWay>();

            // initially all ways are ungrouped
            foreach (TDWay tdWay in ways)
            {
                // reset reversed flag, may already be set when way is part of another relation
                tdWay.ReversedInRelation = false;

                // first extract all way that are closed polygons in their own right
                if (isClosedPolygon(tdWay))
                {
                    if (tdWay.WayNodes.length < MIN_NODES_POLYGON)
                    {
                        this.illegal.Add(tdWay);
                    }
                    else
                    {
                        Deque <TDWay> cluster = new ArrayDeque <TDWay>();
                        cluster.add(tdWay);
                        this.polygons.Add(cluster);
                    }
                }
                else
                {
                    ungroupedWays.add(tdWay);
                }
            }

            // all ways have been polygons, nice!
            if (ungroupedWays.Empty)
            {
                return;
            }

            if (ungroupedWays.size() == 1)
            {
                this.dangling.Add(ungroupedWays.First);
                return;
            }

            bool startNewPolygon = true;

            while (true)
            {
                bool merge = false;
                if (startNewPolygon)
                {
                    // we start a new polygon either during first iteration or when
                    // the previous iterations merged ways to a closed polygon and there
                    // are still ungrouped ways left
                    Deque <TDWay> cluster = new ArrayDeque <TDWay>();
                    // get the first way of the yet ungrouped ways and form a new group
                    cluster.add(ungroupedWays.removeFirst());
                    this.polygons.Add(cluster);
                    startNewPolygon = false;
                }

                // test if we can merge the current polygon with an ungrouped way
                IEnumerator <TDWay> it = ungroupedWays.GetEnumerator();
                while (it.MoveNext())
                {
                    TDWay current = it.Current;

                    Deque <TDWay> currentPolygonSegments = this.polygons[this.polygons.Count - 1];
                    // first way in current polygon
                    TDWay c1Start = currentPolygonSegments.First;
                    // last way in current polygon
                    TDWay c1End = currentPolygonSegments.Last;

                    long startFirst = c1Start.ReversedInRelation ? c1Start.WayNodes[c1Start.WayNodes.length - 1].Id : c1Start.WayNodes[0].Id;

                    long endLast = c1End.ReversedInRelation ? c1End.WayNodes[0].Id : c1End.WayNodes[c1End.WayNodes.length - 1].Id;

                    long currentFirst = current.WayNodes[0].Id;
                    long currentLast  = current.WayNodes[current.WayNodes.length - 1].Id;

                    // current way end connects to the start of the current polygon (correct direction)
                    if (startFirst == currentLast)
                    {
                        merge = true;
//JAVA TO C# CONVERTER TODO TASK: .NET enumerators are read-only:
                        it.remove();
                        // add way to start of current polygon
                        currentPolygonSegments.offerFirst(current);
                    }
                    // // current way start connects to the start of the current polygon (reversed
                    // direction)
                    else if (startFirst == currentFirst)
                    {
                        current.ReversedInRelation = true;
                        merge = true;
//JAVA TO C# CONVERTER TODO TASK: .NET enumerators are read-only:
                        it.remove();
                        currentPolygonSegments.offerFirst(current);
                    }
                    // current way start connects to the end of the current polygon (correct direction)
                    else if (endLast == currentFirst)
                    {
                        merge = true;
//JAVA TO C# CONVERTER TODO TASK: .NET enumerators are read-only:
                        it.remove();
                        // add way to end of current polygon
                        currentPolygonSegments.offerLast(current);
                    }
                    // // current way end connects to the end of the current polygon (reversed direction)
                    else if (endLast == currentLast)
                    {
                        current.ReversedInRelation = true;
                        merge = true;
//JAVA TO C# CONVERTER TODO TASK: .NET enumerators are read-only:
                        it.remove();
                        // add way to end of current polygon
                        currentPolygonSegments.offerLast(current);
                    }
                }

                Deque <TDWay> currentCluster = this.polygons[this.polygons.Count - 1];
                bool          closed         = isClosedPolygon(currentCluster);
                // not a closed polygon and no more ways to merge
                if (!closed)
                {
                    if (ungroupedWays.Empty || !merge)
                    {
                        ((List <TDWay>) this.dangling).AddRange(this.polygons[this.polygons.Count - 1]);
                        // may be a non operation when ungrouped is empty
                        ((List <TDWay>) this.dangling).AddRange(ungroupedWays);
                        this.polygons.Remove(this.polygons.Count - 1);
                        return;
                    }
                }
                else
                {
                    // built a closed polygon and no more ways left --> we are finished
                    if (ungroupedWays.Empty)
                    {
                        return;
                    }

                    startNewPolygon = true;
                }

                // if we are here, the polygon is not yet closed, but there are also some ungrouped ways
                // which may be merge-able in the next iteration
            }
        }