ThinkGeo.com    |     Documentation    |     Premium Support

Some finding on how to boost shapes union using TPL


using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Text;

using System.Threading;
using System.Threading.Tasks;

using ThinkGeo;
using ThinkGeo.MapSuite;
using ThinkGeo.MapSuite.Core;

namespace THKGEOShapeUnion
{
    public class ThkGeoShapeUnion
    {
        Collection<AreaBaseShape> _featuresQueueA = new Collection<AreaBaseShape>();
        Collection<AreaBaseShape> _featuresQueueB = new Collection<AreaBaseShape>();
        Collection<AreaBaseShape> _featuresQueueC = new Collection<AreaBaseShape>();
        Collection<AreaBaseShape> _featuresQueueD = new Collection<AreaBaseShape>();
        Collection<AreaBaseShape> _featuresQueueA2 = new Collection<AreaBaseShape>();
        Collection<AreaBaseShape> _featuresQueueB2 = new Collection<AreaBaseShape>();
        Collection<AreaBaseShape> _featuresQueueC2 = new Collection<AreaBaseShape>();
        Collection<AreaBaseShape> _featuresQueueD2 = new Collection<AreaBaseShape>();
        Collection<AreaBaseShape> _featuresQueueA3 = new Collection<AreaBaseShape>();
        Collection<AreaBaseShape> _featuresQueueB3 = new Collection<AreaBaseShape>();
        Collection<AreaBaseShape> _featuresQueueC3 = new Collection<AreaBaseShape>();
        Collection<AreaBaseShape> _featuresQueueD3 = new Collection<AreaBaseShape>();
        Collection<AreaBaseShape> _featuresQueueReWork = new Collection<AreaBaseShape>();
        ConcurrentQueue<AreaBaseShape> featuresQueueQ = new ConcurrentQueue<AreaBaseShape>();
        ConcurrentQueue<AreaBaseShape> featuresQueueR = new ConcurrentQueue<AreaBaseShape>();
        public MultipolygonShape ThkGeoShapeUnionStart(ConcurrentQueue<AreaBaseShape> featuresQueue)
        {
            featuresQueueQ = featuresQueue;

            while (featuresQueueQ.Count > 1)
            {
                _featuresQueueA.Clear(); _featuresQueueB.Clear(); _featuresQueueC.Clear(); _featuresQueueD.Clear();
                _featuresQueueA2.Clear(); _featuresQueueB2.Clear(); _featuresQueueC2.Clear(); _featuresQueueD2.Clear();
                _featuresQueueA3.Clear(); _featuresQueueB3.Clear(); _featuresQueueC3.Clear(); _featuresQueueD3.Clear();
                // phase 1
                while (featuresQueueQ.Count > 0)
                {
                    AreaBaseShape areaBaseShape;
                    #region unload queue
                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueA.Add(areaBaseShape);
                    }
                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueB.Add(areaBaseShape);
                    }
                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueC.Add(areaBaseShape);
                    }
                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueD.Add(areaBaseShape);
                    }

                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueA2.Add(areaBaseShape);
                    }
                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueB2.Add(areaBaseShape);
                    }
                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueC2.Add(areaBaseShape);
                    }
                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueD2.Add(areaBaseShape);
                    }

                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueA3.Add(areaBaseShape);
                    }
                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueB3.Add(areaBaseShape);
                    }
                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueC3.Add(areaBaseShape);
                    }
                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueD3.Add(areaBaseShape);
                    }
                    
                    #endregion
                }

                var TaskQA = Task.Factory.StartNew(QA);
                var TaskQB = Task.Factory.StartNew(QB);
                var TaskQC = Task.Factory.StartNew(QC);
                var TaskQD = Task.Factory.StartNew(QD);

                var TaskQA2 = Task.Factory.StartNew(QA2);
                var TaskQB2 = Task.Factory.StartNew(QB2);
                var TaskQC2 = Task.Factory.StartNew(QC2);
                var TaskQD2 = Task.Factory.StartNew(QD2);

                var TaskQA3 = Task.Factory.StartNew(QA3);
                var TaskQB3 = Task.Factory.StartNew(QB3);
                var TaskQC3 = Task.Factory.StartNew(QC3);
                var TaskQD3 = Task.Factory.StartNew(QD3);

                Task.WaitAll(new Task[] { TaskQA, TaskQB, TaskQC, TaskQD, TaskQA2, TaskQB2, TaskQC2, TaskQD2, TaskQA3, TaskQB3, TaskQC3, TaskQD3 });

                if (featuresQueueR.Count > 0)
                    featuresQueueQ = featuresQueueR;

                _featuresQueueA.Clear(); _featuresQueueB.Clear(); _featuresQueueC.Clear(); _featuresQueueD.Clear();
                _featuresQueueA2.Clear(); _featuresQueueB2.Clear(); _featuresQueueC2.Clear(); _featuresQueueD2.Clear();
                _featuresQueueA3.Clear(); _featuresQueueB3.Clear(); _featuresQueueC3.Clear(); _featuresQueueD3.Clear();
                // phase 2
                while (featuresQueueQ.Count > 0)
                {
                    AreaBaseShape areaBaseShape;
                    #region unload queue
                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueA.Add(areaBaseShape);
                    }
                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueB.Add(areaBaseShape);
                    }
                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueC.Add(areaBaseShape);
                    }
                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueD.Add(areaBaseShape);
                    }
                    #endregion
                }

                TaskQA = Task.Factory.StartNew(QA);
                TaskQB = Task.Factory.StartNew(QB);
                TaskQC = Task.Factory.StartNew(QC);
                TaskQD = Task.Factory.StartNew(QD);

                Task.WaitAll(new Task[] { TaskQA, TaskQB, TaskQC, TaskQD});

                if (featuresQueueR.Count > 0)
                    featuresQueueQ = featuresQueueR;

                _featuresQueueA.Clear(); _featuresQueueB.Clear(); _featuresQueueC.Clear(); _featuresQueueD.Clear();
                _featuresQueueA2.Clear(); _featuresQueueB2.Clear(); _featuresQueueC2.Clear(); _featuresQueueD2.Clear();
                _featuresQueueA3.Clear(); _featuresQueueB3.Clear(); _featuresQueueC3.Clear(); _featuresQueueD3.Clear();
                // phase 3
                while (featuresQueueQ.Count > 0)
                {
                    AreaBaseShape areaBaseShape;
                    #region unload queue
                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueA.Add(areaBaseShape);
                    }
                    if (featuresQueueQ.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueB.Add(areaBaseShape);
                    }
                    #endregion
                }

                TaskQA = Task.Factory.StartNew(QA);
                TaskQB = Task.Factory.StartNew(QB);

                Task.WaitAll(new Task[] { TaskQA, TaskQB});

                if (featuresQueueR.Count > 0)
                    featuresQueueQ = featuresQueueR;

                while (featuresQueueR.Count > 0)
                {
                    AreaBaseShape areaBaseShape;
                    if (featuresQueueR.TryDequeue(out areaBaseShape))
                    {
                        _featuresQueueReWork.Add(areaBaseShape);
                    }                   
                }
                break;
            }
            return (PolygonShape.Union(_featuresQueueReWork));
        }
        private bool featureInQueue(ConcurrentQueue<AreaBaseShape> featuresQueue)
        {
            bool rc = false;
            if (featuresQueue.Count > 0)
                rc = true;
            return (rc);
        }
        private void QA()
        {
            if (_featuresQueueA.Count > 0)
            {
                MultipolygonShape unionMultipolygonShape = PolygonShape.Union(_featuresQueueA);
                featuresQueueR.Enqueue(unionMultipolygonShape);
            }
        }
        private void QB()
        {
            if (_featuresQueueB.Count > 0)
            {
                MultipolygonShape unionMultipolygonShape = PolygonShape.Union(_featuresQueueB);
                featuresQueueR.Enqueue(unionMultipolygonShape);
            }
        }
        private void QC()
        {
            if (_featuresQueueC.Count > 0)
            {
                MultipolygonShape unionMultipolygonShape = PolygonShape.Union(_featuresQueueC);
                featuresQueueR.Enqueue(unionMultipolygonShape);
            }
        }
        private void QD()
        {
            if (_featuresQueueD.Count > 0)
            {
                MultipolygonShape unionMultipolygonShape = PolygonShape.Union(_featuresQueueD);
                featuresQueueR.Enqueue(unionMultipolygonShape);
            }
        }
        private void QA2()
        {
            if (_featuresQueueA2.Count > 0)
            {
                MultipolygonShape unionMultipolygonShape = PolygonShape.Union(_featuresQueueA2);
                featuresQueueR.Enqueue(unionMultipolygonShape);
            }
        }
        private void QB2()
        {
            if (_featuresQueueB2.Count > 0)
            {
                MultipolygonShape unionMultipolygonShape = PolygonShape.Union(_featuresQueueB2);
                featuresQueueR.Enqueue(unionMultipolygonShape);
            }
        }
        private void QC2()
        {
            if (_featuresQueueC2.Count > 0)
            {
                MultipolygonShape unionMultipolygonShape = PolygonShape.Union(_featuresQueueC2);
                featuresQueueR.Enqueue(unionMultipolygonShape);
            }
        }
        private void QD2()
        {
            if (_featuresQueueD2.Count > 0)
            {
                MultipolygonShape unionMultipolygonShape = PolygonShape.Union(_featuresQueueD2);
                featuresQueueR.Enqueue(unionMultipolygonShape);
            }
        }
        private void QA3()
        {
            if (_featuresQueueA3.Count > 0)
            {
                MultipolygonShape unionMultipolygonShape = PolygonShape.Union(_featuresQueueA3);
                featuresQueueR.Enqueue(unionMultipolygonShape);
            }
        }
        private void QB3()
        {
            if (_featuresQueueB3.Count > 0)
            {
                MultipolygonShape unionMultipolygonShape = PolygonShape.Union(_featuresQueueB3);
                featuresQueueR.Enqueue(unionMultipolygonShape);
            }
        }
        private void QC3()
        {
            if (_featuresQueueC3.Count > 0)
            {
                MultipolygonShape unionMultipolygonShape = PolygonShape.Union(_featuresQueueC3);
                featuresQueueR.Enqueue(unionMultipolygonShape);
            }
        }
        private void QD3()
        {
            if (_featuresQueueD3.Count > 0)
            {
                MultipolygonShape unionMultipolygonShape = PolygonShape.Union(_featuresQueueD3);
                featuresQueueR.Enqueue(unionMultipolygonShape);
            }
        }
    }
}



Hi, 
  
 A class to  boost union.   However, when the final two shapes are available for the last step (return) it is still taking a good amount of time to the union function… 
  
 jm

jm, 
  
 Thanks for your sharing. 
  
 James