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);
}
}
}
}
Some finding on how to boost shapes union using TPL
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