| 1 | """
|
|---|
| 2 | @package gcp.manager
|
|---|
| 3 |
|
|---|
| 4 | @brief Georectification module for GRASS GIS. Includes ground control
|
|---|
| 5 | point management and interactive point and click GCP creation
|
|---|
| 6 |
|
|---|
| 7 | Classes:
|
|---|
| 8 | - manager::GCPWizard
|
|---|
| 9 | - manager::LocationPage
|
|---|
| 10 | - manager::GroupPage
|
|---|
| 11 | - manager::DispMapPage
|
|---|
| 12 | - manager::GCP
|
|---|
| 13 | - manager::GCPList
|
|---|
| 14 | - manager::VectGroup
|
|---|
| 15 | - manager::EditGCP
|
|---|
| 16 | - manager::GrSettingsDialog
|
|---|
| 17 |
|
|---|
| 18 | (C) 2006-2014 by the GRASS Development Team
|
|---|
| 19 |
|
|---|
| 20 | This program is free software under the GNU General Public License
|
|---|
| 21 | (>=v2). Read the file COPYING that comes with GRASS for details.
|
|---|
| 22 |
|
|---|
| 23 | @author Original author Michael Barton
|
|---|
| 24 | @author Original version improved by Martin Landa <landa.martin gmail.com>
|
|---|
| 25 | @author Rewritten by Markus Metz redesign georectfier -> GCP Manage
|
|---|
| 26 | @author Support for GraphicsSet added by Stepan Turek <stepan.turek seznam.cz> (2012)
|
|---|
| 27 | """
|
|---|
| 28 |
|
|---|
| 29 | from __future__ import print_function
|
|---|
| 30 |
|
|---|
| 31 | import os
|
|---|
| 32 | import sys
|
|---|
| 33 | import shutil
|
|---|
| 34 | import time
|
|---|
| 35 | import six
|
|---|
| 36 | from copy import copy
|
|---|
| 37 |
|
|---|
| 38 | import wx
|
|---|
| 39 | from wx.lib.mixins.listctrl import CheckListCtrlMixin, ColumnSorterMixin, ListCtrlAutoWidthMixin
|
|---|
| 40 | import wx.lib.colourselect as csel
|
|---|
| 41 |
|
|---|
| 42 | from core import globalvar
|
|---|
| 43 | if globalvar.wxPythonPhoenix:
|
|---|
| 44 | from wx import adv as wiz
|
|---|
| 45 | from wx.adv import Wizard
|
|---|
| 46 | else:
|
|---|
| 47 | from wx import wizard as wiz
|
|---|
| 48 | from wx.wizard import Wizard
|
|---|
| 49 |
|
|---|
| 50 | import grass.script as grass
|
|---|
| 51 |
|
|---|
| 52 |
|
|---|
| 53 | from core import utils
|
|---|
| 54 | from core.render import Map
|
|---|
| 55 | from core.utils import _
|
|---|
| 56 | from gui_core.gselect import Select, LocationSelect, MapsetSelect
|
|---|
| 57 | from gui_core.dialogs import GroupDialog
|
|---|
| 58 | from core.gcmd import RunCommand, GMessage, GError, GWarning, EncodeString
|
|---|
| 59 | from core.settings import UserSettings
|
|---|
| 60 | from gcp.mapdisplay import MapFrame
|
|---|
| 61 | from core.giface import Notification
|
|---|
| 62 | from gui_core.wrap import SpinCtrl, Button, StaticText, StaticBox, \
|
|---|
| 63 | CheckListBox, TextCtrl, Menu
|
|---|
| 64 |
|
|---|
| 65 | from location_wizard.wizard import TitledPage as TitledPage
|
|---|
| 66 |
|
|---|
| 67 | #
|
|---|
| 68 | # global variables
|
|---|
| 69 | #
|
|---|
| 70 | global src_map
|
|---|
| 71 | global tgt_map
|
|---|
| 72 | global maptype
|
|---|
| 73 |
|
|---|
| 74 | src_map = ''
|
|---|
| 75 | tgt_map = {'raster': '',
|
|---|
| 76 | 'vector': ''}
|
|---|
| 77 | maptype = 'raster'
|
|---|
| 78 |
|
|---|
| 79 |
|
|---|
| 80 | def getSmallUpArrowImage():
|
|---|
| 81 | stream = open(os.path.join(globalvar.IMGDIR, 'small_up_arrow.png'), 'rb')
|
|---|
| 82 | try:
|
|---|
| 83 | img = wx.ImageFromStream(stream)
|
|---|
| 84 | finally:
|
|---|
| 85 | stream.close()
|
|---|
| 86 | return img
|
|---|
| 87 |
|
|---|
| 88 |
|
|---|
| 89 | def getSmallDnArrowImage():
|
|---|
| 90 | stream = open(os.path.join(globalvar.IMGDIR, 'small_down_arrow.png'), 'rb')
|
|---|
| 91 | try:
|
|---|
| 92 | img = wx.ImageFromStream(stream)
|
|---|
| 93 | finally:
|
|---|
| 94 | stream.close()
|
|---|
| 95 | stream.close()
|
|---|
| 96 | return img
|
|---|
| 97 |
|
|---|
| 98 |
|
|---|
| 99 | class GCPWizard(object):
|
|---|
| 100 | """
|
|---|
| 101 | Start wizard here and finish wizard here
|
|---|
| 102 | """
|
|---|
| 103 |
|
|---|
| 104 | def __init__(self, parent, giface):
|
|---|
| 105 | self.parent = parent # GMFrame
|
|---|
| 106 | self._giface = giface
|
|---|
| 107 |
|
|---|
| 108 | #
|
|---|
| 109 | # get environmental variables
|
|---|
| 110 | #
|
|---|
| 111 | self.grassdatabase = grass.gisenv()['GISDBASE']
|
|---|
| 112 |
|
|---|
| 113 | #
|
|---|
| 114 | # read original environment settings
|
|---|
| 115 | #
|
|---|
| 116 | self.target_gisrc = os.environ['GISRC']
|
|---|
| 117 | self.gisrc_dict = {}
|
|---|
| 118 | try:
|
|---|
| 119 | f = open(self.target_gisrc, 'r')
|
|---|
| 120 | for line in f.readlines():
|
|---|
| 121 | line = line.replace('\n', '').strip()
|
|---|
| 122 | if len(line) < 1:
|
|---|
| 123 | continue
|
|---|
| 124 | key, value = line.split(':', 1)
|
|---|
| 125 | self.gisrc_dict[key.strip()] = value.strip()
|
|---|
| 126 | finally:
|
|---|
| 127 | f.close()
|
|---|
| 128 |
|
|---|
| 129 | self.currentlocation = self.gisrc_dict['LOCATION_NAME']
|
|---|
| 130 | self.currentmapset = self.gisrc_dict['MAPSET']
|
|---|
| 131 | # location for xy map to georectify
|
|---|
| 132 | self.newlocation = ''
|
|---|
| 133 | # mapset for xy map to georectify
|
|---|
| 134 | self.newmapset = ''
|
|---|
| 135 |
|
|---|
| 136 | global maptype
|
|---|
| 137 | global src_map
|
|---|
| 138 | global tgt_map
|
|---|
| 139 |
|
|---|
| 140 | #src_map = ''
|
|---|
| 141 | #tgt_map = ''
|
|---|
| 142 | maptype = 'raster'
|
|---|
| 143 |
|
|---|
| 144 | # GISRC file for source location/mapset of map(s) to georectify
|
|---|
| 145 | self.source_gisrc = ''
|
|---|
| 146 | self.src_maps = []
|
|---|
| 147 |
|
|---|
| 148 | #
|
|---|
| 149 | # define wizard pages
|
|---|
| 150 | #
|
|---|
| 151 | self.wizard = wiz.Wizard(
|
|---|
| 152 | parent=parent,
|
|---|
| 153 | id=wx.ID_ANY,
|
|---|
| 154 | title=_("Setup for georectification"))
|
|---|
| 155 | self.startpage = LocationPage(self.wizard, self)
|
|---|
| 156 | self.grouppage = GroupPage(self.wizard, self)
|
|---|
| 157 | self.mappage = DispMapPage(self.wizard, self)
|
|---|
| 158 |
|
|---|
| 159 | #
|
|---|
| 160 | # set the initial order of the pages
|
|---|
| 161 | #
|
|---|
| 162 | self.startpage.SetNext(self.grouppage)
|
|---|
| 163 | self.grouppage.SetPrev(self.startpage)
|
|---|
| 164 | self.grouppage.SetNext(self.mappage)
|
|---|
| 165 | self.mappage.SetPrev(self.grouppage)
|
|---|
| 166 |
|
|---|
| 167 | #
|
|---|
| 168 | # do pages layout
|
|---|
| 169 | #
|
|---|
| 170 | self.startpage.DoLayout()
|
|---|
| 171 | self.grouppage.DoLayout()
|
|---|
| 172 | self.mappage.DoLayout()
|
|---|
| 173 | self.wizard.FitToPage(self.startpage)
|
|---|
| 174 |
|
|---|
| 175 | # self.Bind(wx.EVT_CLOSE, self.Cleanup)
|
|---|
| 176 | # self.parent.Bind(wx.EVT_ACTIVATE, self.OnGLMFocus)
|
|---|
| 177 |
|
|---|
| 178 | success = False
|
|---|
| 179 |
|
|---|
| 180 | #
|
|---|
| 181 | # run wizard
|
|---|
| 182 | #
|
|---|
| 183 | if self.wizard.RunWizard(self.startpage):
|
|---|
| 184 | success = self.OnWizFinished()
|
|---|
| 185 | if success == False:
|
|---|
| 186 | GMessage(parent=self.parent,
|
|---|
| 187 | message=_("Georectifying setup canceled."))
|
|---|
| 188 | self.Cleanup()
|
|---|
| 189 | else:
|
|---|
| 190 | GMessage(parent=self.parent,
|
|---|
| 191 | message=_("Georectifying setup canceled."))
|
|---|
| 192 | self.Cleanup()
|
|---|
| 193 |
|
|---|
| 194 | #
|
|---|
| 195 | # start GCP display
|
|---|
| 196 | #
|
|---|
| 197 | if success != False:
|
|---|
| 198 | # instance of render.Map to be associated with display
|
|---|
| 199 | self.SwitchEnv('source')
|
|---|
| 200 | self.SrcMap = Map(gisrc=self.source_gisrc)
|
|---|
| 201 | self.SwitchEnv('target')
|
|---|
| 202 | self.TgtMap = Map(gisrc=self.target_gisrc)
|
|---|
| 203 | self.Map = self.SrcMap
|
|---|
| 204 |
|
|---|
| 205 | #
|
|---|
| 206 | # add layer to source map
|
|---|
| 207 | #
|
|---|
| 208 | if maptype == 'raster':
|
|---|
| 209 | rendertype = 'raster'
|
|---|
| 210 | cmdlist = ['d.rast', 'map=%s' % src_map]
|
|---|
| 211 | else: # -> vector layer
|
|---|
| 212 | rendertype = 'vector'
|
|---|
| 213 | cmdlist = ['d.vect', 'map=%s' % src_map]
|
|---|
| 214 |
|
|---|
| 215 | self.SwitchEnv('source')
|
|---|
| 216 | name, found = utils.GetLayerNameFromCmd(cmdlist)
|
|---|
| 217 | self.SrcMap.AddLayer(
|
|---|
| 218 | ltype=rendertype,
|
|---|
| 219 | command=cmdlist,
|
|---|
| 220 | active=True,
|
|---|
| 221 | name=name,
|
|---|
| 222 | hidden=False,
|
|---|
| 223 | opacity=1.0,
|
|---|
| 224 | render=False)
|
|---|
| 225 |
|
|---|
| 226 | self.SwitchEnv('target')
|
|---|
| 227 | if tgt_map['raster']:
|
|---|
| 228 | #
|
|---|
| 229 | # add raster layer to target map
|
|---|
| 230 | #
|
|---|
| 231 | rendertype = 'raster'
|
|---|
| 232 | cmdlist = ['d.rast', 'map=%s' % tgt_map['raster']]
|
|---|
| 233 |
|
|---|
| 234 | name, found = utils.GetLayerNameFromCmd(cmdlist)
|
|---|
| 235 | self.TgtMap.AddLayer(
|
|---|
| 236 | ltype=rendertype,
|
|---|
| 237 | command=cmdlist,
|
|---|
| 238 | active=True,
|
|---|
| 239 | name=name,
|
|---|
| 240 | hidden=False,
|
|---|
| 241 | opacity=1.0,
|
|---|
| 242 | render=False)
|
|---|
| 243 |
|
|---|
| 244 | if tgt_map['vector']:
|
|---|
| 245 | #
|
|---|
| 246 | # add raster layer to target map
|
|---|
| 247 | #
|
|---|
| 248 | rendertype = 'vector'
|
|---|
| 249 | cmdlist = ['d.vect', 'map=%s' % tgt_map['vector']]
|
|---|
| 250 |
|
|---|
| 251 | name, found = utils.GetLayerNameFromCmd(cmdlist)
|
|---|
| 252 | self.TgtMap.AddLayer(
|
|---|
| 253 | ltype=rendertype,
|
|---|
| 254 | command=cmdlist,
|
|---|
| 255 | active=True,
|
|---|
| 256 | name=name,
|
|---|
| 257 | hidden=False,
|
|---|
| 258 | opacity=1.0,
|
|---|
| 259 | render=False)
|
|---|
| 260 |
|
|---|
| 261 | #
|
|---|
| 262 | # start GCP Manager
|
|---|
| 263 | #
|
|---|
| 264 | self.gcpmgr = GCP(self.parent, giface=self._giface,
|
|---|
| 265 | grwiz=self, size=globalvar.MAP_WINDOW_SIZE,
|
|---|
| 266 | toolbars=["gcpdisp"],
|
|---|
| 267 | Map=self.SrcMap, lmgr=self.parent)
|
|---|
| 268 |
|
|---|
| 269 | # load GCPs
|
|---|
| 270 | self.gcpmgr.InitMapDisplay()
|
|---|
| 271 | self.gcpmgr.CenterOnScreen()
|
|---|
| 272 | self.gcpmgr.Show()
|
|---|
| 273 | # need to update AUI here for wingrass
|
|---|
| 274 | self.gcpmgr._mgr.Update()
|
|---|
| 275 | else:
|
|---|
| 276 | self.Cleanup()
|
|---|
| 277 |
|
|---|
| 278 | def SetSrcEnv(self, location, mapset):
|
|---|
| 279 | """Create environment to use for location and mapset
|
|---|
| 280 | that are the source of the file(s) to georectify
|
|---|
| 281 |
|
|---|
| 282 | :param location: source location
|
|---|
| 283 | :param mapset: source mapset
|
|---|
| 284 |
|
|---|
| 285 | :return: False on error
|
|---|
| 286 | :return: True on success
|
|---|
| 287 | """
|
|---|
| 288 |
|
|---|
| 289 | self.newlocation = location
|
|---|
| 290 | self.newmapset = mapset
|
|---|
| 291 |
|
|---|
| 292 | # check to see if we are georectifying map in current working
|
|---|
| 293 | # location/mapset
|
|---|
| 294 | if self.newlocation == self.currentlocation and self.newmapset == self.currentmapset:
|
|---|
| 295 | return False
|
|---|
| 296 |
|
|---|
| 297 | self.gisrc_dict['LOCATION_NAME'] = location
|
|---|
| 298 | self.gisrc_dict['MAPSET'] = mapset
|
|---|
| 299 |
|
|---|
| 300 | self.source_gisrc = EncodeString(utils.GetTempfile())
|
|---|
| 301 |
|
|---|
| 302 | try:
|
|---|
| 303 | f = open(self.source_gisrc, mode='w')
|
|---|
| 304 | for line in self.gisrc_dict.items():
|
|---|
| 305 | f.write(line[0] + ": " + line[1] + "\n")
|
|---|
| 306 | finally:
|
|---|
| 307 | f.close()
|
|---|
| 308 |
|
|---|
| 309 | return True
|
|---|
| 310 |
|
|---|
| 311 | def SwitchEnv(self, grc):
|
|---|
| 312 | """
|
|---|
| 313 | Switches between original working location/mapset and
|
|---|
| 314 | location/mapset that is source of file(s) to georectify
|
|---|
| 315 | """
|
|---|
| 316 | # check to see if we are georectifying map in current working
|
|---|
| 317 | # location/mapset
|
|---|
| 318 | if self.newlocation == self.currentlocation and self.newmapset == self.currentmapset:
|
|---|
| 319 | return False
|
|---|
| 320 |
|
|---|
| 321 | if grc == 'target':
|
|---|
| 322 | os.environ['GISRC'] = str(self.target_gisrc)
|
|---|
| 323 | elif grc == 'source':
|
|---|
| 324 | os.environ['GISRC'] = str(self.source_gisrc)
|
|---|
| 325 |
|
|---|
| 326 | return True
|
|---|
| 327 |
|
|---|
| 328 | def OnWizFinished(self):
|
|---|
| 329 | # self.Cleanup()
|
|---|
| 330 |
|
|---|
| 331 | return True
|
|---|
| 332 |
|
|---|
| 333 | def OnGLMFocus(self, event):
|
|---|
| 334 | """Layer Manager focus"""
|
|---|
| 335 | # self.SwitchEnv('target')
|
|---|
| 336 |
|
|---|
| 337 | event.Skip()
|
|---|
| 338 |
|
|---|
| 339 | def Cleanup(self):
|
|---|
| 340 | """Return to current location and mapset"""
|
|---|
| 341 | # here was also the cleaning of gcpmanagement from layer manager
|
|---|
| 342 | # which is no longer needed
|
|---|
| 343 |
|
|---|
| 344 | self.SwitchEnv('target')
|
|---|
| 345 | self.wizard.Destroy()
|
|---|
| 346 |
|
|---|
| 347 |
|
|---|
| 348 | class LocationPage(TitledPage):
|
|---|
| 349 | """
|
|---|
| 350 | Set map type (raster or vector) to georectify and
|
|---|
| 351 | select location/mapset of map(s) to georectify.
|
|---|
| 352 | """
|
|---|
| 353 |
|
|---|
| 354 | def __init__(self, wizard, parent):
|
|---|
| 355 | TitledPage.__init__(self, wizard, _(
|
|---|
| 356 | "Select map type and location/mapset"))
|
|---|
| 357 |
|
|---|
| 358 | self.parent = parent
|
|---|
| 359 | self.grassdatabase = self.parent.grassdatabase
|
|---|
| 360 |
|
|---|
| 361 | self.xylocation = ''
|
|---|
| 362 | self.xymapset = ''
|
|---|
| 363 |
|
|---|
| 364 | #
|
|---|
| 365 | # layout
|
|---|
| 366 | #
|
|---|
| 367 | # map type
|
|---|
| 368 | self.rb_maptype = wx.RadioBox(
|
|---|
| 369 | parent=self, id=wx.ID_ANY, label=' %s ' %
|
|---|
| 370 | _("Map type to georectify"), choices=[
|
|---|
| 371 | _('raster'), _('vector')], majorDimension=wx.RA_SPECIFY_COLS)
|
|---|
| 372 | self.sizer.Add(self.rb_maptype,
|
|---|
| 373 | flag=wx.ALIGN_CENTER | wx.ALL | wx.EXPAND, border=5,
|
|---|
| 374 | pos=(1, 1), span=(1, 2))
|
|---|
| 375 |
|
|---|
| 376 | # location
|
|---|
| 377 | self.sizer.Add(
|
|---|
| 378 | StaticText(
|
|---|
| 379 | parent=self,
|
|---|
| 380 | id=wx.ID_ANY,
|
|---|
| 381 | label=_('Select source location:')),
|
|---|
| 382 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 383 | border=5,
|
|---|
| 384 | pos=(
|
|---|
| 385 | 2,
|
|---|
| 386 | 1))
|
|---|
| 387 | self.cb_location = LocationSelect(
|
|---|
| 388 | parent=self, gisdbase=self.grassdatabase)
|
|---|
| 389 | self.sizer.Add(
|
|---|
| 390 | self.cb_location,
|
|---|
| 391 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 392 | border=5,
|
|---|
| 393 | pos=(
|
|---|
| 394 | 2,
|
|---|
| 395 | 2))
|
|---|
| 396 |
|
|---|
| 397 | # mapset
|
|---|
| 398 | self.sizer.Add(
|
|---|
| 399 | StaticText(
|
|---|
| 400 | parent=self,
|
|---|
| 401 | id=wx.ID_ANY,
|
|---|
| 402 | label=_('Select source mapset:')),
|
|---|
| 403 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 404 | border=5,
|
|---|
| 405 | pos=(
|
|---|
| 406 | 3,
|
|---|
| 407 | 1))
|
|---|
| 408 | self.cb_mapset = MapsetSelect(parent=self, gisdbase=self.grassdatabase,
|
|---|
| 409 | setItems=False)
|
|---|
| 410 | self.sizer.Add(self.cb_mapset, flag=wx.ALIGN_LEFT |
|
|---|
| 411 | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5, pos=(3, 2))
|
|---|
| 412 | self.sizer.AddGrowableCol(2)
|
|---|
| 413 |
|
|---|
| 414 | #
|
|---|
| 415 | # bindings
|
|---|
| 416 | #
|
|---|
| 417 | self.Bind(wx.EVT_RADIOBOX, self.OnMaptype, self.rb_maptype)
|
|---|
| 418 | self.Bind(wx.EVT_COMBOBOX, self.OnLocation, self.cb_location)
|
|---|
| 419 | self.cb_mapset.Bind(wx.EVT_TEXT, self.OnMapset)
|
|---|
| 420 | self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
|
|---|
| 421 | self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnEnterPage)
|
|---|
| 422 | # self.Bind(wx.EVT_CLOSE, self.parent.Cleanup)
|
|---|
| 423 |
|
|---|
| 424 | def OnMaptype(self, event):
|
|---|
| 425 | """Change map type"""
|
|---|
| 426 | global maptype
|
|---|
| 427 |
|
|---|
| 428 | if event.GetInt() == 0:
|
|---|
| 429 | maptype = 'raster'
|
|---|
| 430 | else:
|
|---|
| 431 | maptype = 'vector'
|
|---|
| 432 |
|
|---|
| 433 | def OnLocation(self, event):
|
|---|
| 434 | """Sets source location for map(s) to georectify"""
|
|---|
| 435 | self.xylocation = event.GetString()
|
|---|
| 436 |
|
|---|
| 437 | # create a list of valid mapsets
|
|---|
| 438 | tmplist = os.listdir(os.path.join(self.grassdatabase, self.xylocation))
|
|---|
| 439 | self.mapsetList = []
|
|---|
| 440 | for item in tmplist:
|
|---|
| 441 | if os.path.isdir(os.path.join(self.grassdatabase, self.xylocation, item)) and \
|
|---|
| 442 | os.path.exists(os.path.join(self.grassdatabase, self.xylocation, item, 'WIND')):
|
|---|
| 443 | if item != 'PERMANENT':
|
|---|
| 444 | self.mapsetList.append(item)
|
|---|
| 445 |
|
|---|
| 446 | self.xymapset = 'PERMANENT'
|
|---|
| 447 | utils.ListSortLower(self.mapsetList)
|
|---|
| 448 | self.mapsetList.insert(0, 'PERMANENT')
|
|---|
| 449 | self.cb_mapset.SetItems(self.mapsetList)
|
|---|
| 450 | self.cb_mapset.SetStringSelection(self.xymapset)
|
|---|
| 451 |
|
|---|
| 452 | if not wx.FindWindowById(wx.ID_FORWARD).IsEnabled():
|
|---|
| 453 | wx.FindWindowById(wx.ID_FORWARD).Enable(True)
|
|---|
| 454 |
|
|---|
| 455 | def OnMapset(self, event):
|
|---|
| 456 | """Sets source mapset for map(s) to georectify"""
|
|---|
| 457 | if self.xylocation == '':
|
|---|
| 458 | GMessage(_('You must select a valid location '
|
|---|
| 459 | 'before selecting a mapset'),
|
|---|
| 460 | parent=self)
|
|---|
| 461 | return
|
|---|
| 462 |
|
|---|
| 463 | self.xymapset = event.GetString()
|
|---|
| 464 |
|
|---|
| 465 | if not wx.FindWindowById(wx.ID_FORWARD).IsEnabled():
|
|---|
| 466 | wx.FindWindowById(wx.ID_FORWARD).Enable(True)
|
|---|
| 467 |
|
|---|
| 468 | def OnPageChanging(self, event=None):
|
|---|
| 469 | if event.GetDirection() and \
|
|---|
| 470 | (self.xylocation == '' or self.xymapset == ''):
|
|---|
| 471 | GMessage(_('You must select a valid location '
|
|---|
| 472 | 'and mapset in order to continue'),
|
|---|
| 473 | parent=self)
|
|---|
| 474 | event.Veto()
|
|---|
| 475 | return
|
|---|
| 476 |
|
|---|
| 477 | self.parent.SetSrcEnv(self.xylocation, self.xymapset)
|
|---|
| 478 |
|
|---|
| 479 | def OnEnterPage(self, event=None):
|
|---|
| 480 | if self.xylocation == '' or self.xymapset == '':
|
|---|
| 481 | wx.FindWindowById(wx.ID_FORWARD).Enable(False)
|
|---|
| 482 | else:
|
|---|
| 483 | wx.FindWindowById(wx.ID_FORWARD).Enable(True)
|
|---|
| 484 |
|
|---|
| 485 |
|
|---|
| 486 | class GroupPage(TitledPage):
|
|---|
| 487 | """
|
|---|
| 488 | Set group to georectify. Create group if desired.
|
|---|
| 489 | """
|
|---|
| 490 |
|
|---|
| 491 | def __init__(self, wizard, parent):
|
|---|
| 492 | TitledPage.__init__(self, wizard, _(
|
|---|
| 493 | "Select image/map group to georectify"))
|
|---|
| 494 |
|
|---|
| 495 | self.parent = parent
|
|---|
| 496 |
|
|---|
| 497 | self.grassdatabase = self.parent.grassdatabase
|
|---|
| 498 | self.groupList = []
|
|---|
| 499 |
|
|---|
| 500 | self.xylocation = ''
|
|---|
| 501 | self.xymapset = ''
|
|---|
| 502 | self.xygroup = ''
|
|---|
| 503 |
|
|---|
| 504 | # default extension
|
|---|
| 505 | self.extension = '_georect' + str(os.getpid())
|
|---|
| 506 |
|
|---|
| 507 | #
|
|---|
| 508 | # layout
|
|---|
| 509 | #
|
|---|
| 510 | # group
|
|---|
| 511 | self.sizer.Add(
|
|---|
| 512 | StaticText(
|
|---|
| 513 | parent=self,
|
|---|
| 514 | id=wx.ID_ANY,
|
|---|
| 515 | label=_('Select/create group:')),
|
|---|
| 516 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 517 | border=5,
|
|---|
| 518 | pos=(
|
|---|
| 519 | 1,
|
|---|
| 520 | 1))
|
|---|
| 521 | self.cb_group = wx.ComboBox(parent=self, id=wx.ID_ANY,
|
|---|
| 522 | choices=self.groupList, size=(350, -1),
|
|---|
| 523 | style=wx.CB_DROPDOWN)
|
|---|
| 524 | self.sizer.Add(self.cb_group, flag=wx.ALIGN_LEFT |
|
|---|
| 525 | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5, pos=(1, 2))
|
|---|
| 526 |
|
|---|
| 527 | # create group
|
|---|
| 528 | self.sizer.Add(
|
|---|
| 529 | StaticText(
|
|---|
| 530 | parent=self,
|
|---|
| 531 | id=wx.ID_ANY,
|
|---|
| 532 | label=_('Create group if none exists')),
|
|---|
| 533 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 534 | border=5,
|
|---|
| 535 | pos=(
|
|---|
| 536 | 2,
|
|---|
| 537 | 1))
|
|---|
| 538 | btnSizer = wx.BoxSizer(wx.HORIZONTAL)
|
|---|
| 539 | self.btn_mkgroup = Button(
|
|---|
| 540 | parent=self,
|
|---|
| 541 | id=wx.ID_ANY,
|
|---|
| 542 | label=_("Create/edit group..."))
|
|---|
| 543 | self.btn_vgroup = Button(
|
|---|
| 544 | parent=self,
|
|---|
| 545 | id=wx.ID_ANY,
|
|---|
| 546 | label=_("Add vector map to group..."))
|
|---|
| 547 | btnSizer.Add(self.btn_mkgroup,
|
|---|
| 548 | flag=wx.RIGHT, border=5)
|
|---|
| 549 |
|
|---|
| 550 | btnSizer.Add(self.btn_vgroup,
|
|---|
| 551 | flag=wx.LEFT, border=5)
|
|---|
| 552 |
|
|---|
| 553 | self.sizer.Add(
|
|---|
| 554 | btnSizer,
|
|---|
| 555 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 556 | border=5,
|
|---|
| 557 | pos=(
|
|---|
| 558 | 2,
|
|---|
| 559 | 2))
|
|---|
| 560 |
|
|---|
| 561 | # extension
|
|---|
| 562 | self.sizer.Add(
|
|---|
| 563 | StaticText(
|
|---|
| 564 | parent=self,
|
|---|
| 565 | id=wx.ID_ANY,
|
|---|
| 566 | label=_('Extension for output maps:')),
|
|---|
| 567 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 568 | border=5,
|
|---|
| 569 | pos=(
|
|---|
| 570 | 3,
|
|---|
| 571 | 1))
|
|---|
| 572 | self.ext_txt = TextCtrl(
|
|---|
| 573 | parent=self, id=wx.ID_ANY, value="", size=(
|
|---|
| 574 | 350, -1))
|
|---|
| 575 | self.ext_txt.SetValue(self.extension)
|
|---|
| 576 | self.sizer.Add(self.ext_txt, flag=wx.ALIGN_LEFT |
|
|---|
| 577 | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5, pos=(3, 2))
|
|---|
| 578 |
|
|---|
| 579 | self.sizer.AddGrowableCol(2)
|
|---|
| 580 | #
|
|---|
| 581 | # bindings
|
|---|
| 582 | #
|
|---|
| 583 | self.Bind(wx.EVT_COMBOBOX, self.OnGroup, self.cb_group)
|
|---|
| 584 | self.Bind(wx.EVT_TEXT, self.OnExtension, self.ext_txt)
|
|---|
| 585 | self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
|
|---|
| 586 | self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnEnterPage)
|
|---|
| 587 | self.Bind(wx.EVT_CLOSE, self.parent.Cleanup)
|
|---|
| 588 |
|
|---|
| 589 | # hide vector group button by default
|
|---|
| 590 | self.btn_vgroup.Hide()
|
|---|
| 591 |
|
|---|
| 592 | def OnGroup(self, event):
|
|---|
| 593 | self.xygroup = event.GetString()
|
|---|
| 594 |
|
|---|
| 595 | def OnMkGroup(self, event):
|
|---|
| 596 | """Create new group in source location/mapset"""
|
|---|
| 597 | if self.xygroup == '':
|
|---|
| 598 | self.xygroup = self.cb_group.GetValue()
|
|---|
| 599 | dlg = GroupDialog(parent=self, defaultGroup=self.xygroup)
|
|---|
| 600 | dlg.DisableSubgroupEdit()
|
|---|
| 601 | dlg.ShowModal()
|
|---|
| 602 | gr, s = dlg.GetSelectedGroup()
|
|---|
| 603 | if gr in dlg.GetExistGroups():
|
|---|
| 604 | self.xygroup = gr
|
|---|
| 605 | else:
|
|---|
| 606 | gr = ''
|
|---|
| 607 | dlg.Destroy()
|
|---|
| 608 |
|
|---|
| 609 | self.OnEnterPage()
|
|---|
| 610 | self.Update()
|
|---|
| 611 |
|
|---|
| 612 | def OnVGroup(self, event):
|
|---|
| 613 | """Add vector maps to group"""
|
|---|
| 614 |
|
|---|
| 615 | if self.xygroup == '':
|
|---|
| 616 | self.xygroup = self.cb_group.GetValue()
|
|---|
| 617 |
|
|---|
| 618 | dlg = VectGroup(parent=self,
|
|---|
| 619 | id=wx.ID_ANY,
|
|---|
| 620 | grassdb=self.grassdatabase,
|
|---|
| 621 | location=self.xylocation,
|
|---|
| 622 | mapset=self.xymapset,
|
|---|
| 623 | group=self.xygroup)
|
|---|
| 624 |
|
|---|
| 625 | if dlg.ShowModal() != wx.ID_OK:
|
|---|
| 626 | return
|
|---|
| 627 |
|
|---|
| 628 | dlg.MakeVGroup()
|
|---|
| 629 | self.OnEnterPage()
|
|---|
| 630 |
|
|---|
| 631 | def OnExtension(self, event):
|
|---|
| 632 | self.extension = self.ext_txt.GetValue()
|
|---|
| 633 |
|
|---|
| 634 | def OnPageChanging(self, event=None):
|
|---|
| 635 | if event.GetDirection() and self.xygroup == '':
|
|---|
| 636 | GMessage(_('You must select a valid image/map '
|
|---|
| 637 | 'group in order to continue'),
|
|---|
| 638 | parent=self)
|
|---|
| 639 | event.Veto()
|
|---|
| 640 | return
|
|---|
| 641 |
|
|---|
| 642 | if event.GetDirection() and self.extension == '':
|
|---|
| 643 | GMessage(_('You must enter an map name '
|
|---|
| 644 | 'extension in order to continue'),
|
|---|
| 645 | parent=self)
|
|---|
| 646 | event.Veto()
|
|---|
| 647 | return
|
|---|
| 648 |
|
|---|
| 649 | def OnEnterPage(self, event=None):
|
|---|
| 650 | global maptype
|
|---|
| 651 |
|
|---|
| 652 | self.groupList = []
|
|---|
| 653 |
|
|---|
| 654 | self.xylocation = self.parent.gisrc_dict['LOCATION_NAME']
|
|---|
| 655 | self.xymapset = self.parent.gisrc_dict['MAPSET']
|
|---|
| 656 |
|
|---|
| 657 | # create a list of groups in selected mapset
|
|---|
| 658 | if os.path.isdir(os.path.join(self.grassdatabase,
|
|---|
| 659 | self.xylocation,
|
|---|
| 660 | self.xymapset,
|
|---|
| 661 | 'group')):
|
|---|
| 662 | tmplist = os.listdir(os.path.join(self.grassdatabase,
|
|---|
| 663 | self.xylocation,
|
|---|
| 664 | self.xymapset,
|
|---|
| 665 | 'group'))
|
|---|
| 666 | for item in tmplist:
|
|---|
| 667 | if os.path.isdir(os.path.join(self.grassdatabase,
|
|---|
| 668 | self.xylocation,
|
|---|
| 669 | self.xymapset,
|
|---|
| 670 | 'group',
|
|---|
| 671 | item)):
|
|---|
| 672 | self.groupList.append(item)
|
|---|
| 673 |
|
|---|
| 674 | if maptype == 'raster':
|
|---|
| 675 | self.btn_vgroup.Hide()
|
|---|
| 676 | self.Bind(wx.EVT_BUTTON, self.OnMkGroup, self.btn_mkgroup)
|
|---|
| 677 |
|
|---|
| 678 | elif maptype == 'vector':
|
|---|
| 679 | self.btn_vgroup.Show()
|
|---|
| 680 | self.Bind(wx.EVT_BUTTON, self.OnMkGroup, self.btn_mkgroup)
|
|---|
| 681 | self.Bind(wx.EVT_BUTTON, self.OnVGroup, self.btn_vgroup)
|
|---|
| 682 |
|
|---|
| 683 | utils.ListSortLower(self.groupList)
|
|---|
| 684 | self.cb_group.SetItems(self.groupList)
|
|---|
| 685 |
|
|---|
| 686 | if len(self.groupList) > 0:
|
|---|
| 687 | if self.xygroup and self.xygroup in self.groupList:
|
|---|
| 688 | self.cb_group.SetStringSelection(self.xygroup)
|
|---|
| 689 | else:
|
|---|
| 690 | self.cb_group.SetSelection(0)
|
|---|
| 691 | self.xygroup = self.groupList[0]
|
|---|
| 692 |
|
|---|
| 693 | if self.xygroup == '' or \
|
|---|
| 694 | self.extension == '':
|
|---|
| 695 | wx.FindWindowById(wx.ID_FORWARD).Enable(False)
|
|---|
| 696 | else:
|
|---|
| 697 | wx.FindWindowById(wx.ID_FORWARD).Enable(True)
|
|---|
| 698 |
|
|---|
| 699 | # switch to source
|
|---|
| 700 | self.parent.SwitchEnv('source')
|
|---|
| 701 |
|
|---|
| 702 |
|
|---|
| 703 | class DispMapPage(TitledPage):
|
|---|
| 704 | """
|
|---|
| 705 | Select ungeoreferenced map to display for interactively
|
|---|
| 706 | setting ground control points (GCPs).
|
|---|
| 707 | """
|
|---|
| 708 |
|
|---|
| 709 | def __init__(self, wizard, parent):
|
|---|
| 710 | TitledPage.__init__(
|
|---|
| 711 | self, wizard,
|
|---|
| 712 | _("Select maps to display for ground control point (GCP) creation"))
|
|---|
| 713 |
|
|---|
| 714 | self.parent = parent
|
|---|
| 715 | global maptype
|
|---|
| 716 |
|
|---|
| 717 | #
|
|---|
| 718 | # layout
|
|---|
| 719 | #
|
|---|
| 720 | self.sizer.Add(
|
|---|
| 721 | StaticText(
|
|---|
| 722 | parent=self,
|
|---|
| 723 | id=wx.ID_ANY,
|
|---|
| 724 | label=_('Select source map to display:')),
|
|---|
| 725 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 726 | border=5,
|
|---|
| 727 | pos=(
|
|---|
| 728 | 1,
|
|---|
| 729 | 1))
|
|---|
| 730 |
|
|---|
| 731 | self.srcselection = Select(
|
|---|
| 732 | self,
|
|---|
| 733 | id=wx.ID_ANY,
|
|---|
| 734 | size=globalvar.DIALOG_GSELECT_SIZE,
|
|---|
| 735 | type=maptype,
|
|---|
| 736 | updateOnPopup=False)
|
|---|
| 737 |
|
|---|
| 738 | self.sizer.Add(
|
|---|
| 739 | self.srcselection,
|
|---|
| 740 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 741 | border=5,
|
|---|
| 742 | pos=(
|
|---|
| 743 | 1,
|
|---|
| 744 | 2))
|
|---|
| 745 |
|
|---|
| 746 | self.sizer.Add(
|
|---|
| 747 | StaticText(
|
|---|
| 748 | parent=self,
|
|---|
| 749 | id=wx.ID_ANY,
|
|---|
| 750 | label=_('Select target raster map to display:')),
|
|---|
| 751 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 752 | border=5,
|
|---|
| 753 | pos=(
|
|---|
| 754 | 2,
|
|---|
| 755 | 1))
|
|---|
| 756 |
|
|---|
| 757 | self.tgtrastselection = Select(
|
|---|
| 758 | self, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE,
|
|---|
| 759 | type='raster', updateOnPopup=False)
|
|---|
| 760 |
|
|---|
| 761 | self.sizer.Add(
|
|---|
| 762 | self.tgtrastselection,
|
|---|
| 763 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 764 | border=5,
|
|---|
| 765 | pos=(
|
|---|
| 766 | 2,
|
|---|
| 767 | 2))
|
|---|
| 768 |
|
|---|
| 769 | self.sizer.Add(
|
|---|
| 770 | StaticText(
|
|---|
| 771 | parent=self,
|
|---|
| 772 | id=wx.ID_ANY,
|
|---|
| 773 | label=_('Select target vector map to display:')),
|
|---|
| 774 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 775 | border=5,
|
|---|
| 776 | pos=(
|
|---|
| 777 | 3,
|
|---|
| 778 | 1))
|
|---|
| 779 |
|
|---|
| 780 | self.tgtvectselection = Select(
|
|---|
| 781 | self, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE,
|
|---|
| 782 | type='vector', updateOnPopup=False)
|
|---|
| 783 |
|
|---|
| 784 | self.sizer.Add(
|
|---|
| 785 | self.tgtvectselection,
|
|---|
| 786 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 787 | border=5,
|
|---|
| 788 | pos=(
|
|---|
| 789 | 3,
|
|---|
| 790 | 2))
|
|---|
| 791 |
|
|---|
| 792 | #
|
|---|
| 793 | # bindings
|
|---|
| 794 | #
|
|---|
| 795 | self.srcselection.Bind(wx.EVT_TEXT, self.OnSrcSelection)
|
|---|
| 796 | self.tgtrastselection.Bind(wx.EVT_TEXT, self.OnTgtRastSelection)
|
|---|
| 797 | self.tgtvectselection.Bind(wx.EVT_TEXT, self.OnTgtVectSelection)
|
|---|
| 798 | self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
|
|---|
| 799 | self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnEnterPage)
|
|---|
| 800 | self.Bind(wx.EVT_CLOSE, self.parent.Cleanup)
|
|---|
| 801 |
|
|---|
| 802 | def OnSrcSelection(self, event):
|
|---|
| 803 | """Source map to display selected"""
|
|---|
| 804 | global src_map
|
|---|
| 805 | global maptype
|
|---|
| 806 |
|
|---|
| 807 | src_map = self.srcselection.GetValue()
|
|---|
| 808 |
|
|---|
| 809 | if src_map == '':
|
|---|
| 810 | wx.FindWindowById(wx.ID_FORWARD).Enable(False)
|
|---|
| 811 | else:
|
|---|
| 812 | wx.FindWindowById(wx.ID_FORWARD).Enable(True)
|
|---|
| 813 |
|
|---|
| 814 | try:
|
|---|
| 815 | # set computational region to match selected map and zoom display
|
|---|
| 816 | # to region
|
|---|
| 817 | if maptype == 'raster':
|
|---|
| 818 | p = RunCommand('g.region', 'raster=src_map')
|
|---|
| 819 | elif maptype == 'vector':
|
|---|
| 820 | p = RunCommand('g.region', 'vector=src_map')
|
|---|
| 821 |
|
|---|
| 822 | if p.returncode == 0:
|
|---|
| 823 | print('returncode = ', str(p.returncode))
|
|---|
| 824 | self.parent.Map.region = self.parent.Map.GetRegion()
|
|---|
| 825 | except:
|
|---|
| 826 | pass
|
|---|
| 827 |
|
|---|
| 828 | def OnTgtRastSelection(self, event):
|
|---|
| 829 | """Source map to display selected"""
|
|---|
| 830 | global tgt_map
|
|---|
| 831 |
|
|---|
| 832 | tgt_map['raster'] = self.tgtrastselection.GetValue()
|
|---|
| 833 |
|
|---|
| 834 | def OnTgtVectSelection(self, event):
|
|---|
| 835 | """Source map to display selected"""
|
|---|
| 836 | global tgt_map
|
|---|
| 837 |
|
|---|
| 838 | tgt_map['vector'] = self.tgtvectselection.GetValue()
|
|---|
| 839 |
|
|---|
| 840 | def OnPageChanging(self, event=None):
|
|---|
| 841 | global src_map
|
|---|
| 842 | global tgt_map
|
|---|
| 843 |
|
|---|
| 844 | if event.GetDirection() and (src_map == ''):
|
|---|
| 845 | GMessage(_('You must select a source map '
|
|---|
| 846 | 'in order to continue'),
|
|---|
| 847 | parent=self)
|
|---|
| 848 | event.Veto()
|
|---|
| 849 | return
|
|---|
| 850 |
|
|---|
| 851 | self.parent.SwitchEnv('target')
|
|---|
| 852 |
|
|---|
| 853 | def OnEnterPage(self, event=None):
|
|---|
| 854 | global maptype
|
|---|
| 855 | global src_map
|
|---|
| 856 | global tgt_map
|
|---|
| 857 |
|
|---|
| 858 | self.srcselection.SetElementList(maptype)
|
|---|
| 859 |
|
|---|
| 860 | if maptype == 'raster':
|
|---|
| 861 | ret = RunCommand('i.group',
|
|---|
| 862 | parent=self,
|
|---|
| 863 | read=True,
|
|---|
| 864 | group=self.parent.grouppage.xygroup,
|
|---|
| 865 | flags='g')
|
|---|
| 866 |
|
|---|
| 867 | if ret:
|
|---|
| 868 | self.parent.src_maps = ret.splitlines()
|
|---|
| 869 | else:
|
|---|
| 870 | GError(
|
|---|
| 871 | parent=self, message=_(
|
|---|
| 872 | 'No maps in selected group <%s>.\n'
|
|---|
| 873 | 'Please edit group or select another group.') %
|
|---|
| 874 | self.parent.grouppage.xygroup)
|
|---|
| 875 | return
|
|---|
| 876 |
|
|---|
| 877 | elif maptype == 'vector':
|
|---|
| 878 | grassdatabase = self.parent.grassdatabase
|
|---|
| 879 | xylocation = self.parent.gisrc_dict['LOCATION_NAME']
|
|---|
| 880 | xymapset = self.parent.gisrc_dict['MAPSET']
|
|---|
| 881 | # make list of vectors to georectify from VREF
|
|---|
| 882 |
|
|---|
| 883 | vgrpfile = os.path.join(grassdatabase,
|
|---|
| 884 | xylocation,
|
|---|
| 885 | xymapset,
|
|---|
| 886 | 'group',
|
|---|
| 887 | self.parent.grouppage.xygroup,
|
|---|
| 888 | 'VREF')
|
|---|
| 889 |
|
|---|
| 890 | f = open(vgrpfile)
|
|---|
| 891 | try:
|
|---|
| 892 | for vect in f.readlines():
|
|---|
| 893 | vect = vect.strip('\n')
|
|---|
| 894 | if len(vect) < 1:
|
|---|
| 895 | continue
|
|---|
| 896 | self.parent.src_maps.append(vect)
|
|---|
| 897 | finally:
|
|---|
| 898 | f.close()
|
|---|
| 899 |
|
|---|
| 900 | if len(self.parent.src_maps) < 1:
|
|---|
| 901 | GError(
|
|---|
| 902 | parent=self, message=_(
|
|---|
| 903 | 'No maps in selected group <%s>.\n'
|
|---|
| 904 | 'Please edit group or select another group.') %
|
|---|
| 905 | self.parent.grouppage.xygroup)
|
|---|
| 906 | return
|
|---|
| 907 |
|
|---|
| 908 | # filter out all maps not in group
|
|---|
| 909 | self.srcselection.tcp.GetElementList(elements=self.parent.src_maps)
|
|---|
| 910 | src_map = self.parent.src_maps[0]
|
|---|
| 911 | self.srcselection.SetValue(src_map)
|
|---|
| 912 |
|
|---|
| 913 | self.parent.SwitchEnv('target')
|
|---|
| 914 | self.tgtrastselection.SetElementList('raster')
|
|---|
| 915 | self.tgtrastselection.GetElementList()
|
|---|
| 916 | self.tgtvectselection.SetElementList('vector')
|
|---|
| 917 | self.tgtvectselection.GetElementList()
|
|---|
| 918 | self.parent.SwitchEnv('source')
|
|---|
| 919 |
|
|---|
| 920 | if src_map == '':
|
|---|
| 921 | wx.FindWindowById(wx.ID_FORWARD).Enable(False)
|
|---|
| 922 | else:
|
|---|
| 923 | wx.FindWindowById(wx.ID_FORWARD).Enable(True)
|
|---|
| 924 |
|
|---|
| 925 |
|
|---|
| 926 | class GCP(MapFrame, ColumnSorterMixin):
|
|---|
| 927 | """
|
|---|
| 928 | Manages ground control points for georectifying. Calculates RMS statistics.
|
|---|
| 929 | Calls i.rectify or v.rectify to georectify map.
|
|---|
| 930 | """
|
|---|
| 931 |
|
|---|
| 932 | def __init__(self, parent, giface, grwiz=None, id=wx.ID_ANY,
|
|---|
| 933 | title=_("Manage Ground Control Points"),
|
|---|
| 934 | size=(700, 300), toolbars=["gcpdisp"], Map=None, lmgr=None):
|
|---|
| 935 |
|
|---|
| 936 | self.grwiz = grwiz # GR Wizard
|
|---|
| 937 | self._giface = giface
|
|---|
| 938 |
|
|---|
| 939 | if tgt_map['raster'] == '' and tgt_map['vector'] == '':
|
|---|
| 940 | self.show_target = False
|
|---|
| 941 | else:
|
|---|
| 942 | self.show_target = True
|
|---|
| 943 |
|
|---|
| 944 | #wx.Frame.__init__(self, parent, id, title, size = size, name = "GCPFrame")
|
|---|
| 945 | MapFrame.__init__(
|
|---|
| 946 | self,
|
|---|
| 947 | parent=parent,
|
|---|
| 948 | giface=self._giface,
|
|---|
| 949 | title=title,
|
|---|
| 950 | size=size,
|
|---|
| 951 | Map=Map,
|
|---|
| 952 | toolbars=toolbars,
|
|---|
| 953 | name='GCPMapWindow')
|
|---|
| 954 |
|
|---|
| 955 | # init variables
|
|---|
| 956 | self.parent = parent
|
|---|
| 957 |
|
|---|
| 958 | #
|
|---|
| 959 | # register data structures for drawing GCP's
|
|---|
| 960 | #
|
|---|
| 961 | self.pointsToDrawTgt = self.TgtMapWindow.RegisterGraphicsToDraw(
|
|---|
| 962 | graphicsType="point", setStatusFunc=self.SetGCPSatus)
|
|---|
| 963 | self.pointsToDrawSrc = self.SrcMapWindow.RegisterGraphicsToDraw(
|
|---|
| 964 | graphicsType="point", setStatusFunc=self.SetGCPSatus)
|
|---|
| 965 |
|
|---|
| 966 | # connect to the map windows signals
|
|---|
| 967 | # used to add or edit GCP
|
|---|
| 968 | self.SrcMapWindow.mouseLeftUpPointer.connect(
|
|---|
| 969 | lambda x, y:
|
|---|
| 970 | self._onMouseLeftUpPointer(self.SrcMapWindow, x, y))
|
|---|
| 971 | self.TgtMapWindow.mouseLeftUpPointer.connect(
|
|---|
| 972 | lambda x, y:
|
|---|
| 973 | self._onMouseLeftUpPointer(self.TgtMapWindow, x, y))
|
|---|
| 974 |
|
|---|
| 975 | # window resized
|
|---|
| 976 | self.resize = False
|
|---|
| 977 |
|
|---|
| 978 | self.grassdatabase = self.grwiz.grassdatabase
|
|---|
| 979 |
|
|---|
| 980 | self.currentlocation = self.grwiz.currentlocation
|
|---|
| 981 | self.currentmapset = self.grwiz.currentmapset
|
|---|
| 982 |
|
|---|
| 983 | self.newlocation = self.grwiz.newlocation
|
|---|
| 984 | self.newmapset = self.grwiz.newmapset
|
|---|
| 985 |
|
|---|
| 986 | self.xylocation = self.grwiz.gisrc_dict['LOCATION_NAME']
|
|---|
| 987 | self.xymapset = self.grwiz.gisrc_dict['MAPSET']
|
|---|
| 988 | self.xygroup = self.grwiz.grouppage.xygroup
|
|---|
| 989 | self.src_maps = self.grwiz.src_maps
|
|---|
| 990 | self.extension = self.grwiz.grouppage.extension
|
|---|
| 991 | self.outname = ''
|
|---|
| 992 | self.VectGRList = []
|
|---|
| 993 |
|
|---|
| 994 | self.file = {
|
|---|
| 995 | 'points': os.path.join(self.grassdatabase,
|
|---|
| 996 | self.xylocation,
|
|---|
| 997 | self.xymapset,
|
|---|
| 998 | 'group',
|
|---|
| 999 | self.xygroup,
|
|---|
| 1000 | 'POINTS'),
|
|---|
| 1001 | 'points_bak': os.path.join(self.grassdatabase,
|
|---|
| 1002 | self.xylocation,
|
|---|
| 1003 | self.xymapset,
|
|---|
| 1004 | 'group',
|
|---|
| 1005 | self.xygroup,
|
|---|
| 1006 | 'POINTS_BAK'),
|
|---|
| 1007 | 'rgrp': os.path.join(self.grassdatabase,
|
|---|
| 1008 | self.xylocation,
|
|---|
| 1009 | self.xymapset,
|
|---|
| 1010 | 'group',
|
|---|
| 1011 | self.xygroup,
|
|---|
| 1012 | 'REF'),
|
|---|
| 1013 | 'vgrp': os.path.join(self.grassdatabase,
|
|---|
| 1014 | self.xylocation,
|
|---|
| 1015 | self.xymapset,
|
|---|
| 1016 | 'group',
|
|---|
| 1017 | self.xygroup,
|
|---|
| 1018 | 'VREF'),
|
|---|
| 1019 | 'target': os.path.join(self.grassdatabase,
|
|---|
| 1020 | self.xylocation,
|
|---|
| 1021 | self.xymapset,
|
|---|
| 1022 | 'group',
|
|---|
| 1023 | self.xygroup,
|
|---|
| 1024 | 'TARGET'),
|
|---|
| 1025 | }
|
|---|
| 1026 |
|
|---|
| 1027 | # make a backup of the current points file
|
|---|
| 1028 | if os.path.exists(self.file['points']):
|
|---|
| 1029 | shutil.copy(self.file['points'], self.file['points_bak'])
|
|---|
| 1030 |
|
|---|
| 1031 | # polynomial order transformation for georectification
|
|---|
| 1032 | self.gr_order = 1
|
|---|
| 1033 | # interpolation method for georectification
|
|---|
| 1034 | self.gr_method = 'nearest'
|
|---|
| 1035 | # region clipping for georectified map
|
|---|
| 1036 | self.clip_to_region = False
|
|---|
| 1037 | # number of GCPs selected to be used for georectification (checked)
|
|---|
| 1038 | self.GCPcount = 0
|
|---|
| 1039 | # forward RMS error
|
|---|
| 1040 | self.fwd_rmserror = 0.0
|
|---|
| 1041 | # backward RMS error
|
|---|
| 1042 | self.bkw_rmserror = 0.0
|
|---|
| 1043 | # list map coords and ID of map display they came from
|
|---|
| 1044 | self.mapcoordlist = []
|
|---|
| 1045 | self.mapcoordlist.append([0, # GCP number
|
|---|
| 1046 | 0.0, # source east
|
|---|
| 1047 | 0.0, # source north
|
|---|
| 1048 | 0.0, # target east
|
|---|
| 1049 | 0.0, # target north
|
|---|
| 1050 | 0.0, # forward error
|
|---|
| 1051 | 0.0]) # backward error
|
|---|
| 1052 |
|
|---|
| 1053 | # init vars to highlight high RMS errors
|
|---|
| 1054 | self.highest_only = True
|
|---|
| 1055 | self.show_unused = True
|
|---|
| 1056 | self.highest_key = -1
|
|---|
| 1057 | self.rmsthresh = 0
|
|---|
| 1058 | self.rmsmean = 0
|
|---|
| 1059 | self.rmssd = 0
|
|---|
| 1060 |
|
|---|
| 1061 | self.SetTarget(self.xygroup, self.currentlocation, self.currentmapset)
|
|---|
| 1062 |
|
|---|
| 1063 | self.itemDataMap = None
|
|---|
| 1064 |
|
|---|
| 1065 | # images for column sorting
|
|---|
| 1066 | # CheckListCtrlMixin must set an ImageList first
|
|---|
| 1067 | self.il = self.list.GetImageList(wx.IMAGE_LIST_SMALL)
|
|---|
| 1068 |
|
|---|
| 1069 | SmallUpArrow = wx.BitmapFromImage(getSmallUpArrowImage())
|
|---|
| 1070 | SmallDnArrow = wx.BitmapFromImage(getSmallDnArrowImage())
|
|---|
| 1071 | self.sm_dn = self.il.Add(SmallDnArrow)
|
|---|
| 1072 | self.sm_up = self.il.Add(SmallUpArrow)
|
|---|
| 1073 |
|
|---|
| 1074 | # set mouse characteristics
|
|---|
| 1075 | self.mapwin = self.SrcMapWindow
|
|---|
| 1076 | self.mapwin.mouse['box'] = 'point'
|
|---|
| 1077 | self.mapwin.mouse["use"] == "pointer"
|
|---|
| 1078 | self.mapwin.zoomtype = 0
|
|---|
| 1079 | self.mapwin.pen = wx.Pen(colour='black', width=2, style=wx.SOLID)
|
|---|
| 1080 | self.mapwin.SetNamedCursor('cross')
|
|---|
| 1081 |
|
|---|
| 1082 | self.mapwin = self.TgtMapWindow
|
|---|
| 1083 |
|
|---|
| 1084 | # set mouse characteristics
|
|---|
| 1085 | self.mapwin.mouse['box'] = 'point'
|
|---|
| 1086 | self.mapwin.mouse["use"] == "pointer"
|
|---|
| 1087 | self.mapwin.zoomtype = 0
|
|---|
| 1088 | self.mapwin.pen = wx.Pen(colour='black', width=2, style=wx.SOLID)
|
|---|
| 1089 | self.mapwin.SetNamedCursor('cross')
|
|---|
| 1090 |
|
|---|
| 1091 | #
|
|---|
| 1092 | # show new display & draw map
|
|---|
| 1093 | #
|
|---|
| 1094 | if self.show_target:
|
|---|
| 1095 | self.MapWindow = self.TgtMapWindow
|
|---|
| 1096 | self.Map = self.TgtMap
|
|---|
| 1097 | self.OnZoomToMap(None)
|
|---|
| 1098 |
|
|---|
| 1099 | self.MapWindow = self.SrcMapWindow
|
|---|
| 1100 | self.Map = self.SrcMap
|
|---|
| 1101 | self.OnZoomToMap(None)
|
|---|
| 1102 |
|
|---|
| 1103 | #
|
|---|
| 1104 | # bindings
|
|---|
| 1105 | #
|
|---|
| 1106 | self.Bind(wx.EVT_ACTIVATE, self.OnFocus)
|
|---|
| 1107 | self.Bind(wx.EVT_SIZE, self.OnSize)
|
|---|
| 1108 | self.Bind(wx.EVT_IDLE, self.OnIdle)
|
|---|
| 1109 | self.Bind(wx.EVT_CLOSE, self.OnQuit)
|
|---|
| 1110 |
|
|---|
| 1111 | self.SetSettings()
|
|---|
| 1112 |
|
|---|
| 1113 | def __del__(self):
|
|---|
| 1114 | """Disable GCP manager mode"""
|
|---|
| 1115 | # leaving the method here but was used only to delete gcpmanagement
|
|---|
| 1116 | # from layer manager which is now not needed
|
|---|
| 1117 | pass
|
|---|
| 1118 |
|
|---|
| 1119 | def CreateGCPList(self):
|
|---|
| 1120 | """Create GCP List Control"""
|
|---|
| 1121 |
|
|---|
| 1122 | return GCPList(parent=self, gcp=self)
|
|---|
| 1123 |
|
|---|
| 1124 | # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
|
|---|
| 1125 | def GetListCtrl(self):
|
|---|
| 1126 | return self.list
|
|---|
| 1127 |
|
|---|
| 1128 | def GetMapCoordList(self):
|
|---|
| 1129 | return self.mapcoordlist
|
|---|
| 1130 |
|
|---|
| 1131 | # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
|
|---|
| 1132 | def GetSortImages(self):
|
|---|
| 1133 | return (self.sm_dn, self.sm_up)
|
|---|
| 1134 |
|
|---|
| 1135 | def GetFwdError(self):
|
|---|
| 1136 | return self.fwd_rmserror
|
|---|
| 1137 |
|
|---|
| 1138 | def GetBkwError(self):
|
|---|
| 1139 | return self.bkw_rmserror
|
|---|
| 1140 |
|
|---|
| 1141 | def InitMapDisplay(self):
|
|---|
| 1142 | self.list.LoadData()
|
|---|
| 1143 |
|
|---|
| 1144 | # initialize column sorter
|
|---|
| 1145 | self.itemDataMap = self.mapcoordlist
|
|---|
| 1146 | ncols = self.list.GetColumnCount()
|
|---|
| 1147 | ColumnSorterMixin.__init__(self, ncols)
|
|---|
| 1148 | # init to ascending sort on first click
|
|---|
| 1149 | self._colSortFlag = [1] * ncols
|
|---|
| 1150 |
|
|---|
| 1151 | def SetTarget(self, tgroup, tlocation, tmapset):
|
|---|
| 1152 | """
|
|---|
| 1153 | Sets rectification target to current location and mapset
|
|---|
| 1154 | """
|
|---|
| 1155 | # check to see if we are georectifying map in current working
|
|---|
| 1156 | # location/mapset
|
|---|
| 1157 | if self.newlocation == self.currentlocation and self.newmapset == self.currentmapset:
|
|---|
| 1158 | RunCommand('i.target',
|
|---|
| 1159 | parent=self,
|
|---|
| 1160 | flags='c',
|
|---|
| 1161 | group=tgroup)
|
|---|
| 1162 | else:
|
|---|
| 1163 | self.grwiz.SwitchEnv('source')
|
|---|
| 1164 | RunCommand('i.target',
|
|---|
| 1165 | parent=self,
|
|---|
| 1166 | group=tgroup,
|
|---|
| 1167 | location=tlocation,
|
|---|
| 1168 | mapset=tmapset)
|
|---|
| 1169 | self.grwiz.SwitchEnv('target')
|
|---|
| 1170 |
|
|---|
| 1171 | def AddGCP(self, event):
|
|---|
| 1172 | """
|
|---|
| 1173 | Appends an item to GCP list
|
|---|
| 1174 | """
|
|---|
| 1175 | keyval = self.list.AddGCPItem() + 1
|
|---|
| 1176 | # source east, source north, target east, target north, forward error,
|
|---|
| 1177 | # backward error
|
|---|
| 1178 | self.mapcoordlist.append([keyval, # GCP number
|
|---|
| 1179 | 0.0, # source east
|
|---|
| 1180 | 0.0, # source north
|
|---|
| 1181 | 0.0, # target east
|
|---|
| 1182 | 0.0, # target north
|
|---|
| 1183 | 0.0, # forward error
|
|---|
| 1184 | 0.0]) # backward error
|
|---|
| 1185 |
|
|---|
| 1186 | if self.statusbarManager.GetMode() == 8: # go to
|
|---|
| 1187 | self.StatusbarUpdate()
|
|---|
| 1188 |
|
|---|
| 1189 | def DeleteGCP(self, event):
|
|---|
| 1190 | """
|
|---|
| 1191 | Deletes selected item in GCP list
|
|---|
| 1192 | """
|
|---|
| 1193 | minNumOfItems = self.OnGROrder(None)
|
|---|
| 1194 |
|
|---|
| 1195 | if self.list.GetItemCount() <= minNumOfItems:
|
|---|
| 1196 | GMessage(
|
|---|
| 1197 | parent=self,
|
|---|
| 1198 | message=_("At least %d GCPs required. Operation canceled.") %
|
|---|
| 1199 | minNumOfItems)
|
|---|
| 1200 | return
|
|---|
| 1201 |
|
|---|
| 1202 | key = self.list.DeleteGCPItem()
|
|---|
| 1203 | del self.mapcoordlist[key]
|
|---|
| 1204 |
|
|---|
| 1205 | # update key and GCP number
|
|---|
| 1206 | for newkey in range(key, len(self.mapcoordlist)):
|
|---|
| 1207 | index = self.list.FindItemData(-1, newkey + 1)
|
|---|
| 1208 | self.mapcoordlist[newkey][0] = newkey
|
|---|
| 1209 | self.list.SetStringItem(index, 0, str(newkey))
|
|---|
| 1210 | self.list.SetItemData(index, newkey)
|
|---|
| 1211 |
|
|---|
| 1212 | # update selected
|
|---|
| 1213 | if self.list.GetItemCount() > 0:
|
|---|
| 1214 | if self.list.selected < self.list.GetItemCount():
|
|---|
| 1215 | self.list.selectedkey = self.list.GetItemData(
|
|---|
| 1216 | self.list.selected)
|
|---|
| 1217 | else:
|
|---|
| 1218 | self.list.selected = self.list.GetItemCount() - 1
|
|---|
| 1219 | self.list.selectedkey = self.list.GetItemData(
|
|---|
| 1220 | self.list.selected)
|
|---|
| 1221 |
|
|---|
| 1222 | self.list.SetItemState(self.list.selected,
|
|---|
| 1223 | wx.LIST_STATE_SELECTED,
|
|---|
| 1224 | wx.LIST_STATE_SELECTED)
|
|---|
| 1225 | else:
|
|---|
| 1226 | self.list.selected = wx.NOT_FOUND
|
|---|
| 1227 | self.list.selectedkey = -1
|
|---|
| 1228 |
|
|---|
| 1229 | self.UpdateColours()
|
|---|
| 1230 |
|
|---|
| 1231 | if self.statusbarManager.GetMode() == 8: # go to
|
|---|
| 1232 | self.StatusbarUpdate()
|
|---|
| 1233 | if self.list.selectedkey > 0:
|
|---|
| 1234 | self.statusbarManager.SetProperty(
|
|---|
| 1235 | 'gotoGCP', self.list.selectedkey)
|
|---|
| 1236 |
|
|---|
| 1237 | def ClearGCP(self, event):
|
|---|
| 1238 | """
|
|---|
| 1239 | Clears all values in selected item of GCP list and unchecks it
|
|---|
| 1240 | """
|
|---|
| 1241 | index = self.list.GetSelected()
|
|---|
| 1242 | key = self.list.GetItemData(index)
|
|---|
| 1243 |
|
|---|
| 1244 | for i in range(1, 5):
|
|---|
| 1245 | self.list.SetStringItem(index, i, '0.0')
|
|---|
| 1246 | self.list.SetStringItem(index, 5, '')
|
|---|
| 1247 | self.list.SetStringItem(index, 6, '')
|
|---|
| 1248 | self.list.CheckItem(index, False)
|
|---|
| 1249 |
|
|---|
| 1250 | # GCP number, source E, source N, target E, target N, fwd error, bkwd
|
|---|
| 1251 | # error
|
|---|
| 1252 | self.mapcoordlist[key] = [key, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
|---|
| 1253 |
|
|---|
| 1254 | def SetSettings(self):
|
|---|
| 1255 | """Sets settings for drawing of GCP's.
|
|---|
| 1256 | """
|
|---|
| 1257 | self.highest_only = UserSettings.Get(
|
|---|
| 1258 | group='gcpman', key='rms', subkey='highestonly')
|
|---|
| 1259 | self.show_unused = UserSettings.Get(
|
|---|
| 1260 | group='gcpman', key='symbol', subkey='unused')
|
|---|
| 1261 |
|
|---|
| 1262 | colours = {"color": "default",
|
|---|
| 1263 | "hcolor": "highest",
|
|---|
| 1264 | "scolor": "selected",
|
|---|
| 1265 | "ucolor": "unused"}
|
|---|
| 1266 | wpx = UserSettings.Get(group='gcpman', key='symbol', subkey='width')
|
|---|
| 1267 |
|
|---|
| 1268 | for k, v in six.iteritems(colours):
|
|---|
| 1269 | col = UserSettings.Get(group='gcpman', key='symbol', subkey=k)
|
|---|
| 1270 | self.pointsToDrawSrc.GetPen(v).SetColour(wx.Colour(
|
|---|
| 1271 | col[0], col[1], col[2], 255)) # TODO GetPen neni to spatne?
|
|---|
| 1272 | self.pointsToDrawTgt.GetPen(v).SetColour(
|
|---|
| 1273 | wx.Colour(col[0], col[1], col[2], 255))
|
|---|
| 1274 |
|
|---|
| 1275 | self.pointsToDrawSrc.GetPen(v).SetWidth(wpx)
|
|---|
| 1276 | self.pointsToDrawTgt.GetPen(v).SetWidth(wpx)
|
|---|
| 1277 |
|
|---|
| 1278 | spx = UserSettings.Get(group='gcpman', key='symbol', subkey='size')
|
|---|
| 1279 | self.pointsToDrawSrc.SetPropertyVal("size", int(spx))
|
|---|
| 1280 | self.pointsToDrawTgt.SetPropertyVal("size", int(spx))
|
|---|
| 1281 |
|
|---|
| 1282 | font = self.GetFont()
|
|---|
| 1283 | font.SetPointSize(int(spx) + 2)
|
|---|
| 1284 |
|
|---|
| 1285 | textProp = {}
|
|---|
| 1286 | textProp['active'] = True
|
|---|
| 1287 | textProp['font'] = font
|
|---|
| 1288 | self.pointsToDrawSrc.SetPropertyVal("text", textProp)
|
|---|
| 1289 | self.pointsToDrawTgt.SetPropertyVal("text", copy(textProp))
|
|---|
| 1290 |
|
|---|
| 1291 | def SetGCPSatus(self, item, itemIndex):
|
|---|
| 1292 | """Before GCP is drawn, decides it's colour and whether it
|
|---|
| 1293 | will be drawed.
|
|---|
| 1294 | """
|
|---|
| 1295 | key = self.list.GetItemData(itemIndex)
|
|---|
| 1296 | # incremented because of itemDataMap (has one more item) - will be
|
|---|
| 1297 | # changed
|
|---|
| 1298 | itemIndex += 1
|
|---|
| 1299 |
|
|---|
| 1300 | if not self.list.IsChecked(key - 1):
|
|---|
| 1301 | wxPen = "unused"
|
|---|
| 1302 | if not self.show_unused:
|
|---|
| 1303 | item.SetPropertyVal('hide', True)
|
|---|
| 1304 | else:
|
|---|
| 1305 | item.SetPropertyVal('hide', False)
|
|---|
| 1306 |
|
|---|
| 1307 | else:
|
|---|
| 1308 | item.SetPropertyVal('hide', False)
|
|---|
| 1309 | if self.highest_only == True:
|
|---|
| 1310 | if itemIndex == self.highest_key:
|
|---|
| 1311 | wxPen = "highest"
|
|---|
| 1312 | else:
|
|---|
| 1313 | wxPen = "default"
|
|---|
| 1314 | else:
|
|---|
| 1315 | if (self.mapcoordlist[key][5] > self.rmsthresh):
|
|---|
| 1316 | wxPen = "highest"
|
|---|
| 1317 | else:
|
|---|
| 1318 | wxPen = "default"
|
|---|
| 1319 |
|
|---|
| 1320 | if itemIndex == self.list.selectedkey:
|
|---|
| 1321 | wxPen = "selected"
|
|---|
| 1322 |
|
|---|
| 1323 | item.SetPropertyVal('label', str(itemIndex))
|
|---|
| 1324 | item.SetPropertyVal('penName', wxPen)
|
|---|
| 1325 |
|
|---|
| 1326 | def SetGCPData(self, coordtype, coord, mapdisp=None, confirm=False):
|
|---|
| 1327 | """Inserts coordinates from file, mouse click on map, or
|
|---|
| 1328 | after editing into selected item of GCP list and checks it for
|
|---|
| 1329 | use.
|
|---|
| 1330 | """
|
|---|
| 1331 | index = self.list.GetSelected()
|
|---|
| 1332 | if index == wx.NOT_FOUND:
|
|---|
| 1333 | return
|
|---|
| 1334 |
|
|---|
| 1335 | coord0 = coord[0]
|
|---|
| 1336 | coord1 = coord[1]
|
|---|
| 1337 |
|
|---|
| 1338 | key = self.list.GetItemData(index)
|
|---|
| 1339 | if confirm:
|
|---|
| 1340 | if self.MapWindow == self.SrcMapWindow:
|
|---|
| 1341 | currloc = _("source")
|
|---|
| 1342 | else:
|
|---|
| 1343 | currloc = _("target")
|
|---|
| 1344 | ret = wx.MessageBox(
|
|---|
| 1345 | parent=self, caption=_("Set GCP coordinates"),
|
|---|
| 1346 | message=_(
|
|---|
| 1347 | 'Set %(coor)s coordinates for GCP No. %(key)s? \n\n'
|
|---|
| 1348 | 'East: %(coor0)s \n'
|
|---|
| 1349 | 'North: %(coor1)s') %
|
|---|
| 1350 | {'coor': currloc, 'key': str(key),
|
|---|
| 1351 | 'coor0': str(coord0),
|
|---|
| 1352 | 'coor1': str(coord1)},
|
|---|
| 1353 | style=wx.ICON_QUESTION | wx.YES_NO | wx.CENTRE)
|
|---|
| 1354 |
|
|---|
| 1355 | # for wingrass
|
|---|
| 1356 | if os.name == 'nt':
|
|---|
| 1357 | self.MapWindow.SetFocus()
|
|---|
| 1358 | if ret == wx.NO:
|
|---|
| 1359 | return
|
|---|
| 1360 |
|
|---|
| 1361 | if coordtype == 'source':
|
|---|
| 1362 | self.list.SetStringItem(index, 1, str(coord0))
|
|---|
| 1363 | self.list.SetStringItem(index, 2, str(coord1))
|
|---|
| 1364 | self.mapcoordlist[key][1] = coord[0]
|
|---|
| 1365 | self.mapcoordlist[key][2] = coord[1]
|
|---|
| 1366 | self.pointsToDrawSrc.GetItem(key - 1).SetCoords([coord0, coord1])
|
|---|
| 1367 |
|
|---|
| 1368 | elif coordtype == 'target':
|
|---|
| 1369 | self.list.SetStringItem(index, 3, str(coord0))
|
|---|
| 1370 | self.list.SetStringItem(index, 4, str(coord1))
|
|---|
| 1371 | self.mapcoordlist[key][3] = coord[0]
|
|---|
| 1372 | self.mapcoordlist[key][4] = coord[1]
|
|---|
| 1373 | self.pointsToDrawTgt.GetItem(key - 1).SetCoords([coord0, coord1])
|
|---|
| 1374 |
|
|---|
| 1375 | self.list.SetStringItem(index, 5, '0')
|
|---|
| 1376 | self.list.SetStringItem(index, 6, '0')
|
|---|
| 1377 | self.mapcoordlist[key][5] = 0.0
|
|---|
| 1378 | self.mapcoordlist[key][6] = 0.0
|
|---|
| 1379 |
|
|---|
| 1380 | # self.list.ResizeColumns()
|
|---|
| 1381 |
|
|---|
| 1382 | def SaveGCPs(self, event):
|
|---|
| 1383 | """Make a POINTS file or save GCP coordinates to existing
|
|---|
| 1384 | POINTS file
|
|---|
| 1385 | """
|
|---|
| 1386 | self.GCPcount = 0
|
|---|
| 1387 | try:
|
|---|
| 1388 | f = open(self.file['points'], mode='w')
|
|---|
| 1389 | # use os.linesep or '\n' here ???
|
|---|
| 1390 | f.write('# Ground Control Points File\n')
|
|---|
| 1391 | f.write("# \n")
|
|---|
| 1392 | f.write("# target location: " + self.currentlocation + '\n')
|
|---|
| 1393 | f.write("# target mapset: " + self.currentmapset + '\n')
|
|---|
| 1394 | f.write("#\tsource\t\ttarget\t\tstatus\n")
|
|---|
| 1395 | f.write("#\teast\tnorth\teast\tnorth\t(1=ok, 0=ignore)\n")
|
|---|
| 1396 | f.write(
|
|---|
| 1397 | "#----------------------- ----------------------- ---------------\n")
|
|---|
| 1398 |
|
|---|
| 1399 | for index in range(self.list.GetItemCount()):
|
|---|
| 1400 | if self.list.IsChecked(index) == True:
|
|---|
| 1401 | check = "1"
|
|---|
| 1402 | self.GCPcount += 1
|
|---|
| 1403 | else:
|
|---|
| 1404 | check = "0"
|
|---|
| 1405 | coord0 = self.list.GetItem(index, 1).GetText()
|
|---|
| 1406 | coord1 = self.list.GetItem(index, 2).GetText()
|
|---|
| 1407 | coord2 = self.list.GetItem(index, 3).GetText()
|
|---|
| 1408 | coord3 = self.list.GetItem(index, 4).GetText()
|
|---|
| 1409 | f.write(
|
|---|
| 1410 | coord0 +
|
|---|
| 1411 | ' ' +
|
|---|
| 1412 | coord1 +
|
|---|
| 1413 | ' ' +
|
|---|
| 1414 | coord2 +
|
|---|
| 1415 | ' ' +
|
|---|
| 1416 | coord3 +
|
|---|
| 1417 | ' ' +
|
|---|
| 1418 | check +
|
|---|
| 1419 | '\n')
|
|---|
| 1420 |
|
|---|
| 1421 | except IOError as err:
|
|---|
| 1422 | GError(
|
|---|
| 1423 | parent=self,
|
|---|
| 1424 | message="%s <%s>. %s%s" %
|
|---|
| 1425 | (_("Writing POINTS file failed"),
|
|---|
| 1426 | self.file['points'],
|
|---|
| 1427 | os.linesep,
|
|---|
| 1428 | err))
|
|---|
| 1429 | return
|
|---|
| 1430 |
|
|---|
| 1431 | f.close()
|
|---|
| 1432 |
|
|---|
| 1433 | # if event != None save also to backup file
|
|---|
| 1434 | if event:
|
|---|
| 1435 | shutil.copy(self.file['points'], self.file['points_bak'])
|
|---|
| 1436 | self._giface.WriteLog(
|
|---|
| 1437 | _('POINTS file saved for group <%s>') %
|
|---|
| 1438 | self.xygroup)
|
|---|
| 1439 | #self.SetStatusText(_('POINTS file saved'))
|
|---|
| 1440 |
|
|---|
| 1441 | def ReadGCPs(self):
|
|---|
| 1442 | """
|
|---|
| 1443 | Reads GCPs and georectified coordinates from POINTS file
|
|---|
| 1444 | """
|
|---|
| 1445 |
|
|---|
| 1446 | self.GCPcount = 0
|
|---|
| 1447 |
|
|---|
| 1448 | sourceMapWin = self.SrcMapWindow
|
|---|
| 1449 | targetMapWin = self.TgtMapWindow
|
|---|
| 1450 |
|
|---|
| 1451 | if not sourceMapWin:
|
|---|
| 1452 | GError(parent=self,
|
|---|
| 1453 | message="%s. %s%s" % (_("source mapwin not defined"),
|
|---|
| 1454 | os.linesep, err))
|
|---|
| 1455 |
|
|---|
| 1456 | if not targetMapWin:
|
|---|
| 1457 | GError(parent=self,
|
|---|
| 1458 | message="%s. %s%s" % (_("target mapwin not defined"),
|
|---|
| 1459 | os.linesep, err))
|
|---|
| 1460 |
|
|---|
| 1461 | try:
|
|---|
| 1462 | f = open(self.file['points'], 'r')
|
|---|
| 1463 | GCPcnt = 0
|
|---|
| 1464 |
|
|---|
| 1465 | for line in f.readlines():
|
|---|
| 1466 | if line[0] == '#' or line == '':
|
|---|
| 1467 | continue
|
|---|
| 1468 | line = line.replace('\n', '').strip()
|
|---|
| 1469 | coords = map(float, line.split())
|
|---|
| 1470 | if coords[4] == 1:
|
|---|
| 1471 | check = True
|
|---|
| 1472 | self.GCPcount += 1
|
|---|
| 1473 | else:
|
|---|
| 1474 | check = False
|
|---|
| 1475 |
|
|---|
| 1476 | self.AddGCP(event=None)
|
|---|
| 1477 | self.SetGCPData('source', (coords[0], coords[1]), sourceMapWin)
|
|---|
| 1478 | self.SetGCPData('target', (coords[2], coords[3]), targetMapWin)
|
|---|
| 1479 | index = self.list.GetSelected()
|
|---|
| 1480 | if index != wx.NOT_FOUND:
|
|---|
| 1481 | self.list.CheckItem(index, check)
|
|---|
| 1482 | GCPcnt += 1
|
|---|
| 1483 |
|
|---|
| 1484 | except IOError as err:
|
|---|
| 1485 | GError(
|
|---|
| 1486 | parent=self,
|
|---|
| 1487 | message="%s <%s>. %s%s" %
|
|---|
| 1488 | (_("Reading POINTS file failed"),
|
|---|
| 1489 | self.file['points'],
|
|---|
| 1490 | os.linesep,
|
|---|
| 1491 | err))
|
|---|
| 1492 | return
|
|---|
| 1493 |
|
|---|
| 1494 | f.close()
|
|---|
| 1495 |
|
|---|
| 1496 | if GCPcnt == 0:
|
|---|
| 1497 | # 3 gcp is minimum
|
|---|
| 1498 | for i in range(3):
|
|---|
| 1499 | self.AddGCP(None)
|
|---|
| 1500 |
|
|---|
| 1501 | if self.CheckGCPcount():
|
|---|
| 1502 | # calculate RMS
|
|---|
| 1503 | self.RMSError(self.xygroup, self.gr_order)
|
|---|
| 1504 |
|
|---|
| 1505 | def ReloadGCPs(self, event):
|
|---|
| 1506 | """Reload data from file"""
|
|---|
| 1507 |
|
|---|
| 1508 | # use backup
|
|---|
| 1509 | shutil.copy(self.file['points_bak'], self.file['points'])
|
|---|
| 1510 |
|
|---|
| 1511 | # delete all items in mapcoordlist
|
|---|
| 1512 | self.mapcoordlist = []
|
|---|
| 1513 | self.mapcoordlist.append([0, # GCP number
|
|---|
| 1514 | 0.0, # source east
|
|---|
| 1515 | 0.0, # source north
|
|---|
| 1516 | 0.0, # target east
|
|---|
| 1517 | 0.0, # target north
|
|---|
| 1518 | 0.0, # forward error
|
|---|
| 1519 | 0.0]) # backward error
|
|---|
| 1520 |
|
|---|
| 1521 | self.list.LoadData()
|
|---|
| 1522 | self.itemDataMap = self.mapcoordlist
|
|---|
| 1523 |
|
|---|
| 1524 | if self._col != -1:
|
|---|
| 1525 | self.list.ClearColumnImage(self._col)
|
|---|
| 1526 | self._colSortFlag = [1] * self.list.GetColumnCount()
|
|---|
| 1527 |
|
|---|
| 1528 | # draw GCPs (source and target)
|
|---|
| 1529 | sourceMapWin = self.SrcMapWindow
|
|---|
| 1530 | sourceMapWin.UpdateMap(render=False, renderVector=False)
|
|---|
| 1531 | if self.show_target:
|
|---|
| 1532 | targetMapWin = self.TgtMapWindow
|
|---|
| 1533 | targetMapWin.UpdateMap(render=False, renderVector=False)
|
|---|
| 1534 |
|
|---|
| 1535 | def OnFocus(self, event):
|
|---|
| 1536 | # TODO: it is here just to remove old or obsolate beavior of base class gcp/MapFrame?
|
|---|
| 1537 | # self.grwiz.SwitchEnv('source')
|
|---|
| 1538 | pass
|
|---|
| 1539 |
|
|---|
| 1540 | def _onMouseLeftUpPointer(self, mapWindow, x, y):
|
|---|
| 1541 | if mapWindow == self.SrcMapWindow:
|
|---|
| 1542 | coordtype = 'source'
|
|---|
| 1543 | else:
|
|---|
| 1544 | coordtype = 'target'
|
|---|
| 1545 |
|
|---|
| 1546 | coord = (x, y)
|
|---|
| 1547 | self.SetGCPData(coordtype, coord, self, confirm=True)
|
|---|
| 1548 | mapWindow.UpdateMap(render=False, renderVector=False)
|
|---|
| 1549 |
|
|---|
| 1550 | def OnRMS(self, event):
|
|---|
| 1551 | """
|
|---|
| 1552 | RMS button handler
|
|---|
| 1553 | """
|
|---|
| 1554 | self.RMSError(self.xygroup, self.gr_order)
|
|---|
| 1555 |
|
|---|
| 1556 | sourceMapWin = self.SrcMapWindow
|
|---|
| 1557 | sourceMapWin.UpdateMap(render=False, renderVector=False)
|
|---|
| 1558 | if self.show_target:
|
|---|
| 1559 | targetMapWin = self.TgtMapWindow
|
|---|
| 1560 | targetMapWin.UpdateMap(render=False, renderVector=False)
|
|---|
| 1561 |
|
|---|
| 1562 | def CheckGCPcount(self, msg=False):
|
|---|
| 1563 | """
|
|---|
| 1564 | Checks to make sure that the minimum number of GCPs have been defined and
|
|---|
| 1565 | are active for the selected transformation order
|
|---|
| 1566 | """
|
|---|
| 1567 | if (self.GCPcount < 3 and self.gr_order == 1) or \
|
|---|
| 1568 | (self.GCPcount < 6 and self.gr_order == 2) or \
|
|---|
| 1569 | (self.GCPcount < 10 and self.gr_order == 3):
|
|---|
| 1570 | if msg:
|
|---|
| 1571 | GWarning(
|
|---|
| 1572 | parent=self, message=_(
|
|---|
| 1573 | 'Insufficient points defined and active (checked) '
|
|---|
| 1574 | 'for selected rectification method (order: %d).\n'
|
|---|
| 1575 | '3+ points needed for 1st order,\n'
|
|---|
| 1576 | '6+ points for 2nd order, and\n'
|
|---|
| 1577 | '10+ points for 3rd order.') %
|
|---|
| 1578 | self.gr_order)
|
|---|
| 1579 | return False
|
|---|
| 1580 | else:
|
|---|
| 1581 | return True
|
|---|
| 1582 |
|
|---|
| 1583 | def OnGeorect(self, event):
|
|---|
| 1584 | """
|
|---|
| 1585 | Georectifies map(s) in group using i.rectify or v.transform
|
|---|
| 1586 | """
|
|---|
| 1587 | global maptype
|
|---|
| 1588 | self.SaveGCPs(None)
|
|---|
| 1589 |
|
|---|
| 1590 | if self.CheckGCPcount(msg=True) == False:
|
|---|
| 1591 | return
|
|---|
| 1592 |
|
|---|
| 1593 | if maptype == 'raster':
|
|---|
| 1594 | self.grwiz.SwitchEnv('source')
|
|---|
| 1595 |
|
|---|
| 1596 | if self.clip_to_region:
|
|---|
| 1597 | flags = "ac"
|
|---|
| 1598 | else:
|
|---|
| 1599 | flags = "a"
|
|---|
| 1600 |
|
|---|
| 1601 | busy = wx.BusyInfo(_("Rectifying images, please wait..."),
|
|---|
| 1602 | parent=self)
|
|---|
| 1603 | wx.Yield()
|
|---|
| 1604 |
|
|---|
| 1605 | ret, msg = RunCommand('i.rectify',
|
|---|
| 1606 | parent=self,
|
|---|
| 1607 | getErrorMsg=True,
|
|---|
| 1608 | quiet=True,
|
|---|
| 1609 | group=self.xygroup,
|
|---|
| 1610 | extension=self.extension,
|
|---|
| 1611 | order=self.gr_order,
|
|---|
| 1612 | method=self.gr_method,
|
|---|
| 1613 | flags=flags)
|
|---|
| 1614 |
|
|---|
| 1615 | del busy
|
|---|
| 1616 |
|
|---|
| 1617 | # provide feedback on failure
|
|---|
| 1618 | if ret != 0:
|
|---|
| 1619 | print(msg, file=sys.stderr)
|
|---|
| 1620 |
|
|---|
| 1621 | elif maptype == 'vector':
|
|---|
| 1622 | # loop through all vectors in VREF
|
|---|
| 1623 |
|
|---|
| 1624 | self.grwiz.SwitchEnv('source')
|
|---|
| 1625 |
|
|---|
| 1626 | # make list of vectors to georectify from VREF
|
|---|
| 1627 | f = open(self.file['vgrp'])
|
|---|
| 1628 | vectlist = []
|
|---|
| 1629 | try:
|
|---|
| 1630 | for vect in f.readlines():
|
|---|
| 1631 | vect = vect.strip('\n')
|
|---|
| 1632 | if len(vect) < 1:
|
|---|
| 1633 | continue
|
|---|
| 1634 | vectlist.append(vect)
|
|---|
| 1635 | finally:
|
|---|
| 1636 | f.close()
|
|---|
| 1637 |
|
|---|
| 1638 | # georectify each vector in VREF using v.rectify
|
|---|
| 1639 | for vect in vectlist:
|
|---|
| 1640 | self.outname = str(vect.split('@')[0]) + self.extension
|
|---|
| 1641 | self._giface.WriteLog(text=_('Transforming <%s>...') % vect,
|
|---|
| 1642 | notification=Notification.MAKE_VISIBLE)
|
|---|
| 1643 | ret = msg = ''
|
|---|
| 1644 |
|
|---|
| 1645 | busy = wx.BusyInfo(
|
|---|
| 1646 | _("Rectifying vector map <%s>, please wait...") %
|
|---|
| 1647 | vect, parent=self)
|
|---|
| 1648 | wx.Yield()
|
|---|
| 1649 |
|
|---|
| 1650 | ret, msg = RunCommand('v.rectify',
|
|---|
| 1651 | parent=self,
|
|---|
| 1652 | getErrorMsg=True,
|
|---|
| 1653 | quiet=True,
|
|---|
| 1654 | input=vect,
|
|---|
| 1655 | output=self.outname,
|
|---|
| 1656 | group=self.xygroup,
|
|---|
| 1657 | order=self.gr_order)
|
|---|
| 1658 |
|
|---|
| 1659 | del busy
|
|---|
| 1660 |
|
|---|
| 1661 | # provide feedback on failure
|
|---|
| 1662 | if ret != 0:
|
|---|
| 1663 | print(msg, file=sys.stderr)
|
|---|
| 1664 |
|
|---|
| 1665 | self.grwiz.SwitchEnv('target')
|
|---|
| 1666 |
|
|---|
| 1667 | def OnGeorectDone(self, **kargs):
|
|---|
| 1668 | """Print final message"""
|
|---|
| 1669 | global maptype
|
|---|
| 1670 | if maptype == 'raster':
|
|---|
| 1671 | return
|
|---|
| 1672 |
|
|---|
| 1673 | returncode = kargs['returncode']
|
|---|
| 1674 |
|
|---|
| 1675 | if returncode == 0:
|
|---|
| 1676 | self.VectGRList.append(self.outname)
|
|---|
| 1677 | print('*****vector list = ' + str(self.VectGRList))
|
|---|
| 1678 | else:
|
|---|
| 1679 | self._giface.WriteError(
|
|---|
| 1680 | _('Georectification of vector map <%s> failed') %
|
|---|
| 1681 | self.outname)
|
|---|
| 1682 |
|
|---|
| 1683 | def OnSettings(self, event):
|
|---|
| 1684 | """GCP Manager settings"""
|
|---|
| 1685 | dlg = GrSettingsDialog(parent=self, giface=self._giface,
|
|---|
| 1686 | id=wx.ID_ANY, title=_('GCP Manager settings'))
|
|---|
| 1687 |
|
|---|
| 1688 | if dlg.ShowModal() == wx.ID_OK:
|
|---|
| 1689 | pass
|
|---|
| 1690 |
|
|---|
| 1691 | dlg.Destroy()
|
|---|
| 1692 |
|
|---|
| 1693 | def UpdateColours(self, srcrender=False, srcrenderVector=False,
|
|---|
| 1694 | tgtrender=False, tgtrenderVector=False):
|
|---|
| 1695 | """update colours"""
|
|---|
| 1696 | highest_fwd_err = 0.0
|
|---|
| 1697 | self.highest_key = 0
|
|---|
| 1698 | highest_idx = 0
|
|---|
| 1699 |
|
|---|
| 1700 | for index in range(self.list.GetItemCount()):
|
|---|
| 1701 | if self.list.IsChecked(index):
|
|---|
| 1702 | key = self.list.GetItemData(index)
|
|---|
| 1703 | fwd_err = self.mapcoordlist[key][5]
|
|---|
| 1704 |
|
|---|
| 1705 | if self.highest_only == True:
|
|---|
| 1706 | self.list.SetItemTextColour(index, wx.BLACK)
|
|---|
| 1707 | if highest_fwd_err < fwd_err:
|
|---|
| 1708 | highest_fwd_err = fwd_err
|
|---|
| 1709 | self.highest_key = key
|
|---|
| 1710 | highest_idx = index
|
|---|
| 1711 | elif self.rmsthresh > 0:
|
|---|
| 1712 | if (fwd_err > self.rmsthresh):
|
|---|
| 1713 | self.list.SetItemTextColour(index, wx.RED)
|
|---|
| 1714 | else:
|
|---|
| 1715 | self.list.SetItemTextColour(index, wx.BLACK)
|
|---|
| 1716 | else:
|
|---|
| 1717 | self.list.SetItemTextColour(index, wx.BLACK)
|
|---|
| 1718 |
|
|---|
| 1719 | if self.highest_only and highest_fwd_err > 0.0:
|
|---|
| 1720 | self.list.SetItemTextColour(highest_idx, wx.RED)
|
|---|
| 1721 |
|
|---|
| 1722 | sourceMapWin = self.SrcMapWindow
|
|---|
| 1723 | sourceMapWin.UpdateMap(render=srcrender, renderVector=srcrenderVector)
|
|---|
| 1724 | if self.show_target:
|
|---|
| 1725 | targetMapWin = self.TgtMapWindow
|
|---|
| 1726 | targetMapWin.UpdateMap(
|
|---|
| 1727 | render=tgtrender,
|
|---|
| 1728 | renderVector=tgtrenderVector)
|
|---|
| 1729 |
|
|---|
| 1730 | def OnQuit(self, event):
|
|---|
| 1731 | """Quit georectifier"""
|
|---|
| 1732 | ret = wx.MessageBox(
|
|---|
| 1733 | parent=self, caption=_("Quit GCP Manager"),
|
|---|
| 1734 | message=_('Save ground control points?'),
|
|---|
| 1735 | style=wx.ICON_QUESTION | wx.YES_NO | wx.CANCEL | wx.CENTRE)
|
|---|
| 1736 |
|
|---|
| 1737 | if ret != wx.CANCEL:
|
|---|
| 1738 | if ret == wx.YES:
|
|---|
| 1739 | self.SaveGCPs(None)
|
|---|
| 1740 | elif ret == wx.NO:
|
|---|
| 1741 | # restore POINTS file from backup
|
|---|
| 1742 | if os.path.exists(self.file['points_bak']):
|
|---|
| 1743 | shutil.copy(self.file['points_bak'], self.file['points'])
|
|---|
| 1744 |
|
|---|
| 1745 | if os.path.exists(self.file['points_bak']):
|
|---|
| 1746 | os.unlink(self.file['points_bak'])
|
|---|
| 1747 |
|
|---|
| 1748 | self.SrcMap.Clean()
|
|---|
| 1749 | self.TgtMap.Clean()
|
|---|
| 1750 |
|
|---|
| 1751 | self.grwiz.Cleanup()
|
|---|
| 1752 |
|
|---|
| 1753 | self.Destroy()
|
|---|
| 1754 |
|
|---|
| 1755 | # event.Skip()
|
|---|
| 1756 |
|
|---|
| 1757 | def OnGROrder(self, event):
|
|---|
| 1758 | """
|
|---|
| 1759 | sets transformation order for georectifying
|
|---|
| 1760 | """
|
|---|
| 1761 | if event:
|
|---|
| 1762 | self.gr_order = event.GetInt() + 1
|
|---|
| 1763 |
|
|---|
| 1764 | numOfItems = self.list.GetItemCount()
|
|---|
| 1765 | minNumOfItems = numOfItems
|
|---|
| 1766 |
|
|---|
| 1767 | if self.gr_order == 1:
|
|---|
| 1768 | minNumOfItems = 3
|
|---|
| 1769 | # self.SetStatusText(_('Insufficient points, 3+ points needed for 1st order'))
|
|---|
| 1770 |
|
|---|
| 1771 | elif self.gr_order == 2:
|
|---|
| 1772 | minNumOfItems = 6
|
|---|
| 1773 | diff = 6 - numOfItems
|
|---|
| 1774 | # self.SetStatusText(_('Insufficient points, 6+ points needed for 2nd order'))
|
|---|
| 1775 |
|
|---|
| 1776 | elif self.gr_order == 3:
|
|---|
| 1777 | minNumOfItems = 10
|
|---|
| 1778 | # self.SetStatusText(_('Insufficient points, 10+ points needed for 3rd order'))
|
|---|
| 1779 |
|
|---|
| 1780 | for i in range(minNumOfItems - numOfItems):
|
|---|
| 1781 | self.AddGCP(None)
|
|---|
| 1782 |
|
|---|
| 1783 | return minNumOfItems
|
|---|
| 1784 |
|
|---|
| 1785 | def RMSError(self, xygroup, order):
|
|---|
| 1786 | """
|
|---|
| 1787 | Uses m.transform to calculate forward and backward error for each used GCP
|
|---|
| 1788 | in POINTS file and insert error values into GCP list.
|
|---|
| 1789 | Calculates total forward and backward RMS error for all used points
|
|---|
| 1790 | """
|
|---|
| 1791 | # save GCPs to points file to make sure that all checked GCPs are used
|
|---|
| 1792 | self.SaveGCPs(None)
|
|---|
| 1793 | # self.SetStatusText('')
|
|---|
| 1794 |
|
|---|
| 1795 | if self.CheckGCPcount(msg=True) == False:
|
|---|
| 1796 | return
|
|---|
| 1797 |
|
|---|
| 1798 | # get list of forward and reverse rms error values for each point
|
|---|
| 1799 | self.grwiz.SwitchEnv('source')
|
|---|
| 1800 |
|
|---|
| 1801 | ret = RunCommand('m.transform',
|
|---|
| 1802 | parent=self,
|
|---|
| 1803 | read=True,
|
|---|
| 1804 | group=xygroup,
|
|---|
| 1805 | order=order)
|
|---|
| 1806 |
|
|---|
| 1807 | self.grwiz.SwitchEnv('target')
|
|---|
| 1808 |
|
|---|
| 1809 | if ret:
|
|---|
| 1810 | errlist = ret.splitlines()
|
|---|
| 1811 | else:
|
|---|
| 1812 | GError(parent=self,
|
|---|
| 1813 | message=_('Could not calculate RMS Error.\n'
|
|---|
| 1814 | 'Possible error with m.transform.'))
|
|---|
| 1815 | return
|
|---|
| 1816 |
|
|---|
| 1817 | # insert error values into GCP list for checked items
|
|---|
| 1818 | sdfactor = float(
|
|---|
| 1819 | UserSettings.Get(
|
|---|
| 1820 | group='gcpman',
|
|---|
| 1821 | key='rms',
|
|---|
| 1822 | subkey='sdfactor'))
|
|---|
| 1823 | GCPcount = 0
|
|---|
| 1824 | sumsq_fwd_err = 0.0
|
|---|
| 1825 | sumsq_bkw_err = 0.0
|
|---|
| 1826 | sum_fwd_err = 0.0
|
|---|
| 1827 | highest_fwd_err = 0.0
|
|---|
| 1828 | self.highest_key = 0
|
|---|
| 1829 | highest_idx = 0
|
|---|
| 1830 |
|
|---|
| 1831 | for index in range(self.list.GetItemCount()):
|
|---|
| 1832 | key = self.list.GetItemData(index)
|
|---|
| 1833 | if self.list.IsChecked(index):
|
|---|
| 1834 | fwd_err, bkw_err = errlist[GCPcount].split()
|
|---|
| 1835 | self.list.SetStringItem(index, 5, fwd_err)
|
|---|
| 1836 | self.list.SetStringItem(index, 6, bkw_err)
|
|---|
| 1837 | self.mapcoordlist[key][5] = float(fwd_err)
|
|---|
| 1838 | self.mapcoordlist[key][6] = float(bkw_err)
|
|---|
| 1839 | self.list.SetItemTextColour(index, wx.BLACK)
|
|---|
| 1840 | if self.highest_only:
|
|---|
| 1841 | if highest_fwd_err < float(fwd_err):
|
|---|
| 1842 | highest_fwd_err = float(fwd_err)
|
|---|
| 1843 | self.highest_key = key
|
|---|
| 1844 | highest_idx = index
|
|---|
| 1845 |
|
|---|
| 1846 | sumsq_fwd_err += float(fwd_err)**2
|
|---|
| 1847 | sumsq_bkw_err += float(bkw_err)**2
|
|---|
| 1848 | sum_fwd_err += float(fwd_err)
|
|---|
| 1849 | GCPcount += 1
|
|---|
| 1850 | else:
|
|---|
| 1851 | self.list.SetStringItem(index, 5, '')
|
|---|
| 1852 | self.list.SetStringItem(index, 6, '')
|
|---|
| 1853 | self.mapcoordlist[key][5] = 0.0
|
|---|
| 1854 | self.mapcoordlist[key][6] = 0.0
|
|---|
| 1855 | self.list.SetItemTextColour(index, wx.BLACK)
|
|---|
| 1856 |
|
|---|
| 1857 | # SD
|
|---|
| 1858 | if GCPcount > 0:
|
|---|
| 1859 | self.rmsmean = sum_fwd_err / GCPcount
|
|---|
| 1860 | self.rmssd = ((sumsq_fwd_err - self.rmsmean**2)**0.5)
|
|---|
| 1861 | self.rmsthresh = self.rmsmean + sdfactor * self.rmssd
|
|---|
| 1862 | else:
|
|---|
| 1863 | self.rmsthresh = 0
|
|---|
| 1864 | self.rmsmean = 0
|
|---|
| 1865 | self.rmssd = 0
|
|---|
| 1866 |
|
|---|
| 1867 | if self.highest_only and highest_fwd_err > 0.0:
|
|---|
| 1868 | self.list.SetItemTextColour(highest_idx, wx.RED)
|
|---|
| 1869 | elif GCPcount > 0 and self.rmsthresh > 0 and not self.highest_only:
|
|---|
| 1870 | for index in range(self.list.GetItemCount()):
|
|---|
| 1871 | if self.list.IsChecked(index):
|
|---|
| 1872 | key = self.list.GetItemData(index)
|
|---|
| 1873 | if (self.mapcoordlist[key][5] > self.rmsthresh):
|
|---|
| 1874 | self.list.SetItemTextColour(index, wx.RED)
|
|---|
| 1875 |
|
|---|
| 1876 | # calculate global RMS error (geometric mean)
|
|---|
| 1877 | self.fwd_rmserror = round((sumsq_fwd_err / GCPcount)**0.5, 4)
|
|---|
| 1878 | self.bkw_rmserror = round((sumsq_bkw_err / GCPcount)**0.5, 4)
|
|---|
| 1879 | self.list.ResizeColumns()
|
|---|
| 1880 |
|
|---|
| 1881 | def GetNewExtent(self, region, map=None):
|
|---|
| 1882 |
|
|---|
| 1883 | coord_file = utils.GetTempfile()
|
|---|
| 1884 | newreg = {'n': 0.0, 's': 0.0, 'e': 0.0, 'w': 0.0, }
|
|---|
| 1885 |
|
|---|
| 1886 | try:
|
|---|
| 1887 | f = open(coord_file, mode='w')
|
|---|
| 1888 | # NW corner
|
|---|
| 1889 | f.write(str(region['e']) + " " + str(region['n']) + "\n")
|
|---|
| 1890 | # NE corner
|
|---|
| 1891 | f.write(str(region['e']) + " " + str(region['s']) + "\n")
|
|---|
| 1892 | # SW corner
|
|---|
| 1893 | f.write(str(region['w']) + " " + str(region['n']) + "\n")
|
|---|
| 1894 | # SE corner
|
|---|
| 1895 | f.write(str(region['w']) + " " + str(region['s']) + "\n")
|
|---|
| 1896 | finally:
|
|---|
| 1897 | f.close()
|
|---|
| 1898 |
|
|---|
| 1899 | # save GCPs to points file to make sure that all checked GCPs are used
|
|---|
| 1900 | self.SaveGCPs(None)
|
|---|
| 1901 |
|
|---|
| 1902 | order = self.gr_order
|
|---|
| 1903 | self.gr_order = 1
|
|---|
| 1904 |
|
|---|
| 1905 | if self.CheckGCPcount(msg=True) == False:
|
|---|
| 1906 | self.gr_order = order
|
|---|
| 1907 | return
|
|---|
| 1908 |
|
|---|
| 1909 | self.gr_order = order
|
|---|
| 1910 |
|
|---|
| 1911 | # get list of forward and reverse rms error values for each point
|
|---|
| 1912 | self.grwiz.SwitchEnv('source')
|
|---|
| 1913 |
|
|---|
| 1914 | if map == 'source':
|
|---|
| 1915 | ret = RunCommand('m.transform',
|
|---|
| 1916 | parent=self,
|
|---|
| 1917 | read=True,
|
|---|
| 1918 | group=self.xygroup,
|
|---|
| 1919 | order=1,
|
|---|
| 1920 | format='dst',
|
|---|
| 1921 | coords=coord_file)
|
|---|
| 1922 |
|
|---|
| 1923 | elif map == 'target':
|
|---|
| 1924 | ret = RunCommand('m.transform',
|
|---|
| 1925 | parent=self,
|
|---|
| 1926 | read=True,
|
|---|
| 1927 | group=self.xygroup,
|
|---|
| 1928 | order=1,
|
|---|
| 1929 | flags='r',
|
|---|
| 1930 | format='src',
|
|---|
| 1931 | coords=coord_file)
|
|---|
| 1932 |
|
|---|
| 1933 | os.unlink(coord_file)
|
|---|
| 1934 |
|
|---|
| 1935 | self.grwiz.SwitchEnv('target')
|
|---|
| 1936 |
|
|---|
| 1937 | if ret:
|
|---|
| 1938 | errlist = ret.splitlines()
|
|---|
| 1939 | else:
|
|---|
| 1940 | GError(parent=self,
|
|---|
| 1941 | message=_('Could not calculate new extends.\n'
|
|---|
| 1942 | 'Possible error with m.transform.'))
|
|---|
| 1943 | return
|
|---|
| 1944 |
|
|---|
| 1945 | # fist corner
|
|---|
| 1946 | e, n = errlist[0].split()
|
|---|
| 1947 | fe = float(e)
|
|---|
| 1948 | fn = float(n)
|
|---|
| 1949 | newreg['n'] = fn
|
|---|
| 1950 | newreg['s'] = fn
|
|---|
| 1951 | newreg['e'] = fe
|
|---|
| 1952 | newreg['w'] = fe
|
|---|
| 1953 | # other three corners
|
|---|
| 1954 | for i in range(1, 4):
|
|---|
| 1955 | e, n = errlist[i].split()
|
|---|
| 1956 | fe = float(e)
|
|---|
| 1957 | fn = float(n)
|
|---|
| 1958 | if fe < newreg['w']:
|
|---|
| 1959 | newreg['w'] = fe
|
|---|
| 1960 | if fe > newreg['e']:
|
|---|
| 1961 | newreg['e'] = fe
|
|---|
| 1962 | if fn < newreg['s']:
|
|---|
| 1963 | newreg['s'] = fn
|
|---|
| 1964 | if fn > newreg['n']:
|
|---|
| 1965 | newreg['n'] = fn
|
|---|
| 1966 |
|
|---|
| 1967 | return newreg
|
|---|
| 1968 |
|
|---|
| 1969 | def OnHelp(self, event):
|
|---|
| 1970 | """Show GCP Manager manual page"""
|
|---|
| 1971 | self._giface.Help(entry='wxGUI.gcp')
|
|---|
| 1972 |
|
|---|
| 1973 | def OnUpdateActive(self, event):
|
|---|
| 1974 |
|
|---|
| 1975 | if self.activemap.GetSelection() == 0:
|
|---|
| 1976 | self.MapWindow = self.SrcMapWindow
|
|---|
| 1977 | self.Map = self.SrcMap
|
|---|
| 1978 | else:
|
|---|
| 1979 | self.MapWindow = self.TgtMapWindow
|
|---|
| 1980 | self.Map = self.TgtMap
|
|---|
| 1981 |
|
|---|
| 1982 | self.UpdateActive(self.MapWindow)
|
|---|
| 1983 | # for wingrass
|
|---|
| 1984 | if os.name == 'nt':
|
|---|
| 1985 | self.MapWindow.SetFocus()
|
|---|
| 1986 |
|
|---|
| 1987 | def UpdateActive(self, win):
|
|---|
| 1988 |
|
|---|
| 1989 | # optionally disable tool zoomback tool
|
|---|
| 1990 | self.GetMapToolbar().Enable('zoomback',
|
|---|
| 1991 | enable=(len(self.MapWindow.zoomhistory) > 1))
|
|---|
| 1992 |
|
|---|
| 1993 | if self.activemap.GetSelection() != (win == self.TgtMapWindow):
|
|---|
| 1994 | self.activemap.SetSelection(win == self.TgtMapWindow)
|
|---|
| 1995 | self.StatusbarUpdate()
|
|---|
| 1996 |
|
|---|
| 1997 | def AdjustMap(self, newreg):
|
|---|
| 1998 | """Adjust map window to new extents
|
|---|
| 1999 | """
|
|---|
| 2000 |
|
|---|
| 2001 | # adjust map window
|
|---|
| 2002 | self.Map.region['n'] = newreg['n']
|
|---|
| 2003 | self.Map.region['s'] = newreg['s']
|
|---|
| 2004 | self.Map.region['e'] = newreg['e']
|
|---|
| 2005 | self.Map.region['w'] = newreg['w']
|
|---|
| 2006 |
|
|---|
| 2007 | self.MapWindow.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
|
|---|
| 2008 | self.Map.region['e'], self.Map.region['w'])
|
|---|
| 2009 |
|
|---|
| 2010 | # LL locations
|
|---|
| 2011 | if self.Map.projinfo['proj'] == 'll':
|
|---|
| 2012 | if newreg['n'] > 90.0:
|
|---|
| 2013 | newreg['n'] = 90.0
|
|---|
| 2014 | if newreg['s'] < -90.0:
|
|---|
| 2015 | newreg['s'] = -90.0
|
|---|
| 2016 |
|
|---|
| 2017 | ce = newreg['w'] + (newreg['e'] - newreg['w']) / 2
|
|---|
| 2018 | cn = newreg['s'] + (newreg['n'] - newreg['s']) / 2
|
|---|
| 2019 |
|
|---|
| 2020 | # calculate new center point and display resolution
|
|---|
| 2021 | self.Map.region['center_easting'] = ce
|
|---|
| 2022 | self.Map.region['center_northing'] = cn
|
|---|
| 2023 | self.Map.region["ewres"] = (newreg['e'] - newreg['w']) / self.Map.width
|
|---|
| 2024 | self.Map.region["nsres"] = (
|
|---|
| 2025 | newreg['n'] - newreg['s']) / self.Map.height
|
|---|
| 2026 | self.Map.AlignExtentFromDisplay()
|
|---|
| 2027 |
|
|---|
| 2028 | self.MapWindow.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
|
|---|
| 2029 | self.Map.region['e'], self.Map.region['w'])
|
|---|
| 2030 |
|
|---|
| 2031 | if self.MapWindow.redrawAll is False:
|
|---|
| 2032 | self.MapWindow.redrawAll = True
|
|---|
| 2033 |
|
|---|
| 2034 | self.MapWindow.UpdateMap()
|
|---|
| 2035 | self.StatusbarUpdate()
|
|---|
| 2036 |
|
|---|
| 2037 | def OnZoomToSource(self, event):
|
|---|
| 2038 | """Set target map window to match extents of source map window
|
|---|
| 2039 | """
|
|---|
| 2040 |
|
|---|
| 2041 | if not self.MapWindow == self.TgtMapWindow:
|
|---|
| 2042 | self.MapWindow = self.TgtMapWindow
|
|---|
| 2043 | self.Map = self.TgtMap
|
|---|
| 2044 | self.UpdateActive(self.TgtMapWindow)
|
|---|
| 2045 |
|
|---|
| 2046 | # get new N, S, E, W for target
|
|---|
| 2047 | newreg = self.GetNewExtent(self.SrcMap.region, 'source')
|
|---|
| 2048 | if newreg:
|
|---|
| 2049 | self.AdjustMap(newreg)
|
|---|
| 2050 |
|
|---|
| 2051 | def OnZoomToTarget(self, event):
|
|---|
| 2052 | """Set source map window to match extents of target map window
|
|---|
| 2053 | """
|
|---|
| 2054 |
|
|---|
| 2055 | if not self.MapWindow == self.SrcMapWindow:
|
|---|
| 2056 | self.MapWindow = self.SrcMapWindow
|
|---|
| 2057 | self.Map = self.SrcMap
|
|---|
| 2058 | self.UpdateActive(self.SrcMapWindow)
|
|---|
| 2059 |
|
|---|
| 2060 | # get new N, S, E, W for target
|
|---|
| 2061 | newreg = self.GetNewExtent(self.TgtMap.region, 'target')
|
|---|
| 2062 | if newreg:
|
|---|
| 2063 | self.AdjustMap(newreg)
|
|---|
| 2064 |
|
|---|
| 2065 | def OnZoomMenuGCP(self, event):
|
|---|
| 2066 | """Popup Zoom menu
|
|---|
| 2067 | """
|
|---|
| 2068 | point = wx.GetMousePosition()
|
|---|
| 2069 | zoommenu = Menu()
|
|---|
| 2070 | # Add items to the menu
|
|---|
| 2071 |
|
|---|
| 2072 | zoomsource = wx.MenuItem(zoommenu, wx.ID_ANY, _(
|
|---|
| 2073 | 'Adjust source display to target display'))
|
|---|
| 2074 | zoommenu.AppendItem(zoomsource)
|
|---|
| 2075 | self.Bind(wx.EVT_MENU, self.OnZoomToTarget, zoomsource)
|
|---|
| 2076 |
|
|---|
| 2077 | zoomtarget = wx.MenuItem(zoommenu, wx.ID_ANY, _(
|
|---|
| 2078 | 'Adjust target display to source display'))
|
|---|
| 2079 | zoommenu.AppendItem(zoomtarget)
|
|---|
| 2080 | self.Bind(wx.EVT_MENU, self.OnZoomToSource, zoomtarget)
|
|---|
| 2081 |
|
|---|
| 2082 | # Popup the menu. If an item is selected then its handler
|
|---|
| 2083 | # will be called before PopupMenu returns.
|
|---|
| 2084 | self.PopupMenu(zoommenu)
|
|---|
| 2085 | zoommenu.Destroy()
|
|---|
| 2086 |
|
|---|
| 2087 | def OnSize(self, event):
|
|---|
| 2088 | """Adjust Map Windows after GCP Map Display has been resized
|
|---|
| 2089 | """
|
|---|
| 2090 | # re-render image on idle
|
|---|
| 2091 | self.resize = time.clock()
|
|---|
| 2092 | super(MapFrame, self).OnSize(event)
|
|---|
| 2093 |
|
|---|
| 2094 | def OnIdle(self, event):
|
|---|
| 2095 | """GCP Map Display resized, adjust Map Windows
|
|---|
| 2096 | """
|
|---|
| 2097 | if self.GetMapToolbar():
|
|---|
| 2098 | if self.resize and self.resize + 0.2 < time.clock():
|
|---|
| 2099 | srcwidth, srcheight = self.SrcMapWindow.GetSize()
|
|---|
| 2100 | tgtwidth, tgtheight = self.TgtMapWindow.GetSize()
|
|---|
| 2101 | srcwidth = (srcwidth + tgtwidth) / 2
|
|---|
| 2102 | if self.show_target:
|
|---|
| 2103 | self._mgr.GetPane("target").Hide()
|
|---|
| 2104 | self._mgr.Update()
|
|---|
| 2105 | self._mgr.GetPane("source").BestSize((srcwidth, srcheight))
|
|---|
| 2106 | self._mgr.GetPane("target").BestSize((srcwidth, tgtheight))
|
|---|
| 2107 | if self.show_target:
|
|---|
| 2108 | self._mgr.GetPane("target").Show()
|
|---|
| 2109 | self._mgr.Update()
|
|---|
| 2110 | self.resize = False
|
|---|
| 2111 | elif self.resize:
|
|---|
| 2112 | event.RequestMore()
|
|---|
| 2113 | pass
|
|---|
| 2114 |
|
|---|
| 2115 |
|
|---|
| 2116 | class GCPList(wx.ListCtrl,
|
|---|
| 2117 | CheckListCtrlMixin,
|
|---|
| 2118 | ListCtrlAutoWidthMixin):
|
|---|
| 2119 |
|
|---|
| 2120 | def __init__(self, parent, gcp, id=wx.ID_ANY,
|
|---|
| 2121 | pos=wx.DefaultPosition, size=wx.DefaultSize,
|
|---|
| 2122 | style=wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_HRULES |
|
|---|
| 2123 | wx.LC_SINGLE_SEL):
|
|---|
| 2124 |
|
|---|
| 2125 | wx.ListCtrl.__init__(self, parent, id, pos, size, style)
|
|---|
| 2126 |
|
|---|
| 2127 | self.gcp = gcp # GCP class
|
|---|
| 2128 | self.render = True
|
|---|
| 2129 |
|
|---|
| 2130 | # Mixin settings
|
|---|
| 2131 | CheckListCtrlMixin.__init__(self)
|
|---|
| 2132 | ListCtrlAutoWidthMixin.__init__(self)
|
|---|
| 2133 | # TextEditMixin.__init__(self)
|
|---|
| 2134 |
|
|---|
| 2135 | # tracks whether list items are checked or not
|
|---|
| 2136 | self.CheckList = []
|
|---|
| 2137 |
|
|---|
| 2138 | self._Create()
|
|---|
| 2139 |
|
|---|
| 2140 | self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
|
|---|
| 2141 | self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated)
|
|---|
| 2142 | self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick)
|
|---|
| 2143 |
|
|---|
| 2144 | self.selected = wx.NOT_FOUND
|
|---|
| 2145 | self.selectedkey = -1
|
|---|
| 2146 |
|
|---|
| 2147 | def _Create(self):
|
|---|
| 2148 |
|
|---|
| 2149 | if 0:
|
|---|
| 2150 | # normal, simple columns
|
|---|
| 2151 | idx_col = 0
|
|---|
| 2152 | for col in (_('use'),
|
|---|
| 2153 | _('source E'),
|
|---|
| 2154 | _('source N'),
|
|---|
| 2155 | _('target E'),
|
|---|
| 2156 | _('target N'),
|
|---|
| 2157 | _('Forward error'),
|
|---|
| 2158 | _('Backward error')):
|
|---|
| 2159 | self.InsertColumn(idx_col, col)
|
|---|
| 2160 | idx_col += 1
|
|---|
| 2161 | else:
|
|---|
| 2162 | # the hard way: we want images on the column header
|
|---|
| 2163 | info = wx.ListItem()
|
|---|
| 2164 | info.SetMask(
|
|---|
| 2165 | wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT)
|
|---|
| 2166 | info.SetImage(-1)
|
|---|
| 2167 | info.m_format = wx.LIST_FORMAT_LEFT
|
|---|
| 2168 |
|
|---|
| 2169 | idx_col = 0
|
|---|
| 2170 | for lbl in (_('use'),
|
|---|
| 2171 | _('source E'),
|
|---|
| 2172 | _('source N'),
|
|---|
| 2173 | _('target E'),
|
|---|
| 2174 | _('target N'),
|
|---|
| 2175 | _('Forward error'),
|
|---|
| 2176 | _('Backward error')):
|
|---|
| 2177 | info.SetText(lbl)
|
|---|
| 2178 | self.InsertColumnInfo(idx_col, info)
|
|---|
| 2179 | idx_col += 1
|
|---|
| 2180 |
|
|---|
| 2181 | def LoadData(self):
|
|---|
| 2182 | """Load data into list"""
|
|---|
| 2183 | self.DeleteAllItems()
|
|---|
| 2184 |
|
|---|
| 2185 | self.render = False
|
|---|
| 2186 | if os.path.isfile(self.gcp.file['points']):
|
|---|
| 2187 | self.gcp.ReadGCPs()
|
|---|
| 2188 | else:
|
|---|
| 2189 | # 3 gcp is minimum
|
|---|
| 2190 | for i in range(3):
|
|---|
| 2191 | self.gcp.AddGCP(None)
|
|---|
| 2192 |
|
|---|
| 2193 | # select first point by default
|
|---|
| 2194 | self.selected = 0
|
|---|
| 2195 | self.selectedkey = self.GetItemData(self.selected)
|
|---|
| 2196 | self.SetItemState(self.selected,
|
|---|
| 2197 | wx.LIST_STATE_SELECTED,
|
|---|
| 2198 | wx.LIST_STATE_SELECTED)
|
|---|
| 2199 |
|
|---|
| 2200 | self.ResizeColumns()
|
|---|
| 2201 | self.render = True
|
|---|
| 2202 |
|
|---|
| 2203 | self.EnsureVisible(self.selected)
|
|---|
| 2204 |
|
|---|
| 2205 | def OnCheckItem(self, index, flag):
|
|---|
| 2206 | """Item is checked/unchecked"""
|
|---|
| 2207 |
|
|---|
| 2208 | if self.render:
|
|---|
| 2209 | # redraw points
|
|---|
| 2210 | sourceMapWin = self.gcp.SrcMapWindow
|
|---|
| 2211 | sourceMapWin.UpdateMap(render=False, renderVector=False)
|
|---|
| 2212 | if self.gcp.show_target:
|
|---|
| 2213 | targetMapWin = self.gcp.TgtMapWindow
|
|---|
| 2214 | targetMapWin.UpdateMap(render=False, renderVector=False)
|
|---|
| 2215 |
|
|---|
| 2216 | def AddGCPItem(self):
|
|---|
| 2217 | """
|
|---|
| 2218 | Appends an item to GCP list
|
|---|
| 2219 | """
|
|---|
| 2220 | self.selectedkey = self.GetItemCount() + 1
|
|---|
| 2221 |
|
|---|
| 2222 | self.Append([str(self.selectedkey), # GCP number
|
|---|
| 2223 | '0.0', # source E
|
|---|
| 2224 | '0.0', # source N
|
|---|
| 2225 | '0.0', # target E
|
|---|
| 2226 | '0.0', # target N
|
|---|
| 2227 | '', # forward error
|
|---|
| 2228 | '']) # backward error
|
|---|
| 2229 |
|
|---|
| 2230 | self.selected = self.GetItemCount() - 1
|
|---|
| 2231 | self.SetItemData(self.selected, self.selectedkey)
|
|---|
| 2232 |
|
|---|
| 2233 | self.SetItemState(self.selected,
|
|---|
| 2234 | wx.LIST_STATE_SELECTED,
|
|---|
| 2235 | wx.LIST_STATE_SELECTED)
|
|---|
| 2236 |
|
|---|
| 2237 | self.ResizeColumns()
|
|---|
| 2238 |
|
|---|
| 2239 | self.gcp.pointsToDrawSrc.AddItem(
|
|---|
| 2240 | coords=[0, 0], label=str(self.selectedkey))
|
|---|
| 2241 | self.gcp.pointsToDrawTgt.AddItem(
|
|---|
| 2242 | coords=[0, 0], label=str(self.selectedkey))
|
|---|
| 2243 |
|
|---|
| 2244 | self.EnsureVisible(self.selected)
|
|---|
| 2245 |
|
|---|
| 2246 | return self.selected
|
|---|
| 2247 |
|
|---|
| 2248 | def DeleteGCPItem(self):
|
|---|
| 2249 | """Deletes selected item in GCP list.
|
|---|
| 2250 | """
|
|---|
| 2251 | if self.selected == wx.NOT_FOUND:
|
|---|
| 2252 | return
|
|---|
| 2253 |
|
|---|
| 2254 | key = self.GetItemData(self.selected)
|
|---|
| 2255 | self.DeleteItem(self.selected)
|
|---|
| 2256 |
|
|---|
| 2257 | if self.selected != wx.NOT_FOUND:
|
|---|
| 2258 | item = self.gcp.pointsToDrawSrc.GetItem(key - 1)
|
|---|
| 2259 | self.gcp.pointsToDrawSrc.DeleteItem(item)
|
|---|
| 2260 |
|
|---|
| 2261 | item = self.gcp.pointsToDrawTgt.GetItem(key - 1)
|
|---|
| 2262 | self.gcp.pointsToDrawTgt.DeleteItem(item)
|
|---|
| 2263 |
|
|---|
| 2264 | return key
|
|---|
| 2265 |
|
|---|
| 2266 | def ResizeColumns(self):
|
|---|
| 2267 | """Resize columns"""
|
|---|
| 2268 | minWidth = [90, 120]
|
|---|
| 2269 | for i in range(self.GetColumnCount()):
|
|---|
| 2270 | self.SetColumnWidth(i, wx.LIST_AUTOSIZE)
|
|---|
| 2271 | # first column is checkbox, don't set to minWidth
|
|---|
| 2272 | if i > 0 and self.GetColumnWidth(i) < minWidth[i > 4]:
|
|---|
| 2273 | self.SetColumnWidth(i, minWidth[i > 4])
|
|---|
| 2274 |
|
|---|
| 2275 | self.SendSizeEvent()
|
|---|
| 2276 |
|
|---|
| 2277 | def GetSelected(self):
|
|---|
| 2278 | """Get index of selected item"""
|
|---|
| 2279 | return self.selected
|
|---|
| 2280 |
|
|---|
| 2281 | def OnItemSelected(self, event):
|
|---|
| 2282 | """Item selected
|
|---|
| 2283 | """
|
|---|
| 2284 | if self.render and self.selected != event.GetIndex():
|
|---|
| 2285 | self.selected = event.GetIndex()
|
|---|
| 2286 | self.selectedkey = self.GetItemData(self.selected)
|
|---|
| 2287 | sourceMapWin = self.gcp.SrcMapWindow
|
|---|
| 2288 | sourceMapWin.UpdateMap(render=False, renderVector=False)
|
|---|
| 2289 | if self.gcp.show_target:
|
|---|
| 2290 | targetMapWin = self.gcp.TgtMapWindow
|
|---|
| 2291 | targetMapWin.UpdateMap(render=False, renderVector=False)
|
|---|
| 2292 | event.Skip()
|
|---|
| 2293 |
|
|---|
| 2294 | def OnItemActivated(self, event):
|
|---|
| 2295 | """
|
|---|
| 2296 | When item double clicked, open editor to update coordinate values
|
|---|
| 2297 | """
|
|---|
| 2298 | coords = []
|
|---|
| 2299 | index = event.GetIndex()
|
|---|
| 2300 | key = self.GetItemData(index)
|
|---|
| 2301 | changed = False
|
|---|
| 2302 |
|
|---|
| 2303 | for i in range(1, 5):
|
|---|
| 2304 | coords.append(self.GetItem(index, i).GetText())
|
|---|
| 2305 |
|
|---|
| 2306 | dlg = EditGCP(parent=self, id=wx.ID_ANY, data=coords, gcpno=key)
|
|---|
| 2307 |
|
|---|
| 2308 | if dlg.ShowModal() == wx.ID_OK:
|
|---|
| 2309 | values = dlg.GetValues() # string
|
|---|
| 2310 |
|
|---|
| 2311 | if len(values) == 0:
|
|---|
| 2312 | GError(parent=self, message=_(
|
|---|
| 2313 | "Invalid coordinate value. Operation canceled."))
|
|---|
| 2314 | else:
|
|---|
| 2315 | for i in range(len(values)):
|
|---|
| 2316 | if values[i] != coords[i]:
|
|---|
| 2317 | self.SetStringItem(index, i + 1, values[i])
|
|---|
| 2318 | changed = True
|
|---|
| 2319 |
|
|---|
| 2320 | if changed:
|
|---|
| 2321 | # reset RMS and update mapcoordlist
|
|---|
| 2322 | self.SetStringItem(index, 5, '')
|
|---|
| 2323 | self.SetStringItem(index, 6, '')
|
|---|
| 2324 | key = self.GetItemData(index)
|
|---|
| 2325 | self.gcp.mapcoordlist[key] = [key,
|
|---|
| 2326 | float(values[0]),
|
|---|
| 2327 | float(values[1]),
|
|---|
| 2328 | float(values[2]),
|
|---|
| 2329 | float(values[3]),
|
|---|
| 2330 | 0.0,
|
|---|
| 2331 | 0.0]
|
|---|
| 2332 |
|
|---|
| 2333 | self.gcp.pointsToDrawSrc.GetItem(
|
|---|
| 2334 | key - 1).SetCoords([float(values[0]), float(values[1])])
|
|---|
| 2335 | self.gcp.pointsToDrawTgt.GetItem(
|
|---|
| 2336 | key - 1).SetCoords([float(values[2]), float(values[3])])
|
|---|
| 2337 | self.gcp.UpdateColours()
|
|---|
| 2338 |
|
|---|
| 2339 | def OnColClick(self, event):
|
|---|
| 2340 | """ListCtrl forgets selected item..."""
|
|---|
| 2341 | self.selected = self.FindItemData(-1, self.selectedkey)
|
|---|
| 2342 | self.SetItemState(self.selected,
|
|---|
| 2343 | wx.LIST_STATE_SELECTED,
|
|---|
| 2344 | wx.LIST_STATE_SELECTED)
|
|---|
| 2345 |
|
|---|
| 2346 | event.Skip()
|
|---|
| 2347 |
|
|---|
| 2348 |
|
|---|
| 2349 | class VectGroup(wx.Dialog):
|
|---|
| 2350 | """Dialog to create a vector group (VREF file) for georectifying
|
|---|
| 2351 |
|
|---|
| 2352 | .. todo::
|
|---|
| 2353 | Replace by g.group
|
|---|
| 2354 | """
|
|---|
| 2355 |
|
|---|
| 2356 | def __init__(self, parent, id, grassdb, location, mapset, group,
|
|---|
| 2357 | style=wx.DEFAULT_DIALOG_STYLE):
|
|---|
| 2358 |
|
|---|
| 2359 | wx.Dialog.__init__(self, parent, id, style=style,
|
|---|
| 2360 | title=_("Create vector map group"))
|
|---|
| 2361 |
|
|---|
| 2362 | self.grassdatabase = grassdb
|
|---|
| 2363 | self.xylocation = location
|
|---|
| 2364 | self.xymapset = mapset
|
|---|
| 2365 | self.xygroup = group
|
|---|
| 2366 |
|
|---|
| 2367 | #
|
|---|
| 2368 | # get list of valid vector directories
|
|---|
| 2369 | #
|
|---|
| 2370 | vectlist = os.listdir(os.path.join(self.grassdatabase,
|
|---|
| 2371 | self.xylocation,
|
|---|
| 2372 | self.xymapset,
|
|---|
| 2373 | 'vector'))
|
|---|
| 2374 | for dir in vectlist:
|
|---|
| 2375 | if not os.path.isfile(os.path.join(self.grassdatabase,
|
|---|
| 2376 | self.xylocation,
|
|---|
| 2377 | self.xymapset,
|
|---|
| 2378 | 'vector',
|
|---|
| 2379 | dir,
|
|---|
| 2380 | 'coor')):
|
|---|
| 2381 | vectlist.remove(dir)
|
|---|
| 2382 |
|
|---|
| 2383 | utils.ListSortLower(vectlist)
|
|---|
| 2384 |
|
|---|
| 2385 | # path to vref file
|
|---|
| 2386 | self.vgrpfile = os.path.join(self.grassdatabase,
|
|---|
| 2387 | self.xylocation,
|
|---|
| 2388 | self.xymapset,
|
|---|
| 2389 | 'group',
|
|---|
| 2390 | self.xygroup,
|
|---|
| 2391 | 'VREF')
|
|---|
| 2392 |
|
|---|
| 2393 | #
|
|---|
| 2394 | # buttons
|
|---|
| 2395 | #
|
|---|
| 2396 | self.btnCancel = Button(parent=self,
|
|---|
| 2397 | id=wx.ID_CANCEL)
|
|---|
| 2398 | self.btnOK = Button(parent=self,
|
|---|
| 2399 | id=wx.ID_OK)
|
|---|
| 2400 | self.btnOK.SetDefault()
|
|---|
| 2401 |
|
|---|
| 2402 | #
|
|---|
| 2403 | # list of vector maps
|
|---|
| 2404 | #
|
|---|
| 2405 | self.listMap = CheckListBox(parent=self, id=wx.ID_ANY,
|
|---|
| 2406 | choices=vectlist)
|
|---|
| 2407 |
|
|---|
| 2408 | if os.path.isfile(self.vgrpfile):
|
|---|
| 2409 | f = open(self.vgrpfile)
|
|---|
| 2410 | try:
|
|---|
| 2411 | checked = []
|
|---|
| 2412 | for line in f.readlines():
|
|---|
| 2413 | line = line.replace('\n', '')
|
|---|
| 2414 | if len(line) < 1:
|
|---|
| 2415 | continue
|
|---|
| 2416 | checked.append(line)
|
|---|
| 2417 | self.listMap.SetCheckedStrings(checked)
|
|---|
| 2418 | finally:
|
|---|
| 2419 | f.close()
|
|---|
| 2420 |
|
|---|
| 2421 | line = wx.StaticLine(parent=self,
|
|---|
| 2422 | id=wx.ID_ANY, size=(20, -1),
|
|---|
| 2423 | style=wx.LI_HORIZONTAL)
|
|---|
| 2424 |
|
|---|
| 2425 | #
|
|---|
| 2426 | # layout
|
|---|
| 2427 | #
|
|---|
| 2428 | sizer = wx.BoxSizer(wx.VERTICAL)
|
|---|
| 2429 |
|
|---|
| 2430 | box = wx.BoxSizer(wx.HORIZONTAL)
|
|---|
| 2431 | box.Add(
|
|---|
| 2432 | StaticText(
|
|---|
| 2433 | parent=self,
|
|---|
| 2434 | id=wx.ID_ANY,
|
|---|
| 2435 | label=_('Select vector map(s) to add to group:')),
|
|---|
| 2436 | flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT,
|
|---|
| 2437 | border=5)
|
|---|
| 2438 |
|
|---|
| 2439 | box.Add(self.listMap,
|
|---|
| 2440 | flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT,
|
|---|
| 2441 | border=5)
|
|---|
| 2442 |
|
|---|
| 2443 | sizer.Add(box, flag=wx.ALIGN_RIGHT | wx.ALL,
|
|---|
| 2444 | border=3)
|
|---|
| 2445 |
|
|---|
| 2446 | sizer.Add(line, proportion=0,
|
|---|
| 2447 | flag=wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT,
|
|---|
| 2448 | border=5)
|
|---|
| 2449 |
|
|---|
| 2450 | # buttons
|
|---|
| 2451 | btnSizer = wx.StdDialogButtonSizer()
|
|---|
| 2452 | btnSizer.AddButton(self.btnCancel)
|
|---|
| 2453 | btnSizer.AddButton(self.btnOK)
|
|---|
| 2454 | btnSizer.Realize()
|
|---|
| 2455 |
|
|---|
| 2456 | sizer.Add(btnSizer, proportion=0,
|
|---|
| 2457 | flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER,
|
|---|
| 2458 | border=5)
|
|---|
| 2459 |
|
|---|
| 2460 | self.SetSizer(sizer)
|
|---|
| 2461 | sizer.Fit(self)
|
|---|
| 2462 | self.Layout()
|
|---|
| 2463 |
|
|---|
| 2464 | def MakeVGroup(self):
|
|---|
| 2465 | """Create VREF file"""
|
|---|
| 2466 | vgrouplist = []
|
|---|
| 2467 | for item in range(self.listMap.GetCount()):
|
|---|
| 2468 | if not self.listMap.IsChecked(item):
|
|---|
| 2469 | continue
|
|---|
| 2470 | vgrouplist.append(
|
|---|
| 2471 | self.listMap.GetString(item) +
|
|---|
| 2472 | '@' +
|
|---|
| 2473 | self.xymapset)
|
|---|
| 2474 |
|
|---|
| 2475 | dirname = os.path.dirname(self.vgrpfile)
|
|---|
| 2476 |
|
|---|
| 2477 | if not os.path.exists(dirname):
|
|---|
| 2478 | os.makedirs(dirname)
|
|---|
| 2479 |
|
|---|
| 2480 | f = open(self.vgrpfile, mode='w')
|
|---|
| 2481 | try:
|
|---|
| 2482 | for vect in vgrouplist:
|
|---|
| 2483 | f.write(vect + '\n')
|
|---|
| 2484 | finally:
|
|---|
| 2485 | f.close()
|
|---|
| 2486 |
|
|---|
| 2487 |
|
|---|
| 2488 | class EditGCP(wx.Dialog):
|
|---|
| 2489 |
|
|---|
| 2490 | def __init__(self, parent, data, gcpno, id=wx.ID_ANY,
|
|---|
| 2491 | title=_("Edit GCP"),
|
|---|
| 2492 | style=wx.DEFAULT_DIALOG_STYLE):
|
|---|
| 2493 | """Dialog for editing GPC and map coordinates in list control"""
|
|---|
| 2494 |
|
|---|
| 2495 | wx.Dialog.__init__(self, parent, id, title=title, style=style)
|
|---|
| 2496 |
|
|---|
| 2497 | panel = wx.Panel(parent=self)
|
|---|
| 2498 |
|
|---|
| 2499 | sizer = wx.BoxSizer(wx.VERTICAL)
|
|---|
| 2500 |
|
|---|
| 2501 | box = StaticBox(
|
|---|
| 2502 | parent=panel, id=wx.ID_ANY, label=" %s %s " %
|
|---|
| 2503 | (_("Ground Control Point No."), str(gcpno)))
|
|---|
| 2504 | boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
|
|---|
| 2505 |
|
|---|
| 2506 | # source coordinates
|
|---|
| 2507 | gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
|
|---|
| 2508 |
|
|---|
| 2509 | self.xcoord = TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
|
|---|
| 2510 | self.ycoord = TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
|
|---|
| 2511 | self.ecoord = TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
|
|---|
| 2512 | self.ncoord = TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1))
|
|---|
| 2513 |
|
|---|
| 2514 | # swap source N, target E
|
|---|
| 2515 | tmp_coord = data[1]
|
|---|
| 2516 | data[1] = data[2]
|
|---|
| 2517 | data[2] = tmp_coord
|
|---|
| 2518 |
|
|---|
| 2519 | row = 0
|
|---|
| 2520 | col = 0
|
|---|
| 2521 | idx = 0
|
|---|
| 2522 | for label, win in ((_("source E:"), self.xcoord),
|
|---|
| 2523 | (_("target E:"), self.ecoord),
|
|---|
| 2524 | (_("source N:"), self.ycoord),
|
|---|
| 2525 | (_("target N:"), self.ncoord)):
|
|---|
| 2526 | label = StaticText(parent=panel, id=wx.ID_ANY,
|
|---|
| 2527 | label=label)
|
|---|
| 2528 | gridSizer.Add(label,
|
|---|
| 2529 | flag=wx.ALIGN_CENTER_VERTICAL,
|
|---|
| 2530 | pos=(row, col))
|
|---|
| 2531 |
|
|---|
| 2532 | col += 1
|
|---|
| 2533 | win.SetValue(str(data[idx]))
|
|---|
| 2534 |
|
|---|
| 2535 | gridSizer.Add(win,
|
|---|
| 2536 | pos=(row, col))
|
|---|
| 2537 |
|
|---|
| 2538 | col += 1
|
|---|
| 2539 | idx += 1
|
|---|
| 2540 |
|
|---|
| 2541 | if col > 3:
|
|---|
| 2542 | row += 1
|
|---|
| 2543 | col = 0
|
|---|
| 2544 |
|
|---|
| 2545 | boxSizer.Add(gridSizer, proportion=1,
|
|---|
| 2546 | flag=wx.EXPAND | wx.ALL, border=5)
|
|---|
| 2547 |
|
|---|
| 2548 | sizer.Add(boxSizer, proportion=1,
|
|---|
| 2549 | flag=wx.EXPAND | wx.ALL, border=5)
|
|---|
| 2550 |
|
|---|
| 2551 | #
|
|---|
| 2552 | # buttons
|
|---|
| 2553 | #
|
|---|
| 2554 | self.btnCancel = Button(panel, wx.ID_CANCEL)
|
|---|
| 2555 | self.btnOk = Button(panel, wx.ID_OK)
|
|---|
| 2556 | self.btnOk.SetDefault()
|
|---|
| 2557 |
|
|---|
| 2558 | btnSizer = wx.StdDialogButtonSizer()
|
|---|
| 2559 | btnSizer.AddButton(self.btnCancel)
|
|---|
| 2560 | btnSizer.AddButton(self.btnOk)
|
|---|
| 2561 | btnSizer.Realize()
|
|---|
| 2562 |
|
|---|
| 2563 | sizer.Add(btnSizer, proportion=0,
|
|---|
| 2564 | flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
|
|---|
| 2565 |
|
|---|
| 2566 | panel.SetSizer(sizer)
|
|---|
| 2567 | sizer.Fit(self)
|
|---|
| 2568 |
|
|---|
| 2569 | def GetValues(self, columns=None):
|
|---|
| 2570 | """Return list of values (as strings).
|
|---|
| 2571 | """
|
|---|
| 2572 | valuelist = []
|
|---|
| 2573 | try:
|
|---|
| 2574 | float(self.xcoord.GetValue())
|
|---|
| 2575 | float(self.ycoord.GetValue())
|
|---|
| 2576 | float(self.ecoord.GetValue())
|
|---|
| 2577 | float(self.ncoord.GetValue())
|
|---|
| 2578 | except ValueError:
|
|---|
| 2579 | return valuelist
|
|---|
| 2580 |
|
|---|
| 2581 | valuelist.append(self.xcoord.GetValue())
|
|---|
| 2582 | valuelist.append(self.ycoord.GetValue())
|
|---|
| 2583 | valuelist.append(self.ecoord.GetValue())
|
|---|
| 2584 | valuelist.append(self.ncoord.GetValue())
|
|---|
| 2585 |
|
|---|
| 2586 | return valuelist
|
|---|
| 2587 |
|
|---|
| 2588 |
|
|---|
| 2589 | class GrSettingsDialog(wx.Dialog):
|
|---|
| 2590 |
|
|---|
| 2591 | def __init__(
|
|---|
| 2592 | self, parent, id, giface, title, pos=wx.DefaultPosition,
|
|---|
| 2593 | size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE):
|
|---|
| 2594 | wx.Dialog.__init__(self, parent, id, title, pos, size, style)
|
|---|
| 2595 | """
|
|---|
| 2596 | Dialog to set profile text options: font, title
|
|---|
| 2597 | and font size, axis labels and font size
|
|---|
| 2598 | """
|
|---|
| 2599 | #
|
|---|
| 2600 | # initialize variables
|
|---|
| 2601 | #
|
|---|
| 2602 | self.parent = parent
|
|---|
| 2603 | self.new_src_map = src_map
|
|---|
| 2604 | self.new_tgt_map = {'raster': tgt_map['raster'],
|
|---|
| 2605 | 'vector': tgt_map['vector']}
|
|---|
| 2606 | self.sdfactor = 0
|
|---|
| 2607 |
|
|---|
| 2608 | self.symbol = {}
|
|---|
| 2609 |
|
|---|
| 2610 | self.methods = ["nearest",
|
|---|
| 2611 | "linear",
|
|---|
| 2612 | "linear_f",
|
|---|
| 2613 | "cubic",
|
|---|
| 2614 | "cubic_f",
|
|---|
| 2615 | "lanczos",
|
|---|
| 2616 | "lanczos_f"]
|
|---|
| 2617 |
|
|---|
| 2618 | # notebook
|
|---|
| 2619 | notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
|
|---|
| 2620 | self.__CreateSymbologyPage(notebook)
|
|---|
| 2621 | self.__CreateRectificationPage(notebook)
|
|---|
| 2622 |
|
|---|
| 2623 | # buttons
|
|---|
| 2624 | btnSave = Button(self, wx.ID_SAVE)
|
|---|
| 2625 | btnApply = Button(self, wx.ID_APPLY)
|
|---|
| 2626 | btnClose = Button(self, wx.ID_CLOSE)
|
|---|
| 2627 | btnApply.SetDefault()
|
|---|
| 2628 |
|
|---|
| 2629 | # bindings
|
|---|
| 2630 | btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
|
|---|
| 2631 | btnApply.SetToolTip(_("Apply changes for the current session"))
|
|---|
| 2632 | btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
|
|---|
| 2633 | btnSave.SetToolTip(
|
|---|
| 2634 | _("Apply and save changes to user settings file (default for next sessions)"))
|
|---|
| 2635 | btnClose.Bind(wx.EVT_BUTTON, self.OnClose)
|
|---|
| 2636 | btnClose.SetToolTip(_("Close dialog"))
|
|---|
| 2637 |
|
|---|
| 2638 | # sizers
|
|---|
| 2639 | btnSizer = wx.BoxSizer(wx.HORIZONTAL)
|
|---|
| 2640 | btnSizer.Add(btnApply, flag=wx.LEFT | wx.RIGHT, border=5)
|
|---|
| 2641 | btnSizer.Add(btnSave, flag=wx.LEFT | wx.RIGHT, border=5)
|
|---|
| 2642 | btnSizer.Add(btnClose, flag=wx.LEFT | wx.RIGHT, border=5)
|
|---|
| 2643 |
|
|---|
| 2644 | # sizers
|
|---|
| 2645 | mainSizer = wx.BoxSizer(wx.VERTICAL)
|
|---|
| 2646 | mainSizer.Add(
|
|---|
| 2647 | notebook,
|
|---|
| 2648 | proportion=1,
|
|---|
| 2649 | flag=wx.EXPAND | wx.ALL,
|
|---|
| 2650 | border=5)
|
|---|
| 2651 | mainSizer.Add(btnSizer, proportion=0,
|
|---|
| 2652 | flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
|
|---|
| 2653 | # flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
|
|---|
| 2654 |
|
|---|
| 2655 | self.SetSizer(mainSizer)
|
|---|
| 2656 | mainSizer.Fit(self)
|
|---|
| 2657 |
|
|---|
| 2658 | def __CreateSymbologyPage(self, notebook):
|
|---|
| 2659 | """Create notebook page with symbology settings"""
|
|---|
| 2660 |
|
|---|
| 2661 | panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
|
|---|
| 2662 | notebook.AddPage(page=panel, text=_("Symbology"))
|
|---|
| 2663 |
|
|---|
| 2664 | sizer = wx.BoxSizer(wx.VERTICAL)
|
|---|
| 2665 |
|
|---|
| 2666 | rmsgridSizer = wx.GridBagSizer(vgap=5, hgap=5)
|
|---|
| 2667 |
|
|---|
| 2668 | # highlight only highest forward RMS error
|
|---|
| 2669 | self.highlighthighest = wx.CheckBox(
|
|---|
| 2670 | parent=panel, id=wx.ID_ANY,
|
|---|
| 2671 | label=_("Highlight highest RMS error only"))
|
|---|
| 2672 | hh = UserSettings.Get(group='gcpman', key='rms', subkey='highestonly')
|
|---|
| 2673 | self.highlighthighest.SetValue(hh)
|
|---|
| 2674 | rmsgridSizer.Add(
|
|---|
| 2675 | self.highlighthighest,
|
|---|
| 2676 | flag=wx.ALIGN_CENTER_VERTICAL,
|
|---|
| 2677 | pos=(
|
|---|
| 2678 | 0,
|
|---|
| 2679 | 0))
|
|---|
| 2680 |
|
|---|
| 2681 | # RMS forward error threshold
|
|---|
| 2682 | rmslabel = StaticText(
|
|---|
| 2683 | parent=panel, id=wx.ID_ANY,
|
|---|
| 2684 | label=_("Highlight RMS error > M + SD * factor:"))
|
|---|
| 2685 | rmslabel.SetToolTip(
|
|---|
| 2686 | wx.ToolTip(
|
|---|
| 2687 | _(
|
|---|
| 2688 | "Highlight GCPs with an RMS error larger than \n"
|
|---|
| 2689 | "mean + standard deviation * given factor. \n"
|
|---|
| 2690 | "Recommended values for this factor are between 1 and 2.")))
|
|---|
| 2691 | rmsgridSizer.Add(
|
|---|
| 2692 | rmslabel,
|
|---|
| 2693 | flag=wx.ALIGN_CENTER_VERTICAL,
|
|---|
| 2694 | pos=(
|
|---|
| 2695 | 1,
|
|---|
| 2696 | 0))
|
|---|
| 2697 | sdfactor = UserSettings.Get(
|
|---|
| 2698 | group='gcpman', key='rms', subkey='sdfactor')
|
|---|
| 2699 | self.rmsWin = TextCtrl(parent=panel, id=wx.ID_ANY,
|
|---|
| 2700 | size=(70, -1), style=wx.TE_NOHIDESEL)
|
|---|
| 2701 | self.rmsWin.SetValue("%s" % str(sdfactor))
|
|---|
| 2702 | if (self.parent.highest_only == True):
|
|---|
| 2703 | self.rmsWin.Disable()
|
|---|
| 2704 |
|
|---|
| 2705 | self.symbol['sdfactor'] = self.rmsWin.GetId()
|
|---|
| 2706 | rmsgridSizer.Add(self.rmsWin, flag=wx.ALIGN_RIGHT, pos=(1, 1))
|
|---|
| 2707 | rmsgridSizer.AddGrowableCol(1)
|
|---|
| 2708 | sizer.Add(rmsgridSizer, flag=wx.EXPAND | wx.ALL, border=5)
|
|---|
| 2709 |
|
|---|
| 2710 | box = StaticBox(parent=panel, id=wx.ID_ANY,
|
|---|
| 2711 | label=" %s " % _("Symbol settings"))
|
|---|
| 2712 | boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
|
|---|
| 2713 | gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
|
|---|
| 2714 |
|
|---|
| 2715 | #
|
|---|
| 2716 | # general symbol color
|
|---|
| 2717 | #
|
|---|
| 2718 | row = 0
|
|---|
| 2719 | label = StaticText(parent=panel, id=wx.ID_ANY, label=_("Color:"))
|
|---|
| 2720 | gridSizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
|
|---|
| 2721 | col = UserSettings.Get(group='gcpman', key='symbol', subkey='color')
|
|---|
| 2722 | colWin = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
|
|---|
| 2723 | colour=wx.Colour(col[0],
|
|---|
| 2724 | col[1],
|
|---|
| 2725 | col[2],
|
|---|
| 2726 | 255))
|
|---|
| 2727 | self.symbol['color'] = colWin.GetId()
|
|---|
| 2728 | gridSizer.Add(colWin,
|
|---|
| 2729 | flag=wx.ALIGN_RIGHT,
|
|---|
| 2730 | pos=(row, 1))
|
|---|
| 2731 |
|
|---|
| 2732 | #
|
|---|
| 2733 | # symbol color for high forward RMS error
|
|---|
| 2734 | #
|
|---|
| 2735 | row += 1
|
|---|
| 2736 | label = StaticText(
|
|---|
| 2737 | parent=panel,
|
|---|
| 2738 | id=wx.ID_ANY,
|
|---|
| 2739 | label=_("Color for high RMS error:"))
|
|---|
| 2740 | gridSizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
|
|---|
| 2741 | hcol = UserSettings.Get(group='gcpman', key='symbol', subkey='hcolor')
|
|---|
| 2742 | hcolWin = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
|
|---|
| 2743 | colour=wx.Colour(hcol[0],
|
|---|
| 2744 | hcol[1],
|
|---|
| 2745 | hcol[2],
|
|---|
| 2746 | 255))
|
|---|
| 2747 | self.symbol['hcolor'] = hcolWin.GetId()
|
|---|
| 2748 | gridSizer.Add(hcolWin,
|
|---|
| 2749 | flag=wx.ALIGN_RIGHT,
|
|---|
| 2750 | pos=(row, 1))
|
|---|
| 2751 |
|
|---|
| 2752 | #
|
|---|
| 2753 | # symbol color for selected GCP
|
|---|
| 2754 | #
|
|---|
| 2755 | row += 1
|
|---|
| 2756 | label = StaticText(
|
|---|
| 2757 | parent=panel,
|
|---|
| 2758 | id=wx.ID_ANY,
|
|---|
| 2759 | label=_("Color for selected GCP:"))
|
|---|
| 2760 | gridSizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
|
|---|
| 2761 | scol = UserSettings.Get(group='gcpman', key='symbol', subkey='scolor')
|
|---|
| 2762 | scolWin = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
|
|---|
| 2763 | colour=wx.Colour(scol[0],
|
|---|
| 2764 | scol[1],
|
|---|
| 2765 | scol[2],
|
|---|
| 2766 | 255))
|
|---|
| 2767 | self.symbol['scolor'] = scolWin.GetId()
|
|---|
| 2768 | gridSizer.Add(scolWin,
|
|---|
| 2769 | flag=wx.ALIGN_RIGHT,
|
|---|
| 2770 | pos=(row, 1))
|
|---|
| 2771 |
|
|---|
| 2772 | #
|
|---|
| 2773 | # symbol color for unused GCP
|
|---|
| 2774 | #
|
|---|
| 2775 | row += 1
|
|---|
| 2776 | label = StaticText(
|
|---|
| 2777 | parent=panel,
|
|---|
| 2778 | id=wx.ID_ANY,
|
|---|
| 2779 | label=_("Color for unused GCPs:"))
|
|---|
| 2780 | gridSizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
|
|---|
| 2781 | ucol = UserSettings.Get(group='gcpman', key='symbol', subkey='ucolor')
|
|---|
| 2782 | ucolWin = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
|
|---|
| 2783 | colour=wx.Colour(ucol[0],
|
|---|
| 2784 | ucol[1],
|
|---|
| 2785 | ucol[2],
|
|---|
| 2786 | 255))
|
|---|
| 2787 | self.symbol['ucolor'] = ucolWin.GetId()
|
|---|
| 2788 | gridSizer.Add(ucolWin,
|
|---|
| 2789 | flag=wx.ALIGN_RIGHT,
|
|---|
| 2790 | pos=(row, 1))
|
|---|
| 2791 |
|
|---|
| 2792 | # show unused GCPs
|
|---|
| 2793 | row += 1
|
|---|
| 2794 | self.showunused = wx.CheckBox(parent=panel, id=wx.ID_ANY,
|
|---|
| 2795 | label=_("Show unused GCPs"))
|
|---|
| 2796 | shuu = UserSettings.Get(group='gcpman', key='symbol', subkey='unused')
|
|---|
| 2797 | self.showunused.SetValue(shuu)
|
|---|
| 2798 | gridSizer.Add(
|
|---|
| 2799 | self.showunused,
|
|---|
| 2800 | flag=wx.ALIGN_CENTER_VERTICAL,
|
|---|
| 2801 | pos=(
|
|---|
| 2802 | row,
|
|---|
| 2803 | 0))
|
|---|
| 2804 |
|
|---|
| 2805 | #
|
|---|
| 2806 | # symbol size
|
|---|
| 2807 | #
|
|---|
| 2808 | row += 1
|
|---|
| 2809 | label = StaticText(
|
|---|
| 2810 | parent=panel,
|
|---|
| 2811 | id=wx.ID_ANY,
|
|---|
| 2812 | label=_("Symbol size:"))
|
|---|
| 2813 | gridSizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
|
|---|
| 2814 | symsize = int(
|
|---|
| 2815 | UserSettings.Get(
|
|---|
| 2816 | group='gcpman',
|
|---|
| 2817 | key='symbol',
|
|---|
| 2818 | subkey='size'))
|
|---|
| 2819 | sizeWin = SpinCtrl(parent=panel, id=wx.ID_ANY,
|
|---|
| 2820 | min=1, max=20)
|
|---|
| 2821 | sizeWin.SetValue(symsize)
|
|---|
| 2822 | self.symbol['size'] = sizeWin.GetId()
|
|---|
| 2823 | gridSizer.Add(sizeWin,
|
|---|
| 2824 | flag=wx.ALIGN_RIGHT,
|
|---|
| 2825 | pos=(row, 1))
|
|---|
| 2826 |
|
|---|
| 2827 | #
|
|---|
| 2828 | # symbol width
|
|---|
| 2829 | #
|
|---|
| 2830 | row += 1
|
|---|
| 2831 | label = StaticText(
|
|---|
| 2832 | parent=panel,
|
|---|
| 2833 | id=wx.ID_ANY,
|
|---|
| 2834 | label=_("Line width:"))
|
|---|
| 2835 | gridSizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
|
|---|
| 2836 | width = int(
|
|---|
| 2837 | UserSettings.Get(
|
|---|
| 2838 | group='gcpman',
|
|---|
| 2839 | key='symbol',
|
|---|
| 2840 | subkey='width'))
|
|---|
| 2841 | widWin = SpinCtrl(parent=panel, id=wx.ID_ANY,
|
|---|
| 2842 | min=1, max=10)
|
|---|
| 2843 | widWin.SetValue(width)
|
|---|
| 2844 | self.symbol['width'] = widWin.GetId()
|
|---|
| 2845 | gridSizer.Add(widWin,
|
|---|
| 2846 | flag=wx.ALIGN_RIGHT,
|
|---|
| 2847 | pos=(row, 1))
|
|---|
| 2848 | gridSizer.AddGrowableCol(1)
|
|---|
| 2849 |
|
|---|
| 2850 | boxSizer.Add(gridSizer, flag=wx.EXPAND)
|
|---|
| 2851 | sizer.Add(boxSizer, flag=wx.EXPAND | wx.ALL, border=5)
|
|---|
| 2852 |
|
|---|
| 2853 | #
|
|---|
| 2854 | # maps to display
|
|---|
| 2855 | #
|
|---|
| 2856 | # source map to display
|
|---|
| 2857 | self.srcselection = Select(
|
|---|
| 2858 | panel,
|
|---|
| 2859 | id=wx.ID_ANY,
|
|---|
| 2860 | size=globalvar.DIALOG_GSELECT_SIZE,
|
|---|
| 2861 | type='maptype',
|
|---|
| 2862 | updateOnPopup=False)
|
|---|
| 2863 | self.parent.grwiz.SwitchEnv('source')
|
|---|
| 2864 | self.srcselection.SetElementList(maptype)
|
|---|
| 2865 | # filter out all maps not in group
|
|---|
| 2866 | self.srcselection.tcp.GetElementList(elements=self.parent.src_maps)
|
|---|
| 2867 |
|
|---|
| 2868 | # target map(s) to display
|
|---|
| 2869 | self.parent.grwiz.SwitchEnv('target')
|
|---|
| 2870 | self.tgtrastselection = Select(
|
|---|
| 2871 | panel, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE,
|
|---|
| 2872 | type='raster', updateOnPopup=False)
|
|---|
| 2873 | self.tgtrastselection.SetElementList('cell')
|
|---|
| 2874 | self.tgtrastselection.GetElementList()
|
|---|
| 2875 |
|
|---|
| 2876 | self.tgtvectselection = Select(
|
|---|
| 2877 | panel, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE,
|
|---|
| 2878 | type='vector', updateOnPopup=False)
|
|---|
| 2879 | self.tgtvectselection.SetElementList('vector')
|
|---|
| 2880 | self.tgtvectselection.GetElementList()
|
|---|
| 2881 |
|
|---|
| 2882 | sizer.Add(
|
|---|
| 2883 | StaticText(
|
|---|
| 2884 | parent=panel,
|
|---|
| 2885 | id=wx.ID_ANY,
|
|---|
| 2886 | label=_('Select source map to display:')),
|
|---|
| 2887 | proportion=0,
|
|---|
| 2888 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 2889 | border=5)
|
|---|
| 2890 | sizer.Add(
|
|---|
| 2891 | self.srcselection,
|
|---|
| 2892 | proportion=0,
|
|---|
| 2893 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 2894 | border=5)
|
|---|
| 2895 | self.srcselection.SetValue(src_map)
|
|---|
| 2896 | sizer.Add(
|
|---|
| 2897 | StaticText(
|
|---|
| 2898 | parent=panel,
|
|---|
| 2899 | id=wx.ID_ANY,
|
|---|
| 2900 | label=_('Select target raster map to display:')),
|
|---|
| 2901 | proportion=0,
|
|---|
| 2902 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 2903 | border=5)
|
|---|
| 2904 | sizer.Add(
|
|---|
| 2905 | self.tgtrastselection,
|
|---|
| 2906 | proportion=0,
|
|---|
| 2907 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 2908 | border=5)
|
|---|
| 2909 | self.tgtrastselection.SetValue(tgt_map['raster'])
|
|---|
| 2910 | sizer.Add(
|
|---|
| 2911 | StaticText(
|
|---|
| 2912 | parent=panel,
|
|---|
| 2913 | id=wx.ID_ANY,
|
|---|
| 2914 | label=_('Select target vector map to display:')),
|
|---|
| 2915 | proportion=0,
|
|---|
| 2916 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 2917 | border=5)
|
|---|
| 2918 | sizer.Add(
|
|---|
| 2919 | self.tgtvectselection,
|
|---|
| 2920 | proportion=0,
|
|---|
| 2921 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 2922 | border=5)
|
|---|
| 2923 | self.tgtvectselection.SetValue(tgt_map['vector'])
|
|---|
| 2924 |
|
|---|
| 2925 | # bindings
|
|---|
| 2926 | self.highlighthighest.Bind(wx.EVT_CHECKBOX, self.OnHighlight)
|
|---|
| 2927 | self.rmsWin.Bind(wx.EVT_TEXT, self.OnSDFactor)
|
|---|
| 2928 | self.srcselection.Bind(wx.EVT_TEXT, self.OnSrcSelection)
|
|---|
| 2929 | self.tgtrastselection.Bind(wx.EVT_TEXT, self.OnTgtRastSelection)
|
|---|
| 2930 | self.tgtvectselection.Bind(wx.EVT_TEXT, self.OnTgtVectSelection)
|
|---|
| 2931 |
|
|---|
| 2932 | panel.SetSizer(sizer)
|
|---|
| 2933 |
|
|---|
| 2934 | return panel
|
|---|
| 2935 |
|
|---|
| 2936 | def __CreateRectificationPage(self, notebook):
|
|---|
| 2937 | """Create notebook page with symbology settings"""
|
|---|
| 2938 |
|
|---|
| 2939 | panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
|
|---|
| 2940 | notebook.AddPage(page=panel, text=_("Rectification"))
|
|---|
| 2941 |
|
|---|
| 2942 | sizer = wx.BoxSizer(wx.VERTICAL)
|
|---|
| 2943 |
|
|---|
| 2944 | # transformation order
|
|---|
| 2945 | self.rb_grorder = wx.RadioBox(
|
|---|
| 2946 | parent=panel,
|
|---|
| 2947 | id=wx.ID_ANY,
|
|---|
| 2948 | label=" %s " %
|
|---|
| 2949 | _("Select rectification order"),
|
|---|
| 2950 | choices=[
|
|---|
| 2951 | _('1st order'),
|
|---|
| 2952 | _('2nd order'),
|
|---|
| 2953 | _('3rd order')],
|
|---|
| 2954 | majorDimension=wx.RA_SPECIFY_COLS)
|
|---|
| 2955 | sizer.Add(self.rb_grorder, proportion=0,
|
|---|
| 2956 | flag=wx.EXPAND | wx.ALL, border=5)
|
|---|
| 2957 | self.rb_grorder.SetSelection(self.parent.gr_order - 1)
|
|---|
| 2958 |
|
|---|
| 2959 | # interpolation method
|
|---|
| 2960 | gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
|
|---|
| 2961 | gridSizer.Add(
|
|---|
| 2962 | StaticText(
|
|---|
| 2963 | parent=panel,
|
|---|
| 2964 | id=wx.ID_ANY,
|
|---|
| 2965 | label=_('Select interpolation method:')),
|
|---|
| 2966 | pos=(
|
|---|
| 2967 | 0,
|
|---|
| 2968 | 0),
|
|---|
| 2969 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 2970 | border=5)
|
|---|
| 2971 | self.grmethod = wx.Choice(parent=panel, id=wx.ID_ANY,
|
|---|
| 2972 | choices=self.methods)
|
|---|
| 2973 | gridSizer.Add(self.grmethod, pos=(0, 1),
|
|---|
| 2974 | flag=wx.ALIGN_RIGHT, border=5)
|
|---|
| 2975 | self.grmethod.SetStringSelection(self.parent.gr_method)
|
|---|
| 2976 | gridSizer.AddGrowableCol(1)
|
|---|
| 2977 | sizer.Add(gridSizer, flag=wx.EXPAND | wx.ALL, border=5)
|
|---|
| 2978 |
|
|---|
| 2979 | # clip to region
|
|---|
| 2980 | self.check = wx.CheckBox(parent=panel, id=wx.ID_ANY, label=_(
|
|---|
| 2981 | "clip to computational region in target location"))
|
|---|
| 2982 | sizer.Add(self.check, proportion=0,
|
|---|
| 2983 | flag=wx.EXPAND | wx.ALL, border=5)
|
|---|
| 2984 | self.check.SetValue(self.parent.clip_to_region)
|
|---|
| 2985 |
|
|---|
| 2986 | # extension
|
|---|
| 2987 | sizer.Add(
|
|---|
| 2988 | StaticText(
|
|---|
| 2989 | parent=panel,
|
|---|
| 2990 | id=wx.ID_ANY,
|
|---|
| 2991 | label=_('Extension for output maps:')),
|
|---|
| 2992 | proportion=0,
|
|---|
| 2993 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 2994 | border=5)
|
|---|
| 2995 | self.ext_txt = TextCtrl(
|
|---|
| 2996 | parent=panel, id=wx.ID_ANY, value="", size=(
|
|---|
| 2997 | 350, -1))
|
|---|
| 2998 | self.ext_txt.SetValue(self.parent.extension)
|
|---|
| 2999 | sizer.Add(
|
|---|
| 3000 | self.ext_txt,
|
|---|
| 3001 | proportion=0,
|
|---|
| 3002 | flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
|
|---|
| 3003 | border=5)
|
|---|
| 3004 |
|
|---|
| 3005 | # bindings
|
|---|
| 3006 | self.ext_txt.Bind(wx.EVT_TEXT, self.OnExtension)
|
|---|
| 3007 | self.Bind(wx.EVT_RADIOBOX, self.parent.OnGROrder, self.rb_grorder)
|
|---|
| 3008 | self.Bind(wx.EVT_CHOICE, self.OnMethod, self.grmethod)
|
|---|
| 3009 | self.Bind(wx.EVT_CHECKBOX, self.OnClipRegion, self.check)
|
|---|
| 3010 |
|
|---|
| 3011 | panel.SetSizer(sizer)
|
|---|
| 3012 |
|
|---|
| 3013 | return panel
|
|---|
| 3014 |
|
|---|
| 3015 | def OnHighlight(self, event):
|
|---|
| 3016 | """Checkbox 'highlighthighest' checked/unchecked"""
|
|---|
| 3017 | if self.highlighthighest.IsChecked():
|
|---|
| 3018 | self.parent.highest_only = True
|
|---|
| 3019 | self.rmsWin.Disable()
|
|---|
| 3020 | else:
|
|---|
| 3021 | self.parent.highest_only = False
|
|---|
| 3022 | self.rmsWin.Enable()
|
|---|
| 3023 |
|
|---|
| 3024 | def OnSDFactor(self, event):
|
|---|
| 3025 | """New factor for RMS threshold = M + SD * factor"""
|
|---|
| 3026 | try:
|
|---|
| 3027 | self.sdfactor = float(self.rmsWin.GetValue())
|
|---|
| 3028 | except ValueError:
|
|---|
| 3029 | return
|
|---|
| 3030 | if self.sdfactor <= 0:
|
|---|
| 3031 | GError(parent=self,
|
|---|
| 3032 | message=_('RMS threshold factor must be > 0'))
|
|---|
| 3033 | elif self.sdfactor < 1:
|
|---|
| 3034 | GError(parent=self,
|
|---|
| 3035 | message=_('RMS threshold factor is < 1\n'
|
|---|
| 3036 | 'Too many points might be highlighted'))
|
|---|
| 3037 |
|
|---|
| 3038 | def OnSrcSelection(self, event):
|
|---|
| 3039 | """Source map to display selected"""
|
|---|
| 3040 | global src_map
|
|---|
| 3041 |
|
|---|
| 3042 | tmp_map = self.srcselection.GetValue()
|
|---|
| 3043 |
|
|---|
| 3044 | if not tmp_map == '' and not tmp_map == src_map:
|
|---|
| 3045 | self.new_src_map = tmp_map
|
|---|
| 3046 |
|
|---|
| 3047 | def OnTgtRastSelection(self, event):
|
|---|
| 3048 | """Target map to display selected"""
|
|---|
| 3049 | global tgt_map
|
|---|
| 3050 |
|
|---|
| 3051 | self.new_tgt_map['raster'] = self.tgtrastselection.GetValue()
|
|---|
| 3052 |
|
|---|
| 3053 | def OnTgtVectSelection(self, event):
|
|---|
| 3054 | """Target map to display selected"""
|
|---|
| 3055 | global tgt_map
|
|---|
| 3056 |
|
|---|
| 3057 | self.new_tgt_map['vector'] = self.tgtvectselection.GetValue()
|
|---|
| 3058 |
|
|---|
| 3059 | def OnMethod(self, event):
|
|---|
| 3060 | self.parent.gr_method = self.methods[event.GetSelection()]
|
|---|
| 3061 |
|
|---|
| 3062 | def OnClipRegion(self, event):
|
|---|
| 3063 | self.parent.clip_to_region = event.IsChecked()
|
|---|
| 3064 |
|
|---|
| 3065 | def OnExtension(self, event):
|
|---|
| 3066 | self.parent.extension = self.ext_txt.GetValue()
|
|---|
| 3067 |
|
|---|
| 3068 | def UpdateSettings(self):
|
|---|
| 3069 | global src_map
|
|---|
| 3070 | global tgt_map
|
|---|
| 3071 | global maptype
|
|---|
| 3072 |
|
|---|
| 3073 | layers = None
|
|---|
| 3074 |
|
|---|
| 3075 | UserSettings.Set(group='gcpman', key='rms', subkey='highestonly',
|
|---|
| 3076 | value=self.highlighthighest.GetValue())
|
|---|
| 3077 |
|
|---|
| 3078 | if self.sdfactor > 0:
|
|---|
| 3079 | UserSettings.Set(group='gcpman', key='rms', subkey='sdfactor',
|
|---|
| 3080 | value=self.sdfactor)
|
|---|
| 3081 |
|
|---|
| 3082 | self.parent.sdfactor = self.sdfactor
|
|---|
| 3083 | if self.parent.rmsthresh > 0:
|
|---|
| 3084 | self.parent.rmsthresh = self.parent.rmsmean + self.parent.sdfactor * self.parent.rmssd
|
|---|
| 3085 |
|
|---|
| 3086 | UserSettings.Set(
|
|---|
| 3087 | group='gcpman',
|
|---|
| 3088 | key='symbol',
|
|---|
| 3089 | subkey='color',
|
|---|
| 3090 | value=tuple(
|
|---|
| 3091 | wx.FindWindowById(
|
|---|
| 3092 | self.symbol['color']).GetColour()))
|
|---|
| 3093 | UserSettings.Set(
|
|---|
| 3094 | group='gcpman',
|
|---|
| 3095 | key='symbol',
|
|---|
| 3096 | subkey='hcolor',
|
|---|
| 3097 | value=tuple(
|
|---|
| 3098 | wx.FindWindowById(
|
|---|
| 3099 | self.symbol['hcolor']).GetColour()))
|
|---|
| 3100 | UserSettings.Set(
|
|---|
| 3101 | group='gcpman',
|
|---|
| 3102 | key='symbol',
|
|---|
| 3103 | subkey='scolor',
|
|---|
| 3104 | value=tuple(
|
|---|
| 3105 | wx.FindWindowById(
|
|---|
| 3106 | self.symbol['scolor']).GetColour()))
|
|---|
| 3107 | UserSettings.Set(
|
|---|
| 3108 | group='gcpman',
|
|---|
| 3109 | key='symbol',
|
|---|
| 3110 | subkey='ucolor',
|
|---|
| 3111 | value=tuple(
|
|---|
| 3112 | wx.FindWindowById(
|
|---|
| 3113 | self.symbol['ucolor']).GetColour()))
|
|---|
| 3114 | UserSettings.Set(group='gcpman', key='symbol', subkey='unused',
|
|---|
| 3115 | value=self.showunused.GetValue())
|
|---|
| 3116 | UserSettings.Set(
|
|---|
| 3117 | group='gcpman',
|
|---|
| 3118 | key='symbol',
|
|---|
| 3119 | subkey='size',
|
|---|
| 3120 | value=wx.FindWindowById(
|
|---|
| 3121 | self.symbol['size']).GetValue())
|
|---|
| 3122 | UserSettings.Set(
|
|---|
| 3123 | group='gcpman',
|
|---|
| 3124 | key='symbol',
|
|---|
| 3125 | subkey='width',
|
|---|
| 3126 | value=wx.FindWindowById(
|
|---|
| 3127 | self.symbol['width']).GetValue())
|
|---|
| 3128 |
|
|---|
| 3129 | srcrender = False
|
|---|
| 3130 | srcrenderVector = False
|
|---|
| 3131 | tgtrender = False
|
|---|
| 3132 | tgtrenderVector = False
|
|---|
| 3133 | reload_target = False
|
|---|
| 3134 | if self.new_src_map != src_map:
|
|---|
| 3135 | # remove old layer
|
|---|
| 3136 | layers = self.parent.grwiz.SrcMap.GetListOfLayers()
|
|---|
| 3137 | self.parent.grwiz.SrcMap.DeleteLayer(layers[0])
|
|---|
| 3138 |
|
|---|
| 3139 | src_map = self.new_src_map
|
|---|
| 3140 | if maptype == 'raster':
|
|---|
| 3141 | cmdlist = ['d.rast', 'map=%s' % src_map]
|
|---|
| 3142 | srcrender = True
|
|---|
| 3143 | else:
|
|---|
| 3144 | cmdlist = ['d.vect', 'map=%s' % src_map]
|
|---|
| 3145 | srcrenderVector = True
|
|---|
| 3146 | self.parent.grwiz.SwitchEnv('source')
|
|---|
| 3147 | name, found = utils.GetLayerNameFromCmd(cmdlist)
|
|---|
| 3148 | self.parent.grwiz.SrcMap.AddLayer(
|
|---|
| 3149 | ltype=maptype, command=cmdlist, active=True, name=name,
|
|---|
| 3150 | hidden=False, opacity=1.0, render=False)
|
|---|
| 3151 |
|
|---|
| 3152 | self.parent.grwiz.SwitchEnv('target')
|
|---|
| 3153 |
|
|---|
| 3154 | if self.new_tgt_map['raster'] != tgt_map['raster'] or \
|
|---|
| 3155 | self.new_tgt_map['vector'] != tgt_map['vector']:
|
|---|
| 3156 | # remove all layers
|
|---|
| 3157 | layers = self.parent.grwiz.TgtMap.GetListOfLayers()
|
|---|
| 3158 | while layers:
|
|---|
| 3159 | self.parent.grwiz.TgtMap.DeleteLayer(layers[0])
|
|---|
| 3160 | del layers[0]
|
|---|
| 3161 | layers = self.parent.grwiz.TgtMap.GetListOfLayers()
|
|---|
| 3162 | # self.parent.grwiz.TgtMap.DeleteAllLayers()
|
|---|
| 3163 | reload_target = True
|
|---|
| 3164 | tgt_map['raster'] = self.new_tgt_map['raster']
|
|---|
| 3165 | tgt_map['vector'] = self.new_tgt_map['vector']
|
|---|
| 3166 |
|
|---|
| 3167 | if tgt_map['raster'] != '':
|
|---|
| 3168 | cmdlist = ['d.rast', 'map=%s' % tgt_map['raster']]
|
|---|
| 3169 | name, found = utils.GetLayerNameFromCmd(cmdlist)
|
|---|
| 3170 | self.parent.grwiz.TgtMap.AddLayer(
|
|---|
| 3171 | ltype='raster', command=cmdlist, active=True, name=name,
|
|---|
| 3172 | hidden=False, opacity=1.0, render=False)
|
|---|
| 3173 |
|
|---|
| 3174 | tgtrender = True
|
|---|
| 3175 |
|
|---|
| 3176 | if tgt_map['vector'] != '':
|
|---|
| 3177 | cmdlist = ['d.vect', 'map=%s' % tgt_map['vector']]
|
|---|
| 3178 | name, found = utils.GetLayerNameFromCmd(cmdlist)
|
|---|
| 3179 | self.parent.grwiz.TgtMap.AddLayer(
|
|---|
| 3180 | ltype='vector', command=cmdlist, active=True, name=name,
|
|---|
| 3181 | hidden=False, opacity=1.0, render=False)
|
|---|
| 3182 |
|
|---|
| 3183 | tgtrenderVector = True
|
|---|
| 3184 |
|
|---|
| 3185 | if tgt_map['raster'] == '' and tgt_map['vector'] == '':
|
|---|
| 3186 | if self.parent.show_target == True:
|
|---|
| 3187 | self.parent.show_target = False
|
|---|
| 3188 | self.parent._mgr.GetPane("target").Hide()
|
|---|
| 3189 | self.parent._mgr.Update()
|
|---|
| 3190 | self.parent.activemap.SetSelection(0)
|
|---|
| 3191 | self.parent.activemap.Enable(False)
|
|---|
| 3192 | self.parent.GetMapToolbar().Enable('zoommenu', enable=False)
|
|---|
| 3193 | else:
|
|---|
| 3194 | if self.parent.show_target == False:
|
|---|
| 3195 | self.parent.show_target = True
|
|---|
| 3196 | self.parent._mgr.GetPane("target").Show()
|
|---|
| 3197 | self.parent._mgr.Update()
|
|---|
| 3198 | self.parent.activemap.SetSelection(0)
|
|---|
| 3199 | self.parent.activemap.Enable(True)
|
|---|
| 3200 | self.parent.GetMapToolbar().Enable('zoommenu', enable=True)
|
|---|
| 3201 | self.parent.TgtMapWindow.ZoomToMap(
|
|---|
| 3202 | layers=self.parent.TgtMap.GetListOfLayers())
|
|---|
| 3203 |
|
|---|
| 3204 | self.parent.UpdateColours(
|
|---|
| 3205 | srcrender,
|
|---|
| 3206 | srcrenderVector,
|
|---|
| 3207 | tgtrender,
|
|---|
| 3208 | tgtrenderVector)
|
|---|
| 3209 | self.parent.SetSettings()
|
|---|
| 3210 |
|
|---|
| 3211 | def OnSave(self, event):
|
|---|
| 3212 | """Button 'Save' pressed"""
|
|---|
| 3213 | self.UpdateSettings()
|
|---|
| 3214 | fileSettings = {}
|
|---|
| 3215 | UserSettings.ReadSettingsFile(settings=fileSettings)
|
|---|
| 3216 | fileSettings['gcpman'] = UserSettings.Get(group='gcpman')
|
|---|
| 3217 | file = UserSettings.SaveToFile(fileSettings)
|
|---|
| 3218 | self.parent._giface.WriteLog(
|
|---|
| 3219 | _('GCP Manager settings saved to file \'%s\'.') %
|
|---|
| 3220 | file)
|
|---|
| 3221 | # self.Close()
|
|---|
| 3222 |
|
|---|
| 3223 | def OnApply(self, event):
|
|---|
| 3224 | """Button 'Apply' pressed"""
|
|---|
| 3225 | self.UpdateSettings()
|
|---|
| 3226 | # self.Close()
|
|---|
| 3227 |
|
|---|
| 3228 | def OnClose(self, event):
|
|---|
| 3229 | """Button 'Cancel' pressed"""
|
|---|
| 3230 | self.Close()
|
|---|