mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-06 00:07:29 -04:00
add two new tools - polygon from layer extent - delaunay triangulaltion
changes to menu item - sampling tools -> research tools git-svn-id: http://svn.osgeo.org/qgis/trunk@10265 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
86adf97cc7
commit
f882040718
@ -97,8 +97,8 @@ class fToolsPlugin:
|
||||
self.analysisMenu.addActions( [ self.distMatrix, self.sumLines, self.pointsPoly,
|
||||
self.listUnique, self.compStats, self.nearestNeigh, self.meanCoords, self.intLines ] )
|
||||
|
||||
self.samplingMenu = QMenu( QCoreApplication.translate( "fTools", "&Sampling Tools" ) )
|
||||
self.samplingMenu.setIcon( QIcon( self.getThemeIcon( "sampling.png" ) ) )
|
||||
self.researchMenu = QMenu( QCoreApplication.translate( "fTools", "&Research Tools" ) )
|
||||
self.researchMenu.setIcon( QIcon( self.getThemeIcon( "sampling.png" ) ) )
|
||||
self.randSel = QAction( QIcon( self.getThemeIcon( "random_selection.png" ) ),
|
||||
QCoreApplication.translate( "fTools", "Random selection" ),self.iface.mainWindow() )
|
||||
self.randSub = QAction( QIcon( self.getThemeIcon( "sub_selection.png" ) ),
|
||||
@ -111,8 +111,10 @@ class fToolsPlugin:
|
||||
QCoreApplication.translate( "fTools", "Vector grid" ), self.iface.mainWindow() )
|
||||
self.selectLocation = QAction( QIcon( self.getThemeIcon( "select_location.png" ) ),
|
||||
QCoreApplication.translate( "fTools", "Select by location" ), self.iface.mainWindow() )
|
||||
self.samplingMenu.addActions( [ self.randSel, self.randSub, self.randPoints,
|
||||
self.regPoints, self.vectGrid, self.selectLocation ] )
|
||||
self.layerExtent = QAction( QIcon( self.getThemeIcon( "layer_extent.png" ) ),
|
||||
QCoreApplication.translate( "fTools", "Polygon from layer extent" ), self.iface.mainWindow() )
|
||||
self.researchMenu.addActions( [ self.randSel, self.randSub, self.randPoints,
|
||||
self.regPoints, self.vectGrid, self.selectLocation, self.layerExtent ] )
|
||||
|
||||
self.geoMenu = QMenu( QCoreApplication.translate( "fTools", "&Geoprocessing Tools" ) )
|
||||
self.geoMenu.setIcon( QIcon( self.getThemeIcon( "geoprocessing.png" ) ) )
|
||||
@ -143,6 +145,8 @@ class fToolsPlugin:
|
||||
QCoreApplication.translate( "fTools", "Check geometry validity" ),self.iface.mainWindow() )
|
||||
self.centroids = QAction( QIcon( self.getThemeIcon( "centroids.png") ),
|
||||
QCoreApplication.translate( "fTools", "Polygon centroids" ),self.iface.mainWindow() )
|
||||
self.delaunay = QAction( QIcon( self.getThemeIcon( "delaunay.png") ),
|
||||
QCoreApplication.translate( "fTools", "Delaunay triangulation" ),self.iface.mainWindow() )
|
||||
self.extNodes = QAction( QIcon( self.getThemeIcon( "extract_nodes.png") ),
|
||||
QCoreApplication.translate( "fTools", "Extract nodes" ),self.iface.mainWindow() )
|
||||
self.simplify = QAction( QIcon( self.getThemeIcon( "simplify.png") ),
|
||||
@ -153,8 +157,8 @@ class fToolsPlugin:
|
||||
QCoreApplication.translate( "fTools", "Singleparts to multipart" ),self.iface.mainWindow() )
|
||||
self.polysToLines = QAction( QIcon( self.getThemeIcon( "to_lines.png") ),
|
||||
QCoreApplication.translate( "fTools", "Polygons to lines" ),self.iface.mainWindow() )
|
||||
self.conversionMenu.addActions( [ self.checkGeom, self.compGeo, self.centroids, self.simplify,
|
||||
self.multiToSingle, self.singleToMulti, self.polysToLines, self.extNodes ] )
|
||||
self.conversionMenu.addActions( [ self.checkGeom, self.compGeo, self.centroids, self.delaunay,
|
||||
self.simplify, self.multiToSingle, self.singleToMulti, self.polysToLines, self.extNodes] )
|
||||
|
||||
self.dataManageMenu = QMenu( QCoreApplication.translate( "fTools", "&Data Management Tools") )
|
||||
self.dataManageMenu.setIcon( QIcon( self.getThemeIcon( "management.png") ) )
|
||||
@ -170,21 +174,21 @@ class fToolsPlugin:
|
||||
QCoreApplication.translate( "fTools", "Split vector layer" ), self.iface.mainWindow() )
|
||||
self.dataManageMenu.addActions( [ self.project, self.define, self.joinAttr, self.spatJoin, self.splitVect ] )
|
||||
|
||||
self.ftools_about = QAction( QIcon( self.getThemeIcon( "ftools_logo.png" ) ),
|
||||
QCoreApplication.translate( "fTools", "About fTools" ), self.iface.mainWindow() )
|
||||
self.ftools_aboot = QAction( QIcon( self.getThemeIcon( "ftools_logo.png" ) ),
|
||||
QCoreApplication.translate( "fTools", "fTools About" ), self.iface.mainWindow() )
|
||||
|
||||
self.menu.addMenu( self.analysisMenu )
|
||||
self.menu.addMenu( self.samplingMenu )
|
||||
self.menu.addMenu( self.researchMenu )
|
||||
self.menu.addMenu( self.geoMenu )
|
||||
self.menu.addMenu( self.conversionMenu )
|
||||
self.menu.addMenu( self.dataManageMenu )
|
||||
self.menu.addSeparator()
|
||||
self.menu.addAction( self.ftools_about )
|
||||
self.menu.addAction( self.ftools_aboot )
|
||||
|
||||
menuBar = self.iface.mainWindow().menuBar()
|
||||
actions = menuBar.actions()
|
||||
helpAction = actions[ len( actions ) - 1 ]
|
||||
menuBar.insertMenu( helpAction, self.menu )
|
||||
lastAction = actions[ len( actions ) - 1 ]
|
||||
menuBar.insertMenu( lastAction, self.menu )
|
||||
|
||||
QObject.connect( self.distMatrix, SIGNAL("triggered()"), self.dodistMatrix )
|
||||
QObject.connect( self.sumLines, SIGNAL("triggered()"), self.dosumLines )
|
||||
@ -201,6 +205,7 @@ class fToolsPlugin:
|
||||
QObject.connect( self.regPoints, SIGNAL("triggered()"), self.doregPoints )
|
||||
QObject.connect( self.vectGrid, SIGNAL("triggered()"), self.dovectGrid )
|
||||
QObject.connect( self.selectLocation, SIGNAL("triggered()"), self.doselectLocation )
|
||||
QObject.connect( self.layerExtent, SIGNAL("triggered()"), self.doextent )
|
||||
|
||||
QObject.connect( self.minConvex, SIGNAL("triggered()"), self.dominConvex )
|
||||
QObject.connect( self.intersect, SIGNAL("triggered()"), self.dointersect )
|
||||
@ -216,6 +221,7 @@ class fToolsPlugin:
|
||||
QObject.connect( self.checkGeom, SIGNAL("triggered()"), self.docheckGeom )
|
||||
QObject.connect( self.simplify, SIGNAL("triggered()"), self.dosimplify )
|
||||
QObject.connect( self.centroids, SIGNAL("triggered()"), self.docentroids )
|
||||
QObject.connect( self.delaunay, SIGNAL("triggered()"), self.dodelaunay )
|
||||
QObject.connect( self.polysToLines, SIGNAL("triggered()"), self.dopolysToLines )
|
||||
QObject.connect( self.compGeo, SIGNAL("triggered()"), self.docompGeo )
|
||||
QObject.connect( self.extNodes, SIGNAL("triggered()"), self.doextNodes )
|
||||
@ -226,7 +232,7 @@ class fToolsPlugin:
|
||||
QObject.connect( self.spatJoin, SIGNAL("triggered()"), self.dospatJoin )
|
||||
QObject.connect( self.splitVect, SIGNAL("triggered()"), self.dosplitVect )
|
||||
|
||||
QObject.connect( self.ftools_about, SIGNAL("triggered()"), self.doabout )
|
||||
QObject.connect( self.ftools_aboot, SIGNAL("triggered()"), self.doaboot )
|
||||
|
||||
def unload( self ):
|
||||
pass
|
||||
@ -302,6 +308,14 @@ class fToolsPlugin:
|
||||
def docentroids( self ):
|
||||
d = doGeometry.GeometryDialog( self.iface, 7 )
|
||||
d.exec_()
|
||||
|
||||
def dodelaunay( self ):
|
||||
d = doGeometry.GeometryDialog( self.iface, 8 )
|
||||
d.exec_()
|
||||
|
||||
def doextent( self ):
|
||||
d = doGeometry.GeometryDialog( self.iface, 9 )
|
||||
d.exec_()
|
||||
|
||||
def dosumLines(self):
|
||||
d = doSumLines.Dialog(self.iface)
|
||||
@ -371,6 +385,6 @@ class fToolsPlugin:
|
||||
d = doSpatialJoin.Dialog( self.iface )
|
||||
d.exec_()
|
||||
|
||||
def doabout( self ):
|
||||
def doaboot( self ):
|
||||
d = doAbout.Dialog( self.iface )
|
||||
d.exec_()
|
||||
|
@ -43,5 +43,7 @@ vector_grid.png
|
||||
random_selection.png
|
||||
ftools_logo.png
|
||||
regular_points.png
|
||||
delaunay.png
|
||||
layer_extent.png
|
||||
)
|
||||
INSTALL(FILES ${ICON_FILES} DESTINATION ${QGIS_DATA_DIR}/python/plugins/fTools/icons/default)
|
||||
|
BIN
python/plugins/fTools/icons/default/delaunay.png
Normal file
BIN
python/plugins/fTools/icons/default/delaunay.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
python/plugins/fTools/icons/default/layer_extent.png
Normal file
BIN
python/plugins/fTools/icons/default/layer_extent.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 607 B |
@ -17,7 +17,7 @@
|
||||
version="1.0"
|
||||
sodipodi:docname="gis-0.1.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
inkscape:export-filename="/home/cfarmer/.qgis/python/plugins/fTools/gis_icons/matrix.png"
|
||||
inkscape:export-filename="/home/cfarmer/dev/cpp/qgis/python/plugins/fTools/icons/gis/layer_extent.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"
|
||||
style="display:inline;enable-background:new">
|
||||
@ -32,15 +32,15 @@
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="16"
|
||||
inkscape:cx="9.0201001"
|
||||
inkscape:cy="8.9456096"
|
||||
inkscape:cx="9.2319959"
|
||||
inkscape:cy="11.794933"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer129"
|
||||
inkscape:current-layer="layer155"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1159"
|
||||
inkscape:window-height="700"
|
||||
inkscape:window-x="86"
|
||||
inkscape:window-y="72"
|
||||
inkscape:window-y="48"
|
||||
inkscape:snap-global="false"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
@ -2370,6 +2370,28 @@
|
||||
style="fill:#82a0b4;fill-opacity:1;fill-rule:nonzero;stroke:#3c5a6e;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.4;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer134"
|
||||
inkscape:label="delaunay"
|
||||
style="display:none"
|
||||
sodipodi:insensitive="true">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#3c5a6e;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 5.5,15.9375 L 12.5,9.5625 L 0.625,6.125"
|
||||
id="path3778"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#3c5a6e;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 8.0625,0.9375 L 12.4375,9.5 L 17.3125,0.8125"
|
||||
id="path3780"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#3c5a6e;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 23.25,14 L 12.5625,9.4375 L 16.9375,23.0625"
|
||||
id="path3782"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
style="display:none"
|
||||
@ -6099,25 +6121,34 @@
|
||||
inkscape:groupmode="layer"
|
||||
id="layer129"
|
||||
inkscape:label="matrix"
|
||||
style="display:inline">
|
||||
<g
|
||||
id="g4571">
|
||||
<path
|
||||
id="path3756"
|
||||
d="M 5.499146,0.50519709 L 5.499146,23.480886"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#969696;stroke-width:0.97941929px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<path
|
||||
id="path3761"
|
||||
d="M 0.51176719,5.499146 L 23.528038,5.499146"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#969696;stroke-width:0.98028392px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<rect
|
||||
y="6.4966083"
|
||||
x="6.4907565"
|
||||
height="17.023754"
|
||||
width="17.035219"
|
||||
id="rect4569"
|
||||
style="opacity:1;fill:#82a0b4;fill-opacity:0.99215686;fill-rule:nonzero;stroke:#3c5a6e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.9;stroke-opacity:0.99215686;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
</g>
|
||||
style="display:none">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#969696;stroke-width:0.97941929px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 5.499146,0.50519709 L 5.499146,23.480886"
|
||||
id="path3756" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#969696;stroke-width:0.98028392px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 0.51176719,5.499146 L 23.528038,5.499146"
|
||||
id="path3761" />
|
||||
<rect
|
||||
style="fill:#82a0b4;fill-opacity:0.99215686;fill-rule:nonzero;stroke:#3c5a6e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.9;stroke-opacity:0.99215686;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect4569"
|
||||
width="17.035219"
|
||||
height="17.023754"
|
||||
x="6.4907565"
|
||||
y="6.4966083" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer155"
|
||||
inkscape:label="extent">
|
||||
<rect
|
||||
style="fill:#82a0b4;fill-opacity:0.99215686;fill-rule:nonzero;stroke:#3c5a6e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.9;stroke-opacity:0.99215686;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3768"
|
||||
width="17.035219"
|
||||
height="17.023754"
|
||||
x="0.5448904"
|
||||
y="0.55062294" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
@ -7097,7 +7128,7 @@
|
||||
id="layer39"
|
||||
inkscape:groupmode="layer">
|
||||
<g
|
||||
style="display:inline"
|
||||
style="display:none"
|
||||
inkscape:label="print composer"
|
||||
id="layer43"
|
||||
inkscape:groupmode="layer">
|
||||
@ -8017,7 +8048,7 @@
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
style="display:none"
|
||||
style="display:inline"
|
||||
inkscape:label="actions"
|
||||
id="layer11"
|
||||
inkscape:groupmode="layer">
|
||||
@ -8267,7 +8298,7 @@
|
||||
</g>
|
||||
<g
|
||||
sodipodi:insensitive="true"
|
||||
style="display:none"
|
||||
style="display:inline"
|
||||
inkscape:label="create [yellow]"
|
||||
id="layer15"
|
||||
inkscape:groupmode="layer">
|
||||
|
Before Width: | Height: | Size: 482 KiB After Width: | Height: | Size: 484 KiB |
@ -43,5 +43,7 @@ vector_grid.png
|
||||
random_selection.png
|
||||
ftools_logo.png
|
||||
regular_points.png
|
||||
delaunay.png
|
||||
layer_extent.png
|
||||
)
|
||||
INSTALL(FILES ${ICON_FILES} DESTINATION ${QGIS_DATA_DIR}/python/plugins/fTools/icons/gis)
|
||||
|
BIN
python/plugins/fTools/icons/gis/delaunay.png
Normal file
BIN
python/plugins/fTools/icons/gis/delaunay.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
python/plugins/fTools/icons/gis/layer_extent.png
Normal file
BIN
python/plugins/fTools/icons/gis/layer_extent.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 607 B |
@ -2,8 +2,8 @@
|
||||
|
||||
# Resource object code
|
||||
#
|
||||
# Created: Sun Jan 18 22:55:27 2009
|
||||
# by: The Resource Compiler for PyQt (Qt v4.3.4)
|
||||
# Created: Mon Mar 9 00:09:47 2009
|
||||
# by: The Resource Compiler for PyQt (Qt v4.4.3)
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
@ -1469,6 +1469,97 @@ qt_resource_data = "\
|
||||
\xf4\x92\xbd\x8d\xb3\x84\x5e\xae\x7c\x20\xbb\x4d\x80\xff\x07\x5c\
|
||||
\x69\x9f\x38\xa5\x9a\x04\xb9\x00\x00\x00\x00\x49\x45\x4e\x44\xae\
|
||||
\x42\x60\x82\
|
||||
\x00\x00\x05\x8c\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x18\x00\x00\x00\x18\x08\x06\x00\x00\x00\xe0\x77\x3d\xf8\
|
||||
\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
|
||||
\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\
|
||||
\x01\x42\x28\x9b\x78\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\
|
||||
\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\
|
||||
\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x05\x09\x49\x44\
|
||||
\x41\x54\x48\x89\xad\x55\x4b\x4f\x1b\x57\x18\x3d\x33\xe3\x07\xb6\
|
||||
\xc7\x24\x36\x7e\x04\x1b\x9c\x50\x0c\x34\x82\x38\x01\x43\x9b\x40\
|
||||
\x0a\xca\x2a\x55\x37\x55\xa5\x2a\x51\x21\x54\x5d\x74\x91\x2a\x95\
|
||||
\x92\xd0\x4a\x5d\x35\x52\x1b\x55\x95\x5a\x35\x44\x55\x53\x29\x9b\
|
||||
\xaa\xa4\x69\x16\x74\x93\xf6\x07\x54\x49\x10\xce\xab\x01\x8c\x91\
|
||||
\x2a\xdb\xe0\x07\x60\xde\xb6\xf1\x0b\x7b\xec\x99\x7b\xbb\x48\x4c\
|
||||
\x6d\xec\x4a\x59\xf4\xac\x46\xf7\x9e\xef\x9c\xf9\xbe\xfb\xdd\xef\
|
||||
\x32\x94\x52\x54\xc3\xc9\xc1\x91\x76\xb9\x8c\xb9\x2b\x11\xe9\x50\
|
||||
\x55\x42\x09\x18\x86\x49\x10\x22\xb4\x4c\xfc\xfa\x63\x7c\xef\x9e\
|
||||
\xac\x5a\x40\xff\xf0\xe5\x0f\x65\x32\x7c\x6f\x3b\x78\x48\xb9\xb2\
|
||||
\x1a\x61\x7b\x7b\x7b\xc1\x32\x4c\x55\x71\xcf\xdc\x1c\x52\xa9\x74\
|
||||
\x6d\x36\x87\xf3\x00\xbe\xae\x30\x2f\xcd\xe0\xd4\x99\x0b\x3c\xad\
|
||||
\x51\x8e\x29\xe4\xf2\x37\x3b\x3b\xbb\xd4\xbc\x96\xc7\xf4\xcc\x0c\
|
||||
\x0c\x06\x03\x1a\x1b\x1a\x2a\xc4\xb7\x13\xdb\x70\xcf\xb8\xe1\x38\
|
||||
\xe2\xc0\xd4\xf4\x54\x2c\xad\xca\x1c\xf8\xeb\xe6\xcd\x42\x29\x87\
|
||||
\x2d\x7e\xf4\x0d\x5d\x3e\x46\x6b\x94\x7f\x1b\x8d\xc6\xb7\x7a\xfb\
|
||||
\xfa\xd4\xbc\x96\x07\x00\xb4\x34\xdb\x11\x0c\x2c\x80\x10\x52\x61\
|
||||
\xe0\xf3\x7a\xd1\x62\x6f\x81\x4e\xaf\x83\x4a\xa3\x51\xa8\x53\xaa\
|
||||
\xb3\x7b\x39\x2c\x00\x0c\x9c\xbb\x78\x41\xce\x31\xae\x57\x0f\x1f\
|
||||
\xb6\x3a\x1c\x8e\x1a\x8e\xe3\x76\x09\xbc\x96\xc7\xbe\x7d\xfb\xb1\
|
||||
\xbc\xbc\x5c\x16\xb8\xb6\xb6\x0e\x49\x22\xa8\xb7\x5a\x00\x00\xf6\
|
||||
\xa6\x26\x9e\x95\xb3\x57\x2a\x0c\x06\xde\x1f\xb9\xab\x54\xd6\x7c\
|
||||
\x7b\xfc\xf8\xeb\x2a\xab\xc5\x52\xb5\xd0\x76\x7b\x33\x42\xc1\x20\
|
||||
\x24\xe9\x79\x16\x84\x48\xf0\xfb\x7c\x68\x6b\x6b\x45\x31\xc0\x68\
|
||||
\x36\x43\xc6\xc9\x2c\x27\x87\x2e\x9e\x2a\x33\x60\x80\x4e\x51\x92\
|
||||
\x54\x33\x6e\x37\x7c\x5e\x2f\x62\xb1\x28\x08\x2d\x2f\x87\x46\xc3\
|
||||
\x43\xa7\xd3\x63\x79\x69\x09\x00\x10\x0e\x2f\x82\xd7\xf2\xd0\xeb\
|
||||
\xeb\x76\x39\x0c\x80\x43\x4d\x4d\x6a\x99\x8c\xfb\xbc\xcc\x40\x22\
|
||||
\xd2\x25\x85\x5c\x9e\x39\xea\x38\x0a\x85\x52\x89\x85\x40\x00\xf7\
|
||||
\xef\xdd\x87\x7b\xc6\x8d\x48\x24\x02\x41\x10\x00\x00\xcd\xf6\x66\
|
||||
\x84\xc2\x21\x64\xb3\x59\x84\x42\x21\xb4\xb6\xb5\x56\x64\xda\x60\
|
||||
\xb1\x32\xa0\xe8\x3d\x39\x7c\xa9\xad\xb8\xc6\x2d\x7a\x1e\x7b\x1b\
|
||||
\x3b\x7a\x3e\xaa\x33\x18\x6b\x2d\x16\x0b\xac\x16\x2b\x1a\x1b\x1b\
|
||||
\xc0\x71\x1c\xa2\xd1\x18\x7c\x7e\x1f\x56\x57\x57\x21\x11\x09\x84\
|
||||
\x52\x04\x03\x01\xd4\xd7\x1f\x80\xa5\xde\x52\x61\xc0\xb2\x2c\xc4\
|
||||
\x82\x48\x33\xa9\xf4\xbe\x0f\xde\x39\xfd\x3b\x00\xb0\x94\x52\x4a\
|
||||
\x89\x74\x65\x61\x61\x3e\x53\x24\xca\x64\x72\x98\xcd\x66\x74\x74\
|
||||
\xb4\x63\xa0\xbf\x1f\xed\xed\xed\x60\x59\x0e\x99\x74\x0a\xf9\x7c\
|
||||
\x1e\xc9\x44\x1a\x5b\x5b\x5b\xa8\x76\x49\x0f\x1e\xb4\xc9\x09\x25\
|
||||
\xef\x9d\x1a\xfc\xd4\x00\xbc\xe8\xa2\xb4\x3a\x77\x3b\x9d\x4a\xe5\
|
||||
\x12\xdb\x89\x8a\x00\x86\x61\x50\x5b\x5b\x0b\x2d\xcf\x83\x50\x0a\
|
||||
\x9d\x4e\x07\x96\x63\xe1\xf3\xf9\x31\xe9\x72\x61\x71\x31\x0c\x51\
|
||||
\x14\x77\xf9\xca\x9a\x1a\x98\x8c\x26\x42\x38\xe9\x63\xa0\xe4\xa2\
|
||||
\xbd\x31\x7c\x71\xa4\xae\xce\xf0\xa5\xb3\xb3\x4b\xb3\xd7\x24\x12\
|
||||
\x89\x60\xde\xef\xc7\xb1\xae\x2e\x14\x04\x01\xa1\x70\x18\xdd\xdd\
|
||||
\xdd\x88\xc7\xe2\x08\x2f\x2d\x22\x1e\x8b\xa1\xbe\xfe\x00\x1a\x6d\
|
||||
\x36\x68\xd4\x1a\xa4\x52\x29\x3c\x79\xfc\x24\xa1\x8e\x8a\xe6\xdd\
|
||||
\x51\xa1\x66\x14\x37\xe3\xd1\xd8\x17\x99\x74\x06\x1a\xfe\x5f\x8f\
|
||||
\x40\x60\x01\x91\xe5\x15\x74\xbf\xd6\x03\x8d\x5a\x03\x42\x08\x3c\
|
||||
\x73\x73\x28\xe4\x0b\xd0\xe9\x75\xd0\xe9\x75\xc8\xe5\x04\x2c\x2f\
|
||||
\x2d\xe2\xe9\x93\xa7\xa8\xd5\x6a\x61\xb3\xd9\xa0\xd6\xf2\x5c\x4a\
|
||||
\x4a\x0c\x96\x8d\x8a\x81\x73\x23\x57\xcd\x66\xe3\x27\x47\x1c\x0e\
|
||||
\x15\xa5\x14\x5e\xaf\x17\xb1\x58\x0c\x4e\xa7\x13\x4a\xa5\x72\x97\
|
||||
\x37\xeb\xf1\xa0\x4e\xaf\x87\xd5\x6a\x2d\xcb\x94\x10\x09\x6b\x6b\
|
||||
\x6b\x08\x87\x17\x91\xcf\xe7\x21\x4a\x85\x08\x5b\x4a\x28\xe4\x31\
|
||||
\xba\xbe\xb1\x89\x6c\x36\x0b\x8f\xc7\x83\x64\x32\x85\x9e\x9e\x9e\
|
||||
\x32\x71\x00\x30\x9b\x4c\xd8\x58\x5f\xaf\x38\x2f\x96\xe5\x60\xb1\
|
||||
\x58\x71\xe2\xc4\x09\x98\x4d\x26\x02\x70\x5b\x65\x06\xae\xf1\x6b\
|
||||
\x31\x30\xf4\xa7\xa9\xa9\x67\x92\x24\x49\x70\x3a\x9d\x90\xcb\xe5\
|
||||
\x15\x42\x06\x83\x01\xf1\xed\x44\xd9\xe1\x96\x22\x93\x49\x23\xb2\
|
||||
\xb2\x92\xcb\x13\xf2\x2e\xbb\x77\x53\x10\xe9\xd5\x5c\x36\x17\x10\
|
||||
\xf3\x85\xb4\x20\xe4\xaa\x0a\x70\x1c\x07\x9d\x5e\x87\xad\xcd\xcd\
|
||||
\x8a\x3d\x4a\x28\xdc\xee\xd9\x1d\x42\xf1\x99\xeb\x97\x6b\xf3\x15\
|
||||
\x06\x8f\xee\x5c\x5f\x37\x09\x91\xc3\xdb\xe9\xe4\xd5\x87\x0f\x5d\
|
||||
\x3b\xc1\x60\x40\xa4\xa4\xb2\xdf\xcd\x26\x33\xd6\x37\x36\x2a\xd6\
|
||||
\x03\xc1\x80\x98\xcb\x09\xee\x89\xdb\xa3\x37\x80\x92\x71\x5d\x8a\
|
||||
\xf1\xf1\x71\xe9\xc1\xad\xd1\x6f\x28\xc4\x8e\x60\x20\xf4\x68\xd2\
|
||||
\xe5\x4a\x27\x92\xc9\x32\x8e\xd1\x68\x40\x34\x1a\xdd\x1d\x80\x00\
|
||||
\x90\x4a\x26\x11\x0a\x85\x04\x92\xa7\x67\xe9\x8b\xee\x61\xfe\xeb\
|
||||
\xc9\x2c\x45\xff\xe0\xa5\x73\x8c\x8c\xb9\xd1\x60\xb5\x2a\x5a\xec\
|
||||
\xad\x35\x9c\xec\xf9\x38\x9f\x7a\xf6\x0c\x0d\x8d\x36\x98\x4c\x46\
|
||||
\x10\x42\xe1\x9a\x9c\xdc\xc9\xe6\x73\x17\x1e\xdc\x1a\xfd\xb9\x18\
|
||||
\x5b\x35\x83\xbd\x78\x70\xe7\xfa\xed\x1c\x53\x78\x25\xb2\xb2\xf2\
|
||||
\xc7\xc4\xc4\xc4\x4e\xb1\xf6\x46\x93\x09\xeb\x2f\xba\x69\xde\xef\
|
||||
\x2f\x14\x0a\xf9\x87\xa5\xe2\x2f\x6d\x00\x00\x8f\xc7\x7e\x88\xde\
|
||||
\x1b\xbb\x76\x36\x5f\x10\xde\x76\xcf\xce\xae\x4d\xcf\x4c\xef\xe8\
|
||||
\xf6\xef\x47\x74\x6b\x13\xf1\xf8\x36\x96\x96\x97\x72\x3b\x05\x69\
|
||||
\x68\x6f\xdc\x4b\x95\x68\x2f\x7a\xcf\x8c\xa8\x14\x4a\x7c\x05\x06\
|
||||
\xe7\x95\x4a\x85\x4a\x14\x45\x41\x92\xc4\xe1\x7b\xb7\xae\xff\xf6\
|
||||
\xbf\x18\x14\xd1\x37\x74\xf9\x98\x5c\xc6\xdc\x61\xc1\x4c\xff\x39\
|
||||
\xf6\x5d\xc5\xdf\x03\xc0\x3f\x4b\x1d\x48\xe6\x9d\x4c\x36\xb6\x00\
|
||||
\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
|
||||
\x00\x00\x05\x60\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
@ -2699,6 +2790,46 @@ qt_resource_data = "\
|
||||
\x06\x2d\xed\xb3\x39\x87\x2c\xa3\x4e\xe4\x50\x7f\xb2\x8d\xee\x40\
|
||||
\x10\xc9\x27\x6e\xa3\x3b\x7e\x03\x1c\x81\xee\xcf\x3e\x80\x40\xd3\
|
||||
\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
|
||||
\x00\x00\x02\x5f\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x18\x00\x00\x00\x18\x08\x06\x00\x00\x00\xe0\x77\x3d\xf8\
|
||||
\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
|
||||
\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\
|
||||
\x01\x42\x28\x9b\x78\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\
|
||||
\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\
|
||||
\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x01\xdc\x49\x44\
|
||||
\x41\x54\x48\x89\xed\x95\x31\x6b\x53\x51\x18\x86\x9f\x73\xce\x35\
|
||||
\xbd\x1a\x92\x96\xa6\x12\x6f\x17\x35\x01\x69\x4a\x47\x29\x45\x24\
|
||||
\x6a\x8a\xfe\x03\x25\x38\xe8\x22\x4e\x52\x08\x41\xff\x84\x38\x89\
|
||||
\x4e\x59\xe2\x20\x82\xb3\x60\x14\xdb\x24\x5a\x91\x8c\x0e\x56\x1a\
|
||||
\xa8\x0e\xc6\x24\xd0\xd0\xe6\x56\xed\x25\xf4\x9e\xe3\x20\xc6\x62\
|
||||
\x09\xd8\x5b\x70\xca\x37\x9e\xef\x3d\xdf\xf3\xbe\xc3\x77\x8e\x38\
|
||||
\x7f\x2d\xf7\x5e\x1b\x93\xe4\x00\x25\x10\x9d\x11\x54\xaa\xf4\xe8\
|
||||
\xee\xf7\xbf\x7b\x96\xaf\xf5\x54\x3a\x7d\x4e\x29\x29\x03\x03\x5e\
|
||||
\x57\xab\xb1\xde\xf6\x8f\x08\xb0\x17\x00\x70\xc8\x52\x48\xa9\x02\
|
||||
\x03\x04\x06\x33\xa0\x17\xdc\xf6\x3f\xd6\x10\x30\x04\x0c\x01\xff\
|
||||
\x01\x60\x05\xb9\x34\x26\x3e\x90\x34\x05\x39\xca\x2a\x00\x99\x0c\
|
||||
\x47\x80\xe6\x72\xf1\x61\x5f\x63\xa0\x26\x24\xf9\x40\x80\xa4\x29\
|
||||
\xc8\xf1\x50\x1b\x3b\x72\x1a\xa9\x6c\xa4\xb2\x49\x5d\x7a\xc9\xca\
|
||||
\x8b\x8b\x68\xdf\x43\xfb\x1e\xde\x56\x7d\x76\xa7\xd7\xbd\x17\x08\
|
||||
\x30\xca\x2a\xe1\x58\x06\x65\x85\xc1\xfc\x79\xe6\x7e\xc3\x10\x02\
|
||||
\x15\x8a\xe2\x36\x17\x67\x03\x01\x00\x26\x8e\x5f\x21\x3a\x39\x4f\
|
||||
\xe7\xd3\x13\xa2\xf1\x34\x00\x93\x33\xb7\x71\xdb\x55\x62\x27\xb3\
|
||||
\xb8\x5f\x5f\xe1\x36\x17\xb1\xa4\x10\xeb\x4b\x4b\xe5\xf1\xfd\x0c\
|
||||
\xcf\xcc\x33\xb2\xf1\xe5\x19\xfe\xce\x37\x9c\x99\x3b\x18\xdd\x63\
|
||||
\xb3\xf1\x9c\x48\xfc\x2c\xe1\xa3\x73\xb4\x57\xee\xe3\xb6\x2a\x00\
|
||||
\x58\x42\x6d\x26\x60\xcc\xde\x67\x80\x0d\x30\xb8\xad\x32\xf1\xa9\
|
||||
\x5b\x6c\xb5\xdf\xd0\xfe\xf8\x00\x80\xe8\xb1\x0b\xb8\xad\x72\x5f\
|
||||
\x28\x8c\x19\xf4\x55\x0c\xae\xe5\xa2\x30\x20\x98\x48\x5c\x25\x71\
|
||||
\xa6\x80\xf6\xb7\xe9\x7c\x7e\x4a\xec\xc4\x65\xa4\x3a\xcc\xda\xdb\
|
||||
\x1b\xac\xaf\x3d\x06\x4c\xf0\x3d\x70\x52\x0b\x38\xd3\x39\xea\x95\
|
||||
\x2c\xdd\x46\x89\xf8\xa9\x9b\x74\x1b\x25\xea\x95\x2c\xce\x74\x0e\
|
||||
\x27\xb5\x70\xb0\x04\x52\xd9\x68\xdd\x03\xa3\x01\x98\xbb\x6e\x78\
|
||||
\x57\x14\xbf\x04\x42\x22\x65\x08\xed\x7b\xc1\x12\x18\xa8\x69\xdf\
|
||||
\xeb\x0f\xdf\x2b\xd0\x68\xdf\xc3\x40\x2d\x10\x40\x48\xf2\x06\x6a\
|
||||
\xbb\xcf\xfa\xee\x77\x99\x10\x92\xfc\x4f\xfd\xc2\xaa\x73\x0e\x12\
|
||||
\x9d\x40\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
|
||||
\x00\x00\x04\x68\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
@ -5381,6 +5512,97 @@ qt_resource_data = "\
|
||||
\xf4\x92\xbd\x8d\xb3\x84\x5e\xae\x7c\x20\xbb\x4d\x80\xff\x07\x5c\
|
||||
\x69\x9f\x38\xa5\x9a\x04\xb9\x00\x00\x00\x00\x49\x45\x4e\x44\xae\
|
||||
\x42\x60\x82\
|
||||
\x00\x00\x05\x8c\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x18\x00\x00\x00\x18\x08\x06\x00\x00\x00\xe0\x77\x3d\xf8\
|
||||
\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
|
||||
\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\
|
||||
\x01\x42\x28\x9b\x78\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\
|
||||
\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\
|
||||
\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x05\x09\x49\x44\
|
||||
\x41\x54\x48\x89\xad\x55\x4b\x4f\x1b\x57\x18\x3d\x33\xe3\x07\xb6\
|
||||
\xc7\x24\x36\x7e\x04\x1b\x9c\x50\x0c\x34\x82\x38\x01\x43\x9b\x40\
|
||||
\x0a\xca\x2a\x55\x37\x55\xa5\x2a\x51\x21\x54\x5d\x74\x91\x2a\x95\
|
||||
\x92\xd0\x4a\x5d\x35\x52\x1b\x55\x95\x5a\x35\x44\x55\x53\x29\x9b\
|
||||
\xaa\xa4\x69\x16\x74\x93\xf6\x07\x54\x49\x10\xce\xab\x01\x8c\x91\
|
||||
\x2a\xdb\xe0\x07\x60\xde\xb6\xf1\x0b\x7b\xec\x99\x7b\xbb\x48\x4c\
|
||||
\x6d\xec\x4a\x59\xf4\xac\x46\xf7\x9e\xef\x9c\xf9\xbe\xfb\xdd\xef\
|
||||
\x32\x94\x52\x54\xc3\xc9\xc1\x91\x76\xb9\x8c\xb9\x2b\x11\xe9\x50\
|
||||
\x55\x42\x09\x18\x86\x49\x10\x22\xb4\x4c\xfc\xfa\x63\x7c\xef\x9e\
|
||||
\xac\x5a\x40\xff\xf0\xe5\x0f\x65\x32\x7c\x6f\x3b\x78\x48\xb9\xb2\
|
||||
\x1a\x61\x7b\x7b\x7b\xc1\x32\x4c\x55\x71\xcf\xdc\x1c\x52\xa9\x74\
|
||||
\x6d\x36\x87\xf3\x00\xbe\xae\x30\x2f\xcd\xe0\xd4\x99\x0b\x3c\xad\
|
||||
\x51\x8e\x29\xe4\xf2\x37\x3b\x3b\xbb\xd4\xbc\x96\xc7\xf4\xcc\x0c\
|
||||
\x0c\x06\x03\x1a\x1b\x1a\x2a\xc4\xb7\x13\xdb\x70\xcf\xb8\xe1\x38\
|
||||
\xe2\xc0\xd4\xf4\x54\x2c\xad\xca\x1c\xf8\xeb\xe6\xcd\x42\x29\x87\
|
||||
\x2d\x7e\xf4\x0d\x5d\x3e\x46\x6b\x94\x7f\x1b\x8d\xc6\xb7\x7a\xfb\
|
||||
\xfa\xd4\xbc\x96\x07\x00\xb4\x34\xdb\x11\x0c\x2c\x80\x10\x52\x61\
|
||||
\xe0\xf3\x7a\xd1\x62\x6f\x81\x4e\xaf\x83\x4a\xa3\x51\xa8\x53\xaa\
|
||||
\xb3\x7b\x39\x2c\x00\x0c\x9c\xbb\x78\x41\xce\x31\xae\x57\x0f\x1f\
|
||||
\xb6\x3a\x1c\x8e\x1a\x8e\xe3\x76\x09\xbc\x96\xc7\xbe\x7d\xfb\xb1\
|
||||
\xbc\xbc\x5c\x16\xb8\xb6\xb6\x0e\x49\x22\xa8\xb7\x5a\x00\x00\xf6\
|
||||
\xa6\x26\x9e\x95\xb3\x57\x2a\x0c\x06\xde\x1f\xb9\xab\x54\xd6\x7c\
|
||||
\x7b\xfc\xf8\xeb\x2a\xab\xc5\x52\xb5\xd0\x76\x7b\x33\x42\xc1\x20\
|
||||
\x24\xe9\x79\x16\x84\x48\xf0\xfb\x7c\x68\x6b\x6b\x45\x31\xc0\x68\
|
||||
\x36\x43\xc6\xc9\x2c\x27\x87\x2e\x9e\x2a\x33\x60\x80\x4e\x51\x92\
|
||||
\x54\x33\x6e\x37\x7c\x5e\x2f\x62\xb1\x28\x08\x2d\x2f\x87\x46\xc3\
|
||||
\x43\xa7\xd3\x63\x79\x69\x09\x00\x10\x0e\x2f\x82\xd7\xf2\xd0\xeb\
|
||||
\xeb\x76\x39\x0c\x80\x43\x4d\x4d\x6a\x99\x8c\xfb\xbc\xcc\x40\x22\
|
||||
\xd2\x25\x85\x5c\x9e\x39\xea\x38\x0a\x85\x52\x89\x85\x40\x00\xf7\
|
||||
\xef\xdd\x87\x7b\xc6\x8d\x48\x24\x02\x41\x10\x00\x00\xcd\xf6\x66\
|
||||
\x84\xc2\x21\x64\xb3\x59\x84\x42\x21\xb4\xb6\xb5\x56\x64\xda\x60\
|
||||
\xb1\x32\xa0\xe8\x3d\x39\x7c\xa9\xad\xb8\xc6\x2d\x7a\x1e\x7b\x1b\
|
||||
\x3b\x7a\x3e\xaa\x33\x18\x6b\x2d\x16\x0b\xac\x16\x2b\x1a\x1b\x1b\
|
||||
\xc0\x71\x1c\xa2\xd1\x18\x7c\x7e\x1f\x56\x57\x57\x21\x11\x09\x84\
|
||||
\x52\x04\x03\x01\xd4\xd7\x1f\x80\xa5\xde\x52\x61\xc0\xb2\x2c\xc4\
|
||||
\x82\x48\x33\xa9\xf4\xbe\x0f\xde\x39\xfd\x3b\x00\xb0\x94\x52\x4a\
|
||||
\x89\x74\x65\x61\x61\x3e\x53\x24\xca\x64\x72\x98\xcd\x66\x74\x74\
|
||||
\xb4\x63\xa0\xbf\x1f\xed\xed\xed\x60\x59\x0e\x99\x74\x0a\xf9\x7c\
|
||||
\x1e\xc9\x44\x1a\x5b\x5b\x5b\xa8\x76\x49\x0f\x1e\xb4\xc9\x09\x25\
|
||||
\xef\x9d\x1a\xfc\xd4\x00\xbc\xe8\xa2\xb4\x3a\x77\x3b\x9d\x4a\xe5\
|
||||
\x12\xdb\x89\x8a\x00\x86\x61\x50\x5b\x5b\x0b\x2d\xcf\x83\x50\x0a\
|
||||
\x9d\x4e\x07\x96\x63\xe1\xf3\xf9\x31\xe9\x72\x61\x71\x31\x0c\x51\
|
||||
\x14\x77\xf9\xca\x9a\x1a\x98\x8c\x26\x42\x38\xe9\x63\xa0\xe4\xa2\
|
||||
\xbd\x31\x7c\x71\xa4\xae\xce\xf0\xa5\xb3\xb3\x4b\xb3\xd7\x24\x12\
|
||||
\x89\x60\xde\xef\xc7\xb1\xae\x2e\x14\x04\x01\xa1\x70\x18\xdd\xdd\
|
||||
\xdd\x88\xc7\xe2\x08\x2f\x2d\x22\x1e\x8b\xa1\xbe\xfe\x00\x1a\x6d\
|
||||
\x36\x68\xd4\x1a\xa4\x52\x29\x3c\x79\xfc\x24\xa1\x8e\x8a\xe6\xdd\
|
||||
\x51\xa1\x66\x14\x37\xe3\xd1\xd8\x17\x99\x74\x06\x1a\xfe\x5f\x8f\
|
||||
\x40\x60\x01\x91\xe5\x15\x74\xbf\xd6\x03\x8d\x5a\x03\x42\x08\x3c\
|
||||
\x73\x73\x28\xe4\x0b\xd0\xe9\x75\xd0\xe9\x75\xc8\xe5\x04\x2c\x2f\
|
||||
\x2d\xe2\xe9\x93\xa7\xa8\xd5\x6a\x61\xb3\xd9\xa0\xd6\xf2\x5c\x4a\
|
||||
\x4a\x0c\x96\x8d\x8a\x81\x73\x23\x57\xcd\x66\xe3\x27\x47\x1c\x0e\
|
||||
\x15\xa5\x14\x5e\xaf\x17\xb1\x58\x0c\x4e\xa7\x13\x4a\xa5\x72\x97\
|
||||
\x37\xeb\xf1\xa0\x4e\xaf\x87\xd5\x6a\x2d\xcb\x94\x10\x09\x6b\x6b\
|
||||
\x6b\x08\x87\x17\x91\xcf\xe7\x21\x4a\x85\x08\x5b\x4a\x28\xe4\x31\
|
||||
\xba\xbe\xb1\x89\x6c\x36\x0b\x8f\xc7\x83\x64\x32\x85\x9e\x9e\x9e\
|
||||
\x32\x71\x00\x30\x9b\x4c\xd8\x58\x5f\xaf\x38\x2f\x96\xe5\x60\xb1\
|
||||
\x58\x71\xe2\xc4\x09\x98\x4d\x26\x02\x70\x5b\x65\x06\xae\xf1\x6b\
|
||||
\x31\x30\xf4\xa7\xa9\xa9\x67\x92\x24\x49\x70\x3a\x9d\x90\xcb\xe5\
|
||||
\x15\x42\x06\x83\x01\xf1\xed\x44\xd9\xe1\x96\x22\x93\x49\x23\xb2\
|
||||
\xb2\x92\xcb\x13\xf2\x2e\xbb\x77\x53\x10\xe9\xd5\x5c\x36\x17\x10\
|
||||
\xf3\x85\xb4\x20\xe4\xaa\x0a\x70\x1c\x07\x9d\x5e\x87\xad\xcd\xcd\
|
||||
\x8a\x3d\x4a\x28\xdc\xee\xd9\x1d\x42\xf1\x99\xeb\x97\x6b\xf3\x15\
|
||||
\x06\x8f\xee\x5c\x5f\x37\x09\x91\xc3\xdb\xe9\xe4\xd5\x87\x0f\x5d\
|
||||
\x3b\xc1\x60\x40\xa4\xa4\xb2\xdf\xcd\x26\x33\xd6\x37\x36\x2a\xd6\
|
||||
\x03\xc1\x80\x98\xcb\x09\xee\x89\xdb\xa3\x37\x80\x92\x71\x5d\x8a\
|
||||
\xf1\xf1\x71\xe9\xc1\xad\xd1\x6f\x28\xc4\x8e\x60\x20\xf4\x68\xd2\
|
||||
\xe5\x4a\x27\x92\xc9\x32\x8e\xd1\x68\x40\x34\x1a\xdd\x1d\x80\x00\
|
||||
\x90\x4a\x26\x11\x0a\x85\x04\x92\xa7\x67\xe9\x8b\xee\x61\xfe\xeb\
|
||||
\xc9\x2c\x45\xff\xe0\xa5\x73\x8c\x8c\xb9\xd1\x60\xb5\x2a\x5a\xec\
|
||||
\xad\x35\x9c\xec\xf9\x38\x9f\x7a\xf6\x0c\x0d\x8d\x36\x98\x4c\x46\
|
||||
\x10\x42\xe1\x9a\x9c\xdc\xc9\xe6\x73\x17\x1e\xdc\x1a\xfd\xb9\x18\
|
||||
\x5b\x35\x83\xbd\x78\x70\xe7\xfa\xed\x1c\x53\x78\x25\xb2\xb2\xf2\
|
||||
\xc7\xc4\xc4\xc4\x4e\xb1\xf6\x46\x93\x09\xeb\x2f\xba\x69\xde\xef\
|
||||
\x2f\x14\x0a\xf9\x87\xa5\xe2\x2f\x6d\x00\x00\x8f\xc7\x7e\x88\xde\
|
||||
\x1b\xbb\x76\x36\x5f\x10\xde\x76\xcf\xce\xae\x4d\xcf\x4c\xef\xe8\
|
||||
\xf6\xef\x47\x74\x6b\x13\xf1\xf8\x36\x96\x96\x97\x72\x3b\x05\x69\
|
||||
\x68\x6f\xdc\x4b\x95\x68\x2f\x7a\xcf\x8c\xa8\x14\x4a\x7c\x05\x06\
|
||||
\xe7\x95\x4a\x85\x4a\x14\x45\x41\x92\xc4\xe1\x7b\xb7\xae\xff\xf6\
|
||||
\xbf\x18\x14\xd1\x37\x74\xf9\x98\x5c\xc6\xdc\x61\xc1\x4c\xff\x39\
|
||||
\xf6\x5d\xc5\xdf\x03\xc0\x3f\x4b\x1d\x48\xe6\x9d\x4c\x36\xb6\x00\
|
||||
\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
|
||||
\x00\x00\x07\x53\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
@ -7579,6 +7801,46 @@ qt_resource_data = "\
|
||||
\x14\xaa\x9a\xa3\x61\x0c\xfc\x0e\x5c\x02\xae\x00\x37\xf9\x3f\xda\
|
||||
\x7f\xdb\xbb\xc9\xf9\x3e\x97\xfc\xce\x00\x00\x00\x00\x49\x45\x4e\
|
||||
\x44\xae\x42\x60\x82\
|
||||
\x00\x00\x02\x5f\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x18\x00\x00\x00\x18\x08\x06\x00\x00\x00\xe0\x77\x3d\xf8\
|
||||
\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
|
||||
\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0d\xd7\x00\x00\x0d\xd7\
|
||||
\x01\x42\x28\x9b\x78\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\
|
||||
\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\
|
||||
\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x01\xdc\x49\x44\
|
||||
\x41\x54\x48\x89\xed\x95\x31\x6b\x53\x51\x18\x86\x9f\x73\xce\x35\
|
||||
\xbd\x1a\x92\x96\xa6\x12\x6f\x17\x35\x01\x69\x4a\x47\x29\x45\x24\
|
||||
\x6a\x8a\xfe\x03\x25\x38\xe8\x22\x4e\x52\x08\x41\xff\x84\x38\x89\
|
||||
\x4e\x59\xe2\x20\x82\xb3\x60\x14\xdb\x24\x5a\x91\x8c\x0e\x56\x1a\
|
||||
\xa8\x0e\xc6\x24\xd0\xd0\xe6\x56\xed\x25\xf4\x9e\xe3\x20\xc6\x62\
|
||||
\x09\xd8\x5b\x70\xca\x37\x9e\xef\x3d\xdf\xf3\xbe\xc3\x77\x8e\x38\
|
||||
\x7f\x2d\xf7\x5e\x1b\x93\xe4\x00\x25\x10\x9d\x11\x54\xaa\xf4\xe8\
|
||||
\xee\xf7\xbf\x7b\x96\xaf\xf5\x54\x3a\x7d\x4e\x29\x29\x03\x03\x5e\
|
||||
\x57\xab\xb1\xde\xf6\x8f\x08\xb0\x17\x00\x70\xc8\x52\x48\xa9\x02\
|
||||
\x03\x04\x06\x33\xa0\x17\xdc\xf6\x3f\xd6\x10\x30\x04\x0c\x01\xff\
|
||||
\x01\x60\x05\xb9\x34\x26\x3e\x90\x34\x05\x39\xca\x2a\x00\x99\x0c\
|
||||
\x47\x80\xe6\x72\xf1\x61\x5f\x63\xa0\x26\x24\xf9\x40\x80\xa4\x29\
|
||||
\xc8\xf1\x50\x1b\x3b\x72\x1a\xa9\x6c\xa4\xb2\x49\x5d\x7a\xc9\xca\
|
||||
\x8b\x8b\x68\xdf\x43\xfb\x1e\xde\x56\x7d\x76\xa7\xd7\xbd\x17\x08\
|
||||
\x30\xca\x2a\xe1\x58\x06\x65\x85\xc1\xfc\x79\xe6\x7e\xc3\x10\x02\
|
||||
\x15\x8a\xe2\x36\x17\x67\x03\x01\x00\x26\x8e\x5f\x21\x3a\x39\x4f\
|
||||
\xe7\xd3\x13\xa2\xf1\x34\x00\x93\x33\xb7\x71\xdb\x55\x62\x27\xb3\
|
||||
\xb8\x5f\x5f\xe1\x36\x17\xb1\xa4\x10\xeb\x4b\x4b\xe5\xf1\xfd\x0c\
|
||||
\xcf\xcc\x33\xb2\xf1\xe5\x19\xfe\xce\x37\x9c\x99\x3b\x18\xdd\x63\
|
||||
\xb3\xf1\x9c\x48\xfc\x2c\xe1\xa3\x73\xb4\x57\xee\xe3\xb6\x2a\x00\
|
||||
\x58\x42\x6d\x26\x60\xcc\xde\x67\x80\x0d\x30\xb8\xad\x32\xf1\xa9\
|
||||
\x5b\x6c\xb5\xdf\xd0\xfe\xf8\x00\x80\xe8\xb1\x0b\xb8\xad\x72\x5f\
|
||||
\x28\x8c\x19\xf4\x55\x0c\xae\xe5\xa2\x30\x20\x98\x48\x5c\x25\x71\
|
||||
\xa6\x80\xf6\xb7\xe9\x7c\x7e\x4a\xec\xc4\x65\xa4\x3a\xcc\xda\xdb\
|
||||
\x1b\xac\xaf\x3d\x06\x4c\xf0\x3d\x70\x52\x0b\x38\xd3\x39\xea\x95\
|
||||
\x2c\xdd\x46\x89\xf8\xa9\x9b\x74\x1b\x25\xea\x95\x2c\xce\x74\x0e\
|
||||
\x27\xb5\x70\xb0\x04\x52\xd9\x68\xdd\x03\xa3\x01\x98\xbb\x6e\x78\
|
||||
\x57\x14\xbf\x04\x42\x22\x65\x08\xed\x7b\xc1\x12\x18\xa8\x69\xdf\
|
||||
\xeb\x0f\xdf\x2b\xd0\x68\xdf\xc3\x40\x2d\x10\x40\x48\xf2\x06\x6a\
|
||||
\xbb\xcf\xfa\xee\x77\x99\x10\x92\xfc\x4f\xfd\xc2\xaa\x73\x0e\x12\
|
||||
\x9d\x40\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
|
||||
\x00\x00\x04\xfd\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
@ -8024,6 +8286,10 @@ qt_resource_name = "\
|
||||
\x09\x28\xf5\xe7\
|
||||
\x00\x66\
|
||||
\x00\x74\x00\x6f\x00\x6f\x00\x6c\x00\x73\x00\x5f\x00\x6c\x00\x6f\x00\x67\x00\x6f\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x0c\
|
||||
\x09\xd4\x06\xc7\
|
||||
\x00\x64\
|
||||
\x00\x65\x00\x6c\x00\x61\x00\x75\x00\x6e\x00\x61\x00\x79\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x15\
|
||||
\x0a\xb1\xae\x07\
|
||||
\x00\x64\
|
||||
@ -8109,6 +8375,10 @@ qt_resource_name = "\
|
||||
\x00\x65\
|
||||
\x00\x78\x00\x70\x00\x6f\x00\x72\x00\x74\x00\x5f\x00\x67\x00\x65\x00\x6f\x00\x6d\x00\x65\x00\x74\x00\x72\x00\x79\x00\x2e\x00\x70\
|
||||
\x00\x6e\x00\x67\
|
||||
\x00\x10\
|
||||
\x05\x40\x6b\xe7\
|
||||
\x00\x6c\
|
||||
\x00\x61\x00\x79\x00\x65\x00\x72\x00\x5f\x00\x65\x00\x78\x00\x74\x00\x65\x00\x6e\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x13\
|
||||
\x06\xd5\x17\xc7\
|
||||
\x00\x73\
|
||||
@ -8133,91 +8403,95 @@ qt_resource_name = "\
|
||||
qt_resource_struct = "\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\
|
||||
\x00\x00\x00\x24\x00\x02\x00\x00\x00\x2a\x00\x00\x00\x2e\
|
||||
\x00\x00\x00\x10\x00\x02\x00\x00\x00\x2a\x00\x00\x00\x04\
|
||||
\x00\x00\x03\x6c\x00\x00\x00\x00\x00\x01\x00\x01\x6e\x70\
|
||||
\x00\x00\x02\xd2\x00\x00\x00\x00\x00\x01\x00\x01\x4e\xaa\
|
||||
\x00\x00\x03\xe2\x00\x00\x00\x00\x00\x01\x00\x01\x86\x54\
|
||||
\x00\x00\x00\xb6\x00\x00\x00\x00\x00\x01\x00\x00\xd0\x92\
|
||||
\x00\x00\x03\x84\x00\x00\x00\x00\x00\x01\x00\x01\x74\xc5\
|
||||
\x00\x00\x00\xe6\x00\x00\x00\x00\x00\x01\x00\x00\xdb\x54\
|
||||
\x00\x00\x00\x6a\x00\x00\x00\x00\x00\x01\x00\x00\xc1\x2f\
|
||||
\x00\x00\x05\x32\x00\x00\x00\x00\x00\x01\x00\x01\xc9\x5a\
|
||||
\x00\x00\x02\x1c\x00\x00\x00\x00\x00\x01\x00\x01\x19\xef\
|
||||
\x00\x00\x04\x8a\x00\x00\x00\x00\x00\x01\x00\x01\xa9\x20\
|
||||
\x00\x00\x01\xcc\x00\x00\x00\x00\x00\x01\x00\x01\x09\x30\
|
||||
\x00\x00\x04\xf4\x00\x00\x00\x00\x00\x01\x00\x01\xbc\xe0\
|
||||
\x00\x00\x05\x5e\x00\x00\x00\x00\x00\x01\x00\x01\xcd\xf4\
|
||||
\x00\x00\x04\xb4\x00\x00\x00\x00\x00\x01\x00\x01\xaf\xb7\
|
||||
\x00\x00\x02\xf0\x00\x00\x00\x00\x00\x01\x00\x01\x55\xc4\
|
||||
\x00\x00\x03\x1c\x00\x00\x00\x00\x00\x01\x00\x01\x5b\x84\
|
||||
\x00\x00\x00\x8e\x00\x00\x00\x00\x00\x01\x00\x00\xc8\x9b\
|
||||
\x00\x00\x00\xcc\x00\x00\x00\x00\x00\x01\x00\x00\xd5\x72\
|
||||
\x00\x00\x05\xb6\x00\x00\x00\x00\x00\x01\x00\x01\xd8\x12\
|
||||
\x00\x00\x02\x64\x00\x00\x00\x00\x00\x01\x00\x01\x26\xcd\
|
||||
\x00\x00\x02\x7e\x00\x00\x00\x00\x00\x01\x00\x01\x31\x5b\
|
||||
\x00\x00\x05\xe4\x00\x00\x00\x00\x00\x01\x00\x01\xdb\xbd\
|
||||
\x00\x00\x01\xa2\x00\x00\x00\x00\x00\x01\x00\x01\x04\x55\
|
||||
\x00\x00\x04\x60\x00\x00\x00\x00\x00\x01\x00\x01\xa1\xda\
|
||||
\x00\x00\x02\xa2\x00\x00\x00\x00\x00\x01\x00\x01\x47\x53\
|
||||
\x00\x00\x01\x4a\x00\x00\x00\x00\x00\x01\x00\x00\xf3\xf7\
|
||||
\x00\x00\x01\x82\x00\x00\x00\x00\x00\x01\x00\x00\xfe\x7e\
|
||||
\x00\x00\x01\x6c\x00\x00\x00\x00\x00\x01\x00\x00\xfa\xa4\
|
||||
\x00\x00\x05\x8a\x00\x00\x00\x00\x00\x01\x00\x01\xd2\xf5\
|
||||
\x00\x00\x04\x20\x00\x00\x00\x00\x00\x01\x00\x01\x95\x53\
|
||||
\x00\x00\x00\x54\x00\x00\x00\x00\x00\x01\x00\x00\xb8\x76\
|
||||
\x00\x00\x05\x12\x00\x00\x00\x00\x00\x01\x00\x01\xc4\xc6\
|
||||
\x00\x00\x01\x04\x00\x00\x00\x00\x00\x01\x00\x00\xe2\x5f\
|
||||
\x00\x00\x04\xd2\x00\x00\x00\x00\x00\x01\x00\x01\xb7\x0b\
|
||||
\x00\x00\x00\x30\x00\x00\x00\x00\x00\x01\x00\x00\xb1\x9f\
|
||||
\x00\x00\x04\x3e\x00\x00\x00\x00\x00\x01\x00\x01\x9a\x4e\
|
||||
\x00\x00\x04\x02\x00\x00\x00\x00\x00\x01\x00\x01\x8e\xeb\
|
||||
\x00\x00\x01\xf4\x00\x00\x00\x00\x00\x01\x00\x01\x0f\x84\
|
||||
\x00\x00\x03\xb4\x00\x00\x00\x00\x00\x01\x00\x01\x7c\x32\
|
||||
\x00\x00\x01\x1e\x00\x00\x00\x00\x00\x01\x00\x00\xec\x50\
|
||||
\x00\x00\x03\x44\x00\x00\x00\x00\x00\x01\x00\x01\x65\x33\
|
||||
\x00\x00\x02\x44\x00\x00\x00\x00\x00\x01\x00\x01\x20\xeb\
|
||||
\x00\x00\x03\x6c\x00\x00\x00\x00\x00\x01\x00\x00\x6d\x8f\
|
||||
\x00\x00\x02\xd2\x00\x00\x00\x00\x00\x01\x00\x00\x5d\xf4\
|
||||
\x00\x00\x03\xe2\x00\x00\x00\x00\x00\x01\x00\x00\x78\x85\
|
||||
\x00\x00\x00\x24\x00\x02\x00\x00\x00\x2c\x00\x00\x00\x30\
|
||||
\x00\x00\x00\x10\x00\x02\x00\x00\x00\x2c\x00\x00\x00\x04\
|
||||
\x00\x00\x03\x8a\x00\x00\x00\x00\x00\x01\x00\x01\x7b\xf3\
|
||||
\x00\x00\x02\xf0\x00\x00\x00\x00\x00\x01\x00\x01\x5c\x2d\
|
||||
\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\x00\x01\x93\xd7\
|
||||
\x00\x00\x00\xb6\x00\x00\x00\x00\x00\x01\x00\x00\xd8\x85\
|
||||
\x00\x00\x03\xa2\x00\x00\x00\x00\x00\x01\x00\x01\x82\x48\
|
||||
\x00\x00\x00\xe6\x00\x00\x00\x00\x00\x01\x00\x00\xe3\x47\
|
||||
\x00\x00\x00\x6a\x00\x00\x00\x00\x00\x01\x00\x00\xc9\x22\
|
||||
\x00\x00\x05\x50\x00\x00\x00\x00\x00\x01\x00\x01\xd6\xdd\
|
||||
\x00\x00\x02\x1c\x00\x00\x00\x00\x00\x01\x00\x01\x21\xe2\
|
||||
\x00\x00\x05\x7c\x00\x00\x00\x00\x00\x01\x00\x01\xdb\x77\
|
||||
\x00\x00\x04\xa8\x00\x00\x00\x00\x00\x01\x00\x01\xb6\xa3\
|
||||
\x00\x00\x01\xcc\x00\x00\x00\x00\x00\x01\x00\x01\x11\x23\
|
||||
\x00\x00\x05\x12\x00\x00\x00\x00\x00\x01\x00\x01\xca\x63\
|
||||
\x00\x00\x05\xa2\x00\x00\x00\x00\x00\x01\x00\x01\xdd\xda\
|
||||
\x00\x00\x04\xd2\x00\x00\x00\x00\x00\x01\x00\x01\xbd\x3a\
|
||||
\x00\x00\x03\x0e\x00\x00\x00\x00\x00\x01\x00\x01\x63\x47\
|
||||
\x00\x00\x03\x3a\x00\x00\x00\x00\x00\x01\x00\x01\x69\x07\
|
||||
\x00\x00\x00\x8e\x00\x00\x00\x00\x00\x01\x00\x00\xd0\x8e\
|
||||
\x00\x00\x00\xcc\x00\x00\x00\x00\x00\x01\x00\x00\xdd\x65\
|
||||
\x00\x00\x05\xfa\x00\x00\x00\x00\x00\x01\x00\x01\xe7\xf8\
|
||||
\x00\x00\x02\x64\x00\x00\x00\x00\x00\x01\x00\x01\x2e\xc0\
|
||||
\x00\x00\x02\x7e\x00\x00\x00\x00\x00\x01\x00\x01\x39\x4e\
|
||||
\x00\x00\x06\x28\x00\x00\x00\x00\x00\x01\x00\x01\xeb\xa3\
|
||||
\x00\x00\x02\xa2\x00\x00\x00\x00\x00\x01\x00\x01\x4f\x46\
|
||||
\x00\x00\x01\xa2\x00\x00\x00\x00\x00\x01\x00\x01\x0c\x48\
|
||||
\x00\x00\x04\x7e\x00\x00\x00\x00\x00\x01\x00\x01\xaf\x5d\
|
||||
\x00\x00\x02\xc0\x00\x00\x00\x00\x00\x01\x00\x01\x54\xd6\
|
||||
\x00\x00\x01\x4a\x00\x00\x00\x00\x00\x01\x00\x00\xfb\xea\
|
||||
\x00\x00\x01\x82\x00\x00\x00\x00\x00\x01\x00\x01\x06\x71\
|
||||
\x00\x00\x01\x6c\x00\x00\x00\x00\x00\x01\x00\x01\x02\x97\
|
||||
\x00\x00\x05\xce\x00\x00\x00\x00\x00\x01\x00\x01\xe2\xdb\
|
||||
\x00\x00\x04\x3e\x00\x00\x00\x00\x00\x01\x00\x01\xa2\xd6\
|
||||
\x00\x00\x00\x54\x00\x00\x00\x00\x00\x01\x00\x00\xc0\x69\
|
||||
\x00\x00\x05\x30\x00\x00\x00\x00\x00\x01\x00\x01\xd2\x49\
|
||||
\x00\x00\x01\x04\x00\x00\x00\x00\x00\x01\x00\x00\xea\x52\
|
||||
\x00\x00\x04\xf0\x00\x00\x00\x00\x00\x01\x00\x01\xc4\x8e\
|
||||
\x00\x00\x00\x30\x00\x00\x00\x00\x00\x01\x00\x00\xb9\x92\
|
||||
\x00\x00\x04\x5c\x00\x00\x00\x00\x00\x01\x00\x01\xa7\xd1\
|
||||
\x00\x00\x04\x20\x00\x00\x00\x00\x00\x01\x00\x01\x9c\x6e\
|
||||
\x00\x00\x01\xf4\x00\x00\x00\x00\x00\x01\x00\x01\x17\x77\
|
||||
\x00\x00\x03\xd2\x00\x00\x00\x00\x00\x01\x00\x01\x89\xb5\
|
||||
\x00\x00\x01\x1e\x00\x00\x00\x00\x00\x01\x00\x00\xf4\x43\
|
||||
\x00\x00\x03\x62\x00\x00\x00\x00\x00\x01\x00\x01\x72\xb6\
|
||||
\x00\x00\x02\x44\x00\x00\x00\x00\x00\x01\x00\x01\x28\xde\
|
||||
\x00\x00\x03\x8a\x00\x00\x00\x00\x00\x01\x00\x00\x73\x1f\
|
||||
\x00\x00\x02\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x63\x84\
|
||||
\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\x00\x00\x7e\x15\
|
||||
\x00\x00\x00\xb6\x00\x00\x00\x00\x00\x01\x00\x00\x13\x9c\
|
||||
\x00\x00\x03\x84\x00\x00\x00\x00\x00\x01\x00\x00\x70\xcd\
|
||||
\x00\x00\x03\xa2\x00\x00\x00\x00\x00\x01\x00\x00\x76\x5d\
|
||||
\x00\x00\x00\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x19\x04\
|
||||
\x00\x00\x00\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x09\xbd\
|
||||
\x00\x00\x05\x32\x00\x00\x00\x00\x00\x01\x00\x00\xa0\x0a\
|
||||
\x00\x00\x05\x50\x00\x00\x00\x00\x00\x01\x00\x00\xa5\x9a\
|
||||
\x00\x00\x02\x1c\x00\x00\x00\x00\x00\x01\x00\x00\x3a\xc5\
|
||||
\x00\x00\x04\x8a\x00\x00\x00\x00\x00\x01\x00\x00\x8a\x39\
|
||||
\x00\x00\x05\x7c\x00\x00\x00\x00\x00\x01\x00\x00\xa8\x7b\
|
||||
\x00\x00\x04\xa8\x00\x00\x00\x00\x00\x01\x00\x00\x8f\xc9\
|
||||
\x00\x00\x01\xcc\x00\x00\x00\x00\x00\x01\x00\x00\x33\xf7\
|
||||
\x00\x00\x04\xf4\x00\x00\x00\x00\x00\x01\x00\x00\x96\x18\
|
||||
\x00\x00\x05\x5e\x00\x00\x00\x00\x00\x01\x00\x00\xa2\xeb\
|
||||
\x00\x00\x04\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x8d\x88\
|
||||
\x00\x00\x02\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x61\x96\
|
||||
\x00\x00\x03\x1c\x00\x00\x00\x00\x00\x01\x00\x00\x64\x12\
|
||||
\x00\x00\x05\x12\x00\x00\x00\x00\x00\x01\x00\x00\x9b\xa8\
|
||||
\x00\x00\x05\xa2\x00\x00\x00\x00\x00\x01\x00\x00\xaa\xde\
|
||||
\x00\x00\x04\xd2\x00\x00\x00\x00\x00\x01\x00\x00\x93\x18\
|
||||
\x00\x00\x03\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x67\x26\
|
||||
\x00\x00\x03\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x69\xa2\
|
||||
\x00\x00\x00\x8e\x00\x00\x00\x00\x00\x01\x00\x00\x0d\x65\
|
||||
\x00\x00\x00\xcc\x00\x00\x00\x00\x00\x01\x00\x00\x17\x33\
|
||||
\x00\x00\x05\xb6\x00\x00\x00\x00\x00\x01\x00\x00\xab\xd0\
|
||||
\x00\x00\x05\xfa\x00\x00\x00\x00\x00\x01\x00\x00\xb3\xc3\
|
||||
\x00\x00\x02\x64\x00\x00\x00\x00\x00\x01\x00\x00\x41\x8a\
|
||||
\x00\x00\x02\x7e\x00\x00\x00\x00\x00\x01\x00\x00\x42\x98\
|
||||
\x00\x00\x05\xe4\x00\x00\x00\x00\x00\x01\x00\x00\xad\xfd\
|
||||
\x00\x00\x01\xa2\x00\x00\x00\x00\x00\x01\x00\x00\x31\x1f\
|
||||
\x00\x00\x04\x60\x00\x00\x00\x00\x00\x01\x00\x00\x88\xd6\
|
||||
\x00\x00\x06\x28\x00\x00\x00\x00\x00\x01\x00\x00\xb5\xf0\
|
||||
\x00\x00\x02\xa2\x00\x00\x00\x00\x00\x01\x00\x00\x58\x90\
|
||||
\x00\x00\x01\xa2\x00\x00\x00\x00\x00\x01\x00\x00\x31\x1f\
|
||||
\x00\x00\x04\x7e\x00\x00\x00\x00\x00\x01\x00\x00\x8e\x66\
|
||||
\x00\x00\x02\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x5e\x20\
|
||||
\x00\x00\x01\x4a\x00\x00\x00\x00\x00\x01\x00\x00\x25\x4f\
|
||||
\x00\x00\x01\x82\x00\x00\x00\x00\x00\x01\x00\x00\x2d\xad\
|
||||
\x00\x00\x01\x6c\x00\x00\x00\x00\x00\x01\x00\x00\x28\x55\
|
||||
\x00\x00\x05\x8a\x00\x00\x00\x00\x00\x01\x00\x00\xa7\x57\
|
||||
\x00\x00\x04\x20\x00\x00\x00\x00\x00\x01\x00\x00\x80\x2b\
|
||||
\x00\x00\x05\xce\x00\x00\x00\x00\x00\x01\x00\x00\xaf\x4a\
|
||||
\x00\x00\x04\x3e\x00\x00\x00\x00\x00\x01\x00\x00\x85\xbb\
|
||||
\x00\x00\x00\x54\x00\x00\x00\x00\x00\x01\x00\x00\x01\x04\
|
||||
\x00\x00\x05\x12\x00\x00\x00\x00\x00\x01\x00\x00\x9b\x3f\
|
||||
\x00\x00\x05\x30\x00\x00\x00\x00\x00\x01\x00\x00\xa0\xcf\
|
||||
\x00\x00\x01\x04\x00\x00\x00\x00\x00\x01\x00\x00\x1d\xe8\
|
||||
\x00\x00\x04\xd2\x00\x00\x00\x00\x00\x01\x00\x00\x92\x34\
|
||||
\x00\x00\x04\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x97\xc4\
|
||||
\x00\x00\x00\x30\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
|
||||
\x00\x00\x04\x3e\x00\x00\x00\x00\x00\x01\x00\x00\x83\x8d\
|
||||
\x00\x00\x04\x02\x00\x00\x00\x00\x00\x01\x00\x00\x7d\x6e\
|
||||
\x00\x00\x04\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x89\x1d\
|
||||
\x00\x00\x04\x20\x00\x00\x00\x00\x00\x01\x00\x00\x82\xfe\
|
||||
\x00\x00\x01\xf4\x00\x00\x00\x00\x00\x01\x00\x00\x37\x71\
|
||||
\x00\x00\x03\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x76\x38\
|
||||
\x00\x00\x03\xd2\x00\x00\x00\x00\x00\x01\x00\x00\x7b\xc8\
|
||||
\x00\x00\x01\x1e\x00\x00\x00\x00\x00\x01\x00\x00\x22\x2e\
|
||||
\x00\x00\x03\x44\x00\x00\x00\x00\x00\x01\x00\x00\x67\x31\
|
||||
\x00\x00\x03\x62\x00\x00\x00\x00\x00\x01\x00\x00\x6c\xc1\
|
||||
\x00\x00\x02\x44\x00\x00\x00\x00\x00\x01\x00\x00\x3d\xd6\
|
||||
"
|
||||
|
||||
|
@ -42,6 +42,8 @@
|
||||
<file>icons/default/vector_grid.png</file>
|
||||
<file>icons/default/split_layer.png</file>
|
||||
<file>icons/default/neighbour.png</file>
|
||||
<file>icons/default/delaunay.png</file>
|
||||
<file>icons/default/layer_extent.png</file>
|
||||
<file>icons/gis/single_to_multi.png</file>
|
||||
<file>icons/gis/simplify.png</file>
|
||||
<file>icons/gis/difference.png</file>
|
||||
@ -84,5 +86,7 @@
|
||||
<file>icons/gis/vector_grid.png</file>
|
||||
<file>icons/gis/split_layer.png</file>
|
||||
<file>icons/gis/neighbour.png</file>
|
||||
<file>icons/gis/delaunay.png</file>
|
||||
<file>icons/gis/layer_extent.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -53,6 +53,7 @@ frmVisual.ui
|
||||
doVectorGrid.py
|
||||
frmRandPoints.py
|
||||
ftools_utils.py
|
||||
voronoi.py
|
||||
doVectorSplit.py
|
||||
frmRandPoints.ui
|
||||
)
|
||||
|
@ -4,6 +4,7 @@ from qgis.core import *
|
||||
from frmGeometry import Ui_Dialog
|
||||
import ftools_utils
|
||||
import math
|
||||
from itertools import izip
|
||||
|
||||
class GeometryDialog(QDialog, Ui_Dialog):
|
||||
|
||||
@ -92,7 +93,7 @@ class GeometryDialog(QDialog, Ui_Dialog):
|
||||
self.label_2.setText( self.tr( "Output shapefile" ) )
|
||||
self.cmbField.setVisible(False)
|
||||
self.field_label.setVisible(False)
|
||||
else: # Polygon centroids
|
||||
elif self.myFunction == 7: # Polygon centroids
|
||||
self.setWindowTitle( self.tr( "Polygon centroids" ) )
|
||||
self.label_2.setText( self.tr( "Output point shapefile" ) )
|
||||
self.label_3.setText( self.tr( "Input polygon vector layer" ) )
|
||||
@ -100,6 +101,18 @@ class GeometryDialog(QDialog, Ui_Dialog):
|
||||
self.lineEdit.setVisible( False )
|
||||
self.cmbField.setVisible( False )
|
||||
self.field_label.setVisible( False )
|
||||
else:
|
||||
if self.myFunction == 8: # Delaunay triangulation
|
||||
self.setWindowTitle( self.tr( "Delaunay triangulation" ) )
|
||||
self.label_3.setText( self.tr( "Input point vector layer" ) )
|
||||
else: # Polygon from layer extent
|
||||
self.setWindowTitle( self.tr( "Polygon from layer extent" ) )
|
||||
self.label_3.setText( self.tr( "Input layer" ) )
|
||||
self.label_2.setText( self.tr( "Output polygon shapefile" ) )
|
||||
self.label.setVisible( False )
|
||||
self.lineEdit.setVisible( False )
|
||||
self.cmbField.setVisible( False )
|
||||
self.field_label.setVisible( False )
|
||||
self.resize( 381, 100 )
|
||||
myList = []
|
||||
self.inShape.clear()
|
||||
@ -107,6 +120,10 @@ class GeometryDialog(QDialog, Ui_Dialog):
|
||||
myList = ftools_utils.getLayerNames( [ QGis.Polygon, QGis.Line ] )
|
||||
elif self.myFunction == 4 or self.myFunction == 7:
|
||||
myList = ftools_utils.getLayerNames( [ QGis.Polygon ] )
|
||||
elif self.myFunction == 8:
|
||||
myList = ftools_utils.getLayerNames( [ QGis.Point ] )
|
||||
elif self.myFunction == 9:
|
||||
myList = ftools_utils.getLayerNames( "all" )
|
||||
else:
|
||||
myList = ftools_utils.getLayerNames( [ QGis.Point, QGis.Line, QGis.Polygon ] )
|
||||
self.inShape.addItems( myList )
|
||||
@ -119,9 +136,14 @@ class GeometryDialog(QDialog, Ui_Dialog):
|
||||
#5: Export/Add geometry columns
|
||||
#6: Simplify geometries
|
||||
#7: Polygon centroids
|
||||
#8: Delaunay triangulation
|
||||
#9: Polygon from layer extent
|
||||
|
||||
def geometry( self, myLayer, myParam, myField ):
|
||||
vlayer = ftools_utils.getVectorLayerByName( myLayer )
|
||||
if self.myFunction == 9:
|
||||
vlayer = ftools_utils.getMapLayerByName( myLayer )
|
||||
else:
|
||||
vlayer = ftools_utils.getVectorLayerByName( myLayer )
|
||||
error = False
|
||||
check = QFile( self.shapefileName )
|
||||
if check.exists():
|
||||
@ -143,21 +165,21 @@ class GeometryDialog(QDialog, Ui_Dialog):
|
||||
def runFinishedFromThread( self, success ):
|
||||
self.testThread.stop()
|
||||
if success == "math_error":
|
||||
QMessageBox.warning( self, "Geoprocessing", self.tr( "Error processing specified tolerance!" ) + "\n"
|
||||
QMessageBox.warning( self, "Geometry", self.tr( "Error processing specified tolerance!" ) + "\n"
|
||||
+ self.tr( "Please choose larger tolerance..." ) )
|
||||
if not QgsVectorFileWriter.deleteShapeFile( self.shapefileName ):
|
||||
QMessageBox.warning( self, "Geoprocessing", self.tr( "Unable to delete incomplete shapefile." ) )
|
||||
QMessageBox.warning( self, "Geometry", self.tr( "Unable to delete incomplete shapefile." ) )
|
||||
else:
|
||||
self.cancel_close.setText( "Close" )
|
||||
QObject.disconnect( self.cancel_close, SIGNAL( "clicked()" ), self.cancelThread )
|
||||
if success:
|
||||
addToTOC = QMessageBox.question( self, "Geoprocessing", self.tr( "Created output shapefile:" ) + "\n" +
|
||||
addToTOC = QMessageBox.question( self, "Geometry", self.tr( "Created output shapefile:" ) + "\n" +
|
||||
unicode( self.shapefileName ) + "\n\n" + self.tr( "Would you like to add the new layer to the TOC?" ),
|
||||
QMessageBox.Yes, QMessageBox.No, QMessageBox.NoButton )
|
||||
if addToTOC == QMessageBox.Yes:
|
||||
ftools_utils.addShapeToCanvas( unicode( self.shapefileName ) )
|
||||
else:
|
||||
QMessageBox.warning( self, "Geoprocessing", self.tr( "Error writing output shapefile." ) )
|
||||
QMessageBox.warning( self, "Geometry", self.tr( "Error writing output shapefile." ) )
|
||||
|
||||
def runStatusFromThread( self, status ):
|
||||
self.progressBar.setValue( status )
|
||||
@ -193,6 +215,10 @@ class geometryThread( QThread ):
|
||||
success = self.simplify_geometry()
|
||||
elif self.myFunction == 7: # Polygon centroids
|
||||
success = self.polygon_centroids()
|
||||
elif self.myFunction == 8: # Delaunay triangulation
|
||||
success = self.delaunay_triangulation()
|
||||
elif self.myFunction == 9: # Polygon from layer extent
|
||||
success = self.layer_extent()
|
||||
self.emit( SIGNAL( "runFinished(PyQt_PyObject)" ), success )
|
||||
self.emit( SIGNAL( "runStatus(PyQt_PyObject)" ), 0 )
|
||||
|
||||
@ -452,6 +478,108 @@ class geometryThread( QThread ):
|
||||
self.emit( SIGNAL( "runStatus(PyQt_PyObject)" ), nElement )
|
||||
del writer
|
||||
return True
|
||||
|
||||
def delaunay_triangulation( self ):
|
||||
import voronoi
|
||||
vprovider = self.vlayer.dataProvider()
|
||||
allAttrs = vprovider.attributeIndexes()
|
||||
vprovider.select( allAttrs )
|
||||
fields = {
|
||||
0 : QgsField( "POINTA", QVariant.Double ),
|
||||
1 : QgsField( "POINTB", QVariant.Double ),
|
||||
2 : QgsField( "POINTC", QVariant.Double ) }
|
||||
writer = QgsVectorFileWriter( self.myName, self.myEncoding,
|
||||
fields, QGis.WKBPolygon, vprovider.crs() )
|
||||
inFeat = QgsFeature()
|
||||
points = []
|
||||
print "here"
|
||||
while vprovider.nextFeature( inFeat ):
|
||||
inGeom = QgsGeometry( inFeat.geometry() )
|
||||
point = inGeom.asPoint()
|
||||
points.append( point )
|
||||
print "or here"
|
||||
vprovider.rewind()
|
||||
vprovider.select( allAttrs )
|
||||
triangles = voronoi.computeDelaunayTriangulation( points )
|
||||
feat = QgsFeature()
|
||||
nFeat = len( triangles )
|
||||
nElement = 0
|
||||
self.emit( SIGNAL( "runStatus(PyQt_PyObject)" ), 0 )
|
||||
self.emit( SIGNAL( "runRange(PyQt_PyObject)" ), ( 0, nFeat ) )
|
||||
for triangle in triangles:
|
||||
indicies = list( triangle )
|
||||
indicies.append( indicies[ 0 ] )
|
||||
polygon = []
|
||||
step = 0
|
||||
for index in indicies:
|
||||
vprovider.featureAtId( index, feat, True, allAttrs )
|
||||
geom = QgsGeometry( feat.geometry() )
|
||||
point = QgsPoint( geom.asPoint() )
|
||||
polygon.append( point )
|
||||
feat.addAttribute( step, QVariant( index ) )
|
||||
step += 1
|
||||
geometry = QgsGeometry().fromPolygon( [ polygon ] )
|
||||
feat.setGeometry( geometry )
|
||||
writer.addFeature( feat )
|
||||
nElement += 1
|
||||
self.emit( SIGNAL( "runStatus(PyQt_PyObject)" ), nElement )
|
||||
del writer
|
||||
return True
|
||||
|
||||
def layer_extent( self ):
|
||||
self.emit( SIGNAL( "runStatus(PyQt_PyObject)" ), 0 )
|
||||
self.emit( SIGNAL( "runRange(PyQt_PyObject)" ), ( 0, 0 ) )
|
||||
fields = {
|
||||
0 : QgsField( "MINX", QVariant.Double ),
|
||||
1 : QgsField( "MINY", QVariant.Double ),
|
||||
2 : QgsField( "MAXX", QVariant.Double ),
|
||||
3 : QgsField( "MAXY", QVariant.Double ),
|
||||
4 : QgsField( "CNTX", QVariant.Double ),
|
||||
5 : QgsField( "CNTY", QVariant.Double ),
|
||||
6 : QgsField( "AREA", QVariant.Double ),
|
||||
7 : QgsField( "PERIM", QVariant.Double ),
|
||||
8 : QgsField( "HEIGHT", QVariant.Double ),
|
||||
9 : QgsField( "WIDTH", QVariant.Double ) }
|
||||
|
||||
writer = QgsVectorFileWriter( self.myName, self.myEncoding,
|
||||
fields, QGis.WKBPolygon, self.vlayer.srs() )
|
||||
rect = self.vlayer.extent()
|
||||
minx = rect.xMinimum()
|
||||
miny = rect.yMinimum()
|
||||
maxx = rect.xMaximum()
|
||||
maxy = rect.yMaximum()
|
||||
height = rect.height()
|
||||
width = rect.width()
|
||||
cntx = minx + ( width / 2.0 )
|
||||
cnty = miny + ( height / 2.0 )
|
||||
area = width * height
|
||||
perim = ( 2 * width ) + (2 * height )
|
||||
rect = [
|
||||
QgsPoint( minx, miny ),
|
||||
QgsPoint( minx, maxy ),
|
||||
QgsPoint( maxx, maxy ),
|
||||
QgsPoint( maxx, miny ),
|
||||
QgsPoint( minx, miny ) ]
|
||||
geometry = QgsGeometry().fromPolygon( [ rect ] )
|
||||
feat = QgsFeature()
|
||||
feat.setGeometry( geometry )
|
||||
feat.setAttributeMap( {
|
||||
0 : QVariant( minx ),
|
||||
1 : QVariant( miny ),
|
||||
2 : QVariant( maxx ),
|
||||
3 : QVariant( maxy ),
|
||||
4 : QVariant( cntx ),
|
||||
5 : QVariant( cnty ),
|
||||
6 : QVariant( area ),
|
||||
7 : QVariant( perim ),
|
||||
8 : QVariant( height ),
|
||||
9 : QVariant( width ) } )
|
||||
writer.addFeature( feat )
|
||||
self.emit( SIGNAL( "runRange(PyQt_PyObject)" ), ( 0, 100 ) )
|
||||
self.emit( SIGNAL( "runStatus(PyQt_PyObject)" ), 0 )
|
||||
del writer
|
||||
|
||||
return True
|
||||
|
||||
def extractAsSimple( self, geom, tolerance ):
|
||||
temp_geom1 = []
|
||||
|
@ -218,7 +218,6 @@ class Dialog(QDialog, Ui_Dialog):
|
||||
if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName):
|
||||
return
|
||||
writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fields, QGis.WKBPoint, None)
|
||||
#writer = QgsVectorFileWriter(unicode(outPath), "CP1250", fields, QGis.WKBPoint, None)
|
||||
idVar = 0
|
||||
count = 70.00
|
||||
add = 30.00 / len(points)
|
||||
|
@ -159,10 +159,14 @@ def createUniqueFieldName( field ):
|
||||
def getLayerNames( vTypes ):
|
||||
layermap = QgsMapLayerRegistry.instance().mapLayers()
|
||||
layerlist = []
|
||||
for name, layer in layermap.iteritems():
|
||||
if layer.type() == QgsMapLayer.VectorLayer:
|
||||
if layer.geometryType() in vTypes and not layer.name() in layerlist:
|
||||
layerlist.append( unicode( layer.name() ) )
|
||||
if vTypes == "all":
|
||||
for name, layer in layermap.iteritems():
|
||||
layerlist.append( unicode( layer.name() ) )
|
||||
else:
|
||||
for name, layer in layermap.iteritems():
|
||||
if layer.type() == QgsMapLayer.VectorLayer:
|
||||
if layer.geometryType() in vTypes:
|
||||
layerlist.append( unicode( layer.name() ) )
|
||||
return layerlist
|
||||
|
||||
# Return list of names of all fields from input QgsVectorLayer
|
||||
|
838
python/plugins/fTools/tools/voronoi.py
Normal file
838
python/plugins/fTools/tools/voronoi.py
Normal file
@ -0,0 +1,838 @@
|
||||
#############################################################################
|
||||
#
|
||||
# Voronoi diagram calculator/ Delaunay triangulator
|
||||
# Translated to Python by Bill Simons
|
||||
# September, 2005
|
||||
#
|
||||
# Calculate Delaunay triangulation or the Voronoi polygons for a set of
|
||||
# 2D input points.
|
||||
#
|
||||
# Derived from code bearing the following notice:
|
||||
#
|
||||
# The author of this software is Steven Fortune. Copyright (c) 1994 by AT&T
|
||||
# Bell Laboratories.
|
||||
# Permission to use, copy, modify, and distribute this software for any
|
||||
# purpose without fee is hereby granted, provided that this entire notice
|
||||
# is included in all copies of any software which is or includes a copy
|
||||
# or modification of this software and in all copies of the supporting
|
||||
# documentation for such software.
|
||||
# THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
# WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
|
||||
# REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
# OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
#
|
||||
# Comments were incorporated from Shane O'Sullivan's translation of the
|
||||
# original code into C++ (http://mapviewer.skynet.ie/voronoi.html)
|
||||
#
|
||||
# Steve Fortune's homepage: http://netlib.bell-labs.com/cm/cs/who/sjf/index.html
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
def usage():
|
||||
print """
|
||||
voronoi - compute Voronoi diagram or Delaunay triangulation
|
||||
|
||||
voronoi [-t -p -d] [filename]
|
||||
|
||||
Voronoi reads from filename (or standard input if no filename given) for a set
|
||||
of points in the plane and writes either the Voronoi diagram or the Delaunay
|
||||
triangulation to the standard output. Each input line should consist of two
|
||||
real numbers, separated by white space.
|
||||
|
||||
If option -t is present, the Delaunay triangulation is produced.
|
||||
Each output line is a triple i j k, which are the indices of the three points
|
||||
in a Delaunay triangle. Points are numbered starting at 0.
|
||||
|
||||
If option -t is not present, the Voronoi diagram is produced.
|
||||
There are four output record types.
|
||||
|
||||
s a b indicates that an input point at coordinates a b was seen.
|
||||
l a b c indicates a line with equation ax + by = c.
|
||||
v a b indicates a vertex at a b.
|
||||
e l v1 v2 indicates a Voronoi segment which is a subsegment of line number l
|
||||
with endpoints numbered v1 and v2. If v1 or v2 is -1, the line
|
||||
extends to infinity.
|
||||
|
||||
Other options include:
|
||||
|
||||
d Print debugging info
|
||||
|
||||
p Produce output suitable for input to plot (1), rather than the forms
|
||||
described above.
|
||||
|
||||
On unsorted data uniformly distributed in the unit square, voronoi uses about
|
||||
20n+140 bytes of storage.
|
||||
|
||||
AUTHOR
|
||||
Steve J. Fortune (1987) A Sweepline Algorithm for Voronoi Diagrams,
|
||||
Algorithmica 2, 153-174.
|
||||
"""
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# For programmatic use two functions are available:
|
||||
#
|
||||
# computeVoronoiDiagram(points)
|
||||
#
|
||||
# Takes a list of point objects (which must have x and y fields).
|
||||
# Returns a 3-tuple of:
|
||||
#
|
||||
# (1) a list of 2-tuples, which are the x,y coordinates of the
|
||||
# Voronoi diagram vertices
|
||||
# (2) a list of 3-tuples (a,b,c) which are the equations of the
|
||||
# lines in the Voronoi diagram: a*x + b*y = c
|
||||
# (3) a list of 3-tuples, (l, v1, v2) representing edges of the
|
||||
# Voronoi diagram. l is the index of the line, v1 and v2 are
|
||||
# the indices of the vetices at the end of the edge. If
|
||||
# v1 or v2 is -1, the line extends to infinity.
|
||||
#
|
||||
# computeDelaunayTriangulation(points):
|
||||
#
|
||||
# Takes a list of point objects (which must have x and y fields).
|
||||
# Returns a list of 3-tuples: the indices of the points that form a
|
||||
# Delaunay triangle.
|
||||
#
|
||||
#############################################################################
|
||||
import math
|
||||
import sys
|
||||
import getopt
|
||||
TOLERANCE = 1e-9
|
||||
BIG_FLOAT = 1e38
|
||||
|
||||
#------------------------------------------------------------------
|
||||
class Context( object ):
|
||||
def __init__(self):
|
||||
self.doPrint = 0
|
||||
self.debug = 0
|
||||
self.plot = 0
|
||||
self.triangulate = False
|
||||
self.vertices = [] # list of vertex 2-tuples: (x,y)
|
||||
self.lines = [] # equation of line 3-tuple (a b c), for the equation of the line a*x+b*y = c
|
||||
self.edges = [] # edge 3-tuple: (line index, vertex 1 index, vertex 2 index) if either vertex index is -1, the edge extends to infiinity
|
||||
self.triangles = [] # 3-tuple of vertex indices
|
||||
# self.extra_edges = [] # list of additional vertex 2-tubles (x,y) based on bounded voronoi tesselation
|
||||
# self.set_bounds(None)
|
||||
# self.use_bound = False
|
||||
self.xmin = self.ymin = self.xmax = self.ymax = None
|
||||
|
||||
def circle(self,x,y,rad):
|
||||
pass
|
||||
|
||||
def clip_line(self,edge,lid,rid):
|
||||
pass
|
||||
# here is where I will create false verticies if
|
||||
# the voronoi line extends to infinity...
|
||||
# the extra verticies will be added to the
|
||||
# extra edges list as 2-tuples
|
||||
# a,b,c = edge.a,edge.b,edge.c
|
||||
# if lid == -1:
|
||||
# x = self.xMin
|
||||
# y = (c-a*x) / b
|
||||
# if y < self.yMin or y > self.yMax:
|
||||
# if y < self.yMin: y = self.yMin
|
||||
# elif y > self.yMax: y = self.yMax
|
||||
# x = (c-b*y) / a
|
||||
# self.extra_edges.append((x,y))
|
||||
# lid = -(len(self.extra_edges)-1)
|
||||
# if rid == -1:
|
||||
# x = self.xMax
|
||||
# y = (c-a*x) / b
|
||||
# if y < self.yMin or y > self.yMax:
|
||||
# if y < self.yMin: y = self.yMin
|
||||
# elif y > self.yMax: y = self.yMax
|
||||
# x = (c-b*y) / a
|
||||
# self.extra_edges.append((x,y))
|
||||
# rid = -(len(self.extra_edges)-1)
|
||||
# print lid,rid
|
||||
# return (lid,rid)
|
||||
|
||||
def line(self,x0,y0,x1,y1):
|
||||
pass
|
||||
|
||||
def outSite(self,s):
|
||||
if(self.debug):
|
||||
print "site (%d) at %f %f" % (s.sitenum, s.x, s.y)
|
||||
elif(self.triangulate):
|
||||
pass
|
||||
elif(self.plot):
|
||||
self.circle (s.x, s.y, 3) #cradius)
|
||||
elif(self.doPrint):
|
||||
print "s %f %f" % (s.x, s.y)
|
||||
|
||||
def outVertex(self,s):
|
||||
self.vertices.append((s.x,s.y))
|
||||
if s.x < self.xmin: self.xmin = s.x
|
||||
elif s.x > self.xmax: self.xmax = s.x
|
||||
if s.y < self.ymin: self.ymin = s.y
|
||||
elif s.y > self.ymax: self.ymax = s.y
|
||||
|
||||
if(self.debug):
|
||||
print "vertex(%d) at %f %f" % (s.sitenum, s.x, s.y)
|
||||
elif(self.triangulate):
|
||||
pass
|
||||
elif(self.doPrint and not self.plot):
|
||||
print "v %f %f" % (s.x,s.y)
|
||||
|
||||
def outTriple(self,s1,s2,s3):
|
||||
self.triangles.append((s1.sitenum, s2.sitenum, s3.sitenum))
|
||||
if(self.debug):
|
||||
print "circle through left=%d right=%d bottom=%d" % (s1.sitenum, s2.sitenum, s3.sitenum)
|
||||
elif(self.triangulate and self.doPrint and not self.plot):
|
||||
print "%d %d %d" % (s1.sitenum, s2.sitenum, s3.sitenum)
|
||||
|
||||
def outBisector(self,edge):
|
||||
self.lines.append((edge.a, edge.b, edge.c))
|
||||
if(self.debug):
|
||||
print "line(%d) %gx+%gy=%g, bisecting %d %d" % (edge.edgenum, edge.a, edge.b, edge.c, edge.reg[0].sitenum, edge.reg[1].sitenum)
|
||||
elif(self.triangulate):
|
||||
if(self.plot):
|
||||
self.line(edge.reg[0].x, edge.reg[0].y, edge.reg[1].x, edge.reg[1].y)
|
||||
elif(self.doPrint and not self.plot):
|
||||
print "l %f %f %f" % (edge.a, edge.b, edge.c)
|
||||
|
||||
def outEdge(self,edge):
|
||||
sitenumL = -1
|
||||
if edge.ep[Edge.LE] is not None:
|
||||
sitenumL = edge.ep[Edge.LE].sitenum
|
||||
sitenumR = -1
|
||||
if edge.ep[Edge.RE] is not None:
|
||||
sitenumR = edge.ep[Edge.RE].sitenum
|
||||
|
||||
# if sitenumL == -1 or sitenumR == -1 and self.use_bound:
|
||||
# sitenumL,sitenumR = self.clip_line(edge,sitenumL,sitenumR)
|
||||
|
||||
self.edges.append((edge.edgenum,sitenumL,sitenumR))
|
||||
if(not self.triangulate):
|
||||
if self.plot:
|
||||
self.clip_line(edge)
|
||||
elif(self.doPrint):
|
||||
print "e %d" % edge.edgenum,
|
||||
print " %d " % sitenumL,
|
||||
print "%d" % sitenumR
|
||||
|
||||
def set_bounds(self,bounds):
|
||||
if not bounds == None:
|
||||
self.xmin = bounds.xmin
|
||||
self.ymin = bounds.ymin
|
||||
self.xmax = bounds.xmax
|
||||
self.ymax = bounds.ymax
|
||||
else:
|
||||
self.xmin = self.ymin = self.xmax = self.ymax = None
|
||||
|
||||
|
||||
#------------------------------------------------------------------
|
||||
def voronoi(siteList,context):
|
||||
edgeList = EdgeList(siteList.xmin,siteList.xmax,len(siteList))
|
||||
priorityQ = PriorityQueue(siteList.ymin,siteList.ymax,len(siteList))
|
||||
siteIter = siteList.iterator()
|
||||
|
||||
bottomsite = siteIter.next()
|
||||
context.outSite(bottomsite)
|
||||
newsite = siteIter.next()
|
||||
minpt = Site(-BIG_FLOAT,-BIG_FLOAT)
|
||||
while True:
|
||||
if not priorityQ.isEmpty():
|
||||
minpt = priorityQ.getMinPt()
|
||||
|
||||
if (newsite and (priorityQ.isEmpty() or cmp(newsite,minpt) < 0)):
|
||||
# newsite is smallest - this is a site event
|
||||
context.outSite(newsite)
|
||||
|
||||
# get first Halfedge to the LEFT and RIGHT of the new site
|
||||
lbnd = edgeList.leftbnd(newsite)
|
||||
rbnd = lbnd.right
|
||||
|
||||
# if this halfedge has no edge, bot = bottom site (whatever that is)
|
||||
# create a new edge that bisects
|
||||
bot = lbnd.rightreg(bottomsite)
|
||||
edge = Edge.bisect(bot,newsite)
|
||||
context.outBisector(edge)
|
||||
|
||||
# create a new Halfedge, setting its pm field to 0 and insert
|
||||
# this new bisector edge between the left and right vectors in
|
||||
# a linked list
|
||||
bisector = Halfedge(edge,Edge.LE)
|
||||
edgeList.insert(lbnd,bisector)
|
||||
|
||||
# if the new bisector intersects with the left edge, remove
|
||||
# the left edge's vertex, and put in the new one
|
||||
p = lbnd.intersect(bisector)
|
||||
if p is not None:
|
||||
priorityQ.delete(lbnd)
|
||||
priorityQ.insert(lbnd,p,newsite.distance(p))
|
||||
|
||||
# create a new Halfedge, setting its pm field to 1
|
||||
# insert the new Halfedge to the right of the original bisector
|
||||
lbnd = bisector
|
||||
bisector = Halfedge(edge,Edge.RE)
|
||||
edgeList.insert(lbnd,bisector)
|
||||
|
||||
# if this new bisector intersects with the right Halfedge
|
||||
p = bisector.intersect(rbnd)
|
||||
if p is not None:
|
||||
# push the Halfedge into the ordered linked list of vertices
|
||||
priorityQ.insert(bisector,p,newsite.distance(p))
|
||||
|
||||
newsite = siteIter.next()
|
||||
|
||||
elif not priorityQ.isEmpty():
|
||||
# intersection is smallest - this is a vector (circle) event
|
||||
|
||||
# pop the Halfedge with the lowest vector off the ordered list of
|
||||
# vectors. Get the Halfedge to the left and right of the above HE
|
||||
# and also the Halfedge to the right of the right HE
|
||||
lbnd = priorityQ.popMinHalfedge()
|
||||
llbnd = lbnd.left
|
||||
rbnd = lbnd.right
|
||||
rrbnd = rbnd.right
|
||||
|
||||
# get the Site to the left of the left HE and to the right of
|
||||
# the right HE which it bisects
|
||||
bot = lbnd.leftreg(bottomsite)
|
||||
top = rbnd.rightreg(bottomsite)
|
||||
|
||||
# output the triple of sites, stating that a circle goes through them
|
||||
mid = lbnd.rightreg(bottomsite)
|
||||
context.outTriple(bot,top,mid)
|
||||
|
||||
# get the vertex that caused this event and set the vertex number
|
||||
# couldn't do this earlier since we didn't know when it would be processed
|
||||
v = lbnd.vertex
|
||||
siteList.setSiteNumber(v)
|
||||
context.outVertex(v)
|
||||
|
||||
# set the endpoint of the left and right Halfedge to be this vector
|
||||
if lbnd.edge.setEndpoint(lbnd.pm,v):
|
||||
context.outEdge(lbnd.edge)
|
||||
|
||||
if rbnd.edge.setEndpoint(rbnd.pm,v):
|
||||
context.outEdge(rbnd.edge)
|
||||
|
||||
|
||||
# delete the lowest HE, remove all vertex events to do with the
|
||||
# right HE and delete the right HE
|
||||
edgeList.delete(lbnd)
|
||||
priorityQ.delete(rbnd)
|
||||
edgeList.delete(rbnd)
|
||||
|
||||
|
||||
# if the site to the left of the event is higher than the Site
|
||||
# to the right of it, then swap them and set 'pm' to RIGHT
|
||||
pm = Edge.LE
|
||||
if bot.y > top.y:
|
||||
bot,top = top,bot
|
||||
pm = Edge.RE
|
||||
|
||||
# Create an Edge (or line) that is between the two Sites. This
|
||||
# creates the formula of the line, and assigns a line number to it
|
||||
edge = Edge.bisect(bot, top)
|
||||
context.outBisector(edge)
|
||||
|
||||
# create a HE from the edge
|
||||
bisector = Halfedge(edge, pm)
|
||||
|
||||
# insert the new bisector to the right of the left HE
|
||||
# set one endpoint to the new edge to be the vector point 'v'
|
||||
# If the site to the left of this bisector is higher than the right
|
||||
# Site, then this endpoint is put in position 0; otherwise in pos 1
|
||||
edgeList.insert(llbnd, bisector)
|
||||
if edge.setEndpoint(Edge.RE - pm, v):
|
||||
context.outEdge(edge)
|
||||
|
||||
# if left HE and the new bisector don't intersect, then delete
|
||||
# the left HE, and reinsert it
|
||||
p = llbnd.intersect(bisector)
|
||||
if p is not None:
|
||||
priorityQ.delete(llbnd);
|
||||
priorityQ.insert(llbnd, p, bot.distance(p))
|
||||
|
||||
# if right HE and the new bisector don't intersect, then reinsert it
|
||||
p = bisector.intersect(rrbnd)
|
||||
if p is not None:
|
||||
priorityQ.insert(bisector, p, bot.distance(p))
|
||||
else:
|
||||
break
|
||||
|
||||
he = edgeList.leftend.right
|
||||
while he is not edgeList.rightend:
|
||||
context.outEdge(he.edge)
|
||||
he = he.right
|
||||
|
||||
#------------------------------------------------------------------
|
||||
def isEqual(a,b,relativeError=TOLERANCE):
|
||||
# is nearly equal to within the allowed relative error
|
||||
norm = max(abs(a),abs(b))
|
||||
return (norm < relativeError) or (abs(a - b) < (relativeError * norm))
|
||||
|
||||
#------------------------------------------------------------------
|
||||
class Site(object):
|
||||
def __init__(self,x=0.0,y=0.0,sitenum=0):
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.sitenum = sitenum
|
||||
|
||||
def dump(self):
|
||||
print "Site #%d (%g, %g)" % (self.sitenum,self.x,self.y)
|
||||
|
||||
def __cmp__(self,other):
|
||||
if self.y < other.y:
|
||||
return -1
|
||||
elif self.y > other.y:
|
||||
return 1
|
||||
elif self.x < other.x:
|
||||
return -1
|
||||
elif self.x > other.x:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def distance(self,other):
|
||||
dx = self.x - other.x
|
||||
dy = self.y - other.y
|
||||
return math.sqrt(dx*dx + dy*dy)
|
||||
|
||||
#------------------------------------------------------------------
|
||||
class Edge(object):
|
||||
LE = 0
|
||||
RE = 1
|
||||
EDGE_NUM = 0
|
||||
DELETED = {} # marker value
|
||||
|
||||
def __init__(self):
|
||||
self.a = 0.0
|
||||
self.b = 0.0
|
||||
self.c = 0.0
|
||||
self.ep = [None,None]
|
||||
self.reg = [None,None]
|
||||
self.edgenum = 0
|
||||
|
||||
def dump(self):
|
||||
print "(#%d a=%g, b=%g, c=%g)" % (self.edgenum,self.a,self.b,self.c)
|
||||
print "ep",self.ep
|
||||
print "reg",self.reg
|
||||
|
||||
def setEndpoint(self, lrFlag, site):
|
||||
self.ep[lrFlag] = site
|
||||
if self.ep[Edge.RE - lrFlag] is None:
|
||||
return False
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def bisect(s1,s2):
|
||||
newedge = Edge()
|
||||
newedge.reg[0] = s1 # store the sites that this edge is bisecting
|
||||
newedge.reg[1] = s2
|
||||
|
||||
# to begin with, there are no endpoints on the bisector - it goes to infinity
|
||||
# ep[0] and ep[1] are None
|
||||
|
||||
# get the difference in x dist between the sites
|
||||
dx = float(s2.x - s1.x)
|
||||
dy = float(s2.y - s1.y)
|
||||
adx = abs(dx) # make sure that the difference in positive
|
||||
ady = abs(dy)
|
||||
|
||||
# get the slope of the line
|
||||
newedge.c = float(s1.x * dx + s1.y * dy + (dx*dx + dy*dy)*0.5)
|
||||
if adx > ady :
|
||||
# set formula of line, with x fixed to 1
|
||||
newedge.a = 1.0
|
||||
newedge.b = dy/dx
|
||||
newedge.c /= dx
|
||||
else:
|
||||
# set formula of line, with y fixed to 1
|
||||
newedge.b = 1.0
|
||||
newedge.a = dx/dy
|
||||
newedge.c /= dy
|
||||
|
||||
newedge.edgenum = Edge.EDGE_NUM
|
||||
Edge.EDGE_NUM += 1
|
||||
return newedge
|
||||
|
||||
|
||||
#------------------------------------------------------------------
|
||||
class Halfedge(object):
|
||||
def __init__(self,edge=None,pm=Edge.LE):
|
||||
self.left = None # left Halfedge in the edge list
|
||||
self.right = None # right Halfedge in the edge list
|
||||
self.qnext = None # priority queue linked list pointer
|
||||
self.edge = edge # edge list Edge
|
||||
self.pm = pm
|
||||
self.vertex = None # Site()
|
||||
self.ystar = BIG_FLOAT
|
||||
|
||||
def dump(self):
|
||||
print "Halfedge--------------------------"
|
||||
print "left: ", self.left
|
||||
print "right: ", self.right
|
||||
print "edge: ", self.edge
|
||||
print "pm: ", self.pm
|
||||
print "vertex: ",
|
||||
if self.vertex: self.vertex.dump()
|
||||
else: print "None"
|
||||
print "ystar: ", self.ystar
|
||||
|
||||
|
||||
def __cmp__(self,other):
|
||||
if self.ystar > other.ystar:
|
||||
return 1
|
||||
elif self.ystar < other.ystar:
|
||||
return -1
|
||||
elif self.vertex.x > other.vertex.x:
|
||||
return 1
|
||||
elif self.vertex.x < other.vertex.x:
|
||||
return -1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def leftreg(self,default):
|
||||
if not self.edge:
|
||||
return default
|
||||
elif self.pm == Edge.LE:
|
||||
return self.edge.reg[Edge.LE]
|
||||
else:
|
||||
return self.edge.reg[Edge.RE]
|
||||
|
||||
def rightreg(self,default):
|
||||
if not self.edge:
|
||||
return default
|
||||
elif self.pm == Edge.LE:
|
||||
return self.edge.reg[Edge.RE]
|
||||
else:
|
||||
return self.edge.reg[Edge.LE]
|
||||
|
||||
|
||||
# returns True if p is to right of halfedge self
|
||||
def isPointRightOf(self,pt):
|
||||
e = self.edge
|
||||
topsite = e.reg[1]
|
||||
right_of_site = pt.x > topsite.x
|
||||
|
||||
if(right_of_site and self.pm == Edge.LE):
|
||||
return True
|
||||
|
||||
if(not right_of_site and self.pm == Edge.RE):
|
||||
return False
|
||||
|
||||
if(e.a == 1.0):
|
||||
dyp = pt.y - topsite.y
|
||||
dxp = pt.x - topsite.x
|
||||
fast = 0;
|
||||
if ((not right_of_site and e.b < 0.0) or (right_of_site and e.b >= 0.0)):
|
||||
above = dyp >= e.b * dxp
|
||||
fast = above
|
||||
else:
|
||||
above = pt.x + pt.y * e.b > e.c
|
||||
if(e.b < 0.0):
|
||||
above = not above
|
||||
if (not above):
|
||||
fast = 1
|
||||
if (not fast):
|
||||
dxs = topsite.x - (e.reg[0]).x
|
||||
above = e.b * (dxp*dxp - dyp*dyp) < dxs*dyp*(1.0+2.0*dxp/dxs + e.b*e.b)
|
||||
if(e.b < 0.0):
|
||||
above = not above
|
||||
else: # e.b == 1.0
|
||||
yl = e.c - e.a * pt.x
|
||||
t1 = pt.y - yl
|
||||
t2 = pt.x - topsite.x
|
||||
t3 = yl - topsite.y
|
||||
above = t1*t1 > t2*t2 + t3*t3
|
||||
|
||||
if(self.pm==Edge.LE):
|
||||
return above
|
||||
else:
|
||||
return not above
|
||||
|
||||
#--------------------------
|
||||
# create a new site where the Halfedges el1 and el2 intersect
|
||||
def intersect(self,other):
|
||||
e1 = self.edge
|
||||
e2 = other.edge
|
||||
if (e1 is None) or (e2 is None):
|
||||
return None
|
||||
|
||||
# if the two edges bisect the same parent return None
|
||||
if e1.reg[1] is e2.reg[1]:
|
||||
return None
|
||||
|
||||
d = e1.a * e2.b - e1.b * e2.a
|
||||
if isEqual(d,0.0):
|
||||
return None
|
||||
|
||||
xint = (e1.c*e2.b - e2.c*e1.b) / d
|
||||
yint = (e2.c*e1.a - e1.c*e2.a) / d
|
||||
if(cmp(e1.reg[1],e2.reg[1]) < 0):
|
||||
he = self
|
||||
e = e1
|
||||
else:
|
||||
he = other
|
||||
e = e2
|
||||
|
||||
rightOfSite = xint >= e.reg[1].x
|
||||
if((rightOfSite and he.pm == Edge.LE) or
|
||||
(not rightOfSite and he.pm == Edge.RE)):
|
||||
return None
|
||||
|
||||
# create a new site at the point of intersection - this is a new
|
||||
# vector event waiting to happen
|
||||
return Site(xint,yint)
|
||||
|
||||
|
||||
|
||||
#------------------------------------------------------------------
|
||||
class EdgeList(object):
|
||||
def __init__(self,xmin,xmax,nsites):
|
||||
if xmin > xmax: xmin,xmax = xmax,xmin
|
||||
self.hashsize = int(2*math.sqrt(nsites+4))
|
||||
|
||||
self.xmin = xmin
|
||||
self.deltax = float(xmax - xmin)
|
||||
self.hash = [None]*self.hashsize
|
||||
|
||||
self.leftend = Halfedge()
|
||||
self.rightend = Halfedge()
|
||||
self.leftend.right = self.rightend
|
||||
self.rightend.left = self.leftend
|
||||
self.hash[0] = self.leftend
|
||||
self.hash[-1] = self.rightend
|
||||
|
||||
def insert(self,left,he):
|
||||
he.left = left
|
||||
he.right = left.right
|
||||
left.right.left = he
|
||||
left.right = he
|
||||
|
||||
def delete(self,he):
|
||||
he.left.right = he.right
|
||||
he.right.left = he.left
|
||||
he.edge = Edge.DELETED
|
||||
|
||||
# Get entry from hash table, pruning any deleted nodes
|
||||
def gethash(self,b):
|
||||
if(b < 0 or b >= self.hashsize):
|
||||
return None
|
||||
he = self.hash[b]
|
||||
if he is None or he.edge is not Edge.DELETED:
|
||||
return he
|
||||
|
||||
# Hash table points to deleted half edge. Patch as necessary.
|
||||
self.hash[b] = None
|
||||
return None
|
||||
|
||||
def leftbnd(self,pt):
|
||||
# Use hash table to get close to desired halfedge
|
||||
bucket = int(((pt.x - self.xmin)/self.deltax * self.hashsize))
|
||||
|
||||
if(bucket < 0):
|
||||
bucket =0;
|
||||
|
||||
if(bucket >=self.hashsize):
|
||||
bucket = self.hashsize-1
|
||||
|
||||
he = self.gethash(bucket)
|
||||
if(he is None):
|
||||
i = 1
|
||||
while True:
|
||||
he = self.gethash(bucket-i)
|
||||
if (he is not None): break;
|
||||
he = self.gethash(bucket+i)
|
||||
if (he is not None): break;
|
||||
i += 1
|
||||
|
||||
# Now search linear list of halfedges for the corect one
|
||||
if (he is self.leftend) or (he is not self.rightend and he.isPointRightOf(pt)):
|
||||
he = he.right
|
||||
while he is not self.rightend and he.isPointRightOf(pt):
|
||||
he = he.right
|
||||
he = he.left;
|
||||
else:
|
||||
he = he.left
|
||||
while (he is not self.leftend and not he.isPointRightOf(pt)):
|
||||
he = he.left
|
||||
|
||||
# Update hash table and reference counts
|
||||
if(bucket > 0 and bucket < self.hashsize-1):
|
||||
self.hash[bucket] = he
|
||||
return he
|
||||
|
||||
|
||||
#------------------------------------------------------------------
|
||||
class PriorityQueue(object):
|
||||
def __init__(self,ymin,ymax,nsites):
|
||||
self.ymin = ymin
|
||||
self.deltay = ymax - ymin
|
||||
self.hashsize = int(4 * math.sqrt(nsites))
|
||||
self.count = 0
|
||||
self.minidx = 0
|
||||
self.hash = []
|
||||
for i in range(self.hashsize):
|
||||
self.hash.append(Halfedge())
|
||||
|
||||
def __len__(self):
|
||||
return self.count
|
||||
|
||||
def isEmpty(self):
|
||||
return self.count == 0
|
||||
|
||||
def insert(self,he,site,offset):
|
||||
he.vertex = site
|
||||
he.ystar = site.y + offset
|
||||
last = self.hash[self.getBucket(he)]
|
||||
next = last.qnext
|
||||
while((next is not None) and cmp(he,next) > 0):
|
||||
last = next
|
||||
next = last.qnext
|
||||
he.qnext = last.qnext
|
||||
last.qnext = he
|
||||
self.count += 1
|
||||
|
||||
def delete(self,he):
|
||||
if (he.vertex is not None):
|
||||
last = self.hash[self.getBucket(he)]
|
||||
while last.qnext is not he:
|
||||
last = last.qnext
|
||||
last.qnext = he.qnext
|
||||
self.count -= 1
|
||||
he.vertex = None
|
||||
|
||||
def getBucket(self,he):
|
||||
bucket = int(((he.ystar - self.ymin) / self.deltay) * self.hashsize)
|
||||
if bucket < 0: bucket = 0
|
||||
if bucket >= self.hashsize: bucket = self.hashsize-1
|
||||
if bucket < self.minidx: self.minidx = bucket
|
||||
return bucket
|
||||
|
||||
def getMinPt(self):
|
||||
while(self.hash[self.minidx].qnext is None):
|
||||
self.minidx += 1
|
||||
he = self.hash[self.minidx].qnext
|
||||
x = he.vertex.x
|
||||
y = he.ystar
|
||||
return Site(x,y)
|
||||
|
||||
def popMinHalfedge(self):
|
||||
curr = self.hash[self.minidx].qnext
|
||||
self.hash[self.minidx].qnext = curr.qnext
|
||||
self.count -= 1
|
||||
return curr
|
||||
|
||||
|
||||
#------------------------------------------------------------------
|
||||
class SiteList(object):
|
||||
def __init__(self,pointList):
|
||||
self.__sites = []
|
||||
self.__sitenum = 0
|
||||
|
||||
self.__xmin = pointList[0].x()
|
||||
self.__ymin = pointList[0].y()
|
||||
self.__xmax = pointList[0].x()
|
||||
self.__ymax = pointList[0].y()
|
||||
for i,pt in enumerate(pointList):
|
||||
self.__sites.append(Site(pt.x(),pt.y(),i))
|
||||
if pt.x() < self.__xmin: self.__xmin = pt.x()
|
||||
if pt.y() < self.__ymin: self.__ymin = pt.y()
|
||||
if pt.x() > self.__xmax: self.__xmax = pt.x()
|
||||
if pt.y() > self.__ymax: self.__ymax = pt.y()
|
||||
self.__sites.sort()
|
||||
|
||||
def setSiteNumber(self,site):
|
||||
site.sitenum = self.__sitenum
|
||||
self.__sitenum += 1
|
||||
|
||||
class Iterator(object):
|
||||
def __init__(this,lst): this.generator = (s for s in lst)
|
||||
def __iter__(this): return this
|
||||
def next(this):
|
||||
try:
|
||||
return this.generator.next()
|
||||
except StopIteration:
|
||||
return None
|
||||
|
||||
def iterator(self):
|
||||
return SiteList.Iterator(self.__sites)
|
||||
|
||||
def __iter__(self):
|
||||
return SiteList.Iterator(self.__sites)
|
||||
|
||||
def __len__(self):
|
||||
return len(self.__sites)
|
||||
|
||||
def _getxmin(self): return self.__xmin
|
||||
def _getymin(self): return self.__ymin
|
||||
def _getxmax(self): return self.__xmax
|
||||
def _getymax(self): return self.__ymax
|
||||
xmin = property(_getxmin)
|
||||
ymin = property(_getymin)
|
||||
xmax = property(_getxmax)
|
||||
ymax = property(_getymax)
|
||||
|
||||
|
||||
#------------------------------------------------------------------
|
||||
def computeVoronoiDiagram( points ):
|
||||
""" Takes a list of point objects (which must have x and y fields).
|
||||
Returns a 3-tuple of:
|
||||
|
||||
(1) a list of 2-tuples, which are the x,y coordinates of the
|
||||
Voronoi diagram vertices
|
||||
(2) a list of 3-tuples (a,b,c) which are the equations of the
|
||||
lines in the Voronoi diagram: a*x + b*y = c
|
||||
(3) a list of 3-tuples, (l, v1, v2) representing edges of the
|
||||
Voronoi diagram. l is the index of the line, v1 and v2 are
|
||||
the indices of the vetices at the end of the edge. If
|
||||
v1 or v2 is -1, the line extends to infinity.
|
||||
"""
|
||||
siteList = SiteList( points )
|
||||
context = Context()
|
||||
context.set_bounds( siteList )
|
||||
voronoi( siteList, context )
|
||||
return ( context.vertices, context.lines, context.edges, (context.xmin,context.ymin,context.xmax,context.ymax))
|
||||
|
||||
#------------------------------------------------------------------
|
||||
def computeDelaunayTriangulation( points ):
|
||||
""" Takes a list of point objects (which must have x and y fields).
|
||||
Returns a list of 3-tuples: the indices of the points that form a
|
||||
Delaunay triangle.
|
||||
"""
|
||||
siteList = SiteList( points )
|
||||
context = Context()
|
||||
context.triangulate = True
|
||||
voronoi( siteList, context )
|
||||
return context.triangles
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
if __name__=="__main__":
|
||||
try:
|
||||
optlist,args = getopt.getopt(sys.argv[1:],"thdp")
|
||||
except getopt.GetoptError:
|
||||
usage()
|
||||
sys.exit(2)
|
||||
|
||||
doHelp = 0
|
||||
c = Context()
|
||||
c.doPrint = 1
|
||||
for opt in optlist:
|
||||
if opt[0] == "-d": c.debug = 1
|
||||
if opt[0] == "-p": c.plot = 1
|
||||
if opt[0] == "-t": c.triangulate = 1
|
||||
if opt[0] == "-h": doHelp = 1
|
||||
|
||||
if not doHelp:
|
||||
pts = []
|
||||
fp = sys.stdin
|
||||
if len(args) > 0:
|
||||
fp = open(args[0],'r')
|
||||
for line in fp:
|
||||
fld = line.split()
|
||||
x = float(fld[0])
|
||||
y = float(fld[1])
|
||||
pts.append(Site(x,y))
|
||||
if len(args) > 0: fp.close()
|
||||
|
||||
if doHelp or len(pts) == 0:
|
||||
usage()
|
||||
sys.exit(2)
|
||||
|
||||
sl = SiteList(pts)
|
||||
voronoi(sl,c)
|
||||
|
Loading…
x
Reference in New Issue
Block a user