├── icon.png
├── resources.qrc
├── CHANGELOG
├── metadata.txt
├── dialogs.py
├── __init__.py
├── matrix.py
├── generalizer.py
├── points.py
├── simplify.py
├── smooth.py
├── resources.py
├── ui_generalizer.ui
├── ui_generalizer.py
└── generalizerdialog.py
/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p0cisk/Generalizer/HEAD/icon.png
--------------------------------------------------------------------------------
/resources.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | icon.png
4 |
5 |
6 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | 0.5 (24.11.2013)
2 | -updated to QGIS 2.0 API (thanks to Matthew Petroff)
3 | -fix unicode error
4 |
5 | 0.4 (27.10.2013)
6 | -add setDecimal() method in batch mode. Added by Bakhtiar Hasmanan
7 |
8 | 0.3 (15.09.2011)
9 | -new algorithms:
10 | smoothing: Snakes Algorithm
11 | simplifying: Jenk's Algorithm, Reumann-Witkam Algorithm
12 |
13 | 0.2 (11.09.2011)
14 | -added batch mode
15 | -choose to save layer(s) on disk or to store in memory
16 | -new algorithms:
17 | smoothing: Hermite Spline Interpolation
18 |
19 | 0.1 (28.08.2011)
20 | -first release
21 | -supported algorithms:
22 | generalization: Remove small objects
23 | simplifying: Douglas-Peucker, Lang, Vertex Reduction
24 | smoothing: Boyle's Forward-Looking, Chaiken's, McMaster's Distance-Weighting, McMaster's Sliding Averaging
--------------------------------------------------------------------------------
/metadata.txt:
--------------------------------------------------------------------------------
1 | # This file contains metadata for your plugin. Beginning
2 | # with version 1.8 this is the preferred way to supply information about a
3 | # plugin. The current method of embedding metadata in __init__.py will
4 | # be supported until version 2.0
5 |
6 | # This file should be included when you package your plugin.
7 |
8 | # Mandatory items:
9 |
10 |
11 | [general]
12 | name=Generalizer
13 | qgisMinimumVersion=2.0
14 | description=Lines generalization and smoothing (partially based on v.generalize GRASS module)
15 | version=0.5
16 | author=Piotr Pociask
17 | email=
18 |
19 | # end of mandatory metadata
20 |
21 | # Optional items:
22 |
23 | homepage=https://github.com/p0cisk/Generalizer
24 | tracker=https://github.com/p0cisk/Generalizer/issues
25 | repository=https://github.com/p0cisk/Generalizer
26 | icon=icon.png
27 |
28 | # experimental flag
29 | experimental=True
30 |
31 | # deprecated flag (applies to the whole plugin, not just a single version
32 | deprecated=False
33 |
--------------------------------------------------------------------------------
/dialogs.py:
--------------------------------------------------------------------------------
1 | from PyQt4.QtGui import *
2 | from PyQt4.QtCore import *
3 |
4 | from os.path import splitext, dirname
5 |
6 | def saveDialog(parent):
7 | """Shows a save file dialog and return the selected file path."""
8 | settings = QSettings()
9 | key = '/UI/lastShapefileDir'
10 | outDir = settings.value(key)
11 |
12 | filter = 'Shapefiles (*.shp)'
13 | outFilePath = QFileDialog.getSaveFileName(parent, parent.tr('Save output shapefile'), outDir, filter)
14 | outFilePath = unicode(outFilePath)
15 |
16 | if outFilePath:
17 | root, ext = splitext(outFilePath)
18 | if ext.upper() != '.SHP':
19 | outFilePath = '%s.shp' % outFilePath
20 | outDir = dirname(outFilePath)
21 | settings.setValue(key, outDir)
22 |
23 | return outFilePath
24 |
25 | def openDir(parent):
26 | settings = QSettings()
27 | key = '/UI/lastShapefileDir'
28 | outDir = settings.value(key)
29 |
30 | outPath = QFileDialog.getExistingDirectory(parent, 'Generalizer', outDir)#, QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)
31 | return outPath
32 |
--------------------------------------------------------------------------------
/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | /***************************************************************************
3 | generalizer
4 | A QGIS plugin
5 | "Lines generalization and smoothing (partially based on v.generalize GRASS module)"
6 | -------------------
7 | begin : 2011-08-17
8 | copyright : (C) 2011 by Piotr Pociask
9 | email : ppociask (at) o2 pl
10 | ***************************************************************************/
11 |
12 | /***************************************************************************
13 | * *
14 | * This program is free software; you can redistribute it and/or modify *
15 | * it under the terms of the GNU General Public License as published by *
16 | * the Free Software Foundation; either version 2 of the License, or *
17 | * (at your option) any later version. *
18 | * *
19 | ***************************************************************************/
20 | This script initializes the plugin, making it known to QGIS.
21 | """
22 | def classFactory(iface):
23 | # load generalizer class from file generalizer
24 | from generalizer import generalizer
25 | return generalizer(iface)
26 |
--------------------------------------------------------------------------------
/matrix.py:
--------------------------------------------------------------------------------
1 | class MATRIX(object):
2 | def __init__(self, rows, cols):
3 | self.rows = rows
4 | self.cols = cols
5 | self.a = []
6 |
7 |
8 | i = 0
9 | while i n-1: break
36 | point_assign(points, j, p2)
37 | dst = point_dist(p1, p2)
38 | res.add_point(p2)
39 |
40 | i = j
41 |
42 |
43 | points.repleace_all_pts(res)
44 |
45 | return points.n_points
46 |
47 |
48 |
49 | def douglas_peucker(pts, tolerance):
50 | anchor = 0
51 | floater = len(pts) - 1
52 | stack = []
53 | keep = set()
54 |
55 | if len(pts) < 3: return pts
56 |
57 | stack.append((anchor, floater))
58 | while stack:
59 | anchor, floater = stack.pop()
60 |
61 | # initialize line segment
62 | if pts[floater] != pts[anchor]:
63 | anchorX = float(pts[floater][0] - pts[anchor][0])
64 | anchorY = float(pts[floater][1] - pts[anchor][1])
65 | seg_len = math.sqrt(anchorX ** 2 + anchorY ** 2)
66 | # get the unit vector
67 | anchorX /= seg_len
68 | anchorY /= seg_len
69 | else:
70 | anchorX = anchorY = seg_len = 0.0
71 |
72 | # inner loop:
73 | max_dist = 0.0
74 | farthest = anchor + 1
75 | for i in range(anchor + 1, floater):
76 | dist_to_seg = 0.0
77 | # compare to anchor
78 | vecX = float(pts[i][0] - pts[anchor][0])
79 | vecY = float(pts[i][1] - pts[anchor][1])
80 | seg_len = math.sqrt( vecX ** 2 + vecY ** 2 )
81 | # dot product:
82 | proj = vecX * anchorX + vecY * anchorY
83 | if proj < 0.0:
84 | dist_to_seg = seg_len
85 | else:
86 | # compare to floater
87 | vecX = float(pts[i][0] - pts[floater][0])
88 | vecY = float(pts[i][1] - pts[floater][1])
89 | seg_len = math.sqrt( vecX ** 2 + vecY ** 2 )
90 | # dot product:
91 | proj = vecX * (-anchorX) + vecY * (-anchorY)
92 | if proj < 0.0:
93 | dist_to_seg = seg_len
94 | else: # calculate perpendicular distance to line (pythagorean theorem):
95 | dist_to_seg = math.sqrt(abs(seg_len ** 2 - proj ** 2))
96 | if max_dist < dist_to_seg:
97 | max_dist = dist_to_seg
98 | farthest = i
99 |
100 | if max_dist <= tolerance: # use line segment
101 | keep.add(anchor)
102 | keep.add(floater)
103 | else:
104 | stack.append((anchor, farthest))
105 | stack.append((farthest, floater))
106 |
107 | keep = list(keep)
108 | keep.sort()
109 | return [pts[i] for i in keep]
110 |
111 |
112 | def lang(points, eps, look_ahead):
113 | i = 0
114 | j = look_ahead
115 | n = points.n_points
116 | if j > n-1: j = n-1
117 | p1 = point()
118 | p2 = point()
119 | p = point()
120 | res = line_pnts()
121 |
122 | point_assign(points, i, p1)
123 | point_assign(points, j, p2)
124 | res.add_point_xy(points.x[0], points.y[0])
125 | #point_add_new(points, 0, res) #use point_add insted of this function
126 |
127 | end = False
128 | while not end:
129 | dists = []
130 | between = True
131 |
132 | for m in range(i+1, j):
133 | point_assign(points, m, p)
134 | dists.append(point_distance(p1, p2, p))
135 |
136 | for dist in dists:
137 | if dist > eps:
138 | between = False
139 | break
140 |
141 | if not between:
142 | j = j - 1
143 | point_assign(points, j, p2)
144 | else:
145 | res.add_point_xy(points.x[j], points.y[j])
146 | #point_add_new(points, j, res) #use point_add insted of this function
147 | i = j
148 | if i == n-1:
149 | end = True
150 | j = j + look_ahead
151 | if j > n-1: j = n-1
152 | point_assign(points, i, p1)
153 | point_assign(points, j, p2)
154 |
155 | points.repleace_all_pts(res)
156 |
157 | return points.n_points
158 |
159 |
160 | def jenks(points, threshold, angle_thresh):
161 | n = points.n_points
162 | i = 1
163 | p = point()
164 | p1 = point()
165 | p2 = point()
166 | res = line_pnts()
167 |
168 | res.add_point_xy(points.x[0], points.y[0])
169 | #point_add_new(points, 0, res) #use point_add insted of this function
170 |
171 | point_assign(points, 0, p1)
172 | while i < n-1:
173 | point_assign(points, i, p)
174 | point_assign(points, i+1, p2)
175 |
176 | dist = point_distance(p1, p2, p)
177 | #angle = point_angle(p1, p, p2)
178 | #print i, angle
179 | if dist >= threshold:# and angle >= angle_thresh:
180 | i = i + 1
181 | res.add_point_xy(points.x[i-1], points.y[i-1])
182 | point_assign(points, i-1, p1)
183 | else:
184 | while dist < threshold:# or angle < angle_thresh:
185 | i = i+1
186 | if i == n-1: break
187 | point_assign(points, i, p)
188 | point_assign(points, i+1, p2)
189 | dist = point_distance(p1, p2, p)
190 | #angle = point_angle(p1, p, p2)
191 |
192 | res.add_point_xy(points.x[n-1], points.y[n-1])
193 |
194 | points.repleace_all_pts(res)
195 |
196 | return points.n_points
197 |
198 |
199 | def reumann_witkam(points, thresh):
200 | x0 = point()
201 | x1 = point()
202 | x2 = point()
203 | sub = point()
204 | diff = point()
205 | res = line_pnts()
206 | same = True
207 |
208 | n = points.n_points
209 |
210 | if n<3: return n
211 |
212 | thresh = thresh**2
213 |
214 | seg1 = 0
215 | seg2 = 1
216 | count = 1
217 |
218 | point_assign(points, 0, x1)
219 | res.add_point(x1)
220 | i = 1
221 | while same:
222 | point_assign(points, i, x2)
223 | same = compare_points(x1, x2)
224 | i = i+1
225 | if i == n: return n
226 | point_substract(x2, x1, sub)
227 | subd = point_dist2(sub)
228 |
229 | i = 2
230 | while i < n:
231 | point_assign(points, i, x0)
232 | point_substract(x1, x0, diff)
233 | diffd = point_dist2(diff)
234 | sp = point_dot(diff, sub)
235 | if subd == 0: dist = 0
236 | else: dist = (diffd * subd - sp*sp) / subd
237 |
238 | if dist > thresh:
239 | point_assign(points, i-1, x1)
240 | same = True
241 | j = i
242 | while same:
243 | point_assign(points, j, x2)
244 | same = compare_points(x2, x1)
245 | j = j+1
246 | point_substract(x2, x1, sub)
247 | subd = point_dist2(sub)
248 |
249 | res.add_point(x0)
250 |
251 | count = count + 1
252 |
253 | i = i+1
254 |
255 | res.add_point_xy(points.x[n-1], points.y[n-1])
256 |
257 |
258 | points.repleace_all_pts(res)
259 |
260 | return points.n_points
261 |
262 |
263 |
264 | """
265 | l = [[0,0], [1,1], [1,2], [2,3], [3,3], [4,2], [5,3], [4,5], [4,7], [6,9], [9,10]]
266 | #l = [[9,10], [6,9], [4,7], [4,5], [5,3], [4,2], [3,3], [2,3], [1,2], [1,1], [0,0]]
267 | #l = [(487532,653736), (487532,653736), (487608,653726), (487646,653736)]
268 | p = Vect_new_line_struct(l)
269 | reumann_witkam(p, 1)
270 | print l
271 | print 'X,Y'
272 | for i in range(len(p.x)):
273 | print p.x[i], ',', p.y[i]"""
--------------------------------------------------------------------------------
/smooth.py:
--------------------------------------------------------------------------------
1 | from PyQt4.QtGui import *
2 | from points import *
3 | from matrix import *
4 |
5 | GRASS_EPSILON = 1.0e-15
6 |
7 |
8 | def boyle(points, look_ahead):
9 | ppoint = point()
10 | npoint = point()
11 | last = point()
12 | next = 1
13 | i = 0
14 | p = 0
15 | c1 = 0.
16 | c2 = 0.
17 |
18 | n = points.n_points
19 |
20 | if look_ahead < 2 or look_ahead > n: return n
21 |
22 | point_assign(points, 0, last)
23 |
24 | c1 = 1. / float(look_ahead-1)
25 | c2 = 1. - c1
26 |
27 | while i < n-2:
28 | p = i + look_ahead
29 | if p >= n: p = n - 1
30 | point_assign(points, p, ppoint)
31 | point_scalar(ppoint, c1, ppoint)
32 | point_scalar(last, c2, last)
33 | points_add(last, ppoint, npoint)
34 | points.repleace_point(next, npoint)
35 |
36 | next = next + 1
37 | i = i + 1
38 |
39 | last = npoint
40 |
41 | points_copy_last(points, next)
42 |
43 | return points.n_points
44 |
45 | def sliding_averaging(points, slide, look_ahead):
46 | n = 0
47 | half = 0
48 | i = 1
49 | sc = 0.
50 | p = point()
51 | tmp = point()
52 | s = point()
53 |
54 | n = points.n_points
55 | res = []
56 | for w in range(n):
57 | res.append(point())
58 |
59 | half = look_ahead / 2
60 |
61 | if look_ahead % 2 == 0:
62 | return n
63 |
64 | if look_ahead >= n or look_ahead == 1:
65 | return 0
66 |
67 | sc = 1. / float(look_ahead)
68 |
69 | point_assign(points, 0, p)
70 | while i < look_ahead:
71 | point_assign(points, i, tmp)
72 | points_add(p, tmp, p)
73 | i = i + 1
74 |
75 | i = half
76 | while i+half < n:
77 | point_assign(points, i, s)
78 | point_scalar(s, 1. - slide, s)
79 | point_scalar(p, sc*slide, tmp)
80 | points_add(tmp, s, res[i])
81 | if i+half+1 < n:
82 | point_assign(points, i-half, tmp)
83 | point_substract(p, tmp, p)
84 | point_assign(points, i+half+1, tmp)
85 | points_add(p, tmp, p)
86 | i = i + 1
87 |
88 | i = half
89 | while i+half < n:
90 | points.repleace_point(i, res[i])
91 |
92 | i = i + 1
93 |
94 | return points.n_points
95 |
96 | def distance_weighting(points, slide, look_ahead):
97 | p = point()
98 | c = point()
99 | s = point()
100 | tmp = point()
101 |
102 | n = 0
103 | i = 0
104 | half = 0
105 | j = 0
106 |
107 | dists = 0.
108 | d = 0.
109 |
110 | n = points.n_points
111 |
112 | res = []
113 | for w in range(n):
114 | res.append(point())
115 |
116 | if look_ahead % 2 == 0:
117 | return n
118 |
119 | point_assign(points, 0, res[0])
120 |
121 | half = look_ahead / 2
122 |
123 | i = half
124 | while i+half < n:
125 | point_assign(points, i, c)
126 | s.x = 0.
127 | s.y = 0.
128 | dists = 0.
129 |
130 | j = i-half
131 | while j <= i+half:
132 | if j == i:
133 | j = j + 1
134 | continue
135 |
136 | point_assign(points, j, p)
137 | d = point_dist(p, c)
138 |
139 | if d < GRASS_EPSILON:
140 |
141 | j = j + 1
142 | continue
143 |
144 | d = 1. / d
145 | dists = dists + d
146 | point_scalar(p, d, tmp)
147 | s.x = s.x + tmp.x
148 | s.y = s.y + tmp.y
149 | j = j + 1
150 |
151 | if dists == 0:
152 | point_scalar(s, slide, tmp)
153 | else:
154 | point_scalar(s, slide/dists, tmp)
155 | point_scalar(c, 1.-slide, s)
156 | points_add(s, tmp, res[i])
157 | i = i + 1
158 |
159 | i = half
160 | while i+half < n:
161 | points.repleace_point(i, res[i])
162 |
163 | i = i + 1
164 |
165 | return points.n_points
166 |
167 |
168 | def chaiken(points, level, weight):
169 | n = 0
170 | i = 0
171 | j = 0
172 | p0 = point()
173 | pn = point()
174 | p1 = point()
175 | p2 = point()
176 | m1 = point()
177 | m2 = point()
178 | res = line_pnts()
179 |
180 | n = points.n_points
181 |
182 | if n < 3: return n
183 |
184 | d1 = 1./(1+weight)
185 | d2 = float(weight)/(1+weight)
186 |
187 | point_assign(points, 0, p0)
188 | point_assign(points, n-1, pn)
189 |
190 | tmp = line_pnts(points)
191 |
192 | for i in range(level):
193 | cut_edges(tmp, res, d1, d2)
194 |
195 | res.n_points = len(res.x)
196 | tmp = line_pnts(res)
197 |
198 | res = line_pnts()
199 |
200 |
201 | tmp.insert_point(0, p0)
202 | tmp.add_point(pn)
203 |
204 | points.repleace_all_pts(tmp)
205 |
206 | return points.n_points
207 |
208 |
209 | def point_calc_new(p1, p2, d, m):
210 | m.x = (p1.x+d*(p2.x-p1.x))
211 | m.y = (p1.y+d*(p2.y-p1.y))
212 |
213 |
214 | def cut_edges(points, res, d1, d2):
215 | p1 = point()
216 | p2 = point()
217 | m1 = point()
218 | m2 = point()
219 |
220 | for i in range(points.n_points):
221 | if i == points.n_points-1: break
222 | point_assign(points, i, p1)
223 | point_assign(points, i+1, p2)
224 |
225 | point_calc_new(p1, p2, d1, m1)
226 | point_calc_new(p1, p2, d2, m2)
227 |
228 | res.add_point(m1)
229 | res.add_point(m2)
230 |
231 |
232 | def hermite(points, threshold, a):
233 | i = 1
234 | p1 = point()
235 | p2 = point()
236 | t1 = point()
237 | t2 = point()
238 | h1p1 = point()
239 | h2p2 = point()
240 | h3t1 = point()
241 | h4t2 = point()
242 | tmp1 = point()
243 | tmp2 = point()
244 | tmp = point()
245 |
246 | res = line_pnts()
247 |
248 |
249 | point_assign(points, 1, p1)
250 | point_assign(points, 0, p2)
251 | t1 = getEdgeTangent(p1, p2)
252 | points.insert_point(0, t1)
253 |
254 | point_assign(points, -2, p1)
255 | point_assign(points, -1, p2)
256 | t2 = getEdgeTangent(p1, p2)
257 | points.insert_point(points.n_points, t1)
258 |
259 | n = points.n_points
260 |
261 | if n < 3:
262 | return n
263 |
264 | h1 = lambda s: (2*(s**3))-(3*(s**2))+1
265 | h2 = lambda s: 3*(s**2)-2*(s**3)
266 | h3 = lambda s: (s**3)-(2*(s**2))+s
267 | h4 = lambda s: (s**3)-(s**2)
268 | ht = lambda s: (1+2*s)*(1-s)**2
269 |
270 | while i < n-2:
271 | point_assign(points, i, p1)
272 | point_assign(points, i+1, p2)
273 |
274 | dist = point_dist(p1, p2)
275 | #t = 0.
276 | if dist == 0 or dist= 0 and index <=4:
377 | g.a[i][j] = val[index]
378 | else:
379 | g.a[i][j] = 0
380 | j = j +1
381 |
382 | i = i+1
383 |
384 | i = 0
385 | while i < g.rows:
386 | g.a[i][i]= g.a[i][i] + 1.
387 | i = i+1
388 |
389 | print 2
390 | ginv = matrix_inverse(g)
391 | print 3
392 |
393 | xout = matrix_mult(ginv, xcoord)
394 | yout = matrix_mult(ginv, ycoord)
395 |
396 | print 4
397 |
398 | i = 1
399 | while i < n-1:
400 | points.x[i] = xout.a[i+plus][0] + x0
401 | points.y[i] = yout.a[i+plus][0] + y0
402 |
403 | i = i+1
404 |
405 | points.n_points = len(points.x)
406 | return points.n_points
407 |
408 | """
409 | l = [[0,0], [1,1], [1,2], [2,3], [3,3], [4,2], [5,3], [4,5], [4,7], [6,9], [9,10]]
410 | p = Vect_new_line_struct(l)
411 | pi = hermite(p, 1, 0.3)
412 | print l
413 | print 'X;Y'
414 | for i in range(len(p.x)):
415 | print p.x[i], ';', p.y[i]"""
--------------------------------------------------------------------------------
/resources.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # Resource object code
4 | #
5 | # Created: N 28. sie 10:51:26 2011
6 | # by: The Resource Compiler for PyQt (Qt v4.7.1)
7 | #
8 | # WARNING! All changes made in this file will be lost!
9 |
10 | from PyQt4 import QtCore
11 |
12 | qt_resource_data = "\
13 | \x00\x00\x17\xc5\
14 | \x89\
15 | \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
16 | \x00\x00\x40\x00\x00\x00\x40\x08\x06\x00\x00\x00\xaa\x69\x71\xde\
17 | \x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
18 | \x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\
19 | \x01\x42\x28\x9b\x78\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\
20 | \x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\
21 | \x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x17\x42\x49\x44\
22 | \x41\x54\x78\x9c\xed\x9b\x5b\x6c\x5d\xd7\x9d\xde\x7f\xdf\xda\xfb\
23 | \x5c\x78\x48\xf1\x4e\x91\x12\x69\x49\xb6\x25\xcb\x36\x6d\xc7\x36\
24 | \xed\xf8\x96\xd8\x72\x9a\x66\xea\x41\x9b\x5e\x50\x69\x8a\x4e\xd1\
25 | \x87\x00\x35\x50\x14\x19\xa0\x83\xe9\xbc\x8a\x7c\x9d\x87\x0e\xd0\
26 | \x3c\x65\x80\x62\xda\x87\xbe\x48\x40\x81\xa6\xd3\x64\x92\x60\x12\
27 | \x66\x9a\x9b\xe3\xc8\x76\xe2\x50\x96\x2d\x59\x17\x8b\xa4\x28\x91\
28 | \xa2\xc4\x8b\x78\x6e\x7b\xaf\xaf\x0f\xe7\x50\x17\x5b\x96\x25\xc5\
29 | \x99\x04\x98\xfe\x81\x03\xf0\x90\xe7\xec\xf5\x5f\xdf\xfa\xfe\xf7\
30 | \x45\xd9\xe6\xef\xb3\x84\xdf\xb6\x02\xbf\x6d\xf9\xff\x00\xfc\xb6\
31 | \x15\xf8\x6d\xcb\xdf\x7b\x00\xd2\xdb\xf9\x90\x84\x00\x6c\x7e\x27\
32 | \x3c\x66\x5b\x9f\xcd\x97\x41\xf6\x5d\x7a\x73\xdd\xea\x7b\x12\x7a\
33 | \xf5\xd5\x23\x29\x9c\x2b\x74\x76\x0e\xf8\xca\x95\x62\xb6\x7d\xfb\
34 | \x5f\xe5\x93\x93\x93\x77\xbd\xe0\xaf\x2b\x12\x9a\x98\x20\x5d\x5c\
35 | \xfc\xa0\x4b\xaa\x94\xed\x8d\xda\xd0\xd0\x8e\xf5\x23\x47\xc8\xee\
36 | \xe6\x80\x6e\x09\xc0\xd4\xd4\x74\x3a\x3b\xdb\x31\x10\x42\x63\x34\
37 | \x0f\xa4\x49\x4c\x2e\xe6\xf9\xda\xa5\x4a\xe5\xfe\x2b\x0b\x0b\x6f\
38 | \x66\x87\x0f\xef\x8f\x7f\x97\xac\x90\xd0\xee\xdd\x14\xab\xd5\xe5\
39 | \x21\xf0\x03\x0e\x61\x6b\xb0\x16\x6a\xca\xde\x5b\x3a\x7b\x61\x09\
40 | \x1e\x6e\xde\xa9\x3e\x1f\x0b\x80\x84\xbe\xf2\x95\x6f\x74\x25\x49\
41 | \xef\xa3\x04\xbe\x60\x6b\x20\x5a\x67\x9d\xf1\x9e\x1d\xcf\xd4\xeb\
42 | \xa5\x0b\x5b\xb6\xa4\x6b\xef\x6d\x5f\x6b\x4c\x4f\xee\xcb\x7f\xd3\
43 | \x40\x48\x68\xd7\xae\xd3\x25\x28\x8f\xd8\x85\x27\x73\xf3\x12\xd6\
44 | \x3d\x79\xe4\x94\x89\xdf\xcb\xea\xbc\xb1\xb4\x34\xb8\x04\x77\xc6\
45 | \x84\x8f\x05\xe0\xc0\x81\xc3\xc9\xf0\x70\xef\x70\xb3\x59\xfa\x62\
46 | \x84\x3f\x88\xd6\xfd\x8e\x61\xd5\x91\x53\x46\xef\xc4\x2c\xbc\x93\
47 | \xe1\x53\xb1\x91\x9e\xdb\xa8\x34\x2e\x8f\xa4\xe5\xda\x6f\xca\x3c\
48 | \x5a\x9b\xa7\x14\x8b\x17\xb6\x87\x3c\x7c\xd6\xb9\xbf\x14\xa3\x9e\
49 | \xc9\xad\x7e\xa2\x16\x72\xf8\x81\x23\xdf\x22\x2f\xbd\x75\xe1\xc2\
50 | \xb1\x65\x78\x2a\xbb\x5d\x1d\x3e\xd6\x09\x8e\x8c\x74\xa5\xb5\x98\
51 | \xf6\x49\xdc\x2b\x73\x8f\x60\xcc\x20\xa3\x9d\xd1\x7a\xd8\xf0\x01\
52 | \xd6\xbb\x4a\x7d\xb4\x54\x2d\x1e\x5f\x89\xcc\xce\xad\xff\x83\xe5\
53 | \x57\x5e\xf9\xc3\x8d\xa9\x29\x9a\x93\x93\xf8\xd3\x62\xc5\xbe\x7d\
54 | \x24\xf3\xf3\xb3\x03\xcd\x58\x7a\xd2\xf6\xef\x21\x9e\x47\x8c\x2a\
55 | \x52\x8a\xa2\xa2\xa8\x68\x87\x46\xae\x2c\x1b\x19\xd9\xfb\xcb\x85\
56 | \x05\x5f\x02\xb2\xdb\x79\xf6\x4d\xc3\xa0\x24\xe5\x79\x47\x21\x8d\
57 | \x0c\x02\x3b\xc0\xfd\x12\x25\x70\x07\x30\x80\xbd\xc7\xf0\x9c\xac\
58 | \x7f\x62\xeb\x0f\x05\xff\x26\xb3\xbf\xdc\xd1\xe8\x7c\xb6\x52\xb9\
59 | \xb2\xfb\xc8\xbb\xef\xf5\xef\xdb\x37\x5d\x9a\x9a\xfa\x74\xc2\xec\
60 | \xec\xec\x89\x24\xc6\xb4\x47\xb0\x1b\xf1\x20\x30\x02\x74\x20\x52\
61 | \x4c\xa7\xe1\x3e\xf0\x4b\xc0\x17\xb2\x2c\x7b\x78\x74\x74\xad\x47\
62 | \x9a\xbe\xad\x08\x77\xd3\x0f\xed\xdf\x7f\x28\xc4\x58\xac\x84\x90\
63 | \x8d\x08\x46\x8d\xba\x1c\x49\x68\x85\x9d\x04\x42\x00\x15\x0c\x5d\
64 | \xc2\xc3\xb2\xee\x17\x3c\x16\xf1\x49\x94\x1d\x4d\xaa\x1b\x6f\x77\
65 | \x76\x76\xbf\xfb\xd6\x5b\x6f\x9d\x7b\xf9\xe5\xc7\xd7\xa7\xa7\xf9\
66 | \xb5\x7c\x44\x4f\xcf\x4a\xbc\x78\xb1\x6b\x23\x84\x78\x41\x84\x45\
67 | \xc3\x06\xd0\x01\x6a\xe9\x63\xb6\x18\xf6\x60\x65\x11\x35\xab\x55\
68 | \x9a\x3d\x3b\x9e\x78\x47\x62\xd5\x26\xbf\x63\x00\xfa\xfa\xee\x0b\
69 | \x79\x72\xb9\x57\xa4\x3b\x40\x43\x98\x52\x7b\xf3\x6d\x71\x3b\x06\
70 | \x2b\xd8\xa4\x86\x16\x33\xe4\x9d\x31\x0f\x0f\x45\x78\x24\x84\xf0\
71 | \x7a\x9e\xfb\xf5\xee\xee\x77\x8f\xef\xdb\x57\x5a\x96\x76\x35\x6c\
72 | \xe2\xdd\x00\x70\xe4\xc8\x44\x36\x3e\xbe\xb8\x74\xe5\x0a\x6f\x48\
73 | \xea\x03\x2a\xc6\x8f\x81\xfb\x40\x69\x0b\x04\x6d\x01\xf6\x1a\x65\
74 | \x88\x86\xaf\x14\xb3\xde\xde\xcb\xef\x49\xbd\x6b\xb7\x02\xe1\x23\
75 | \x14\x95\x24\xa0\x10\x48\x07\xc0\x3b\xb1\xfb\x3f\x04\x94\x41\xb1\
76 | \xf5\xc2\x6d\x60\x52\xa0\x03\x33\x08\x3c\x80\xfd\xa2\xc5\x3f\x37\
77 | \xe1\x5f\x34\x63\xed\xf3\x1d\x1d\x97\xee\xfb\xe2\x17\x8f\x6c\x79\
78 | \xf9\xe5\xe9\x74\x33\xa9\xba\x13\xb1\xf1\xcc\xcc\x74\x35\x84\xf4\
79 | \x94\xa4\xbf\x8d\xd1\xdf\x13\x3a\x0a\xac\x80\xda\xb6\xee\x14\xd3\
80 | \x03\x3c\x64\x87\x2f\x28\x66\x2f\xd9\xc5\xfb\xfa\xfb\xe9\x94\x3e\
81 | \xde\x14\x3f\xc2\x80\xc9\xc9\x49\xad\xac\x34\xca\xb5\x9a\x87\x15\
82 | \x18\x03\xba\x41\x9b\x0f\x30\xb8\x01\xae\xba\xc5\x80\x22\x50\x80\
83 | \xeb\xcd\x83\x32\x52\x01\xab\x12\xcd\x00\x0e\xdb\xad\x30\x9a\x24\
84 | \x7e\xbd\x9e\x0c\x9f\xd8\xb7\xef\xf4\xa5\xbb\x61\x83\xbd\x3f\x97\
85 | \x58\xdf\xb1\x63\xe5\x44\x50\xbd\x90\x5b\x05\xa3\x14\xfc\x30\xa8\
86 | \xbb\xbd\x76\x82\xd5\x6b\xfc\x88\x63\xc8\xb0\x1a\xf5\xfa\x95\x1c\
87 | \xaa\x27\xa5\xc1\x2b\x37\x5b\xf3\x26\x26\xf0\x52\xb0\xeb\xdd\x4a\
88 | \x19\xb3\x19\x96\x28\xdb\x0e\x6d\x0b\xc8\x8c\x17\x11\xef\x83\x6a\
89 | \x88\x41\x60\x18\xdc\x0b\x2a\xb5\x9f\x27\x20\x95\xd4\x05\xda\x69\
90 | \xd3\xed\xa8\x91\xdc\x8c\x15\xf1\x8f\x63\xb9\xfe\xf6\x2b\xaf\x9c\
91 | \x38\xf7\xf2\xcb\xb3\x1b\xd3\xd3\x77\x96\x3f\xd8\xe4\x52\xcf\xea\
92 | \xe8\xe8\xdc\xbb\x21\x14\x53\x47\x15\x8c\x53\xc3\x5e\xd0\x16\x70\
93 | \xd2\x62\x82\xfa\x11\x8f\xd9\x31\x93\xd4\xec\xea\xea\xce\xd6\xd7\
94 | \x39\x2d\x51\xfd\x30\x08\x1f\x01\x60\x66\x66\xb1\x30\x38\xd8\x33\
95 | \xa0\xa4\xb8\x13\x34\x40\xeb\x84\xa1\x45\xf7\x9a\xa4\x93\x96\xbf\
96 | \x45\xce\x9c\x1d\xb7\xe1\xe4\x41\xa3\x3d\x46\xf7\x00\x03\xb4\xfc\
97 | \x41\xd2\x02\x8d\x12\x68\xc8\x50\x81\x30\x00\xda\xee\x66\x1c\xad\
98 | \xdb\xaf\xc3\xd6\x93\xaf\xbc\x72\xe2\x92\xf4\x3f\x9a\xf6\xc1\xdb\
99 | \x66\x43\x0b\x84\xd1\x95\x91\x91\x85\x77\x9c\x84\x54\x56\x51\x28\
100 | \xb5\xbd\x07\xd4\x45\xcb\xac\x53\xcc\x80\x1d\x3e\x03\x34\x63\x8c\
101 | \xcd\x62\xb1\x91\x37\x1a\xc5\x0f\xa4\xa9\xda\xf5\xeb\xdd\x00\x40\
102 | \x2b\xf7\xef\x2b\xaa\xa0\x21\xcc\x3d\x32\x3d\x6e\xfb\x09\x89\x1c\
103 | \xb1\x2a\xf4\x7e\xc0\x6f\x34\x92\x70\xcc\xf5\x66\x87\x93\xf0\x73\
104 | \xe5\xc9\x5e\xe1\xc7\x23\xe1\x31\xc1\xbd\x40\x9f\xa4\xc2\xa6\x32\
105 | \x12\x5b\x80\x7b\xb1\x7b\xa4\x30\x92\xa3\x51\x2b\xfc\x74\x6d\x2d\
106 | \xfb\xd5\x0b\x2f\xfc\x87\x73\x2f\xbf\x3c\x5d\xbd\x13\x36\xd8\x64\
107 | \xd2\xdc\xe5\xe1\xe1\xbd\xbf\x8a\x49\x23\x15\xb1\x00\x21\x05\xdd\
108 | \x07\x74\xb6\xd7\x2d\x00\x43\xd1\x3c\x69\x9c\x85\x10\x9b\xa5\x52\
109 | \x3d\xaf\xd7\x0f\xce\x4a\xd4\x36\xd7\xba\x01\x80\x7d\xfb\xa6\x93\
110 | \x52\x29\xdd\x62\x31\x1a\xa3\xb7\xd1\x3a\xb9\xd0\x3e\xff\x5c\xe6\
111 | \x92\xed\xd3\x39\xcd\x73\x65\x8f\x2e\x5e\x89\xaf\xc7\x62\xba\x63\
112 | \x21\x0f\xcd\x53\xce\x8b\xef\x39\xc6\x93\x26\x7d\x16\x34\x6e\x7b\
113 | \x1b\xa8\xcd\x06\x02\x50\x32\xde\x6a\xbb\x42\x64\xd0\x84\x31\x8b\
114 | \xed\x8e\x97\x8f\x54\xab\x83\x27\x77\xef\x3e\x71\xf9\xce\xd8\x30\
115 | \x91\x9d\x3f\xcf\xa5\xc1\xc1\xa5\xb7\x49\x93\x82\x50\xd1\xa6\x00\
116 | \xda\x45\x8b\x85\x02\x17\x21\x6c\xb5\x99\x00\x9a\xb6\x9a\x94\xeb\
117 | \x39\xb5\xd2\xbc\x44\xdd\xc6\x37\x00\xf0\xe8\xa3\xd5\xc4\x69\xa1\
118 | \x8f\x3c\xd9\x29\x31\xd8\x7a\xa0\x05\xb2\xa1\x81\x58\x94\xf4\x41\
119 | \x21\x2f\x2c\x9f\x3c\xfd\xdf\xb3\xef\x7f\xff\x60\x26\xd1\x7c\xf5\
120 | \xd5\x23\xd5\xb9\xf5\x8d\x95\x72\xdc\x72\x3e\x27\x9e\x35\x9a\xc3\
121 | \x9a\x68\x9f\x48\xef\x35\x36\x28\x95\xd4\x1d\x51\x49\x76\x2f\xd2\
122 | \x48\x0c\x8c\x41\xf9\x27\x43\x43\x9a\x49\x86\xff\xd5\xf9\x03\x07\
123 | \xd8\x38\x7c\x58\xf1\x93\x52\x59\x1b\x4b\x64\x5d\x5d\xeb\x97\xaa\
124 | \xd5\x8e\xa3\x79\x2c\xf6\xa2\x74\x08\xd3\xdb\x76\xce\x6d\x7f\xe4\
125 | \x12\x68\x9b\xad\xa7\x0d\xcd\x24\xaa\x99\x53\x7b\x0d\xca\x0b\x12\
126 | \x8d\xab\x00\x48\xe8\x2b\x7f\xda\x5d\xec\xca\xb2\xc1\x18\xe2\x0e\
127 | \x22\xbd\xf6\x55\x86\x44\xf0\x86\x61\x81\x3c\x9b\xaf\xd7\x4b\xeb\
128 | \xd3\xd3\x07\xf3\x4d\x45\x60\xa2\x39\x35\xc5\xca\xcc\xcc\x4f\x6a\
129 | \x81\xca\xe5\x7a\x93\x05\xe3\x59\xcc\x73\x58\xe3\xb6\x87\x37\xd9\
130 | \xd4\x66\x43\xd9\x66\x18\x87\x8a\xd0\x20\x78\x34\xb3\xb6\x6f\x89\
131 | \xc5\x23\x27\x16\x16\x4e\x8d\x8f\xcf\xac\x48\x7c\x6c\x65\xd7\x0a\
132 | \xd5\xd6\xee\xdd\x14\xaa\xd5\x42\x27\x14\x3b\x5b\x24\xa5\x8a\xdd\
133 | \x68\xfd\x78\x35\xda\xaa\xc5\x3e\xb6\x83\x9e\xc1\xb1\x99\x24\x85\
134 | \x66\x9e\xf3\x3a\x70\xe1\x2a\x00\xfb\xf7\x1f\x0e\x5b\xea\xfd\x95\
135 | \x28\xb6\x63\x6d\xbf\xce\xa1\x00\xca\x11\x97\x65\x7d\x80\xbc\x58\
136 | \x28\x54\x1b\x1f\x56\xee\xe0\x41\xa2\xf4\x5c\x6d\xdf\x24\xe7\x3b\
137 | \x5f\x7f\x7b\xc3\x66\x29\x2a\xce\xa1\x30\xe7\xa8\x09\xe0\x5e\x70\
138 | \xaf\x14\xd2\x4d\x36\x80\x7b\x30\x65\xa3\x5e\xf0\x36\x72\x8d\x29\
139 | \x6f\xfc\xa4\x52\xe9\x3a\x3a\x3e\xbe\x78\xe1\xc0\x81\xa1\xea\x87\
140 | \xd9\x20\x11\x76\xef\x3e\x5e\xa8\xd5\x56\x3b\xd7\x1b\xd9\x88\x29\
141 | \xdd\x67\xf1\x10\x41\x8f\x06\xfb\x91\x28\xf5\x62\x7d\x38\xee\xab\
142 | \x05\xba\xc7\x44\x78\xc6\xc4\x8d\x34\xf5\x95\x2c\x4b\x6b\xd7\x4c\
143 | \x60\x9c\x24\x5f\xcb\xfb\x92\x98\xde\x93\xb7\xb2\xbf\xa2\x5a\xc5\
144 | \x8f\xc1\x19\xe6\xa2\xc4\x19\x93\x2d\xef\xda\x15\x6e\x5a\x68\xb4\
145 | \x41\xc9\xa6\xa6\x1e\x5d\x99\x99\x99\xad\xad\xac\x5c\xbe\xec\x10\
146 | \xcf\x41\x98\x33\x7a\x16\xf3\x70\x8b\x0d\xea\x68\xe7\x16\x01\x28\
147 | \x63\x46\x84\xba\xa2\x19\x74\x8c\xa3\x4d\x87\x1f\xab\x58\x7b\xe3\
148 | \xe4\xc9\x73\xa7\xc7\xc7\x67\x56\xa5\x56\x61\x33\x3e\x7e\x34\xdd\
149 | \xb5\x6b\x7b\x25\xcf\x7b\x87\x49\xf2\xfb\x13\xfb\x33\x39\xc9\x63\
150 | \x48\xbb\x05\xdb\xdc\x0a\xc7\xe5\x56\x38\xbc\x21\xdf\x72\xfb\x15\
151 | \x0c\xdd\x48\x3b\xec\x6c\x07\x64\xc7\xd3\x4d\x4a\xfd\xc9\x9f\x7c\
152 | \xbb\x90\xe5\x85\x81\x9c\xb8\x4b\xa6\x1f\x94\xfa\xea\x97\x5d\x95\
153 | \x74\x3e\xa2\xd9\x6a\xb1\xb8\x0a\x7f\x13\x61\xdf\xcd\x30\xb8\x8e\
154 | \x0d\x63\xb5\x89\x89\xf3\x0b\x23\x23\xc5\xf5\x5a\x5e\x58\x14\x71\
155 | \x36\xca\xcf\x63\x9e\xc4\xec\x32\xee\x01\x15\xda\xa7\x53\x70\x2b\
156 | \x8b\xdb\x23\xe8\x8b\xb0\x4d\x91\xb1\x46\xd6\xf8\x69\x96\x74\xbe\
157 | \x73\xdf\x7d\x27\x97\x63\x77\xbf\xea\xeb\x83\x03\x52\xe3\xbe\x48\
158 | \x78\x0c\xe2\x13\x36\x0f\x4a\x1e\x35\xee\x41\x49\x01\x6b\x33\x21\
159 | \xdb\x94\x08\xe4\x40\x43\x62\x15\x58\xc4\x3a\x25\xe2\xdb\x46\x73\
160 | \x90\x55\x53\x68\x65\x7f\x6b\x6b\x8d\x0e\x92\xc2\x70\x30\xa3\x31\
161 | \x67\xcb\x35\xfa\x6f\x86\x3f\xce\xc6\xc8\x85\xae\xfc\x72\xfd\xe0\
162 | \xc1\x4f\xf6\xd4\xd7\xfb\x86\x23\x47\x8e\xd4\xab\xd5\x8e\xcb\xd1\
163 | \x3a\x27\x6b\x16\xf1\x1c\xd6\x83\xc0\x56\x5a\x45\xcd\x26\x1b\x3a\
164 | \x0c\xdb\x84\x3a\xc1\x43\x26\x19\x4d\xad\xd7\x5c\x2a\x9c\xcc\x37\
165 | \x6a\x05\x4b\x7b\x2c\x1e\xc7\x3c\x2c\x7c\x8f\x50\xaf\x4d\xa9\xf5\
166 | \x7d\xab\xbd\x77\xb7\x37\x9e\x81\xab\x48\xcb\xe0\x73\x26\x9c\x44\
167 | \xbc\x8b\xe2\xbb\xb2\x4e\x65\x59\x71\x1e\x4a\x97\x53\x80\xf9\xf9\
168 | \x6d\x49\x67\x7f\x47\xb7\x9a\xf1\x9e\x68\x6d\x45\x94\xdb\xce\x0a\
169 | \x20\x93\x75\x31\x3a\x9c\x09\x79\x76\x91\x64\x5b\xf3\x93\x36\xff\
170 | \x51\x36\x4c\x54\x27\x26\x8e\x9c\x1b\x1c\xec\x58\xaf\xd7\xf3\x45\
171 | \x53\x98\x05\x3d\x0f\x7e\xd2\xb0\x13\xdc\x7d\x8d\x0d\x2a\x00\xbd\
172 | \x10\xca\x96\xfa\x9c\x7b\x57\x20\xcc\x3a\x50\x8c\x19\x3b\xa4\x70\
173 | \x4f\x8c\xee\x87\x50\xe2\x5a\x0a\xbe\xb9\xf1\x1c\xdc\x40\x5a\x97\
174 | \xb8\x20\xe9\xac\x22\xc7\x83\x7c\x0c\x87\xe3\x10\xe7\x1a\x8d\xc6\
175 | \x52\x4e\xd7\x3a\xd0\x04\xf2\x14\xa0\xb3\xb3\x2f\x0d\xcd\xe6\x40\
176 | \x24\xdd\x29\x31\x60\x2b\x6d\x3f\xd1\x92\xeb\x51\x2c\x2a\xe6\x67\
177 | \x63\x4c\x56\x56\x57\x4f\x46\x98\xb8\x13\x0c\xae\xb2\xe1\xc0\x81\
178 | \xc3\x2b\x2b\x2b\x7b\x8f\x67\x99\x2e\x35\x9b\x3a\x17\x1d\xe6\x20\
179 | \x3c\x03\x3c\x04\x1a\x6a\xd9\x2f\x89\xed\x04\xa8\x60\x8f\x5a\xea\
180 | \x33\xf1\x21\x48\x02\xa2\x53\x76\x59\x52\x62\xdf\x70\xe2\x39\x50\
181 | \x45\xbe\x04\x3a\x87\x39\x65\x74\xcc\xc4\x77\x93\x24\x39\xd5\x68\
182 | \x84\x85\x5a\x2d\xbd\x04\xd4\xa0\x98\xc1\xb5\x66\x4d\x3a\x35\x35\
183 | \x15\xdc\xf3\x52\xc9\x57\x9a\x43\x8e\xbe\x07\xab\x67\xd3\x89\x48\
184 | \xe4\x31\x6a\x0d\x7b\x2e\x49\x58\x48\xd3\xbc\xfa\x97\x7f\x79\x20\
185 | \x72\x97\xa5\xfd\xa1\x43\xfb\x73\x89\x8d\x89\x09\xe6\x7b\x7b\x8f\
186 | \xad\x5f\x69\x84\x45\xe5\x9e\x8d\x84\xe7\x8c\x9f\x00\x6d\xb2\x21\
187 | \xbd\xca\x06\x6b\x0b\xa8\xab\xbd\x64\xf0\x47\x4e\x9c\x1a\xb0\x8c\
188 | \x38\x63\x73\x2c\x84\xf0\xab\xdc\x7a\x2f\x2a\x3d\x4b\x56\x5c\xec\
189 | \xea\x66\x7d\x7e\x9e\x06\xdc\xbc\x27\x91\xc2\x4b\x41\x2b\xeb\x9d\
190 | \xa4\xa5\xad\x40\x7f\xab\xcb\xa2\x96\xd7\x34\x19\xf8\x92\xe4\x33\
191 | \x4d\x85\xa5\xb9\x53\x1b\xcd\x5f\xb7\xdf\xd7\x56\xa2\x79\xe0\xc0\
192 | \xdb\x97\x17\x57\x5e\xac\x55\x56\xab\xcb\x91\x7c\x1e\x27\xb3\x86\
193 | \x67\x5b\xbe\x41\x83\x52\x8b\x0d\x5c\xf5\x45\x9b\x95\xf7\xa6\x8d\
194 | \xbb\x0e\xba\x24\xf8\x00\xf9\x28\xe6\xcd\x10\x99\x69\x26\x85\x0f\
195 | \x42\xb3\xba\xbc\x7a\xb9\xb3\x0a\x64\xeb\xeb\xdc\xb2\x73\xdd\x8e\
196 | \x02\xc5\x80\xc9\xa4\x70\x21\x9a\xf9\x76\x95\x57\x01\xea\x88\xf3\
197 | \x92\xce\x84\xa6\x2e\x77\x75\xad\xdf\x56\x9f\xed\x76\x64\x93\x0d\
198 | \xe3\xe3\x47\xe7\xcb\x43\xe9\xba\xab\x85\x0b\x64\xf9\x9c\xe1\x79\
199 | \xf0\xe3\x36\x3b\x80\x2d\xd7\xd8\x70\xd5\xb9\x35\x68\xf5\x01\x66\
200 | \x11\xef\x08\xde\x44\xc9\x2f\x83\x39\xd5\x8c\xf9\xd2\xca\x52\xa9\
201 | \x0a\xa5\xfc\x76\xcb\xed\x14\x7e\x10\x0b\x85\x17\x56\x9b\x4d\x66\
202 | \x10\x89\xcc\x99\x08\x3b\x41\xc3\x88\x20\xc7\x63\x44\x3e\xc8\xb2\
203 | \x74\xfd\xf0\xe1\xfd\x77\xd5\xd1\xf9\x38\x69\xa5\xb3\xe3\xcd\xfd\
204 | \xfb\x7d\xe9\xe8\xd1\xa3\xb5\x4a\xa5\xeb\x52\x74\x98\x23\xf7\xac\
205 | \xe1\x19\xd0\x5e\x60\xb0\xed\x18\x73\x60\x15\x31\x2f\x78\x57\xd2\
206 | \x9b\x92\x7e\x41\x4c\xdf\x6f\x14\xf3\x0b\x97\xe6\xfa\x36\xb8\xc3\
207 | \x96\x38\xb4\xc7\x4b\x87\x0e\x1d\x0a\x3f\xff\x79\xa9\xb2\x9e\x95\
208 | \x7b\x89\x1a\x28\x38\x0c\x65\xd6\x08\x4e\xba\x4c\x3c\x1f\x9c\xbc\
209 | \x79\xfe\xfc\xf9\xb9\x43\x87\xf6\x37\x3e\x4d\x00\x6e\x50\x44\x68\
210 | \x7c\xfc\x68\xa1\x58\x2c\xf6\x34\x5c\xda\x15\x1c\x9e\x8c\x79\x7c\
211 | \x3e\x3a\x3c\x1a\xa3\xfa\x1c\xb5\x96\x47\x1d\xb7\xc3\x2f\x9c\xfb\
212 | \xad\x18\xd3\xe3\x79\x5e\x3d\xdf\xd3\x33\xb6\x3e\x33\x43\x76\xb7\
213 | \xed\xb6\xb4\x6d\xd3\xf9\xfe\xfd\xac\x4f\x4d\x4d\x57\x2f\x5e\xac\
214 | \x5e\x28\x75\x74\xbf\xdf\x5c\x6f\x76\xc6\xe8\x72\x9a\x66\x8d\x95\
215 | \x95\xe6\xca\xf8\xf8\xd1\x4f\x8d\xfe\x37\x93\xeb\xd8\xb0\x7c\xf4\
216 | \xe8\x62\xd5\xaa\x2d\xe7\x84\x39\x11\x4f\x88\x64\x38\xb7\x2e\x04\
217 | \x3c\x93\xa7\x7e\xaf\x1e\xe2\xb9\x4a\x1c\x58\x3b\x73\x86\xe6\xd9\
218 | \xb3\x77\xb7\xf1\x4d\xf9\xb8\xc1\x88\x0e\x1c\x38\x1c\xc6\xc7\x87\
219 | \x34\x3d\x0d\xdf\xff\xfe\xbe\x9c\xbb\x75\xfd\x77\xa3\x94\xa6\xc2\
220 | \xf8\xf8\xc1\xb4\x59\x3e\xd7\x5d\xa8\x69\x2b\xd0\x55\xaf\xb3\x6e\
221 | \x6b\x29\xcf\xab\xab\xa7\x4f\xbf\xde\x84\x4f\x67\x2c\x77\xcb\xd9\
222 | \xe0\x47\x15\x93\x30\x30\x85\x98\x41\x8c\x23\x66\x30\xe3\x98\x83\
223 | \xd8\x7c\x7a\x13\xa1\xcd\x09\xf0\xf8\x38\xe9\xca\xca\x6c\xd2\xd3\
224 | \x33\x96\xcf\xcc\x1c\xce\x3f\xad\x8d\x5f\x5d\xe7\x76\x00\x10\x12\
225 | \x53\x24\x63\x2b\x63\x85\x62\xf1\x4a\xd1\xb5\x42\x59\xa4\xa5\x2c\
226 | \xe4\x69\x12\x42\x4e\x96\xd7\x54\x6e\xd6\x62\x47\x4f\xfd\x34\xa7\
227 | \x33\x0e\x92\x7f\xba\x60\x48\xb7\x0a\xbf\x9a\x52\xd8\xc7\xbe\x00\
228 | \xb0\x8f\xe9\x38\x79\x07\x87\x71\xeb\xf1\xf8\x94\xc2\xf8\x0c\xe9\
229 | \x95\xd1\xde\x4a\xa6\x38\x18\x63\x32\x82\xc2\x60\x82\xfb\x45\xe8\
230 | \x26\xa8\x64\xb9\x11\xac\x15\x85\x70\x31\x49\xbc\x98\x34\xb4\x10\
231 | \x7b\x9a\x4b\x3d\xf3\xcb\xd5\x23\x5f\x27\xfb\x34\x81\xb8\x99\x1c\
232 | \x38\x7c\x20\x39\xb7\x74\xac\x3b\x75\x61\xa0\x90\x44\xd5\xaa\xc9\
233 | \x7a\x52\xac\xad\xb1\x38\x54\x9b\x3e\x38\xfd\x89\x07\xf1\xf1\xd3\
234 | \xe1\x03\x4a\xfa\xfa\xfa\xba\x3a\x8a\x61\x5b\x54\xbc\x5f\xe2\x31\
235 | \xc4\xc3\x01\x6d\x97\xd4\x25\x42\x59\xc1\x89\xa4\x5c\xa8\x26\xb4\
236 | \x46\xd0\x5c\x80\xb7\x83\xc2\x2f\x14\xf2\xf7\x15\xf3\xc5\x77\x2b\
237 | \x4b\x55\x26\xc9\x7f\x13\xf7\x09\x84\xf4\xc2\x9f\xed\xed\x2a\x76\
238 | \x76\x3d\x8c\xb3\xe7\xa5\xd0\x19\x60\x5e\x81\xf7\x93\xba\xcf\xc4\
239 | \x81\xb8\xd8\x53\xde\x5b\x3b\xb4\xff\xd0\xc7\x0e\x46\x3e\x02\x80\
240 | \x24\x31\x49\x32\x72\xb1\xab\x2f\xcb\x78\x38\x09\xc9\xf3\x0a\x7a\
241 | \x2a\xa0\x3d\x04\x0d\x0b\xba\x24\xa5\x52\xab\x2f\x23\x09\x21\x4b\
242 | \xca\xd4\x2a\x42\xe6\x24\xbd\x83\xf8\x39\xf8\xcd\x90\xa4\xc7\xe3\
243 | \x70\x79\xe9\xc4\x57\x4f\x34\x3e\x6d\x36\x1c\x38\x7c\x20\xb9\x38\
244 | \xfb\xde\x08\x05\xbe\x04\xda\x0f\xdc\x13\xa4\x15\x05\x4e\x58\xc9\
245 | \xcf\x43\xa2\x37\xc8\x0b\x27\x2e\x86\xfa\xa5\x23\xaf\x1e\xb9\x29\
246 | \x1b\x3f\xd4\x15\x96\x78\x95\x74\x70\xa9\x32\x94\xe5\xe1\x89\x44\
247 | \x7c\x49\xf0\x3c\xb0\xcb\x78\x8b\x4c\x81\xd6\xe4\xe8\x66\xd3\x9d\
248 | \x02\x50\x06\xba\x81\xed\x88\x07\x82\xc3\xc3\xca\xf3\xe9\xd2\x72\
249 | \xed\xb5\xb1\x3f\x1f\x9b\xd3\x7f\x54\xed\xd3\x04\xe1\xe4\xa5\x93\
250 | \xa1\xb3\x94\x74\x27\x31\xbf\x17\x74\xaf\xc4\x4e\x84\xdd\xea\x45\
251 | \x3e\xe0\x3c\xee\x49\x92\xc6\xdf\xf4\xe4\xd9\x91\xfd\x87\xc7\x17\
252 | \x75\x40\x1f\x49\xe5\x6f\x9c\x0b\xec\x23\x19\x4a\x3b\x07\x82\xc3\
253 | \xd3\x11\xff\x63\xd0\xe7\x8c\xc6\x64\x2a\xdc\x62\xbc\xd4\x96\x4d\
254 | \x60\x4a\xc0\xa0\xd0\x16\xc4\x90\xa5\x81\x3c\xa3\xd2\xb1\x9c\xff\
255 | \x70\xf8\x3f\x0d\x7f\xa0\x2e\x55\x7d\xd0\x9f\x4a\x46\xb9\xe5\xdc\
256 | \xc5\x84\xfe\xee\x1e\xd0\x28\xa2\x07\x51\xb4\x08\x42\x25\xf0\x16\
257 | \x49\xfd\xb6\xb6\x14\x55\x4c\xab\x17\x2b\xaf\x4d\x7c\x7d\xe2\x02\
258 | \xad\x32\xf8\xaa\x5c\xdd\x94\x90\xfa\x1e\xe8\xeb\x74\xa6\x87\xf2\
259 | \xdc\xbf\x07\xbc\x68\xb4\x13\xbb\xf3\xba\xcf\x6d\x56\x60\x4d\x5a\
260 | \x75\x42\x0d\xa8\xb7\xdf\x6f\xe6\x0a\x9b\x13\xdb\x0e\xa4\x6d\x42\
261 | \xcf\x62\xff\x53\x91\x7e\xa1\xbf\x58\xbc\x77\xfc\xc2\x50\x45\x53\
262 | \x1f\xe9\xd9\xdd\xb1\x48\x52\xb3\xa3\x54\xc0\xf4\x1a\x86\x90\x2b\
263 | \x32\xc2\x08\x9c\x08\x3a\xdd\x1a\xed\x7f\xde\x09\xaf\xe4\xc5\xe6\
264 | \x63\xbd\xe5\xa4\x7b\x8a\x1b\xd7\xbe\xc6\x80\x3f\xa2\x28\x35\x47\
265 | \x8d\x9e\x15\x7c\x16\x34\x86\x5d\x26\x68\x93\xee\x91\x56\xe9\x79\
266 | \x09\x74\x11\x58\x73\xa4\x29\x51\x90\xe8\x06\x06\x81\x5e\xa0\xd8\
267 | \x06\x4c\x98\x02\x62\x08\x78\x2a\x98\x02\x41\x69\x3e\x50\xfa\xde\
268 | \x63\x9d\xc3\x27\x35\xf5\x6b\x32\x61\x12\xf5\x6e\x29\xa6\x1b\xcd\
269 | \x50\x32\xe4\x58\x55\x07\x95\x02\xbe\xba\xbe\xa0\x6c\x34\x2a\x78\
270 | \x96\x18\x2e\x14\x9b\xc9\xc2\xcc\x9f\x3f\xb7\xa1\x3f\x56\x6d\xd3\
271 | \x14\x5a\xd5\xe0\x94\x42\xd7\x7a\x57\x37\x45\x1e\x06\x3f\xa3\x56\
272 | \x5d\x5e\x6e\xdb\x3b\xb4\x9a\x92\x2b\xc2\x27\x8d\x7e\x89\xe3\x4c\
273 | \x50\x32\x07\xae\x86\x40\x07\xe6\x1e\xc9\x8f\x80\xc6\x69\x15\x52\
274 | \xbd\xed\xcd\xb7\x27\xc7\x1a\x90\x78\x02\xa1\xa0\x10\xb3\xd5\x52\
275 | \x9c\x48\xb6\x9f\x12\xaa\xde\xb5\x4f\x38\x88\x2f\xff\x59\x23\x2b\
276 | \x96\x4a\x0b\x84\xe4\x35\x20\x6f\x5f\xdc\x18\x93\xe8\x46\xad\x6e\
277 | \x51\x68\xb5\xc4\xc7\x10\x4f\x05\xc7\x77\xae\xf4\xc5\x73\xfb\x0f\
278 | \xb5\xfa\x03\x57\x01\x60\x9e\xa4\x58\x64\x08\xf3\x18\xf0\x80\xa1\
279 | \xfb\xba\x91\x72\x8e\xbd\x22\xe9\x2d\x5b\xdf\x8d\x8e\x3f\x25\xe1\
280 | \x4c\x52\xca\x57\x36\x62\x21\xab\x84\x46\xaa\xac\xdc\x5b\x48\x74\
281 | \x84\x4c\x4f\x5a\x7e\x01\xfc\x04\xd2\x36\x4c\xe9\x1a\x08\xf4\x05\
282 | \xe9\x33\x98\x5c\x52\xd6\x4c\x4a\xd9\xd8\x1f\x8f\x7d\xa0\xff\x7c\
283 | \x97\x8e\x51\x50\xf8\xfe\xb6\x6a\xf1\xcd\xc5\xe3\x59\x48\xd6\x2c\
284 | \x7e\x81\xfc\xa4\x08\x2f\x82\x1f\x6f\x0f\x48\x53\x43\xc0\x74\x02\
285 | \xf7\x5b\x7e\xc2\x79\x3a\xb3\xbe\xb0\xfb\xd2\x0d\x00\x6c\x87\x42\
286 | \x23\x32\x64\xf9\x7e\x05\x0d\x72\xcd\x34\x0c\x54\x0d\xc7\x63\xd4\
287 | \xb7\x93\xe0\xef\x34\x08\xa7\x96\x7b\x97\x37\x38\x48\x7e\xb5\x4a\
288 | \x9f\x5a\x59\xdb\xbb\x31\xb8\xd4\x8c\xa5\xf9\x34\xc9\xe6\x73\xc2\
289 | \x6a\x68\x45\x8f\x7b\x30\xe5\x36\x08\x89\xed\x7e\x49\x8f\xd3\x1a\
290 | \x58\x36\x7a\x7a\xf8\x41\x3a\xb5\x6b\x56\x07\x55\xbf\x53\x10\x6c\
291 | \x5b\x52\x3e\x39\xc9\xe5\xc3\x8c\xaf\x6f\xdb\x56\x9e\x73\xee\x39\
292 | \x47\xaf\xb5\x27\x51\x4f\x8a\x56\x73\x57\xad\xfd\x0c\xda\xec\x21\
293 | \x78\x04\x06\xde\x97\xd4\xb0\xed\x54\x53\x0a\xdd\x9d\xdd\xe5\xf4\
294 | \x4a\xdc\x2a\x31\x62\xab\x72\xdd\x25\x86\x08\x2c\x0b\xde\x52\xe0\
295 | \xa7\x5d\x1d\xe9\xc9\xb9\xca\xd2\x95\xab\xb6\xbb\xa9\xf2\x41\x32\
296 | \xa1\xf5\xdd\x7f\xb4\xfb\x4c\x4c\xab\x1b\x92\xab\xa0\x06\xe2\x45\
297 | \xc4\xce\xeb\x41\xc0\x0c\x28\x78\xc2\xa6\x99\x50\x68\x76\x27\xf1\
298 | \xff\xee\xfe\xda\xee\x79\x7d\x55\x77\x9c\x27\xb4\xed\xd8\x07\xa1\
299 | \x31\x35\xa5\x6c\x7a\x68\xfc\x64\x21\x2d\x16\x31\xa3\x88\x31\x43\
300 | \x45\x9b\xfe\x08\x4a\x82\x01\xc8\x87\xd3\x8e\xd0\x31\x39\xc9\x3a\
301 | \xe0\xc0\x0c\x4a\xb3\x66\x45\xad\x16\x75\x8f\xe4\xcd\x0e\x0c\x98\
302 | \xdc\xb0\x64\x74\x54\x81\x33\xef\x56\x96\x3e\xd6\x71\x19\xfb\xc4\
303 | \xd7\x4e\x34\x7a\x2e\xcf\x9d\x6f\x26\x85\x9f\x59\xfc\x6f\xc4\xdf\
304 | \x0a\xce\x22\xea\xb8\x1d\x21\x5a\xb4\x1c\x14\x7a\x1a\xf9\xf7\xed\
305 | \xe4\xb9\xca\x4a\x73\xfb\xae\xff\xb6\xab\xf4\xeb\x44\x87\x83\x07\
306 | \x1d\xa7\x87\x66\xaa\xcd\x3c\x9d\x05\xde\x91\xb5\x04\xd7\x5d\x8d\
307 | \x11\xa1\x75\xd7\x29\x0c\x18\x57\xa6\xdb\xb5\x43\x60\x1c\xe5\x99\
308 | \x8b\x11\x57\x6c\x8a\xf6\x0d\x77\x81\x22\xb0\x2e\xbc\x90\x36\xe2\
309 | \x1a\x93\xb7\xae\xbd\x6d\xfb\xc8\x5f\x90\x0d\x2e\x9d\x59\x4a\x55\
310 | \x3f\xa2\xe0\xff\x63\xf4\x43\xc1\xdc\x87\x40\x28\x00\x5b\x41\xcf\
311 | \x06\xfb\xcb\x22\xd9\xd7\x3d\x9f\xec\x9e\x28\xdf\xb7\xe5\xe5\xa9\
312 | \x97\x53\x49\x37\x4b\xb4\x3e\x59\x0e\x10\x9b\xe5\xe2\x15\x89\x8b\
313 | \x86\x0d\xae\xab\x1a\x6d\x24\x28\x48\xea\xc8\x4d\x81\x97\x5a\xbf\
314 | \x6f\x21\x5e\x07\xf9\xea\xf8\xe8\x9a\x08\x0b\x62\xb4\xb2\xb5\x3c\
315 | \xc4\x8f\xfc\xfd\x16\x20\x54\x96\x96\x96\xec\x70\x44\xe2\x9b\x11\
316 | \x7e\x0c\x9c\xa3\xd5\xcf\x73\x2b\x56\x53\x04\xb6\x21\x7d\x0e\xe9\
317 | \x0f\x12\xf3\xcf\x6c\x4d\x5c\x4a\xe7\x87\xf7\x4d\xde\x25\x1b\x0c\
318 | \x1d\x59\x2d\xd8\xa4\x12\xe1\x23\xf9\xaa\x94\x63\x67\x69\x48\xae\
319 | \xbb\x20\x31\x83\x93\x21\x35\x95\xa9\x06\xce\x3e\xfc\x0d\xec\x72\
320 | \x40\x3d\x85\x8e\x46\x99\xfd\xac\xc3\xad\xaf\x9d\x6d\x82\x20\x29\
321 | \x1b\x9f\x9c\x5d\xac\x35\xb7\xff\xac\x08\x29\x24\x29\xd2\x0b\xc0\
322 | \x48\x9b\x01\x9b\x4c\x18\x96\x5d\x91\xb4\xd5\x51\x3b\xd3\xc0\x0f\
323 | \x57\xca\xc5\xb7\x3e\x1b\x1f\x9c\xdd\xf3\xb5\x3d\xeb\x27\x96\x4f\
324 | \x34\x99\xe4\xb6\x6e\x9f\x4e\xfc\xc5\x44\x1a\x9b\xb1\x37\x24\x1a\
325 | \xb5\xdd\x13\xa4\xe4\xea\x4e\x5a\x6a\x35\x50\x58\x57\x28\xd4\x87\
326 | \x16\x87\x0c\x2d\x13\x70\xda\x08\x0d\x72\xaf\x59\xda\xd0\xb5\x8c\
327 | \x2e\x82\x6c\xa9\x03\x79\xb8\xd8\x4c\xb6\x30\x7e\xfb\x37\xbc\x6c\
328 | \x7b\x66\x92\xa6\x56\x2b\x17\x9c\xc7\xd7\x24\x7f\x13\xfc\x33\x99\
329 | \x45\x4c\x13\x5d\x65\x42\x0a\xea\x31\x3c\x28\xf1\x25\xf0\xbf\x0e\
330 | \xd1\xff\x12\xc5\x17\x7b\xeb\xde\x33\xd1\xf5\x40\xff\xbe\xc9\x5d\
331 | \xa5\x03\x87\x0f\x24\xe2\xe6\xa6\x21\x49\x2f\x4f\xbd\x9c\xf6\x36\
332 | \x93\xee\x10\xd8\x23\xeb\xf1\xb6\x4f\x4b\xda\xbb\x37\xad\x51\xd9\
333 | \x9a\x60\xb9\x81\x6b\xe3\x47\xc7\xdd\x06\x06\x0d\x7e\x85\xae\x58\
334 | \xe8\x7c\x41\xe8\xdf\x09\x5e\x24\xd0\x09\xaa\x05\x69\x11\x71\x0c\
335 | \xf1\x6d\x15\xf4\xd7\xe7\x7b\x56\x3e\xf0\xc1\x0f\xb3\xe4\xd6\x22\
336 | \x49\xbb\xff\xcb\xee\x22\x17\xea\x63\xa5\x94\xcf\x2b\x86\x2f\x13\
337 | \xf4\x94\xc4\x56\xa1\xa2\xda\x65\xa5\x02\x16\xca\x5b\x15\xa5\x16\
338 | \x04\x27\x14\xf4\x8b\x60\x7e\x99\x88\x93\x4e\xc2\x62\x68\xa6\xab\
339 | \x79\xa9\xab\xb6\xba\xba\x9a\x97\xb7\x95\x5d\x3b\x57\xd3\x8e\xfe\
340 | \xba\xf2\x7a\x25\xcd\xba\xd4\x9b\x66\xc9\xde\x18\xfc\x0f\x51\xf8\
341 | \x47\x12\x0f\x48\xea\x90\xa4\x20\x22\xd2\x12\xf0\xdd\x10\xf4\x5f\
342 | \x9b\x85\x9e\x9f\x7d\xe7\xdf\x7e\x67\xc3\xb6\x53\xdb\xd6\xef\xab\
343 | \xd1\xb7\x8b\x79\x22\x47\x05\xc3\x58\x05\xc1\x9c\xf1\xb1\x80\xde\
344 | \x76\x9a\xcc\x34\x33\x2d\xb5\x58\x71\x67\x62\xdb\x42\x8d\x5d\x53\
345 | \xbb\xe6\x4a\x64\x3f\x74\x22\x07\x7b\x03\x6b\x02\x31\x0a\xed\x42\
346 | \xcb\xad\x08\x41\xab\x9a\xac\x20\x46\x30\x0f\x38\xe8\xe9\x0c\x1d\
347 | \x0f\xe2\x44\x2c\xc6\xb3\x8a\xeb\x8b\xfd\x3d\x71\xdd\xeb\xb5\xbc\
348 | \xb3\x3f\x0d\x6b\x31\x29\x16\x3a\xe8\x72\x43\xf7\xe6\x89\x9f\x02\
349 | \x9e\x11\xbe\x4f\xad\x31\xdb\xe6\x24\xa5\x29\x7c\x41\x4a\x8e\xe5\
350 | \x64\xf3\x17\xab\x17\x1b\x37\xa4\xc2\x74\x91\x35\xad\x85\x22\xfe\
351 | \x11\x70\xc9\x50\x95\x7d\x2a\xa0\x59\xec\x0b\x95\xbe\xfe\xd5\xd3\
352 | \x9c\x6e\xdc\x6d\xee\x6e\x6c\x1d\x54\x7d\xd7\xd4\xae\xd9\x8e\x44\
353 | \xd3\x49\x43\xcb\x04\xe6\x81\x67\x0d\x7b\x64\xfa\x10\xc5\xb6\xc2\
354 | \x81\x96\x83\x2c\x20\x3a\x11\x23\x82\x87\x64\x2d\x23\x2f\x4b\xf1\
355 | \x82\x63\xb2\x4c\x12\x9a\xb6\x0b\x89\x54\x8e\xa6\x57\x81\x11\x60\
356 | \x94\x56\x4d\x52\x76\x2b\x01\x82\xf6\x3c\xc1\xf0\x9e\xec\xb7\x9b\
357 | \x85\xb0\x74\xe4\xec\xcf\xae\xfa\x31\xd9\x6e\xf5\x01\xf6\x53\xe8\
358 | \x1a\xe9\xea\xa9\xd4\x93\xee\x2c\x36\xea\x74\x74\xac\x2e\x2f\x2c\
359 | \xd7\x18\x27\xbb\x5d\x27\xf4\x49\x22\x49\x13\x5f\x9f\x48\xd7\xce\
360 | \x9d\xeb\x29\xe4\xe5\x7b\x93\x02\x4f\x07\xf1\x39\xa4\xcf\x08\x46\
361 | \x25\x75\x4a\x4a\x6e\x68\xb6\x48\x96\x88\x52\xc8\x25\x32\x05\x55\
362 | \x65\xd5\x24\x45\x49\x41\x22\x95\x54\x6a\xbf\x0a\x12\xc9\x55\xb3\
363 | \x6a\x7d\x66\x4d\xe2\x57\xa0\xff\x19\xe0\xaf\x5c\x5b\x3e\xf3\xcd\
364 | \xaf\x1e\xaf\xdf\x00\xc0\xa6\x72\x4c\xb6\x4f\x60\x06\x73\x98\x4f\
365 | \xbc\xa8\x74\xd7\x40\x1c\x50\xf2\xd8\xce\xe1\x32\x3d\xe5\xad\x22\
366 | \x19\x17\x3c\x2f\xe9\x69\x89\xdd\x41\x61\x00\xa9\xe3\x43\x1b\xe1\
367 | \x3a\x3f\x61\x11\xbc\x09\x50\xab\xc0\x6a\x19\xba\xb8\x01\xb8\x5c\
368 | \xd2\x15\x49\xc7\xc1\x7f\x5d\x48\x0a\xdf\x08\x17\xc3\x3b\xdf\xf8\
369 | \xd3\x1f\xad\x5f\x9f\x71\x5e\x2d\x87\x37\xd3\x4a\xee\xc2\xce\xef\
370 | \x54\x7c\xc8\xb9\xa4\x8d\x89\xaf\x4f\xcc\x5e\xb9\xb8\xb0\x5a\xca\
371 | \x3a\xe6\x14\x7c\x4c\x0a\x13\x46\x8f\xa8\x95\x3e\x0f\x21\xca\x40\
372 | \xca\xe6\x3f\x49\xb5\xfc\x84\xae\x1b\x94\x5e\x0b\x4b\xed\x5f\xe9\
373 | \xea\xe5\x08\x56\x80\x13\x86\x1f\x24\xd2\x77\xdd\x48\x8e\x3f\x59\
374 | \xfd\xe1\x95\xff\xc5\xad\x3a\x42\x7f\x87\xd2\x06\xbc\xa9\x29\x5d\
375 | \x7a\x6e\x65\x6c\xa3\x31\x98\x2c\xc4\x98\x1c\x4d\x55\x78\x10\xf8\
376 | \x0c\xc1\x8f\x60\xed\x40\xf4\x63\xba\x0c\x45\x89\x70\x9d\x6d\xb7\
377 | \xf6\x2c\xf9\xea\x5b\x91\x59\x6c\xc8\x5c\x40\xbc\x63\xfb\x47\x69\
378 | \x8c\x3f\x8a\xc5\xd2\x7b\x5d\x83\xdb\x56\x0f\xfe\xfb\x8f\xfa\xb0\
379 | \x3b\x1a\x8c\xfc\xa6\x44\x92\x38\x44\x78\x6e\x76\xac\x18\xab\x85\
380 | \xee\x3c\x24\xdb\x93\x90\xdc\x6f\xd8\x2b\x85\xfb\x24\x6d\x57\xf0\
381 | \xa0\x50\xaf\xa4\xae\xd0\xaa\xf6\x80\x90\x87\x40\x16\x14\x32\x89\
382 | \x3a\xd2\x65\x82\xce\x82\x8e\x26\xf2\x1b\x99\xc3\x51\x0f\x56\xe7\
383 | \x86\x0e\x3f\x5c\x3d\x74\xe8\xe6\x9d\xe1\xdf\x09\x00\x36\x65\xd3\
384 | \x0f\xed\x62\x57\x71\x6b\xb1\xdc\x99\x94\x93\x3e\xe7\x1e\x90\xc3\
385 | \x90\x0a\xde\xde\xbe\xbe\xbb\x4d\x84\x8a\x02\x91\x10\x1a\xc2\xf5\
386 | \x40\xa8\x2b\x78\x55\x0e\xe7\x94\xe8\x54\x74\x7e\xd6\x85\xf4\x7c\
387 | \x47\x7d\x65\xed\x5b\x9f\xd0\x8d\xfe\x9d\x02\x60\x53\x36\x81\xd8\
388 | \xc7\xbe\xd0\xd1\x3f\x9b\x2c\x43\x29\xad\x26\x5d\x31\x29\x76\x87\
389 | \xe0\xae\x68\x8a\x0a\x72\xe2\x90\x53\x74\x96\xc6\x24\xb7\xb2\x7a\
390 | \x48\xc3\x5a\xa9\x59\x5e\xfb\x60\x79\xbd\xb6\x9f\x99\x6c\xf2\x36\
391 | \xa2\xd7\xef\x24\x00\x1f\x16\x21\xed\x3f\x40\x58\x1c\xdf\xa7\x45\
392 | \x16\xc3\x8e\xfe\xba\x00\xba\x46\x4a\x3e\x7a\x14\xca\xdb\xca\xde\
393 | \xf2\xc0\x16\x0f\x2d\x0e\xf9\xf0\xfe\xc3\xf1\x4e\xfa\x0a\xff\x0f\
394 | \xc1\xea\x47\x68\xcb\x86\x1c\x37\x00\x00\x00\x00\x49\x45\x4e\x44\
395 | \xae\x42\x60\x82\
396 | "
397 |
398 | qt_resource_name = "\
399 | \x00\x07\
400 | \x07\x3b\xe0\xb3\
401 | \x00\x70\
402 | \x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\x00\x73\
403 | \x00\x0b\
404 | \x08\xd8\x99\x42\
405 | \x00\x67\
406 | \x00\x65\x00\x6e\x00\x65\x00\x72\x00\x61\x00\x6c\x00\x69\x00\x7a\x00\x65\x00\x72\
407 | \x00\x08\
408 | \x0a\x61\x5a\xa7\
409 | \x00\x69\
410 | \x00\x63\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\
411 | "
412 |
413 | qt_resource_struct = "\
414 | \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
415 | \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
416 | \x00\x00\x00\x14\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\
417 | \x00\x00\x00\x30\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
418 | "
419 |
420 | def qInitResources():
421 | QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
422 |
423 | def qCleanupResources():
424 | QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
425 |
426 | qInitResources()
427 |
--------------------------------------------------------------------------------
/ui_generalizer.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | generalizer
4 |
5 |
6 |
7 | 0
8 | 0
9 | 493
10 | 348
11 |
12 |
13 |
14 | Generalizer
15 |
16 |
17 | -
18 |
19 |
20 | Batch mode
21 |
22 |
23 |
24 | -
25 |
26 |
27 |
28 | 0
29 | 0
30 |
31 |
32 |
33 | ?
34 |
35 |
36 | true
37 |
38 |
39 |
40 | -
41 |
42 |
43 |
44 | 0
45 | 0
46 |
47 |
48 |
49 | OK
50 |
51 |
52 |
53 | -
54 |
55 |
56 | Close
57 |
58 |
59 |
60 | -
61 |
62 |
63 | 0
64 |
65 |
66 |
67 |
-
68 |
69 |
70 | Input line layer:
71 |
72 |
73 | cbInput
74 |
75 |
76 |
77 | -
78 |
79 |
80 | -
81 |
82 |
83 | Options
84 |
85 |
86 |
-
87 |
88 |
89 | Alghoritm:
90 |
91 |
92 |
93 | -
94 |
95 |
96 |
97 | 0
98 | 0
99 |
100 |
101 |
102 | 1
103 |
104 |
-
105 |
106 | -----Generalizing-----
107 |
108 |
109 | -
110 |
111 | Remove small objects
112 |
113 |
114 | -
115 |
116 | -----Simplifying-----
117 |
118 |
119 | -
120 |
121 | Douglas-Peucker Algorithm
122 |
123 |
124 | -
125 |
126 | Jenk's Algorithm
127 |
128 |
129 | -
130 |
131 | Lang Algorithm
132 |
133 |
134 | -
135 |
136 | Reumann-Witkam Algorithm
137 |
138 |
139 | -
140 |
141 | Vertex Reduction
142 |
143 |
144 | -
145 |
146 | -----Smoothing-----
147 |
148 |
149 | -
150 |
151 | Boyle's Forward-Looking Algorithm
152 |
153 |
154 | -
155 |
156 | Chaiken's Algorithm
157 |
158 |
159 | -
160 |
161 | Hermite Spline Interpolation
162 |
163 |
164 | -
165 |
166 | McMaster's Distance-Weighting Algorithm
167 |
168 |
169 | -
170 |
171 | McMaster's Sliding Averaging Algorithm
172 |
173 |
174 | -
175 |
176 | Snakes Algorithm
177 |
178 |
179 |
180 |
181 | -
182 |
183 |
184 | 0
185 |
186 |
187 |
188 |
-
189 |
190 |
191 | Threshold:
192 |
193 |
194 | sbRemove_thresh
195 |
196 |
197 |
198 | -
199 |
200 |
201 | 4
202 |
203 |
204 | 0.000100000000000
205 |
206 |
207 | 9999999.999900000169873
208 |
209 |
210 | 0.000100000000000
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 | -
219 |
220 |
221 | Threshold:
222 |
223 |
224 |
225 | -
226 |
227 |
228 | 4
229 |
230 |
231 | 0.000100000000000
232 |
233 |
234 | 9999999.999900000169873
235 |
236 |
237 | 0.000100000000000
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 | -
246 |
247 |
248 | Threshold:
249 |
250 |
251 |
252 | -
253 |
254 |
255 | 4
256 |
257 |
258 | 9999999.999900000169873
259 |
260 |
261 | 0.000100000000000
262 |
263 |
264 |
265 | -
266 |
267 |
268 | Angle threshold:
269 |
270 |
271 |
272 | -
273 |
274 |
275 | 180.000000000000000
276 |
277 |
278 | 3.000000000000000
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 | -
287 |
288 |
289 | Threshold:
290 |
291 |
292 |
293 | -
294 |
295 |
296 | 4
297 |
298 |
299 | 0.000100000000000
300 |
301 |
302 | 9999999.999900000169873
303 |
304 |
305 | 0.000100000000000
306 |
307 |
308 |
309 | -
310 |
311 |
312 | Looka ahead:
313 |
314 |
315 |
316 | -
317 |
318 |
319 | 1
320 |
321 |
322 | 9999
323 |
324 |
325 | 8
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 | -
334 |
335 |
336 | Threshold:
337 |
338 |
339 |
340 | -
341 |
342 |
343 | 4
344 |
345 |
346 | 9999999.999900000169873
347 |
348 |
349 | 0.000100000000000
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 | -
358 |
359 |
360 | Threshold:
361 |
362 |
363 |
364 | -
365 |
366 |
367 | 4
368 |
369 |
370 | 0.000100000000000
371 |
372 |
373 | 9999999.999900000169873
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 | -
382 |
383 |
384 | Look ahead:
385 |
386 |
387 |
388 | -
389 |
390 |
391 | 2
392 |
393 |
394 | 999
395 |
396 |
397 | 7
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 | -
406 |
407 |
408 | Level:
409 |
410 |
411 |
412 | -
413 |
414 |
415 | 1
416 |
417 |
418 | 99
419 |
420 |
421 |
422 | -
423 |
424 |
425 | Weight:
426 |
427 |
428 |
429 | -
430 |
431 |
432 | 1.000000000000000
433 |
434 |
435 | 3.000000000000000
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 | -
444 |
445 |
446 | Threshold:
447 |
448 |
449 |
450 | -
451 |
452 |
453 | Thightness:
454 |
455 |
456 |
457 | -
458 |
459 |
460 | 0.500000000000000
461 |
462 |
463 |
464 | -
465 |
466 |
467 | 4
468 |
469 |
470 | 9999999.999900000169873
471 |
472 |
473 | 0.000100000000000
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 | -
482 |
483 |
484 | Slide:
485 |
486 |
487 |
488 | -
489 |
490 |
491 | 0.100000000000000
492 |
493 |
494 | 0.500000000000000
495 |
496 |
497 |
498 | -
499 |
500 |
501 | Look ahead:
502 |
503 |
504 |
505 | -
506 |
507 |
508 | 3
509 |
510 |
511 | 999
512 |
513 |
514 | 2
515 |
516 |
517 | 7
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 | -
526 |
527 |
528 | Slide:
529 |
530 |
531 |
532 | -
533 |
534 |
535 | 0.100000000000000
536 |
537 |
538 | 0.500000000000000
539 |
540 |
541 |
542 | -
543 |
544 |
545 | Look ahead:
546 |
547 |
548 |
549 | -
550 |
551 |
552 | 3
553 |
554 |
555 | 999
556 |
557 |
558 | 2
559 |
560 |
561 | 7
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 | -
570 |
571 |
572 | Alpha:
573 |
574 |
575 |
576 | -
577 |
578 |
579 | 9999.989999999999782
580 |
581 |
582 | 1.000000000000000
583 |
584 |
585 |
586 | -
587 |
588 |
589 | Beta:
590 |
591 |
592 |
593 | -
594 |
595 |
596 | 9999.989999999999782
597 |
598 |
599 | 0.500000000000000
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 | -
611 |
612 |
613 | false
614 |
615 |
616 |
617 | -
618 |
619 |
620 | false
621 |
622 |
623 | Browse
624 |
625 |
626 |
627 | -
628 |
629 |
630 | Save output layer
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 | -
639 |
640 |
641 |
642 | 0
643 | 0
644 |
645 |
646 |
647 |
648 | -
649 |
650 |
651 |
652 | 0
653 | 0
654 |
655 |
656 |
657 |
658 | Algorithm
659 |
660 |
661 |
662 |
663 | Parameter 1
664 |
665 |
666 |
667 |
668 | Parameter 2
669 |
670 |
671 |
672 |
673 | -
674 |
675 |
676 | Add
677 |
678 |
679 |
680 | -
681 |
682 |
683 | Delete
684 |
685 |
686 |
687 | -
688 |
689 |
690 | Edit
691 |
692 |
693 |
694 | -
695 |
696 |
697 | false
698 |
699 |
700 |
701 | -
702 |
703 |
704 | false
705 |
706 |
707 | Browse
708 |
709 |
710 |
711 | -
712 |
713 |
714 | Save output layer(s) to folder
715 |
716 |
717 |
718 | -
719 |
720 |
721 | Algorithm(s)
722 |
723 |
724 |
725 | -
726 |
727 |
728 | Choose layer(s)
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 | cbBatch
740 | cbInput
741 | cbAlgorithm
742 | sbRemove_thresh
743 | cbOutFile
744 | eOutput
745 | bBrowse
746 | bOk
747 | bCancel
748 | sbLang_LA
749 | sbReduction_thresh
750 | sbBoyle_LA
751 | sbChaiken_level
752 | sbChaiken_weight
753 | sbHermite_steps
754 | sbHermite_tightness
755 | sbDist_slide
756 | sbDist_LA
757 | sbSlide_slide
758 | sbSlide_LA
759 | bHelp
760 | sbLang_thresh
761 | sbDP_thresh
762 | lstLayers
763 | tblBatchAlg
764 | bAddAlg
765 | bDelAlg
766 | bEditAlg
767 | eDir
768 | bBrowseDir
769 | cbOutDir
770 |
771 |
772 |
773 |
774 | bCancel
775 | clicked()
776 | generalizer
777 | close()
778 |
779 |
780 | 328
781 | 234
782 |
783 |
784 | 202
785 | 210
786 |
787 |
788 |
789 |
790 |
791 |
--------------------------------------------------------------------------------
/ui_generalizer.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # Form implementation generated from reading ui file 'C:\Documents and Settings\Pocisk\.qgis\python\plugins\generalizer\ui_generalizer.ui'
4 | #
5 | # Created: Tue Sep 13 17:03:23 2011
6 | # by: PyQt4 UI code generator 4.8.3
7 | #
8 | # WARNING! All changes made in this file will be lost!
9 |
10 | from PyQt4 import QtCore, QtGui
11 |
12 | class Ui_generalizer(object):
13 | def setupUi(self, generalizer):
14 | generalizer.setObjectName("generalizer")
15 | generalizer.resize(493, 348)
16 | self.gridLayout_20 = QtGui.QGridLayout(generalizer)
17 | self.gridLayout_20.setObjectName("gridLayout_20")
18 | self.cbBatch = QtGui.QCheckBox(generalizer)
19 | self.cbBatch.setObjectName("cbBatch")
20 | self.gridLayout_20.addWidget(self.cbBatch, 0, 0, 1, 1)
21 | self.bHelp = QtGui.QPushButton(generalizer)
22 | sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Fixed)
23 | sizePolicy.setHorizontalStretch(0)
24 | sizePolicy.setVerticalStretch(0)
25 | sizePolicy.setHeightForWidth(self.bHelp.sizePolicy().hasHeightForWidth())
26 | self.bHelp.setSizePolicy(sizePolicy)
27 | self.bHelp.setFlat(True)
28 | self.bHelp.setObjectName("bHelp")
29 | self.gridLayout_20.addWidget(self.bHelp, 0, 2, 1, 1)
30 | self.bOk = QtGui.QPushButton(generalizer)
31 | sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Fixed)
32 | sizePolicy.setHorizontalStretch(0)
33 | sizePolicy.setVerticalStretch(0)
34 | sizePolicy.setHeightForWidth(self.bOk.sizePolicy().hasHeightForWidth())
35 | self.bOk.setSizePolicy(sizePolicy)
36 | self.bOk.setObjectName("bOk")
37 | self.gridLayout_20.addWidget(self.bOk, 2, 1, 1, 1)
38 | self.bCancel = QtGui.QPushButton(generalizer)
39 | self.bCancel.setObjectName("bCancel")
40 | self.gridLayout_20.addWidget(self.bCancel, 2, 2, 1, 1)
41 | self.stackBatch = QtGui.QStackedWidget(generalizer)
42 | self.stackBatch.setObjectName("stackBatch")
43 | self.page_6 = QtGui.QWidget()
44 | self.page_6.setObjectName("page_6")
45 | self.gridLayout_19 = QtGui.QGridLayout(self.page_6)
46 | self.gridLayout_19.setObjectName("gridLayout_19")
47 | self.label = QtGui.QLabel(self.page_6)
48 | self.label.setObjectName("label")
49 | self.gridLayout_19.addWidget(self.label, 0, 0, 1, 1)
50 | self.cbInput = QtGui.QComboBox(self.page_6)
51 | self.cbInput.setObjectName("cbInput")
52 | self.gridLayout_19.addWidget(self.cbInput, 1, 0, 1, 2)
53 | self.groupBox = QtGui.QGroupBox(self.page_6)
54 | self.groupBox.setObjectName("groupBox")
55 | self.gridLayout_2 = QtGui.QGridLayout(self.groupBox)
56 | self.gridLayout_2.setObjectName("gridLayout_2")
57 | self.label_3 = QtGui.QLabel(self.groupBox)
58 | self.label_3.setObjectName("label_3")
59 | self.gridLayout_2.addWidget(self.label_3, 0, 0, 1, 1)
60 | self.cbAlgorithm = QtGui.QComboBox(self.groupBox)
61 | sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Fixed)
62 | sizePolicy.setHorizontalStretch(0)
63 | sizePolicy.setVerticalStretch(0)
64 | sizePolicy.setHeightForWidth(self.cbAlgorithm.sizePolicy().hasHeightForWidth())
65 | self.cbAlgorithm.setSizePolicy(sizePolicy)
66 | self.cbAlgorithm.setObjectName("cbAlgorithm")
67 | self.cbAlgorithm.addItem("")
68 | self.cbAlgorithm.addItem("")
69 | self.cbAlgorithm.addItem("")
70 | self.cbAlgorithm.addItem("")
71 | self.cbAlgorithm.addItem("")
72 | self.cbAlgorithm.addItem("")
73 | self.cbAlgorithm.addItem("")
74 | self.cbAlgorithm.addItem("")
75 | self.cbAlgorithm.addItem("")
76 | self.cbAlgorithm.addItem("")
77 | self.cbAlgorithm.addItem("")
78 | self.cbAlgorithm.addItem("")
79 | self.cbAlgorithm.addItem("")
80 | self.cbAlgorithm.addItem("")
81 | self.cbAlgorithm.addItem("")
82 | self.gridLayout_2.addWidget(self.cbAlgorithm, 0, 1, 1, 1)
83 | self.stackOptions = QtGui.QStackedWidget(self.groupBox)
84 | self.stackOptions.setObjectName("stackOptions")
85 | self.page_11 = QtGui.QWidget()
86 | self.page_11.setObjectName("page_11")
87 | self.gridLayout_11 = QtGui.QGridLayout(self.page_11)
88 | self.gridLayout_11.setObjectName("gridLayout_11")
89 | self.label_12 = QtGui.QLabel(self.page_11)
90 | self.label_12.setObjectName("label_12")
91 | self.gridLayout_11.addWidget(self.label_12, 0, 0, 1, 1)
92 | self.sbRemove_thresh = QtGui.QDoubleSpinBox(self.page_11)
93 | self.sbRemove_thresh.setDecimals(4)
94 | self.sbRemove_thresh.setMinimum(0.0001)
95 | self.sbRemove_thresh.setMaximum(9999999.9999)
96 | self.sbRemove_thresh.setProperty("value", 0.0001)
97 | self.sbRemove_thresh.setObjectName("sbRemove_thresh")
98 | self.gridLayout_11.addWidget(self.sbRemove_thresh, 0, 1, 1, 1)
99 | self.stackOptions.addWidget(self.page_11)
100 | self.page_12 = QtGui.QWidget()
101 | self.page_12.setObjectName("page_12")
102 | self.gridLayout_12 = QtGui.QGridLayout(self.page_12)
103 | self.gridLayout_12.setObjectName("gridLayout_12")
104 | self.label_18 = QtGui.QLabel(self.page_12)
105 | self.label_18.setObjectName("label_18")
106 | self.gridLayout_12.addWidget(self.label_18, 0, 0, 1, 1)
107 | self.sbDP_thresh = QtGui.QDoubleSpinBox(self.page_12)
108 | self.sbDP_thresh.setDecimals(4)
109 | self.sbDP_thresh.setMinimum(0.0001)
110 | self.sbDP_thresh.setMaximum(9999999.9999)
111 | self.sbDP_thresh.setProperty("value", 0.0001)
112 | self.sbDP_thresh.setObjectName("sbDP_thresh")
113 | self.gridLayout_12.addWidget(self.sbDP_thresh, 0, 1, 1, 1)
114 | self.stackOptions.addWidget(self.page_12)
115 | self.page_2 = QtGui.QWidget()
116 | self.page_2.setObjectName("page_2")
117 | self.gridLayout_4 = QtGui.QGridLayout(self.page_2)
118 | self.gridLayout_4.setObjectName("gridLayout_4")
119 | self.label_7 = QtGui.QLabel(self.page_2)
120 | self.label_7.setObjectName("label_7")
121 | self.gridLayout_4.addWidget(self.label_7, 0, 0, 1, 1)
122 | self.sbJenks_thresh = QtGui.QDoubleSpinBox(self.page_2)
123 | self.sbJenks_thresh.setDecimals(4)
124 | self.sbJenks_thresh.setMaximum(9999999.9999)
125 | self.sbJenks_thresh.setProperty("value", 0.0001)
126 | self.sbJenks_thresh.setObjectName("sbJenks_thresh")
127 | self.gridLayout_4.addWidget(self.sbJenks_thresh, 0, 1, 1, 1)
128 | self.label_8 = QtGui.QLabel(self.page_2)
129 | self.label_8.setObjectName("label_8")
130 | self.gridLayout_4.addWidget(self.label_8, 1, 0, 1, 1)
131 | self.sbJenks_angle = QtGui.QDoubleSpinBox(self.page_2)
132 | self.sbJenks_angle.setMaximum(180.0)
133 | self.sbJenks_angle.setProperty("value", 3.0)
134 | self.sbJenks_angle.setObjectName("sbJenks_angle")
135 | self.gridLayout_4.addWidget(self.sbJenks_angle, 1, 1, 1, 1)
136 | self.stackOptions.addWidget(self.page_2)
137 | self.page_13 = QtGui.QWidget()
138 | self.page_13.setObjectName("page_13")
139 | self.gridLayout_3 = QtGui.QGridLayout(self.page_13)
140 | self.gridLayout_3.setObjectName("gridLayout_3")
141 | self.label_13 = QtGui.QLabel(self.page_13)
142 | self.label_13.setObjectName("label_13")
143 | self.gridLayout_3.addWidget(self.label_13, 0, 0, 1, 1)
144 | self.sbLang_thresh = QtGui.QDoubleSpinBox(self.page_13)
145 | self.sbLang_thresh.setDecimals(4)
146 | self.sbLang_thresh.setMinimum(0.0001)
147 | self.sbLang_thresh.setMaximum(9999999.9999)
148 | self.sbLang_thresh.setProperty("value", 0.0001)
149 | self.sbLang_thresh.setObjectName("sbLang_thresh")
150 | self.gridLayout_3.addWidget(self.sbLang_thresh, 0, 1, 1, 1)
151 | self.label_19 = QtGui.QLabel(self.page_13)
152 | self.label_19.setObjectName("label_19")
153 | self.gridLayout_3.addWidget(self.label_19, 1, 0, 1, 1)
154 | self.sbLang_LA = QtGui.QSpinBox(self.page_13)
155 | self.sbLang_LA.setMinimum(1)
156 | self.sbLang_LA.setMaximum(9999)
157 | self.sbLang_LA.setProperty("value", 8)
158 | self.sbLang_LA.setObjectName("sbLang_LA")
159 | self.gridLayout_3.addWidget(self.sbLang_LA, 1, 1, 1, 1)
160 | self.stackOptions.addWidget(self.page_13)
161 | self.page_4 = QtGui.QWidget()
162 | self.page_4.setObjectName("page_4")
163 | self.gridLayout_6 = QtGui.QGridLayout(self.page_4)
164 | self.gridLayout_6.setObjectName("gridLayout_6")
165 | self.label_11 = QtGui.QLabel(self.page_4)
166 | self.label_11.setObjectName("label_11")
167 | self.gridLayout_6.addWidget(self.label_11, 0, 0, 1, 1)
168 | self.sbRW_thresh = QtGui.QDoubleSpinBox(self.page_4)
169 | self.sbRW_thresh.setDecimals(4)
170 | self.sbRW_thresh.setMaximum(9999999.9999)
171 | self.sbRW_thresh.setProperty("value", 0.0001)
172 | self.sbRW_thresh.setObjectName("sbRW_thresh")
173 | self.gridLayout_6.addWidget(self.sbRW_thresh, 0, 1, 1, 1)
174 | self.stackOptions.addWidget(self.page_4)
175 | self.page_14 = QtGui.QWidget()
176 | self.page_14.setObjectName("page_14")
177 | self.gridLayout_14 = QtGui.QGridLayout(self.page_14)
178 | self.gridLayout_14.setObjectName("gridLayout_14")
179 | self.label_20 = QtGui.QLabel(self.page_14)
180 | self.label_20.setObjectName("label_20")
181 | self.gridLayout_14.addWidget(self.label_20, 0, 0, 1, 1)
182 | self.sbReduction_thresh = QtGui.QDoubleSpinBox(self.page_14)
183 | self.sbReduction_thresh.setDecimals(4)
184 | self.sbReduction_thresh.setMinimum(0.0001)
185 | self.sbReduction_thresh.setMaximum(9999999.9999)
186 | self.sbReduction_thresh.setObjectName("sbReduction_thresh")
187 | self.gridLayout_14.addWidget(self.sbReduction_thresh, 0, 1, 1, 1)
188 | self.stackOptions.addWidget(self.page_14)
189 | self.page_15 = QtGui.QWidget()
190 | self.page_15.setObjectName("page_15")
191 | self.gridLayout_15 = QtGui.QGridLayout(self.page_15)
192 | self.gridLayout_15.setObjectName("gridLayout_15")
193 | self.label_21 = QtGui.QLabel(self.page_15)
194 | self.label_21.setObjectName("label_21")
195 | self.gridLayout_15.addWidget(self.label_21, 0, 0, 1, 1)
196 | self.sbBoyle_LA = QtGui.QSpinBox(self.page_15)
197 | self.sbBoyle_LA.setMinimum(2)
198 | self.sbBoyle_LA.setMaximum(999)
199 | self.sbBoyle_LA.setProperty("value", 7)
200 | self.sbBoyle_LA.setObjectName("sbBoyle_LA")
201 | self.gridLayout_15.addWidget(self.sbBoyle_LA, 0, 1, 1, 1)
202 | self.stackOptions.addWidget(self.page_15)
203 | self.page_16 = QtGui.QWidget()
204 | self.page_16.setObjectName("page_16")
205 | self.gridLayout_16 = QtGui.QGridLayout(self.page_16)
206 | self.gridLayout_16.setObjectName("gridLayout_16")
207 | self.label_22 = QtGui.QLabel(self.page_16)
208 | self.label_22.setObjectName("label_22")
209 | self.gridLayout_16.addWidget(self.label_22, 0, 0, 1, 1)
210 | self.sbChaiken_level = QtGui.QSpinBox(self.page_16)
211 | self.sbChaiken_level.setMinimum(1)
212 | self.sbChaiken_level.setMaximum(99)
213 | self.sbChaiken_level.setObjectName("sbChaiken_level")
214 | self.gridLayout_16.addWidget(self.sbChaiken_level, 0, 1, 1, 1)
215 | self.label_23 = QtGui.QLabel(self.page_16)
216 | self.label_23.setObjectName("label_23")
217 | self.gridLayout_16.addWidget(self.label_23, 1, 0, 1, 1)
218 | self.sbChaiken_weight = QtGui.QDoubleSpinBox(self.page_16)
219 | self.sbChaiken_weight.setMinimum(1.0)
220 | self.sbChaiken_weight.setProperty("value", 3.0)
221 | self.sbChaiken_weight.setObjectName("sbChaiken_weight")
222 | self.gridLayout_16.addWidget(self.sbChaiken_weight, 1, 1, 1, 1)
223 | self.stackOptions.addWidget(self.page_16)
224 | self.page = QtGui.QWidget()
225 | self.page.setObjectName("page")
226 | self.gridLayout = QtGui.QGridLayout(self.page)
227 | self.gridLayout.setObjectName("gridLayout")
228 | self.label_2 = QtGui.QLabel(self.page)
229 | self.label_2.setObjectName("label_2")
230 | self.gridLayout.addWidget(self.label_2, 0, 0, 1, 1)
231 | self.label_4 = QtGui.QLabel(self.page)
232 | self.label_4.setObjectName("label_4")
233 | self.gridLayout.addWidget(self.label_4, 1, 0, 1, 1)
234 | self.sbHermite_tightness = QtGui.QDoubleSpinBox(self.page)
235 | self.sbHermite_tightness.setProperty("value", 0.5)
236 | self.sbHermite_tightness.setObjectName("sbHermite_tightness")
237 | self.gridLayout.addWidget(self.sbHermite_tightness, 1, 1, 1, 1)
238 | self.sbHermite_steps = QtGui.QDoubleSpinBox(self.page)
239 | self.sbHermite_steps.setDecimals(4)
240 | self.sbHermite_steps.setMaximum(9999999.9999)
241 | self.sbHermite_steps.setProperty("value", 0.0001)
242 | self.sbHermite_steps.setObjectName("sbHermite_steps")
243 | self.gridLayout.addWidget(self.sbHermite_steps, 0, 1, 1, 1)
244 | self.stackOptions.addWidget(self.page)
245 | self.page_17 = QtGui.QWidget()
246 | self.page_17.setObjectName("page_17")
247 | self.gridLayout_17 = QtGui.QGridLayout(self.page_17)
248 | self.gridLayout_17.setObjectName("gridLayout_17")
249 | self.label_24 = QtGui.QLabel(self.page_17)
250 | self.label_24.setObjectName("label_24")
251 | self.gridLayout_17.addWidget(self.label_24, 0, 0, 1, 1)
252 | self.sbDist_slide = QtGui.QDoubleSpinBox(self.page_17)
253 | self.sbDist_slide.setSingleStep(0.1)
254 | self.sbDist_slide.setProperty("value", 0.5)
255 | self.sbDist_slide.setObjectName("sbDist_slide")
256 | self.gridLayout_17.addWidget(self.sbDist_slide, 0, 1, 1, 1)
257 | self.label_25 = QtGui.QLabel(self.page_17)
258 | self.label_25.setObjectName("label_25")
259 | self.gridLayout_17.addWidget(self.label_25, 1, 0, 1, 1)
260 | self.sbDist_LA = QtGui.QSpinBox(self.page_17)
261 | self.sbDist_LA.setMinimum(3)
262 | self.sbDist_LA.setMaximum(999)
263 | self.sbDist_LA.setSingleStep(2)
264 | self.sbDist_LA.setProperty("value", 7)
265 | self.sbDist_LA.setObjectName("sbDist_LA")
266 | self.gridLayout_17.addWidget(self.sbDist_LA, 1, 1, 1, 1)
267 | self.stackOptions.addWidget(self.page_17)
268 | self.page_18 = QtGui.QWidget()
269 | self.page_18.setObjectName("page_18")
270 | self.gridLayout_18 = QtGui.QGridLayout(self.page_18)
271 | self.gridLayout_18.setObjectName("gridLayout_18")
272 | self.label_26 = QtGui.QLabel(self.page_18)
273 | self.label_26.setObjectName("label_26")
274 | self.gridLayout_18.addWidget(self.label_26, 0, 0, 1, 1)
275 | self.sbSlide_slide = QtGui.QDoubleSpinBox(self.page_18)
276 | self.sbSlide_slide.setSingleStep(0.1)
277 | self.sbSlide_slide.setProperty("value", 0.5)
278 | self.sbSlide_slide.setObjectName("sbSlide_slide")
279 | self.gridLayout_18.addWidget(self.sbSlide_slide, 0, 1, 1, 1)
280 | self.label_27 = QtGui.QLabel(self.page_18)
281 | self.label_27.setObjectName("label_27")
282 | self.gridLayout_18.addWidget(self.label_27, 1, 0, 1, 1)
283 | self.sbSlide_LA = QtGui.QSpinBox(self.page_18)
284 | self.sbSlide_LA.setMinimum(3)
285 | self.sbSlide_LA.setMaximum(999)
286 | self.sbSlide_LA.setSingleStep(2)
287 | self.sbSlide_LA.setProperty("value", 7)
288 | self.sbSlide_LA.setObjectName("sbSlide_LA")
289 | self.gridLayout_18.addWidget(self.sbSlide_LA, 1, 1, 1, 1)
290 | self.stackOptions.addWidget(self.page_18)
291 | self.page_3 = QtGui.QWidget()
292 | self.page_3.setObjectName("page_3")
293 | self.gridLayout_5 = QtGui.QGridLayout(self.page_3)
294 | self.gridLayout_5.setObjectName("gridLayout_5")
295 | self.label_9 = QtGui.QLabel(self.page_3)
296 | self.label_9.setObjectName("label_9")
297 | self.gridLayout_5.addWidget(self.label_9, 0, 0, 1, 1)
298 | self.sbSnakes_alpha = QtGui.QDoubleSpinBox(self.page_3)
299 | self.sbSnakes_alpha.setMaximum(9999.99)
300 | self.sbSnakes_alpha.setProperty("value", 1.0)
301 | self.sbSnakes_alpha.setObjectName("sbSnakes_alpha")
302 | self.gridLayout_5.addWidget(self.sbSnakes_alpha, 0, 1, 1, 1)
303 | self.label_10 = QtGui.QLabel(self.page_3)
304 | self.label_10.setObjectName("label_10")
305 | self.gridLayout_5.addWidget(self.label_10, 1, 0, 1, 1)
306 | self.sbSnakes_beta = QtGui.QDoubleSpinBox(self.page_3)
307 | self.sbSnakes_beta.setMaximum(9999.99)
308 | self.sbSnakes_beta.setProperty("value", 0.5)
309 | self.sbSnakes_beta.setObjectName("sbSnakes_beta")
310 | self.gridLayout_5.addWidget(self.sbSnakes_beta, 1, 1, 1, 1)
311 | self.stackOptions.addWidget(self.page_3)
312 | self.gridLayout_2.addWidget(self.stackOptions, 1, 0, 1, 2)
313 | self.gridLayout_19.addWidget(self.groupBox, 2, 0, 1, 2)
314 | self.eOutput = QtGui.QLineEdit(self.page_6)
315 | self.eOutput.setEnabled(False)
316 | self.eOutput.setObjectName("eOutput")
317 | self.gridLayout_19.addWidget(self.eOutput, 4, 0, 1, 1)
318 | self.bBrowse = QtGui.QPushButton(self.page_6)
319 | self.bBrowse.setEnabled(False)
320 | self.bBrowse.setObjectName("bBrowse")
321 | self.gridLayout_19.addWidget(self.bBrowse, 4, 1, 1, 1)
322 | self.cbOutFile = QtGui.QCheckBox(self.page_6)
323 | self.cbOutFile.setObjectName("cbOutFile")
324 | self.gridLayout_19.addWidget(self.cbOutFile, 3, 0, 1, 1)
325 | self.stackBatch.addWidget(self.page_6)
326 | self.page_10 = QtGui.QWidget()
327 | self.page_10.setObjectName("page_10")
328 | self.gridLayout_21 = QtGui.QGridLayout(self.page_10)
329 | self.gridLayout_21.setObjectName("gridLayout_21")
330 | self.lstLayers = QtGui.QListWidget(self.page_10)
331 | sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
332 | sizePolicy.setHorizontalStretch(0)
333 | sizePolicy.setVerticalStretch(0)
334 | sizePolicy.setHeightForWidth(self.lstLayers.sizePolicy().hasHeightForWidth())
335 | self.lstLayers.setSizePolicy(sizePolicy)
336 | self.lstLayers.setObjectName("lstLayers")
337 | self.gridLayout_21.addWidget(self.lstLayers, 1, 0, 1, 1)
338 | self.tblBatchAlg = QtGui.QTableWidget(self.page_10)
339 | sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
340 | sizePolicy.setHorizontalStretch(0)
341 | sizePolicy.setVerticalStretch(0)
342 | sizePolicy.setHeightForWidth(self.tblBatchAlg.sizePolicy().hasHeightForWidth())
343 | self.tblBatchAlg.setSizePolicy(sizePolicy)
344 | self.tblBatchAlg.setObjectName("tblBatchAlg")
345 | self.tblBatchAlg.setColumnCount(3)
346 | self.tblBatchAlg.setRowCount(0)
347 | item = QtGui.QTableWidgetItem()
348 | self.tblBatchAlg.setHorizontalHeaderItem(0, item)
349 | item = QtGui.QTableWidgetItem()
350 | self.tblBatchAlg.setHorizontalHeaderItem(1, item)
351 | item = QtGui.QTableWidgetItem()
352 | self.tblBatchAlg.setHorizontalHeaderItem(2, item)
353 | self.gridLayout_21.addWidget(self.tblBatchAlg, 3, 0, 3, 1)
354 | self.bAddAlg = QtGui.QPushButton(self.page_10)
355 | self.bAddAlg.setObjectName("bAddAlg")
356 | self.gridLayout_21.addWidget(self.bAddAlg, 3, 1, 1, 1)
357 | self.bDelAlg = QtGui.QPushButton(self.page_10)
358 | self.bDelAlg.setObjectName("bDelAlg")
359 | self.gridLayout_21.addWidget(self.bDelAlg, 4, 1, 1, 1)
360 | self.bEditAlg = QtGui.QPushButton(self.page_10)
361 | self.bEditAlg.setObjectName("bEditAlg")
362 | self.gridLayout_21.addWidget(self.bEditAlg, 5, 1, 1, 1)
363 | self.eDir = QtGui.QLineEdit(self.page_10)
364 | self.eDir.setEnabled(False)
365 | self.eDir.setObjectName("eDir")
366 | self.gridLayout_21.addWidget(self.eDir, 7, 0, 1, 1)
367 | self.bBrowseDir = QtGui.QPushButton(self.page_10)
368 | self.bBrowseDir.setEnabled(False)
369 | self.bBrowseDir.setObjectName("bBrowseDir")
370 | self.gridLayout_21.addWidget(self.bBrowseDir, 7, 1, 1, 1)
371 | self.cbOutDir = QtGui.QCheckBox(self.page_10)
372 | self.cbOutDir.setObjectName("cbOutDir")
373 | self.gridLayout_21.addWidget(self.cbOutDir, 6, 0, 1, 1)
374 | self.label_5 = QtGui.QLabel(self.page_10)
375 | self.label_5.setObjectName("label_5")
376 | self.gridLayout_21.addWidget(self.label_5, 2, 0, 1, 1)
377 | self.label_6 = QtGui.QLabel(self.page_10)
378 | self.label_6.setObjectName("label_6")
379 | self.gridLayout_21.addWidget(self.label_6, 0, 0, 1, 1)
380 | self.stackBatch.addWidget(self.page_10)
381 | self.gridLayout_20.addWidget(self.stackBatch, 1, 0, 1, 3)
382 | self.label.setBuddy(self.cbInput)
383 | self.label_12.setBuddy(self.sbRemove_thresh)
384 |
385 | self.retranslateUi(generalizer)
386 | self.stackBatch.setCurrentIndex(0)
387 | self.cbAlgorithm.setCurrentIndex(1)
388 | self.stackOptions.setCurrentIndex(0)
389 | self.bCancel.clicked.connect( generalizer.close )
390 | QtCore.QMetaObject.connectSlotsByName(generalizer)
391 | generalizer.setTabOrder(self.cbBatch, self.cbInput)
392 | generalizer.setTabOrder(self.cbInput, self.cbAlgorithm)
393 | generalizer.setTabOrder(self.cbAlgorithm, self.sbRemove_thresh)
394 | generalizer.setTabOrder(self.sbRemove_thresh, self.cbOutFile)
395 | generalizer.setTabOrder(self.cbOutFile, self.eOutput)
396 | generalizer.setTabOrder(self.eOutput, self.bBrowse)
397 | generalizer.setTabOrder(self.bBrowse, self.bOk)
398 | generalizer.setTabOrder(self.bOk, self.bCancel)
399 | generalizer.setTabOrder(self.bCancel, self.sbLang_LA)
400 | generalizer.setTabOrder(self.sbLang_LA, self.sbReduction_thresh)
401 | generalizer.setTabOrder(self.sbReduction_thresh, self.sbBoyle_LA)
402 | generalizer.setTabOrder(self.sbBoyle_LA, self.sbChaiken_level)
403 | generalizer.setTabOrder(self.sbChaiken_level, self.sbChaiken_weight)
404 | generalizer.setTabOrder(self.sbChaiken_weight, self.sbHermite_steps)
405 | generalizer.setTabOrder(self.sbHermite_steps, self.sbHermite_tightness)
406 | generalizer.setTabOrder(self.sbHermite_tightness, self.sbDist_slide)
407 | generalizer.setTabOrder(self.sbDist_slide, self.sbDist_LA)
408 | generalizer.setTabOrder(self.sbDist_LA, self.sbSlide_slide)
409 | generalizer.setTabOrder(self.sbSlide_slide, self.sbSlide_LA)
410 | generalizer.setTabOrder(self.sbSlide_LA, self.bHelp)
411 | generalizer.setTabOrder(self.bHelp, self.sbLang_thresh)
412 | generalizer.setTabOrder(self.sbLang_thresh, self.sbDP_thresh)
413 | generalizer.setTabOrder(self.sbDP_thresh, self.lstLayers)
414 | generalizer.setTabOrder(self.lstLayers, self.tblBatchAlg)
415 | generalizer.setTabOrder(self.tblBatchAlg, self.bAddAlg)
416 | generalizer.setTabOrder(self.bAddAlg, self.bDelAlg)
417 | generalizer.setTabOrder(self.bDelAlg, self.bEditAlg)
418 | generalizer.setTabOrder(self.bEditAlg, self.eDir)
419 | generalizer.setTabOrder(self.eDir, self.bBrowseDir)
420 | generalizer.setTabOrder(self.bBrowseDir, self.cbOutDir)
421 |
422 | def retranslateUi(self, generalizer):
423 | generalizer.setWindowTitle(QtGui.QApplication.translate("generalizer", "Generalizer", None, QtGui.QApplication.UnicodeUTF8))
424 | self.cbBatch.setText(QtGui.QApplication.translate("generalizer", "Batch mode", None, QtGui.QApplication.UnicodeUTF8))
425 | self.bHelp.setText(QtGui.QApplication.translate("generalizer", "?", None, QtGui.QApplication.UnicodeUTF8))
426 | self.bOk.setText(QtGui.QApplication.translate("generalizer", "OK", None, QtGui.QApplication.UnicodeUTF8))
427 | self.bCancel.setText(QtGui.QApplication.translate("generalizer", "Close", None, QtGui.QApplication.UnicodeUTF8))
428 | self.label.setText(QtGui.QApplication.translate("generalizer", "Input line layer:", None, QtGui.QApplication.UnicodeUTF8))
429 | self.groupBox.setTitle(QtGui.QApplication.translate("generalizer", "Options", None, QtGui.QApplication.UnicodeUTF8))
430 | self.label_3.setText(QtGui.QApplication.translate("generalizer", "Alghoritm:", None, QtGui.QApplication.UnicodeUTF8))
431 | self.cbAlgorithm.setItemText(0, QtGui.QApplication.translate("generalizer", "-----Generalizing-----", None, QtGui.QApplication.UnicodeUTF8))
432 | self.cbAlgorithm.setItemText(1, QtGui.QApplication.translate("generalizer", "Remove small objects", None, QtGui.QApplication.UnicodeUTF8))
433 | self.cbAlgorithm.setItemText(2, QtGui.QApplication.translate("generalizer", "-----Simplifying-----", None, QtGui.QApplication.UnicodeUTF8))
434 | self.cbAlgorithm.setItemText(3, QtGui.QApplication.translate("generalizer", "Douglas-Peucker Algorithm", None, QtGui.QApplication.UnicodeUTF8))
435 | self.cbAlgorithm.setItemText(4, QtGui.QApplication.translate("generalizer", "Jenk\'s Algorithm", None, QtGui.QApplication.UnicodeUTF8))
436 | self.cbAlgorithm.setItemText(5, QtGui.QApplication.translate("generalizer", "Lang Algorithm", None, QtGui.QApplication.UnicodeUTF8))
437 | self.cbAlgorithm.setItemText(6, QtGui.QApplication.translate("generalizer", "Reumann-Witkam Algorithm", None, QtGui.QApplication.UnicodeUTF8))
438 | self.cbAlgorithm.setItemText(7, QtGui.QApplication.translate("generalizer", "Vertex Reduction", None, QtGui.QApplication.UnicodeUTF8))
439 | self.cbAlgorithm.setItemText(8, QtGui.QApplication.translate("generalizer", "-----Smoothing-----", None, QtGui.QApplication.UnicodeUTF8))
440 | self.cbAlgorithm.setItemText(9, QtGui.QApplication.translate("generalizer", "Boyle\'s Forward-Looking Algorithm", None, QtGui.QApplication.UnicodeUTF8))
441 | self.cbAlgorithm.setItemText(10, QtGui.QApplication.translate("generalizer", "Chaiken\'s Algorithm", None, QtGui.QApplication.UnicodeUTF8))
442 | self.cbAlgorithm.setItemText(11, QtGui.QApplication.translate("generalizer", "Hermite Spline Interpolation", None, QtGui.QApplication.UnicodeUTF8))
443 | self.cbAlgorithm.setItemText(12, QtGui.QApplication.translate("generalizer", "McMaster\'s Distance-Weighting Algorithm", None, QtGui.QApplication.UnicodeUTF8))
444 | self.cbAlgorithm.setItemText(13, QtGui.QApplication.translate("generalizer", "McMaster\'s Sliding Averaging Algorithm", None, QtGui.QApplication.UnicodeUTF8))
445 | self.cbAlgorithm.setItemText(14, QtGui.QApplication.translate("generalizer", "Snakes Algorithm", None, QtGui.QApplication.UnicodeUTF8))
446 | self.label_12.setText(QtGui.QApplication.translate("generalizer", "Threshold:", None, QtGui.QApplication.UnicodeUTF8))
447 | self.label_18.setText(QtGui.QApplication.translate("generalizer", "Threshold:", None, QtGui.QApplication.UnicodeUTF8))
448 | self.label_7.setText(QtGui.QApplication.translate("generalizer", "Threshold:", None, QtGui.QApplication.UnicodeUTF8))
449 | self.label_8.setText(QtGui.QApplication.translate("generalizer", "Angle threshold:", None, QtGui.QApplication.UnicodeUTF8))
450 | self.label_13.setText(QtGui.QApplication.translate("generalizer", "Threshold:", None, QtGui.QApplication.UnicodeUTF8))
451 | self.label_19.setText(QtGui.QApplication.translate("generalizer", "Looka ahead:", None, QtGui.QApplication.UnicodeUTF8))
452 | self.label_11.setText(QtGui.QApplication.translate("generalizer", "Threshold:", None, QtGui.QApplication.UnicodeUTF8))
453 | self.label_20.setText(QtGui.QApplication.translate("generalizer", "Threshold:", None, QtGui.QApplication.UnicodeUTF8))
454 | self.label_21.setText(QtGui.QApplication.translate("generalizer", "Look ahead:", None, QtGui.QApplication.UnicodeUTF8))
455 | self.label_22.setText(QtGui.QApplication.translate("generalizer", "Level:", None, QtGui.QApplication.UnicodeUTF8))
456 | self.label_23.setText(QtGui.QApplication.translate("generalizer", "Weight:", None, QtGui.QApplication.UnicodeUTF8))
457 | self.label_2.setText(QtGui.QApplication.translate("generalizer", "Threshold:", None, QtGui.QApplication.UnicodeUTF8))
458 | self.label_4.setText(QtGui.QApplication.translate("generalizer", "Thightness:", None, QtGui.QApplication.UnicodeUTF8))
459 | self.label_24.setText(QtGui.QApplication.translate("generalizer", "Slide:", None, QtGui.QApplication.UnicodeUTF8))
460 | self.label_25.setText(QtGui.QApplication.translate("generalizer", "Look ahead:", None, QtGui.QApplication.UnicodeUTF8))
461 | self.label_26.setText(QtGui.QApplication.translate("generalizer", "Slide:", None, QtGui.QApplication.UnicodeUTF8))
462 | self.label_27.setText(QtGui.QApplication.translate("generalizer", "Look ahead:", None, QtGui.QApplication.UnicodeUTF8))
463 | self.label_9.setText(QtGui.QApplication.translate("generalizer", "Alpha:", None, QtGui.QApplication.UnicodeUTF8))
464 | self.label_10.setText(QtGui.QApplication.translate("generalizer", "Beta:", None, QtGui.QApplication.UnicodeUTF8))
465 | self.bBrowse.setText(QtGui.QApplication.translate("generalizer", "Browse", None, QtGui.QApplication.UnicodeUTF8))
466 | self.cbOutFile.setText(QtGui.QApplication.translate("generalizer", "Save output layer", None, QtGui.QApplication.UnicodeUTF8))
467 | self.tblBatchAlg.horizontalHeaderItem(0).setText(QtGui.QApplication.translate("generalizer", "Algorithm", None, QtGui.QApplication.UnicodeUTF8))
468 | self.tblBatchAlg.horizontalHeaderItem(1).setText(QtGui.QApplication.translate("generalizer", "Parameter 1", None, QtGui.QApplication.UnicodeUTF8))
469 | self.tblBatchAlg.horizontalHeaderItem(2).setText(QtGui.QApplication.translate("generalizer", "Parameter 2", None, QtGui.QApplication.UnicodeUTF8))
470 | self.bAddAlg.setText(QtGui.QApplication.translate("generalizer", "Add", None, QtGui.QApplication.UnicodeUTF8))
471 | self.bDelAlg.setText(QtGui.QApplication.translate("generalizer", "Delete", None, QtGui.QApplication.UnicodeUTF8))
472 | self.bEditAlg.setText(QtGui.QApplication.translate("generalizer", "Edit", None, QtGui.QApplication.UnicodeUTF8))
473 | self.bBrowseDir.setText(QtGui.QApplication.translate("generalizer", "Browse", None, QtGui.QApplication.UnicodeUTF8))
474 | self.cbOutDir.setText(QtGui.QApplication.translate("generalizer", "Save output layer(s) to folder", None, QtGui.QApplication.UnicodeUTF8))
475 | self.label_5.setText(QtGui.QApplication.translate("generalizer", "Algorithm(s)", None, QtGui.QApplication.UnicodeUTF8))
476 | self.label_6.setText(QtGui.QApplication.translate("generalizer", "Choose layer(s)", None, QtGui.QApplication.UnicodeUTF8))
477 |
478 |
--------------------------------------------------------------------------------
/generalizerdialog.py:
--------------------------------------------------------------------------------
1 | """
2 | /***************************************************************************
3 | generalizerDialog
4 | A QGIS plugin
5 | Lines generalization (smooth and simplify) based on v.generalize GRASS module
6 | -------------------
7 | begin : 2011-08-17
8 | copyright : (C) 2011 by Piotr Pociask
9 | email : ppociask (at) o2 pl
10 | ***************************************************************************/
11 |
12 | /***************************************************************************
13 | * *
14 | * This program is free software; you can redistribute it and/or modify *
15 | * it under the terms of the GNU General Public License as published by *
16 | * the Free Software Foundation; either version 2 of the License, or *
17 | * (at your option) any later version. *
18 | * *
19 | ***************************************************************************/
20 | """
21 |
22 | from PyQt4.QtCore import *
23 | from PyQt4.QtGui import *
24 |
25 | from qgis.core import *
26 | from qgis.gui import *
27 |
28 | import smooth, simplify, points
29 | from dialogs import *
30 |
31 | from ui_generalizer import Ui_generalizer
32 |
33 | #global variable with short to full algorithm names
34 | algorithm = {'remove':'Remove small objects',
35 | 'DP':'Douglas-Peucker Algorithm',
36 | 'lang':'Lang Algorithm',
37 | 'reduction':'Vertex Reduction',
38 | 'boyle':'Boyle\'s Forward-Looking Algorithm',
39 | 'chaiken':'Chaiken\'s Algorithm',
40 | 'hermite':'Hermite Spline Interpolation',
41 | 'distance':'McMaster\'s Distance-Weighting Algorithm',
42 | 'sliding':'McMaster\'s Sliding Averaging Algorithm',
43 | 'snakes':'Snakes Algorithm',
44 | 'jenks':'Jenk\'s Algorithm',
45 | 'RW':'Reumann-Witkam Algorithm'
46 | }
47 |
48 |
49 | class generalizerDialog(QDialog):
50 | def __init__(self, iface):
51 | QDialog.__init__(self)
52 | # Set up the user interface from Designer.
53 | self.ui = Ui_generalizer()
54 | self.ui.setupUi(self)
55 | self.iface = iface
56 |
57 | self.ui.sbJenks_angle.setVisible(False)
58 | self.ui.label_8.setVisible(False)
59 |
60 | #set signals
61 | self.ui.bBrowse.clicked.connect( self.outFile )
62 | self.ui.bBrowseDir.clicked.connect( self.outDir )
63 | self.ui.bOk.clicked.connect( self.generalize )
64 | self.ui.cbAlgorithm.currentIndexChanged.connect( self.cbChange )
65 | self.ui.bHelp.clicked.connect( self.showHelp )
66 | self.ui.cbBatch.stateChanged.connect( self.BatchOn )
67 | self.ui.bAddAlg.clicked.connect( self.AddAlgorithm )
68 | self.ui.bDelAlg.clicked.connect( self.DelAlgorithm )
69 | self.ui.bEditAlg.clicked.connect( self.EditAlgorithm )
70 | self.ui.cbOutFile.stateChanged.connect( self.FileEnabled )
71 | self.ui.cbOutDir.stateChanged.connect( self.DirEnabled )
72 |
73 | #load line layers to lists
74 | self.layerList = getLayersNames()
75 | self.ui.cbInput.addItems(self.layerList)
76 | self.ui.lstLayers.addItems(self.layerList)
77 | [self.ui.lstLayers.item(i).setCheckState(Qt.Unchecked) for i in range(self.ui.lstLayers.count()) ]
78 |
79 | def FileEnabled(self, state):
80 | #enable or disable path to file
81 | enabled = self.ui.eOutput.isEnabled()
82 | self.ui.eOutput.setEnabled(not enabled)
83 | self.ui.bBrowse.setEnabled(not enabled)
84 |
85 | def DirEnabled(self, state):
86 | #enable/disable directory
87 | enabled = self.ui.eDir.isEnabled()
88 | self.ui.eDir.setEnabled(not enabled)
89 | self.ui.bBrowseDir.setEnabled(not enabled)
90 |
91 | def AddAlgorithm(self):
92 | #add new algorithm in batch mode
93 | self.doAddAlgorithm(self.ui.tblBatchAlg.rowCount())
94 |
95 | def EditAlgorithm(self):
96 | #edit algorithm in batch mode
97 | if self.ui.tblBatchAlg.currentRow() == -1:
98 | QMessageBox.warning(self, 'Generalizer', 'Select algorithm to edit!')
99 | return
100 |
101 | self.doAddAlgorithm(self.ui.tblBatchAlg.currentRow())
102 |
103 | def doAddAlgorithm(self, index):
104 | #add new algorithm in batch mode
105 | global algorithm
106 |
107 | new = index > self.ui.tblBatchAlg.rowCount()-1
108 |
109 | items = [self.ui.cbAlgorithm.itemText(i) for i in range(self.ui.cbAlgorithm.count())]
110 | algName = QInputDialog.getItem(None, 'Generalizer', 'Choose algorithm:', items, 1, False)
111 | if not algName[1] or algName[0].startswith('-'): return
112 | #QMessageBox.question(self, 'Generalizer', str(alg))
113 | par1 = None
114 | par2 = None
115 |
116 | if algName[0] == algorithm['boyle']:#Boyle\'s Forward-Looking Algorithm':
117 | par1 = QSpinBox()
118 | par1.setRange(2, 999)
119 | msg = QInputDialog.getInt(None, 'Generalizer', 'Look ahead:', 7, 2)
120 | if not msg[1]: return
121 | par1.setValue(msg[0])
122 | par1.setToolTip('Look ahead')
123 |
124 | elif algName[0] == algorithm['sliding']:#'McMaster\'s Sliding Averaging Algorithm':
125 | par1 = QDoubleSpinBox()
126 | par1.setDecimals(2)
127 | par1.setRange(0, 99.99)
128 | msg = QInputDialog.getDouble(None, 'Generalizer', 'Slide:', 0.5, 0, 99.99)
129 | if not msg[1]: return
130 | par1.setValue(msg[0])
131 | par1.setToolTip('Slide')
132 |
133 | par2 = QSpinBox()
134 | par2.setRange(3, 999)
135 | par2.setSingleStep(2)
136 | par2.setValue(6)
137 | while par2.value()%2 == 0:
138 | msg = QInputDialog.getInt(None, 'Generalizer', 'Look ahead (must be odd number):', par2.value()+1, 3, 999)
139 | if not msg[1]: return
140 | par2.setValue(msg[0])
141 | par2.setToolTip('Look ahead')
142 |
143 |
144 | elif algName[0] == algorithm['distance']:#'McMaster\'s Distance-Weighting Algorithm':
145 | par1 = QDoubleSpinBox()
146 | par1.setDecimals(2)
147 | par1.setRange(0, 99.99)
148 | msg = QInputDialog.getDouble(None, 'Generalizer', 'Slide:', 0.5, 0, 99.99)
149 | if not msg[1]: return
150 | par1.setValue(msg[0])
151 | par1.setToolTip('Slide')
152 |
153 | par2 = QSpinBox()
154 | par2.setRange(3, 999)
155 | par2.setSingleStep(2)
156 | par2.setValue(6)
157 | while par2.value()%2 == 0:
158 | msg = QInputDialog.getInt(None, 'Generalizer', 'Look ahead (must be odd number):', par2.value()+1, 3, 999)
159 | if not msg[1]: return
160 | par2.setValue(msg[0])
161 | par2.setToolTip('Look ahead')
162 |
163 | elif algName[0] == algorithm['chaiken']: #'Chaiken\'s Algorithm':
164 | par1 = QSpinBox()
165 | par1.setRange(0, 99)
166 | msg = QInputDialog.getInt(None, 'Generalizer', 'Level:', 1, 0, 99)
167 | if not msg[1]: return
168 | par1.setValue(msg[0])
169 | par1.setToolTip('Level')
170 |
171 | par2 = QDoubleSpinBox()
172 | par2.setDecimals(2)
173 | par2.setRange(1, 99.99)
174 | msg = QInputDialog.getDouble(None, 'Generalizer', 'Weight:', 3., 1, 99.99)
175 | if not msg[1]: return
176 | par2.setValue(msg[0])
177 | par2.setToolTip('Weight')
178 |
179 | elif algName[0] == algorithm['reduction']:#'Vertex Reduction':
180 | par1 = QDoubleSpinBox()
181 | par1.setDecimals(4)
182 | par1.setRange(0.0001, 9999999.9999)
183 | msg = QInputDialog.getDouble(None, 'Generalizer', 'Threshold:', 0.0001, 0.0001, 9999999.9999, 4)
184 | if not msg[1]: return
185 | par1.setValue(msg[0])
186 | par1.setToolTip('Threshold')
187 |
188 | elif algName[0] == algorithm['DP']:#'Douglas-Peucker Algorithm':
189 | par1 = QDoubleSpinBox()
190 | par1.setDecimals(4)
191 | par1.setRange(0.0001, 9999999.9999)
192 | msg = QInputDialog.getDouble(None, 'Generalizer', 'Threshold:', 0.0001, 0.0001, 9999999.9999, 4)
193 | if not msg[1]: return
194 | par1.setValue(msg[0])
195 | par1.setToolTip('Threshold')
196 |
197 | elif algName[0] == algorithm['remove']:#'Remove small objects':
198 | par1 = QDoubleSpinBox()
199 | par1.setDecimals(4)
200 | par1.setRange(0.0001, 9999999.9999)
201 | msg = QInputDialog.getDouble(None, 'Generalizer', 'Threshold:', 0.0001, 0.0001, 9999999.9999, 4)
202 | if not msg[1]: return
203 | par1.setValue(msg[0])
204 | par1.setToolTip('Threshold')
205 |
206 | elif algName[0] == algorithm['lang']:#'Lang Algorithm':
207 | par1 = QDoubleSpinBox()
208 | par1.setDecimals(2)
209 | par1.setRange(0.0001, 9999999.9999)
210 | msg = QInputDialog.getDouble(None, 'Generalizer', 'Threshold:', 0.0001, 0.0001, 9999999.9999, 4)
211 | if not msg[1]: return
212 | par1.setValue(msg[0])
213 | par1.setToolTip('Threshold')
214 |
215 | par2 = QSpinBox()
216 | par2.setRange(1, 9999)
217 | msg = QInputDialog.getInt(None, 'Generalizer', 'Look ahead:', 8, 1, 999)
218 | if not msg[1]: return
219 | par2.setValue(msg[0])
220 | par2.setToolTip('Look ahead')
221 |
222 |
223 | elif algName[0] == algorithm['hermite']:#'Hermite Spline Interpolation':
224 | par1 = QDoubleSpinBox()
225 | par1.setDecimals(4)
226 | par1.setRange(0.0001, 9999999.9999)
227 | msg = QInputDialog.getDouble(None, 'Generalizer', 'Threshold:', 2., 0.0001, 9999999.9999, 4)
228 | if not msg[1]: return
229 | par1.setValue(msg[0])
230 | par1.setToolTip('Threshold')
231 |
232 | par2 = QDoubleSpinBox()
233 | par2.setDecimals(2)
234 | par2.setRange(0, 1)
235 | msg = QInputDialog.getDouble(None, 'Generalizer', 'Thightness:', 0.5, 0, 1, 2)
236 | if not msg[1]: return
237 | par2.setValue(msg[0])
238 | par2.setToolTip('Thightness')
239 |
240 | elif algName[0] == algorithm['snakes']:#'Snakes algorithm':
241 | par1 = QDoubleSpinBox()
242 | par1.setDecimals(2)
243 | par1.setRange(0, 9999.99)
244 | msg = QInputDialog.getDouble(None, 'Generalizer', 'Alpha:', 1., 0.00, 9999.99, 2)
245 | if not msg[1]: return
246 | par1.setValue(msg[0])
247 | par1.setToolTip('Alpha')
248 |
249 | par2 = QDoubleSpinBox()
250 | par2.setDecimals(2)
251 | par2.setRange(0, 9999.99)
252 | msg = QInputDialog.getDouble(None, 'Generalizer', 'Beta:', 0.5, 0., 9999.99, 2)
253 | if not msg[1]: return
254 | par2.setValue(msg[0])
255 | par2.setToolTip('Beta')
256 |
257 | elif algName[0] == algorithm['jenks']:#'Snakes algorithm':
258 | par1 = QDoubleSpinBox()
259 | par1.setDecimals(4)
260 | par1.setRange(0, 9999999.9999)
261 | msg = QInputDialog.getDouble(None, 'Generalizer', 'Threshold:', 0.0001, 0.00, 9999999.9999, 4)
262 | if not msg[1]: return
263 | par1.setValue(msg[0])
264 | par1.setToolTip('Threshold')
265 |
266 | """par2 = QDoubleSpinBox()
267 | par2.setRange(0, 180)
268 | msg = QInputDialog.getDouble(None, 'Generalizer', 'Angle threshold:', 3, 0., 180, 2)
269 | if not msg[1]: return
270 | par2.setValue(msg[0])
271 | par2.setToolTip('Angle threshold') """
272 |
273 | elif algName[0] == algorithm['RW']:#Reumann-Witkam Algorithm
274 | par1 = QDoubleSpinBox()
275 | par1.setDecimals(4)
276 | par1.setRange(0, 9999999.9999)
277 | msg = QInputDialog.getDouble(None, 'Generalizer', 'Threshold:', 0.0001, 0.00, 9999999.9999, 4)
278 | if not msg[1]: return
279 | par1.setValue(msg[0])
280 | par1.setToolTip('Threshold')
281 |
282 | #QMessageBox.question(self, 'Generalizer', str(type(par1)))
283 | itemAlg = QTableWidgetItem(algName[0])
284 | itemAlg.setFlags(Qt.ItemIsEnabled)
285 |
286 | if new:
287 | self.ui.tblBatchAlg.setRowCount(self.ui.tblBatchAlg.rowCount()+1)
288 |
289 | self.ui.tblBatchAlg.setItem(index, 0, itemAlg)
290 | self.ui.tblBatchAlg.setCellWidget(index, 1, par1)
291 | if par2 == None:
292 | self.ui.tblBatchAlg.setCellWidget(index, 2, None)
293 | par2 = QTableWidgetItem(0)
294 | par2.setFlags(Qt.ItemIsSelectable)
295 | self.ui.tblBatchAlg.setItem(index, 2, par2)
296 | else:
297 | self.ui.tblBatchAlg.setCellWidget(index, 2, par2)
298 |
299 | def DelAlgorithm(self):
300 | #del algorithm in batch mode
301 | if self.ui.tblBatchAlg.currentRow() == -1:
302 | QMessageBox.warning(self, 'Generalizer', 'Select algorithm to delete!')
303 | return
304 |
305 | alg = self.ui.tblBatchAlg.item(self.ui.tblBatchAlg.currentRow(), 0).text()
306 | msg = QMessageBox.question(self, 'Generalizer', 'Do you want to delete %s' % (alg), QMessageBox.Yes | QMessageBox.No)
307 |
308 | if msg == QMessageBox.Yes:
309 | self.ui.tblBatchAlg.removeRow(self.ui.tblBatchAlg.currentRow())
310 |
311 | def BatchOn(self, state):
312 | #set batch mode on/off
313 | if state == 0:
314 | self.ui.stackBatch.setCurrentIndex(0)
315 | else:
316 | self.ui.stackBatch.setCurrentIndex(1)
317 |
318 | def showHelp(self):
319 | #show information about plugin
320 | QMessageBox.information(self, 'Generalizer', """Generalizer
321 | Version 0.5
322 |
323 | Created by
324 | Piotr Pociask
325 |
326 | This plugin is marked as experimental.
327 | If you find any bugs or have suggestions,
328 | please contact with me:
329 | opengis84 (at) gmail (dot) com
330 |
331 | """)
332 |
333 | def outFile(self):
334 | """Open a file save dialog and set the output file path."""
335 | outFilePath = saveDialog(self)
336 | if not outFilePath:
337 | return
338 | self.ui.eOutput.setText(outFilePath)
339 |
340 | def outDir(self):
341 | #select directory to save layer(s) in created batch mode
342 | outPath = openDir(self)
343 | if outPath:
344 | self.ui.eDir.setText(outPath)
345 |
346 | def cbChange(self, index):
347 | #set parameters after algorithm change
348 | if index == 0: self.ui.cbAlgorithm.setCurrentIndex(1)
349 | elif index == 1: self.ui.stackOptions.setCurrentIndex(index-1) #generalization
350 | elif index == 2: self.ui.cbAlgorithm.setCurrentIndex(3)
351 | elif index < 8: self.ui.stackOptions.setCurrentIndex(index-2) #simplify
352 | elif index == 8: self.ui.cbAlgorithm.setCurrentIndex(9)
353 | else: self.ui.stackOptions.setCurrentIndex(index-3) #smooth
354 |
355 |
356 | def GetArguments(self, par1=-1, par2=-1):
357 | #set parameters to algorithm
358 | if not self.ui.cbBatch.checkState():
359 | arguments = {}
360 | arguments['remove_thresh'] = self.ui.sbRemove_thresh.value()
361 | arguments['dp_thresh'] = self.ui.sbDP_thresh.value()
362 | arguments['lang_thresh'] = self.ui.sbLang_thresh.value()
363 | arguments['lang_LA'] = self.ui.sbLang_LA.value()
364 | arguments['reduction_thresh'] = self.ui.sbReduction_thresh.value()
365 | arguments['boyle_LA'] = self.ui.sbBoyle_LA.value()
366 | arguments['slide_slide'] = self.ui.sbSlide_slide.value()
367 | arguments['slide_LA'] = self.ui.sbSlide_LA.value()
368 | arguments['dist_slide'] = self.ui.sbDist_slide.value()
369 | arguments['dist_LA'] = self.ui.sbDist_LA.value()
370 | arguments['chaiken_level'] = self.ui.sbChaiken_level.value()
371 | arguments['chaiken_weight'] = self.ui.sbChaiken_weight.value()
372 | arguments['hermite_thresh'] = self.ui.sbHermite_steps.value()
373 | arguments['hermite_tightness'] = self.ui.sbHermite_tightness.value()
374 | arguments['jenks_thresh'] = self.ui.sbJenks_thresh.value()
375 | arguments['jenks_angle'] = self.ui.sbJenks_angle.value()
376 | arguments['snakes_alpha'] = self.ui.sbSnakes_alpha.value()
377 | arguments['snakes_beta'] = self.ui.sbSnakes_beta.value()
378 | arguments['rw_thresh'] = self.ui.sbRW_thresh.value()
379 | else:
380 | arguments = {}
381 | arguments['remove_thresh'] = par1
382 | arguments['dp_thresh'] = par1
383 | arguments['lang_thresh'] = par1
384 | arguments['lang_LA'] = par2
385 | arguments['reduction_thresh'] = par1
386 | arguments['boyle_LA'] = par1
387 | arguments['slide_slide'] = par1
388 | arguments['slide_LA'] = par2
389 | arguments['dist_slide'] = par1
390 | arguments['dist_LA'] = par2
391 | arguments['chaiken_level'] = par1
392 | arguments['chaiken_weight'] = par2
393 | arguments['hermite_thresh'] = par1
394 | arguments['hermite_tightness'] = par2
395 | arguments['jenks_thresh'] = par1
396 | arguments['jenks_angle'] = par2
397 | arguments['snakes_alpha'] = par1
398 | arguments['snakes_beta'] = par2
399 | arguments['rw_thresh'] = par1
400 |
401 | if (arguments['slide_LA']%2 == 0) or (arguments['dist_LA']%2 == 0):
402 | QMessageBox.critical(None, 'Generalizer', 'Look ehead parameter must be odd number!')
403 | return None
404 | else:
405 | return arguments
406 |
407 | def GetFunction(self, funcName):
408 | #set function from name
409 | global algorithm
410 |
411 | if funcName == algorithm['boyle']:#'Boyle\'s Forward-Looking Algorithm':
412 | return self.boyle
413 | elif funcName == algorithm['sliding']:#'McMaster\'s Sliding Averaging Algorithm':
414 | return self.sliding_averaging
415 | elif funcName == algorithm['distance']:#'McMaster\'s Distance-Weighting Algorithm':
416 | return self.distance_weighting
417 | elif funcName == algorithm['chaiken']:#'Chaiken\'s Algorithm':
418 | return self.chaiken
419 | elif funcName == algorithm['reduction']:#'Vertex Reduction':
420 | return self.vertex_reduction
421 | elif funcName == algorithm['DP']:#'Douglas-Peucker Algorithm':
422 | return self.douglas_peucker
423 | elif funcName == algorithm['remove']:#'Remove small objects':
424 | return self.remove
425 | elif funcName == algorithm['lang']:#'Lang Algorithm':
426 | return self.lang
427 | elif funcName == algorithm['hermite']:#'Hermite Spline Interpolation':
428 | return self.hermite
429 | elif funcName == algorithm['jenks']:#'Jenk's Algorithm':
430 | return self.jenks
431 | elif funcName == algorithm['snakes']:#'Snakes':
432 | return self.snakes
433 | elif funcName == algorithm['RW']:#'Reumann-Witkam Algorithm':
434 | return self.reumann_witkam
435 |
436 | def NameFromFunc(self, func, arguments):
437 | if func == self.boyle:
438 | return '-boyle_LA-' + str(arguments['boyle_LA'])
439 | elif func == self.sliding_averaging:
440 | return '-slide_slide-' + str(arguments['slide_slide']) + '_LA-' + str(arguments['slide_LA'])
441 | elif func == self.distance_weighting:
442 | return '-dist_slide-' + str(arguments['dist_slide']) + '_LA-' + str(arguments['dist_LA'])
443 | elif func == self.chaiken:
444 | return '-chaiken_level-' + str(arguments['chaiken_level']) + '_weight-' + str(arguments['chaiken_weight'])
445 | elif func == self.vertex_reduction:
446 | return '-reduction_thresh-' + str(arguments['reduction_thresh'])
447 | elif func == self.douglas_peucker:
448 | return '-DP_thresh-' + str(arguments['dp_thresh'])
449 | elif func == self.remove:
450 | return '-remove_thresh-' + str(arguments['remove_thresh'])
451 | elif func == self.lang:
452 | return '-lang_thresh-' + str(arguments['lang_thresh']) + '_LA-' + str(arguments['lang_LA'])
453 | elif func == self.hermite:
454 | return '-hermite_thresh-' + str(arguments['hermite_thresh']) + '_tight-' + str(arguments['hermite_tightness'])
455 | elif func == self.jenks:
456 | return '-jenks_thresh-' + str(arguments['jenks_thresh']) + '_angle-' + str(arguments['jenks_angle'])
457 | elif func == self.snakes:
458 | return '-snakes_alpha-' + str(arguments['snakes_alpha']) + '_beta-' + str(arguments['snakes_beta'])
459 | elif func == self.reumann_witkam:
460 | return '-RW_thresh-' + str(arguments['rw_thresh'])
461 |
462 |
463 | def LoadLayers(self, fileList):
464 | #load created layer
465 | msg = QMessageBox.question(self, 'Generalizer', 'New layer(s) created. \n Add to TOC?', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
466 | if msg == QMessageBox.Yes:
467 | for filePath in fileList:
468 | if "\\" in filePath:
469 | out_name = filePath[(len(filePath) - filePath.rfind("\\")) - 1:]
470 | else:
471 | out_name = filePath[(len(filePath) - filePath.rfind("/")) - 1:]
472 |
473 | if out_name.endswith(".shp"):
474 | out_name = out_name[:len(out_name) - 4]
475 |
476 | self.iface.addVectorLayer(filePath, out_name, "ogr")
477 |
478 |
479 | def doGeneralize(self, iLayerName, iLayer, oPath, func, arguments):
480 | #do calculations
481 | fet = QgsFeature()
482 |
483 | iProvider = iLayer.dataProvider()
484 | fields = iProvider.fields()
485 |
486 | if oPath == 'memory': #create memory layer
487 | if iLayer.wkbType() == QGis.WKBLineString:
488 | mLayer = QgsVectorLayer('LineString', iLayerName + '_memory', 'memory')#self.NameFromFunc(func, arguments), 'memory')
489 | else:
490 | mLayer = QgsVectorLayer('MultiLineString', iLayerName + '_memory', 'memory')#self.NameFromFunc(func, arguments), 'memory')
491 |
492 | mProvider = mLayer.dataProvider()
493 | mProvider.addAttributes( [key for key in fields] )
494 |
495 | for feat in iProvider.getFeatures():
496 | geom = feat.geometry()
497 | if geom.isMultipart():
498 | lm = geom.asMultiPolyline()
499 | l = []
500 | for ls in lm:
501 | p = func(ls, **arguments)
502 | l2 = []
503 | for n in range(p.n_points):
504 | l2.append(QgsPoint(p.x[n], p.y[n]))
505 | if len(l2) > 1:
506 | l.append(l2)
507 | if len(l) > 1:
508 | fet.setGeometry(QgsGeometry.fromMultiPolyline(l))
509 | elif len(l) == 1: #jesli z obiektu wieloczesciowego zostaje tylko jedna linia (np. przy usuwaniu malych obiektow)
510 | fet.setGeometry(QgsGeometry.fromPolyline(l[0]))
511 | else:
512 | ls = geom.asPolyline()
513 | p = func(ls, **arguments)
514 | l = []
515 | for n in range(p.n_points):
516 | l.append(QgsPoint(p.x[n], p.y[n]))
517 | if len(l) > 1:
518 | fet.setGeometry(QgsGeometry.fromPolyline(l))
519 | else:
520 | continue #jak linia jest pusta to przejdz do nastepnej
521 | fet.setAttributes(feat.attributes())
522 | mProvider.addFeatures([fet])
523 | mLayer.updateFields()
524 | mLayer.updateExtents()
525 | return mLayer
526 |
527 | else: #write shapefile on disk
528 | writer = QgsVectorFileWriter(oPath, iProvider.encoding(), fields, QGis.WKBLineString, iLayer.crs())
529 | if writer.hasError() != QgsVectorFileWriter.NoError:
530 | QMessageBox.critical(None, 'Generalizer', 'Error when creating shapefile: %s' % (writer.hasError()))
531 |
532 | for feat in iProvider.getFeatures():
533 | geom = feat.geometry()
534 | if geom.isMultipart():
535 | lm = geom.asMultiPolyline()
536 | #QInputDialog.getText( self.iface.mainWindow(), "m", "e", QLineEdit.Normal, str(lm) )
537 | l = []
538 | for ls in lm:
539 | p = func(ls, **arguments)
540 | l2 = []
541 | #QInputDialog.getText( self.iface.mainWindow(), "m", "e", QLineEdit.Normal, str(p.n_points) )
542 | for n in range(p.n_points):
543 | l2.append(QgsPoint(p.x[n], p.y[n]))
544 | if len(l2) > 1:
545 | l.append(l2)
546 | if len(l) > 1:
547 | #QInputDialog.getText( self.iface.mainWindow(), "m", "e", QLineEdit.Normal, str(l) )
548 | fet.setGeometry(QgsGeometry.fromMultiPolyline(l))
549 | else:
550 | ls = geom.asPolyline()
551 | #QInputDialog.getText( self.iface.mainWindow(), "m", "e", QLineEdit.Normal, str(ls) )
552 | p = func(ls, **arguments)
553 | l = []
554 | for n in range(p.n_points):
555 | l.append(QgsPoint(p.x[n], p.y[n]))
556 |
557 | if len(l) > 1:
558 | #QInputDialog.getText( self.iface.mainWindow(), "m", "e", QLineEdit.Normal, str(l) )
559 | fet.setGeometry(QgsGeometry.fromPolyline(l))
560 | fet.setAttributes(feat.attributes())
561 | writer.addFeature(fet)
562 |
563 | del writer
564 | return self.ui.eOutput.text()
565 |
566 |
567 | def batchGeneralize(self, layers):
568 | outNames = []
569 | for layer in layers:
570 | vLayer = getMapLayerByName(layer)
571 | for i in range(self.ui.tblBatchAlg.rowCount()):
572 | #QInputDialog.getText( self.iface.mainWindow(), "m", "e", QLineEdit.Normal, str(i) )
573 | alg = self.ui.tblBatchAlg.item(i, 0).text()
574 | func = self.GetFunction(alg)
575 |
576 | par1 = self.ui.tblBatchAlg.cellWidget(i,1).value()
577 | if not func in [self.remove, self.douglas_peucker, self.vertex_reduction, self.boyle, self.jenks, self.reumann_witkam]:
578 | par2 = self.ui.tblBatchAlg.cellWidget(i,2).value()
579 | else:
580 | par2 = -1
581 | #QInputDialog.getText( self.iface.mainWindow(), "m", "e", QLineEdit.Normal, str(par2) )
582 |
583 | arguments = self.GetArguments(par1, par2)
584 | if self.ui.cbOutDir.isChecked() and i == self.ui.tblBatchAlg.rowCount()-1:
585 | #QInputDialog.getText( self.iface.mainWindow(), "m", "e", QLineEdit.Normal, str(i) )
586 | path = self.ui.eDir.text()
587 | if path.contains("\\"):
588 | out_name = path + '\\' + layer + '_new.shp'
589 | else:
590 | out_name = path + '/' + layer + '_new.shp'
591 | outNames.append(out_name)
592 | vLayer = self.doGeneralize(layer, vLayer, out_name, func, arguments)
593 | else:
594 | vLayer = self.doGeneralize(layer, vLayer, 'memory', func, arguments)
595 |
596 | if not self.ui.cbOutDir.isChecked():
597 | QgsMapLayerRegistry.instance().addMapLayer(vLayer)
598 |
599 | if self.ui.cbOutDir.isChecked():
600 | self.LoadLayers(outNames)
601 |
602 |
603 |
604 | def generalize(self):
605 | if self.ui.cbBatch.isChecked():
606 | if self.ui.cbOutDir.isChecked():
607 | if self.ui.eDir.text() == '':
608 | QMessageBox.critical(None, 'Generalizer', 'Enter output directory!')
609 | return
610 |
611 |
612 | layers = [self.ui.lstLayers.item(i).text() for i in range(self.ui.lstLayers.count()) if self.ui.lstLayers.item(i).checkState() ]
613 | self.batchGeneralize(layers)
614 | #QInputDialog.getText( self.iface.mainWindow(), "m", "e", QLineEdit.Normal, str(layers) )
615 | else:
616 | if self.ui.cbInput.currentText() == '':
617 | QMessageBox.critical(None, 'Generalizer', 'No line layers!')
618 | return
619 |
620 | arguments = self.GetArguments()
621 | #QInputDialog.getText( self.iface.mainWindow(), "m", "e", QLineEdit.Normal, str(arguments) )
622 | if arguments == None:
623 | return
624 |
625 | func = self.GetFunction(self.ui.cbAlgorithm.currentText())
626 | if self.ui.cbOutFile.isChecked():
627 | if self.ui.eOutput.text() == '':
628 | QMessageBox.critical(None, 'Generalizer', 'Enter output file name!')
629 | return
630 | filePath = self.doGeneralize(self.ui.cbInput.currentText(), getMapLayerByName(self.ui.cbInput.currentText()), self.ui.eOutput.text(), func, arguments)
631 | self.LoadLayers([filePath])
632 | else:
633 | mLayer = self.doGeneralize(self.ui.cbInput.currentText(), getMapLayerByName(self.ui.cbInput.currentText()), 'memory', func, arguments)
634 | QgsMapLayerRegistry.instance().addMapLayer(mLayer)
635 |
636 | #self.close()
637 | #refresh layer list
638 | self.layerList = getLayersNames()
639 | self.ui.cbInput.clear()
640 | self.ui.lstLayers.clear()
641 | self.ui.cbInput.addItems(self.layerList)
642 | self.ui.lstLayers.addItems(self.layerList)
643 | [self.ui.lstLayers.item(i).setCheckState(Qt.Unchecked) for i in range(self.ui.lstLayers.count()) ]
644 |
645 | def remove(self, l, **kwargs):
646 | #Remove Small Objects
647 | thresh = kwargs['remove_thresh']
648 | length = 0.
649 | p = points.Vect_new_line_struct(l)
650 | p1 = points.point()
651 | p2 = points.point()
652 |
653 | for i in range(p.n_points-1):
654 | points.point_assign(p, i, p1)
655 | points.point_assign(p, i+1, p2)
656 | length = length + points.point_dist(p1, p2)
657 |
658 | #QInputDialog.getText( self.iface.mainWindow(), "m", "e", QLineEdit.Normal, str( length ) )
659 | if length < thresh:
660 | p.x = []
661 | p.y = []
662 | p.n_points = 0
663 | #QInputDialog.getText( self.iface.mainWindow(), "m", "e", QLineEdit.Normal, str( p.x ) )
664 |
665 | return p
666 |
667 | def boyle(self,l, **kwargs):
668 | #Boyle's Forward-Looking Algorithm
669 | p = points.Vect_new_line_struct(l)
670 | n = smooth.boyle(p, kwargs['boyle_LA'])
671 |
672 | return p
673 |
674 | def sliding_averaging(self,l, **kwargs):
675 | #McMaster's Sliding Averaging Algorithm
676 | p = points.Vect_new_line_struct(l)
677 | n = smooth.sliding_averaging(p, kwargs['slide_slide'], kwargs['slide_LA'])
678 |
679 | return p
680 |
681 | def distance_weighting(self,l, **kwargs):
682 | #McMaster's Distance Weighting Algorithm
683 | p = points.Vect_new_line_struct(l)
684 | n = smooth.distance_weighting(p, kwargs['dist_slide'], kwargs['dist_LA'])
685 |
686 | return p
687 |
688 | def chaiken(self,l, **kwargs):
689 | #Chaiken's Algorithm
690 | p = points.Vect_new_line_struct(l)
691 | #QInputDialog.getText( self.iface.mainWindow(), "m", "e", QLineEdit.Normal, str(p.n_points) )
692 | n = smooth.chaiken(p, kwargs['chaiken_level'], kwargs['chaiken_weight'])
693 |
694 | return p
695 |
696 | def vertex_reduction(self,l, **kwargs):
697 | #Vertex Reduction
698 | #QInputDialog.getText( self.iface.mainWindow(), "m", "e", QLineEdit.Normal, str(l) )
699 | p = points.Vect_new_line_struct(l)
700 | n = simplify.vertex_reduction(p, kwargs['reduction_thresh'])
701 |
702 | return p
703 |
704 | def douglas_peucker(self,l, **kwargs):
705 | #Douglas-peucker Algorithm
706 | tmp = simplify.douglas_peucker(l, kwargs['dp_thresh'])
707 | p = points.Vect_new_line_struct(tmp)
708 |
709 | return p
710 |
711 | def lang(self,l, **kwargs):
712 | #Vertex Reduction
713 | p = points.Vect_new_line_struct(l)
714 | n = simplify.lang(p, kwargs['lang_thresh'], kwargs['lang_LA'])
715 |
716 | return p
717 |
718 | def hermite(self,l, **kwargs):
719 | #Vertex Reduction
720 | p = points.Vect_new_line_struct(l)
721 | n = smooth.hermite(p, kwargs['hermite_thresh'], kwargs['hermite_tightness'])
722 |
723 | return p
724 |
725 | def jenks(self,l, **kwargs):
726 | #Jenk's Algorithm
727 | #QInputDialog.getText( self.iface.mainWindow(), "m", "e", QLineEdit.Normal, str(kwargs['jenks_angle']) )
728 | p = points.Vect_new_line_struct(l)
729 | n = simplify.jenks(p, kwargs['jenks_thresh'], kwargs['jenks_angle'])
730 |
731 | return p
732 |
733 | def snakes(self,l, **kwargs):
734 | #Snakes
735 | p = points.Vect_new_line_struct(l)
736 | n = smooth.snakes(p, kwargs['snakes_alpha'], kwargs['snakes_beta'])
737 |
738 | return p
739 |
740 | def reumann_witkam(self,l, **kwargs):
741 | #Snakes
742 | p = points.Vect_new_line_struct(l)
743 | n = simplify.reumann_witkam(p, kwargs['rw_thresh'])
744 |
745 | return p
746 |
747 |
748 | def getLayersNames():
749 | layermap = QgsMapLayerRegistry.instance().mapLayers()
750 | layerlist = []
751 | for name, layer in layermap.iteritems():
752 | if layer.type() == QgsMapLayer.VectorLayer:
753 | if layer.geometryType() == QGis.Line:
754 | layerlist.append( unicode( layer.name() ) )
755 |
756 | return layerlist
757 |
758 | def getMapLayerByName(myName):
759 | layermap = QgsMapLayerRegistry.instance().mapLayers()
760 | for name, layer in layermap.iteritems():
761 | if layer.name() == myName:
762 | if layer.isValid():
763 | return layer
764 | else:
765 | return None
766 |
--------------------------------------------------------------------------------