浏览代码

Added g.gui.iimage2target first shot, GUI is mostly done, algorithm connection not working

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@70856 15284696-431f-4ddb-bdfa-cd5b030d7da7
Yann Chemin 8 年之前
父节点
当前提交
dc58af8722

+ 5 - 0
gui/wxpython/iimage2target/Makefile

@@ -0,0 +1,5 @@
+MODULE_TOPDIR = ../../..
+
+include $(MODULE_TOPDIR)/include/Make/GuiScript.make
+
+default: guiscript

+ 5 - 0
gui/wxpython/iimage2target/__init__.py

@@ -0,0 +1,5 @@
+all = [
+    'ii2t_manager',
+    'ii2t_mapdisplay',
+    'ii2t_toolbars',
+]

+ 318 - 0
gui/wxpython/iimage2target/g.gui.iimage2target.html

@@ -0,0 +1,318 @@
+<!-- meta page description: wxGUI GCP Manager -->
+<!-- meta page index: topic_gui|GUI -->
+<h2>DESCRIPTION</h2>
+
+The <b>GCP Manager</b> is a <em><a href="wxGUI.html">wxGUI</a></em>
+extension which allows the user to create, edit, and manage
+Ground Control Points. It is available from the menu
+&quot;File | Manage Ground Control Points&quot;.
+
+<p>
+The <b>GCP Manager</b> provides an interactive graphical interface to
+manage and analyze Ground Control Points. A backup copy of the initial
+POINTS file is always maintained and updated only on request (Save GCPs
+to POINTS file). This guarantees that accidental changes are not
+permanent and can be undone by reloading the Ground Control Points.
+
+<p>
+The GCP Manager must be started in the target location, not in the
+source location.
+
+<p>
+The GCP Manager is structured into three panels:
+
+<ul>
+  <li>The topmost panel shows a list of Ground Control Points. Tools to
+  manipulate and analyze GCPs are provided in the toolbar. This panel can
+  be moved out of the GCP manager window by either dragging with the
+  caption or by clicking on the pin button on the right in the caption.
+  This panel can also be placed below the map displays by dragging.
+  <li>The two panels in the lower part are used for map and GCP display,
+  the left pane showing a map from the source location and the right
+  pane showing a reference map from the target location. Numbered Ground
+  Control Points are shown on both map displays.
+</ul>
+
+
+
+<h3>Components of the GCP Manager</h3>
+
+<center>
+  <br><img src="wxGUI_gcp_frame.jpg" border="0" alt="GCP Manager"><br><br>
+</center>
+
+<p>
+<em>Toolbars</em>
+<p>
+Two toolbars are provided with the GCP Manager, one for managing the map
+displays and one for managing the GCP list.
+
+<p>
+<em>List of ground control points</em>
+<p>
+The list of Ground Control Points can be sorted by clicking on a column 
+header. Clicking on a cloumn header will sort the GCPs ascending, a
+second click on the same column will sort the GCPs descending. Overall
+RMS error and individual RMS errors of all points are often improved if
+the GCP with the highest RMS error is adjusted. Individual coordinates
+can be edited by double-clicking on a row.
+<p>
+The first column holds a checkbox and displays the point number. A GCP
+is only used for RMS error calculation and georectification if its
+checkbox on the left is checked. Uncheck to deactivate a GCP (mark as
+unused GCP).
+
+<p>
+<em>Two panels for map display</em>
+<p>
+The left panel is used to display a map from the source location, the
+right panel to display a map from the target loaction. Zooming in and
+out is always possible with the mouse wheel and done for each map canvas
+separately.
+<p>
+GCPs are displayed in different colors, depending on whether a GCP has
+a high RMS error, is currently unused or is currently selected. Optionally,
+currently unused GCPs are not shown on the map display.
+
+<p>
+<em>Statusbar</em>
+<p>
+At the bottom of the GCP Manager is a statusbar providing several
+functions. The default is set to <em>Go to GCP No.</em> (see also below).
+Typing a number or using the up/down arrows will center the maps on the
+given GCP, useful with a high zoom.
+
+<h4>GCP Map Display Toolbar</h4>
+
+<dl>
+
+<dt><img src="icons/show.png" alt="icon">&nbsp;
+  <em>Display map</em></dt>
+<dd>Displays maps for source and target canvas and re-renders any layers
+that have changed since the last time the display was updated.</dd>
+
+<dt><img src="icons/layer-redraw.png" alt="icon">&nbsp;
+  <em>Re-render map</em></dt>
+<dd>Re-renders both source and target canvas regardless of whether they
+have changed or not.</dd>
+
+<dt><img src="icons/erase.png" alt="icon">&nbsp;
+  <em>Erase display</em></dt>
+<dd>Erases both source and target canvas to a white background.</dd>
+
+<dt><img src="icons/gcp-create.png" alt="icon">&nbsp;
+  <em>Define GCP (Ground Control Points)</em></dt>
+<dd>On left mouse click, coordinates are defined for the currently
+selected GCP.</dd>
+
+<dt><img src="icons/pan.png" alt="icon">&nbsp;
+  <em>Pan</em></dt>
+<dd>Interactive selection of a new center of view in the active
+display monitor. Drag the pan cursor while pressing the left mouse
+button to pan. Alternatively left-click on the new center. Panning
+changes the location of the region displayed but not the size of the
+area displayed or the resolution.</dd>
+
+<dt><img src="icons/zoom-in.png" alt="icon">&nbsp;
+  <em>Zoom in</em></dt>
+<dd>Interactive zooming with the mouse in the active map canvas (source 
+or target). Drawing a box or just a left click with the mouse and zoom-in
+cursor causes the display to zoom in so that the area defined by the box
+fills the display. The map resolution is not changed. Clicking with the
+zoom-in cursor causes the display to zoom in by 30%, centered on the
+point where the mouse is clicked. Zooming changes the display region
+extents (both size and location of area displayed).</dd>
+
+<dt><img src="icons/zoom-out.png" alt="icon">&nbsp;
+  <em>Zoom out</em></dt>
+<dd>Interactive zooming with the mouse in the active map canvas (source 
+or target). Drawing a box or just a left click with the mouse and zoom-out
+cursor causes the display to zoom out so that the area displayed
+shrinks to fill the area defined by the box. The map resolution is not
+changed. Clicking with the zoom-out cursor causes the display to zoom
+out by 30%, centered on the point where the mouse is clicked. Zooming
+changes the display region extents (both size and location of area
+displayed).</dd>
+
+<dt><img src="icons/zoom-more.png" alt="icon">&nbsp;
+  <em>Adjust display zoom</em></dt>
+<dd>Source and target display are adjusted by using the current GCPs for
+coordinate transformation:
+<br><br>
+  <dl>
+    <dt><em>Adjust source display to target display</em>
+    <dd>The extents of the source display are adjusted to the current
+    extents of the target display.
+    <dt><em>Adjust target display to source display</em>
+    <dd>The extents of the source display are adjusted to the current
+    extents of the target display.
+  </dl>
+
+<dt><em>Set active map canvas</em></dt>
+<dd>Sets the currently active map canvas (source or target). Click 
+to set active map canvas for <em>Return to previous zoom</em> or 
+<em>Zoom to extent of currently displayed map</em>. Alternatively, move
+the mouse over the map canvas to be used as active canvas.</dd>
+
+<dt><img src="icons/zoom-last.png" alt="icon">&nbsp;
+  <em>Return to previous zoom</em></dt>
+<dd>Returns to the previous zoom extent. Up to 10 levels of zoom back are
+maintained.</dd>
+
+<dt><img src="icons/zoom-extent.png" alt="icon">&nbsp;
+<em>Zoom to extent of currently displayed map</em></dt>
+<dd>Zoom to the extent of the currently displayed map in the active map
+canvas (source or target).</dd>
+
+<dt><img src="icons/settings.png" alt="icon">&nbsp;
+<em>Settings</em></dt>
+<dd>Shows a settings dialog for GCP management and display:<br><br> 
+
+  <dl>
+    <dt><em>Symbology</em></dt>
+      <dd>Settings for map and GCP display:<br><br>
+
+      <dl>
+        <dt><em>Highlight highest RMS error only</em></dt>
+          <dd>Only the GCP with the highest RMS error will be displayed in
+          a different colour, both in the list of GCPs and the GCP Map Display.
+        <dt><em>Factor for RMS error threshold = M + SD * factor:</em></dt>
+          <dd>All GCPs with an RMS error larger than mean RMS + RMS standard
+          deviation * this factor will be displayed in a different colour,
+          both in the list of GCPs and the GCP Map Display. As a rule of
+          thumb, GCPs with an RMS error larger than <em>M + SD * 2</em> are
+          most probably wrong. GCPs with an RMS error larger than
+          <em>M + SD * 1</em> are worth closer inspection. This option is
+          only available if <em>Highlight highest RMS error only</em> is
+          unchecked.</dd>
+        <dt><em>Color</em></dt>
+          <dd>Set the color for GCPs on the GCP Map Display.</dd>
+        <dt><em>Color for high RMS error</em></dt>
+          <dd>Set the color for GCPs with a high RMS error on the GCP Map
+          Display.</dd>
+        <dt><em>Color for selected GCP</em></dt>
+          <dd>Set the color for the currently selected GCP on the GCP Map
+          Display.</dd>
+        <dt><em>Show unused GCPs</em></dt>
+          <dd>If unchecked, unused GCPs will not be shown on the GCP Map
+          Display.</dd>
+        <dt><em>Color for unused GCPs</em></dt>
+          <dd>Set the color for unused GCPs on the GCP Map Display.</dd>
+        <dt><em>Symbol size</em></dt>
+          <dd>Set the symbol size for GCPs on the GCP Map Display.</dd>
+        <dt><em>Line width</em></dt>
+          <dd>Set the line width for GCPs on the GCP Map Display.</dd>
+        <dt><em>Select source map to display</em></dt>
+          <dd>Select a source map for the left pane of the GCP Map Display.</dd>
+        <dt><em>Select target map to display</em></dt>
+          <dd>Select a target map for the right pane of the GCP Map Display.</dd>
+      </dl>
+      </dd>
+
+    <dt><br><em>Rectification</em></dt>
+      <dd>Settings for georectification:<br><br>
+      <dl>
+        <dt><em>Select rectification method</em></dt>
+          <dd>Set the polynomial order for georectification. This order will
+          also be used for RMS error calculation.</dd>
+        <dt><em>Clip to computational region in target location</em></dt>
+          <dd>Clip raster maps to the current computational region in the
+          target location when georectifying.</dd>
+        <dt><em>Extension for output maps</em></dt>
+          <dd>Change the extension for output map names when doing the actual
+          georectification.</dd>
+      </dl>
+      </dd>
+  </dl><br>
+</dd>
+
+<dt><img src="icons/help.png" alt="icon">&nbsp;
+<em>Show Help</em></dt>
+<dd>Show help page for the GCP Manager.
+
+<dt><img src="icons/quit.png" alt="icon">&nbsp;
+<em>Quit</em></dt>
+<dd>Quit the GCP Manager.
+
+</dl>
+
+<h4>Toolbar for the GCP list</h4>
+
+<dl>
+
+<dt><img src="icons/gcp-save.png" alt="icon">&nbsp;
+<em>Save GCPs to POINTS file</em></dt>
+<dd>The current list of GCPs is saved to the imagery group's POINTS file
+and to a backup copy.</dd>
+
+<dt><img src="icons/gcp-add.png" alt="icon">&nbsp;
+<em>Add new GCP</em></dt>
+<dd>Adds a new Ground Control Point to the list and selects it for editing.</dd>
+
+<dt><img src="icons/gcp-delete.png" alt="icon">&nbsp;
+<em>Delete selected GCP</em></dt>
+<dd>Deletes the currently selected GCP from the list.</dd>
+
+<dt><img src="icons/gcp-remove.png" alt="icon">&nbsp;
+<em>Clear selected GCP</em></dt>
+<dd>Resets all coordinates of the currently selected GCP to 0 (zero).</dd>
+
+<dt><img src="icons/reload.png" alt="icon">&nbsp;
+<em>Reload GCPs from POINTS file</em></dt>
+<dd>Reloads GCPs from the imagery group's POINTS file.</dd>
+
+<dt><img src="icons/gcp-rms.png" alt="icon">&nbsp;
+<em>Recalculate RMS error</em></dt>
+<dd>Recalculates forward and backward RMS error for all GCP marked for
+use (activated checkbox in first row).
+</dd>
+
+<dt><img src="icons/georectify.png" alt="icon">&nbsp;
+<em>Georectify</em></dt>
+<dd>Uses <em><a href="i.rectify.html">i.rectify</a></em> to georectify
+all images in the source imagery group.
+</dd>
+
+</dl>
+
+<h4>GCP Map Display Statusbar</h4>
+
+The GCP map display statusbar is similar to the statusbar in the regular
+GRASS GIS map display with two differences, <em>Go to</em> has been
+replaced with <em>Go to GCP No.</em> and <em>Projection</em> has been
+replaced with <em>RMS error</em>.
+<p>
+If <em>Go to GCP No.</em> is selected, a GCP number can be given in the
+left side of the statusbar and the source and target map canvas will be
+centered on the given GCP. Clicking on the map canvas will update
+coordinates for this GCP.
+<p>
+If <em>RMS error</em> is selected, the overall forward and backward RMS
+error is displayed.
+
+<h2>SEE ALSO</h2>
+
+<em>
+  <a href="wxGUI.html">wxGUI</a><br>
+  <a href="wxGUI.components.html">wxGUI components</a>
+</em>
+
+<p>
+<em>
+<a href="i.rectify.html">i.rectify</a>,
+<a href="m.transform.html">m.transform</a>,
+<a href="v.rectify.html">v.rectify</a>
+</em>
+
+<p>
+See also <a href="http://grasswiki.osgeo.org/wiki/WxGUI/Video_tutorials#Georectifier">video
+tutorials</a> on GRASS Wiki.
+
+<h2>AUTHORS</h2>
+
+Markus Metz<br><br>
+<em>Based on the Georectifier (GRASS 6.4.0)</em> by Michael Barton<br>
+Martin Landa, Czech Technical University in Prague, Czech Republic
+
+<p>
+<i>$Date: 2016-09-19 11:37:30 +0200 (lun., 19 sept. 2016) $</i>

+ 184 - 0
gui/wxpython/iimage2target/g.gui.iimage2target.py

@@ -0,0 +1,184 @@
+#!/usr/bin/env python
+
+############################################################################
+#
+# MODULE:    Create 3-Dimensional GCPs from elevation and target image
+# AUTHOR(S): Yann modified the code (was Markus Metz for the GCP manager)
+# PURPOSE:   Georectification and Ground Control Points management for 3D correction.
+# COPYRIGHT: (C) 2012-2017 by Markus Metz, and the GRASS Development Team
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+############################################################################
+
+#%module
+#% description: Georectifies a map and allows managing Ground Control Points for 3D correction.
+#% keyword: imagery
+#% keyword: aerial
+#% keyword: photo
+#% keyword: georectification
+#% keyword: GCP
+#% keyword: GUI
+#%end
+
+##%option G_OPT_M_LOCATION
+##% key: source_location
+##% label: The name of the source location (has no projection)
+##% description: The name of the source location (has no projection)
+###% section: source
+##% required: yes
+##%end
+
+##%option G_OPT_M_MAPSET
+##% key: source_mapset
+##% label: The name of the source mapset (has no projection)
+##% description: The name of the source mapset (has no projection)
+###% section: source
+##% required: yes
+##%end
+
+##%option G_OPT_I_GROUP
+##% key: source_group
+##% required: yes
+##% section: source
+##%end
+
+##%option G_OPT_R_INPUT
+##% key: source_image
+##% required: yes
+###% section: source
+##%end
+
+##%option G_OPT_R_INPUT
+##% key: target_image
+##% label: The name of the image that is already georeferenced used to find location of GCPs
+##% description: The name of the image that is already georeferenced used to find the location of GCPs
+###% section: target
+##% required: no
+##%end
+
+##%option 
+##% key: camera
+##% type: string
+##% label: The name of the camera (generated in i.ortho.camera)
+##% description: The name of the camera (generated in i.ortho.camera)
+##% required: yes
+###% section: parameters
+##%end
+
+##%option 
+##% key: order
+##% type: string
+##% label: The rectification order 
+##% description: The rectification order 
+##% required: yes
+##% answer: 1
+###% section: parameters
+##%end
+
+##%option 
+##% key: extension
+##% type: string
+##% label: The name of the output files extension
+##% description: The name of the output files extension
+##% required: yes
+##% answer: _ii2t_out
+##% section: target
+##%end
+
+
+"""
+Module to run GCP management tool as stadalone application.
+
+@author Vaclav Petras  <wenzeslaus gmail.com> (standalone module)
+"""
+
+import os
+
+import grass.script as gscript
+
+
+def main():
+    """
+    Sets the GRASS display driver
+    """
+    options, flags = gscript.parser()
+
+    import wx
+
+    from grass.script.setup import set_gui_path
+    set_gui_path()
+
+    from core.settings import UserSettings
+    from core.globalvar import CheckWxVersion
+    from core.giface import StandaloneGrassInterface
+    from iimage2target.ii2t_manager import GCPWizard
+
+    driver = UserSettings.Get(group='display', key='driver', subkey='type')
+    if driver == 'png':
+        os.environ['GRASS_RENDER_IMMEDIATE'] = 'png'
+    else:
+        os.environ['GRASS_RENDER_IMMEDIATE'] = 'cairo'
+
+#    if options['source_location']:
+#        src_loc = options['source_location']
+#    else:
+#        gscript.fatal(_("No georeferenced source location provided"))
+
+#    if options['source_mapset']:
+#        src_mpt = options['source_mapset']
+#    else:
+#        gscript.fatal(_("No georeferenced source mapset provided"))
+
+#    if options['source_group']:
+#        src_grp = options['source_group']
+#    else:
+#        gscript.fatal(_("Please provide a source group name to process"))
+    
+#    if options['source_image']:
+#        src_ras = options['source_image']
+#    else:
+#        gscript.fatal(_("Please provide a source image map name to process"))
+
+#    if options['target_image']:
+#        tgt_ras = options['target_image']
+#    else:
+#        gscript.fatal(_("No georeferenced target map provided"))
+
+#    if options['camera']:
+#        camera = options['camera']
+#    else:
+#        gscript.fatal(_("Please provide a camera name (generated by i.ortho.camera)"))
+
+#    if options['order']:
+#        order = options['order']
+#    else:
+#        gscript.fatal(_("Please provive an order value"))
+
+#    if options['extension']:
+#        extension = options['extension']
+#    else:
+#        gscript.fatal(_("Please provide an output file extension"))
+
+
+    app = wx.App()
+    if not CheckWxVersion([2, 9]):
+        wx.InitAllImageHandlers()
+
+#    wizard = GCPWizard(parent=None, giface=StandaloneGrassInterface(), 
+#            srcloc=src_loc,srcmpt=src_mpt,srcgrp=src_grp,srcras=src_ras,
+#            tgtras=tgt_ras,camera=camera, order=order, extension=extension)
+
+    wizard = GCPWizard(parent=None, giface=StandaloneGrassInterface())
+    app.MainLoop()
+
+if __name__ == '__main__':
+    main()

文件差异内容过多而无法显示
+ 1185 - 0
gui/wxpython/iimage2target/ii2t_gis_set.py


+ 38 - 0
gui/wxpython/iimage2target/ii2t_gis_set_error.py

@@ -0,0 +1,38 @@
+"""
+@package gis_set_error
+
+GRASS start-up screen error message.
+
+(C) 2010-2011 by the GRASS Development Team
+
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
+
+@author Martin Landa <landa.martin gmail.com>
+"""
+
+import os
+import sys
+
+from core import globalvar
+import wx
+
+
+def main():
+    app = wx.App()
+
+    if len(sys.argv) == 1:
+        msg = "Unknown reason"
+    else:
+        msg = ''
+        for m in sys.argv[1:]:
+            msg += m
+
+    wx.MessageBox(caption="Error",
+                  message=msg,
+                  style=wx.OK | wx.ICON_ERROR)
+
+    app.MainLoop()
+
+if __name__ == "__main__":
+    main()

文件差异内容过多而无法显示
+ 3282 - 0
gui/wxpython/iimage2target/ii2t_manager.py


+ 533 - 0
gui/wxpython/iimage2target/ii2t_mapdisplay.py

@@ -0,0 +1,533 @@
+"""
+@package gcp.mapdisplay
+
+@brief Display to manage ground control points with two toolbars, one
+for various display management functions, one for manipulating GCPs.
+
+Classes:
+- mapdisplay::MapFrame
+
+(C) 2006-2011 by the GRASS Development Team
+
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
+
+@author Markus Metz
+"""
+
+import os
+import math
+import platform
+
+from core import globalvar
+import wx
+import wx.aui
+
+from mapdisp.toolbars import MapToolbar
+from gcp.toolbars import GCPDisplayToolbar, GCPManToolbar
+from mapdisp.gprint import PrintOptions
+from core.gcmd import GMessage
+from core.utils import _
+from gui_core.dialogs import GetImageHandlers, ImageSizeDialog
+from gui_core.mapdisp import SingleMapFrame
+from core.settings import UserSettings
+from mapwin.buffered import BufferedMapWindow
+from mapwin.base import MapWindowProperties
+
+import mapdisp.statusbar as sb
+import gcp.statusbar as sbgcp
+
+# for standalone app
+cmdfilename = None
+
+
+class MapFrame(SingleMapFrame):
+    """Main frame for map display window. Drawing takes place in
+    child double buffered drawing window.
+    """
+
+    def __init__(self, parent, giface,
+                 title=_("GRASS GIS Manage Ground Control Points"),
+                 toolbars=["gcpdisp"], Map=None, auimgr=None,
+                 name='GCPMapWindow', **kwargs):
+        """Main map display window with toolbars, statusbar and
+        DrawWindow
+
+        :param giface: GRASS interface instance
+        :param title: window title
+        :param toolbars: array of activated toolbars, e.g. ['map', 'digit']
+        :param map: instance of render.Map
+        :param auimgs: AUI manager
+        :param kwargs: wx.Frame attribures
+        """
+
+        SingleMapFrame.__init__(
+            self,
+            parent=parent,
+            giface=giface,
+            title=title,
+            Map=Map,
+            auimgr=auimgr,
+            name=name,
+            **kwargs)
+
+        self._giface = giface
+        # properties are shared in other objects, so defining here
+        self.mapWindowProperties = MapWindowProperties()
+        self.mapWindowProperties.setValuesFromUserSettings()
+        self.mapWindowProperties.alignExtent = True
+
+        #
+        # Add toolbars
+        #
+        for toolb in toolbars:
+            self.AddToolbar(toolb)
+
+        self.activemap = self.toolbars['gcpdisp'].togglemap
+        self.activemap.SetSelection(0)
+
+        self.SrcMap = self.grwiz.SrcMap       # instance of render.Map
+        self.TgtMap = self.grwiz.TgtMap       # instance of render.Map
+        self._mgr.SetDockSizeConstraint(0.5, 0.5)
+
+        #
+        # Add statusbar
+        #
+
+        # items for choice
+        self.statusbarItems = [sb.SbCoordinates,
+                               sb.SbRegionExtent,
+                               sb.SbCompRegionExtent,
+                               sb.SbShowRegion,
+                               sb.SbResolution,
+                               sb.SbDisplayGeometry,
+                               sb.SbMapScale,
+                               sb.SbProjection,
+                               sbgcp.SbGoToGCP,
+                               sbgcp.SbRMSError]
+
+        # create statusbar and its manager
+        statusbar = self.CreateStatusBar(number=4, style=0)
+        statusbar.SetStatusWidths([-5, -2, -1, -1])
+        self.statusbarManager = sb.SbManager(
+            mapframe=self, statusbar=statusbar)
+
+        # fill statusbar manager
+        self.statusbarManager.AddStatusbarItemsByClass(
+            self.statusbarItems, mapframe=self, statusbar=statusbar)
+        self.statusbarManager.AddStatusbarItem(
+            sb.SbMask(self, statusbar=statusbar, position=2))
+        self.statusbarManager.AddStatusbarItem(
+            sb.SbRender(self, statusbar=statusbar, position=3))
+
+        self.statusbarManager.SetMode(8)  # goto GCP
+
+        #
+        # Init map display (buffered DC & set default cursor)
+        #
+        self.grwiz.SwitchEnv('source')
+        self.SrcMapWindow = BufferedMapWindow(
+            parent=self, giface=self._giface, id=wx.ID_ANY,
+            properties=self.mapWindowProperties, Map=self.SrcMap)
+
+        self.grwiz.SwitchEnv('target')
+        self.TgtMapWindow = BufferedMapWindow(
+            parent=self, giface=self._giface, id=wx.ID_ANY,
+            properties=self.mapWindowProperties, Map=self.TgtMap)
+        self.MapWindow = self.SrcMapWindow
+        self.Map = self.SrcMap
+        self._setUpMapWindow(self.SrcMapWindow)
+        self._setUpMapWindow(self.TgtMapWindow)
+        self.SrcMapWindow.SetNamedCursor('cross')
+        self.TgtMapWindow.SetNamedCursor('cross')
+        # used to switch current map (combo box in toolbar)
+        self.SrcMapWindow.mouseEntered.connect(
+            lambda:
+            self._setActiveMapWindow(self.SrcMapWindow))
+        self.TgtMapWindow.mouseEntered.connect(
+            lambda:
+            self._setActiveMapWindow(self.TgtMapWindow))
+
+        #
+        # initialize region values
+        #
+        self._initMap(Map=self.SrcMap)
+        self._initMap(Map=self.TgtMap)
+
+        self.GetMapToolbar().SelectDefault()
+
+        #
+        # Bind various events
+        #
+        self.activemap.Bind(wx.EVT_CHOICE, self.OnUpdateActive)
+        self.Bind(wx.EVT_SIZE, self.OnSize)
+
+        #
+        # Update fancy gui style
+        #
+        # AuiManager wants a CentrePane, workaround to get two equally sized
+        # windows
+        self.list = self.CreateGCPList()
+
+        #self.SrcMapWindow.SetSize((300, 300))
+        #self.TgtMapWindow.SetSize((300, 300))
+        self.list.SetSize((100, 150))
+        self._mgr.AddPane(self.list, wx.aui.AuiPaneInfo().
+                          Name("gcplist").Caption(_("GCP List")).LeftDockable(False).
+                          RightDockable(False).PinButton().FloatingSize((600, 200)).
+                          CloseButton(False).DestroyOnClose(True).
+                          Top().Layer(1).MinSize((200, 100)))
+        self._mgr.AddPane(self.SrcMapWindow, wx.aui.AuiPaneInfo().
+                          Name("source").Caption(_("Source Display")).Dockable(False).
+                          CloseButton(False).DestroyOnClose(True).Floatable(False).
+                          Centre())
+        self._mgr.AddPane(self.TgtMapWindow, wx.aui.AuiPaneInfo().
+                          Name("target").Caption(_("Target Display")).Dockable(False).
+                          CloseButton(False).DestroyOnClose(True).Floatable(False).
+                          Right().Layer(0))
+
+        srcwidth, srcheight = self.SrcMapWindow.GetSize()
+        tgtwidth, tgtheight = self.TgtMapWindow.GetSize()
+        srcwidth = (srcwidth + tgtwidth) / 2
+        self._mgr.GetPane("target").Hide()
+        self._mgr.Update()
+        self._mgr.GetPane("source").BestSize((srcwidth, srcheight))
+        self._mgr.GetPane("target").BestSize((srcwidth, srcheight))
+        if self.show_target:
+            self._mgr.GetPane("target").Show()
+        else:
+            self.activemap.Enable(False)
+        # needed by Mac OS, does not harm on Linux, breaks display on Windows
+        if platform.system() != 'Windows':
+            self._mgr.Update()
+
+        #
+        # Init print module and classes
+        #
+        self.printopt = PrintOptions(self, self.MapWindow)
+
+        #
+        # Initialization of digitization tool
+        #
+        self.digit = None
+
+        # set active map
+        self.MapWindow = self.SrcMapWindow
+        self.Map = self.SrcMap
+
+        # do not init zoom history here, that happens when zooming to map(s)
+
+        #
+        # Re-use dialogs
+        #
+        self.dialogs = {}
+        self.dialogs['attributes'] = None
+        self.dialogs['category'] = None
+        self.dialogs['barscale'] = None
+        self.dialogs['legend'] = None
+
+        self.decorationDialog = None  # decoration/overlays
+
+        # doing nice things in statusbar when other things are ready
+        self.statusbarManager.Update()
+
+    def _setUpMapWindow(self, mapWindow):
+        # TODO: almost the smae implementation as for MapFrameBase (only names differ)
+        # enable or disable zoom history tool
+        mapWindow.zoomHistoryAvailable.connect(
+            lambda:
+            self.GetMapToolbar().Enable('zoomback', enable=True))
+        mapWindow.zoomHistoryUnavailable.connect(
+            lambda:
+            self.GetMapToolbar().Enable('zoomback', enable=False))
+        mapWindow.mouseMoving.connect(self.CoordinatesChanged)
+
+    def AddToolbar(self, name):
+        """Add defined toolbar to the window
+
+        Currently known toolbars are:
+         - 'map'     - basic map toolbar
+         - 'vdigit'  - vector digitizer
+         - 'gcpdisp' - GCP Manager, Display
+         - 'gcpman'  - GCP Manager, points management
+         - 'nviz'    - 3D view mode
+        """
+        # default toolbar
+        if name == "map":
+            self.toolbars['map'] = MapToolbar(self, self._toolSwitcher)
+
+            self._mgr.AddPane(self.toolbars['map'],
+                              wx.aui.AuiPaneInfo().
+                              Name("maptoolbar").Caption(_("Map Toolbar")).
+                              ToolbarPane().Top().
+                              LeftDockable(False).RightDockable(False).
+                              BottomDockable(False).TopDockable(True).
+                              CloseButton(False).Layer(2).
+                              BestSize((self.toolbars['map'].GetSize())))
+
+        # GCP display
+        elif name == "gcpdisp":
+            self.toolbars['gcpdisp'] = GCPDisplayToolbar(
+                self, self._toolSwitcher)
+
+            self._mgr.AddPane(self.toolbars['gcpdisp'],
+                              wx.aui.AuiPaneInfo().
+                              Name("gcpdisplaytoolbar").Caption(_("GCP Display toolbar")).
+                              ToolbarPane().Top().
+                              LeftDockable(False).RightDockable(False).
+                              BottomDockable(False).TopDockable(True).
+                              CloseButton(False).Layer(2))
+
+            if self.show_target == False:
+                self.toolbars['gcpdisp'].Enable('zoommenu', enable=False)
+
+            self.toolbars['gcpman'] = GCPManToolbar(self)
+
+            self._mgr.AddPane(self.toolbars['gcpman'],
+                              wx.aui.AuiPaneInfo().
+                              Name("gcpmanagertoolbar").Caption(_("GCP Manager toolbar")).
+                              ToolbarPane().Top().Row(1).
+                              LeftDockable(False).RightDockable(False).
+                              BottomDockable(False).TopDockable(True).
+                              CloseButton(False).Layer(2))
+
+        self._mgr.Update()
+
+    def OnUpdateProgress(self, event):
+        """
+        Update progress bar info
+        """
+        self.GetProgressBar().UpdateProgress(event.layer, event.map)
+
+        event.Skip()
+
+    def OnFocus(self, event):
+        """
+        Change choicebook page to match display.
+        Or set display for georectifying
+        """
+        # was in if layer manager but considering the state it was executed
+        # always, moreover, there is no layer manager dependent code
+
+        # in GCP Management, set focus to current MapWindow for mouse actions
+        self.OnPointer(event)
+        self.MapWindow.SetFocus()
+
+        event.Skip()
+
+    def OnDraw(self, event):
+        """Re-display current map composition
+        """
+        self.MapWindow.UpdateMap(render=False)
+
+    def OnRender(self, event):
+        """Re-render map composition (each map layer)
+        """
+        # FIXME: remove qlayer code or use RemoveQueryLayer() now in mapdisp.frame
+        # delete tmp map layers (queries)
+        qlayer = self.Map.GetListOfLayers(name=globalvar.QUERYLAYER)
+        for layer in qlayer:
+            self.Map.DeleteLayer(layer)
+
+        self.SrcMapWindow.UpdateMap(render=True)
+        if self.show_target:
+            self.TgtMapWindow.UpdateMap(render=True)
+
+        # update statusbar
+        self.StatusbarUpdate()
+
+    def OnPointer(self, event):
+        """Pointer button clicked
+        """
+        self.SrcMapWindow.SetModePointer()
+        self.TgtMapWindow.SetModePointer()
+        # change the default cursor
+        self.SrcMapWindow.SetNamedCursor('cross')
+        self.TgtMapWindow.SetNamedCursor('cross')
+
+    def OnZoomIn(self, event):
+        """Zoom in the map."""
+        self.SrcMapWindow.SetModeZoomIn()
+        self.TgtMapWindow.SetModeZoomIn()
+
+    def OnZoomOut(self, event):
+        """Zoom out the map."""
+        self.SrcMapWindow.SetModeZoomOut()
+        self.TgtMapWindow.SetModeZoomOut()
+
+    def OnPan(self, event):
+        """Panning, set mouse to drag"""
+        self.SrcMapWindow.SetModePan()
+        self.TgtMapWindow.SetModePan()
+
+    def OnErase(self, event):
+        """
+        Erase the canvas
+        """
+        self.MapWindow.EraseMap()
+
+        if self.MapWindow == self.SrcMapWindow:
+            win = self.TgtMapWindow
+        elif self.MapWindow == self.TgtMapWindow:
+            win = self.SrcMapWindow
+
+        win.EraseMap()
+
+    def SaveToFile(self, event):
+        """Save map to image
+        """
+        img = self.MapWindow.img
+        if not img:
+            GMessage(parent=self, message=_(
+                "Nothing to render (empty map). Operation canceled."))
+            return
+        filetype, ltype = GetImageHandlers(img)
+
+        # get size
+        dlg = ImageSizeDialog(self)
+        dlg.CentreOnParent()
+        if dlg.ShowModal() != wx.ID_OK:
+            dlg.Destroy()
+            return
+        width, height = dlg.GetValues()
+        dlg.Destroy()
+
+        # get filename
+        dlg = wx.FileDialog(parent=self,
+                            message=_("Choose a file name to save the image "
+                                      "(no need to add extension)"),
+                            wildcard=filetype,
+                            style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
+
+        if dlg.ShowModal() == wx.ID_OK:
+            path = dlg.GetPath()
+            if not path:
+                dlg.Destroy()
+                return
+
+            base, ext = os.path.splitext(path)
+            fileType = ltype[dlg.GetFilterIndex()]['type']
+            extType = ltype[dlg.GetFilterIndex()]['ext']
+            if ext != extType:
+                path = base + '.' + extType
+
+            self.MapWindow.SaveToFile(path, fileType,
+                                      width, height)
+
+        dlg.Destroy()
+
+    def PrintMenu(self, event):
+        """
+        Print options and output menu for map display
+        """
+        point = wx.GetMousePosition()
+        printmenu = wx.Menu()
+        # Add items to the menu
+        setup = wx.MenuItem(printmenu, wx.ID_ANY, _('Page setup'))
+        printmenu.AppendItem(setup)
+        self.Bind(wx.EVT_MENU, self.printopt.OnPageSetup, setup)
+
+        preview = wx.MenuItem(printmenu, wx.ID_ANY, _('Print preview'))
+        printmenu.AppendItem(preview)
+        self.Bind(wx.EVT_MENU, self.printopt.OnPrintPreview, preview)
+
+        doprint = wx.MenuItem(printmenu, wx.ID_ANY, _('Print display'))
+        printmenu.AppendItem(doprint)
+        self.Bind(wx.EVT_MENU, self.printopt.OnDoPrint, doprint)
+
+        # Popup the menu.  If an item is selected then its handler
+        # will be called before PopupMenu returns.
+        self.PopupMenu(printmenu)
+        printmenu.Destroy()
+
+    def OnZoomToRaster(self, event):
+        """
+        Set display extents to match selected raster map (ignore NULLs)
+        """
+        self.MapWindow.ZoomToMap(ignoreNulls=True)
+
+    def OnZoomToSaved(self, event):
+        """Set display geometry to match extents in
+        saved region file
+        """
+        self.MapWindow.SetRegion(zoomOnly=True)
+
+    def OnDisplayToWind(self, event):
+        """Set computational region (WIND file) to match display
+        extents
+        """
+        self.MapWindow.DisplayToWind()
+
+    def SaveDisplayRegion(self, event):
+        """Save display extents to named region file.
+        """
+        self.MapWindow.SaveDisplayRegion()
+
+    def OnZoomMenu(self, event):
+        """Popup Zoom menu
+        """
+        point = wx.GetMousePosition()
+        zoommenu = wx.Menu()
+        # Add items to the menu
+
+        zoomwind = wx.MenuItem(zoommenu, wx.ID_ANY, _(
+            'Zoom to computational region (set with g.region)'))
+        zoommenu.AppendItem(zoomwind)
+        self.Bind(wx.EVT_MENU, self.OnZoomToWind, zoomwind)
+
+        zoomdefault = wx.MenuItem(
+            zoommenu, wx.ID_ANY, _('Zoom to default region'))
+        zoommenu.AppendItem(zoomdefault)
+        self.Bind(wx.EVT_MENU, self.OnZoomToDefault, zoomdefault)
+
+        zoomsaved = wx.MenuItem(zoommenu, wx.ID_ANY, _('Zoom to saved region'))
+        zoommenu.AppendItem(zoomsaved)
+        self.Bind(wx.EVT_MENU, self.OnZoomToSaved, zoomsaved)
+
+        savewind = wx.MenuItem(zoommenu, wx.ID_ANY, _(
+            'Set computational region from display'))
+        zoommenu.AppendItem(savewind)
+        self.Bind(wx.EVT_MENU, self.OnDisplayToWind, savewind)
+
+        savezoom = wx.MenuItem(zoommenu, wx.ID_ANY, _(
+            'Save display geometry to named region'))
+        zoommenu.AppendItem(savezoom)
+        self.Bind(wx.EVT_MENU, self.SaveDisplayRegion, savezoom)
+
+        # Popup the menu. If an item is selected then its handler
+        # will be called before PopupMenu returns.
+        self.PopupMenu(zoommenu)
+        zoommenu.Destroy()
+
+    def IsStandalone(self):
+        """Check if Map display is standalone"""
+        # we do not know and we do not care, so always False
+        return True
+
+    def GetLayerManager(self):
+        """Get reference to Layer Manager
+
+        :return: always None
+        """
+        return None
+
+    def GetSrcWindow(self):
+        return self.SrcMapWindow
+
+    def GetTgtWindow(self):
+        return self.TgtMapWindow
+
+    def GetShowTarget(self):
+        return self.show_target
+
+    def GetMapToolbar(self):
+        """Returns toolbar with zooming tools"""
+        return self.toolbars['gcpdisp']
+
+    def _setActiveMapWindow(self, mapWindow):
+        if not self.MapWindow == mapWindow:
+            self.MapWindow = mapWindow
+            self.Map = mapWindow.Map
+            self.UpdateActive(mapWindow)
+            # needed for wingrass
+            self.SetFocus()

文件差异内容过多而无法显示
+ 2063 - 0
gui/wxpython/iimage2target/ii2t_menustrings.py


+ 128 - 0
gui/wxpython/iimage2target/ii2t_statusbar.py

@@ -0,0 +1,128 @@
+"""
+@package gcp.statusbar
+
+@brief Classes for statusbar management in GCP Manager
+
+Classes:
+ - statusbar::SbRMSError
+ - statusbar::SbGoToGCP
+
+(C) 2012-2013 by the GRASS Development Team
+
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
+
+@author Vaclav Petras <wenzeslaus gmail.com> (statusbar refactoring)
+@author Anna Kratochvilova <kratochanna gmail.com> (statusbar refactoring)
+"""
+
+
+import wx
+
+from core.gcmd import GMessage
+from core.utils import _
+from mapdisp.statusbar import SbItem, SbTextItem
+from gui_core.wrap import SpinCtrl
+
+
+class SbGoToGCP(SbItem):
+    """SpinCtrl to select GCP to focus on
+
+    Requires MapFrame.GetSrcWindow, MapFrame.GetTgtWindow,
+    MapFrame.GetListCtrl, MapFrame.GetMapCoordList.
+    """
+
+    def __init__(self, mapframe, statusbar, position=0):
+        SbItem.__init__(self, mapframe, statusbar, position)
+        self.name = 'gotoGCP'
+        self.label = _("Go to GCP No.")
+
+        self.widget = SpinCtrl(parent=self.statusbar, id=wx.ID_ANY,
+                               value="", min=0)
+        self.widget.Hide()
+
+        self.widget.Bind(wx.EVT_TEXT_ENTER, self.OnGoToGCP)
+        self.widget.Bind(wx.EVT_SPINCTRL, self.OnGoToGCP)
+
+    def OnGoToGCP(self, event):
+        """Zooms to given GCP."""
+        gcpNumber = self.GetValue()
+        mapCoords = self.mapFrame.GetMapCoordList()
+
+        # always false, spin checks it
+        if gcpNumber < 0 or gcpNumber > len(mapCoords):
+            GMessage(parent=self,
+                     message="%s 1 - %s." % (_("Valid Range:"),
+                                             len(mapCoords)))
+            return
+
+        if gcpNumber == 0:
+            return
+
+        listCtrl = self.mapFrame.GetListCtrl()
+
+        listCtrl.selectedkey = gcpNumber
+        listCtrl.selected = listCtrl.FindItemData(-1, gcpNumber)
+        listCtrl.render = False
+        listCtrl.SetItemState(listCtrl.selected,
+                              wx.LIST_STATE_SELECTED,
+                              wx.LIST_STATE_SELECTED)
+        listCtrl.render = True
+
+        listCtrl.EnsureVisible(listCtrl.selected)
+
+        srcWin = self.mapFrame.GetSrcWindow()
+        tgtWin = self.mapFrame.GetTgtWindow()
+
+        # Source MapWindow:
+        begin = (mapCoords[gcpNumber][1], mapCoords[gcpNumber][2])
+        begin = srcWin.Cell2Pixel(begin)
+        end = begin
+        srcWin.Zoom(begin, end, 0)
+
+        # redraw map
+        srcWin.UpdateMap()
+
+        if self.mapFrame.GetShowTarget():
+            # Target MapWindow:
+            begin = (mapCoords[gcpNumber][3], mapCoords[gcpNumber][4])
+            begin = tgtWin.Cell2Pixel(begin)
+            end = begin
+            tgtWin.Zoom(begin, end, 0)
+
+            # redraw map
+            tgtWin.UpdateMap()
+
+        self.GetWidget().SetFocus()
+
+    def Update(self):
+        """Checks the number of items in the gcp list
+        and sets the spin limits accordingly."""
+        self.statusbar.SetStatusText("")
+        maximum = self.mapFrame.GetListCtrl().GetItemCount()
+        if maximum < 1:
+            maximum = 1
+        self.widget.SetRange(0, maximum)
+        self.Show()
+
+        # disable long help
+        self.mapFrame.StatusbarEnableLongHelp(False)
+
+
+class SbRMSError(SbTextItem):
+    """Shows RMS error.
+
+    Requires MapFrame.GetFwdError, MapFrame.GetBkwError.
+    """
+
+    def __init__(self, mapframe, statusbar, position=0):
+        SbTextItem.__init__(self, mapframe, statusbar, position)
+        self.name = 'RMSError'
+        self.label = _("RMS error")
+
+    def Show(self):
+        """Shows the RMS errors."""
+        self.SetValue(_("Forward: %(forw)s, Backward: %(back)s") %
+                      {'forw': self.mapFrame.GetFwdError(),
+                       'back': self.mapFrame.GetBkwError()})
+        SbTextItem.Show(self)

+ 163 - 0
gui/wxpython/iimage2target/ii2t_toolbars.py

@@ -0,0 +1,163 @@
+"""
+@package gcp.toolbars
+
+@brief Georectification module - toolbars
+
+Classes:
+ - toolbars::GCPMapToolbar
+ - toolbars::GCPDisplayToolbar
+
+(C) 2007-2011 by the GRASS Development Team
+
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
+
+@author Markus Metz
+"""
+
+import os
+import sys
+
+import wx
+
+from core import globalvar
+from core.utils import _
+from gui_core.toolbars import BaseToolbar, BaseIcons
+from icons.icon import MetaIcon
+
+
+class GCPManToolbar(BaseToolbar):
+    """Toolbar for managing ground control points
+
+    :param parent: reference to GCP widget
+    """
+
+    def __init__(self, parent):
+        BaseToolbar.__init__(self, parent)
+
+        self.InitToolbar(self._toolbarData())
+
+        # realize the toolbar
+        self.Realize()
+
+    def _toolbarData(self):
+        icons = {
+            'gcpAdd': MetaIcon(img='gcp-add',
+                               label=_('Add new GCP to the list')),
+            'gcpDelete': MetaIcon(img='gcp-delete',
+                                  label=_('Delete selected GCP')),
+            'gcpClear': MetaIcon(img='gcp-remove',
+                                 label=_('Clear selected GCP')),
+            'gcpRms': MetaIcon(img='gcp-rms',
+                               label=_('Recalculate RMS error')),
+            'georectify': MetaIcon(img='georectify',
+                                   label=_('Georectify')),
+            'gcpSave': MetaIcon(img='gcp-save',
+                                label=_('Save GCPs to POINTS file')),
+            'gcpReload': MetaIcon(img='reload',
+                                  label=_('Reload GCPs from POINTS file')),
+        }
+
+        return self._getToolbarData((('gcpAdd', icons["gcpAdd"],
+                                      self.parent.AddGCP),
+                                     ('gcpDelete', icons["gcpDelete"],
+                                      self.parent.DeleteGCP),
+                                     ('gcpClear', icons["gcpClear"],
+                                      self.parent.ClearGCP),
+                                     (None, ),
+                                     ('rms', icons["gcpRms"],
+                                      self.parent.OnRMS),
+                                     ('georect', icons["georectify"],
+                                      self.parent.OnGeorect),
+                                     (None, ),
+                                     ('gcpSave', icons["gcpSave"],
+                                      self.parent.SaveGCPs),
+                                     ('gcpReload', icons["gcpReload"],
+                                      self.parent.ReloadGCPs))
+                                    )
+
+
+class GCPDisplayToolbar(BaseToolbar):
+    """GCP Display toolbar
+    """
+
+    def __init__(self, parent, toolSwitcher):
+        """GCP Display toolbar constructor
+        """
+        BaseToolbar.__init__(self, parent, toolSwitcher)
+
+        self.InitToolbar(self._toolbarData())
+        self._default = self.gcpset
+
+        # add tool to toggle active map window
+        self.togglemapid = wx.NewId()
+        self.togglemap = wx.Choice(parent=self, id=self.togglemapid,
+                                   choices=[_('source'), _('target')])
+
+        self.InsertControl(10, self.togglemap)
+
+        self.SetToolShortHelp(
+            self.togglemapid, '%s %s %s' %
+            (_('Set map canvas for '),
+             BaseIcons["zoomBack"].GetLabel(),
+             _(' / Zoom to map')))
+
+        for tool in (self.gcpset, self.pan, self.zoomin, self.zoomout):
+            self.toolSwitcher.AddToolToGroup(
+                group='mouseUse', toolbar=self, tool=tool)
+
+        # realize the toolbar
+        self.Realize()
+
+        self.EnableTool(self.zoomback, False)
+
+    def _toolbarData(self):
+        """Toolbar data"""
+        icons = {
+            'gcpSet': MetaIcon(
+                img='gcp-create',
+                label=_('Update GCP coordinates'),
+                desc=_('Update GCP coordinates)')),
+            'quit': BaseIcons['quit'].SetLabel(
+                _('Quit georectification tool')),
+            'settings': BaseIcons['settings'].SetLabel(
+                _('Georectifier settings')),
+            'help': BaseIcons['help'].SetLabel(
+                _('Georectifier manual')),
+        }
+
+        return self._getToolbarData((("displaymap", BaseIcons["display"],
+                                      self.parent.OnDraw),
+                                     ("rendermap", BaseIcons["render"],
+                                      self.parent.OnRender),
+                                     ("erase", BaseIcons["erase"],
+                                      self.parent.OnErase),
+                                     (None, ),
+                                     ("gcpset", icons["gcpSet"],
+                                      self.parent.OnPointer,
+                                      wx.ITEM_CHECK),
+                                     ("pan", BaseIcons["pan"],
+                                      self.parent.OnPan,
+                                      wx.ITEM_CHECK),
+                                     ("zoomin", BaseIcons["zoomIn"],
+                                      self.parent.OnZoomIn,
+                                      wx.ITEM_CHECK),
+                                     ("zoomout", BaseIcons["zoomOut"],
+                                      self.parent.OnZoomOut,
+                                      wx.ITEM_CHECK),
+                                     ("zoommenu", BaseIcons["zoomMenu"],
+                                      self.parent.OnZoomMenuGCP),
+                                     (None, ),
+                                     ("zoomback", BaseIcons["zoomBack"],
+                                      self.parent.OnZoomBack),
+                                     ("zoomtomap", BaseIcons["zoomExtent"],
+                                      self.parent.OnZoomToMap),
+                                     (None, ),
+                                     ('settings', icons["settings"],
+                                      self.parent.OnSettings),
+                                     ('help', icons["help"],
+                                      self.parent.OnHelp),
+                                     (None, ),
+                                     ('quit', icons["quit"],
+                                      self.parent.OnQuit))
+                                    )

二进制
gui/wxpython/iimage2target/wxGUI_iimage2target_frame.jpg