-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsimple_0.go
More file actions
130 lines (109 loc) · 2.62 KB
/
simple_0.go
File metadata and controls
130 lines (109 loc) · 2.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package constdp
import (
"github.com/TopoSimplify/constrain"
"github.com/TopoSimplify/hdb"
"github.com/TopoSimplify/node"
"github.com/intdxdt/geom"
"sync"
)
func findDeformableNodes(hulls []node.Node, hulldb *hdb.Hdb) map[*node.Node]struct{} {
return processConstSimplification(hulls, hulldb, ConcurProcs)
}
func processConstSimplification(nodeHulls []node.Node, db *hdb.Hdb, concurrency int) map[*node.Node]struct{} {
var wg sync.WaitGroup
var nodes = make([]*node.Node, len(nodeHulls))
for i := range nodeHulls {
nodes[i] = &nodeHulls[i]
}
var hulls = chunkTasks(nodes, concurrency)
wg.Add(len(hulls))
var out = make(chan *node.Node, 2*concurrency)
var fn = func(in []*node.Node) {
defer wg.Done()
var selections []*node.Node
for i := range in {
var bln = true
var hull = in[i]
var self = hull.Instance.(*ConstDP)
if hull.Range.Size() == 1 { //segment
continue
}
//if hull geometry is line then points are collinear
if _, ok := hull.Geom.(*geom.LineString); ok {
continue
}
// self intersection constraint
if self.Opts.AvoidNewSelfIntersects {
bln = constrain.ByFeatureClassIntersection(self.Opts, hull, db, &selections)
}
// short circuit, if invalid, skip context validation
if bln {
bln = self.ValidateContextRelation(hull, &selections)
}
for _, o := range selections {
out <- o
}
selections = selections[:0]
}
}
go func() {
for i := range hulls {
go fn(hulls[i])
}
}()
go func() {
wg.Wait()
close(out)
}()
var results = make(map[*node.Node]struct{})
for o := range out {
results[o] = struct{}{}
}
return results
}
func chunkTasks(vals []*node.Node, concurrency int) [][]*node.Node {
var n = len(vals)
var chunkSize = n / concurrency
if chunkSize == 0 {
chunkSize = 1
}
var idx = 0
var chunks = make([][]*node.Node, 0, concurrency+3)
for idx < n {
var stop = idx + chunkSize
//if stop > n || (stop < n && stop+chunkSize > n) {
if stop > n {
stop = n
}
var task []*node.Node
for _, o := range vals[idx:stop] {
task = append(task, o)
}
chunks = append(chunks, task)
idx = stop
}
return chunks
}
func chunkInstances(vals []*ConstDP, concurrency int) [][]*ConstDP {
var n = len(vals)
var chunkSize = n / concurrency
if chunkSize == 0 {
chunkSize = 1
}
var idx = 0
var chunks = make([][]*ConstDP, 0, concurrency+3)
for idx < n {
var stop = idx + chunkSize
//if stop > n || (stop < n && stop+chunkSize > n) {
if stop > n {
stop = n
}
var task []*ConstDP
for _, o := range vals[idx:stop] {
task = append(task, o)
}
chunks = append(chunks, task)
idx = stop
}
return chunks
}