From 4be568e6ecb70c9d5aa5493d110fc147a0f23c0e Mon Sep 17 00:00:00 2001 From: scastil Date: Thu, 3 May 2018 10:47:21 -0500 Subject: [PATCH 001/142] se agrega la carpeta qgisplugin, la cual contiene el desarrollo para el plugin de WMF aplicado a Qgis. --- qgisplugin/HydroSEDPlugin.py | 233 ++++++++ qgisplugin/HydroSEDPlugin_dockwidget.py | 138 +++++ qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 531 ++++++++++++++++++ .../HydroSEDPlugin_dockwidget_base.ui.save.1 | 339 +++++++++++ qgisplugin/Makefile | 229 ++++++++ qgisplugin/README.html | 42 ++ qgisplugin/README.txt | 32 ++ qgisplugin/__init__.py | 35 ++ qgisplugin/help/Makefile | 130 +++++ qgisplugin/help/make.bat | 155 +++++ qgisplugin/help/source/conf.py | 216 +++++++ qgisplugin/help/source/index.rst | 20 + qgisplugin/i18n/af.ts | 11 + qgisplugin/icon.png | Bin 0 -> 1034 bytes qgisplugin/metadata.txt | 39 ++ qgisplugin/pb_tool.cfg | 74 +++ qgisplugin/plugin_upload.py | 107 ++++ qgisplugin/pylintrc | 281 +++++++++ qgisplugin/resources.py | 109 ++++ qgisplugin/resources.qrc | 5 + qgisplugin/scripts/compile-strings.sh | 12 + qgisplugin/scripts/run-env-linux.sh | 28 + qgisplugin/scripts/update-strings.sh | 56 ++ qgisplugin/test/__init__.py | 2 + qgisplugin/test/qgis_interface.py | 205 +++++++ qgisplugin/test/tenbytenraster.asc | 19 + qgisplugin/test/tenbytenraster.asc.aux.xml | 13 + qgisplugin/test/tenbytenraster.keywords | 1 + qgisplugin/test/tenbytenraster.lic | 18 + qgisplugin/test/tenbytenraster.prj | 1 + qgisplugin/test/tenbytenraster.qml | 26 + .../test/test_HydroSEDPlugin_dockwidget.py | 45 ++ qgisplugin/test/test_init.py | 64 +++ qgisplugin/test/test_qgis_environment.py | 60 ++ qgisplugin/test/test_resources.py | 44 ++ qgisplugin/test/test_translations.py | 55 ++ qgisplugin/test/utilities.py | 61 ++ 37 files changed, 3436 insertions(+) create mode 100644 qgisplugin/HydroSEDPlugin.py create mode 100644 qgisplugin/HydroSEDPlugin_dockwidget.py create mode 100644 qgisplugin/HydroSEDPlugin_dockwidget_base.ui create mode 100644 qgisplugin/HydroSEDPlugin_dockwidget_base.ui.save.1 create mode 100644 qgisplugin/Makefile create mode 100644 qgisplugin/README.html create mode 100644 qgisplugin/README.txt create mode 100644 qgisplugin/__init__.py create mode 100644 qgisplugin/help/Makefile create mode 100644 qgisplugin/help/make.bat create mode 100644 qgisplugin/help/source/conf.py create mode 100644 qgisplugin/help/source/index.rst create mode 100644 qgisplugin/i18n/af.ts create mode 100644 qgisplugin/icon.png create mode 100644 qgisplugin/metadata.txt create mode 100644 qgisplugin/pb_tool.cfg create mode 100755 qgisplugin/plugin_upload.py create mode 100644 qgisplugin/pylintrc create mode 100644 qgisplugin/resources.py create mode 100644 qgisplugin/resources.qrc create mode 100644 qgisplugin/scripts/compile-strings.sh create mode 100644 qgisplugin/scripts/run-env-linux.sh create mode 100644 qgisplugin/scripts/update-strings.sh create mode 100644 qgisplugin/test/__init__.py create mode 100644 qgisplugin/test/qgis_interface.py create mode 100644 qgisplugin/test/tenbytenraster.asc create mode 100644 qgisplugin/test/tenbytenraster.asc.aux.xml create mode 100644 qgisplugin/test/tenbytenraster.keywords create mode 100644 qgisplugin/test/tenbytenraster.lic create mode 100644 qgisplugin/test/tenbytenraster.prj create mode 100644 qgisplugin/test/tenbytenraster.qml create mode 100644 qgisplugin/test/test_HydroSEDPlugin_dockwidget.py create mode 100644 qgisplugin/test/test_init.py create mode 100644 qgisplugin/test/test_qgis_environment.py create mode 100644 qgisplugin/test/test_resources.py create mode 100644 qgisplugin/test/test_translations.py create mode 100644 qgisplugin/test/utilities.py diff --git a/qgisplugin/HydroSEDPlugin.py b/qgisplugin/HydroSEDPlugin.py new file mode 100644 index 0000000..69d39a2 --- /dev/null +++ b/qgisplugin/HydroSEDPlugin.py @@ -0,0 +1,233 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + HydroSEDPlugin + A QGIS plugin + Este plugin facilita la ejecucion de modelos hidrologicos implementados desde QGIS. + ------------------- + begin : 2018-05-02 + git sha : $Format:%H$ + copyright : (C) 2018 by Universidad Nacional de Colombia - Sede Medellín + email : jctrujil@unal.edu.co + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" +from PyQt4.QtCore import QSettings, QTranslator, qVersion, QCoreApplication, Qt +from PyQt4.QtGui import QAction, QIcon +# Initialize Qt resources from file resources.py +import resources + +# Import the code for the DockWidget +from HydroSEDPlugin_dockwidget import HydroSEDPluginDockWidget +import os.path + + +class HydroSEDPlugin: + """QGIS Plugin Implementation.""" + + def __init__(self, iface): + """Constructor. + + :param iface: An interface instance that will be passed to this class + which provides the hook by which you can manipulate the QGIS + application at run time. + :type iface: QgisInterface + """ + # Save reference to the QGIS interface + self.iface = iface + + # initialize plugin directory + self.plugin_dir = os.path.dirname(__file__) + + # initialize locale + locale = QSettings().value('locale/userLocale')[0:2] + locale_path = os.path.join( + self.plugin_dir, + 'i18n', + 'HydroSEDPlugin_{}.qm'.format(locale)) + + if os.path.exists(locale_path): + self.translator = QTranslator() + self.translator.load(locale_path) + + if qVersion() > '4.3.3': + QCoreApplication.installTranslator(self.translator) + + # Declare instance attributes + self.actions = [] + self.menu = self.tr(u'&Hydro-SED') + # TODO: We are going to let the user set this up in a future iteration + self.toolbar = self.iface.addToolBar(u'HydroSEDPlugin') + self.toolbar.setObjectName(u'HydroSEDPlugin') + + #print "** INITIALIZING HydroSEDPlugin" + + self.pluginIsActive = False + self.dockwidget = None + + + # noinspection PyMethodMayBeStatic + def tr(self, message): + """Get the translation for a string using Qt translation API. + + We implement this ourselves since we do not inherit QObject. + + :param message: String for translation. + :type message: str, QString + + :returns: Translated version of message. + :rtype: QString + """ + # noinspection PyTypeChecker,PyArgumentList,PyCallByClass + return QCoreApplication.translate('HydroSEDPlugin', message) + + + def add_action( + self, + icon_path, + text, + callback, + enabled_flag=True, + add_to_menu=True, + add_to_toolbar=True, + status_tip=None, + whats_this=None, + parent=None): + """Add a toolbar icon to the toolbar. + + :param icon_path: Path to the icon for this action. Can be a resource + path (e.g. ':/plugins/foo/bar.png') or a normal file system path. + :type icon_path: str + + :param text: Text that should be shown in menu items for this action. + :type text: str + + :param callback: Function to be called when the action is triggered. + :type callback: function + + :param enabled_flag: A flag indicating if the action should be enabled + by default. Defaults to True. + :type enabled_flag: bool + + :param add_to_menu: Flag indicating whether the action should also + be added to the menu. Defaults to True. + :type add_to_menu: bool + + :param add_to_toolbar: Flag indicating whether the action should also + be added to the toolbar. Defaults to True. + :type add_to_toolbar: bool + + :param status_tip: Optional text to show in a popup when mouse pointer + hovers over the action. + :type status_tip: str + + :param parent: Parent widget for the new action. Defaults None. + :type parent: QWidget + + :param whats_this: Optional text to show in the status bar when the + mouse pointer hovers over the action. + + :returns: The action that was created. Note that the action is also + added to self.actions list. + :rtype: QAction + """ + + icon = QIcon(icon_path) + action = QAction(icon, text, parent) + action.triggered.connect(callback) + action.setEnabled(enabled_flag) + + if status_tip is not None: + action.setStatusTip(status_tip) + + if whats_this is not None: + action.setWhatsThis(whats_this) + + if add_to_toolbar: + self.toolbar.addAction(action) + + if add_to_menu: + self.iface.addPluginToMenu( + self.menu, + action) + + self.actions.append(action) + + return action + + + def initGui(self): + """Create the menu entries and toolbar icons inside the QGIS GUI.""" + + icon_path = ':/plugins/HydroSEDPlugin/icon.png' + self.add_action( + icon_path, + text=self.tr(u'Hydro-SED'), + callback=self.run, + parent=self.iface.mainWindow()) + + #-------------------------------------------------------------------------- + + def onClosePlugin(self): + """Cleanup necessary items here when plugin dockwidget is closed""" + + #print "** CLOSING HydroSEDPlugin" + + # disconnects + self.dockwidget.closingPlugin.disconnect(self.onClosePlugin) + + # remove this statement if dockwidget is to remain + # for reuse if plugin is reopened + # Commented next statement since it causes QGIS crashe + # when closing the docked window: + # self.dockwidget = None + + self.pluginIsActive = False + + + def unload(self): + """Removes the plugin menu item and icon from QGIS GUI.""" + + #print "** UNLOAD HydroSEDPlugin" + + for action in self.actions: + self.iface.removePluginMenu( + self.tr(u'&Hydro-SED'), + action) + self.iface.removeToolBarIcon(action) + # remove the toolbar + del self.toolbar + + #-------------------------------------------------------------------------- + + def run(self): + """Run method that loads and starts the plugin""" + + if not self.pluginIsActive: + self.pluginIsActive = True + + #print "** STARTING HydroSEDPlugin" + + # dockwidget may not exist if: + # first run of plugin + # removed on close (see self.onClosePlugin method) + if self.dockwidget == None: + # Create the dockwidget (after translation) and keep reference + self.dockwidget = HydroSEDPluginDockWidget() + + # connect to provide cleanup on closing of dockwidget + self.dockwidget.closingPlugin.connect(self.onClosePlugin) + + # show the dockwidget + # TODO: fix to allow choice of dock location + self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget) + self.dockwidget.show() + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py new file mode 100644 index 0000000..37d3f97 --- /dev/null +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + HydroSEDPluginDockWidget + A QGIS plugin + Este plugin facilita la ejecucion de modelos hidrologicos implementados desde QGIS. + ------------------- + begin : 2018-05-02 + git sha : $Format:%H$ + copyright : (C) 2018 by Universidad Nacional de Colombia - Sede Medellín + email : jctrujil@unal.edu.co + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +import os + +from PyQt4 import QtGui, uic +from PyQt4.QtCore import pyqtSignal + +from qgis.gui import QgsMessageBar +from PyQt4.QtGui import QFileDialog + +from wmf import wmf + +FORM_CLASS, _ = uic.loadUiType(os.path.join( + os.path.dirname(__file__), 'HydroSEDPlugin_dockwidget_base.ui')) + + +class HydroSEDPluginDockWidget(QtGui.QDockWidget, FORM_CLASS): + + closingPlugin = pyqtSignal() + + def __init__(self, parent=None): + + """Constructor.""" + super(HydroSEDPluginDockWidget, self).__init__(parent) + # Set up the user interface from Designer. + # After setupUI you can access any designer object by doing + # self., and you can use autoconnect slots - see + # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html + # #widgets-and-dialogs-with-auto-connect + self.setupUi(self) + self.setupUIInputsOutputs () + self.setupUIButtonEvents () + + def closeEvent(self, event): + + self.closingPlugin.emit() + event.accept() + + def handleClickEventEjecutarTrazadorCorrientes (self): + + print wmf + print self.spinBoxLatitudTrazadorCorrientes.value () + print self.spinBoxLongitudTrazadorCorrientes.value () + print self.lineEditSelectorOutputCorrienteShapefileTrazadorCorrientes.text () + + + def handleClickEventEjecutarTrazadorCuencas (self): + + print wmf + print self.spinBoxLatitudTrazadorCuencas.value () + print self.spinBoxLongitudTrazadorCuencas.value () + print self.lineEditInputCorrienteShapefileTrazadorCuencas.text () + print self.lineEditOutputCuencaShapefileTrazadorCuencas.text () + print self.lineEditOutputCuencaNCTrazadorCuencas.text () + + +# from PyQt4.QtGui import QFileDialog +# filename1 = QFileDialog.getOpenFileName() +# filename2 = QFileDialog.getSaveFileName() +# print filename1 +# print filename2 + + def setupUIInputsOutputs (self): + + def setupLineEditButtonOpenFileDialog (lineEditHolder, fileDialogHolder): + + lineEditHolder.setText (fileDialogHolder.getOpenFileName ()) + + def setupLineEditButtonSaveFileDialog (lineEditHolder, fileDialogHolder): + + lineEditHolder.setText (fileDialogHolder.getSaveFileName ()) + + def clickEventSelectorMapaDEM (): + + setupLineEditButtonOpenFileDialog (self.lineEditMapaDEM, QFileDialog) + + def clickEventSelectorMapaDIR (): + + setupLineEditButtonOpenFileDialog (self.lineEditMapaDIR, QFileDialog) + + def clickEventSelectorBinarioNC (): + + setupLineEditButtonOpenFileDialog (self.lineEditSelectorBinarioNC, QFileDialog) + + def clickEventSelectorOutputCorrienteShapefileTrazadorCorrientes (): + + setupLineEditButtonSaveFileDialog (self.lineEditSelectorOutputCorrienteShapefileTrazadorCorrientes, QFileDialog) + + def clickEventSelectorInputCorrienteShapefileTrazadorCuencas (): + + setupLineEditButtonOpenFileDialog (self.lineEditInputCorrienteShapefileTrazadorCuencas, QFileDialog) + + def clickEventSelectorOutputCuencaShapefileTrazadorCuencas (): + + setupLineEditButtonSaveFileDialog (self.lineEditOutputCuencaShapefileTrazadorCuencas, QFileDialog) + + def clickEventSelectorOutputCuencaNCTrazadorCuencas (): + + setupLineEditButtonSaveFileDialog (self.lineEditOutputCuencaNCTrazadorCuencas, QFileDialog) + + self.botonSelectorMapaDEM.clicked.connect (clickEventSelectorMapaDEM) + self.botonSelectorMapaDIR.clicked.connect (clickEventSelectorMapaDIR) + self.botonSelectorBinarioNC.clicked.connect (clickEventSelectorBinarioNC) + self.botonSelectorOutputCorrienteShapefileTrazadorCorrientes.clicked.connect (clickEventSelectorOutputCorrienteShapefileTrazadorCorrientes) + self.botonInputCorrienteShapefileTrazadorCuencas.clicked.connect (clickEventSelectorInputCorrienteShapefileTrazadorCuencas) + self.botonOutputCuencaShapefileTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaShapefileTrazadorCuencas) + self.botonOutputCuencaNCTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaNCTrazadorCuencas) + + def setupUIButtonEvents (self): + + self.botonEjecutarTrazadorCorrientes.clicked.connect (self.handleClickEventEjecutarTrazadorCorrientes) + self.botonEjecutarTrazadorCuencas.clicked.connect (self.handleClickEventEjecutarTrazadorCuencas) + + + + + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui new file mode 100644 index 0000000..3e3c91c --- /dev/null +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -0,0 +1,531 @@ + + + HydroSEDPluginDockWidgetBase + + + + 0 + 0 + 383 + 869 + + + + + 0 + 0 + + + + 0.500000000000000 + + + Hydro-SED + + + + + + + 0 + + + + Configuración + + + + + 0 + 0 + 361 + 451 + + + + + + + Configuración General + + + + + 0 + 230 + 359 + 211 + + + + Explorador Binarios *.nc + + + + + 10 + 31 + 341 + 181 + + + + + + + Path Archivos Binarios *.nc + + + + + + + + + true + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + ... + + + + + + + + + + + + + + + 10 + 21 + 341 + 201 + + + + + + + Mapa DEM: + + + + + + + + + true + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + ... + + + + + + + + + Mapa DIR: + + + + + + + + + true + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + ... + + + + + + + + + Umbral: + + + + + + + + + + + + + + + + Trazadores + + + + + 0 + 0 + 361 + 641 + + + + + + + Corrientes: + + + + + 0 + 250 + 359 + 381 + + + + Cuencas: + + + + + 10 + 22 + 341 + 351 + + + + + + + Latitud: + + + + + + + + + + Longitud: + + + + + + + + + + Path Corriente: + + + + + + + + + true + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + ... + + + + + + + + + Path Salida (*.shp): + + + + + + + + + true + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + ... + + + + + + + + + Path Salida (*.nc): + + + + + + + + + true + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + ... + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ejecutar Trazador + + + + + + + + labelLatitudTrazadorCuencas + labelLongitudTrazadorCuencas + labelInputCorrienteShapefileTrazadorCuencas + labelOutputTrazadorCuencasShapefile + spinBoxLatitudTrazadorCuencas + spinBoxLongitudTrazadorCuencas + layoutWidget_4 + lineEditInputCorrienteShapefileTrazadorCuencas + layoutWidget_5 + layoutWidget_6 + + + + + 10 + 22 + 341 + 221 + + + + + + + Latitud: + + + + + + + + + + Longitud: + + + + + + + + + + Path Salida (*.shp): + + + + + + + + + true + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + ... + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ejecutar Trazador + + + + + + + + + + + + + + + + + + + + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui.save.1 b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui.save.1 new file mode 100644 index 0000000..bea30db --- /dev/null +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui.save.1 @@ -0,0 +1,339 @@ + + + HydroSEDPluginDockWidgetBase + + + + 0 + 0 + 383 + 869 + + + + + 0 + 0 + + + + 0.500000000000000 + + + Hydro-SED + + + + + + + 1 + + + + Configuración + + + + + 0 + 0 + 361 + 451 + + + + + + + Configuración General + + + + + 9 + 20 + 341 + 191 + + + + + + + Mapa DEM: + + + + + + + + + + Mapa DIR: + + + + + + + + + + Umbral: + + + + + + + + + + + + 0 + 230 + 359 + 211 + + + + Explorador Binarios *.nc + + + + + 10 + 30 + 341 + 181 + + + + + + + Path Archivos Binarios *.nc + + + + + + + + + + + + + + + + + + + + Trazadores + + + + + 0 + 0 + 361 + 641 + + + + + + + Corrientes: + + + + + 10 + 250 + 359 + 371 + + + + Cuencas: + + + + + 1 + 21 + 341 + 341 + + + + + + + Latitud: + + + + + + + + + + Longitud: + + + + + + + + + + Path Corriente: + + + + + + + + + + Path Salida (*.shp): + + + + + + + + + + Path Salida (*.nc): + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ejecutar Trazador + + + + + + + + + + + + 11 + 21 + 341 + 221 + + + + + + + Latitud: + + + + + + + + + + Longitud: + + + + + + + + + + Path Salida (*.shp): + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ejecutar Trazador + + + + + + + + + + + + + + + + + + + + QgsFileWidget + QWidget +
qgsfilewidget.h
+
+
+ + +
diff --git a/qgisplugin/Makefile b/qgisplugin/Makefile new file mode 100644 index 0000000..ff6235e --- /dev/null +++ b/qgisplugin/Makefile @@ -0,0 +1,229 @@ +#/*************************************************************************** +# HydroSEDPlugin +# +# Este plugin facilita la ejecucion de modelos hidrologicos implementados desde QGIS. +# ------------------- +# begin : 2018-05-02 +# git sha : $Format:%H$ +# copyright : (C) 2018 by Universidad Nacional de Colombia - Sede Medellín +# email : jctrujil@unal.edu.co +# ***************************************************************************/ +# +#/*************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License as published by * +# * the Free Software Foundation; either version 2 of the License, or * +# * (at your option) any later version. * +# * * +# ***************************************************************************/ + +################################################# +# Edit the following to match your sources lists +################################################# + + +#Add iso code for any locales you want to support here (space separated) +# default is no locales +# LOCALES = af +LOCALES = + +# If locales are enabled, set the name of the lrelease binary on your system. If +# you have trouble compiling the translations, you may have to specify the full path to +# lrelease +#LRELEASE = lrelease +#LRELEASE = lrelease-qt4 + + +# translation +SOURCES = \ + __init__.py \ + HydroSEDPlugin.py HydroSEDPlugin_dockwidget.py + +PLUGINNAME = HydroSEDPlugin + +PY_FILES = \ + __init__.py \ + HydroSEDPlugin.py HydroSEDPlugin_dockwidget.py + +UI_FILES = HydroSEDPlugin_dockwidget_base.ui + +EXTRAS = metadata.txt icon.png + +EXTRA_DIRS = + +COMPILED_RESOURCE_FILES = resources.py + +PEP8EXCLUDE=pydev,resources.py,conf.py,third_party,ui + + +################################################# +# Normally you would not need to edit below here +################################################# + +HELP = help/build/html + +PLUGIN_UPLOAD = $(c)/plugin_upload.py + +RESOURCE_SRC=$(shell grep '^ *@@g;s/.*>//g' | tr '\n' ' ') + +QGISDIR=.qgis2 + +default: compile + +compile: $(COMPILED_RESOURCE_FILES) + +%.py : %.qrc $(RESOURCES_SRC) + pyrcc4 -o $*.py $< + +%.qm : %.ts + $(LRELEASE) $< + +test: compile transcompile + @echo + @echo "----------------------" + @echo "Regression Test Suite" + @echo "----------------------" + + @# Preceding dash means that make will continue in case of errors + @-export PYTHONPATH=`pwd`:$(PYTHONPATH); \ + export QGIS_DEBUG=0; \ + export QGIS_LOG_FILE=/dev/null; \ + nosetests -v --with-id --with-coverage --cover-package=. \ + 3>&1 1>&2 2>&3 3>&- || true + @echo "----------------------" + @echo "If you get a 'no module named qgis.core error, try sourcing" + @echo "the helper script we have provided first then run make test." + @echo "e.g. source run-env-linux.sh ; make test" + @echo "----------------------" + +deploy: compile doc transcompile + @echo + @echo "------------------------------------------" + @echo "Deploying plugin to your .qgis2 directory." + @echo "------------------------------------------" + # The deploy target only works on unix like operating system where + # the Python plugin directory is located at: + # $HOME/$(QGISDIR)/python/plugins + mkdir -p $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) + cp -vf $(PY_FILES) $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) + cp -vf $(UI_FILES) $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) + cp -vf $(COMPILED_RESOURCE_FILES) $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) + cp -vf $(EXTRAS) $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) + cp -vfr i18n $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) + cp -vfr $(HELP) $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME)/help + # Copy extra directories if any + # (temporarily removed) + + +# The dclean target removes compiled python files from plugin directory +# also deletes any .git entry +dclean: + @echo + @echo "-----------------------------------" + @echo "Removing any compiled python files." + @echo "-----------------------------------" + find $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) -iname "*.pyc" -delete + find $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) -iname ".git" -prune -exec rm -Rf {} \; + + +derase: + @echo + @echo "-------------------------" + @echo "Removing deployed plugin." + @echo "-------------------------" + rm -Rf $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) + +zip: deploy dclean + @echo + @echo "---------------------------" + @echo "Creating plugin zip bundle." + @echo "---------------------------" + # The zip target deploys the plugin and creates a zip file with the deployed + # content. You can then upload the zip file on http://plugins.qgis.org + rm -f $(PLUGINNAME).zip + cd $(HOME)/$(QGISDIR)/python/plugins; zip -9r $(CURDIR)/$(PLUGINNAME).zip $(PLUGINNAME) + +package: compile + # Create a zip package of the plugin named $(PLUGINNAME).zip. + # This requires use of git (your plugin development directory must be a + # git repository). + # To use, pass a valid commit or tag as follows: + # make package VERSION=Version_0.3.2 + @echo + @echo "------------------------------------" + @echo "Exporting plugin to zip package. " + @echo "------------------------------------" + rm -f $(PLUGINNAME).zip + git archive --prefix=$(PLUGINNAME)/ -o $(PLUGINNAME).zip $(VERSION) + echo "Created package: $(PLUGINNAME).zip" + +upload: zip + @echo + @echo "-------------------------------------" + @echo "Uploading plugin to QGIS Plugin repo." + @echo "-------------------------------------" + $(PLUGIN_UPLOAD) $(PLUGINNAME).zip + +transup: + @echo + @echo "------------------------------------------------" + @echo "Updating translation files with any new strings." + @echo "------------------------------------------------" + @chmod +x scripts/update-strings.sh + @scripts/update-strings.sh $(LOCALES) + +transcompile: + @echo + @echo "----------------------------------------" + @echo "Compiled translation files to .qm files." + @echo "----------------------------------------" + @chmod +x scripts/compile-strings.sh + @scripts/compile-strings.sh $(LRELEASE) $(LOCALES) + +transclean: + @echo + @echo "------------------------------------" + @echo "Removing compiled translation files." + @echo "------------------------------------" + rm -f i18n/*.qm + +clean: + @echo + @echo "------------------------------------" + @echo "Removing uic and rcc generated files" + @echo "------------------------------------" + rm $(COMPILED_UI_FILES) $(COMPILED_RESOURCE_FILES) + +doc: + @echo + @echo "------------------------------------" + @echo "Building documentation using sphinx." + @echo "------------------------------------" + cd help; make html + +pylint: + @echo + @echo "-----------------" + @echo "Pylint violations" + @echo "-----------------" + @pylint --reports=n --rcfile=pylintrc . || true + @echo + @echo "----------------------" + @echo "If you get a 'no module named qgis.core' error, try sourcing" + @echo "the helper script we have provided first then run make pylint." + @echo "e.g. source run-env-linux.sh ; make pylint" + @echo "----------------------" + + +# Run pep8 style checking +#http://pypi.python.org/pypi/pep8 +pep8: + @echo + @echo "-----------" + @echo "PEP8 issues" + @echo "-----------" + @pep8 --repeat --ignore=E203,E121,E122,E123,E124,E125,E126,E127,E128 --exclude $(PEP8EXCLUDE) . || true + @echo "-----------" + @echo "Ignored in PEP8 check:" + @echo $(PEP8EXCLUDE) diff --git a/qgisplugin/README.html b/qgisplugin/README.html new file mode 100644 index 0000000..e0b71a3 --- /dev/null +++ b/qgisplugin/README.html @@ -0,0 +1,42 @@ + + +

Plugin Builder Results

+ +Congratulations! You just built a plugin for QGIS!

+ +
+Your plugin HydroSEDPlugin was created in:
+  /home/jctrujillo/Documents/ManoNegra/Aplicaciones/unal_isagen/WMF/qgis_plugin/HydroSEDPlugin +

+Your QGIS plugin directory is located at:
+  /home/jctrujillo/.qgis2/python/plugins +

+

What's Next

+
    +
  1. In your plugin directory, compile the resources file using pyrcc4 (simply run make if you have automake or use pb_tool) +
  2. Test the generated sources using make test (or run tests from your IDE) +
  3. Copy the entire directory containing your new plugin to the QGIS plugin directory (see Notes below) +
  4. Test the plugin by enabling it in the QGIS plugin manager +
  5. Customize it by editing the implementation file HydroSEDPlugin.py +
  6. Create your own custom icon, replacing the default icon.png +
  7. Modify your user interface by opening HydroSEDPlugin_dialog_base.ui in Qt Designer +
+Notes: +
    +
  • You can use the Makefile to compile and deploy when you + make changes. This requires GNU make (gmake). The Makefile is ready to use, however you + will have to edit it to add addional Python source files, dialogs, and translations. +
  • You can also use pb_tool to compile and deploy your plugin. Tweak the pb_tool.cfg file included with your plugin as you add files. Install pb_tool using + pip or easy_install. See http://loc8.cc/pb_tool for more information. +
+
+
+

+For information on writing PyQGIS code, see http://loc8.cc/pyqgis_resources for a list of resources. +

+
+

+©2011-2018 GeoApt LLC - geoapt.com +

+ + diff --git a/qgisplugin/README.txt b/qgisplugin/README.txt new file mode 100644 index 0000000..a64254b --- /dev/null +++ b/qgisplugin/README.txt @@ -0,0 +1,32 @@ +Plugin Builder Results + +Your plugin HydroSEDPlugin was created in: + /home/jctrujillo/Documents/ManoNegra/Aplicaciones/unal_isagen/WMF/qgis_plugin/HydroSEDPlugin + +Your QGIS plugin directory is located at: + /home/jctrujillo/.qgis2/python/plugins + +What's Next: + + * Copy the entire directory containing your new plugin to the QGIS plugin + directory + + * Compile the resources file using pyrcc4 + + * Run the tests (``make test``) + + * Test the plugin by enabling it in the QGIS plugin manager + + * Customize it by editing the implementation file: ``HydroSEDPlugin.py`` + + * Create your own custom icon, replacing the default icon.png + + * Modify your user interface by opening HydroSEDPlugin.ui in Qt Designer + + * You can use the Makefile to compile your Ui and resource files when + you make changes. This requires GNU make (gmake) + +For more information, see the PyQGIS Developer Cookbook at: +http://www.qgis.org/pyqgis-cookbook/index.html + +(C) 2011-2018 GeoApt LLC - geoapt.com diff --git a/qgisplugin/__init__.py b/qgisplugin/__init__.py new file mode 100644 index 0000000..03233eb --- /dev/null +++ b/qgisplugin/__init__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + HydroSEDPlugin + A QGIS plugin + Este plugin facilita la ejecucion de modelos hidrologicos implementados desde QGIS. + ------------------- + begin : 2018-05-02 + copyright : (C) 2018 by Universidad Nacional de Colombia - Sede Medellín + email : jctrujil@unal.edu.co + git sha : $Format:%H$ + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + This script initializes the plugin, making it known to QGIS. +""" + + +# noinspection PyPep8Naming +def classFactory(iface): # pylint: disable=invalid-name + """Load HydroSEDPlugin class from file HydroSEDPlugin. + + :param iface: A QGIS interface instance. + :type iface: QgisInterface + """ + # + from .HydroSEDPlugin import HydroSEDPlugin + return HydroSEDPlugin(iface) diff --git a/qgisplugin/help/Makefile b/qgisplugin/help/Makefile new file mode 100644 index 0000000..9def777 --- /dev/null +++ b/qgisplugin/help/Makefile @@ -0,0 +1,130 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/template_class.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/template_class.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/template_class" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/template_class" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + make -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/qgisplugin/help/make.bat b/qgisplugin/help/make.bat new file mode 100644 index 0000000..3377610 --- /dev/null +++ b/qgisplugin/help/make.bat @@ -0,0 +1,155 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\template_class.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\template_class.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end diff --git a/qgisplugin/help/source/conf.py b/qgisplugin/help/source/conf.py new file mode 100644 index 0000000..294bd08 --- /dev/null +++ b/qgisplugin/help/source/conf.py @@ -0,0 +1,216 @@ +# -*- coding: utf-8 -*- +# +# HydroSEDPlugin documentation build configuration file, created by +# sphinx-quickstart on Sun Feb 12 17:11:03 2012. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.todo', 'sphinx.ext.pngmath', 'sphinx.ext.viewcode'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'HydroSEDPlugin' +copyright = u'2013, Universidad Nacional de Colombia - Sede Medellín' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.1' +# The full version, including alpha/beta/rc tags. +release = '0.1' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_TemplateModuleNames = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'TemplateClassdoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +#latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'HydroSEDPlugin.tex', u'HydroSEDPlugin Documentation', + u'Universidad Nacional de Colombia - Sede Medellín', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'TemplateClass', u'HydroSEDPlugin Documentation', + [u'Universidad Nacional de Colombia - Sede Medellín'], 1) +] diff --git a/qgisplugin/help/source/index.rst b/qgisplugin/help/source/index.rst new file mode 100644 index 0000000..af4ac23 --- /dev/null +++ b/qgisplugin/help/source/index.rst @@ -0,0 +1,20 @@ +.. HydroSEDPlugin documentation master file, created by + sphinx-quickstart on Sun Feb 12 17:11:03 2012. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to HydroSEDPlugin's documentation! +============================================ + +Contents: + +.. toctree:: + :maxdepth: 2 + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/qgisplugin/i18n/af.ts b/qgisplugin/i18n/af.ts new file mode 100644 index 0000000..615a88c --- /dev/null +++ b/qgisplugin/i18n/af.ts @@ -0,0 +1,11 @@ + + + + @default + + + Good morning + Goeie more + + + diff --git a/qgisplugin/icon.png b/qgisplugin/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f696c00303219cfcc2f0d57608d04e298fbf56c3 GIT binary patch literal 1034 zcmV+l1oiugP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXD@ z77;9+NQ1io00W9iL_t(Y$E}r1Xk1ko$A9PCduQg(OlBrY(9Ks7iMEcmzAKc3;VzZCAM*45PN_;^e6>czpi>a)k;jWgn$XwX#(ffW0x= z+8`f&KFz}YS*DXYlF=gSn-KxzBG6N#o}Sbu5ylW$ifX;y!Gxcoccb7X?l*&Cg%BLp+upi(AsPbFBN>WXDC?; z&(>7p1`~%XZ)m0`uQ4(<$FhGH?|poXGiT2da3o4;)@nx9({OUBf@d^Etti_X6*QRt zM(yu64Vk}6JTN%G$V;!1TAbqGBW-lFx`bT|DMfv_l!BJF5c985o@kjA(}*tNFK{QCU>`#$u@1vR=}>qa5@&kCuGhvP`xkhN}@YN}=O zQj$Y2Uc!t58W8mdtiyG1gOY%=`Oqf#kFzPpKDdk-HFaxyemu%W41P&5^jJIh_B4=) zIRqS8AO73bJYStlGW|rdy4U))V9(wb+>k{~N-CaW{!Ycn!A{zChUn=E(`kQe>l33Is7?7;qutHE1STpm8YoYyRmhySVLwneD zILtlW(W=jJRx_{aH|L?0Ar`gK1}rHy^>Uk*mB7T>op^&oQzC$62^{-|!2sta za1=;y9wJfWb=kJ1ful09`}7PjxUqtpunAx=vHSGQzo6-Eu3FzqfdBvi07*qoM6N<$ Ef=x2zx&QzG literal 0 HcmV?d00001 diff --git a/qgisplugin/metadata.txt b/qgisplugin/metadata.txt new file mode 100644 index 0000000..f7b5cc7 --- /dev/null +++ b/qgisplugin/metadata.txt @@ -0,0 +1,39 @@ +# This file contains metadata for your plugin. Since +# version 2.0 of QGIS this is the proper way to supply +# information about a plugin. The old method of +# embedding metadata in __init__.py will +# is no longer supported since version 2.0. + +# This file should be included when you package your plugin.# Mandatory items: + +[general] +name=Hydro-SED +qgisMinimumVersion=2.0 +description=Este plugin facilita la ejecucion de modelos hidrologicos implementados desde QGIS. +version=0.1 +author=Universidad Nacional de Colombia - Sede Medellín +email=jctrujil@unal.edu.co + +about=Este plugin facilita la ejecucion de modelos hidrologicos implementados desde QGIS. + +tracker=https://github.com/nicolas998/wmf/issues/ +repository=https://github.com/nicolas998/wmf/ +# End of mandatory metadata + +# Recommended items: + +# Uncomment the following line and add your changelog: +# changelog= + +# Tags are comma separated with spaces allowed +tags=python wmf + +homepage=https://github.com/nicolas998/wmf/ +category=Plugins +icon=icon.png +# experimental flag +experimental=True + +# deprecated flag (applies to the whole plugin, not just a single version) +deprecated=False + diff --git a/qgisplugin/pb_tool.cfg b/qgisplugin/pb_tool.cfg new file mode 100644 index 0000000..0a74bde --- /dev/null +++ b/qgisplugin/pb_tool.cfg @@ -0,0 +1,74 @@ +#/*************************************************************************** +# HydroSEDPlugin +# +# Configuration file for plugin builder tool (pb_tool) +# ------------------- +# begin : 2018-05-02 +# copyright : (C) 2018 by Universidad Nacional de Colombia - Sede Medellín +# email : jctrujil@unal.edu.co +# ***************************************************************************/ +# +#/*************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License as published by * +# * the Free Software Foundation; either version 2 of the License, or * +# * (at your option) any later version. * +# * * +# ***************************************************************************/ +# +# +# You can install pb_tool using: +# pip install http://geoapt.net/files/pb_tool.zip +# +# Consider doing your development (and install of pb_tool) in a virtualenv. +# +# For details on setting up and using pb_tool, see: +# http://spatialgalaxy.net/qgis-plugin-development-with-pb_tool +# +# Issues and pull requests here: +# https://github.com/g-sherman/plugin_build_tool: +# +# Sane defaults for your plugin generated by the Plugin Builder are +# already set below. +# +# As you add Python source files and UI files to your plugin, add +# them to the appropriate [files] section below. + +[plugin] +# Name of the plugin. This is the name of the directory that will +# be created in .qgis2/python/plugins +name: HydroSEDPlugin + +[files] +# Python files that should be deployed with the plugin +python_files: __init__.py HydroSEDPlugin.py HydroSEDPlugin_dockwidget.py + +# The main dialog file that is loaded (not compiled) +main_dialog: HydroSEDPlugin_dockwidget_base.ui + +# Other ui files for dialogs you create (these will be compiled) +compiled_ui_files: + +# Resource file(s) that will be compiled +resource_files: resources.qrc + +# Other files required for the plugin +extras: metadata.txt icon.png + +# Other directories to be deployed with the plugin. +# These must be subdirectories under the plugin directory +extra_dirs: + +# ISO code(s) for any locales (translations), separated by spaces. +# Corresponding .ts files must exist in the i18n directory +locales: + +[help] +# the built help directory that should be deployed with the plugin +dir: help/build/html +# the name of the directory to target in the deployed plugin +target: help + + + diff --git a/qgisplugin/plugin_upload.py b/qgisplugin/plugin_upload.py new file mode 100755 index 0000000..8a23854 --- /dev/null +++ b/qgisplugin/plugin_upload.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python +# coding=utf-8 +"""This script uploads a plugin package on the server. + Authors: A. Pasotti, V. Picavet + git sha : $TemplateVCSFormat +""" + +import sys +import getpass +import xmlrpclib +from optparse import OptionParser + +# Configuration +PROTOCOL = 'http' +SERVER = 'plugins.qgis.org' +PORT = '80' +ENDPOINT = '/plugins/RPC2/' +VERBOSE = False + + +def main(parameters, arguments): + """Main entry point. + + :param parameters: Command line parameters. + :param arguments: Command line arguments. + """ + address = "%s://%s:%s@%s:%s%s" % ( + PROTOCOL, + parameters.username, + parameters.password, + parameters.server, + parameters.port, + ENDPOINT) + print "Connecting to: %s" % hide_password(address) + + server = xmlrpclib.ServerProxy(address, verbose=VERBOSE) + + try: + plugin_id, version_id = server.plugin.upload( + xmlrpclib.Binary(open(arguments[0]).read())) + print "Plugin ID: %s" % plugin_id + print "Version ID: %s" % version_id + except xmlrpclib.ProtocolError, err: + print "A protocol error occurred" + print "URL: %s" % hide_password(err.url, 0) + print "HTTP/HTTPS headers: %s" % err.headers + print "Error code: %d" % err.errcode + print "Error message: %s" % err.errmsg + except xmlrpclib.Fault, err: + print "A fault occurred" + print "Fault code: %d" % err.faultCode + print "Fault string: %s" % err.faultString + + +def hide_password(url, start=6): + """Returns the http url with password part replaced with '*'. + + :param url: URL to upload the plugin to. + :type url: str + + :param start: Position of start of password. + :type start: int + """ + start_position = url.find(':', start) + 1 + end_position = url.find('@') + return "%s%s%s" % ( + url[:start_position], + '*' * (end_position - start_position), + url[end_position:]) + + +if __name__ == "__main__": + parser = OptionParser(usage="%prog [options] plugin.zip") + parser.add_option( + "-w", "--password", dest="password", + help="Password for plugin site", metavar="******") + parser.add_option( + "-u", "--username", dest="username", + help="Username of plugin site", metavar="user") + parser.add_option( + "-p", "--port", dest="port", + help="Server port to connect to", metavar="80") + parser.add_option( + "-s", "--server", dest="server", + help="Specify server name", metavar="plugins.qgis.org") + options, args = parser.parse_args() + if len(args) != 1: + print "Please specify zip file.\n" + parser.print_help() + sys.exit(1) + if not options.server: + options.server = SERVER + if not options.port: + options.port = PORT + if not options.username: + # interactive mode + username = getpass.getuser() + print "Please enter user name [%s] :" % username, + res = raw_input() + if res != "": + options.username = res + else: + options.username = username + if not options.password: + # interactive mode + options.password = getpass.getpass() + main(options, args) diff --git a/qgisplugin/pylintrc b/qgisplugin/pylintrc new file mode 100644 index 0000000..7e168f6 --- /dev/null +++ b/qgisplugin/pylintrc @@ -0,0 +1,281 @@ +[MASTER] + +# Specify a configuration file. +#rcfile= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Profiled execution. +profile=no + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS + +# Pickle collected data for later comparisons. +persistent=yes + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + + +[MESSAGES CONTROL] + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time. See also the "--disable" option for examples. +#enable= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once).You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use"--disable=all --enable=classes +# --disable=W" +# see http://stackoverflow.com/questions/21487025/pylint-locally-defined-disables-still-give-warnings-how-to-suppress-them +disable=locally-disabled,C0103 + + +[REPORTS] + +# Set the output format. Available formats are text, parseable, colorized, msvs +# (visual studio) and html. You can also give a reporter class, eg +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Put messages in a separate file for each module / package specified on the +# command line instead of printing them on stdout. Reports (if any) will be +# written in a file name "pylint_global.[txt|html]". +files-output=no + +# Tells whether to display a full report or only the messages +reports=yes + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Add a comment according to your evaluation note. This is used by the global +# evaluation report (RP0004). +comment=no + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details +#msg-template= + + +[BASIC] + +# Required attributes for module, separated by a comma +required-attributes= + +# List of builtins function names that should not be used, separated by a comma +bad-functions=map,filter,apply,input + +# Regular expression which should only match correct module names +module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ + +# Regular expression which should only match correct module level names +const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ + +# Regular expression which should only match correct class names +class-rgx=[A-Z_][a-zA-Z0-9]+$ + +# Regular expression which should only match correct function names +function-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct method names +method-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct instance attribute names +attr-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct argument names +argument-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct variable names +variable-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct attribute names in class +# bodies +class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ + +# Regular expression which should only match correct list comprehension / +# generator expression variable names +inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ + +# Good variable names which should always be accepted, separated by a comma +good-names=i,j,k,ex,Run,_ + +# Bad variable names which should always be refused, separated by a comma +bad-names=foo,bar,baz,toto,tutu,tata + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=__.*__ + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME,XXX,TODO + + +[TYPECHECK] + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# List of classes names for which member attributes should not be checked +# (useful for classes with attributes dynamically set). +ignored-classes=SQLObject + +# When zope mode is activated, add a predefined set of Zope acquired attributes +# to generated-members. +zope=no + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E0201 when accessed. Python regular +# expressions are accepted. +generated-members=REQUEST,acl_users,aq_parent + + +[VARIABLES] + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# A regular expression matching the beginning of the name of dummy variables +# (i.e. not used). +dummy-variables-rgx=_$|dummy + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +additional-builtins= + + +[FORMAT] + +# Maximum number of characters on a single line. +max-line-length=80 + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + +# List of optional constructs for which whitespace checking is disabled +no-space-check=trailing-comma,dict-separator + +# Maximum number of lines in a module +max-module-lines=1000 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + + +[SIMILARITIES] + +# Minimum lines number of a similarity. +min-similarity-lines=4 + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=no + + +[IMPORTS] + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub,TERMIOS,Bastion,rexec + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled) +import-graph= + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled) +ext-import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled) +int-import-graph= + + +[DESIGN] + +# Maximum number of arguments for function / method +max-args=5 + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore +ignored-argument-names=_.* + +# Maximum number of locals for function / method body +max-locals=15 + +# Maximum number of return / yield for function / method body +max-returns=6 + +# Maximum number of branch for function / method body +max-branches=12 + +# Maximum number of statements in function / method body +max-statements=50 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + + +[CLASSES] + +# List of interface methods to ignore, separated by a comma. This is used for +# instance to not check methods defines in Zope's Interface base class. +ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__,__new__,setUp + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=mcs + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception" +overgeneral-exceptions=Exception diff --git a/qgisplugin/resources.py b/qgisplugin/resources.py new file mode 100644 index 0000000..8d99e4b --- /dev/null +++ b/qgisplugin/resources.py @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- + +# Resource object code +# +# Created by: The Resource Compiler for PyQt4 (Qt v4.8.7) +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore + +qt_resource_data = "\ +\x00\x00\x04\x0a\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x17\x00\x00\x00\x18\x08\x06\x00\x00\x00\x11\x7c\x66\x75\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ +\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\ +\x00\x9a\x9c\x18\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xd9\x02\x15\ +\x16\x11\x2c\x9d\x48\x83\xbb\x00\x00\x03\x8a\x49\x44\x41\x54\x48\ +\xc7\xad\x95\x4b\x68\x5c\x55\x18\xc7\x7f\xe7\xdc\x7b\x67\xe6\xce\ +\x4c\x66\x26\x49\xd3\x24\x26\xa6\xc6\xf8\x40\x21\xa5\x04\xb3\x28\ +\xda\x98\x20\xa5\x0b\xad\x55\xa8\x2b\xc5\x50\x1f\xa0\x6e\x34\x2b\ +\x45\x30\x14\x02\xba\x52\x69\x15\x17\x66\x63\x45\x97\x95\xa0\xad\ +\x0b\xfb\xc0\x06\x25\xb6\x71\x61\x12\x41\x50\xdb\x2a\x21\xd1\xe2\ +\x24\xf3\x9e\xc9\xcc\xbd\xe7\x1c\x17\x35\x43\x1e\x33\x21\xb6\xfd\ +\x56\x87\xf3\x9d\xfb\xfb\x1e\xf7\xff\x9d\x23\x8c\x31\x43\x95\xf4\ +\x85\x1e\x3f\x3b\x35\xac\xfd\xcc\x43\xdc\xa4\x49\x3b\xfe\x9d\x1d\ +\xdb\x7b\x22\x90\x78\xf8\xb2\x28\xa7\xbe\x7d\xc1\x4b\x9d\x79\xdf\ +\x18\x15\xe5\x16\x99\x10\x56\xde\x69\xdc\x3f\x22\xfd\xec\xd4\xf0\ +\xad\x04\x03\x18\xa3\xa2\x7e\x76\x6a\x58\xde\x68\x2b\xb4\x36\xf8\ +\xbe\xc6\x18\x53\xdb\xef\xe7\xfa\xec\xed\x67\x63\x10\x42\x00\xf0\ +\xfb\xd5\x65\x2a\x15\x45\xc7\x6d\x0d\x00\xc4\xa2\xc1\xaa\x6f\x0d\ +\x3e\x6c\xab\xc2\x1c\x56\xa4\x77\x4b\xb0\xf2\x35\x15\x5f\x21\x85\ +\xe0\xc8\x6b\x5f\x92\x2d\x37\x33\x39\xf9\x03\x27\x8e\x1f\xa2\xf7\ +\xbe\x9d\x04\x1c\x0b\x37\xe4\xac\xff\xa6\x30\x87\xbd\xba\x00\x6a\ +\x06\x79\xe5\xf5\xaf\x89\xd9\x92\xc5\xcc\x0a\xd9\x7c\x19\xcf\xe9\ +\xe2\xe4\xa9\x2f\x78\x7c\xff\x01\x72\x85\x0a\x2b\x65\x1f\xa5\x4c\ +\xb5\xb2\x55\x16\x80\xbd\x31\xda\xda\x20\x1f\x7d\x3e\xcd\xc2\xfd\ +\x59\xa6\x93\x39\x92\xd1\x22\xea\x9b\x16\xce\x9d\x3f\xce\xe0\x83\ +\x03\x24\x82\x59\x3a\xdb\x7b\x88\xc7\x82\x68\x63\x58\xc9\xcc\x62\ +\x8c\x21\x18\xb0\x6a\xc3\x37\x06\x49\x16\xff\x24\x6b\xa5\x49\xbb\ +\x25\xbc\xa2\xa6\x21\xbb\x40\x7f\xdf\x00\x83\xbd\x01\x8e\x3c\xd5\ +\x45\xd7\x8e\x6b\x9c\x9c\x98\x25\x1a\xb6\xe8\xbe\x3d\xc2\xdd\x77\ +\x44\x48\xc4\x1c\x22\xe1\xeb\x58\x59\xaf\xcf\xd3\x33\x29\x2e\x34\ +\x2d\x91\x93\x3e\xbe\x34\x78\x01\xc5\xe2\x61\xc5\xae\x72\x8e\x70\ +\xc8\xc2\x0d\x5a\xbc\xf5\xee\x2f\x9c\xfa\x3e\x86\x69\x7a\x8e\xcf\ +\x26\xe6\xf9\x63\xa1\x44\xa1\xa4\xd0\xda\x6c\x0d\x2f\x15\x7c\xb4\ +\x67\x28\x59\x0a\xcf\xd6\x54\xe2\x06\x13\x87\x2b\x6f\x68\xa6\x27\ +\xaf\x31\x32\x36\xc7\xb2\x7f\x17\xef\x7d\x7c\x8c\x33\x67\xcf\x12\ +\x70\x24\x4a\x69\xd6\x6a\x46\xd6\xd3\x70\x72\xa9\x82\x67\x34\x45\ +\xad\x28\xdb\x1a\x15\x34\x98\xff\x46\xed\xef\x37\x0d\x99\xbf\x4a\ +\x3c\x30\x38\xc0\xc8\x4b\xaf\x92\x5a\x9c\xe2\xe0\x23\x6d\x74\xb4\ +\xba\x84\x5d\x0b\x29\x45\x7d\xb8\x94\x82\x96\xb6\x10\xf3\xc5\x12\ +\x2a\xef\x53\x11\x1a\x63\xad\x3f\x93\x19\x85\xf1\xb1\x77\x58\x5a\ +\xf8\x99\x97\x9f\xe9\xa6\x75\x47\x90\xc6\xb8\x43\xd8\xb5\xb6\xce\ +\xfc\xfa\xfd\x00\xfb\x3e\xf4\xc8\x05\x35\xba\x5e\xeb\x46\x21\xf9\ +\xcf\x0a\xa9\x8c\x87\xe3\x48\xdc\x90\xb5\x6e\x98\x6a\xaa\x65\xf2\ +\x52\x92\x43\x2f\x5e\xc2\x8c\x02\x1a\x10\xf5\x07\xac\xc3\x75\x70\ +\x83\x92\x80\xb3\xf9\xd0\x26\xf8\x8f\xb3\x29\xc6\x3e\xb8\x8c\x19\ +\x35\x75\x6b\x7b\x7e\x3c\xca\x45\x0c\x7e\x49\x31\xf4\x58\x3b\xf7\ +\xf6\x34\x90\x88\x39\x04\x1c\x59\x1f\xfe\xdb\xd5\x3c\x5f\x9d\x4b\ +\x32\xfd\x44\xb2\xba\xd7\xfa\xb6\x60\xcf\xde\x16\xdc\x90\x45\x4c\ +\x4a\x2a\x9e\x62\xfe\x4e\xc5\xc8\xc1\x4e\xda\x76\x86\xe8\xe9\x0a\ +\xe3\xd8\x92\x58\xd4\xc6\xb2\x44\x6d\x78\x2a\x53\xe1\xca\x7c\x99\ +\x63\x5d\xbf\x56\x9d\xbd\x9f\x44\x18\x7a\xba\x95\x27\x0f\xb4\xd3\ +\xdc\x18\xc0\xf3\x0d\x52\x40\xd8\xb5\xb0\xa4\x20\x14\xb2\x70\x6c\ +\x81\x63\xcb\xaa\x42\xd6\xfd\xb7\xf4\xec\xa3\x06\xa0\x50\x52\xd8\ +\x4e\x1b\x7e\x4a\xd3\x31\xf9\x29\xcf\xfe\xd4\x49\x7f\x5f\x13\xfb\ +\xfa\x9b\x71\x43\x92\x58\xd4\x21\x18\x90\xac\xde\xb0\x42\x50\x13\ +\x58\x33\xf3\x88\x6b\xa1\xfd\x65\x96\xf2\x79\xc6\x43\x7b\xd8\x75\ +\x38\xcc\x3d\xdd\xd1\xaa\xcf\x71\xe4\xff\x7f\x91\x56\x33\xaf\xea\ +\x37\xe7\xa1\x94\x21\x16\xb5\xd1\x06\x2c\x29\x36\xf5\x72\x9b\x96\ +\x95\xc0\xc4\xda\x9d\x78\x83\x43\x53\x22\x80\x65\x09\x1c\xfb\x86\ +\xc1\x00\xe7\x25\x70\x14\x48\x6f\x1e\x22\x51\xe3\x75\xd9\xb6\xa5\ +\x81\xa3\x32\xb1\xfb\xf4\x0c\x30\xb8\xb1\x82\x9b\xb0\x09\x60\x30\ +\xb1\xfb\xf4\xcc\xbf\xa0\xe9\x6e\xae\x5a\xdf\x4b\x81\x00\x00\x00\ +\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +" + +qt_resource_name = "\ +\x00\x07\ +\x07\x3b\xe0\xb3\ +\x00\x70\ +\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\x00\x73\ +\x00\x0e\ +\x06\x01\x21\x3e\ +\x00\x48\ +\x00\x79\x00\x64\x00\x72\x00\x6f\x00\x53\x00\x45\x00\x44\x00\x50\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ +\x00\x08\ +\x0a\x61\x5a\xa7\ +\x00\x69\ +\x00\x63\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ +" + +qt_resource_struct = "\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ +\x00\x00\x00\x14\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\ +\x00\x00\x00\x36\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/qgisplugin/resources.qrc b/qgisplugin/resources.qrc new file mode 100644 index 0000000..7560345 --- /dev/null +++ b/qgisplugin/resources.qrc @@ -0,0 +1,5 @@ + + + icon.png + + diff --git a/qgisplugin/scripts/compile-strings.sh b/qgisplugin/scripts/compile-strings.sh new file mode 100644 index 0000000..9d76083 --- /dev/null +++ b/qgisplugin/scripts/compile-strings.sh @@ -0,0 +1,12 @@ +#!/bin/bash +LRELEASE=$1 +LOCALES=$2 + + +for LOCALE in ${LOCALES} +do + echo "Processing: ${LOCALE}.ts" + # Note we don't use pylupdate with qt .pro file approach as it is flakey + # about what is made available. + $LRELEASE i18n/${LOCALE}.ts +done diff --git a/qgisplugin/scripts/run-env-linux.sh b/qgisplugin/scripts/run-env-linux.sh new file mode 100644 index 0000000..668247c --- /dev/null +++ b/qgisplugin/scripts/run-env-linux.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +QGIS_PREFIX_PATH=/usr/local/qgis-2.0 +if [ -n "$1" ]; then + QGIS_PREFIX_PATH=$1 +fi + +echo ${QGIS_PREFIX_PATH} + + +export QGIS_PREFIX_PATH=${QGIS_PREFIX_PATH} +export QGIS_PATH=${QGIS_PREFIX_PATH} +export LD_LIBRARY_PATH=${QGIS_PREFIX_PATH}/lib +export PYTHONPATH=${QGIS_PREFIX_PATH}/share/qgis/python:${QGIS_PREFIX_PATH}/share/qgis/python/plugins:${PYTHONPATH} + +echo "QGIS PATH: $QGIS_PREFIX_PATH" +export QGIS_DEBUG=0 +export QGIS_LOG_FILE=/tmp/inasafe/realtime/logs/qgis.log + +export PATH=${QGIS_PREFIX_PATH}/bin:$PATH + +echo "This script is intended to be sourced to set up your shell to" +echo "use a QGIS 2.0 built in $QGIS_PREFIX_PATH" +echo +echo "To use it do:" +echo "source $BASH_SOURCE /your/optional/install/path" +echo +echo "Then use the make file supplied here e.g. make guitest" diff --git a/qgisplugin/scripts/update-strings.sh b/qgisplugin/scripts/update-strings.sh new file mode 100644 index 0000000..03dcfd7 --- /dev/null +++ b/qgisplugin/scripts/update-strings.sh @@ -0,0 +1,56 @@ +#!/bin/bash +LOCALES=$* + +# Get newest .py files so we don't update strings unnecessarily + +CHANGED_FILES=0 +PYTHON_FILES=`find . -regex ".*\(ui\|py\)$" -type f` +for PYTHON_FILE in $PYTHON_FILES +do + CHANGED=$(stat -c %Y $PYTHON_FILE) + if [ ${CHANGED} -gt ${CHANGED_FILES} ] + then + CHANGED_FILES=${CHANGED} + fi +done + +# Qt translation stuff +# for .ts file +UPDATE=false +for LOCALE in ${LOCALES} +do + TRANSLATION_FILE="i18n/$LOCALE.ts" + if [ ! -f ${TRANSLATION_FILE} ] + then + # Force translation string collection as we have a new language file + touch ${TRANSLATION_FILE} + UPDATE=true + break + fi + + MODIFICATION_TIME=$(stat -c %Y ${TRANSLATION_FILE}) + if [ ${CHANGED_FILES} -gt ${MODIFICATION_TIME} ] + then + # Force translation string collection as a .py file has been updated + UPDATE=true + break + fi +done + +if [ ${UPDATE} == true ] +# retrieve all python files +then + print ${PYTHON_FILES} + # update .ts + echo "Please provide translations by editing the translation files below:" + for LOCALE in ${LOCALES} + do + echo "i18n/"${LOCALE}".ts" + # Note we don't use pylupdate with qt .pro file approach as it is flakey + # about what is made available. + pylupdate4 -noobsolete ${PYTHON_FILES} -ts i18n/${LOCALE}.ts + done +else + echo "No need to edit any translation files (.ts) because no python files" + echo "has been updated since the last update translation. " +fi diff --git a/qgisplugin/test/__init__.py b/qgisplugin/test/__init__.py new file mode 100644 index 0000000..8feeb0b --- /dev/null +++ b/qgisplugin/test/__init__.py @@ -0,0 +1,2 @@ +# import qgis libs so that ve set the correct sip api version +import qgis # pylint: disable=W0611 # NOQA \ No newline at end of file diff --git a/qgisplugin/test/qgis_interface.py b/qgisplugin/test/qgis_interface.py new file mode 100644 index 0000000..607c100 --- /dev/null +++ b/qgisplugin/test/qgis_interface.py @@ -0,0 +1,205 @@ +# coding=utf-8 +"""QGIS plugin implementation. + +.. note:: This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + +.. note:: This source code was copied from the 'postgis viewer' application + with original authors: + Copyright (c) 2010 by Ivan Mincik, ivan.mincik@gista.sk + Copyright (c) 2011 German Carrillo, geotux_tuxman@linuxmail.org + Copyright (c) 2014 Tim Sutton, tim@linfiniti.com + +""" + +__author__ = 'tim@linfiniti.com' +__revision__ = '$Format:%H$' +__date__ = '10/01/2011' +__copyright__ = ( + 'Copyright (c) 2010 by Ivan Mincik, ivan.mincik@gista.sk and ' + 'Copyright (c) 2011 German Carrillo, geotux_tuxman@linuxmail.org' + 'Copyright (c) 2014 Tim Sutton, tim@linfiniti.com' +) + +import logging +from PyQt4.QtCore import QObject, pyqtSlot, pyqtSignal +from qgis.core import QgsMapLayerRegistry +from qgis.gui import QgsMapCanvasLayer +LOGGER = logging.getLogger('QGIS') + + +#noinspection PyMethodMayBeStatic,PyPep8Naming +class QgisInterface(QObject): + """Class to expose QGIS objects and functions to plugins. + + This class is here for enabling us to run unit tests only, + so most methods are simply stubs. + """ + currentLayerChanged = pyqtSignal(QgsMapCanvasLayer) + + def __init__(self, canvas): + """Constructor + :param canvas: + """ + QObject.__init__(self) + self.canvas = canvas + # Set up slots so we can mimic the behaviour of QGIS when layers + # are added. + LOGGER.debug('Initialising canvas...') + # noinspection PyArgumentList + QgsMapLayerRegistry.instance().layersAdded.connect(self.addLayers) + # noinspection PyArgumentList + QgsMapLayerRegistry.instance().layerWasAdded.connect(self.addLayer) + # noinspection PyArgumentList + QgsMapLayerRegistry.instance().removeAll.connect(self.removeAllLayers) + + # For processing module + self.destCrs = None + + @pyqtSlot('QStringList') + def addLayers(self, layers): + """Handle layers being added to the registry so they show up in canvas. + + :param layers: list list of map layers that were added + + .. note:: The QgsInterface api does not include this method, + it is added here as a helper to facilitate testing. + """ + #LOGGER.debug('addLayers called on qgis_interface') + #LOGGER.debug('Number of layers being added: %s' % len(layers)) + #LOGGER.debug('Layer Count Before: %s' % len(self.canvas.layers())) + current_layers = self.canvas.layers() + final_layers = [] + for layer in current_layers: + final_layers.append(QgsMapCanvasLayer(layer)) + for layer in layers: + final_layers.append(QgsMapCanvasLayer(layer)) + + self.canvas.setLayerSet(final_layers) + #LOGGER.debug('Layer Count After: %s' % len(self.canvas.layers())) + + @pyqtSlot('QgsMapLayer') + def addLayer(self, layer): + """Handle a layer being added to the registry so it shows up in canvas. + + :param layer: list list of map layers that were added + + .. note: The QgsInterface api does not include this method, it is added + here as a helper to facilitate testing. + + .. note: The addLayer method was deprecated in QGIS 1.8 so you should + not need this method much. + """ + pass + + @pyqtSlot() + def removeAllLayers(self): + """Remove layers from the canvas before they get deleted.""" + self.canvas.setLayerSet([]) + + def newProject(self): + """Create new project.""" + # noinspection PyArgumentList + QgsMapLayerRegistry.instance().removeAllMapLayers() + + # ---------------- API Mock for QgsInterface follows ------------------- + + def zoomFull(self): + """Zoom to the map full extent.""" + pass + + def zoomToPrevious(self): + """Zoom to previous view extent.""" + pass + + def zoomToNext(self): + """Zoom to next view extent.""" + pass + + def zoomToActiveLayer(self): + """Zoom to extent of active layer.""" + pass + + def addVectorLayer(self, path, base_name, provider_key): + """Add a vector layer. + + :param path: Path to layer. + :type path: str + + :param base_name: Base name for layer. + :type base_name: str + + :param provider_key: Provider key e.g. 'ogr' + :type provider_key: str + """ + pass + + def addRasterLayer(self, path, base_name): + """Add a raster layer given a raster layer file name + + :param path: Path to layer. + :type path: str + + :param base_name: Base name for layer. + :type base_name: str + """ + pass + + def activeLayer(self): + """Get pointer to the active layer (layer selected in the legend).""" + # noinspection PyArgumentList + layers = QgsMapLayerRegistry.instance().mapLayers() + for item in layers: + return layers[item] + + def addToolBarIcon(self, action): + """Add an icon to the plugins toolbar. + + :param action: Action to add to the toolbar. + :type action: QAction + """ + pass + + def removeToolBarIcon(self, action): + """Remove an action (icon) from the plugin toolbar. + + :param action: Action to add to the toolbar. + :type action: QAction + """ + pass + + def addToolBar(self, name): + """Add toolbar with specified name. + + :param name: Name for the toolbar. + :type name: str + """ + pass + + def mapCanvas(self): + """Return a pointer to the map canvas.""" + return self.canvas + + def mainWindow(self): + """Return a pointer to the main window. + + In case of QGIS it returns an instance of QgisApp. + """ + pass + + def addDockWidget(self, area, dock_widget): + """Add a dock widget to the main window. + + :param area: Where in the ui the dock should be placed. + :type area: + + :param dock_widget: A dock widget to add to the UI. + :type dock_widget: QDockWidget + """ + pass + + def legendInterface(self): + """Get the legend.""" + return self.canvas diff --git a/qgisplugin/test/tenbytenraster.asc b/qgisplugin/test/tenbytenraster.asc new file mode 100644 index 0000000..96a0ee1 --- /dev/null +++ b/qgisplugin/test/tenbytenraster.asc @@ -0,0 +1,19 @@ +NCOLS 10 +NROWS 10 +XLLCENTER 1535380.000000 +YLLCENTER 5083260.000000 +DX 10 +DY 10 +NODATA_VALUE -9999 +0 1 2 3 4 5 6 7 8 9 +0 1 2 3 4 5 6 7 8 9 +0 1 2 3 4 5 6 7 8 9 +0 1 2 3 4 5 6 7 8 9 +0 1 2 3 4 5 6 7 8 9 +0 1 2 3 4 5 6 7 8 9 +0 1 2 3 4 5 6 7 8 9 +0 1 2 3 4 5 6 7 8 9 +0 1 2 3 4 5 6 7 8 9 +0 1 2 3 4 5 6 7 8 9 +CRS +NOTES diff --git a/qgisplugin/test/tenbytenraster.asc.aux.xml b/qgisplugin/test/tenbytenraster.asc.aux.xml new file mode 100644 index 0000000..cfb1578 --- /dev/null +++ b/qgisplugin/test/tenbytenraster.asc.aux.xml @@ -0,0 +1,13 @@ + + + Point + + + + 9 + 4.5 + 0 + 2.872281323269 + + + diff --git a/qgisplugin/test/tenbytenraster.keywords b/qgisplugin/test/tenbytenraster.keywords new file mode 100644 index 0000000..8be3f61 --- /dev/null +++ b/qgisplugin/test/tenbytenraster.keywords @@ -0,0 +1 @@ +title: Tenbytenraster diff --git a/qgisplugin/test/tenbytenraster.lic b/qgisplugin/test/tenbytenraster.lic new file mode 100644 index 0000000..8345533 --- /dev/null +++ b/qgisplugin/test/tenbytenraster.lic @@ -0,0 +1,18 @@ + + + + Tim Sutton, Linfiniti Consulting CC + + + + tenbytenraster.asc + 2700044251 + Yes + Tim Sutton + Tim Sutton (QGIS Source Tree) + Tim Sutton + This data is publicly available from QGIS Source Tree. The original + file was created and contributed to QGIS by Tim Sutton. + + + diff --git a/qgisplugin/test/tenbytenraster.prj b/qgisplugin/test/tenbytenraster.prj new file mode 100644 index 0000000..a30c00a --- /dev/null +++ b/qgisplugin/test/tenbytenraster.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] \ No newline at end of file diff --git a/qgisplugin/test/tenbytenraster.qml b/qgisplugin/test/tenbytenraster.qml new file mode 100644 index 0000000..85247d4 --- /dev/null +++ b/qgisplugin/test/tenbytenraster.qml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 0 + diff --git a/qgisplugin/test/test_HydroSEDPlugin_dockwidget.py b/qgisplugin/test/test_HydroSEDPlugin_dockwidget.py new file mode 100644 index 0000000..791155d --- /dev/null +++ b/qgisplugin/test/test_HydroSEDPlugin_dockwidget.py @@ -0,0 +1,45 @@ +# coding=utf-8 +"""DockWidget test. + +.. note:: This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + +""" + +__author__ = 'jctrujil@unal.edu.co' +__date__ = '2018-05-02' +__copyright__ = 'Copyright 2018, Universidad Nacional de Colombia - Sede Medellín' + +import unittest + +from PyQt4.QtGui import QDockWidget + +from HydroSEDPlugin_dockwidget import HydroSEDPluginDockWidget + +from utilities import get_qgis_app + +QGIS_APP = get_qgis_app() + + +class HydroSEDPluginDockWidgetTest(unittest.TestCase): + """Test dockwidget works.""" + + def setUp(self): + """Runs before each test.""" + self.dockwidget = HydroSEDPluginDockWidget(None) + + def tearDown(self): + """Runs after each test.""" + self.dockwidget = None + + def test_dockwidget_ok(self): + """Test we can click OK.""" + pass + +if __name__ == "__main__": + suite = unittest.makeSuite(HydroSEDPluginDialogTest) + runner = unittest.TextTestRunner(verbosity=2) + runner.run(suite) + diff --git a/qgisplugin/test/test_init.py b/qgisplugin/test/test_init.py new file mode 100644 index 0000000..923ce83 --- /dev/null +++ b/qgisplugin/test/test_init.py @@ -0,0 +1,64 @@ +# coding=utf-8 +"""Tests QGIS plugin init.""" + +__author__ = 'Tim Sutton ' +__revision__ = '$Format:%H$' +__date__ = '17/10/2010' +__license__ = "GPL" +__copyright__ = 'Copyright 2012, Australia Indonesia Facility for ' +__copyright__ += 'Disaster Reduction' + +import os +import unittest +import logging +import ConfigParser + +LOGGER = logging.getLogger('QGIS') + + +class TestInit(unittest.TestCase): + """Test that the plugin init is usable for QGIS. + + Based heavily on the validator class by Alessandro + Passoti available here: + + http://github.com/qgis/qgis-django/blob/master/qgis-app/ + plugins/validator.py + + """ + + def test_read_init(self): + """Test that the plugin __init__ will validate on plugins.qgis.org.""" + + # You should update this list according to the latest in + # https://github.com/qgis/qgis-django/blob/master/qgis-app/ + # plugins/validator.py + + required_metadata = [ + 'name', + 'description', + 'version', + 'qgisMinimumVersion', + 'email', + 'author'] + + file_path = os.path.abspath(os.path.join( + os.path.dirname(__file__), os.pardir, + 'metadata.txt')) + LOGGER.info(file_path) + metadata = [] + parser = ConfigParser.ConfigParser() + parser.optionxform = str + parser.read(file_path) + message = 'Cannot find a section named "general" in %s' % file_path + assert parser.has_section('general'), message + metadata.extend(parser.items('general')) + + for expectation in required_metadata: + message = ('Cannot find metadata "%s" in metadata source (%s).' % ( + expectation, file_path)) + + self.assertIn(expectation, dict(metadata), message) + +if __name__ == '__main__': + unittest.main() diff --git a/qgisplugin/test/test_qgis_environment.py b/qgisplugin/test/test_qgis_environment.py new file mode 100644 index 0000000..8372c55 --- /dev/null +++ b/qgisplugin/test/test_qgis_environment.py @@ -0,0 +1,60 @@ +# coding=utf-8 +"""Tests for QGIS functionality. + + +.. note:: This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + +""" +__author__ = 'tim@linfiniti.com' +__date__ = '20/01/2011' +__copyright__ = ('Copyright 2012, Australia Indonesia Facility for ' + 'Disaster Reduction') + +import os +import unittest +from qgis.core import ( + QgsProviderRegistry, + QgsCoordinateReferenceSystem, + QgsRasterLayer) + +from utilities import get_qgis_app +QGIS_APP = get_qgis_app() + + +class QGISTest(unittest.TestCase): + """Test the QGIS Environment""" + + def test_qgis_environment(self): + """QGIS environment has the expected providers""" + + r = QgsProviderRegistry.instance() + self.assertIn('gdal', r.providerList()) + self.assertIn('ogr', r.providerList()) + self.assertIn('postgres', r.providerList()) + + def test_projection(self): + """Test that QGIS properly parses a wkt string. + """ + crs = QgsCoordinateReferenceSystem() + wkt = ( + 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",' + 'SPHEROID["WGS_1984",6378137.0,298.257223563]],' + 'PRIMEM["Greenwich",0.0],UNIT["Degree",' + '0.0174532925199433]]') + crs.createFromWkt(wkt) + auth_id = crs.authid() + expected_auth_id = 'EPSG:4326' + self.assertEqual(auth_id, expected_auth_id) + + # now test for a loaded layer + path = os.path.join(os.path.dirname(__file__), 'tenbytenraster.asc') + title = 'TestRaster' + layer = QgsRasterLayer(path, title) + auth_id = layer.crs().authid() + self.assertEqual(auth_id, expected_auth_id) + +if __name__ == '__main__': + unittest.main() diff --git a/qgisplugin/test/test_resources.py b/qgisplugin/test/test_resources.py new file mode 100644 index 0000000..61df170 --- /dev/null +++ b/qgisplugin/test/test_resources.py @@ -0,0 +1,44 @@ +# coding=utf-8 +"""Resources test. + +.. note:: This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + +""" + +__author__ = 'jctrujil@unal.edu.co' +__date__ = '2018-05-02' +__copyright__ = 'Copyright 2018, Universidad Nacional de Colombia - Sede Medellín' + +import unittest + +from PyQt4.QtGui import QIcon + + + +class HydroSEDPluginDialogTest(unittest.TestCase): + """Test rerources work.""" + + def setUp(self): + """Runs before each test.""" + pass + + def tearDown(self): + """Runs after each test.""" + pass + + def test_icon_png(self): + """Test we can click OK.""" + path = ':/plugins/HydroSEDPlugin/icon.png' + icon = QIcon(path) + self.assertFalse(icon.isNull()) + +if __name__ == "__main__": + suite = unittest.makeSuite(HydroSEDPluginResourcesTest) + runner = unittest.TextTestRunner(verbosity=2) + runner.run(suite) + + + diff --git a/qgisplugin/test/test_translations.py b/qgisplugin/test/test_translations.py new file mode 100644 index 0000000..862b342 --- /dev/null +++ b/qgisplugin/test/test_translations.py @@ -0,0 +1,55 @@ +# coding=utf-8 +"""Safe Translations Test. + +.. note:: This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + +""" +from utilities import get_qgis_app + +__author__ = 'ismailsunni@yahoo.co.id' +__date__ = '12/10/2011' +__copyright__ = ('Copyright 2012, Australia Indonesia Facility for ' + 'Disaster Reduction') +import unittest +import os + +from PyQt4.QtCore import QCoreApplication, QTranslator + +QGIS_APP = get_qgis_app() + + +class SafeTranslationsTest(unittest.TestCase): + """Test translations work.""" + + def setUp(self): + """Runs before each test.""" + if 'LANG' in os.environ.iterkeys(): + os.environ.__delitem__('LANG') + + def tearDown(self): + """Runs after each test.""" + if 'LANG' in os.environ.iterkeys(): + os.environ.__delitem__('LANG') + + def test_qgis_translations(self): + """Test that translations work.""" + parent_path = os.path.join(__file__, os.path.pardir, os.path.pardir) + dir_path = os.path.abspath(parent_path) + file_path = os.path.join( + dir_path, 'i18n', 'af.qm') + translator = QTranslator() + translator.load(file_path) + QCoreApplication.installTranslator(translator) + + expected_message = 'Goeie more' + real_message = QCoreApplication.translate("@default", 'Good morning') + self.assertEqual(real_message, expected_message) + + +if __name__ == "__main__": + suite = unittest.makeSuite(SafeTranslationsTest) + runner = unittest.TextTestRunner(verbosity=2) + runner.run(suite) diff --git a/qgisplugin/test/utilities.py b/qgisplugin/test/utilities.py new file mode 100644 index 0000000..0f4d965 --- /dev/null +++ b/qgisplugin/test/utilities.py @@ -0,0 +1,61 @@ +# coding=utf-8 +"""Common functionality used by regression tests.""" + +import sys +import logging + + +LOGGER = logging.getLogger('QGIS') +QGIS_APP = None # Static variable used to hold hand to running QGIS app +CANVAS = None +PARENT = None +IFACE = None + + +def get_qgis_app(): + """ Start one QGIS application to test against. + + :returns: Handle to QGIS app, canvas, iface and parent. If there are any + errors the tuple members will be returned as None. + :rtype: (QgsApplication, CANVAS, IFACE, PARENT) + + If QGIS is already running the handle to that app will be returned. + """ + + try: + from PyQt4 import QtGui, QtCore + from qgis.core import QgsApplication + from qgis.gui import QgsMapCanvas + from qgis_interface import QgisInterface + except ImportError: + return None, None, None, None + + global QGIS_APP # pylint: disable=W0603 + + if QGIS_APP is None: + gui_flag = True # All test will run qgis in gui mode + #noinspection PyPep8Naming + QGIS_APP = QgsApplication(sys.argv, gui_flag) + # Make sure QGIS_PREFIX_PATH is set in your env if needed! + QGIS_APP.initQgis() + s = QGIS_APP.showSettings() + LOGGER.debug(s) + + global PARENT # pylint: disable=W0603 + if PARENT is None: + #noinspection PyPep8Naming + PARENT = QtGui.QWidget() + + global CANVAS # pylint: disable=W0603 + if CANVAS is None: + #noinspection PyPep8Naming + CANVAS = QgsMapCanvas(PARENT) + CANVAS.resize(QtCore.QSize(400, 400)) + + global IFACE # pylint: disable=W0603 + if IFACE is None: + # QgisInterface is a stub implementation of the QGIS plugin interface + #noinspection PyPep8Naming + IFACE = QgisInterface(CANVAS) + + return QGIS_APP, CANVAS, IFACE, PARENT From 58c1906d02b1eba1bebd5d53e85200b118d474a6 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 3 May 2018 11:10:00 -0500 Subject: [PATCH 002/142] cambios menores en los botones del .ui --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 67 +++++++++++++++----- 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 3e3c91c..e6baadd 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -60,7 +60,7 @@ Explorador Binarios *.nc - + 10 @@ -72,6 +72,12 @@ + + <html><head/><body><p>Seleccionar ruta al archivo .nc con la topología de la cuenca.</p></body></html> + + + <html><head/><body><p>Seleccionar ruta al archivo .nc con la topología de la cuenca.</p></body></html> + Path Archivos Binarios *.nc @@ -113,7 +119,7 @@ - + 10 @@ -125,8 +131,14 @@ + + <html><head/><body><p>Dirección al MDE (modelo digital de elevación), este se usa como base para un proyecto.</p></body></html> + + + <html><head/><body><p>Dirección al MDE (modelo digital de elevación), este se usa como base para un proyecto.</p></body></html> + - Mapa DEM: + Mapa MDE: @@ -162,6 +174,12 @@ + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + Mapa DIR: @@ -199,6 +217,12 @@ + + <html><head/><body><p>Umbral de celdas necesarias (100) para que se genere red hídrica en la cuenca.</p></body></html> + + + <html><head/><body><p>Umbral de celdas necesarias (100) para que se genere red hídrica en la cuenca.</p></body></html> + Umbral: @@ -213,6 +237,29 @@ + + + + 10 + 490 + 341 + 221 + + + + + + + 10 + 470 + 241 + 17 + + + + Variables archivo de cuenca .nc + + @@ -245,7 +292,7 @@ Cuencas: - + 10 @@ -412,18 +459,8 @@ - labelLatitudTrazadorCuencas - labelLongitudTrazadorCuencas - labelInputCorrienteShapefileTrazadorCuencas - labelOutputTrazadorCuencasShapefile - spinBoxLatitudTrazadorCuencas - spinBoxLongitudTrazadorCuencas - layoutWidget_4 - lineEditInputCorrienteShapefileTrazadorCuencas - layoutWidget_5 - layoutWidget_6 - + 10 From a3803b30f1d828bbdcdee904b9a5ac975872d38b Mon Sep 17 00:00:00 2001 From: camilo2046 Date: Thu, 3 May 2018 14:43:30 -0500 Subject: [PATCH 003/142] Se agrega tab de Hidrologia - Se elimina temporal de backup .ui --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 7 +- .../HydroSEDPlugin_dockwidget_base.ui.save.1 | 339 ------------------ 2 files changed, 6 insertions(+), 340 deletions(-) delete mode 100644 qgisplugin/HydroSEDPlugin_dockwidget_base.ui.save.1 diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index e6baadd..3b59320 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -27,7 +27,7 @@ - 0 + 2 @@ -558,6 +558,11 @@ + + + Hidrologia + + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui.save.1 b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui.save.1 deleted file mode 100644 index bea30db..0000000 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui.save.1 +++ /dev/null @@ -1,339 +0,0 @@ - - - HydroSEDPluginDockWidgetBase - - - - 0 - 0 - 383 - 869 - - - - - 0 - 0 - - - - 0.500000000000000 - - - Hydro-SED - - - - - - - 1 - - - - Configuración - - - - - 0 - 0 - 361 - 451 - - - - - - - Configuración General - - - - - 9 - 20 - 341 - 191 - - - - - - - Mapa DEM: - - - - - - - - - - Mapa DIR: - - - - - - - - - - Umbral: - - - - - - - - - - - - 0 - 230 - 359 - 211 - - - - Explorador Binarios *.nc - - - - - 10 - 30 - 341 - 181 - - - - - - - Path Archivos Binarios *.nc - - - - - - - - - - - - - - - - - - - - Trazadores - - - - - 0 - 0 - 361 - 641 - - - - - - - Corrientes: - - - - - 10 - 250 - 359 - 371 - - - - Cuencas: - - - - - 1 - 21 - 341 - 341 - - - - - - - Latitud: - - - - - - - - - - Longitud: - - - - - - - - - - Path Corriente: - - - - - - - - - - Path Salida (*.shp): - - - - - - - - - - Path Salida (*.nc): - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Ejecutar Trazador - - - - - - - - - - - - 11 - 21 - 341 - 221 - - - - - - - Latitud: - - - - - - - - - - Longitud: - - - - - - - - - - Path Salida (*.shp): - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Ejecutar Trazador - - - - - - - - - - - - - - - - - - - - QgsFileWidget - QWidget -
qgsfilewidget.h
-
-
- - -
From 99b37e8074d959efc6923f63f91f3421ce7ed4b7 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 3 May 2018 14:48:33 -0500 Subject: [PATCH 004/142] pone tab de geomorfologia --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 3b59320..bf0fde4 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -560,7 +560,12 @@
- Hidrologia + Hidrología + + + + + Geomorfología
From e29842d94e55ef854290c72fe7c30189ab5b4ca1 Mon Sep 17 00:00:00 2001 From: camilo2046 Date: Thu, 3 May 2018 14:59:24 -0500 Subject: [PATCH 005/142] Prueba para el fork --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 41 +++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index bf0fde4..174e365 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -27,7 +27,7 @@ - 2 + 3 @@ -562,11 +562,50 @@ Hidrología + + + + 60 + 50 + 99 + 27 + + + + PushButton + + Geomorfología + + + + 110 + 50 + 99 + 27 + + + + PushButton + + + + + + 130 + 100 + 99 + 27 + + + + PushButton + + From 020af4868f8b7634000cd0e100a2c309ed1e7513 Mon Sep 17 00:00:00 2001 From: camilo2046 Date: Fri, 4 May 2018 12:56:10 -0500 Subject: [PATCH 006/142] Cambios PluginQGIS: HydroSEDPlugin_dockwidget_base.ui (Elimine botones innecesarios en tabs) HydroSEDPlugin.py Se cambia constructor referenciado de HydroSEDPlugin_dockwidget para enviar el iface y poder cargar las capas desde alli HydroSEDPlugin_dockwidget.py Constructor (Para pasar el iface de QGIS) y poder agregar la capa desde la vista interna setupLineEditButtonOpenShapeFileDialog (Metodo para el selector de archivos pero cargando la capa y restringiendo solo a archivos *.shp) Se modificaron los selectores de DEM/DIR/Corriente (Para Cuenca) para que usen este nuevo metodo y carguen la capa automaticamente --- qgisplugin/HydroSEDPlugin.py | 2 +- qgisplugin/HydroSEDPlugin_dockwidget.py | 24 ++++++++++-- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 41 +------------------- 3 files changed, 22 insertions(+), 45 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin.py b/qgisplugin/HydroSEDPlugin.py index 69d39a2..a170728 100644 --- a/qgisplugin/HydroSEDPlugin.py +++ b/qgisplugin/HydroSEDPlugin.py @@ -221,7 +221,7 @@ def run(self): # removed on close (see self.onClosePlugin method) if self.dockwidget == None: # Create the dockwidget (after translation) and keep reference - self.dockwidget = HydroSEDPluginDockWidget() + self.dockwidget = HydroSEDPluginDockWidget(iface = self.iface) # connect to provide cleanup on closing of dockwidget self.dockwidget.closingPlugin.connect(self.onClosePlugin) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 37d3f97..0b56a28 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -29,6 +29,8 @@ from qgis.gui import QgsMessageBar from PyQt4.QtGui import QFileDialog +import os.path + from wmf import wmf FORM_CLASS, _ = uic.loadUiType(os.path.join( @@ -39,7 +41,7 @@ class HydroSEDPluginDockWidget(QtGui.QDockWidget, FORM_CLASS): closingPlugin = pyqtSignal() - def __init__(self, parent=None): + def __init__(self, iface = None, parent=None): """Constructor.""" super(HydroSEDPluginDockWidget, self).__init__(parent) @@ -52,6 +54,9 @@ def __init__(self, parent=None): self.setupUIInputsOutputs () self.setupUIButtonEvents () + if not (iface is None): + self.iface = iface + def closeEvent(self, event): self.closingPlugin.emit() @@ -83,6 +88,14 @@ def handleClickEventEjecutarTrazadorCuencas (self): def setupUIInputsOutputs (self): + def setupLineEditButtonOpenShapeFileDialog (lineEditHolder, fileDialogHolder): + + lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Shapefiles (*.shp);;")) + + if ((os.path.exists (lineEditHolder.text ().strip ())) and (not (self.iface is None))): + + self.iface.addVectorLayer (lineEditHolder.text ().strip (), os.path.basename (lineEditHolder.text ()).strip (), "ogr") + def setupLineEditButtonOpenFileDialog (lineEditHolder, fileDialogHolder): lineEditHolder.setText (fileDialogHolder.getOpenFileName ()) @@ -93,11 +106,13 @@ def setupLineEditButtonSaveFileDialog (lineEditHolder, fileDialogHolder): def clickEventSelectorMapaDEM (): - setupLineEditButtonOpenFileDialog (self.lineEditMapaDEM, QFileDialog) +# setupLineEditButtonOpenFileDialog (self.lineEditMapaDEM, QFileDialog) + setupLineEditButtonOpenShapeFileDialog (self.lineEditMapaDEM, QFileDialog) def clickEventSelectorMapaDIR (): - setupLineEditButtonOpenFileDialog (self.lineEditMapaDIR, QFileDialog) +# setupLineEditButtonOpenFileDialog (self.lineEditMapaDIR, QFileDialog) + setupLineEditButtonOpenShapeFileDialog (self.lineEditMapaDIR, QFileDialog) def clickEventSelectorBinarioNC (): @@ -109,7 +124,8 @@ def clickEventSelectorOutputCorrienteShapefileTrazadorCorrientes (): def clickEventSelectorInputCorrienteShapefileTrazadorCuencas (): - setupLineEditButtonOpenFileDialog (self.lineEditInputCorrienteShapefileTrazadorCuencas, QFileDialog) +# setupLineEditButtonOpenFileDialog (self.lineEditInputCorrienteShapefileTrazadorCuencas, QFileDialog) + setupLineEditButtonOpenShapeFileDialog (self.lineEditInputCorrienteShapefileTrazadorCuencas, QFileDialog) def clickEventSelectorOutputCuencaShapefileTrazadorCuencas (): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 174e365..2149796 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -27,7 +27,7 @@ - 3 + 0 @@ -562,50 +562,11 @@ Hidrología - - - - 60 - 50 - 99 - 27 - - - - PushButton - - Geomorfología - - - - 110 - 50 - 99 - 27 - - - - PushButton - - - - - - 130 - 100 - 99 - 27 - - - - PushButton - - From cf84a9e7bf4447b3be57863b5166a548874017a6 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 7 May 2018 09:27:08 -0500 Subject: [PATCH 007/142] se agregan iconos --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 279 ++++++++++++++++--- qgisplugin/resources.qrc | 9 +- 2 files changed, 245 insertions(+), 43 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 2149796..7e560a8 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -6,7 +6,7 @@ 0 0 - 383 + 391 869 @@ -27,11 +27,15 @@ - 0 + 1 + + + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png + - Configuración + @@ -39,7 +43,7 @@ 0 0 361 - 451 + 781 @@ -52,9 +56,9 @@ 0 - 230 + 330 359 - 211 + 451 @@ -66,7 +70,7 @@ 10 31 341 - 181 + 361 @@ -107,7 +111,11 @@ - ... + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -116,6 +124,48 @@ + + + + Variables archivo de cuenca .nc + + + + + + + + + + + + 10 + 400 + 341 + 41 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Cargar Variable + + + @@ -125,7 +175,7 @@ 10 21 341 - 201 + 301 @@ -166,7 +216,48 @@ - ... + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + <html><head/><body><p>Carga el MDE en el layout de mapas de Qgis.</p></body></html> + + + Visualizar + + + + + + + <html><head/><body><p>Establece el MDE y sus propiedades como el mapa base para WMF.</p></body></html> + + + Cargar @@ -209,59 +300,87 @@ - ... + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + <html><head/><body><p>Carga el DIR en el layout de mapas de Qgis.</p></body></html> + + + Visualizar + + + + + + + <html><head/><body><p>Establece el DIR y sus propiedades como el mapa base para WMF.</p></body></html> + + + Cargar + + + + + + + - <html><head/><body><p>Umbral de celdas necesarias (100) para que se genere red hídrica en la cuenca.</p></body></html> + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - <html><head/><body><p>Umbral de celdas necesarias (100) para que se genere red hídrica en la cuenca.</p></body></html> + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Umbral: + Propiedades mapas - + + labelDIR_2 + labelDEM + labelDIR + horizontalLayoutWidget + horizontalLayoutWidget_2 + tableView - - - - 10 - 490 - 341 - 221 - - - - - - - 10 - 470 - 241 - 17 - - - - Variables archivo de cuenca .nc - - + + + :/plugins/HydroSEDPlugin/icons/cuenca.ico:/plugins/HydroSEDPlugin/icons/cuenca.ico + Trazadores @@ -562,17 +681,97 @@ Hidrología + + + + 110 + 520 + 99 + 27 + + + + PushButton + + + + + + -10 + 0 + 381 + 511 + + + + true + + + + + 0 + 0 + 379 + 509 + + + + + + -10 + 0 + 381 + 131 + + + + + + Geomorfología + + + + 110 + 50 + 99 + 27 + + + + PushButton + + + + + + 130 + 100 + 99 + 27 + + + + PushButton + + + + + + Simulación + - + + + diff --git a/qgisplugin/resources.qrc b/qgisplugin/resources.qrc index 7560345..d456999 100644 --- a/qgisplugin/resources.qrc +++ b/qgisplugin/resources.qrc @@ -1,5 +1,8 @@ - - icon.png - + + icons/config.png + icons/folder.png + icons/cuenca.ico + icon.png + From 2309a26e6cb5048ddc5d126986ef827de6fbec31 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 7 May 2018 09:37:43 -0500 Subject: [PATCH 008/142] algo --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 7e560a8..1bd7903 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -27,7 +27,7 @@ - 1 + 0 From 076b79fb46e01dfe205c9048bcbe5c0dc5e7bb4b Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 7 May 2018 09:39:39 -0500 Subject: [PATCH 009/142] se agregan archivos de icionos --- qgisplugin/icons/canal-0.png | Bin 0 -> 820 bytes qgisplugin/icons/canal-1.png | Bin 0 -> 365 bytes qgisplugin/icons/config.png | Bin 0 -> 21200 bytes qgisplugin/icons/cuenca.ico | Bin 0 -> 32924 bytes qgisplugin/icons/favicon.ico | Bin 0 -> 32924 bytes qgisplugin/icons/folder.png | Bin 0 -> 1994 bytes 6 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 qgisplugin/icons/canal-0.png create mode 100644 qgisplugin/icons/canal-1.png create mode 100644 qgisplugin/icons/config.png create mode 100644 qgisplugin/icons/cuenca.ico create mode 100644 qgisplugin/icons/favicon.ico create mode 100644 qgisplugin/icons/folder.png diff --git a/qgisplugin/icons/canal-0.png b/qgisplugin/icons/canal-0.png new file mode 100644 index 0000000000000000000000000000000000000000..17f049cebf387da3b2066f018466381bae62127c GIT binary patch literal 820 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP$D+KC&U#*9M^ZB_#nGA4Pu zyT}!BDQE*Z>?NMQuI!IkSwut`yWOuU0Hs%Zx;TbJ9DY0PWLdKTkE`J!rXa4&*-Kt7 z`2YWGRl)>cj%k};cTQ_qH{UH-#J~DhZm?=ctk&6@30|5G!dJN$F7)DRm?mt*ps2_$ zAh3y{FTjpTU{ zW@vL;%yt()!cyM;;(X#$>DTjK*c>-xV6W-AW4rJP!_R~QdDRz3ZdQpo-yAU7YlL-`rb*i!a`}@}_NpbN0IT?ak_W z=8iQ#8@@3+uY0e}8h6Aj;V+v>)#u*V9fvdZ++`e{iX5Uv)iy|1t3=JY-C?M#?N(KP z>%f``iVkbUp6e}%JvB$p;XuaCMMnQVF&4Y7T>egk^?>UX{vYS3%RKwlU#(W`=;Ju0 zQo74?$0@4>-G|rv`u#gm=+W+QuOG|if2m&<{muJeNQy_n?A3KHEzWQLWxi2Z za{cS&fBXM3?k$unJlO3EN~@|Rt`Q|Ei6yC4$wjF^iowXh&_dV1RM)^H#L(2r(9+7- r49K-IFqrYkJ{v_tZhlH;S|t_@h7b)p5<4S-8W=oX{an^LB{Ts5#MU~% literal 0 HcmV?d00001 diff --git a/qgisplugin/icons/canal-1.png b/qgisplugin/icons/canal-1.png new file mode 100644 index 0000000000000000000000000000000000000000..5b4974af381d38d849891caa84f4e0eda43afd15 GIT binary patch literal 365 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaP3?%1DUd;wlEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8U)v6XFV_85sTpLF|o_ z%0MP#NswPKgTu2MX&_FLx4R2d8h1?!ki%Z$>Fdh=h?PY|l(F0Wssd0b#M8wwgyXvJ zIY+(&3LGp4R1aFS|C0aJZ2RN?c9A<~n(XSE7BR)^K1@%&HDSxF6$fsL1^wVZv|PHN zOs4q8yV^~sO*ibin<~01ro|)i%J1kWzgJGGVX%M9c5^L5w4upo>{FKbJN-P=-AsTcfc18j< OFnGH9xvX?*R3FR(D7|Ufz z*vefP=Cb6n&9KdGzxRjE`JOuc`TP8FPCk3zKhOJlp7-l{J@4RSM@{7yu3ji5B_)68 z;Jy=5Qh$Jd{vkDA2K;XV(=;t5bt3xEzCBi$ucKWH5;i*f^YBqav16ld%BT15TLNSK zaVCt^6WG50eW^?8_g7=-Y3Z)suEoXaSf4p+FWCc;VWvB_YzsDB8vZip!dYVSfxfj% zn3(;6FQ49%4Ov{i?wKaP>a(`zLEPlcHWW=A_LVFgzrF|$wm_^Gegp9rbvM=WhGac>39JO)^_ zJ|4r8JxVr-@DSGa^v*nCpY7^ZQB%mswlv}g(jt|ahc>^oS=d{y`p#tPRVEu2@S}mh zVA~^b+c3qs-|?yEl6pw0rJs;1XGegZpcS*8l_y7tK{cCD|I}7qba~~>qnxFL*xg2& zb5GPe*_KxDfn+ZKqs|LjahsiVsq#%$ZF3vx{kC3Y>v(iYLX~ z%j|>CU|;IB%}y_N;(4LWpZZcFqrl0aE11Ha+<>$)pe$|b*eK>PYjLVN7 zwlntY!`-De`<wMXTGA&&D9b0Z}aopY_Wwr9h59ZiO8|h<1 z+|LfgIX1P|0@uuxhZEV@ zzgNUgSlfG<6oH5qE0F9LP{kg3rGbCfx#%0o@_aexTdPK9xW1JB--Gr<>1Q&)?7#bj zKV9k}mHKz_I^W~+;j3@fprXZQPC<+HrB42@hS#KtyVR%B5Xru_wdUk8CEXuiu$}Wg zPv&U@^BD;vee5Xl@Zx~585xV-33Hc9M-2P&%$DW(%+(P8kmt$o!GzvWeW^_$$eBe# z4VIoqGs&x^{{H(ov3UjV?|xPP|Cd)er||kP-+8~c>I>Vh#=xPm3o&EQU5cqoQ@Pvg zuQ{Z}(u{Z13ZA+fB^}pcAVrcJMVh6ma*ai&R#L($-k^^!66}jN_0beanAF!2}l zHKEqN1cO6hMDk6c?wBSi^QqzqhlR#>Ue0;B9U2b1is<=#b63v!A{&LqWlRUlQ=DP4ov4A+!|1p-1JJErq&8T#CTo&;Ij62(PlzF5epLhDe-( zh^&0`8vW#LXykLr-Gb$0WFFV-q>+M}n8j-8-!H%Wtt&zS@3vv;!8)=kXpWZP)(wMa zr0{ay%dOCj(>JbOhR0wsrv4?cjX#5aSkSZ z2uGkJS6W0)rBtb^sDLrSL}Z8JjxAzo)VAEB7fV4|MLe8n<(EEm;{hFcA;)t8J1EE$ zC^s`SyS23XSY}Y)TDMD5pwn=Ac#wfNXo{>jyxwksM01X#zhS^Rd*&FsiswJl|?OVy9MoZ=7ogoS|Y7b3u z%0Bts7m>Y2U~a7)md*ky_<5>RX)&~FTg6{+$XS!Y8X-YDU~=k?6DbjDKV~dG7zrny zTrRoxu7i1=nj)!$Sy$vsY%ijnKv&H91ibh3As~{a;n1A5rZjsQ$D}{!SlXz1NVx<3 zi$YtxB}$&#D6~h=TJM3Tmj6cnru}fYrZV6vuM0R+%c^RTo$wTTe^mC+N#kC_LlNaF4Hl2rr zy}gr@k4sCzk6VC}&0yUbG6?`xE%c+dZUl3Z>CY-)L3_DZN2*ce2~|5;;IIc&%iFK3 zg3^Q^F+xAL3IDLng~0?11qXTfn{a0f`-K#Q5#==08*jDtY2kJ1w(AHw4?O>5Q`JfW!4oWT}cG?(vB9d z7iFtBeB7^V6q47F|LVV5KhJ5p-j)`%DO<`?NN%6g9scwYB#snK;CTawfjJEw)u{u0 ztsQ)ISF|0h5yHurIx7*sT2QpF#X$j6qa_)Lxp)(3Ec#={-AUk-92Si&u{taNeg_bC zpYv3tvcCZtTSXWu4Vd|Wzj0iMG(v8tgS5M^3cbs^h!3B1C?4(e=V$4y~n{*S* zZ@7;iI0DA>5+N`K^FvwWsCY;qk@ zn=_rO^k%dgTASc-hjutmC7yeLzG_xgt)RmGQcbZ5uNSNXT|g>LIW+AM(?fB1n{O(2 z6DWpm*7si<5OEys?JbbmpLf)9byiy4cTW7155kB$Zzmkjw5F{jeeuOfvn*%EfJJT~ zm@;&<-+VetGt6@`O4HO~KLtGojU)Ov=@=DjZ+pdFsy=;t;$SH99 zF50E?O7j;b8%{B{;T_?^tZIwga%)9VqXIHP%4=E}3pX zJ*fT)f18&Z1{$`gGq%`B%B)`&)wi&+%;{xyYc77hc54sjetpKBq`mUHNk^UhGv~bA z)>b*`{bp*-aMGk?cuPc1cPt(o^wlV`FVDzAe}&J9%54|Bii*WHM)rzWio2d>$typ0Y+o&8C3Mg}pNot9xKavCjtlZxkt;N!I+ zrPtGkMqA98`0A@S0$k%1+x-_;pWBGCs!Wz~eBGKNInlNr*s{oSmF%>FglgI7{_4aV zqC2cZSZwk?M~iFg}EgTIMyaSS86E3rI>ENdv*j0t-v+-?Oc#;WQ|4WP*Q z4I_W1p5@A|99fT*_vH5N80vZ$)$hmH8#G4fS#+zfqZ?AiTUyRd^*3}!I6O|Al+F3J zUtvXBKTo{<-Si>cs<>aR%E(FI!?pes*AxUPPS?^?IkDe{+#fI>A?m%lP4iT8(hdsz z`=e>da{E6Ay)?toS2j65^W4sN-tvo<2=Z-rFj9~!>9&Hs-eAt`HgzRI710ypgucnmG=M3XsPrF0`A)0$*&zJh@<&!*_zyo?+j8{908hI(AKcuT=ZkD-+gZ>cwScbUJb zQZMhaWtgnM)si7s%im5mQX>rcYhZ9GTl^g6da}V;VGP@n)ZCYGn41h~-s8wE;-Z*@ zxPdZtbd9xs7gbh4Z;;Kq+~Z^6`QQMSza0UpKugIl^2>2OSO6%PDj!$ zFqCE3?s<>{w4q#M$6>^Co@*M9YHVSD`SFVNd>MsW{{G2FZiupc7Y4@37sjPN#U0sJ zW&8$FFjT6IIbx8-ALzO3l*&!{OQqYfaYJ&+BkYbgdJ=CGDdRUUTBNXb!jpSa91?jW z(e9)hQ%)t-td@;xX~?G1R@E|%mR%gPD=kceOzP26+M*+R zU4?TqhQjnnb4v!?8bk}L4X`aAMInp3+(IOA|2pe&#YLR!NM^uB2L>xB8^=`YR(dd9 zN^{&3({u89kIIH>X>_FZ>nXWPoZ!zd*oiHi+HyZps({#Ycy)CjYp@QdK*k>-Bfm1! ze54oSidKX3+NzN<3!%iYrZAdu1JO3;YFqW*x)SvZQ39XZQWBN@-mYt5%+#g73cKH& zX;w8F5pKBOmG&x%le8vW%`g26ZrkLAlVsAGu_@zr&mjq`HWGN`D?03A%2CpEqHc_rUtDQ36r`~xVk@&uN0tI`^K z;=R5vf|Exp%l3Xzy8iu32=Oq_ut{oSSh1yg_081*{&(n1pAq)x&O=d$P@`8#S9zAD z9)9|ty86^94v)0i2l_=PJbY2Y$kw<0(LJARt_0ri%ey^rTZj1}GIO6Ti|!yl?As*u zWV%c3W!37NV2K~8OmiMAD9Ag1E!(9_im}tF2tVjc>vs<~-HUbQlO@I*&4^bqxFyrD ztN}vNSK(5^q{OWuANQczsdipG#aXLpwdH5JYBTHQoS2d8LnKA-`M?=V;iGRv%S3(oF(H~zNa zNa`*XM3mglF4tqi=*gdfmSamo@wEs&F?Lmi=WfE6vWusZy5DrNKihVt&5ahWL=t!S zm0!ALc#d(pb|AXvu=N#kC|jAOx4(R}%9jzWC@Jy%8UI4k{UxQ`u$+nN{xxr0nXTrG zf#Ph7d3^}i4(|L@EW67N^T2e&Xyr#z&I{x{J&nhd`lAB_PZ?tT)|IVX-e=I`8luhk z?vkH>i;geU_e+h~%F|n7BE6fcf2-0q@LY*9qYn{S9H(T#(DP?&tM@bPMBKeA_pP<$BR{=1t_HNqh zDdY*EhS*~YIH>PuUw);@uML|%z;<}6l(|bO)3E-01ynXhJ#pBjp2BW22$8rGuj3Z` z->ta=;H~K6uqpR-lVS8EVHs&4fjV2dpjG!w{B*(HLP^NZT_Il#_s2}>m~V!_$@|RZ z>k_-ST%$_AL`$rBmDll0VN0#FKJ{Ge#C*N8p(Dw4JA@AoR02rjYKY_+-QjSPRMph7 zY$fO8^T-#Fp|ichm@Ke{TSHi^Q#hkGP^R|iyt`v6H z5X>Y&4%v5HC2!kk6-6kkJql#2%`xCHsq6_*qzC<(2FUk^tK61Uj06~sQx*Kp-C z-%~3p?J%=?B+#>Iq4&H`?LGGbySPp>-)VVcd=ip``bH;3C1olc-CJzo^5eZnOo^%~ z8|KJXz%@msZJQm!_v?k0LOB~@fNIu&_K$Z%09Mlw&(jvmqUXe9&x)JYOZBc5WYSGC zlD8yEZ&s+Z(iuCqi0An)|0_S?hcMm7>Tv6xuaH!sB?H&5Kw!emm(O{L;y!u4T+-Gc z307K=K5+Gl*O{afI!y1)%b;EK1kG&7+e?$&4Gm^L)A$fy9V;VrImjKcSc`s{7+id-jjBbcn66GUn> z>-Ng#P{pcy{FPZ21X)wJqVTEso5QnXST(swfIU*6YUZEJ%W3nV_^1vT%xRt71=|^C z8ZQ*39q-;E&X}?qGO>!Jh0pHE)4n}ae(+hZqtD8Y3tLA<7jwcDT^I{zHR$(JEvpRw zr9jUibGZRBF#E!=1S$eLhCIquBiTt`jX zJt}%oe)^dKFdvJfxQ4SW9vj|N-lnVlk)K|4%u+u6}>)0H_@` zQ`@JIF40QaCfWF1mW(V!dE&U0;BddHMjBW*=I3HD(t0v6JPmhD=*iR{91Vh?n8&g} z!S$;0^hPpVs)TM$3L$tWVv!-|5jZ=VKoxV|p%{K0foxsSCg}3~gm*XAb?6hqS@?uW3nBUKgXu9hrDv=4wmI_$qC zXb&c;Pq$>E6VhxcWHBB`Li``ogr{*;n0nBTX+D1*)fJ$af*AMw7}5d9X91K(`StXaR3hD zS8laY`Qe+o!{7ckx|Garacl5H)JVgKnfMF`UU!G?+H*h)r0NqG7X>Qvjdq{SnUy{! z4)57yV@$gw401UZfq|hm3D>wwOlBwFL5w$h)Cjb2+H$EqE-s^;Yd0%sdI6(mMrPypXqbp)F< zz*{l)T2lLwdyf137q4c~6b}I)J(HR(T-vRk^%^I+DiN(1LZkQPKM8-RqZYE#lV~^< zK5pbUQ34INl^ZGO{F6q#OzL*rb=qKuUJ1j`-=k* zUN8*y)Y}Ayhxe}y9ui!8o43oliT|viI0QiOOJPNv?AZAD*p1!cU7@RQx>K<#;)Z=A zYk}nqfj3|Aet3Vpk6+Ch>{&V#rQ>>O%e3(Gb^pV9rAjhrqs1`a@dTZIL7v~_J}L_Y z>6em`{s5T9Z(cP}X*oejbJ6eHF<5;DFJ$}P*_>z=9DM_WqhO7p`CZynD>`~i*a%Qm zZFAXB(!=|&M>SIYLxHOLDBLwpE%O&V_!G6({<8cWI?Rp$46A;;Ql@&h>-!nxIEcwl zd~;~~CoJ2iOfTbf+A?Yl@S8Xo(gNNbcJw8SH}FIZC91mTMV;Kvv+GwmzvIaRS{1-iCp)#u;B4z^PvMnY^&OmGuuWOi>Vph+XLqU z$mjpeezaTY{MqxeNkc<(zh4Lvr3$kVB%XglrZYQtwAx=>ObuW+4W6)znaZkin1a6@ zaI4ZItD-@a1IygF$~l`SIeWkXvyct%v35Gb4F_S_I9_d(53fTCDhIp8@TI+Q_ceHY z|8;*6GS)*I{s5!WAf0!>CmE@Z+b?wf$cZmF5Nr6-B;)4HoI@(HMI(59GTw`zX&gS{v*{-0 zXmey4tU$-O^~N;B6gBFyoPL4UGo47K)N>*uM%SQT>m$TYQa1Ly#jVipuvbpLX;)KsP)C zHl`9-FU~1D-l~yuY={#+w*S%V<#nq=J*zx-BAkjgvlF&j=qH-pb1j(v!MLuY%)d6T zywv5fX-Ej^vc#C3aLFQqq69t?2*r@ZPNz-bmO}Pfn*BMk!XcGc<9}{}0@>8|DPbRP z2i@=zimOPErH3nVnq2&X`yXwfe!FoKLkUvX=H}OhPhkGS8nMmU)uFy|L&SvsM=BQ0 zrPYh6d{)zk2Jb=B5cs*F4Kvjp%Imx&k^PTWQ28s_2{4OCqi9{^33?4BC>ZQ8R2}$| z^J>&Kp=uHF7)o^7&gido;a-^ZH~8J~aMF*BH9ekUnLf~UbbKX=A>nMN8{%m|L#hs| zb|>i}8+zIWuC9gXb%g4{{bmyNnTVtU6>_fkj~}dwN=fCK(+!hQkDKSjswT6A)Z}}N zynk;nLRvxb!WuPsf~QA*d;4xUqtWs_caQk0$$R0!Km#*)cnZ%{Aey)=RROcE%$FDi zAmA2yU9OMdCvqK%z?OkCi0wNQ&0-G2|jm}OKo zPP!8Uuz^mH{N_g5NbA-+Dzr9gbB#BKv#}uHwT=+lyP#I^2j^TJ!K>^DJiO|^gpEqB zkj_zlTpd#y#aKcmvxNCnrR~TMBY-SJ_x<)8XI4WZdpt)qjlc>!lKqf54)3GWhPuX_!B=_&zFL@b!jq1k(g9o8ifN#pNOHILOOPXQ$bG5$mwy&UXmvi+sp3oAFX9N zUXG;1-?mrow+Gt_xf3mz`ryB#ae2kHZWVmWy&8fJ>>Xk+T&c0qoRL)*o@uiCTi4=# zl!SW+_>fQyFLcJSql(xPwHKnC@~>=j$_OARP&WB0Hge=XhQ_G2bFC_i_>M=XJUt&K z$ATEfE#Lh7Fj>t5emS~Es>@RSwIcLfEmVg?jmWt%PzW(b)t573r(erISm|}?I-`ht z7Wn(tBf#+%Oz(MPt>2L}DeaDo&?C_Lbov8tJ4fi3<7qB?oRVN2j1DTRDI{U^lixiX)xFtk{doS^^>`_1`Xj zdM~{93(YI_`fKVcGaaX|-5YG!Ep)QaA1~gms5KU@-#sWx3qd4vj(}*{2_xjMOo?^Z zBhEA{5uUCbg)Pp+1hAk0ve`E6)U?CgXLSn1J(!S-__8n8EX>-4FG2j_Feyk(m)~v3 z*4&eW?4P(#Rn8Vu81pY09_pTwrul=Zp&-qLK&Cmfsb-RMP#HZgA z6_$dorfysB(*PoP$IB&F6%)Yi3&PoH{7#GxB*1wn*SHSBb`gbKyXG5Y4#`<-+&MQR>=^ z+H%`vuaZ>3sk*Xs1m7aFz9VVlJJ#Kyc^SCli=arG*cGhP6$GPuYP7@0>(roWoC>cb zrl&&r78eJ#McZ7V9PDZYd&bLo!82G<0LA*iur30hj0lv7cOgd_ZAHNUB@kWeAmG-JN!`wd{zHLa z>{}4vbh(WD)&^C1rC>Xfbzn#XEAUm6sL(n)9|#syidApRp`Q@I@iUZet8HO32J{3* z4PaQ-9fbyCd)dg_X`iO@7i=Xy@)>+Bx*Xz>2X``5b;b3Bb$S$ay-|eV&oK9E?oooZ zprHwZzdrfxE)>f)>LCRUwZwhFeXCd(eql&b6*{;1F2azJNjU&Y+5`QfZfPIdyWdYr z7s>k2`>MgWE#{x#oQcry8jSU`dF_HlkzjDewW_5jPgO9Q;j04RayF@-0yrbih6n#lb=7*wc4|9UePN zxZH5=98k3lK4fojmw$W#GHCTpTw=vE2&*d(_A7EI!C+b6mEIlFIcCopUC`*a87zJ$ zD!<+2@*Pg{&)`!fAwk?OSp_Pz6|$a;1#QXZPYLsLVBkZ17+p{)s$5bZ{_?J={QL7c zW|EZLz4un%{Jv##8giW`kcG<@k(5hN@q_k(q1LzDR;@H%Zy6|t`{XxXdZ@DBm z*ElAm3%0VRzv)HChIgzJUt;ZOo*LQw2>@(7=HH6`lX~gCBd!S?&{Mki;sFqxfQfuM z$DDGv{q6j%#2uK5iEP&1Yir5+4g`j81cY(odQ!?Q?Fc(>|Ge3T4;UJX=EQD#$7;|s zOk5S>Q3iLq?gJE2109f#CcvP6AXRQnWCzu5&upzQFXCB#%+A?eqg>v_9~b-wIl%Z!7S4C z4J?`0U1}zo3+itLJWR5F2`YCq$GxZ2qU(wkB**D?>aFO{Q7Uj=(hm?(?7{ZFtV{OoIwRPJRkiY!#_ zncT0}R4nq2y0N1Z^F@8WH^DeE7)kx&KCl!2O*WSdD@)cmupuQs-MLmP{u50$@9S!msjP*;s^QGts z=#tdhWs=H2_0vuxpXbUl6u~g%2<~mLWSg|gWevEsprd&??ISe&B2L!NJ1seGq};Nl z-10H#NQNlw?)eI^9COlEj=COaqjr zzIuHnWdPJ3h4(p^gD~K$CDg+IY&ZV-R&DNe(31;%NNBsVD@<|t3)cNyt6_R?Ct&M2 zfAnj<$FM_y?1yQ@gc4fnQ?T`d)hvetHmLZXirOdYi5`M1#e;0so>)===ao2Cg1(0& zYWvFPdxT-i{!Mr8DZYAS>TbL5A|MBQm<(+tc!-{atOtyPg|OGT-earRQ5E)$znOy{ zP74E)AYfxhZBZ=fC@u}SnGd{-Z_<%5wc-SRpL0V5C8t`q+gaR=ixNRYN&HFAU@U)&KnK| zkyikG#tn!gk(;3=eJ2VsrqyOsMGUh0AtF0aoHcB!K0Jc&t6)gYKSeb6Yv4bZ7+Yu^W-FzZ?0wsbhQ`bF66k3B4a*d@utXd%eqc>nH#!-aFzc5CI*e1IDmw;hm{h6idU6N!|)}z#} zl&-^Iixp2BWYbmQH82Qv_naV?Ps{8{u3(cZLkH7KH0F_!zu-wmV}1`qLqnH?D9L)z zUQ{>ECUVSlN271qSNnv-#7l558!|q1y@lIK$|62T>j>`*{r@xV$-uBgD@m+sJwX^~(7DB8vFfM67Gl|1` zV9Q2ift*8+b4A1$MG>B>{FCdeAueZ9>tn-#xq+UBv3b;?m&Vjm>xHzISO4>O)j&)E z4R$Z|xPcw(zjag2_ZEoUvClRX&suUpasU-68zo<;-BDG9r+r*`A5Se z`br71uGgcfRxkribFSZ9Eht?GWz;%!g|vsQ`dCRj^l&Z|e(OzX0Cc|N!k~WrI?B2E zr=avMVEXC?9H$W?d?5Qzn~{3n2+ z?g&NxvYO?_gEdRT7c`bsP+Owh6kQdfqrT~$E8M}1XiU0C;z&rf zfnG?!)pg(}0hM>z5}+$o&gNvc`%ah*6VI*QXaGej{V0)O8%1u(nF-#$or3R+>GHH{ z?8pL9FMv6*Lg|HpZrzV1Y|reb%rT8s8saa_0>De*YKoUR`RFb$ad;R^R~3DOaDpT6 zUGuKv4U!q}7~wJzuxW@Ub$8rn(~}nfT$u;~bFS zas%XCocv~1qMy%c=vi-gq}U;tRFK$9moULeeD8q}{6r_joBf}KJ>33$4+xE2NEN8# zT(M^90cJ+6yd<;0fztYVe_Jc7yvF)&h-4c`v-=0j(v2V^#mOJX z0<3C9(HO_Do$nGv>0bD6vJ`cpWE3sBiI0+yGRm_;0O!&uo!zm1P*np^grJ^bdFrLg zx3$ufKXJ=1$&fE3rLQ(S@uh=mDKC)!%i9DHY$DUWE-P2_=25M{A!8Uyc~Z-nURzoh zhiE*cB#fP(H0R?DHfeZ81?APAv{fUjy1bh6-5Xx`7wL|KzdRtgj+1g|(@n_2_2MsF z$Ud%7(jO+_EP4EFy5qJ^tQH#IJ?Pr1SW_2#Zb+yh)* zQikNvM~e0G#-go5ym{6hfdird31SKU+qOzFvZ(NDMbbdI8#tRm@ojMI;P2to^$@IB zBR9MGqikf@-60VYV(R1x?4L9U@(#xGIs4UNt&$a}H zWG!q0NnJ2DBuhQxmNjO1TUIcBs(azv{ko{_utm7Xn}8rb@_yT~*Cd6fx65z>I>Enj zH;SHVGfG38w5!46L%(GRG9XbJhKV_FkYTXV3~ZY=j~dctFi7>J6T(#q34Zd8XEvS& zs&Q>uiVpt?o!X=LUas}vI`C?F7oeybfZo|p>9B;rA4!k*eNGW|6myg1K`BklH>WsX%8g}8NWc=LO=J~#y`7F zV*5jbq9f=qkf2E?B?_%~{fC`#6<$9v1$d^caRxwxxAJqY{Fm&%HKCA#{)2X8oLpHO z4xC!#W6Ofs0%JBS^?B-4ypylMeCZ_7Z6l9cC5v34o~`_p9_K)LI(yl`oiVIYQh)^# zhDOyKpoE^g-}yCz%}}ukOvU)t4Kptf&_PD$>c=3xRg-8PF;iD^b4|NpkE7Q1B|c^bo$E+PYtND7ol6~#slzs$j{86MLTKZ3V(Q8 ztdH&M4Wq>`$qEBqELZ$pHj6SdTmI&d*br)N0z~j~Hahffn)oHrkk*S7OpO}bM$jw{ z4Pr2TEF{klM7BPHgTTGw8r2%UKx^^c18j4hEfbv~thRD4$ z;0>Cr#r(|wtsWi%sN8Dsh0#JnZUPK^x+wPl5?fJ73jnX~hGZo??Gr@}v=H=nco9!5 zBRrh)fMje4gr3SCgLT(LzYR<(-%9XlIjzSXkNEO-R!q_dgnzY8E*M{~VmG%>zTPry z(~S5fshj)A@)v^qQ-d8K0LG2D!DgL!w?7wzz{)B>_Pji~WBsTAAQoYes6zpp?hN2{ zD$Q28Vv*m8+{~xqdUY&+^70bPw`QlErjQ$q?~I!ry#RcgU39x{x?eQi?9f9CUFr+~1@m2tD|1W5#)XG^_ zGca33Eb&>z&td&W&t*elsE5$Nh-QvluW<*b(qF*`$6UD)w+4Y9vz!Mr0HmH-FoUHK5*jaP@KaRi-^lJU&r6VCi{?B>&5?K+U&6#JgR6e z^fd%P62l`T3y1zmo_=tmpCAiCS5W)@u$bC>dCn4`(bP<&uQX}mSB?ll)VTB^^sB1H zqbakGc#O2jDc5r-t5KVA7#chdPQKu9NL&fTYSKi2_QmgmK3bAN8q6e72qhK{U*&iE z%hfDZfZ+k#q41#u(tovLZ9s9!hyqR&_#wz{uE5hcrmr6f@?~k;qb0_dAVY~m04L#* zgtc-FvBVby90z~?ihbAZ_`7FWW-Ea9E!qV_OlW)ghQkULhFyes5oGJ$!#eQ zwJk>uF^saBM=yZnZr~#INK&)l|n*ftbuID!m0LVXf#v(}Xifh-Jo@rH&s~;1c%Fc;$|X8&VtzDkz2uQ3NuqUO zhfpHwwyO0nK@(AtqtTil8u;mD7btGVNk-?i6LULb&$E)_XqO+Lu?XZ*+EKCAlV5fN zXQ;mJg2FL#!HUPu?xi_nfX(?WlkC7^jurSV(7%xufa@7}C5jj;o%=hdgfZkEPDQS@Q-}p9v%BqpSre=FeXaPuA&sV{hd(K(Y z{RW$8_A#w!>c1MBl9%?TxO$#nV1%~iw?m9py(k}MW_6NHn}1SI`yUU`s}X*r=ik&H zTX+sP|Ad^clQGUGd>!BM*!i&aMZHo_&Qg5(MPzhe{80Gjt02Q&iTpytEvqG33*;i_&W;!=SjdGFx2maKL&$(TWnEdC#)Yb_PKJy zaz_7}n$%}SkBpYufJ6@1Lxy@_?V+flaXQnLp(EbWC{Utrx)f^e>j2!p&KXKq{^+LD zSz+f5D}e9S{S6$%2KB{b_HRBG1!E3<* zbz-uh=6b&+Tqf-%iX?OMyrB_QBH7yU#?3*4$%dF!x?RjAupt(JH=KS@>sg?PAm}%qycf;J0Q22?5tU20Vf*f1 zJ`JFjw~OI3y^FQjK56Rb1?Q@2SHc?wx@_xrzwUe!1jx~iId4eUgVh%8f7B(r1n+|l zxomP2qO{e5taiZUv3~g*V4=>DQP-jQWEnsq93BrGq!On<&B;4o%3?69UU6%`@t4ta z7XL!Lq+B2O*RQ#@1C`7AM5mt(ChF-&c|qR`?V={Fl~R0AA^0p$jK znldQt!7e1K*IkaltO^En6lT^Ed?4#TgiG(^k8`-@j|XP%dniRfK{w)}b`L|dDu?yN z-&iU-#I%Z~MIVf+98a)|mrINYCea|$oK=daGJCr=FfVNDmH$bkFJixGAp~7$D7kgs z5CgVQZ7`{-#0q6DlrN81k7Qo(D+ZarW^aXU+bz+%QLT*M>$2##s z#y2`>*N979jE>M1a+Gq@E2xf)4$G7h z9Sq`Of61qQt;7z+WPeR|p;3;Lx5}~|&#Jn=Gx;6|T$izf44$aU7)xmPFI=*679bCm zWf%&+3pcR~cUtHhp`Y?{HcXi_^uq3Pz(pazCo9}Mqds1KXpjR$j@bTq-pFv=r8q2- zj=n_O`7Gf@4CT6_G-OAG1?uR zn88Idz}y~$1L!EwD@o@CM>#|y@mFjtI^*_+@E37Wi$@Gi0w~$CWXaaT*lfA2TqZ>6 zr_X~N%WLSCku^;9=LR~_38B1+0{1rbI@H}h{yE`+5J@6B8YD|v135+nD-rdZCay2~ zljhhWuUo9#r(C3%$CFjan5U4n1XjszN@UQ?Kz6&vHMUX%|E9}zi}fg0OV2<2u)apL3vW>m9Tc9=y77pwK zE=>Ljp(tM@`J6fC{QyRr|DO|9pZvAH=nwQin{$!HotCsALyixw?V>lcntde5phH*n z8Av8`3sWNJq8rVbNf65!YNiz2Y&4b0=!G4rqAhvB>kDg^J7o-LcKSHFu-j|7grWdt z;8Yu&A%L(52nKxGv0UQle2^6D-<+9;*#M@q=zn&++AIPh6tI+UafJO?--TNR4(Y(* zxO$^;Xr5i~!dk&!t5*aroo*m_QjU++v&qWIe_Qryv#d1RvCY6sd}T{x0>ZFso6r1Y z(RV0ehRi-#s5Ek7NR?zg*0`NQGikVn($9cm z3Q}TfDL#yeGp?TS*8>pNB|N|;-9-tHFwH{pyl4;Beia$2U`~T;jfm#H&=pa4E|d0y z3$_Au#EDwBYu_1rUo2IxR*OgFqIXw%DT(@~MRSxSNpiI%2e*BNx`i%Tqs5fAw~tn9 zU2}_eDOPRLX0$Xb;>mB&OB%$jMT6O!l?DBu?9^YBoQX{2X597UxQF0#zdPm%uYet) z(86F~dX5WMT_h@E%MS;**T%BrZ;?PC@hSktjEEY?Qn)3oSL|^2RL(d^i$5puzUuG+ z)=euv@TD!~Iz*P06AooVaYQ* zTgdG!UwG%fDy_Fru3`Ywx^3oXSt!^5R4f(TJp(-h$+NW7*=yr!1OM?Feq5@?|CeVl z6Vt%N{`VRss3GTq-x9HB>$H#mf?`0S6&2JV@z?B#A6;<%V~=MqxC1r*YkPm(;K%sY zgZ*(~-lbpeocK}v-}f8ML~!c-esGuZ(4TPPa}1P8^rK%BxXeE**E4(l;c+2zI;fgE z|D}Rsk>gAiIB^L!gJ0R_H@8V9*IsvKjw-YFAvU*7S2Rl7Z2kMnLvYuOgmpa+@kdMb zP9+;C1_PdGdDwRA@u28)esir_-u=@6h8X-JbZ%DY=#s_$n_GE7vmXwCNm|f_eGY{C z{)eS`m9x`gedq%(H~%SF^Y*Ulk3m^shNrK~nO2(&xBOE%rAi=~vruuHTRdm+OK?-A P)S>-H_htX(c>DhVr*G=M literal 0 HcmV?d00001 diff --git a/qgisplugin/icons/cuenca.ico b/qgisplugin/icons/cuenca.ico new file mode 100644 index 0000000000000000000000000000000000000000..ab52abfac3926764a61b7f792c8f7f1412e05a55 GIT binary patch literal 32924 zcmeI4&x##I6vj(8i5pig0=ft&$(@-9Zro?%O3+zEFbeuAf}ki0q6-!0&l?DezJjZ~ zgNTwSg9g#fKr+|wS6%1Mxt*?iZ{L}5Iz8vYp}MN8zB=D`PE}WT!ld*>dNSR-nN(g) z6P4FeN>{Fw`co;rrnZUNRHXN0^ow685DJ6>p+G1Q3WNeqrX|Y#p{m0T?;SK)}xi=P`H6G&luFT?1`LT@rzX;q}>p#li{jKam@Fo|;74DzP zEcUl+IWop}@qWv3M}u2q|^>U5MwMcv|c~(Dl37qXPnwD$?V+o5%sa~^*qFj*c;Ee{Z8#Z2S&FJ3U^!Qi3oXPvTaJ>e-a{#|& zDjDC7H?g4o9T^yNXBi*E)3{!D9*yhr-SV`Z16}$MW8Xfvhp+2bUrjU*zM}KonQ0l0 z`rBEXv2(t+$Lc&Cnq>vN}?cj{+*z^LBaTD+=xr+$`WC~`o2Ece;hslXKwa^HM+{6Eok=Q-N?4y`P_S@ZV1XD?ql_V7`ETQiKcGsB>Dke}o_?*{fB zW4^C*UNZh(L({>|l!MWuaJO}Cynj+Vd9ZZPZ|AVa82>kQ4NrR}8n%_Jt8>*s^ZPvx zzkZNWuKjP28f*OX{;xXE1bABPDZSq3_J14XhdtlnOs<>nT(9-5&0$oZe_+edgD@>0>|JGZ#v6= zp98(tfyVlr8hZSV|08}D4bX*s;eG0+&!STOSkH{XW;wNJ%z50CZ%gB(K0XgtdY>(0 z&UIf~rf1=9d)&e}sc$t$md!K7`yJd_-_GW9$FG-P}!YdrZyq zi`p{wy7=IFOs+Tf(u0ki^l)nqo6ik>e)cJ;DJOgBaI%|@HuuuejlDGW*wh;zmg9SW zh4q&(5AhWY!}ZwLchZB^@sE8rJWAnDH>8CbT4S0Y%Q`Lhzrj|#4!wVd-Y^exHIg6*~Z=!o*Dk5SMmSnMflfu z(|xc_-!1tBw#`?tj^yuAj)ms&_zgCGwttQ9F#!?rycr--3j_fUDq8S_xJa^?kUDjFov#sgT{IO zV*(~%0w!PrCSU@s5xDHSduY$m&e4uq(^t|HbbrD1W#68Z=C?9l&`tgC`K%S4B^}WC z8cq3T{}GM#e;c%Ot^Y!!?r&(fLN{vxTB-drnsR?ps*x7Qq5EafP6p>K>da|^)|mV6 zJqPZ0x8i*Voyz??Tt7h5I^ccN44^OO{*3j3u?sZq1J80b)5;ih#@uh-aTq&7)4AsZ z?_1FubwC$$FP&Ta9mZn~G`9|V?ONxo^-b-I5AIn5@p%&rdfhzNDDTvsJ=djt_Gj$G7(IxpCDp!RIhma^5;KjrqZRowaGZ6?NUnbb`4v8Fa3c=ecAPmamFQ1)oXJshFzcc@l|u<=fXDDPOybtSfAAlU?YY_{WWp! zYcAr9xxe1yF}~9o?myD6JZ*9>&WJzOK-D^cZLF!a=U@8&inC`xF5DO1@?Ly~dd%Z` zrVZP5O%2%`;u&Ha%@gLtI+*l*wzoOxzBb0Q*RDNoFi)6UtdX(LS>yAJcCPQ@8K))v zwc44#R`k!&-kAQlFAvsyT(=G7pL==rz6=|kg;x76i}_mm8v4m?*6-#^$6|jbU;-v! z0w!PrCQu@9f(Q7g1G>j(|MK4nz&UC2yGJRmx#RN7ey)#_oqU&`?=mjm`;2>O--=nf z_u*f@*)QoojeSY~Ip0h9FZrJ1U%uGWo`2%?)yU0%HUDNLf0fSDz52Y>)hOqbo{!lN z*~+JUOqnYi^;2v#N1r3xv3}}&`KQ0BHkvyYL(RO@SBxut7VoFdi#EKTVpqdM{$(@f zU-M))rH?l8I<*~omd@3E&L%g;`5c$suKkj}aAFZJHE~{Q3hG*7i7n(%4b5ccT9T)W znP!qh^NM7eL?)VwBwp}}DFWtVhF=59v_O=>zp(wdbDsBn&ilOQbKY~_=Q;0t@epR8 z%|_>q007va!*@pkfSIK!tRY5b$a=r2U`C4C7X~yAxhRc^<+0GnPylEugz1y4jQNI> z;qfE@ubiTqs}>neC&A9?G}r={;I33s=7Q-b1p@{VtR zbaEu77FOXQ9WR>gD!wfV+f}eF8TNoM%(MT9;HPZ)1nt|R9H^YV%bM$=!rYwOOI zBE$yU8$JQjvo63c&{;+<&SESTt5-;K`oLPu&7c_coNd8f(U6-@uKSUV`* zc8pw*8-(NbpiU$Z#l7w|%~gW4ScM?(9LLN5_%Vm^J|RErA-N(R#k_+l;>jg(yx{i{ z;Mcw`dqZ#cF+67+jc*OS>oXQ?K;vXZrz);uW()+4;U@>b`wC`zq#`#lE#b#T1oO_7 z6B-oaftTkb^AD zi&1kh_3`16EiN9I6Dv$0ny`-F@4dLb2RSJ@#27vOww$K9W)sM0V`(coDGmh(b?U;agoqO$m1`|ZSM>m|C%N79|p=Oy$&T)?m%$nmIxt$J5sgHe76R7^Qw32Yv{~_*kRX@T>UF z(#oknduPtJ*09`h8nLH({DhY;J&{ACTn6#K`gje+ef!+wKa$D(@hN3 z>Sp$KWF{|B4(9_GJ{u&i?$07JaY5YW3h^g7&%>L8c?k^3%UIsCZq|1|_m!V1Zgryc zw;s5~E2g^R<0j*O6b+ax4h3@m6~Z`>B-IN0fvp)_FiW49_t#bBty`Fy`J7H!=F+nv zW{uu7!1Di!--tF{$p)Tj+U^;PGLu|>@{TsLH9p*H1!WSa*lR_d=4S5rM@zt(NsbOG zF%7HDl@nYo;}}((<>`U#%Um+EWyjhraZ=7Q`qJ7Y=nGnudnr*Bi}NC4VK4<7rSPXGNaDW{_3y>|`uzvF0RrsB`){ViPZx5&KTa9$MTE zeIE_yTu0ivhL)Zgbj|Ca;FM!^I+1(h1 G&;18$Y??9v literal 0 HcmV?d00001 From ee6576934402ad7b1d88fd9bb9a8adda00c50a08 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 7 May 2018 09:59:55 -0500 Subject: [PATCH 010/142] se agrega boton para hcer set del dx plano --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 84 ++++++++++++++++---- 1 file changed, 68 insertions(+), 16 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 1bd7903..b762813 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -6,7 +6,7 @@ 0 0 - 391 + 407 869 @@ -42,7 +42,7 @@ 0 0 - 361 + 381 781 @@ -56,9 +56,9 @@ 0 - 330 - 359 - 451 + 500 + 381 + 281 @@ -69,7 +69,7 @@ 10 31 - 341 + 361 361 @@ -174,8 +174,8 @@ 10 21 - 341 - 301 + 363 + 397 @@ -242,7 +242,7 @@ - + <html><head/><body><p>Carga el MDE en el layout de mapas de Qgis.</p></body></html> @@ -252,7 +252,7 @@ - + <html><head/><body><p>Establece el MDE y sus propiedades como el mapa base para WMF.</p></body></html> @@ -326,7 +326,7 @@ - + <html><head/><body><p>Carga el DIR en el layout de mapas de Qgis.</p></body></html> @@ -336,7 +336,7 @@ - + <html><head/><body><p>Establece el DIR y sus propiedades como el mapa base para WMF.</p></body></html> @@ -347,6 +347,59 @@ + + + + + + + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + Valor Dxp + + + + + + + + 100 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + <html><head/><body><p>Establece el DIR y sus propiedades como el mapa base para WMF.</p></body></html> + + + Establecer + + + + + @@ -361,15 +414,14 @@ - + labelDIR_2 labelDEM labelDIR - horizontalLayoutWidget - horizontalLayoutWidget_2 - tableView + Tabla_PropMDE + layoutWidget_2 From c723efa2f84f578cc9b472378890d70b1d20a300 Mon Sep 17 00:00:00 2001 From: camilo2046 Date: Mon, 7 May 2018 14:44:12 -0500 Subject: [PATCH 011/142] Se agrega enlace de carga de mapas raster en QGIS --- qgisplugin/HydroSEDPluginUtils.py | 39 + qgisplugin/HydroSEDPlugin_dockwidget.py | 47 +- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 17 +- qgisplugin/resources.py | 1557 +++++++++++++++- qgisplugin/resources_rc.py | 1662 ++++++++++++++++++ qgisplugin/scripts/compile-strings.sh | 0 6 files changed, 3307 insertions(+), 15 deletions(-) create mode 100644 qgisplugin/HydroSEDPluginUtils.py create mode 100644 qgisplugin/resources_rc.py mode change 100644 => 100755 qgisplugin/scripts/compile-strings.sh diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py new file mode 100644 index 0000000..13cadf0 --- /dev/null +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -0,0 +1,39 @@ +import os.path + +from qgis.core import QgsRasterLayer, QgsMapLayerRegistry + +from wmf import wmf + +def cargar_mapa_raster (pathMapaRaster): + + retornoCargaLayerMapaRaster = False + + pathMapaRaster = pathMapaRaster.strip () + + if (os.path.exists (pathMapaRaster)): + + baseNameMapaRaster = os.path.basename (pathMapaRaster) + layerMapaRaster = QgsRasterLayer (pathMapaRaster, baseNameMapaRaster) + QgsMapLayerRegistry.instance ().addMapLayer (layerMapaRaster) + + retornoCargaLayerMapaRaster = layerMapaRaster.isValid () + + return retornoCargaLayerMapaRaster + +def cargar_mapa_dem_wmf (pathMapaDEM, dxp): + + retornoCargaLayerMapaRaster = False + + pathMapaDEM = pathMapaDEM.strip () + + try: + + demWMF = wmf.read_map_raster (pathMapaDEM, isDEMorDIR = True, dxp = dxp, noDataP = -9999) + retornoCargaLayerMapaRaster = True + + except: + + retornoCargaLayerMapaRaster = False + + return retornoCargaLayerMapaRaster + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 0b56a28..b85e411 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -31,7 +31,7 @@ import os.path -from wmf import wmf +from HydroSEDPluginUtils import cargar_mapa_raster, cargar_mapa_dem_wmf FORM_CLASS, _ = uic.loadUiType(os.path.join( os.path.dirname(__file__), 'HydroSEDPlugin_dockwidget_base.ui')) @@ -86,16 +86,23 @@ def handleClickEventEjecutarTrazadorCuencas (self): # print filename1 # print filename2 + + def setupUIInputsOutputs (self): def setupLineEditButtonOpenShapeFileDialog (lineEditHolder, fileDialogHolder): +# lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Shapefiles (*.shp);;")) lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Shapefiles (*.shp);;")) if ((os.path.exists (lineEditHolder.text ().strip ())) and (not (self.iface is None))): self.iface.addVectorLayer (lineEditHolder.text ().strip (), os.path.basename (lineEditHolder.text ()).strip (), "ogr") + def setupLineEditButtonOpenRasterFileDialog (lineEditHolder, fileDialogHolder): + + lineEditHolder.setText (fileDialogHolder.getOpenFileName ()) + def setupLineEditButtonOpenFileDialog (lineEditHolder, fileDialogHolder): lineEditHolder.setText (fileDialogHolder.getOpenFileName ()) @@ -107,12 +114,41 @@ def setupLineEditButtonSaveFileDialog (lineEditHolder, fileDialogHolder): def clickEventSelectorMapaDEM (): # setupLineEditButtonOpenFileDialog (self.lineEditMapaDEM, QFileDialog) - setupLineEditButtonOpenShapeFileDialog (self.lineEditMapaDEM, QFileDialog) + setupLineEditButtonOpenRasterFileDialog (self.lineEditMapaDEM, QFileDialog) def clickEventSelectorMapaDIR (): # setupLineEditButtonOpenFileDialog (self.lineEditMapaDIR, QFileDialog) - setupLineEditButtonOpenShapeFileDialog (self.lineEditMapaDIR, QFileDialog) + setupLineEditButtonOpenRasterFileDialog (self.lineEditMapaDIR, QFileDialog) + + def clickEventVisualizarMapaDEM (): + + pathMapaDEM = self.lineEditMapaDEM.text ().strip () + + flagCargaMapaDEM = cargar_mapa_raster (pathMapaDEM) + + if flagCargaMapaDEM: + + self.iface.messageBar().pushInfo (u'Hydro-SED', u'Se cargó el mapa MDE de forma exitosa') + + else: + + self.iface.messageBar().pushError (u'Hydro-SED', u'No fue posible cargar el mapa MDE. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.') + + def clickEventCargarWMFMapaDEM (): + + pathMapaDEM = self.lineEditMapaDEM.text ().strip () + dxpMapaDEM = self.spinBox_dxPlano.value () + + flagCargaMapaDEM_WMF = cargar_mapa_dem_wmf (pathMapaDEM, dxpMapaDEM) + + if flagCargaMapaDEM_WMF: + + self.iface.messageBar().pushInfo (u'Hydro-SED', u'Se cargó el mapa MDE al WMF de forma exitosa') + + else: + + self.iface.messageBar().pushError (u'Hydro-SED', u'No fue posible cargar el mapa MDE al WMF. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.') def clickEventSelectorBinarioNC (): @@ -137,6 +173,11 @@ def clickEventSelectorOutputCuencaNCTrazadorCuencas (): self.botonSelectorMapaDEM.clicked.connect (clickEventSelectorMapaDEM) self.botonSelectorMapaDIR.clicked.connect (clickEventSelectorMapaDIR) + + self.Boton_verMDE.clicked.connect (clickEventVisualizarMapaDEM) + self.Boton_MDE2WMF.clicked.connect (clickEventCargarWMFMapaDEM) +# self.Boton_verDIR.clicked.connect (clickEventVisualizarMapaDIR) + self.botonSelectorBinarioNC.clicked.connect (clickEventSelectorBinarioNC) self.botonSelectorOutputCorrienteShapefileTrazadorCorrientes.clicked.connect (clickEventSelectorOutputCorrienteShapefileTrazadorCorrientes) self.botonInputCorrienteShapefileTrazadorCuencas.clicked.connect (clickEventSelectorInputCorrienteShapefileTrazadorCuencas) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index b762813..6ab87c7 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -31,7 +31,7 @@ - + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png @@ -114,7 +114,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -219,7 +219,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -303,7 +303,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -366,7 +366,7 @@ - + 100 @@ -421,7 +421,6 @@ labelDEM labelDIR Tabla_PropMDE - layoutWidget_2 @@ -430,7 +429,7 @@ - + :/plugins/HydroSEDPlugin/icons/cuenca.ico:/plugins/HydroSEDPlugin/icons/cuenca.ico @@ -822,8 +821,6 @@ - - - + diff --git a/qgisplugin/resources.py b/qgisplugin/resources.py index 8d99e4b..5d4eb4d 100644 --- a/qgisplugin/resources.py +++ b/qgisplugin/resources.py @@ -76,6 +76,1539 @@ \x81\xa3\x32\xb1\xfb\xf4\x0c\x30\xb8\xb1\x82\x9b\xb0\x09\x60\x30\ \xb1\xfb\xf4\xcc\xbf\xa0\xe9\x6e\xae\x5a\xdf\x4b\x81\x00\x00\x00\ \x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x52\xd0\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x02\x00\x00\x00\x02\x00\x08\x06\x00\x00\x00\xf4\x78\xd4\xfa\ +\x00\x00\x52\x97\x49\x44\x41\x54\x78\xda\xed\xdd\x09\x9c\x24\x65\ +\x7d\xf8\x7f\x96\xe9\x99\xee\xed\x69\x1b\x59\x45\x44\x11\x2f\xf0\ +\x02\x5d\x8d\xbf\xe0\x85\xd9\x45\xc0\xbd\x66\xa6\xea\xa9\xee\xaa\ +\xa7\xaa\x67\x76\x67\xba\xba\xaa\x7a\x77\x01\x23\xa8\xf1\xe5\x95\ +\x8d\x47\x34\x28\x31\x89\x47\x12\x8f\xa8\xaf\x68\x62\xbc\xa3\x46\ +\xe3\x1d\x11\xef\x78\x45\x85\xa8\xa0\x88\x07\x8a\x10\xc1\x20\x88\ +\x2c\xec\xff\x5f\xb5\x54\x6d\x8a\x65\xb6\xbb\x66\xa6\x8f\x3a\x3e\ +\xf3\x7a\xf5\x0b\x8f\x9e\xf7\xb2\x4f\x7d\x9f\xef\xf7\x5b\xd7\xf3\ +\x1c\x75\x14\x3f\xfc\xf0\xc3\x0f\x3f\xfc\xf0\xc3\xcf\x4a\x7f\xce\ +\x3e\x7b\xf3\x3a\xff\x73\x74\xec\xb3\x0e\x0f\x0f\x0f\x0f\x0f\x0f\ +\x2f\x5b\xde\x4a\xff\xf0\x89\xc3\x3f\x78\x78\x78\x78\x78\x78\x78\ +\xd9\xf2\x56\xda\x75\x94\xfc\xcf\x64\xec\x53\x5a\x6d\xf7\x81\x87\ +\x87\x87\x87\x87\x87\x37\x7a\x6f\x35\x7f\x78\xf0\x07\x4e\xc5\x3e\ +\x93\x6b\xfc\xcb\xe0\xe1\xe1\xe1\xe1\xe1\xe1\x8d\xd0\x5b\xcd\x1f\ +\x5e\xf6\x3f\x95\xd8\xa7\xbc\xc6\xbf\x0c\x1e\x1e\x1e\x1e\x1e\x1e\ +\xde\x08\xbd\xd5\xfc\xe1\xc1\x1f\xb8\x3e\xf6\xa9\xac\xf1\x2f\x83\ +\x87\x87\x87\x87\x87\x87\x37\x42\x2f\x32\x93\x7e\x31\x78\xba\xb0\ +\xea\x7f\xa6\x63\x9f\xe0\xbf\x1f\xbd\xca\x3f\x18\x0f\x0f\x0f\x0f\ +\x0f\x0f\x6f\xf4\xde\xba\xf0\xa1\xc1\xa3\x93\xfe\xe1\xc1\x1f\x58\ +\x8b\x7d\xa6\xd7\xf8\x97\xc1\xc3\xc3\xc3\xc3\xc3\xc3\x1b\xad\x17\ +\x3d\x40\xd8\xbf\x01\x88\xfd\xe1\xf5\xd8\xa7\xb6\xc6\xbf\x4c\x0d\ +\x0f\x0f\x0f\x0f\x0f\x0f\x6f\xa4\xde\xba\xd8\x5b\x03\xbd\x1b\x80\ +\xf0\xcb\xd5\xd8\xbf\xc0\x31\xe1\x3f\xd7\xf2\x97\x89\x9c\x63\xf0\ +\xf0\xf0\xf0\xf0\xf0\xf0\x46\xe2\x45\x0f\x10\x4e\xc5\x1a\x80\x75\ +\xbd\xbe\x5c\x89\x5d\x7a\xa8\x33\xd8\x78\x78\x78\x78\x78\x78\x99\ +\xf4\xa2\xb7\x06\x0e\x35\x00\xfd\x3a\x85\xf5\x87\xdd\x7b\x60\xb0\ +\xf1\xf0\xf0\xf0\xf0\xf0\xb2\xe5\x55\x63\x6f\x0d\x04\x0d\x40\xa9\ +\xdf\x3d\x82\x4a\xac\x01\x98\x66\xb0\xf1\xf0\xf0\xf0\xf0\xf0\x32\ +\xe7\x45\x35\x3c\x6a\x00\x26\x7b\x5d\xfa\x2f\x85\x1d\x42\xd4\x00\ +\x54\x19\x6c\x3c\x3c\x3c\x3c\x3c\xbc\xcc\x79\xf1\xb7\x06\xd6\xf7\ +\x5c\x34\x28\x7c\x28\x60\x32\xd6\x00\x54\x18\x6c\x3c\x3c\x3c\x3c\ +\x3c\xbc\x4c\x7a\xf5\x58\x03\x50\xe9\xf7\xd0\x5f\xbc\x01\x58\xcb\ +\x72\x85\x1c\x3c\x3c\x3c\x3c\x3c\x3c\xbc\xf1\x7a\x51\x03\x50\xed\ +\x59\xcf\xc3\x5f\x9a\x88\xbd\x23\x48\xf1\xc7\xc3\xc3\xc3\xc3\xc3\ +\xcb\xae\x57\x4f\xf4\x0c\x5f\xac\x01\x28\x51\xfc\xf1\xf0\xf0\xf0\ +\xf0\xf0\x32\xef\x25\x7b\x7b\x2f\xd6\x00\x50\xfc\xf1\xf0\xf0\xf0\ +\xf0\xf0\x8a\xe2\xad\x71\x47\x21\x06\x1b\x0f\x0f\x0f\x0f\x0f\x2f\ +\xe3\x1e\x83\x83\x87\x87\x87\x87\x87\x47\xf1\x67\x70\xf0\xf0\xf0\ +\xf0\xf0\xf0\x28\xfe\x0c\x36\x1e\x1e\x1e\x1e\x1e\x1e\xc5\x9f\xc1\ +\xc6\xc3\xc3\xc3\xc3\xc3\xa3\xf8\xe3\xe1\xe1\xe1\xe1\xe1\xe1\x51\ +\xfc\xf1\xf0\xf0\xf0\xf0\xf0\xf0\xd2\x58\xfc\x13\xbf\xfd\xc7\x60\ +\xe3\xe1\xe1\xe1\xe1\xe1\xe5\xc2\x8b\x96\xfe\x4f\xbc\x48\x50\x8d\ +\xc1\xc6\xc3\xc3\xc3\xc3\xc3\xcb\x7c\xf1\x2f\x25\x6a\x00\x62\xfb\ +\x09\xd7\x19\x6c\x3c\x3c\x3c\x3c\x3c\xbc\x4c\x17\xff\x68\xbf\x9f\ +\xde\x0d\x40\xf8\xe5\x6a\x78\xf6\x5f\x67\xb0\xf1\xf0\xf0\xf0\xf0\ +\xf0\x32\x5b\xfc\xcb\xe1\x6e\xbf\x93\x3d\x97\xfe\x0f\xbf\x5c\x09\ +\xcf\xfe\x6b\xb1\xbd\x85\x19\x6c\x3c\x3c\x3c\x3c\x3c\xbc\x6c\x79\ +\x95\xf0\x73\xa8\x01\xe8\xd7\x29\xac\x8f\x35\x00\x35\x06\x1b\x0f\ +\x0f\x0f\x0f\x0f\x2f\x73\x5e\x35\xac\xe7\x51\x03\x50\xea\x77\x8f\ +\xa0\x12\x6b\x00\xa6\x19\x6c\x3c\x3c\x3c\x3c\x3c\xbc\xcc\x79\x51\ +\x0d\x8f\x1a\x80\xc9\x5e\x97\xfe\x4b\x61\x87\x10\x35\x00\x55\x06\ +\x1b\x0f\x0f\x0f\x0f\x0f\x2f\x73\x5e\x74\xf5\x3e\x6a\x00\xca\xbd\ +\x8a\xff\x44\xd8\x1d\x4c\xc5\xee\x17\x30\xd8\x78\x78\x78\x78\x78\ +\x78\xd9\xf3\xea\xb1\x06\xa0\xd2\xef\xa1\xbf\x78\x03\x50\x4e\xbc\ +\x4a\x10\x83\x8d\x87\x87\x87\x87\x87\x97\x36\x2f\x6a\x00\xaa\x3d\ +\xeb\x79\xf8\x4b\x13\xb1\x77\x04\x29\xfe\x78\x78\x78\x78\x78\x78\ +\xd9\xf5\xea\x89\x9e\xe1\x8b\x35\x00\x25\x8a\x3f\x1e\x1e\x1e\x1e\ +\x1e\x5e\xe6\xbd\x64\x6f\xef\xc5\x1a\x00\x8a\x3f\x1e\x1e\x1e\x1e\ +\x1e\x5e\x51\xbc\xd5\x16\x7e\x06\x1b\x0f\x0f\x0f\x0f\x0f\x2f\x1f\ +\x1e\x83\x83\x87\x87\x87\x87\x87\x47\xf1\x67\x70\xf0\xf0\xf0\xf0\ +\xf0\xf0\x28\xfe\x0c\x36\x1e\x1e\x1e\x1e\x1e\x1e\xc5\x9f\xc1\xc6\ +\xc3\xc3\xc3\xc3\xc3\xa3\xf8\xe3\xe1\xe1\xe1\xe1\xe1\xe1\x51\xfc\ +\xf1\xf0\xf0\xf0\xf0\xf0\xf0\xd2\x58\xfc\x13\xbf\xfd\xc7\x60\xe3\ +\xe1\xe1\xe1\xe1\xe1\xe5\xc2\x8b\x96\xfe\x4f\xbc\x48\x50\x8d\xc1\ +\xc6\xc3\x1b\xaf\xb7\x75\xeb\xf9\x65\x45\x76\x1f\xa4\x5a\xdd\xd3\ +\x85\xe9\xee\x68\x98\xee\xa2\x66\xba\xcf\x12\xa6\xf7\x32\xcd\x72\ +\x5f\xa7\x99\xde\x3b\x34\xcb\xfb\xa0\x6a\x3a\x9f\x51\x2d\xe7\x3f\ +\xfd\xff\x7c\xb9\x2a\xbd\x1f\x0b\xd3\xb9\x56\x18\xce\x8d\xc2\xb4\ +\x6f\x51\x0c\xfb\x36\xff\x73\x87\xff\xff\xfd\x7f\xf1\x8f\x2a\x9d\ +\x3b\xfc\xcf\x6d\xfe\xef\xdd\xa2\x49\xef\x06\xff\x9f\xbf\xd0\x2c\ +\xe7\xaa\xc0\xf0\x3f\x5f\x0d\xcc\xc0\x16\x96\xfb\x0e\xd5\xe8\xbc\ +\x41\x95\xed\x57\xaa\x46\xfb\xf9\x8a\xd1\xde\xed\xff\xb3\xa9\xea\ +\xce\x13\x74\xdd\x3b\x49\xd7\xf5\x29\x8e\x2f\x1e\x5e\xaa\x8b\x7f\ +\x29\x51\x03\x10\xdb\x4f\xb8\xce\x60\xe3\xe1\x0d\xdf\xdb\xbc\xf9\ +\x8c\x63\x94\x46\xeb\x89\x7e\x81\xfd\x63\xd5\xb0\xff\xce\x2f\xd6\ +\x1f\xf7\x8b\xfb\x77\x34\xe9\xfc\xfa\xf0\xa2\x9d\xe4\xe3\x17\xff\ +\xbb\x7d\x56\xe3\xac\xc4\x53\x2d\xef\x7f\x82\x7f\x67\x55\xba\x1f\ +\xf1\x9b\x93\xd7\xfa\xcd\x83\xab\xb4\xdc\x47\xfb\x7f\xc5\x75\xc4\ +\x0b\x1e\xde\x58\x8b\x7f\xb4\xdf\x4f\xef\x06\x20\xfc\x72\x35\x3c\ +\xfb\xaf\x33\xd8\x78\x78\xc3\xf3\xfc\xc2\xf9\x54\xff\x4c\xfa\xcd\ +\x07\xcf\xd6\x47\x58\xac\x47\xea\x49\xe7\x1a\xff\x77\xfe\xd6\x6f\ +\x10\x9e\x44\xbc\xe0\xe1\x8d\xbc\xf8\x97\xc3\xdd\x7e\x27\x7b\x2e\ +\xfd\x1f\x7e\xb9\x12\x9e\xfd\xd7\x62\x7b\x0b\x33\xd8\x78\x78\x83\ +\xf3\xd6\x09\xcb\x35\x55\xcb\xfd\x46\xea\x8a\xf5\xd0\x3d\xfb\x5b\ +\x8a\xb1\xb4\xb8\x79\xf3\x19\xf7\x24\x5e\xf0\xf0\x86\xee\x55\xc2\ +\xcf\xa1\x06\xa0\x5f\xa7\xb0\x3e\xd6\x00\xd4\x18\x6c\x3c\xbc\xc1\ +\x79\x0d\xe9\x3e\x59\xb3\x9c\xaf\x67\xa3\x58\x0f\xcf\x53\x64\xfb\ +\x1b\x6a\x73\xe7\xd3\x88\x17\x3c\xbc\xa1\x79\xd5\xb0\x9e\x47\x0d\ +\x40\xa9\xdf\x3d\x82\x4a\xac\x01\x98\x66\xb0\xf1\xf0\x06\xe3\x05\ +\x0f\xf2\x69\x96\xfb\x57\xc1\x43\x77\x45\x2f\xfe\xd1\x27\x1c\x8b\ +\x57\x79\x9e\x37\x49\xbc\xe0\xe1\x0d\xd4\x8b\x6a\x78\xd4\x00\x4c\ +\xf6\xba\xf4\x5f\x0a\x3b\x84\xa8\x01\xa8\x32\xd8\x78\x78\x83\xf1\ +\xc4\xbc\x73\xa2\x26\xdd\xaf\x64\xb9\x58\x0f\xd3\x13\x96\xf3\x65\ +\x31\xef\x9e\x40\xbc\xe0\xe1\x0d\xc4\x8b\xae\xde\x47\x0d\x40\xb9\ +\x57\xf1\x9f\x08\xbb\x83\xa9\xd8\xfd\x02\x06\x1b\x0f\x6f\x00\x9e\ +\x5f\xe0\x1e\xa1\x5a\xce\xcf\x28\xfe\xbd\x3d\x7f\x8c\xae\x0e\xc6\ +\x8a\xf8\xc3\xc3\x5b\xb3\x57\x8f\x35\x00\x95\x7e\x0f\xfd\xc5\x1b\ +\x80\x72\xe2\x55\x82\x18\x6c\x3c\xbc\x04\xc5\xdf\xfb\x15\xc5\x3f\ +\xb1\xf7\x4b\x55\x3a\x0f\x23\xfe\xf0\xf0\xd6\xe4\x45\x0d\x40\xb5\ +\x67\x3d\x0f\x7f\x69\x22\xf6\x8e\x20\xc5\x1f\x0f\x6f\x00\xde\x9c\ +\x69\xdf\x2f\x3c\xab\xa5\xf8\xaf\xc0\x0b\x16\x30\x9a\x35\x3b\xc7\ +\x13\x7f\x78\x78\xab\xf6\xea\x89\x9e\xe1\x8b\x35\x00\x25\x8a\x3f\ +\x1e\xde\x60\xbc\xe0\xa1\x36\x4d\x3a\x5f\xa4\xf8\xaf\x7a\xdd\x80\ +\x4b\x37\x6d\xda\x57\x22\xfe\xf0\xf0\x56\xe5\x25\x7b\x7b\x2f\xd6\ +\x00\x50\xfc\xf1\xf0\x06\xe4\x69\xa6\xfb\x17\x14\xff\x35\x7a\xa6\ +\xf3\x12\xe2\x0f\x0f\x6f\x88\xde\x6a\x0b\x3f\x83\x8d\x87\xb7\xfc\ +\x4f\xc3\xdc\xfd\x38\xd5\xf2\x6e\xa7\xf8\xaf\xd5\x73\xf6\x2b\x8d\ +\xf9\x27\x11\x7f\x78\x78\xc3\xf7\x18\x1c\x3c\xbc\x01\x78\xaa\xe9\ +\x7e\x9e\xe2\x3f\x18\x4f\x95\xf6\xa5\xc4\x1f\x1e\x1e\xc5\x1f\x0f\ +\x2f\xfd\xc5\x5f\xba\xdb\x28\xfe\x03\x5e\x31\xb0\xb9\xa4\x12\x7f\ +\x78\x78\x14\x7f\x3c\xbc\x54\x7b\xaa\xe9\x7c\x8e\xe2\x3f\x68\xaf\ +\x73\x09\xf1\x87\x87\x47\xf1\xc7\xc3\x4b\x6f\xf1\xd7\xbd\xc7\x50\ +\xac\x87\xe3\x1d\x69\x6d\x00\xe2\x0f\x0f\x8f\xe2\x8f\x87\x37\x76\ +\x4f\x95\xf6\xc5\x14\xeb\x21\x79\xa6\xf3\x12\xe2\x0f\x0f\x8f\xe2\ +\x8f\x87\x97\x4a\x4f\x98\x9d\xef\x51\xac\x87\xe4\x49\xe7\xdb\xc4\ +\x1f\x1e\xde\x60\x8a\x7f\xe2\xb7\xff\x18\x6c\x3c\xbc\xfe\xde\x8c\ +\x66\x3c\x9c\x62\x3d\x5c\x4f\x2c\xec\xbe\x0f\xf1\x87\x87\xb7\x26\ +\x2f\x5a\xfa\x3f\xf1\x22\x41\x35\x06\x1b\x0f\xaf\xb7\xa7\xe8\xbb\ +\xe6\x29\xd6\xc3\xf5\x84\xe9\xce\x11\x7f\x78\x78\x6b\x2a\xfe\xa5\ +\x44\x0d\x40\x6c\x3f\xe1\x3a\x83\x8d\x87\xd7\xdb\x53\x65\xfb\xcf\ +\x29\xd6\xc3\xf6\xdc\x17\x10\x7f\x78\x78\xab\x2e\xfe\xd1\x7e\x3f\ +\xbd\x1b\x80\xf0\xcb\xd5\xf0\xec\xbf\xce\x60\xe3\xe1\xf5\xf6\x84\ +\x61\xbf\x9d\x62\x3d\x5c\x4f\x98\xee\x9b\x89\x3f\x3c\xbc\x55\x15\ +\xff\x72\xb8\xdb\xef\x64\xcf\xa5\xff\xc3\x2f\x57\xc2\xb3\xff\x5a\ +\x6c\x6f\x61\x06\x1b\x0f\xef\x08\x9e\x7f\x76\xfa\x49\x8a\xf5\xd0\ +\xbd\x8f\x12\x7f\x78\x78\x2b\xf6\x2a\xe1\xe7\x50\x03\xd0\xaf\x53\ +\x58\x1f\x6b\x00\x6a\x0c\x36\x1e\x5e\x6f\x4f\xb5\xbc\xff\xa2\x58\ +\x0f\xd9\x93\xde\xd7\x88\x3f\x3c\xbc\x15\x79\xd5\xb0\x9e\x47\x0d\ +\x40\xa9\xdf\x3d\x82\x4a\xac\x01\x98\x66\xb0\xf1\xf0\xfa\x7b\x7e\ +\x81\xfa\x25\xc5\x7a\xd8\x5b\x04\x7b\x3f\x25\xfe\xf0\xf0\x12\x7b\ +\x51\x0d\x8f\x1a\x80\xc9\x5e\x97\xfe\x4b\x61\x87\x10\x35\x00\x55\ +\x06\x1b\x0f\xaf\xbf\xb7\x6f\xdf\xbe\xa3\xa3\xdd\xff\x28\xd6\xc3\ +\xf4\x9c\x5b\x89\x3f\x3c\xbc\x44\x5e\x74\xf5\x3e\x6a\x00\xca\xbd\ +\x8a\xff\x44\xd8\x1d\x4c\xc5\xee\x17\x30\xd8\x78\x78\x09\xbc\x66\ +\xb3\x7d\x1c\xc5\x7a\x34\xde\xdc\xc2\xfc\x06\xe2\x0f\x0f\xaf\xaf\ +\x57\x8f\x35\x00\x95\x7e\x0f\xfd\xc5\x1b\x80\x72\xe2\x55\x82\x18\ +\x6c\x3c\xbc\xa3\x1a\xa6\x73\x2a\xc5\x7a\x34\xde\xac\xd6\xfa\x03\ +\xe2\x0f\x0f\xaf\xaf\x17\x35\x00\xd5\x9e\xf5\x3c\xfc\xa5\x89\xd8\ +\x3b\x82\x14\x7f\x3c\xbc\x15\x78\x5a\xcb\x3d\x93\x62\x3d\x1a\x6f\ +\x56\xdf\xb5\x95\xf8\xc3\xc3\xeb\xeb\xd5\x13\x3d\xc3\x17\x6b\x00\ +\x4a\x14\x7f\x3c\xbc\x95\x7b\xc2\x72\x4d\x8a\xf5\x68\x3c\xd5\x58\ +\xdc\x49\xfc\xe1\xe1\xf5\xf5\x92\xbd\xbd\x17\x6b\x00\x28\xfe\x78\ +\x78\xab\xf0\x84\xe9\x3e\x83\x62\x3d\x1a\x4f\x35\x96\x2e\x24\xfe\ +\xf0\xf0\x06\xe4\xad\xb6\xf0\x33\xd8\x78\x78\xe1\x2d\x00\xd3\xfd\ +\x73\x8a\xf5\x68\x3c\x55\xb6\x5f\x41\xfc\xe1\xe1\xb1\x45\x30\x1e\ +\x5e\x2a\x3c\x4d\x3a\x6f\xa2\x58\x8f\xc6\x13\x66\xe7\xef\x88\x3f\ +\x3c\x3c\x8a\x3f\x1e\x5e\x2a\x3c\x21\xdd\x0f\x51\xac\x47\xe4\x99\ +\xee\xfb\x88\x3f\x3c\x3c\x8a\x3f\x1e\x5e\x2a\x3c\x61\x39\x5f\xa6\ +\x58\x8f\xc8\x93\xce\xa5\xc4\x1f\x1e\x1e\xc5\x1f\x0f\x2f\x15\x9e\ +\x66\x39\x57\x51\xac\x47\xe3\xa9\xd2\xf9\x01\xf1\x87\x87\x47\xf1\ +\xc7\xc3\x4b\x85\xe7\x37\x00\x37\x53\xac\x47\xe3\xa9\x96\x77\x23\ +\xf1\x87\x87\x47\xf1\xc7\xc3\x1b\xbb\xb7\xb0\xb0\x30\x4d\xb1\x1e\ +\xad\xb7\x75\xeb\xf9\x65\xe2\x0f\x0f\x6f\xf5\xc5\x3f\xf1\xdb\x7f\ +\x0c\x36\x1e\xde\x91\x7f\x84\xd5\x3d\x99\x62\x3d\x5a\x4f\x91\x7b\ +\x1e\x40\xfc\xe1\xe1\xad\xae\xf0\x87\xeb\xfe\x24\x5e\x24\xa8\xc6\ +\x60\xe3\xe1\x2d\xef\xcd\x19\x3b\xcf\xa2\x58\x8f\xd6\x53\x5b\xce\ +\xe3\x89\x3f\x3c\xbc\x55\x15\xff\x52\xa2\x06\x20\xb6\x9f\x70\x9d\ +\xc1\xc6\xc3\x5b\xde\x9b\x33\x96\x5a\x14\xeb\x51\x7b\xdd\xed\xc4\ +\x1f\x1e\xde\x8a\x8b\x7f\xb4\xdf\x4f\xef\x06\x20\xfc\x72\x35\x3c\ +\xfb\xaf\x33\xd8\x78\x78\xcb\x7b\x73\xfa\xe2\x33\x28\xd6\x23\xf6\ +\x5a\xce\x12\xf1\x87\x87\xb7\xa2\xe2\x5f\x0e\x77\xfb\x9d\xec\xb9\ +\xf4\x7f\xf8\xe5\x4a\x78\xf6\x5f\x8b\xed\x2d\xcc\x60\xe3\xe1\x1d\ +\xe6\xa9\x86\xfd\x32\x8a\xf5\x68\x3d\x61\x79\xcf\x25\xfe\xf0\xf0\ +\x12\x7b\x95\xf0\x73\xa8\x01\xe8\xd7\x29\xac\x8f\x35\x00\x35\x06\ +\x1b\x0f\x6f\x79\x4f\x48\xfb\xef\x29\xd6\xa3\xf5\x84\xe9\xfe\x25\ +\xf1\x87\x87\x97\xc8\xab\x86\xf5\x3c\x6a\x00\x4a\xfd\xee\x11\x54\ +\x62\x0d\xc0\x34\x83\x8d\x87\x77\x64\xcf\x3f\x1b\x7d\x37\xc5\x7a\ +\xc4\x9e\xe9\xbd\x83\xf8\xc3\xc3\xeb\xeb\x45\x35\x3c\x6a\x00\x26\ +\x7b\x5d\xfa\x2f\x85\x1d\x42\xd4\x00\x54\x19\x6c\x3c\xbc\xde\x9e\ +\xb0\xdc\xff\xa0\x58\x8f\xda\x73\x3f\x49\xfc\xe1\xe1\xf5\xf4\xa2\ +\xab\xf7\x51\x03\x50\xee\x55\xfc\x27\xc2\xee\x60\x2a\x76\xbf\x80\ +\xc1\xc6\xc3\xeb\xe3\xf9\x85\xec\x32\x8a\xf5\xa8\x3d\xfb\x3b\xc4\ +\x1f\x1e\x5e\x4f\xaf\x1e\x6b\x00\x2a\xfd\x1e\xfa\x8b\x37\x00\xe5\ +\xc4\xab\x04\x31\xd8\x78\x05\xf7\x34\xe9\x5c\x4f\xb1\x1e\xad\xa7\ +\x98\xf6\x2f\x89\x3f\x3c\xbc\x9e\x5e\xd4\x00\x54\x7b\xd6\xf3\xf0\ +\x97\x26\x62\xef\x08\x52\xfc\xf1\xf0\x12\x78\x9b\x36\xed\x2b\xf9\ +\x45\xe9\x00\xc5\x7a\xd4\x9e\xbd\x7f\xf3\xe6\x33\xee\x49\x3c\xe3\ +\xe1\x1d\xd1\xab\x27\x7a\x86\x2f\xd6\x00\x94\x28\xfe\x78\x78\xc9\ +\x3d\x31\xef\x9e\x40\xb1\x1e\x8f\xb7\x4d\x35\x1e\x4c\x3c\xe3\xe1\ +\x1d\xd1\x4b\xf6\xf6\x5e\xac\x01\xa0\xf8\xe3\xe1\xad\xc0\x13\x46\ +\x77\x23\xc5\x7a\x3c\x5e\xa3\xe5\x9e\x46\x3c\xe3\xe1\xad\xd1\x5b\ +\x6d\xe1\x67\xb0\xf1\x8a\xee\x35\xa4\xfb\x74\x8a\xf5\x98\xbc\x96\ +\x7b\x26\xf1\x8c\x87\xc7\x16\xc1\x78\x78\x63\xf1\x1a\xa6\xb7\x40\ +\xb1\x1e\x93\x27\x3d\x49\x3c\xe3\xe1\x51\xfc\xf1\xf0\xc6\xe2\x69\ +\xa6\xfb\x2c\x8a\xf5\x78\x3c\x61\xba\xcf\x20\x9e\xf1\xf0\x28\xfe\ +\x78\x78\x63\xf1\x84\xe5\x5d\x44\xb1\x1e\x8f\x27\x4c\xef\x65\xc4\ +\x33\x1e\x1e\xc5\x1f\x0f\x6f\x2c\x9e\x5f\x84\xde\x4a\xb1\x1e\x9b\ +\xf7\x46\xe2\x19\x0f\x8f\xe2\x8f\x87\x37\x16\xcf\x2f\x42\x1f\xa5\ +\x58\x8f\xcd\xfb\x20\xf1\x8c\x87\x47\xf1\xc7\xc3\x1b\x8b\xa7\x49\ +\xef\x6b\x14\xeb\x31\x79\xa6\xf7\x25\xe2\x19\x0f\x6f\xd5\x35\x7d\ +\x1d\x83\x93\x51\x6f\x76\x76\xfb\x06\x45\xb1\x4e\x53\x1a\xad\xa7\ +\xcc\xea\xf3\x9b\x94\xc6\xfc\x93\x84\xb5\xf4\x60\x5d\xd7\xa7\x18\ +\xbf\xd1\x79\x7e\x03\xf0\x53\x8a\xf5\x78\x3c\x61\x7a\x3f\x22\x9e\ +\x47\xe7\x2d\x2c\xb4\xca\x62\xde\x39\xb1\x61\x3a\xa7\x2a\x2d\xe7\ +\xb1\xcd\xf9\xee\xa3\x82\x85\xb0\xfc\x9c\x33\xc1\xf8\x65\xca\x8b\ +\x96\xfe\x4f\xbc\x48\x50\x8d\xc1\x1e\xaf\xd7\x9c\xdf\xfd\x70\x3f\ +\xe1\x3d\x53\xb3\xdc\xf7\x2a\x46\xe7\x2a\xc5\xb0\xef\x38\x42\xb2\ +\x3c\xa0\x59\xce\x55\x42\x3a\x1f\x10\xd2\x7d\xb6\x30\x76\x9f\xc6\ +\xf8\x0d\xcf\xf3\xc7\xfa\x56\x8a\xf5\x78\x3c\x21\xbd\xdf\x12\xcf\ +\xc3\xf3\x66\x35\xeb\x74\x45\x5f\x7a\xbe\x30\xec\x0f\xaa\xd2\xfd\ +\xa1\x6a\x79\xb7\x2f\x7f\x2c\x9c\xfd\xfe\x3f\xbf\xaf\x99\xde\x3b\ +\x85\xe5\xee\xd5\x5a\x7b\x1e\xc2\xf8\xa5\xba\xf8\x97\x12\x35\x00\ +\xb1\xfd\x84\xeb\x0c\xf6\xe8\x3d\x65\x71\xf1\x9e\xfe\xc4\xba\xd0\ +\x9f\x78\xdf\x5d\xdb\x99\x92\xfb\x3d\x61\x79\xcf\x55\x77\x9e\x7b\ +\x2f\x8e\xc7\xe0\xbc\xb9\x85\xf9\x0d\x14\xeb\xf1\x7a\x0b\x0b\x0b\ +\xd3\xc4\xf3\xe0\xbc\x1d\x9a\xf9\x20\xd5\x68\xff\xa9\x30\x3b\xdf\ +\x5b\xdb\xf1\x75\xbe\xee\xe7\x9d\xf3\xb6\x69\xea\xfd\x38\x1e\xa9\ +\x2a\xfe\xd1\x7e\x3f\xbd\x1b\x80\xf0\xcb\xd5\xf0\xec\xbf\xce\x60\ +\x8f\xce\x3b\x58\xf8\x4d\xf7\x2f\x54\xcb\xb9\x69\xb0\xc9\xd7\xb9\ +\xd9\x37\x2f\x6e\x36\x3b\x1b\x38\x1e\x03\xb8\x0d\xa3\xb5\xfe\x80\ +\x62\x3d\x5e\xaf\xb9\xe0\x3c\x98\xfc\x32\x80\x2b\x59\xda\xe2\xbd\ +\x15\xd9\x7e\x8d\x30\xed\x5b\x06\x7a\x7c\x0d\xe7\x46\x55\xb6\xff\ +\x62\xc7\x0e\xed\xfe\x1c\x8f\xb1\x17\xff\x72\xb8\xdb\xef\x64\xcf\ +\xa5\xff\xc3\x2f\x57\xc2\xb3\xff\x5a\x6c\x6f\x61\x06\x7b\xc8\x9e\ +\xb0\xba\xbb\x96\xdb\x5e\x76\x90\xc9\x57\xb5\xbc\xff\x11\xfa\xd2\ +\x5e\x8e\xc7\xda\x3c\xb5\xb1\xb0\x8d\x62\x3d\x5e\x4f\xcc\x3b\x4f\ +\x24\xbf\xac\xcd\x13\x96\xe3\x0a\xc3\xbe\x61\xa8\xc7\xd7\xb0\x7f\ +\x21\x2c\xd7\xe0\x78\x8c\xcd\xab\x84\x9f\x43\x0d\x40\xbf\x4e\x61\ +\x7d\xac\x01\xa8\x31\xd8\xc3\xf5\x76\xb4\xf6\x1c\xeb\x9f\xf5\xff\ +\xeb\x28\x93\xaf\xdf\x99\x7f\x7a\x87\xda\x3a\x95\xe3\xb1\x3a\x4f\ +\x35\x16\x77\x52\xac\xc7\xeb\x09\xe9\x28\xe4\x97\xd5\x79\xba\xee\ +\x9d\xa4\x59\xee\x27\x47\x79\x7c\x55\xcb\xf9\x27\x5d\xdf\x5b\xe3\ +\x78\x8c\xd4\xab\x86\xf5\x3c\x6a\x00\x4a\xfd\xee\x11\x54\x62\x0d\ +\xc0\x34\x83\x3d\x5c\xcf\x9f\x18\x8f\xd0\x2c\xe7\xca\xb1\x24\x5f\ +\xe9\xdc\xe4\x9f\x01\xec\xe6\x78\xac\xdc\x53\x8d\xa5\x0b\x29\xd6\ +\xe3\xf5\x14\x63\xe9\x3c\xf2\xcb\x8a\xbd\x75\xaa\xe9\xed\xd6\x4c\ +\xef\x7f\xc7\x71\x7c\x83\x67\x9a\x14\xd9\x7d\x10\xc7\x63\x24\x5e\ +\x54\xc3\xa3\x06\x60\xb2\xd7\xa5\xff\x52\xd8\x21\x44\x0d\x40\x95\ +\xc1\x1e\xae\xa7\xb6\x9c\xc7\x07\x97\xe4\xc7\x9d\x7c\xfd\x84\xf0\ +\x49\xad\x65\x3f\x90\xe3\x9b\xdc\x53\x65\xfb\x15\x14\xeb\xf1\x7a\ +\xfe\x31\x78\x29\xf9\x25\xf9\x4f\x50\x78\xfd\x86\xff\x53\x63\x3f\ +\xbe\xd2\xb9\x26\x78\x8d\x90\xfc\x32\x54\x2f\xba\x7a\x1f\x35\x00\ +\xe5\x5e\xc5\x7f\x22\xec\x0e\xa6\x62\xf7\x0b\x18\xec\x21\x7a\x0d\ +\x73\xf7\xe3\x34\xe9\xdd\x90\x96\xe4\x7b\xe7\x43\x87\xee\x9e\xe0\ +\x0c\x81\xe3\xdb\xdf\x13\x66\xe7\xef\x28\xd6\x63\xf6\xe4\xd2\xdf\ +\x93\x5f\x92\x9d\xf5\x07\xaf\xe8\x45\x0f\x16\xa7\xe4\xf8\xfe\x32\ +\xb8\xfa\x49\x7e\x19\x9a\x57\x8f\x35\x00\x95\x7e\x0f\xfd\xc5\x1b\ +\x80\x72\xe2\x55\x82\x18\xec\x55\x79\x4a\xcb\x7d\xf4\x72\x0f\xfb\ +\xa5\x61\x72\xaa\xa6\xf3\x99\xe8\xe9\x6a\x8e\xef\x91\x3d\xcd\x74\ +\xdf\x47\xb1\x1e\xaf\xa7\x48\xfb\x7d\xe4\x97\xde\x3f\xc1\x5c\x0e\ +\xe6\x74\x2a\x8f\x6f\x70\x25\x60\xa1\x73\x32\xf9\x65\x28\x5e\xd4\ +\x00\x54\x7b\xd6\xf3\xf0\x97\x26\x62\xef\x08\x52\xfc\x87\x79\xd9\ +\x5f\x3a\x0f\x0b\xbb\xdf\x54\x2f\xb2\x22\x4c\xef\xdc\xf8\xd5\x00\ +\x8e\xef\x5d\x3d\x3f\x79\x5d\x4a\xb1\x1e\xaf\xa7\xc8\xf6\x25\xe4\ +\x97\x23\x9f\xf5\x6b\x96\x7b\x5e\x30\x97\xd3\x7c\x7c\x55\xcb\xb9\ +\x3a\x78\x20\x91\xfc\x32\x70\xaf\x9e\xe8\x19\xbe\x58\x03\x50\xa2\ +\xf8\x0f\xd7\x0b\xee\xb3\xfb\x93\xf2\x27\x59\x49\xbe\xc2\x72\xff\ +\x23\x58\xd9\x8b\xe3\x7b\x77\xcf\x6f\xe4\x7e\x40\xb1\x1e\xaf\xe7\ +\x7f\x2e\x23\xbf\x2c\x77\x92\xe1\x3e\x54\x93\xde\x67\x33\xf3\x36\ +\x87\xe9\x5d\xa1\x28\xad\x93\xc9\x2f\x03\xf5\x92\xbd\xbd\x17\x6b\ +\x00\x28\xfe\x43\xf4\xc4\xc2\xee\xfb\x1c\xa9\x68\xa4\xfb\x55\x2b\ +\xef\xb7\x8a\xd1\xfe\x93\xcd\x9b\xcf\xb8\x27\xc7\x37\x6a\xe4\xf6\ +\x3c\x24\x78\x8a\x9a\x62\x3d\x66\x4f\x7a\x37\x1c\xe9\x76\x55\x41\ +\xf3\xd5\x3a\x61\xba\xcf\x08\x16\xfd\xca\xdc\xf1\x35\xda\x97\x6d\ +\x55\xf4\x07\x92\x5f\x46\xec\xad\xb6\xf0\x33\xd8\xc9\xbd\xf9\xf9\ +\xf3\xeb\x7e\xb2\xfa\x66\x96\x93\xaf\xdf\x04\x7c\x41\xd1\xcd\xc7\ +\x15\xf5\xf8\x06\x85\x46\x33\xdd\xe7\xa9\x96\xfb\x0d\x8a\x75\xba\ +\xbc\x83\xc7\xc4\x3f\x36\xfd\x9a\x81\x3c\xe7\xab\xe0\x5e\xba\xb0\ +\xbc\xcf\x65\xf9\xf8\xaa\xb2\xf3\xe5\x2d\x5b\xd4\xe3\xa9\x1f\xe3\ +\xf1\x18\x9c\x21\x78\x5b\xb7\x9e\x5f\x3e\x78\x29\x3d\x17\xc9\x37\ +\x58\x2a\xd4\xbd\x60\xdf\xbe\x7d\x47\x17\xe1\xf8\x6e\x53\x8d\x07\ +\xfb\x67\x53\xe7\x0b\xcb\xf9\x32\xc5\x3a\x23\x9e\xe9\x7d\x29\x78\ +\x7e\xa5\x28\x7b\x5f\x04\x73\xf1\xce\x8d\xc2\xee\x7a\xd6\x9f\xd5\ +\xe3\xab\x4a\xf7\xa3\x9b\x36\xed\x2b\x51\x3f\x28\xfe\xb9\x98\x9c\ +\x9a\xe5\xbe\x27\x6f\xc9\x57\x35\xdd\xcf\x07\x0f\x33\xe6\xf1\xf8\ +\x6e\xd9\x72\xd6\x06\x45\x5f\xb4\x84\x61\xff\x9b\xff\x77\xbc\x8d\ +\xe2\x9a\x4d\x4f\xb5\xbc\xdf\x07\x6f\x6a\xa8\x2d\x67\x66\x6e\x6e\ +\x66\x32\xaf\x0f\x14\x07\x73\x31\x6f\xc7\x57\x58\xde\xdb\xa8\x1f\ +\x14\xff\xcc\x7b\x7e\xf1\x7f\x4d\x7e\x2f\xbb\x3a\xb7\xf8\x09\xf6\ +\x59\xfd\xae\x06\x64\xe5\xf8\xce\x6a\xc6\x69\xaa\x61\xbf\x4a\x98\ +\x9d\x5f\x50\x5c\x73\xb6\x62\xa0\x69\xff\x5c\x35\x96\x2e\x52\x14\ +\xeb\xb4\x3c\xe4\x97\x83\x27\x16\xfe\xdc\x3b\x38\x07\xf3\x7a\x7c\ +\x4d\xf7\xcf\xa9\x47\x14\xff\xec\x16\x7f\x7f\x82\x16\x22\xf9\x4a\ +\xe7\x8b\xcd\xf9\xdd\x0f\xcf\xe2\xf1\xdd\xb8\xf1\xb4\x89\xb9\xe6\ +\x62\x43\x18\x9d\x8f\x29\x86\x7d\x07\xc5\x35\xe7\xeb\x06\x98\xce\ +\xed\x7e\x93\xf7\xd1\x86\xe1\x6c\x3d\xaa\xcf\x82\x57\x69\x8d\xe7\ +\x60\xae\x05\x73\xae\x08\xc7\x57\x58\x6e\x97\x7a\x44\xf1\xcf\x9c\ +\x27\x5a\x9e\xee\x07\xf0\x81\xa2\x24\x5f\x55\x7a\xbf\xf3\x1b\x9e\ +\x3f\xd1\x75\x7d\x22\x0b\xc7\x37\xd8\x47\x3e\xd8\xaf\x5c\x95\x9d\ +\x1f\x50\x5c\x8b\xe9\xa9\xd2\xf9\xef\x60\x4d\xfc\x99\x19\xaf\x9a\ +\x85\xfc\x12\xcc\x2d\xff\xdf\xfb\x39\x07\xe7\x5a\x41\x8e\xaf\x6a\ +\x79\xb7\x0b\xd3\xdb\x4a\x3d\xa2\xf8\x67\xa7\xf8\xcf\x3b\x4f\x5c\ +\x6e\x92\x16\x21\xf9\x06\x0f\xcb\xf9\x45\xf5\x91\x69\x3d\xbe\xb3\ +\x66\xe7\x78\x61\x79\x2f\xf7\xcf\xa0\x7e\x4d\x31\xc4\x3b\xb4\x3d\ +\xb6\xe9\xbd\x2c\x78\x4d\x37\xad\xf9\xe5\xe0\x86\x61\xa6\xf7\xa5\ +\x42\x1e\xdf\x60\xd3\x22\xa3\xbb\x91\x7a\x34\xd8\xe2\x9f\xf8\xed\ +\x3f\x06\x7b\x05\x97\xfd\x0f\x2e\xf4\x73\xf7\x55\xfe\x8a\x95\x7c\ +\x9d\x5b\x55\x69\xef\x0b\x1e\xa6\x4b\xcb\xf1\x3d\xb8\x09\x8a\xe9\ +\xfc\x6d\xd4\x98\x51\x0c\xf1\x96\xbd\x8a\x25\xbd\xd7\x1f\xbe\x29\ +\xd6\x38\xf3\x4b\x70\xd6\xef\x37\xac\xcf\xed\x75\xd6\x5f\x8c\xe3\ +\xeb\xfe\x44\xd7\xf7\xde\x97\x7a\x34\x10\x2f\x5a\xfa\x3f\xf1\x22\ +\x41\x35\x06\xbb\xbf\x17\xec\x73\xed\x9f\x59\x7e\x9b\xe4\x1b\x6d\ +\xd4\xd2\xf9\xba\xd2\x68\x3d\x71\x9c\xc7\xf7\xe0\xbb\xd1\xa6\xf7\ +\x56\xbf\x29\xd9\x4f\x31\xc4\x4b\x76\x3b\xcb\xb9\x4d\x33\xdd\xb7\ +\x04\xab\xe9\x8d\x33\xbf\x04\xbb\xe5\x69\xd2\xfd\x0a\xc7\x37\x7a\ +\xd6\xc8\xfd\x8a\x10\xdd\x69\x8a\xff\x9a\x8b\x7f\x29\x51\x03\x10\ +\xdb\x4f\xb8\xce\x60\xf7\xfe\xb9\xf3\x75\x3f\xef\x83\x24\x5f\xe7\ +\xf0\x87\xae\x7e\xef\x17\xdf\x17\x8e\xfa\xbd\xde\x60\x41\x98\xe0\ +\x55\xa2\xe0\x1e\x22\xc7\x03\x6f\x95\x57\xb2\xf6\x0b\xc3\x7e\xfb\ +\x0e\xd1\x7a\xf4\x28\xf3\xcb\xc1\x7b\xfd\xa6\xfb\xbc\xe0\x4a\x1a\ +\xc7\xe3\xf0\xe6\xcc\x7e\x0f\xc5\x7f\x4d\xc5\x3f\xda\xef\xa7\x77\ +\x03\x10\x7e\xb9\x1a\x9e\xfd\xd7\x19\xec\xbe\x4f\xfc\xff\x39\xc9\ +\xb7\x97\xe7\x7c\x3d\xd8\x01\x71\xd8\xc7\x43\xcc\xbb\x27\x68\x96\ +\xfb\x77\xcb\xbd\xbf\xcf\xf1\xc0\x5b\xdd\x0a\x98\xf6\x6d\x42\xb7\ +\xdf\xb4\x5d\xd5\x1f\x3a\xec\xfc\x22\x8c\xdd\xa7\xa9\x96\xf3\x9f\ +\x1c\x8f\x23\x7b\xaa\xd1\x7e\x31\xf5\x68\x55\xc5\xbf\x1c\xee\xf6\ +\x3b\xd9\x73\xe9\xff\xf0\xcb\x95\xf0\xec\xbf\x16\xdb\x5b\x98\xc1\ +\x5e\xae\xe8\x98\xdd\x26\x93\x33\xc9\xba\x01\xde\xef\x85\xe5\xbe\ +\xa8\xdf\xd5\x80\xd5\x1c\x8f\x60\xa9\xe5\x83\x0f\xf7\x2d\xb3\x1a\ +\x1a\xc7\x03\x6f\x20\x1b\x0f\x05\xbb\xea\x99\xce\x4b\x82\x5b\x7d\ +\x83\xce\x2f\xc1\x9c\xf0\x1b\xd7\x17\x1c\x5c\xbc\x88\xe3\xd1\xfb\ +\x55\x4e\xc3\xbe\x43\xd1\x17\x75\xea\xd1\x8a\xbc\x4a\xf8\x39\xd4\ +\x00\xf4\xeb\x14\xd6\xc7\x1a\x80\x1a\x83\x7d\x84\xe2\xef\x77\xec\ +\xf1\xed\x36\x49\x96\x49\x5e\xed\x71\xbf\x71\xf8\x53\xbd\x6b\x7b\ +\x35\xca\xdd\xe3\x27\xce\x5f\x91\x2c\xf1\x46\xe4\xfd\x52\x6b\x79\ +\x5e\xfc\x95\xd7\xb5\xe4\x97\xe0\xca\x58\x70\x85\x8c\xe3\xb1\x82\ +\xe5\x82\x2d\xef\xc6\x95\xac\x44\x5a\xf0\xe2\x5f\x0d\xeb\x79\xd4\ +\x00\x94\xfa\xdd\x23\xa8\xc4\x1a\x80\x69\x8a\xff\x91\x1e\xfa\xf3\ +\x8e\x09\xb6\xb1\x64\x72\xae\x66\xdd\x00\xe7\x36\x61\xb9\x7f\xe6\ +\x79\xde\xe4\x6a\x8f\x47\x43\x7a\x67\xf9\xc5\xff\x3b\x24\x4b\xbc\ +\x71\x78\x7e\x11\xfa\x2f\xad\xe5\x9e\xb9\xda\xfc\x12\x9e\xf5\xff\ +\x69\xd2\xb3\x7e\x8e\xc7\x61\xcb\x05\x9b\xce\x65\x2b\xb9\x1a\x53\ +\xd0\xe2\x1f\xd5\xf0\xa8\x01\x98\xec\x75\xe9\xbf\x14\x76\x08\x51\ +\x03\x50\xa5\xf8\x1f\xf1\x67\x9d\x66\x7a\x1f\x66\x72\xae\xd5\x73\ +\xbe\xa5\xb4\x9c\xc7\xae\xec\xd5\x28\xef\xa4\x60\x8d\x77\xc6\x0f\ +\x2f\x1d\x9e\xfb\x1e\x31\xef\x9c\xb8\x92\xfc\x12\x5c\x01\x63\x57\ +\xc9\x81\xec\x02\xf9\x2f\xd4\xa3\x9e\x6f\xef\xd5\x62\x0d\x40\xb9\ +\x57\xf1\x9f\x08\xbb\x83\xa9\xd8\xfd\x02\x8a\xff\x91\x1e\xfa\xb3\ +\xdc\x17\x30\x39\x07\xf9\xb4\xf5\xd2\x45\xdb\xb6\x3d\xfd\xb8\x5e\ +\xc7\x23\xb8\x5a\x10\x3e\x1d\x7d\x33\xe3\x87\x97\x26\x2f\xbc\x0d\ +\xf8\x9c\xe0\xac\xbe\x57\x7e\x09\x62\x38\xb8\xf2\xb5\xd2\x4d\xa6\ +\x38\x1e\x3d\x96\x0b\x36\xdd\x67\x50\xfc\x97\xf5\xea\xb1\x06\xa0\ +\xd2\xef\xa1\xbf\x78\x03\x50\x4e\xbc\x4a\x50\x11\x8b\x7f\xcb\x3d\ +\x33\xfe\x7a\x19\x93\x73\x40\x9e\xd1\xbe\x6c\x56\x9f\xdf\xb4\xdc\ +\xf1\xd0\x5a\xdd\xa7\x04\x97\xfc\x18\x3f\xbc\x34\x7b\xc1\x6d\x81\ +\x39\x63\xe7\x59\xcb\xe5\x97\xe0\x4a\x57\x70\xc5\x8b\xf1\x1b\xf0\ +\x33\x45\xc1\xed\xc4\x79\xe7\x89\x14\xff\xbb\x79\x51\x03\x50\xed\ +\x59\xcf\xc3\x5f\x9a\x88\xbd\x23\x48\xf1\x3f\xe2\x7d\xff\xbd\xf7\ +\x8d\xaf\xf4\xc7\xe4\x1c\xb4\x67\xef\xd7\x4c\xe7\xe5\xba\xae\x4f\ +\x05\xe3\x3d\x67\xdb\xf7\x08\x56\xf0\x5b\x6e\x5f\x05\xc6\x0f\x2f\ +\x8d\xde\xc1\x4d\xa5\x64\xfb\x0d\x73\x73\x3b\xee\x17\xe4\x97\x85\ +\x85\x56\x39\x78\x7b\x20\xbe\x18\x15\xe3\x37\xe0\x67\x8a\x2c\xe7\ +\xea\x66\xb3\xb3\x81\xe2\x7f\xb7\x35\x7b\xa6\x93\x2e\xf8\x33\x11\ +\x3e\x03\x40\xf1\xef\xbd\xd8\xcf\xa7\x99\x9c\x23\xd8\xa8\xc5\xf2\ +\xbe\x1b\xec\x04\x16\x4c\x6c\xc6\x0f\x2f\xa3\xcd\xec\xd5\x5a\xcb\ +\x73\x0e\x3e\x2c\xc8\xf8\x0d\xdf\x33\xbd\x0f\x53\xfc\xef\xe2\xd5\ +\x56\xb2\xdc\xef\x04\xc5\xbf\xcf\x2b\x7f\x96\xfb\x22\x26\x27\x1e\ +\x1e\x1e\x5e\x3a\x3d\x61\xba\x17\x50\xfc\x57\xe8\xad\xb6\xf0\x17\ +\xa9\xf8\x37\xa4\xfb\xe4\xe8\xbe\x3f\x93\x13\x0f\x0f\x0f\x2f\x95\ +\xcf\x60\xfc\x7e\x56\x5f\xf8\x23\x8a\x3f\x5b\x04\x0f\xcc\x0b\xde\ +\xf7\x57\xa5\xf7\x63\x26\x27\x1e\x1e\x1e\x5e\xda\xbd\xce\x15\xe1\ +\xf3\x17\x14\x7f\x8a\xff\xda\x3d\xcd\xf4\xde\xc9\xe4\xc4\xc3\xc3\ +\xc3\xcb\x86\xa7\x1a\xf6\x3f\x52\xfc\x29\xfe\x6b\xf6\x1a\xa6\xb7\ +\xc0\xe4\xc4\xc3\xc3\xc3\xcb\xda\xde\x0d\x1d\x8d\xfa\x46\xf1\x5f\ +\xb5\x17\xac\x38\x17\xac\x39\xcd\x64\xc2\xc3\xc3\xc3\xcb\x98\x27\ +\x9d\xeb\x66\xcd\xce\xf1\xd4\x37\x8a\xff\x6a\xbc\x75\x7e\x10\x7d\ +\x86\xc9\x84\x87\x87\x87\x97\x51\x2f\xf6\x6a\x20\xf5\x8d\xe2\x9f\ +\xfc\xbe\xbf\xe5\x9c\xcf\x64\xc2\xc3\xc3\xc3\xcb\xb6\xd7\x30\x5d\ +\x9b\xfa\xb6\x86\xb7\xff\x8a\x36\x38\x8a\xd1\x39\x45\x98\xf6\x2d\ +\x4c\x26\x3c\x3c\x3c\xbc\x8c\xef\x15\x20\x9d\xdf\x28\x72\xcf\x03\ +\xa8\x6f\xff\x57\xf8\xc3\x75\x7f\x12\x2f\x12\x54\x2b\xca\xe0\x6c\ +\xdc\x78\xda\x84\x22\xdb\x9f\x67\x32\xe1\xe1\xe1\xe1\xe5\xc3\x13\ +\x96\xf3\x71\x8a\xff\xa1\xe2\x5f\x4a\xd4\x00\xc4\xf6\x13\xae\x17\ +\x65\x51\x05\xc5\x68\x3f\x8b\xc9\x84\x87\x87\x87\x97\x2f\xef\xf0\ +\x5b\x01\x05\x2d\xfe\xd1\x7e\x3f\xbd\x1b\x80\xf0\xcb\xd5\xf0\xec\ +\xbf\x5e\x88\xe2\xaf\xb4\x1e\x25\xa4\x73\x13\x93\x09\x0f\x0f\x0f\ +\x2f\x67\x9e\xf4\x6e\x10\xf3\xee\x09\x05\x2e\xfe\xe5\x70\xb7\xdf\ +\xc9\x9e\x4b\xff\x87\x5f\xae\x84\x67\xff\xb5\xd8\xde\xc2\xb9\x5e\ +\x54\x41\xd5\xed\x7f\x67\x32\xe1\xe1\xe1\xe1\xe5\x74\xaf\x00\xe9\ +\xbd\xb7\xa0\x7b\x05\x54\xc2\xcf\xa1\x06\xa0\x5f\xa7\xb0\x3e\xd6\ +\x00\xd4\xf2\x5e\xfc\xe7\x9a\xbb\x9a\x4c\x26\x3c\x3c\x3c\xbc\x7c\ +\x7b\x6a\x73\x71\xb6\x60\xc5\xbf\x1a\xd6\xf3\xa8\x01\x28\xf5\xbb\ +\x47\x50\x89\x35\x00\xd3\x79\x2f\xfe\x9b\x37\x9f\x71\x4f\x21\xed\ +\xcb\x99\x4c\x78\x78\x78\x78\x39\xf7\x8c\xce\x37\x0b\x54\xfc\xa3\ +\x1a\x1e\x35\x00\x93\xbd\x2e\xfd\x97\xc2\x0e\x21\x6a\x00\xaa\x45\ +\x58\x4b\x79\xce\xd8\x25\x99\x4c\x78\x78\x78\x78\x05\xd9\x2b\xa0\ +\xb1\x4b\x14\xa0\xf8\x47\x57\xef\xa3\x06\xa0\xdc\xab\xf8\x4f\x84\ +\xdd\xc1\x54\xec\x7e\x41\x21\x36\x52\x50\x65\xfb\xd3\x4c\x26\x3c\ +\x3c\x3c\xbc\x82\x78\xb2\xf3\x91\x02\xd4\xb7\x7a\xac\x01\xa8\xf4\ +\x7b\xe8\x2f\xde\x00\x94\x13\xaf\x12\x94\xf1\xe2\xbf\x5d\xd5\x1f\ +\xa1\x18\xf6\x1d\x4c\x26\x3c\x3c\x3c\xbc\xa2\x78\xce\xfe\x19\xcb\ +\xbb\x77\xce\xeb\x5b\xd4\x00\x54\x7b\xd6\xf3\xf0\x97\x26\x62\xef\ +\x08\x16\xa2\xf8\x1f\x3c\xfb\x37\xda\x17\x30\x99\xf0\xf0\xf0\xf0\ +\x8a\xe5\x09\xcb\x6b\xe7\xbc\xbe\xd5\x13\x3d\xc3\x17\x6b\x00\x4a\ +\x45\x2a\xfe\xc1\x7f\xf7\x03\xe1\x03\x4c\x26\x3c\x3c\x3c\xbc\xc2\ +\x6d\x14\xf4\xce\x9c\xd7\xb7\xda\x4a\x96\xfb\x9d\x28\x5a\xf1\x0f\ +\xfe\x77\xd5\x72\x7e\xc1\x64\xc2\xc3\xc3\xc3\x2b\x96\xa7\x4a\xef\ +\xc7\xec\x85\x73\xd4\x0a\x76\x05\xca\xd9\xe0\x88\x85\xdd\xf7\x61\ +\x32\xe1\xe1\xe1\xe1\x15\xd3\x9b\x9f\x3f\xbf\x5e\xe8\xe2\xbf\x96\ +\x9f\xac\x0f\x4e\x43\xba\x4f\x66\x32\xe1\xe1\xe1\xe1\x15\xd3\x6b\ +\x98\xbb\x1f\x47\xf1\x2f\x60\xf1\x0f\x7e\xd4\x96\xa7\x31\x99\xf0\ +\xf0\xf0\xf0\x8a\xea\x75\xb7\x53\xfc\x0b\x58\xfc\x83\x1f\xad\xe5\ +\x2c\x31\x99\xf0\xf0\xf0\xf0\x8a\xe9\x09\xcb\x35\x29\xfe\x05\x2c\ +\xfe\x07\x6f\x01\x98\xae\xcd\x64\xc2\xc3\xc3\xc3\x2b\xa8\x27\xdd\ +\x16\xc5\xbf\x80\xc5\x3f\xf8\x11\x96\x33\xcf\x64\xc2\xc3\xc3\xc3\ +\x2b\xaa\xe7\x36\x28\xfe\x05\x7d\x15\x42\xb3\x9c\x2d\x4c\x26\x3c\ +\x3c\x3c\xbc\x82\x7a\x2d\xf7\xcc\xa2\x16\xff\xc4\x6f\xff\xe5\x75\ +\x70\x1a\xa6\x73\x2a\x93\x09\x0f\x0f\x0f\xaf\xa8\x5e\xf7\x94\xa2\ +\x15\xff\xd8\xd2\xff\x89\x17\x09\xaa\xe5\x71\x70\x74\x5d\x9f\x52\ +\x2d\xef\x76\x26\x13\x1e\x1e\x1e\x5e\xd1\x3c\xe7\xd6\x33\xcf\xdc\ +\x33\x55\xc0\xe2\x5f\x4a\xd4\x00\xc4\xf6\x13\xae\xe7\x75\x70\xfc\ +\x20\xf8\x16\x93\x09\x0f\x0f\x0f\xaf\x60\x9e\x74\xbf\x52\xc0\xe2\ +\x1f\xed\xf7\xd3\xbb\x01\x08\xbf\x5c\x0d\xcf\xfe\xeb\x79\x1d\x1c\ +\x61\x7a\x7f\xcd\x64\xc2\xc3\xc3\xc3\x2b\x98\x27\xed\xbf\x29\x58\ +\xf1\x2f\x87\xbb\xfd\x4e\xf6\x5c\xfa\x3f\xfc\x72\x25\x3c\xfb\xaf\ +\xc5\xf6\x16\xce\xdd\xe0\x34\xa4\xfb\x74\x26\x13\x1e\x1e\x1e\x5e\ +\xb1\x3c\xc5\xd8\x35\x53\x90\xe2\x7f\x74\x58\xcf\x2b\xf1\x06\xa0\ +\x5f\xa7\xb0\x3e\xd6\x00\xd4\xf2\x3a\x38\xc1\x3d\x20\xc5\x74\xae\ +\x63\x32\xe1\xe1\xe1\xe1\x15\xc4\x33\xec\x5f\x6c\xd9\x72\xd6\x86\ +\x82\x14\xff\x6a\x58\xcf\xa3\x06\xa0\xd4\xef\x1e\x41\x25\xd6\x00\ +\x4c\xe7\x7c\x70\xea\xaa\xd1\xfe\x1b\x26\x13\x1e\x1e\x1e\x5e\x31\ +\x3c\xd5\x58\x7a\x75\x41\x8a\x7f\x54\xc3\xa3\x06\x60\xb2\xd7\xa5\ +\xff\x52\xd8\x21\x44\x0d\x40\x35\xef\xc5\x3f\x70\x76\xa8\xad\x53\ +\x85\x69\xef\x67\x32\xe1\xe1\xe1\xe1\xe5\xdb\x53\x0c\xfb\xb6\x99\ +\x86\x7c\x54\x01\x8a\x7f\x74\xf5\x3e\x6a\x00\xca\xbd\x8a\xff\x44\ +\xd8\x1d\x4c\xc5\xee\x17\xe4\xbe\xf8\x47\x1f\xd5\xb0\xdf\xc2\x64\ +\xc2\xc3\xc3\xc3\xcb\xb9\x27\xdb\xff\x50\x80\xe2\x1f\x3d\xb7\x17\ +\x35\x00\x95\x7e\x0f\xfd\xc5\x1b\x80\x72\xe2\x55\x82\x72\xb2\x68\ +\x50\xb3\xd9\xbd\x9f\x6a\x39\x37\x31\x99\xf0\xf0\xf0\xf0\xf2\xe9\ +\xf9\x27\x7a\xff\x3b\xa3\x99\x0f\x29\xc8\xc9\x6d\xd4\x00\x54\x7b\ +\xd6\xf3\xf0\x97\x26\x62\xef\x08\x16\xaa\xf8\x47\x9e\x66\xb9\x7b\ +\x98\x4c\x78\x78\x78\x78\xf9\xf4\x14\xa3\xfd\xcc\x02\x5d\xd9\xae\ +\x27\x7a\x86\x2f\xd6\x00\x94\x8a\x5a\xfc\xc3\x9f\x75\x9a\xe5\xfc\ +\x3b\x93\x09\x0f\x0f\x0f\x2f\x6f\xc5\xdf\xfe\x78\x91\x6e\x6b\x27\ +\x7e\x7b\x2f\xd6\x00\x14\xb9\xf8\x1f\xfc\xd9\xd1\xda\x73\xac\xdf\ +\x04\x5c\xc9\x64\xc2\xc3\xc3\xc3\xcb\x8b\x67\xff\x48\xd3\x16\xef\ +\x5d\xf4\xfa\x76\xc4\x67\x00\x8e\x5a\xe5\x4f\x1e\x07\xa7\x39\xbf\ +\xfb\xe1\x9a\x74\xae\x65\x32\xe1\xe1\xe1\xe1\x65\xfc\xcc\xdf\x74\ +\xae\xf3\xcf\xfe\x1f\x41\x7d\x1b\xf0\x4f\x9e\x07\x47\x69\xb9\x8f\ +\xf6\x9b\x80\xeb\x98\x4c\x78\x78\x78\x78\x19\xf5\x0c\xfb\x7a\x4d\ +\xb6\x1f\x4b\x7d\xa3\xf8\xaf\xd8\x6b\xce\x77\x1f\xe5\x37\x01\xd7\ +\x30\x99\xf0\xf0\xf0\xf0\x32\xe7\x5d\xd3\x68\xb9\xa7\x51\xdf\x28\ +\xfe\xab\xf6\x54\xe9\x3e\x54\x95\xde\x8f\x99\x4c\x78\x78\x78\x78\ +\x59\x79\xe0\xcf\xf9\x89\x62\x74\x4e\xa1\xbe\x51\xfc\xd7\xec\xed\ +\x10\xf3\x8f\x14\x66\xe7\x0a\x26\x27\x1e\x1e\x1e\x5e\xea\xbd\x2b\ +\x54\xab\x7d\x12\xf5\x8d\xe2\x3f\x30\x6f\x9b\xda\x3c\x45\x18\xed\ +\xcb\x98\x9c\x78\x78\x78\x78\xa9\xbd\xe7\xff\xdd\x19\x63\xe9\x04\ +\xea\x1b\xc5\x7f\xe0\xde\xec\x6c\xe3\x81\x7e\xd0\x7d\x95\xc9\x89\ +\x87\x87\x87\x97\x36\xaf\xf3\x75\x5e\xf5\x5b\x91\xb9\x8e\xc1\x59\ +\xa1\x37\x67\xdb\xf7\x10\x96\xf7\x39\x26\x27\x1e\x1e\x1e\x5e\x4a\ +\xee\xf9\xcb\xf6\xe7\x67\x77\xed\x3c\x86\xe2\x9f\xac\xf0\x87\xeb\ +\xfe\x24\x5e\x24\xa8\x46\xf1\xff\x3f\x6f\x66\xc6\xab\x0a\xcb\xf9\ +\x38\x93\x13\x0f\x0f\x0f\x6f\xdc\x0f\xfc\x75\x3e\x25\x44\x77\x9a\ +\xe2\x9f\xb8\xf8\x97\x12\x35\x00\xb1\xfd\x84\xeb\x14\xff\xbb\xfe\ +\xe8\xba\x3e\x25\xa4\xf3\x01\x26\x27\x1e\x1e\x1e\xde\x98\x3c\xd9\ +\xf9\x90\xaa\x2a\x15\x8a\x7f\xe2\xe2\x1f\xed\xf7\xd3\xbb\x01\x08\ +\xbf\x5c\x0d\xcf\xfe\xeb\x14\xff\xbb\xff\x6c\xda\xb4\xaf\xa4\x99\ +\xde\x3b\x98\x9c\x78\x78\x78\x78\xa3\x7e\xe0\xaf\xf3\xae\x33\xcf\ +\xdc\x33\x45\x3d\x4a\x5c\xfc\xcb\xe1\x6e\xbf\x93\x3d\x97\xfe\x0f\ +\xbf\x5c\x09\xcf\xfe\x6b\xb1\xbd\x85\x29\xfe\x87\xfd\xec\xdb\xb7\ +\xef\x68\x3f\x38\xdf\xc8\xe4\xc4\xc3\xc3\xc3\x1b\x8d\xa7\x1a\xf6\ +\x5b\x96\x96\x76\x95\xa8\x47\x89\xbd\x4a\xf8\x39\xd4\x00\xf4\xeb\ +\x14\xd6\xc7\x1a\x80\x1a\xc5\xbf\xf7\x8f\x1f\xa4\xaf\x66\x72\xe2\ +\xe1\xe1\xe1\x0d\xbd\xf8\xbf\x96\x7a\xb4\x22\xaf\x1a\xd6\xf3\xa8\ +\x01\x28\xf5\xbb\x47\x50\x89\x35\x00\xd3\x0c\x76\xc2\x26\xc0\xec\ +\xbc\x94\xc9\x8e\x87\x87\x87\x37\xb4\xe2\xff\x17\xd4\xa3\x15\x79\ +\x51\x0d\x8f\x1a\x80\xc9\x5e\x97\xfe\x4b\x61\x87\x10\x35\x00\x55\ +\x06\x7b\x65\x9e\x6a\xb4\x5f\xc4\x64\xc7\xc3\xc3\xc3\x1b\x70\xf1\ +\xd7\xdb\x2f\xa0\x1e\xad\xc8\x8b\xae\xde\x47\x0d\x40\xb9\x57\xf1\ +\x9f\x08\xbb\x83\xa9\xd8\xfd\x02\x06\x7b\x15\x9e\x6a\x2c\x5d\xe8\ +\x07\xec\x01\x26\x3b\x1e\x1e\x1e\xde\x9a\xbd\x03\xfe\x89\xd5\x05\ +\xd4\xa3\x15\x7b\xf5\x58\x03\x50\xe9\xf7\xd0\x5f\xbc\x01\x28\x27\ +\x5e\x25\x88\xc1\x5e\xd6\x13\x96\xb7\xa8\x5a\xde\xed\x4c\x76\x3c\ +\x3c\x3c\xbc\xd5\x79\x8a\xe9\xdc\xae\x18\x76\x97\xe2\xbf\x2a\x2f\ +\x6a\x00\xaa\x3d\xeb\x79\xf8\x4b\x13\xb1\x77\x04\x29\xfe\x03\xf0\ +\x34\xcb\x6d\xf8\x4d\xc0\xef\x99\xec\x78\x78\x78\x78\x2b\x2e\xfe\ +\xbf\x57\x8d\xa5\x05\x8a\xff\xaa\xbd\x7a\xa2\x67\xf8\x62\x0d\x40\ +\x89\xe2\x3f\x58\x4f\x95\xee\x36\xd5\x72\x6e\x61\xb2\xe3\xe1\xe1\ +\xe1\x25\x2d\xfe\xf6\xef\xe6\x9a\x8b\x0d\x8a\xff\x9a\xbc\xda\x4a\ +\x96\xfb\x9d\xa0\xf8\x0f\xc7\x6b\xc8\xee\x66\xbf\x09\xb8\x89\xc9\ +\x8e\x87\x87\x87\xd7\xc7\x93\xce\x4d\x73\xfa\xae\x6d\xd4\x8f\x11\ +\x79\xab\x2d\xfc\x0c\x76\x72\xaf\x61\xba\x4f\xd0\xa4\xf3\x6b\x26\ +\x3b\x1e\x1e\x1e\xde\x11\x3c\xc3\xbe\x61\x56\x5f\x3c\x93\xfa\x31\ +\x1e\x8f\xc1\x19\xa2\x27\x8c\xee\x46\xbf\x09\xb8\x96\xc9\x8e\x87\ +\x87\x87\x77\xb7\xe2\xff\x2b\xa5\x31\xff\x24\xea\x07\xc5\x3f\xb7\ +\x5e\x73\x7e\xf7\xc3\x55\xcb\xf9\x19\xc9\x03\x0f\x0f\x0f\xef\xd0\ +\xba\xfe\x3f\x57\xf5\x9d\x8f\xa7\x7e\x50\xfc\x73\xef\x35\xe6\xed\ +\x87\x2a\x46\xe7\x2a\x92\x07\x1e\x1e\x5e\xe1\x1f\xf8\x33\xec\xab\ +\x66\xc4\xfc\x69\xd4\x0f\x8a\x7f\x61\xbc\xb9\x39\xf3\x91\x8a\xd1\ +\xfe\x3e\xc9\x03\x0f\x0f\xaf\xb8\x5e\xe7\x7b\xdb\x85\xf1\x30\xea\ +\x07\xc5\xbf\x70\xde\xec\x6c\xe3\xa1\xc2\x70\xbe\x4d\xf2\xc0\xc3\ +\xc3\x2b\xdc\x99\xbf\xb4\xff\x6b\x76\xb6\xf9\x10\xea\x07\xc5\xbf\ +\xb0\xde\xdc\xc2\xfc\x06\xcd\xf4\xbe\x44\xf2\xc0\xc3\xc3\x2b\xce\ +\x3d\xff\xf6\x57\xb6\x6b\xea\x03\xa8\x1f\xe3\x2b\xfe\x89\xdf\xfe\ +\x63\xb0\x87\xeb\xe9\xfa\xde\x9a\x6a\x3a\x9f\x21\x79\xe0\x8d\xd2\ +\x53\xa5\x73\x9b\x66\x39\xfb\x19\x3f\xbc\xd1\xde\xf3\x6f\x7f\x6e\ +\x66\xa6\x71\x02\xf5\x63\x6c\x5e\xb4\xf4\x7f\xe2\x45\x82\x6a\x0c\ +\xf6\x70\xbd\xc5\xc5\xc5\x8a\x2a\xdd\x8f\x90\x3c\xf0\xd6\xe6\x39\ +\xfb\xfd\xef\x5f\xa6\x59\xee\x7b\x84\xe9\xbe\x52\x58\xce\xb9\x8a\ +\xbe\xa8\xcf\x36\x77\x3d\x6d\x46\x58\x8f\xdd\x26\x94\x93\xce\x39\ +\x47\xb9\xf7\xc6\x8d\xa7\x4d\xc4\xc2\x6f\xdd\xd6\xad\xe7\x97\x77\ +\xb4\xf6\x1c\xdb\x5c\xe8\x9c\x2c\xe6\x9d\x27\xfa\xd6\xac\x6f\x9c\ +\xa7\x5a\xce\xc5\xfe\x7f\x7e\xbf\x6f\x7d\xcf\x6f\x18\xee\xe0\x78\ +\xe0\xad\x6d\x91\x9f\xf6\xc7\xe6\xe6\x76\x1c\x47\xfd\x18\x6b\xf1\ +\x2f\x25\x6a\x00\x62\xfb\x09\xd7\x19\xec\xe1\x7b\x9e\xe7\x4d\x06\ +\x89\x9b\xe4\x81\x97\xd4\x13\xa6\x77\x85\xb0\xbc\xb7\x69\x2d\xcf\ +\x6b\x98\xbb\x1f\x17\x14\xf2\x61\xc5\xb3\x10\xdd\x69\xb5\xb9\x6b\ +\x93\x62\x2c\x3d\x4b\x91\xed\x77\x0b\xd3\xbe\x9a\xe3\x81\xb7\x82\ +\x57\xfd\x3e\x30\x3b\xbb\x7d\x03\xf9\x7e\xac\xc5\x3f\xda\xef\xa7\ +\x77\x03\x10\x7e\xb9\x1a\x9e\xfd\xd7\x19\xec\xd1\x78\xba\xae\x4f\ +\x1c\x4c\xe8\x24\x0f\xbc\x65\x3c\x21\xbd\xdf\x0a\xe9\x7c\x20\x28\ +\xf8\xba\xee\x9d\x34\xee\x78\x16\x56\xf7\x64\xbf\x09\x39\x37\xb8\ +\x7a\xa5\x4a\xef\x77\x1c\x5f\xbc\xe5\x3c\xd5\xb0\xff\x69\xcb\x96\ +\xb3\x8f\x25\xdf\x8f\xb5\xf8\x97\xc3\xdd\x7e\x27\x7b\x2e\xfd\x1f\ +\x7e\xb9\x12\x9e\xfd\xd7\x62\x7b\x0b\x33\xd8\xa3\xf1\xd6\x69\xd2\ +\x7b\x3d\xc9\x03\x2f\xbc\xac\x7f\xab\x5f\xf8\xdf\xdb\x30\x1d\x63\ +\x66\xc6\xab\xa6\x35\x9e\xe7\x6c\xfb\x1e\x0d\xd3\x5b\xd0\x4c\xef\ +\xc3\x77\x3e\x5f\xc0\xf1\xc5\x3b\x78\xd9\xff\x8d\x9b\x37\x9f\x71\ +\x0c\xf9\x7e\xac\x5e\x25\xfc\x1c\x6a\x00\xfa\x75\x0a\xeb\x63\x0d\ +\x40\x8d\xc1\x1e\xbd\x27\x2c\xef\x22\x92\x51\x71\xbd\xe0\x5e\xbe\ +\x7f\x76\xfd\xcc\x66\xb3\xb3\x21\x6b\xf1\x3c\x6b\x76\x8e\xf7\xe3\ +\xf7\xb9\xc1\x2d\x0a\x8e\x6f\xa1\x9f\xf6\xff\x2b\xf2\xfd\xd8\xbd\ +\x6a\x58\xcf\xa3\x06\xa0\xd4\xef\x1e\x41\x25\xd6\x00\x4c\x33\xd8\ +\xe3\xf3\x54\xd9\x7e\x19\xc9\xa8\x68\x9e\xf3\x31\xad\xe5\x9e\x9d\ +\x93\x78\x5e\xa7\xb6\x9c\x19\x4d\x7a\x9f\xe5\xf8\x16\xee\xb2\xff\ +\xcb\xc8\xf7\x63\xf7\xa2\x1a\x1e\x35\x00\x93\xbd\x2e\xfd\x97\xc2\ +\x0e\x21\x6a\x00\xaa\x0c\xf6\xf8\x3d\x45\x5f\x7a\x3e\xc9\x28\xf7\ +\xde\x81\xe0\x21\x29\x55\xf7\x1e\x93\xd7\x78\x9e\xd3\x76\x6e\x0e\ +\x9e\x02\x27\x5e\x0a\xf0\xaa\x9f\xde\x7e\x1e\xf9\x7e\xec\x5e\x74\ +\xf5\x3e\x6a\x00\xca\xbd\x8a\xff\x44\xd8\x1d\x4c\xc5\xee\x17\x30\ +\xd8\x29\xf1\x54\x69\xbf\x87\x64\x94\xd3\x33\x25\xdd\xfe\xf7\x39\ +\x6d\xd7\x93\x8b\x12\xcf\x73\xc6\xc2\xd9\xc2\xec\x5c\x42\xbc\xe4\ +\x75\x85\xbf\xf6\xbb\xc9\xf7\xa9\xf0\xea\xb1\x06\xa0\xd2\xef\xa1\ +\xbf\x78\x03\x50\x4e\xbc\x4a\x10\x83\x3d\x74\x2f\x78\x7a\x56\xb5\ +\x9c\x5f\x90\x8c\x72\xe6\x49\xfb\x72\xb5\xb1\x38\x57\xd4\xf9\xa1\ +\xb6\xba\x8a\x66\x39\x57\x12\x2f\xb9\xf3\xae\x99\x9b\x9b\x99\x24\ +\xdf\x8f\xdd\x8b\x1a\x80\x6a\xcf\x7a\x1e\xfe\xd2\x44\xec\x1d\x41\ +\x8a\x7f\x8a\x3c\xd5\x70\x76\x90\x8c\xf2\xe3\xf9\xc7\xf3\xe6\xe0\ +\x12\xe9\x96\x2d\x67\x6d\x28\xfa\xfc\xd0\x75\x7d\x4a\x33\xbd\x17\ +\x06\x6f\x3a\x10\x2f\x79\xf2\x9c\x2d\xe4\xfb\xb1\x7b\xf5\x44\xcf\ +\xf0\xc5\x1a\x80\x12\xc5\x3f\x7d\x9e\xb0\xdc\x7f\x26\x19\xe5\xc3\ +\x53\xf4\xce\xa7\x66\x35\xe3\x34\xe6\xc7\x5d\x7f\xfc\xf1\x79\x84\ +\x26\x9d\x4b\x89\x97\x7c\x78\x7e\xce\x7a\x3b\xf9\x7e\xec\x5e\x6d\ +\x25\xcb\xfd\x4e\x50\xfc\xd3\xe7\x2d\x2c\x2c\x4c\x07\x8b\xbf\x90\ +\x8c\xb2\xed\x29\xa6\x7d\x8b\x6a\x2c\x5d\xc8\xfc\x38\xf2\xcf\xbe\ +\x7d\xfb\x8e\x0e\x5e\x1d\x5c\x6e\x0d\x01\xe2\x2f\x5b\x9e\x6a\x39\ +\x37\x35\x9b\x17\xac\x27\xdf\x67\xc0\x5b\x6d\xe1\x67\xb0\x87\xef\ +\xf9\x9d\xb4\x49\x32\xca\x7a\xf1\x77\xbe\x33\xab\x59\xa7\x13\xcf\ +\xc9\x7e\xd4\x96\xf3\x78\xbf\x09\xf8\x01\xf1\x97\x6d\x4f\xb4\x3c\ +\x9d\x78\xce\x96\xc7\xe0\xa4\xcc\x0b\x36\x62\x21\x19\x65\xb8\xf8\ +\xcb\xce\x3b\xb7\x6f\x17\xf7\x25\x9e\x57\xf6\x33\x3f\x7f\x7e\x5d\ +\x33\xdd\x0f\x12\x7f\x59\xf6\xdc\xf7\x10\xcf\x14\x7f\xbc\x55\x3f\ +\x20\xb5\xb7\xb6\x92\xf5\xd5\x49\x46\xe9\xf1\x54\xcb\xbb\x5d\x31\ +\xec\xe7\x10\xcf\xab\xf7\x82\xe5\x63\x83\xc5\x64\x0e\xae\x91\x40\ +\xfc\x65\xd0\x73\x6e\x3e\xd2\xd2\xd5\xe4\x7b\x8a\x3f\x5e\x1f\x2f\ +\x58\xfb\x9d\x64\x94\xc5\xe2\xef\xdc\x34\xd7\x5c\x6c\x10\xcf\x83\ +\xf1\xd4\xe6\x52\x5b\x98\xf6\xad\xc4\x5f\xf6\x3c\xb5\xe5\x69\xc4\ +\x33\xc5\x1f\x6f\x15\x9e\x66\x7a\xef\x24\x19\x65\xae\xf8\xff\x62\ +\x46\x5f\x78\x0a\xf1\x3c\xe0\x57\x61\x4d\xf7\x8f\x34\xe9\xfc\x9a\ +\xf8\xcb\x96\x77\xf8\xdb\x00\xc4\x33\xc5\x1f\x2f\x81\xe7\x79\xde\ +\xa4\x6a\x79\x37\x92\x8c\xb2\xe4\xb9\x3f\x99\x6b\x2c\x3c\x8e\x78\ +\x1e\xd2\x03\xb1\x46\x77\xa3\x3f\x27\x7e\x45\xfc\x65\xc8\xf3\x9b\ +\xb6\x4d\x9b\xf6\x95\x88\x67\x8a\x3f\xde\x4a\xde\x8b\x6e\xb9\x67\ +\x93\x8c\x32\x74\xe6\x2f\xdd\x1f\xce\x35\xe4\xa9\xc4\xf3\x70\xbd\ +\x83\xeb\x05\x58\xde\xcf\x89\xbf\xec\x78\x0d\xd9\xdd\x4c\x3c\xa7\ +\xaf\xf8\x27\x7e\xfb\x8f\xc1\x1e\xbd\x27\x4c\xef\xaf\x49\x1e\x99\ +\xb9\xec\x7f\x35\xc5\x7f\x74\x9e\x2a\x3b\x8f\xec\x77\x25\x80\x78\ +\x4e\xd5\x95\xb1\x8b\x89\xe7\x54\x79\xd1\xd2\xff\x89\x17\x09\xaa\ +\x31\xd8\xa3\xf5\xe2\xef\x41\x93\x8c\xd2\x7d\xcf\x9f\xcb\xfe\xa3\ +\xf7\x82\xdb\x01\x47\x7a\x26\x80\x78\x4e\x97\xa7\x4a\xfb\xbf\x89\ +\xe7\x54\x15\xff\x52\xa2\x06\x20\xb6\x9f\x70\x9d\xc1\x1e\x9d\xd7\ +\x5c\x70\x1e\x4c\xf2\xc8\xc6\xd3\xfe\x3c\xf0\x37\x3e\xaf\x21\x9d\ +\xa7\x1e\xbe\x87\x00\xf1\x9c\x4e\x6f\x87\xda\x3a\x95\x78\x4e\x45\ +\xf1\x8f\xf6\xfb\xe9\xdd\x00\x84\x5f\xae\x86\x67\xff\x75\x06\x7b\ +\x74\x9e\xb0\xdc\x2e\xc9\x23\xfd\xef\xf9\xf3\xaa\xdf\xf8\x3d\x4d\ +\xba\x2d\xff\x78\x1c\x20\x9e\x53\xbe\xe5\xb5\x6c\x9f\x47\x3c\x8f\ +\xbd\xf8\x97\xc3\xdd\x7e\x27\x7b\x2e\xfd\x1f\x7e\xb9\x12\x9e\xfd\ +\xd7\x62\x7b\x0b\x33\xd8\x23\xf0\x84\xf4\xde\x4b\xf2\x48\xf9\x0a\ +\x7f\x2c\xf2\x93\x1a\x4f\x98\xee\x4b\x88\xe7\x74\x7b\x8a\xb4\xdf\ +\x47\x3c\x8f\xd5\xab\x84\x9f\x43\x0d\x40\xbf\x4e\x61\x7d\xac\x01\ +\xa8\x31\xd8\x23\xf3\xd6\x69\xd2\xb9\x9e\xe4\x91\xee\xe5\x7d\x89\ +\xe7\x74\xad\x18\xa8\xe8\xf6\xc7\x89\xe7\x14\x7b\xd2\xb9\x96\x78\ +\x1e\x9b\x57\x0d\xeb\x79\xd4\x00\x94\xfa\xdd\x23\xa8\xc4\x1a\x80\ +\x69\x06\x7b\x74\x9e\xd2\x72\x1e\x4b\xf2\x48\xf7\xc6\x3e\xac\xed\ +\x9f\x3e\x6f\xab\xa2\x3f\x50\x95\x9d\x1f\x13\xcf\x29\xde\x22\xd8\ +\xd8\x7d\x1a\xf1\x3c\x72\x2f\xaa\xe1\x51\x03\x30\xd9\xeb\xd2\x7f\ +\x29\xec\x10\xa2\x06\xa0\xca\x60\x8f\xd6\x13\xa6\xfb\x0c\x92\x47\ +\x7a\xb7\xf4\x65\x57\xbf\xf4\x7a\x73\xc6\xce\xb3\x34\xcb\xd9\x4f\ +\x3c\xa7\xd3\x13\xa6\x77\x2e\xf1\x3c\x52\x2f\xba\x7a\x1f\x35\x00\ +\xe5\x5e\xc5\x7f\x22\xec\x0e\xa6\x62\xf7\x0b\x18\xec\x11\x7b\xc1\ +\x0e\x5a\x24\x8f\x74\x7a\x8a\xb1\xf4\x2c\xe2\x39\xdd\x9e\x3f\x7f\ +\xfe\x94\x78\x4e\xa7\x27\x2c\xef\x5d\xc4\xf3\x48\xbd\x7a\xac\x01\ +\xa8\xf4\x7b\xe8\x2f\xde\x00\x94\x13\xaf\x12\xc4\x60\x0f\xd4\xd3\ +\xa4\x73\x0d\xc9\x23\x7d\x9e\x2a\xdb\x9f\x26\x9e\xd3\xef\xe9\xba\ +\x3e\xa1\x49\xf7\x2b\xc4\x73\xfa\x3c\xd5\x72\x7e\x46\x3c\x8f\xd4\ +\x8b\x1a\x80\x6a\xcf\x7a\x1e\xfe\xd2\x44\xec\x1d\x41\x8a\xff\x18\ +\xbc\x39\xc3\x7d\x08\xc9\x23\x85\xc5\xdf\x70\x6e\x9e\xd5\x8c\xd3\ +\x88\xe7\x6c\x78\x0d\xb3\xf3\x18\x55\x3a\xb7\x11\xcf\xe9\xf3\x74\ +\xdd\x3b\x89\x78\x1e\x99\x57\x4f\xf4\x0c\x5f\xac\x01\x28\x51\xfc\ +\xc7\xe7\x09\xdd\xb6\x49\x1e\xe9\xf3\x14\xbd\xfd\x3c\xe2\x39\x5b\ +\x9e\x30\xbd\x97\x11\xcf\xe9\xf3\x82\x2d\xce\x89\xe7\x91\x79\xc9\ +\xde\xde\x8b\x35\x00\x14\xff\x31\x7a\x42\xb6\xff\x96\xe4\x91\x32\ +\x4f\xda\x97\x6f\xd9\x72\xd6\x06\xe2\x39\x5b\x5e\xb3\x79\xc1\xfa\ +\x60\x77\x46\xe2\x39\x5d\x9e\x6a\x39\x17\x13\xcf\x29\xf3\x56\x5b\ +\xf8\x19\xec\xc1\x7a\x8a\x61\x7f\x99\xe4\x91\xb2\x15\xcc\x1a\x8b\ +\x73\xc4\x73\x36\x3d\x61\xb9\x26\xf1\x9c\x2e\x4f\x35\x9d\x4b\x88\ +\x67\xb6\x08\xc6\x3b\xcc\xdb\xbe\x7d\xcb\xb1\xc1\xbd\x66\x92\x47\ +\x8a\x8a\xbf\x6e\xff\x3b\xf1\x9c\x6d\x4f\x93\xce\x17\x89\xe7\x14\ +\x79\xa6\xf7\xbf\xfe\x61\x59\x47\x3c\x53\xfc\xf1\x62\xde\x5c\x63\ +\xfe\x0f\x49\x1e\xa9\xf2\x0e\x28\x8d\xf9\x27\x11\xcf\xd9\xf6\xfc\ +\xe3\xf8\x34\xe2\x39\x6d\x5e\xf7\x14\xe2\x99\xe2\x8f\x17\xf3\xd4\ +\x66\x7b\x89\xe4\x91\x22\xcf\xe8\x7c\x80\x78\xce\x87\x27\x2c\xf7\ +\xb3\xcc\x8f\xf4\x78\x42\x7a\x3a\xf1\x4c\xf1\xc7\x8b\x79\x9a\xe9\ +\xbc\x9c\xe4\x91\x1e\x4f\xd5\xbd\xc7\x10\xcf\xf9\xf0\xd4\xc6\xd2\ +\x76\xe6\x47\x8a\x3c\x63\xe9\x22\xe2\x99\xe2\x8f\x17\x5f\xc1\xcc\ +\x74\xff\x95\xe4\x91\x16\xcf\xf9\x18\xf1\x9c\x2f\x4f\x91\xed\x6f\ +\x30\x3f\x52\xe2\xc9\xce\x87\x89\x67\x8a\x3f\x5e\xcc\x13\xa6\x77\ +\x05\xc9\x23\x25\x5e\xcb\x3d\x9b\x78\xce\x97\xa7\x36\x97\xda\xcc\ +\x8f\x74\x78\xaa\xb4\x7f\x40\x3c\x8f\xbf\xf8\x27\x7e\xfb\x8f\xc1\ +\x1e\xfa\xf2\xa5\x53\xaa\xe5\xdd\x4e\xf2\x18\xbf\xe7\xff\xf3\x32\ +\xe2\x39\x7f\xde\x96\x2d\x67\x1f\xeb\x1f\xdf\x9f\x33\x3f\xd2\xe0\ +\xd9\xfb\x67\x67\xb7\x6f\x20\x9e\xc7\xe6\x45\x4b\xff\x27\x5e\x24\ +\xa8\xc6\x60\x0f\xcf\x6b\xce\x77\x1f\x45\xf2\x48\xc9\x96\xa5\xa6\ +\xf7\x4c\xe2\x39\x9f\x5e\x92\xd5\x01\x99\x1f\xa3\xf1\xfc\xcf\xa3\ +\x88\xe7\xb1\x15\xff\x52\xa2\x06\x20\xb6\x9f\x70\x9d\xc1\x1e\x9e\ +\xa7\xb6\xba\x0a\xc9\x23\x0d\x9e\x73\x6b\xb3\xd9\xd9\x40\x3c\xe7\ +\xd3\x53\x64\xf7\x41\xfe\x71\x3e\xc0\xfc\x48\x85\x37\x4b\x3c\x8f\ +\xa5\xf8\x47\xfb\xfd\xf4\x6e\x00\xc2\x2f\x57\xc3\xb3\xff\x3a\x83\ +\x3d\x3c\x4f\x33\xdd\x67\x91\x3c\x52\xb0\x5f\xb9\xf4\xde\x4b\x3c\ +\xe7\xbc\xd9\x36\x9d\x4b\x98\x1f\x69\xb8\xd2\xe6\x5e\x40\x3c\x8f\ +\xbc\xf8\x97\xc3\xdd\x7e\x27\x7b\x2e\xfd\x1f\x7e\xb9\x12\x9e\xfd\ +\xd7\x62\x7b\x0b\x33\xd8\x43\xf0\x34\xe9\xbd\x9e\xe4\x31\x7e\xef\ +\x48\x1b\x95\x10\xcf\xf9\xf1\x84\xe9\x9d\xcb\xfc\x48\x41\xb3\x6d\ +\x7a\xaf\x25\x9e\x47\xea\x55\xc2\xcf\xa1\x06\xa0\x5f\xa7\xb0\x3e\ +\xd6\x00\xd4\x18\xec\xe1\x79\xaa\x74\x3f\x42\xf2\x18\xaf\xe7\x9f\ +\xfd\xff\x76\x66\xc6\xab\x12\xcf\xf9\xf6\x66\xcd\xce\xf1\xfd\x1e\ +\xb8\x65\x7e\x8c\xc0\x33\xbd\x0f\x13\xcf\x23\xf3\xaa\x61\x3d\x8f\ +\x1a\x80\x52\xbf\x7b\x04\x95\x58\x03\x30\xcd\x60\x0f\xd7\xd3\x2c\ +\xf7\x3b\x24\x8f\xf1\x7a\x42\x3a\x1f\x20\x9e\x8b\xe1\x09\xcb\xfb\ +\x02\xf3\x63\xcc\x9e\x74\xbe\x4d\x3c\x8f\xc4\x8b\x6a\x78\xd4\x00\ +\x4c\xf6\xba\xf4\x5f\x0a\x3b\x84\xa8\x01\xa8\x32\xd8\xc3\xf7\xfc\ +\xe2\xf3\x1b\x92\xc7\x98\xbd\x96\xe7\x11\xcf\xc5\xf0\xfc\xb3\xcf\ +\x17\x32\x3f\xc6\xec\x49\xef\x06\xe2\x79\xe8\x5e\x74\xf5\x3e\x6a\ +\x00\xca\xbd\x8a\xff\x44\xd8\x1d\x4c\xc5\xee\x17\x30\xd8\x43\xf6\ +\x74\x7d\x6f\x8d\xe4\x31\x7e\x4f\x91\x7b\x1e\x40\x3c\x17\xc3\x53\ +\x5b\xce\xe3\x99\x1f\xe3\xf7\x16\x16\x16\xa6\x89\xe7\xa1\x7a\xf5\ +\x58\x03\x50\xe9\xf7\xd0\x5f\xbc\x01\x28\x27\x5e\x25\x88\xc1\x5e\ +\x93\x17\xec\x8c\x45\xf2\x18\xaf\x17\xac\xc2\x48\x3c\x17\xca\x5b\ +\x17\x9c\x81\x32\x3f\xc6\xeb\x35\x17\x3a\x27\x13\xcf\x43\xf5\xa2\ +\x06\xa0\xda\xb3\x9e\x87\xbf\x34\x11\x7b\x47\x90\xe2\x3f\x22\xaf\ +\x21\x9d\xa7\x92\x3c\xc6\xeb\x09\xcb\x7b\x1b\xf1\x5c\x2c\x2f\x7a\ +\xf0\x96\xf9\x31\x3e\x4f\xb5\xbc\x33\x88\xe7\xa1\x7a\xf5\x44\xcf\ +\xf0\xc5\x1a\x80\x12\xc5\x7f\x44\x97\x21\xa5\xf3\x30\xcd\x74\x9f\ +\x17\x3c\x0c\x43\xf2\x18\xb3\xb7\xcc\xfd\x7f\xe2\x39\xdf\x9e\x66\ +\x3a\xcf\x67\x7e\x8c\xd9\x0b\x72\x9f\x9f\x03\x83\x5c\x48\x3c\x0f\ +\xc5\x4b\xf6\xf6\x5e\xac\x01\xa0\xf8\x0f\xd1\x13\x46\x77\xa3\x9f\ +\x78\x5e\xe2\x77\xbe\xdf\x25\x79\xa4\xc7\x6b\x98\xbb\x1f\x47\x3c\ +\x17\x6c\x8b\xe0\xe6\xe2\x2c\xf3\x23\x3d\x9e\x62\x3a\x97\xab\x86\ +\x7d\xd1\x9c\xd8\xf9\x14\xe2\x79\xc4\xde\x6a\x0b\x3f\x83\xdd\xd7\ +\x5b\xd7\x30\xdd\x27\x08\xd3\x7d\xa5\x66\x39\x57\x32\xd9\xd3\xe8\ +\x39\xfb\xb7\x6e\x3d\xbf\x4c\x3c\x17\xcb\xdb\xa1\xc9\x93\x99\x1f\ +\xe9\xf4\x54\xe9\xfc\xd0\xff\xe7\xab\x82\xdc\x19\xe4\x50\xe2\x79\ +\x74\x1e\x83\xb3\x46\x4f\xd7\xf5\x89\x86\xec\x6e\xd6\x2c\xf7\x35\ +\x9a\xf4\x7e\xca\x64\x4f\xb7\x17\xdf\xfd\x8f\x78\x2e\x96\x27\x0c\ +\xfb\x57\xcc\x8f\x94\x7b\x07\x73\xa8\xfb\x9a\x20\xa7\x06\xb9\x95\ +\x78\xa6\xf8\xa7\xce\xf3\x3c\x6f\x52\x98\xde\x56\x3f\x60\xdf\xa8\ +\x5a\xde\xaf\x98\xec\x59\xf2\xdc\xf7\x10\xcf\xc5\xf4\x14\xd9\xbe\ +\x84\xf9\x91\x1d\xef\x60\x6e\x95\xce\x9b\x82\x5c\x1b\xe4\x5c\xe2\ +\x99\xe2\x3f\x36\x6f\xfb\xf6\xc6\x7d\x34\xd3\x15\xc2\x72\xdf\x1e\ +\x7f\xa5\x88\xc9\x9e\x2d\x2f\xb8\x3d\x43\x3c\x17\xd3\xd3\x4c\xe7\ +\xad\xcc\x8f\xac\x3e\x40\xe8\xdd\x10\xe4\x5e\xff\xf7\x84\x10\xdd\ +\x69\xe2\x99\xe2\x3f\x74\x6f\xab\x50\x4e\x14\x7a\xbb\x23\xa4\xfd\ +\xaf\xc1\xda\xf1\x4c\xce\xec\x7b\xc2\x72\xce\x25\x79\x14\xd3\xf3\ +\x0b\xc8\x8b\x98\x1f\xd9\xf7\x54\xc3\xb9\xf9\x60\x4e\xf6\x73\x73\ +\x90\xa3\x99\x1f\x14\xff\x81\x79\xb3\xb3\x8d\x07\x2a\x46\x7b\xaf\ +\x30\x3a\x1f\x13\xa6\x7d\x2b\x93\x33\x67\x4f\x1f\xeb\x8b\x3a\xc5\ +\xb0\x98\x9e\xb0\xba\xbb\x98\x1f\x79\xf3\xec\x5b\x35\xcb\xf9\x48\ +\xc3\x74\x6d\x75\xe7\xb9\xf7\x62\x7e\x50\xfc\x57\xec\xe9\xfa\xde\ +\xfb\xfa\x41\xb4\x57\x35\xdb\x9f\xf5\x03\x6a\x3f\x93\x33\xbf\xde\ +\x6c\x73\xd7\xd3\x28\x86\xc5\xf4\x54\xe9\x6e\x63\x7e\xe4\xd9\x73\ +\xf6\xfb\xff\xfc\xb4\xb0\xdc\xbd\x62\xde\x3d\x81\xf9\x71\x37\x73\ +\x1d\xc9\x23\xfc\xd1\x5a\xf6\x03\xfd\x60\xb9\x50\x35\xdd\xcf\xab\ +\xd2\xb9\x83\xc9\x54\x0c\x6f\x46\x58\x8f\xa5\x18\x16\xd3\x53\xad\ +\xee\xe9\xcc\x8f\xc2\x78\x07\xc2\x5d\x20\x2f\x54\x64\xf7\x41\x05\ +\x9f\x1f\xd1\xd2\xff\x89\x17\x09\xaa\xe5\x71\x70\x9a\xf3\xbb\x1f\ +\xee\x07\xc5\xf3\xfd\x4e\xf1\xeb\x4c\xa6\x62\x7a\xdb\x84\x72\x12\ +\xc5\xb0\x98\x9e\xd6\xda\xf3\x10\xe6\x47\x51\xbd\x20\xe7\xbb\x2f\ +\xf0\x7f\xf7\x51\x05\x2c\xfe\xa5\x44\x0d\x40\x6c\x3f\xe1\x7a\x5e\ +\x06\x47\x69\x39\x8f\x0d\x56\xe3\x0b\xde\xff\x66\x32\xe1\x9d\x73\ +\x8e\x72\x6f\x8a\x61\x31\xbd\xe0\xb2\x30\xf3\x03\x4f\x98\x9d\xef\ +\xa9\xb2\xfd\x4a\xa5\xb1\xeb\xa9\x05\x28\xfe\xd1\x7e\x3f\xbd\x1b\ +\x80\xf0\xcb\xd5\xf0\xec\xbf\x9e\xe1\xc9\xbe\x4e\xcc\x3b\x4f\xf4\ +\x0f\xf6\xab\x7a\xad\xc6\xc7\x64\x2a\xa6\xb7\x71\xe3\x69\x13\x14\ +\xc3\x62\x7a\xcd\x66\x67\x03\xf3\x03\xef\xae\xab\x10\xba\x3f\x54\ +\x2d\xe7\x62\xd5\xf2\x9e\x74\xd4\x0a\x56\x21\xcc\x48\xf1\x2f\x87\ +\xbb\xfd\x4e\xf6\x5c\xfa\x3f\xfc\x72\x25\x3c\xfb\xaf\xc5\xf6\x16\ +\xce\xc4\x64\x0f\x56\x8c\xd2\x5a\xee\x99\xc2\xf4\x5e\xeb\x1f\xcc\ +\x9f\x11\xfc\x78\xcb\x4f\x76\xe7\x36\x8a\x61\x71\xbd\x60\x3f\x7a\ +\xe6\x07\x5e\x0f\xef\xe7\x9a\xe5\xbe\xce\xff\xff\x9e\xd6\x6b\x15\ +\xc2\x8c\xcc\x8f\x4a\xf8\x39\xd4\x00\xf4\xeb\x14\xd6\xc7\x1a\x80\ +\x5a\xda\x27\xbb\xaa\x2a\x95\xe0\xa9\x5e\x61\xba\x6f\x5e\xc9\x6a\ +\x7c\x04\x7f\x91\x3d\x67\x3f\xc5\xb0\xb8\x9e\xae\xef\xad\x31\x3f\ +\xf0\x12\x79\xd2\xb9\x4e\x58\xde\x3f\x68\x56\x77\xbb\xdf\x0c\x4c\ +\x65\x6c\x7e\x54\xc3\x7a\x1e\x35\x00\xa5\x7e\xf7\x08\x2a\xb1\x06\ +\x60\x3a\xcd\x93\x5d\x6d\xec\xdc\xe2\x17\xfd\xb7\xf9\x45\xff\x46\ +\x82\x15\x6f\xa5\x5e\xce\x2e\xf3\xe1\xad\xc0\x5b\xee\x16\x00\xf3\ +\x03\xaf\xef\xc2\x43\x7e\xad\x11\xa6\xf7\x56\xcd\xe8\x6c\xca\xc0\ +\xfc\x88\x6a\x78\xd4\x00\x4c\xf6\xba\xf4\x5f\x0a\x3b\x84\xa8\x01\ +\xa8\xa6\x75\xb2\xcf\x19\x4b\x2d\x61\xda\xdf\x22\x58\xf1\xd6\xe2\ +\xc5\x77\x02\xa4\xb8\x16\xcb\x3b\xfc\x21\x40\xe6\x07\xde\x8a\x3d\ +\xa3\xf3\x4d\x45\x5f\xb4\x52\x3a\x3f\xa2\xab\xf7\x51\x03\x50\xee\ +\x55\xfc\x27\xc2\xee\x60\x2a\x76\xbf\x20\x75\x93\x5d\xd5\x17\x9e\ +\xa0\x18\xed\x2f\x10\xac\x78\x83\xf0\x76\xb4\xf6\x1c\x4b\x31\x2c\ +\xa6\xa7\x4a\xf7\xa1\xcc\x0f\xbc\x41\x78\x8a\x6c\x7f\xbe\xd1\x72\ +\x4f\x4b\xd9\xfc\xa8\xc7\x1a\x80\x4a\xbf\x87\xfe\xe2\x0d\x40\x39\ +\xf1\x2a\x41\xa3\x2c\xfe\x46\xfb\xf9\x2c\xc7\x8b\x37\x48\xaf\xb9\ +\xd0\x39\x99\x62\x58\x4c\x2f\xd8\x6f\x9e\xf9\x81\x37\xc0\x67\x8a\ +\xfc\xda\xe4\x5e\x90\xa2\xf9\x11\x35\x00\xd5\x9e\xf5\x3c\xfc\xa5\ +\x89\xd8\x3b\x82\xa9\x2a\xfe\x5b\xb6\xcc\x9d\xa0\xea\x9d\x0f\x12\ +\xac\x78\x83\xf6\x82\x57\x44\x29\x86\xc5\xf4\x84\x74\x66\x99\x1f\ +\x78\x83\xf7\xdc\xf7\x34\x9b\x17\xac\x4f\xc1\xfc\xa8\x27\x7a\x86\ +\x2f\xd6\x00\x94\xd2\x56\xfc\x83\x95\xda\x84\xd1\xfe\x0a\xc1\x85\ +\x37\x24\x6f\x96\x62\x58\x4c\x4f\x95\x8b\x7b\x98\x1f\x78\xc3\xf0\ +\x82\x65\x87\x75\xdd\x3b\x66\xcc\xf3\xa3\xb6\x92\xe5\x7e\x27\xd2\ +\x56\xfc\x77\xec\xd0\xee\x2f\x0c\xfb\x6b\x04\x17\xde\xf0\x3c\xf7\ +\x3c\x8a\x61\x31\x3d\xd5\xb0\x5f\xc1\xfc\xc0\x1b\x96\x27\x2c\xe7\ +\xcb\xc1\x5a\x13\xa9\x9f\x1f\xab\x2d\xfc\xc3\xbd\xec\x7f\xd6\x06\ +\x21\xdb\x9f\x24\xb8\xf0\x86\xe9\x05\xab\x7e\x51\x0c\x8b\xe9\xa9\ +\xd2\xfe\x67\xe6\x07\xde\x70\x3d\xe7\xdf\xf6\xed\xdb\x77\x74\x56\ +\xe6\x47\x9a\x1e\xf8\xbb\x98\xe0\xc2\x1b\x81\xf7\x7e\x8a\x61\x31\ +\x3d\xde\x26\xc2\x1b\x89\x67\x3a\x2f\xa1\xf8\xaf\xa4\xf8\x37\x16\ +\xb6\x29\x86\x7d\x07\xc1\x85\x37\x6c\x4f\x98\xee\xf7\x28\x86\xc5\ +\xf4\x84\x61\x5f\xcf\xfc\xc0\x1b\xb6\x17\x6c\x2f\xaf\x9a\xee\x1f\ +\x51\xfc\x13\x78\xe7\x9c\x33\x77\x1f\x61\x76\xae\x20\xb8\xf0\x46\ +\x32\x39\x2d\xef\x76\x21\xba\xd3\x14\xd7\x62\x79\x33\x0d\x79\x0a\ +\xf3\x03\x6f\x54\x9e\x7f\x42\xfb\xfd\x6d\xdb\x9e\x7e\x1c\xc5\xbf\ +\xdf\x65\x39\x7d\xe9\x85\x04\x17\xde\x28\x3d\xb5\xb9\x6b\x13\xc5\ +\xb5\x58\x5e\xc3\x70\xb6\x32\x3f\xf0\x46\xe9\x29\x7a\xfb\x79\x14\ +\xff\x1e\xde\xdc\xdc\x8e\xfb\x09\xc3\xfe\x1f\x82\x0b\x6f\x94\x9e\ +\x62\x2c\x3d\x8b\xe2\x5a\x2c\x4f\x58\xee\x8b\x98\x1f\x78\x23\xf5\ +\x0c\xfb\x57\xdb\xb7\x37\xee\x43\xf1\x3f\x82\xa7\xca\xf6\xb3\x09\ +\x2e\xbc\x91\x77\xe6\xb2\xfd\x6e\x8a\x6b\xb1\x3c\x61\x39\x1f\x67\ +\x7e\xe0\x8d\xdc\x6b\xb9\xdd\xb4\x14\xff\xc4\x6f\xff\x8d\x6a\x72\ +\x6a\x96\xfb\x1d\x82\x0b\x6f\xf4\x9e\x7d\x35\xc5\xb5\x38\x5e\xf0\ +\x5a\x96\x90\xce\x6f\x98\x1f\x78\x23\xf7\xa4\xf7\xb5\x14\xcc\x8f\ +\x68\xe9\xff\xc4\x8b\x04\xd5\x86\x3d\x39\xe7\xac\xce\x46\x82\x0b\ +\x6f\x5c\x9e\xb0\xba\x27\x53\x5c\x8b\xe1\x45\x7b\x00\x30\x3f\xf0\ +\xc6\xe1\xa9\xd2\x79\xd8\x98\x8b\x7f\x29\x51\x03\x10\xdb\x4f\xb8\ +\x3e\xfc\x7b\x72\xde\xf3\x09\x2e\xbc\x71\x79\xc2\xf4\xce\xa5\xb8\ +\x16\xc3\x13\x96\xfb\x67\xcc\x0f\xbc\x71\x79\x42\xba\xcf\x1e\x63\ +\xf1\x8f\xf6\xfb\xe9\xdd\x00\x84\x5f\xae\x86\x67\xff\xf5\x61\x4f\ +\x4e\xd5\xf4\x3e\x49\x70\xe1\x8d\xcb\x53\xa5\xfb\x11\x8a\x6b\x31\ +\xbc\x60\x89\x56\xe6\x07\xde\xb8\xbc\x24\xb9\x66\x48\xc5\xbf\x1c\ +\xee\xf6\x3b\xd9\x73\xe9\xff\xf0\xcb\x95\xf0\xec\xbf\x16\xdb\x5b\ +\x78\x68\x93\x53\xb5\xbc\x1b\x09\x2e\xbc\xf1\x5d\x96\xf3\x7e\x37\ +\x67\xdb\xf7\xa0\xb8\xe6\xdb\x6b\x36\xbb\xf7\xf7\x8f\xf7\x01\xe6\ +\x07\xde\xd8\x3c\xe9\x5c\x37\x86\xf9\x51\x09\x3f\x87\x1a\x80\x7e\ +\x9d\xc2\xfa\x58\x03\x50\x1b\xe6\xe4\x14\xf3\xce\x89\x04\x17\xde\ +\xb8\xbd\x86\xe9\x2d\x50\x5c\xf3\xed\x09\xd3\x7b\x26\xf3\x03\x6f\ +\xdc\x5e\xb3\xd9\x3e\x6e\x84\xf3\xa3\x1a\xd6\xf3\xa8\x01\x28\xf5\ +\xbb\x47\x50\x89\x35\x00\xd3\xc3\x9e\x9c\xfe\xd9\xff\x19\x04\x17\ +\xde\xd8\xb7\xf0\x94\xee\x87\x28\xae\xf9\xf6\xfc\xb3\xaf\x2f\x32\ +\x3f\xf0\xc6\xed\x09\xc3\xfd\xc3\x11\xcd\x8f\xa8\x86\x47\x0d\xc0\ +\x64\xaf\x4b\xff\xa5\xb0\x43\x88\x1a\x80\xea\x28\x26\xa7\x3f\x20\ +\x2a\xc1\x85\x37\x6e\x4f\x95\xce\x6d\xb3\x66\xe7\x78\x8a\x6b\x3e\ +\xbd\xe0\xe9\x6b\xe6\x07\x5e\x3a\xbc\xee\xf6\x11\xcc\x8f\xe8\xea\ +\x7d\xd4\x00\x94\x7b\x15\xff\x89\xb0\x3b\x98\x8a\xdd\x2f\x18\xc9\ +\xe4\xd4\xa4\xdb\x22\xb8\xf0\x52\xd1\x99\x5b\xde\x73\x29\xae\xf9\ +\xf4\x84\xe9\xbe\x92\xf9\x81\x97\x0e\xcf\x6d\x8c\x60\x7e\xd4\x63\ +\x0d\x40\xa5\xdf\x43\x7f\xf1\x06\xa0\x9c\x78\x95\xa0\x01\x4c\xce\ +\x86\xd9\xb5\x08\x2e\xbc\x34\x78\xc2\xf4\xae\xf0\x43\x72\x1d\xc5\ +\x35\x5f\x9e\xe7\x79\x93\x9a\x74\xae\x65\x7e\xe0\xa5\xc1\x53\x5b\ +\x9e\x36\x82\xf9\x11\x35\x00\xd5\x9e\xf5\x3c\xfc\xa5\x89\xd8\x3b\ +\x82\xeb\x46\x39\x39\xfd\x01\x99\x25\xb8\xf0\xd2\x33\x39\x9d\x19\ +\x8a\x6b\xbe\x3c\x61\x75\x77\x31\x3f\xf0\xd2\xe2\x35\xa4\xfb\xf4\ +\x11\xcc\x8f\x7a\xa2\x67\xf8\x62\x0d\x40\x69\xd4\xc5\xff\xce\x87\ +\x00\xbb\xa7\x13\x5c\x78\xa9\xf1\xa4\xf7\x59\x8a\x6b\xbe\x3c\xff\ +\xec\xff\xdb\xcc\x0f\xbc\xd4\x78\xd2\x7b\xfc\x08\xe6\x47\x6d\x25\ +\xcb\xfd\x4e\x8c\xa3\xf8\x07\x3f\x73\xa6\x7d\x3f\x82\x0b\x2f\x4d\ +\xde\x9c\xb6\x73\x33\xc5\x35\x1f\x9e\x30\xbd\xad\xcc\x0f\xbc\x34\ +\x79\xdb\x54\xe3\xc1\xa9\x99\x6f\xab\x2d\xfc\x03\x9c\xec\xeb\x54\ +\xcb\xfb\x3d\xc1\x85\x97\x1a\x4f\xb6\x3f\x46\x71\xcd\x87\x77\xf8\ +\xca\x7f\xcc\x0f\xbc\x71\x7a\x8a\x69\xff\x36\xad\xf3\x6d\x6c\x7f\ +\xb8\x2a\x9d\x1f\x10\x5c\x78\x69\xf2\xe6\x8c\x85\xb3\x29\xae\x19\ +\x2f\xfe\xa6\xbb\x83\x78\xc6\x4b\x95\x67\xb4\x2f\xa3\xf8\xdf\xbd\ +\x4b\xff\x04\xc1\x85\x97\x2e\xaf\x73\x09\xc5\x35\xbb\x5e\xb0\xed\ +\xaf\x6a\xb9\xdf\x20\x9e\xf1\x52\xe5\xc9\xce\x47\x29\xfe\x87\x79\ +\x42\xef\xbc\x89\xe0\xc2\x4b\x9b\xa7\xb6\xba\x0a\xc5\x35\x9b\x9e\ +\xd6\xea\x76\x88\x67\xbc\xd4\x79\xd2\x7e\x3d\xc5\xff\x30\x4f\xd1\ +\x97\x9e\x4f\x70\xe1\xa5\xcd\x0b\xd6\x05\xd0\x75\x7d\x8a\xe2\x9a\ +\x2d\x6f\x7e\xfe\xfc\xba\x7f\xfc\x7e\x49\x3c\xe3\xa5\xcd\x53\x8c\ +\xf6\x85\x14\xff\xc3\xbc\x39\x63\x97\x24\xb8\xf0\x52\xe9\x99\xde\ +\x0b\x29\xae\xd9\xf2\xfc\xc6\xed\xaf\x89\x67\xbc\x34\x7a\x0d\xc3\ +\x3d\x87\xe2\x7f\x98\x37\xd7\x98\xff\x03\x82\x0b\x2f\x9d\x9e\x73\ +\xab\xff\xcf\x47\x50\x5c\xb3\xe1\x05\xeb\x8a\xa8\xd2\xb9\x83\x78\ +\xc6\x4b\xa3\x17\xec\x7e\x9b\x86\xe2\x9f\xf8\xed\xbf\x51\x4c\xf6\ +\x2d\x5b\xce\x3e\x36\xfe\x2a\x20\xc1\x85\x97\x2a\x4f\x3a\x97\x06\ +\x0f\x95\x51\xac\xd3\xed\x05\xb7\x6b\x82\x45\x7f\x88\x67\xbc\x54\ +\x16\x7f\xe9\xfd\xf6\xa8\xd8\x52\xe3\x63\x9a\x6f\xd1\xd2\xff\x89\ +\x17\x09\xaa\x8d\x62\xb2\xfb\x0d\xc0\x77\x09\x2e\x3c\x36\x0a\xc2\ +\x5b\xf5\xdb\x44\xa6\xf3\x2a\xe2\x19\x2f\xb5\x9e\xf4\xbe\x96\x82\ +\xe2\x5f\x4a\xd4\x00\xc4\xf6\x13\xae\x8f\x62\xb2\x6b\xa6\xf7\x6e\ +\x82\x0b\x2f\xad\x5e\xb0\x5d\xb0\xda\x72\x1e\x4f\xb1\x4e\x69\xf1\ +\x97\x9d\xb3\xfd\xe3\x79\x80\x78\xc6\x4b\xab\xe7\x9f\xe4\xfe\xe3\ +\x98\x8b\x7f\xb4\xdf\x4f\xef\x06\x20\xfc\x72\x35\x3c\xfb\xaf\x8f\ +\x62\xb2\x6b\x96\xfb\xa7\x04\x17\x5e\xaa\x37\x0a\x92\xce\x0f\x82\ +\x27\xcc\x29\xd6\xe9\xf2\x66\x8c\xa5\x13\xfc\xe3\x79\x0d\xf1\x8c\ +\x97\x66\x6f\xb9\xab\x88\x23\x2c\xfe\xe5\x70\xb7\xdf\xc9\x9e\x4b\ +\xff\x87\x5f\xae\x84\x67\xff\xb5\xd8\xde\xc2\x43\x9d\xec\xc1\x16\ +\x89\x04\x17\x5e\xea\x3d\xd3\xfd\xe0\xe6\xcd\x67\x1c\x43\xb1\x4e\ +\x87\x77\xe6\x99\x7b\xa6\x84\xd1\xb9\x94\x78\xc6\x4b\xbf\xd7\xdd\ +\x3e\xa6\xf9\x56\x09\x3f\x87\x1a\x80\x7e\x9d\xc2\xfa\x58\x03\x50\ +\x1b\xc5\x64\xf7\x07\xe7\x14\x82\x0b\x2f\x0b\x9e\x6a\xd8\x2f\xa3\ +\x58\xa7\xc3\x13\xd2\x7e\x1d\xf1\x8c\x97\x05\xaf\xd9\xec\xde\x7f\ +\x0c\xf3\xad\x1a\xd6\xf3\xa8\x01\x28\xf5\xbb\x47\x50\x89\x35\x00\ +\xd3\xa3\x9a\xec\xc1\x53\xd6\xc1\x53\x92\x04\x17\x5e\x06\xbc\x03\ +\x6a\x73\xa9\x4d\xb1\x1e\xaf\xa7\x18\xed\x67\x12\xcf\x78\x99\xf0\ +\xa4\x73\xfd\x18\xe6\x5b\x54\xc3\xa3\x06\x60\xb2\xd7\xa5\xff\x52\ +\xd8\x21\x44\x0d\x40\x75\xd4\x93\xdd\x1f\xa4\x2f\x12\x5c\x78\xd9\ +\xf0\xec\x60\x7d\x80\xa7\x52\xac\xc7\xe3\xcd\x35\x17\x1b\x8a\xe9\ +\xdc\x4e\x3c\xe3\x65\xc1\x13\x96\xf3\xa9\x11\xcf\xb7\xe8\xea\x7d\ +\xd4\x00\x94\x7b\x15\xff\x89\xb0\x3b\x98\x8a\xdd\x2f\x18\xf9\x64\ +\xd7\x2c\xf7\x75\x04\x17\x5e\x66\x3c\xe9\xfc\x5a\x18\xdd\x8d\x14\ +\xeb\xd1\x7a\x6a\x63\xd7\x39\xaa\xe1\xdc\x4c\x3c\xe3\x65\xc8\x7b\ +\xd5\x88\xe7\x5b\x3d\xd6\x00\x54\xfa\x3d\xf4\x17\x6f\x00\xca\x89\ +\x57\x09\x1a\xf0\x5f\x46\x58\x5e\x9b\xe0\xc2\xcb\x94\x27\x9d\x6b\ +\xfb\xad\x14\x48\xf1\x1f\xe0\x99\xbf\xb6\xf3\xa9\xfe\x99\xff\x6f\ +\x88\x3f\xbc\x2c\x79\x0d\xb3\x6b\x8d\x78\xbe\x45\x0d\x40\xb5\x67\ +\x3d\x0f\x7f\x69\x22\xf6\x8e\xe0\xba\x71\x4d\xf6\x86\xd9\x79\x0c\ +\xc1\x85\x97\x41\xef\xe7\x2c\x17\x3c\x8a\x33\xff\xc5\x33\x84\x61\ +\x5f\x4f\xfc\xe1\x65\xcd\x6b\x2e\x74\x4e\x1e\xf1\x7c\xab\x27\x7a\ +\x86\x2f\xd6\x00\x94\xc6\x59\xfc\x83\x9f\x4d\x9b\xf6\x95\x34\xcb\ +\xb9\x99\xe0\xc2\xcb\x9a\xa7\x5a\xde\xaf\x8e\x74\x3b\x80\xe2\x3f\ +\x98\xcb\xfe\x9c\xf9\xe3\x65\xd2\x93\xce\xaf\xc7\x30\xdf\x6a\x2b\ +\x59\xee\x77\x62\xdc\xc5\x3f\xf6\x20\xe0\xe7\x09\x2e\xbc\x4c\x7a\ +\xfe\x44\x6f\x48\xe7\xa9\x14\xff\xc1\x3f\xf0\xc7\x3d\x7f\xbc\xec\ +\x7a\xee\x27\x52\x3b\xdf\x56\x5b\xf8\x87\xf8\x5e\xef\xdf\x10\x5c\ +\x78\xd9\xf5\x9c\x5b\xa3\xfb\x7d\x14\xff\xc1\xbc\xea\xc7\xd3\xfe\ +\x78\x59\xf6\x84\xe5\xbe\x34\x0b\xf3\x2d\x15\xc9\x63\xce\x58\x5a\ +\x20\xb8\xf0\x32\xee\x1d\x10\x96\xf3\x62\x56\x0c\x5c\xe3\x0a\x7f\ +\xd2\x7e\x3d\xf1\x87\x97\x7d\xaf\xbb\x9d\xe2\x9f\xd0\x9b\xd1\x8c\ +\x87\x13\x5c\x78\x79\xf0\x14\xdd\xfe\xf8\x56\x45\x7f\x20\xc5\x7f\ +\x65\x3f\x07\xd7\xf6\x67\x79\x5f\xbc\x9c\x9c\x0c\x6c\x37\x9d\x7b\ +\x51\xfc\x57\xe0\xa9\xd2\xf9\x31\xc1\x85\x97\x07\x4f\x31\xec\xab\ +\xd4\xe6\xce\xa7\x51\xfc\x93\xfd\x84\xbb\xfa\xb1\xb1\x0f\x5e\x2e\ +\xbc\x60\x9b\x7b\x8a\xff\x0a\x3d\xd5\x72\xdf\x4e\x70\xe1\xe5\xc7\ +\x73\xf6\x07\xbb\x5d\xea\xba\x3e\x41\xf1\x5f\xfe\xc7\xf3\xbc\x49\ +\x7f\xac\x5e\xe5\x37\x4c\x77\x10\x2f\x78\xb9\xf1\xa4\xfd\x0f\x14\ +\xff\x15\x7a\xc2\x72\x1d\x82\x0b\x2f\x7f\x8b\x06\xb9\x5f\x51\x5a\ +\xee\xa3\x29\xfe\x77\xfd\x51\xad\xee\xe9\x9a\x74\xbe\x4d\xbc\xe0\ +\xe5\xce\xd3\xdb\x1d\x8a\xff\x0a\xbd\xa4\x3b\x03\x12\xac\x78\x59\ +\xf3\x54\xe9\xdc\x26\x4c\xef\x65\xcd\xe6\x05\xeb\x8b\x5e\xfc\xe7\ +\x6c\xfb\x1e\x9a\xe5\xfe\x95\x3f\x26\x77\x10\x2f\x78\x79\xf4\xb6\ +\xab\xfa\x23\xd2\x58\xfc\x13\xbf\xfd\x37\xae\xe4\xa1\x5a\xce\xcf\ +\x08\x2e\xbc\xbc\x7a\x7e\x7c\x5f\x2d\x2c\xd7\x2c\x62\xf1\x0f\x76\ +\xfe\xd4\x5a\xdd\x8e\x3f\x0e\xbf\x24\x5e\xf0\xf2\xea\x29\x46\xfb\ +\xca\x14\xce\xdf\x68\xe9\xff\xc4\x8b\x04\xd5\xc6\x91\x3c\x44\xc2\ +\xe7\x00\x08\x56\xbc\x4c\x7b\xd2\xf9\xa2\xff\x3b\x4f\x2b\x4a\xf1\ +\x17\xa6\xbb\x43\xb5\xdc\x6f\x10\x2f\x78\xb9\xf7\x74\xfb\x2d\x29\ +\x2c\xfe\xa5\x44\x0d\x40\x6c\x3f\xe1\xfa\x38\x92\xc7\x72\x1b\x03\ +\x11\x5c\x78\x79\xf5\xfc\x86\xf7\xb3\x6a\x63\x69\x7b\x5e\x8b\xbf\ +\x30\xbd\xad\x9a\xe9\x7d\x89\x78\xc1\x2b\x8a\xa7\xc8\xa5\x5d\x29\ +\x2b\xfe\xd1\x7e\x3f\xbd\x1b\x80\xf0\xcb\xd5\xf0\xec\xbf\x3e\x8e\ +\xe4\xa1\xc8\x3d\x0f\x20\xb8\xf0\x0a\xe7\xc9\xce\xd7\xd5\xe6\x52\ +\x7b\xcb\x96\xb3\x8f\xcd\x7a\xf1\x3f\xf8\x64\xbf\xd5\xdd\x15\x3c\ +\xe0\xc7\xf1\xc5\x2b\x54\xf1\x37\xec\x3b\x94\x56\xf7\xb8\x14\x15\ +\xff\x72\xb8\xdb\xef\x64\xcf\xa5\xff\xc3\x2f\x57\xc2\xb3\xff\x5a\ +\x6c\x6f\xe1\x91\x27\x23\x55\x3a\xff\x4d\x70\xe1\x15\xd4\xfb\x79\ +\xf0\xb0\xa0\x22\xbb\x0f\xca\x5a\xf1\xf7\xe7\xed\xc3\xfc\x7f\xff\ +\x57\x05\x1b\x24\x71\x7c\xf1\x0a\xe9\x49\xef\x6b\x29\x6a\xde\x2b\ +\xe1\xe7\x50\x03\xd0\xaf\x53\x58\x1f\x6b\x00\x6a\xe3\x3a\x13\xd1\ +\x2c\xe7\x6f\x08\x2e\xbc\x82\x7b\x07\x54\xd3\xb9\xc4\x6f\x06\xce\ +\x9d\x35\x3b\xc7\xa7\xb5\xf8\x37\x9b\xdd\xfb\x0b\xd3\xbd\xe0\xf0\ +\xcb\xfc\x1c\x5f\xbc\x22\x7a\xc2\xf2\x5e\x9e\x92\xe2\x5f\x0d\xeb\ +\x79\xd4\x00\x94\xfa\xdd\x23\xa8\xc4\x1a\x80\xe9\xf1\x3e\x30\xe4\ +\x6d\x25\xb8\xf0\xf0\x0e\xad\x2a\x76\xbb\x9f\x58\xbe\xe0\x17\xd9\ +\x17\xaa\x2d\xe7\xf1\xfe\x14\x59\x37\xae\xe2\x1f\x3c\xc9\x2f\xe6\ +\x9d\x27\xfa\x73\xf4\xc5\xc1\xfa\x06\x41\xa3\xc2\xf1\xc5\xc3\x8b\ +\xe6\xaa\xbb\x29\x05\xc5\x3f\xaa\xe1\x51\x03\x30\xd9\xeb\xd2\x7f\ +\x29\xec\x10\xa2\x06\xa0\x3a\xee\x7b\x90\x8b\x8b\x8b\x15\xd5\x72\ +\x6e\x21\xb8\xf0\xf0\x96\xdf\x7e\x58\x95\xee\x47\x34\xd3\x79\xbe\ +\xda\x5c\x9c\x9d\x9d\x6d\x3c\x74\x58\xc5\x7f\xa6\x21\x4f\x69\x18\ +\xce\x56\x61\xb9\x2f\x12\x96\xf3\x71\x21\x9d\xdf\x70\x3c\xf0\xf0\ +\x96\x2b\xfe\xde\x8d\x9b\x36\xed\x2b\x8d\xb9\xf8\x47\x57\xef\xa3\ +\x06\xa0\xdc\xab\xf8\x4f\x84\xdd\xc1\x54\xec\x7e\x41\x2a\x1e\x40\ +\xd2\x2c\xe7\x23\x04\x17\x1e\x5e\x62\xef\x5a\x45\xb6\x2f\xf1\x9b\ +\x82\xb7\xde\x59\xac\xbb\xbb\xfc\x26\x61\xdb\xc1\xd5\xf6\x5a\x7b\ +\x1e\x22\xe6\xdd\x13\x9a\xcd\xce\x86\x85\x85\x85\x69\x5d\xdf\x5b\ +\x0b\xfe\x73\xf0\xbf\xf9\xdf\x79\x68\xc3\x74\x9f\xe0\x17\xf6\x59\ +\x55\x2e\xee\x51\x0d\xfb\x15\xaa\xb4\xff\x59\x31\xda\x5f\x10\x86\ +\x7d\x3d\xc7\x03\x0f\x2f\x99\x27\x2c\xef\x5d\x29\x78\x66\xa7\x1e\ +\x6b\x00\x2a\xfd\x1e\xfa\x8b\x37\x00\xe5\xc4\xab\x04\x8d\xe0\x2f\ +\x13\xec\x07\x4e\x70\xe1\xe1\xe1\xe1\xe1\x65\xc2\x93\xee\xce\x14\ +\x3c\xb0\x1b\x35\x00\xd5\x9e\xf5\x3c\xfc\xa5\x89\xd8\x3b\x82\xa9\ +\x29\xfe\xc1\xef\xcf\xcd\x99\x8f\x24\xb8\xf0\xf0\xf0\xf0\xf0\xd2\ +\xee\x05\xcf\xe9\xa8\x3b\xcf\xbd\x57\x0a\xde\xd6\xa9\x27\x7a\x86\ +\x2f\xd6\x00\x94\xd2\x56\xfc\x23\x4b\x91\xed\x6f\x10\x5c\x78\x78\ +\x78\x78\x78\x69\xf6\x84\xe5\x7d\x2e\x25\xaf\xea\xd6\x56\xb2\xdc\ +\xef\x44\x5a\x8b\x7f\xf0\x11\x86\xfd\x52\x82\x0b\x0f\x0f\x0f\x0f\ +\x2f\xe5\xde\x85\x99\x5a\x9e\x7b\xb5\x85\x7f\x94\x7f\x19\x4d\xda\ +\x8f\x26\xb8\xf0\xf0\xf0\xf0\xf0\xd2\xec\x35\x17\x9c\x07\x67\x75\ +\x97\xcf\x54\x2f\x37\x2a\x4c\xf7\x7b\x04\x2b\x1e\x1e\x1e\x1e\x5e\ +\x3a\xd7\xe9\x70\xbf\x41\xf1\x1f\x92\x17\x2c\x8b\x4a\xb0\xe2\xe1\ +\xe1\xe1\xe1\xa5\xd2\x33\xdd\xe7\x51\xfc\x87\xe4\x35\xcc\xce\x63\ +\x08\x56\x3c\x3c\x3c\x3c\xbc\x34\x7a\xcd\x85\xce\xc9\x14\xff\x61\ +\x6e\x11\x6c\x3a\x97\x11\xac\x78\x78\x78\x78\x78\xa9\xf2\x96\xd9\ +\xfc\x87\xe2\x3f\x60\x4f\x48\xf7\xd9\x04\x2b\x1e\x1e\x1e\x1e\x5e\ +\x9a\x3c\x61\xb9\x7b\x29\xfe\x43\xf6\x76\xb4\xf6\x1c\x2b\xa4\xf7\ +\x5b\x82\x15\x0f\x0f\x0f\x0f\x2f\x15\x9e\x74\x7e\x1d\x2c\xab\x9d\ +\xa5\xe2\x9f\xf8\xed\xbf\xb4\xfd\x65\x84\xe5\x5d\x44\xb0\xe2\xe1\ +\xe1\xe1\xe1\xa5\xc3\x73\xff\x34\x2b\xc5\x3f\xb6\xf4\x7f\xe2\x45\ +\x82\x6a\x69\xfa\xcb\x04\x57\x01\xfc\x8e\xeb\x7a\x82\x15\x0f\x0f\ +\x0f\x0f\x6f\xcc\xde\xcf\x83\x8d\xb5\x32\x54\xfc\x4b\x89\x1a\x80\ +\xd8\x7e\xc2\xf5\xb4\xfd\x65\x84\xe5\xb5\x09\x56\x3c\x3c\x3c\x3c\ +\xbc\x71\x7a\xc2\xec\x36\x33\x54\xfc\xa3\xfd\x7e\x7a\x37\x00\xe1\ +\x97\xab\xe1\xd9\x7f\x3d\x85\x7f\x99\xa3\x55\xc3\xfe\x28\xc1\x8a\ +\x87\x87\x87\x87\x37\x96\xe2\x6f\xb9\xff\x9c\xa1\xe2\x5f\x0e\x77\ +\xfb\x9d\xec\xb9\xf4\x7f\xf8\xe5\x4a\x78\xf6\x5f\x8b\xed\x2d\x9c\ +\x9a\xe2\x1f\xfc\xfe\x56\x45\x7f\xa0\x62\xd8\x57\x11\xac\x78\x78\ +\x78\x78\x78\xa3\x3d\xf3\x77\x2e\x0b\x1e\xfc\xcb\x40\xf1\x3f\x3a\ +\xac\xe7\x95\x78\x03\xd0\xaf\x53\x58\x1f\x6b\x00\x6a\x69\x2b\xfe\ +\x91\x35\xab\x59\xa7\x2b\xa6\xf3\x6b\x82\x15\x0f\x0f\x0f\x0f\x6f\ +\x24\x9e\x74\xae\x09\xd6\xfc\xcf\x48\xf1\xaf\x86\xf5\x3c\x6a\x00\ +\x4a\xfd\xee\x11\x54\x62\x0d\xc0\x74\x5a\x8b\xff\xff\x6d\x14\xe4\ +\x9c\xae\x49\xef\x86\xa2\x07\x6b\xb0\x0f\xb5\x66\x39\x57\x09\xcb\ +\xf9\x94\xb0\xdc\xff\x60\xb2\xe3\xe1\xe1\xad\xd5\x0b\xf2\x89\x2a\ +\xbd\x8f\x09\xd3\xbb\xc2\xcf\x2f\xfb\x29\xfe\xce\xb5\x0d\xd3\x39\ +\x35\x23\xc5\x3f\xaa\xe1\x51\x03\x30\xd9\xeb\xd2\x7f\x29\xec\x10\ +\xa2\x06\xa0\x9a\xf6\xe2\x1f\x79\x4a\xcb\x7d\xb4\xdf\x04\xfc\x34\ +\xef\x93\xd3\x9f\x88\xbf\xf3\xff\xbf\xcb\x85\x74\x3f\xa4\x59\xee\ +\x5f\xf9\x9f\xf3\x54\xe9\x6e\x53\xa5\xf3\x30\xcf\xf3\x26\xa3\xf1\ +\x6a\x36\x2f\x58\xef\x7f\xf7\xc7\x24\x37\x3c\x3c\xbc\xd5\x7b\xce\ +\x95\x8b\x8b\x8b\x95\x28\xaf\x6c\xda\xb4\xaf\xa4\xb5\xf6\x3c\x44\ +\x98\xdd\x73\x54\xd3\xdb\xad\x5a\xce\xc5\x42\x3a\x1f\xf0\x8b\xe2\ +\xb7\x85\x69\xdf\x92\xff\xf1\x73\xae\xd4\xac\xee\x29\x19\x29\xfe\ +\xd1\xd5\xfb\xa8\x01\x28\xf7\x2a\xfe\x13\x61\x77\x30\x15\xbb\x5f\ +\x90\x89\xe2\x1f\xfd\xe8\xfa\xde\xfb\xfa\x4d\xc0\x67\x33\x3f\x39\ +\xa5\x77\x83\x30\x3a\xdf\x54\x65\xe7\xfd\xaa\xb4\xff\x52\x95\xed\ +\xf3\xe6\xf4\x5d\xdb\x54\xab\x7d\x92\xff\xd7\x4c\xbc\x75\xb3\x30\ +\xdd\x39\x92\x1b\x1e\x1e\xde\x6a\x3d\xff\xac\x7f\xeb\x4a\xf2\xf3\ +\x8c\x66\x3c\x7c\x56\xdf\xb5\x55\xe8\x4b\xbb\x35\xb3\xf3\xd2\xe0\ +\x21\x39\x4d\xba\x5f\x89\xbf\xb6\x9d\xe1\xe2\xff\xef\xcd\x66\x67\ +\x43\x46\x8a\x7f\xf4\xdc\x5e\xd4\x00\x54\xfa\x3d\xf4\x17\x6f\x00\ +\xca\x89\x57\x09\x4a\xd9\xa2\x41\xba\xae\x4f\x68\xa6\xfb\x27\x7e\ +\x67\x7a\x4b\xaa\x83\x4b\x3a\xd7\xf8\x9f\x4b\x85\xe5\xbd\xcd\x9f\ +\x24\x2f\x6a\x98\x5d\x4b\xb5\xba\xa7\x2b\xad\xee\x71\x83\x1c\x3f\ +\xff\xcf\xfa\x10\xc9\x0d\x0f\x0f\x6f\xc5\xc5\xdf\xf2\xde\x35\xc8\ +\xfc\xac\xeb\xde\x31\x6a\xcb\x79\x7c\xc3\x74\x8c\x60\xd7\x3c\xff\ +\x04\xe5\xcd\x07\x4f\xd8\xee\xbc\x72\x7b\x20\xad\xe3\xe7\xd7\x92\ +\x9b\x82\x2b\xad\xc1\xc9\x57\x86\x8a\xff\x31\xb1\x06\xa0\xda\xb3\ +\x9e\x87\xbf\x34\x11\x7b\x47\x30\x93\xc5\x3f\xfe\xa3\xc8\xee\x83\ +\x54\xcb\xfd\x97\x78\x60\x8d\x36\xb8\x9c\xfd\xaa\x74\x7f\xe8\x07\ +\xce\x27\xfc\xff\xed\x6f\xfd\x80\x7f\x96\xff\xbf\xab\xc1\xad\x8a\ +\x99\x19\xaf\x3a\xaa\xf1\xdb\x21\xe6\x1f\x29\xa4\x73\x13\xc9\x0d\ +\x0f\x0f\x2f\xb1\x27\xbd\x1b\x82\x2b\xaa\xa3\xca\xf7\xc1\x6d\x06\ +\xc5\x68\x9f\xaa\x1a\x4b\x52\xd1\xdb\xcf\x53\x0d\xfb\x0d\x42\x76\ +\x3e\xa1\x18\xf6\x95\xaa\x74\x6e\x1b\xc7\xf8\x05\xcf\x54\x09\xd3\ +\x7b\xeb\x9c\x69\xdf\x2f\x23\xaf\xfa\x1d\xbd\xcc\x9a\x3d\xd3\x49\ +\x17\xfc\x99\x08\x9f\x01\xc8\x7c\xf1\xbf\xeb\x16\xc2\xce\xa9\x41\ +\xa7\x19\xec\x1f\x30\xf8\xc9\x64\xdf\x22\xa4\x7d\xb9\x30\xec\x8f\ +\xa8\x46\xfb\x75\x7e\x00\x5f\xd8\x30\x9c\xad\x7e\xe1\x7f\x68\x70\ +\xaf\x2c\x2d\xe3\xe7\x4f\xaa\xe7\x90\xdc\xf0\xf0\xf0\x12\x3f\x50\ +\x6c\x3a\x6e\x5a\xf2\x7d\x70\x55\x37\x38\xa1\x6b\x48\xef\x2c\x61\ +\xb9\x5d\x3f\x9f\xbf\xd2\x3f\xa1\x7a\x9f\x7f\x92\xf5\xad\x3b\xcf\ +\xce\x07\xbe\xab\xdf\x0d\xfe\x89\xdb\x6b\x82\x3c\x9e\xa1\xe5\x7d\ +\x97\xf3\x6a\x2b\x59\xee\x77\x22\x6f\xc5\x3f\xee\xcd\xcc\x34\x4e\ +\x50\x8c\x45\x5b\x18\x9d\x77\x29\xa6\x7d\x4d\xd2\x60\xf0\xbb\xc0\ +\xff\xf1\xff\xf9\x55\xcd\xf4\xde\xe9\x77\x83\x2f\xd3\x5a\xce\x92\ +\x66\x74\x36\x6d\x17\xc6\xc3\x36\x6f\x3e\xe3\x9e\x59\x08\x86\xe0\ +\xdf\x53\x91\xf6\x97\x48\x6e\x78\x78\x78\x09\xbc\x4f\x67\x29\xdf\ +\xcf\x9a\x9d\xe3\x1b\xd2\x7d\xb2\x26\xdd\x9d\x7e\x8e\x7e\xb1\x9f\ +\xab\xff\x49\xc8\xce\x57\x15\xd3\xb9\x2e\xe9\xf8\x05\x57\x6b\x85\ +\xe5\xfd\x83\xff\x3d\x11\x7f\xe8\x31\xc3\xc5\x3f\xb9\xb7\xda\xc2\ +\x9f\xe5\xc1\x69\x36\xbb\xf7\x6b\xc8\xee\x66\x61\x75\x77\xf9\x41\ +\xf3\xcc\xe0\x9e\x54\xf0\xec\x80\xdf\xf9\xed\xf1\x3f\x8d\x86\xe9\ +\xfd\x3f\x65\x71\xf1\x9e\x79\xf9\xfb\x2a\x86\xfd\x88\x5e\xcf\x45\ +\x90\x2c\xf1\xf0\xf0\x82\x2b\xa5\xc1\xfb\xed\x79\xc9\xf7\x8a\xa2\ +\x9f\xa8\x36\x16\xcf\xf0\x73\xbb\xd0\x5a\x9e\xe7\xff\x1d\x2f\xf4\ +\x3f\xcf\x09\xee\xe9\x07\xcf\x5d\x69\xad\xee\x53\x82\x07\xfb\xf2\ +\x56\xdf\x0a\xb5\x45\x30\x5e\x32\x2f\x0c\x7e\x92\x25\x1e\x1e\xde\ +\x91\x76\xb5\xdb\x43\x3e\xa5\xf8\x33\x38\x39\xf4\xf6\xed\xdb\x77\ +\xb4\x6a\x3a\x97\x90\x2c\xf1\xf0\xf0\x96\x29\xfe\x9f\x38\xd2\x6b\ +\xc6\xe4\x53\x8a\x3f\x83\x9d\x03\x2f\x78\x98\x46\x48\xe7\x37\x24\ +\x4b\x3c\x3c\xbc\xd8\x6b\xc9\xbf\x6e\x36\xbb\xf7\x27\x9f\x52\xfc\ +\x19\x9c\x9c\x7b\x0d\xd3\x5d\x24\x59\xe2\xe1\xe1\x1d\xbe\xa5\x2d\ +\xf9\x94\xe2\xcf\xe0\x14\xc0\x0b\xd7\x48\x20\x59\xe2\xe1\x15\xdd\ +\x33\xdd\xb7\x90\x4f\x29\xfe\x0c\x4e\x81\xbc\x60\x55\x2e\x61\x7a\ +\x3f\x22\x59\xe2\xe1\x15\xf9\xcc\xdf\xfd\xde\xc2\xc2\xc2\x34\xf9\ +\xb4\x78\xc5\x3f\xf1\xdb\x7f\x0c\x76\x3e\xbd\x60\xe9\xe1\x68\x95\ +\x2d\x92\x25\x1e\x5e\xb1\xbc\x60\x63\x31\xa5\xe5\x3c\x96\x7c\x5a\ +\x38\x2f\x5a\xfa\x3f\xf1\x22\x41\x35\x06\x3b\x9f\x9e\x9f\x28\x2e\ +\x24\x59\xe2\xe1\x15\xcf\x0b\x56\xd5\x23\x9f\x16\xb2\xf8\x97\x12\ +\x35\x00\xb1\xfd\x84\xeb\x0c\x76\x7e\x3d\x55\xef\x7c\x90\x64\x89\ +\x87\x57\x20\xcf\xf4\xde\x41\xfe\x2b\x64\xf1\x8f\xf6\xfb\xe9\xdd\ +\x00\x84\x5f\xae\x86\x67\xff\x75\x06\x3b\xbf\x5e\xb0\x5a\x96\x30\ +\x3b\x57\x90\x2c\xf1\xf0\x8a\xe0\xb9\xdf\x39\x7c\x43\x32\xf2\x69\ +\x21\x8a\x7f\x39\xdc\xed\x77\xb2\xe7\xd2\xff\xe1\x97\x2b\xe1\xd9\ +\x7f\x2d\xb6\xb7\x30\x83\x9d\x53\x4f\xd5\x77\xfe\x61\xaf\x8d\x35\ +\x48\xbe\x78\x78\xd9\xf7\x54\xcb\xbb\x51\xb3\xba\xa7\x90\xff\x0a\ +\xe7\x55\xc2\xcf\xa1\x06\xa0\x5f\xa7\xb0\x3e\xd6\x00\xd4\x18\xec\ +\xfc\x7b\x6a\xcb\xd3\x0e\xdf\x3e\x99\xe4\x8b\x87\x97\x93\xe2\x2f\ +\x9d\x3b\xfc\xe2\xbf\x9d\xfc\x57\x38\xaf\x1a\xd6\xf3\xa8\x01\x28\ +\xf5\xbb\x47\x50\x89\x35\x00\xd3\x0c\x76\x71\x3c\xcd\xf4\xf6\x91\ +\x2c\xf1\xf0\xf2\xe7\x09\xcb\x7b\x2e\xf9\xaf\x70\x5e\x54\xc3\xa3\ +\x06\x60\xb2\xd7\xa5\xff\x52\xd8\x21\x44\x0d\x40\x95\xc1\x2e\x9c\ +\xb7\xce\x6f\x02\xde\x4d\xf2\xc5\xc3\xcb\x8f\xa7\x5a\xde\x3f\x92\ +\xff\x0a\xe7\x45\x57\xef\xa3\x06\xa0\xdc\xab\xf8\x4f\x84\xdd\xc1\ +\x54\xec\x7e\x01\x83\x5d\x40\xaf\xd9\xbc\x60\xbd\x9f\x34\xbe\x4a\ +\xf2\xc5\xc3\xcb\xc5\x99\xff\x17\xb6\x6e\x3d\xbf\x4c\xfe\x2b\x9c\ +\x57\x8f\x35\x00\x95\x7e\x0f\xfd\xc5\x1b\x80\x72\xe2\x55\x82\x18\ +\xec\x5c\x7a\xba\xbe\xf7\xbe\xaa\xe5\x5c\x4d\xf2\xc5\xc3\xcb\xb2\ +\xe7\x5c\xd9\x6c\xb6\x8f\x23\xff\x15\xd2\x8b\x1a\x80\x6a\xcf\x7a\ +\x1e\xfe\xd2\x44\xec\x1d\x41\x8a\x3f\xde\x51\x0d\xd3\x39\x55\x93\ +\xde\x0d\x24\x5f\x3c\xbc\x0c\x7a\xd2\xb9\x3e\xfe\xc4\x3f\xf9\xaf\ +\x70\x5e\x3d\xd1\x33\x7c\xb1\x06\xa0\x44\xf1\xc7\x8b\xff\xa8\x96\ +\xbb\xc9\x3f\x8b\xb8\x95\xe4\x8b\x87\x97\xa5\x7b\xfe\xce\x2d\xaa\ +\xe5\x3d\x89\xfc\x57\x68\x2f\xd9\xdb\x7b\xb1\x06\x80\xe2\x8f\x77\ +\xb7\x1f\x21\x3d\x5d\x31\xec\x3b\x48\xbe\x78\x78\x99\x78\xe0\xef\ +\x76\x61\xba\x73\xe4\x3f\xbc\xa4\xc0\xaa\x0a\x3f\x83\x5d\x1c\x4f\ +\x31\x96\x9e\x49\xf2\xc5\xc3\x4b\xbd\x77\xa0\x61\xba\x36\xf9\x0f\ +\xef\xa8\x61\xff\x30\xd8\xc5\xf2\x54\xa3\xfd\x67\x24\x5f\x3c\xbc\ +\x54\x7b\x17\x92\xaf\xf0\x28\xfe\x78\x43\xf1\x34\xd3\x79\x39\xc9\ +\x17\x0f\x2f\x85\x9e\xe9\xed\x23\x5f\xe1\x51\xfc\xf1\x86\xea\xf9\ +\xc9\xe6\xd5\x24\x5f\x3c\xbc\xf4\x78\xc2\xf2\x2e\x22\x5f\xe1\x51\ +\xfc\xf1\x46\xe2\x69\x96\xfb\x1a\x92\x2f\x1e\x5e\x2a\xbc\x57\x93\ +\xaf\xf0\x28\xfe\x78\x23\xf5\x34\xcb\xf9\x1b\x92\x2f\x1e\xde\x18\ +\xcf\xfc\x4d\xf7\x2f\xc9\x57\x78\x14\x7f\xbc\xb1\x78\xaa\xe5\x5c\ +\x4c\x32\xc7\xc3\xe3\xb2\x3f\x5e\xb6\x8a\x7f\xe2\xb7\xff\x18\x6c\ +\xbc\x5e\x3f\x7e\xe2\x7a\x05\xc9\x1c\x0f\x6f\xa4\xc5\xff\xe5\xe4\ +\x2b\xbc\xd5\x16\xfe\x70\xdd\x9f\xc4\x8b\x04\xd5\x18\x6c\xbc\x23\ +\xfd\x04\xef\x1d\x93\xcc\xf1\xf0\x46\xe7\xf9\x0d\x40\x9b\x7c\x85\ +\xb7\xca\xe2\x5f\x4a\xd4\x00\xc4\xf6\x13\xae\x33\xd8\x78\x47\xfa\ +\xd1\xa4\x73\x29\xc9\x1c\x0f\x6f\x74\x9e\xdf\x00\x7c\x8e\x7c\x85\ +\xb7\x8a\xe2\x1f\xed\xf7\xd3\xbb\x01\x08\xbf\x5c\x0d\xcf\xfe\xeb\ +\x0c\x36\xde\xf2\x0f\x02\x76\x4f\x21\x99\xe3\xe1\x8d\xde\x9b\x11\ +\xad\x8d\xe4\x2b\xbc\x15\x14\xff\x72\xb8\xdb\xef\x64\xcf\xa5\xff\ +\xc3\x2f\x57\xc2\xb3\xff\x5a\x6c\x6f\x61\x06\x1b\xef\xae\x0d\x80\ +\xe9\xfe\x39\xc9\x1c\x0f\x6f\xf4\x9e\x2a\xdb\xaf\x24\x5f\xe1\x25\ +\xf4\x2a\xe1\xe7\x50\x03\xd0\xaf\x53\x58\x1f\x6b\x00\x6a\x0c\x36\ +\xde\xe1\x3f\xfb\xf6\xed\x3b\x5a\x93\xde\x4f\x49\xe6\x78\x78\xe3\ +\xf0\x3a\x3f\xdb\xbe\x7d\xcb\xb1\xe4\x2b\xbc\x3e\x5e\x35\xac\xe7\ +\x51\x03\x50\xea\x77\x8f\xa0\x12\x6b\x00\xa6\x19\x6c\xbc\x65\x1f\ +\xfe\x33\x9c\xad\x24\x73\x3c\xbc\xf1\x79\x8a\xbe\xa4\x90\xaf\xf0\ +\xfa\x3c\xc3\x37\x1d\x6b\x00\x26\x7b\x5d\xfa\x2f\x85\x1d\x42\xd4\ +\x00\x54\x19\x6c\xbc\x23\x79\xc2\xe8\xbc\x97\x64\x8e\x87\x37\x3e\ +\x4f\x58\xee\x3b\xc9\x57\x78\x47\xf0\xa2\xab\xf7\x51\x03\x50\xee\ +\x55\xfc\x27\xc2\xee\x60\x2a\x76\xbf\x80\xc1\xc6\x5b\xd6\xdb\xae\ +\xa9\x0f\x50\x0c\xe7\x77\x24\x73\x3c\xbc\xf1\x79\xaa\xf4\x7e\xa7\ +\xeb\xde\x31\xe4\x2b\xbc\x65\xbc\x7a\xac\x01\xa8\xf4\x7b\xe8\x2f\ +\xde\x00\x94\x13\xaf\x12\xc4\x60\x17\xd2\x53\x8d\xa5\x0b\x49\xe6\ +\x78\x78\xe3\xf7\x84\xe5\x76\xc9\x57\x78\xcb\x78\x51\x03\x50\xed\ +\x59\xcf\xc3\x5f\x9a\x88\xbd\x23\x48\xf1\xc7\xeb\xe9\x09\xc3\xfe\ +\x1a\xc9\x17\x0f\x6f\xfc\x9e\xb0\x9c\x2f\x93\xaf\xf0\x96\xf1\xea\ +\x89\x9e\xe1\x8b\x35\x00\x25\x8a\x3f\x5e\x3f\x4f\xd5\x17\x9e\x40\ +\xf2\xc5\xc3\x4b\x8f\xa7\xca\xce\x23\xc9\x57\x78\x87\x79\xc9\xde\ +\xde\x8b\x35\x00\x14\x7f\xbc\xbe\x9e\x90\xf6\x6b\x48\xbe\x78\x78\ +\xe9\xf1\x84\xe9\xbe\x92\x7c\x85\xb7\x2a\x6f\xb5\x85\x9f\xc1\x2e\ +\x9e\x77\xd6\x59\x33\xf7\xf2\x93\xd1\xb5\x24\x5f\x3c\xbc\xf4\x78\ +\xaa\xe5\xfc\x42\xd7\xf5\x09\xf2\x15\x1e\x5b\x04\xe3\x0d\xcd\x53\ +\x8d\x25\x49\xf2\xc5\xc3\x4b\x9f\x27\x4c\x77\x07\xf9\x0a\x8f\xe2\ +\x8f\x37\x34\x4f\x33\xdd\xf7\x93\x7c\xf1\xf0\x52\xb8\x45\xb0\xf4\ +\xde\x4b\xbe\xc2\xa3\xf8\xe3\x0d\xc5\xdb\x21\xed\xfb\xa8\xd2\xb9\ +\x8d\xe4\x8b\x87\x97\x3e\x4f\xb5\xbc\xdf\xab\x3b\xcf\xbd\x17\xf9\ +\x0a\x8f\xe2\x8f\x37\x70\x4f\xb3\xdc\x3f\x26\xf9\xe2\xe1\xa5\xd7\ +\xf3\x7f\xf7\x8f\xc9\x57\x78\x14\x7f\xbc\x81\x7b\x9a\xe5\x7c\x8b\ +\xe4\x8b\x87\x97\x62\xcf\x70\xbe\x4d\xbe\xc2\xa3\xf8\xe3\x0d\xd4\ +\x6b\x98\xbb\x1f\x47\xf2\xc5\xc3\x4b\xbf\x37\x27\x76\x3e\x85\xfc\ +\x87\x97\xc0\x5c\xc7\xe0\xe0\x25\xf2\x34\xcb\x7d\x0d\xc9\x17\x0f\ +\x2f\xfd\x9e\x6a\xd8\x7f\x47\xfe\xc3\xeb\x55\xf8\xc3\x75\x7f\x12\ +\x2f\x12\x54\x63\xb0\x8b\xeb\xe9\xba\x3e\xa5\x49\xe7\x7a\x92\x2f\ +\x1e\x5e\x06\x3c\xc3\xbe\x7e\x61\xa1\x55\x26\xff\xe1\x1d\xa1\xf8\ +\x97\x12\x35\x00\xb1\xfd\x84\xeb\x0c\x76\x71\x3d\xff\xec\xbf\x41\ +\xf2\xc5\xc3\xcb\xd0\x2e\x81\x2d\x4f\x23\xff\xe1\x2d\x53\xfc\xa3\ +\xfd\x7e\x7a\x37\x00\xe1\x97\xab\xe1\xd9\x7f\x9d\xc1\x2e\xae\xa7\ +\x59\xce\xbf\x91\x7c\xf1\xf0\xb2\xe3\x09\xe9\x7e\x88\xfc\x87\x77\ +\x58\x3d\x2f\x87\xbb\xfd\x4e\xf6\x5c\xfa\x3f\xfc\x72\x25\x3c\xfb\ +\xaf\xc5\xf6\x16\x66\xb0\x0b\xe6\x89\x79\xf7\x04\xd5\xf2\x6e\x27\ +\xf9\xe2\xe1\x65\xc9\x73\xf6\xcf\x9a\x9d\xe3\xc9\x7f\x78\xa1\x57\ +\x09\x3f\x87\x1a\x80\x7e\x9d\xc2\xfa\x58\x03\x50\x63\xb0\x8b\xe9\ +\x69\xa6\xfb\x27\x24\x5f\x3c\xbc\xec\x79\x42\xba\xcf\x26\xff\xe1\ +\x85\x57\xf2\xd7\xc7\x1a\x80\x52\xbf\x7b\x04\x95\x58\x03\x30\xcd\ +\x60\x17\xd7\xf3\x13\xc9\xe5\x24\x5f\x3c\xbc\xec\x79\xfe\xff\x77\ +\x19\xf9\xaf\xf0\x5e\x54\xc3\xa3\x06\x60\xb2\xd7\xa5\xff\x52\xd8\ +\x21\x44\x0d\x40\x95\xc1\x2e\xae\xd7\x30\xdd\x27\x90\x7c\xf1\xf0\ +\xb2\xbc\x4b\x60\xf7\x74\xf2\x5f\x61\xbd\xe8\xea\x7d\xd4\x00\x94\ +\x7b\x15\xff\x89\xb0\x3b\x98\x8a\xdd\x2f\x60\xb0\x0b\xec\x69\xd2\ +\xfb\x7b\x92\x2f\x1e\x5e\x76\x3d\xff\x7b\x7f\x4b\xfe\x2b\xac\x57\ +\x8f\x35\x00\x95\x7e\x0f\xfd\xc5\x1b\x80\x72\xe2\x55\x82\x18\xec\ +\x5c\x7a\xcd\xe6\x05\xeb\x55\xcb\xbb\x91\xe4\x8b\x87\x97\x61\x4f\ +\x7a\x37\x2c\x2e\x2e\x56\xc8\x7f\x85\xf4\xa2\x06\xa0\xda\xb3\x9e\ +\x87\xbf\x34\x11\x7b\x47\x90\xe2\x5f\x70\x4f\x93\x6e\x8b\xe4\x8b\ +\x87\x97\x7d\x4f\x58\xae\x49\xfe\x2b\xa4\x57\x4f\xf4\x0c\x5f\xac\ +\x01\x28\x51\xfc\xf1\xee\x7c\xf8\xcf\xfd\x04\xc9\x17\x0f\x2f\xfb\ +\x9e\xb0\x9c\x8f\x93\xff\x0a\xe9\x25\x7b\x7b\x2f\xd6\x00\x50\xfc\ +\xf1\x8e\x52\xe4\x9e\x07\xa8\xd2\xb9\x83\xe4\x8b\x87\x97\x7d\x2f\ +\x98\xcb\xb3\x0d\xf3\x11\xe4\x3f\xbc\x23\x3e\x03\x70\xd4\x2a\x7f\ +\x18\xec\xfc\x79\x9a\xe9\xbd\x90\xe4\x8b\x87\x97\x1f\x4f\x91\xf6\ +\x4b\xc8\x7f\x78\x03\xfd\x61\xb0\x73\xe9\xad\xd3\x2c\xe7\x4a\x92\ +\x2f\x1e\x5e\x7e\x3c\xc5\x68\x5f\x49\xfe\xc3\xa3\xf8\xe3\xf5\x3e\ +\xfb\x6f\x79\x7f\x44\xf2\xc5\xc3\xcb\x9f\x37\xa7\x2f\x3e\x9d\xfc\ +\x87\x47\xf1\xc7\xeb\x71\xf9\xdf\x7d\x0b\xc9\x12\x0f\x2f\x7f\x9e\ +\xb0\xdc\xb7\x90\xff\xf0\x28\xfe\x78\xcb\xfe\x2c\x2c\x2c\x4c\xab\ +\x96\x73\x13\xc9\x12\x0f\x2f\x87\x5b\x04\xfb\x73\x3b\x98\xe3\xe4\ +\x3f\x3c\x8a\x3f\xde\x32\x97\xff\x3b\x6d\x92\x25\x1e\x5e\x7e\x3d\ +\x61\x75\x77\x91\xff\xf0\x18\x1c\xbc\xbb\x79\x8a\x6c\x7f\x9e\x64\ +\x89\x87\x97\x5f\x4f\x58\xee\x7f\x90\xff\xf0\x42\x73\x1d\x83\x83\ +\x77\xd0\x9b\x11\xad\x8d\x24\x4b\x3c\xbc\xdc\x7b\x07\x9a\x0b\xce\ +\x83\xc9\x7f\x85\xf6\xa2\xa5\xff\x13\x2f\x12\x54\x63\xb0\xf3\xed\ +\xa9\xb2\xfd\x4a\x92\x25\x1e\x5e\xfe\x3d\x61\x7a\x2f\x26\xff\x15\ +\xba\xf8\x97\x12\x35\x00\xb1\xfd\x84\xeb\x0c\x76\x7e\xbd\xed\xdb\ +\xb7\x1c\xab\x98\xf6\x4f\x49\x96\x78\x78\x45\xf0\x9c\xab\xfc\xe9\ +\xbf\x8e\xfc\x57\xc8\xe2\x1f\xed\xf7\xd3\xbb\x01\x08\xbf\x5c\x0d\ +\xcf\xfe\xeb\x0c\x76\x7e\x3d\xc5\xd8\xa5\x90\x2c\x53\xec\x49\xe7\ +\x3a\xad\xd5\xed\x68\xa6\xf3\x12\xcd\xf4\xde\xe1\xff\xf7\x4b\x55\ +\xcb\xb9\x5a\xb5\xbc\xdb\xc7\xfd\xef\xa7\x4a\xe7\x36\x55\xba\x3f\ +\x54\x4d\xe7\x33\xfe\x99\xe5\x5b\x85\xe5\xbe\xa8\x61\xba\x8b\xfe\ +\xbf\xe3\xf5\x1c\xdf\xf4\x7a\xfe\x77\x9f\x46\xfe\x2b\x5c\xf1\x2f\ +\x87\xbb\xfd\x4e\xf6\x5c\xfa\x3f\xfc\x72\x25\x3c\xfb\xaf\xc5\xf6\ +\x16\x66\xb0\x73\xe8\x29\xb2\xfd\x6e\x92\x65\x7a\x3d\xbf\xb8\xba\ +\xcb\x1d\x47\x5d\xd7\x27\x9a\xcd\xee\xfd\x55\xab\x7b\xba\xda\xea\ +\x2a\x5a\xcb\xf3\x82\x02\xec\x9f\xe1\xbd\xf6\xe0\x31\x95\x9d\x4f\ +\xa8\xb2\xf3\x65\x21\xed\xcb\x85\x69\x5f\xed\x17\xe5\x6b\x85\x74\ +\x7e\xe3\xff\xff\xb7\xc6\x9b\x87\x3b\xff\xf3\xc1\xff\x2d\xd8\xfe\ +\xf9\x97\x7e\x21\xff\x91\xff\x9f\xff\x2b\x68\x34\xfc\xff\xfd\xdf\ +\x54\xcb\x7d\xbb\x6f\xbc\x5e\x95\xed\x97\x2a\xc6\xd2\xf9\xaa\xbe\ +\x68\xce\x69\x3b\x9f\x3a\x63\x2c\x9d\xb0\xdc\x99\x64\xf0\xa3\x9a\ +\xde\x6e\x8e\x6f\x7a\x3d\x3f\x4e\xde\x4e\xfe\x2b\x94\x57\x09\x3f\ +\x87\x1a\x80\x7e\x9d\xc2\xfa\x58\x03\x50\x63\xb0\xf3\xe9\xcd\xcc\ +\x68\x0f\x50\x4c\xfb\x16\x92\x65\x6a\xbd\xaf\xee\xdb\xb7\xef\xe8\ +\xac\xc5\x5f\xf0\xef\xec\x37\x0f\x5f\xe7\xf8\xa6\xd3\x53\x2d\xe7\ +\x96\xf9\xf9\xf3\xeb\xe4\xd3\x42\x78\xd5\xb0\x9e\x47\x0d\x40\xa9\ +\xdf\x3d\x82\x4a\xac\x01\x98\x66\xb0\xf3\xeb\xf9\x67\x75\xcf\x20\ +\x59\xa6\xd6\x3b\x10\x9c\xdd\x67\x35\xfe\xc4\xbc\xf3\xc4\xe0\xef\ +\xc0\xf1\x4d\xa7\x27\x2c\xc7\x25\x9f\xe6\xde\x8b\x6a\x78\xd4\x00\ +\x4c\xf6\xba\xf4\x5f\x0a\x3b\x84\xa8\x01\xa8\x32\xd8\xf9\xf6\x54\ +\xd3\xf9\x1c\xc9\x32\xa5\x8b\xb6\x98\xee\x9b\xb3\x1e\x7f\xc1\x73\ +\x01\x1c\xdf\xb4\x7a\x9d\x4b\xc8\xa7\xb9\xf6\xa2\xab\xf7\x51\x03\ +\x50\xee\x55\xfc\x27\xc2\xee\x60\x2a\x76\xbf\x80\xc1\xce\xb1\xa7\ +\xb4\xba\xc7\x05\x7b\x85\x93\x2c\x53\xe8\x49\xe7\xd7\x33\x96\x77\ +\xef\xac\xc7\x9f\x58\xd8\x7d\x9f\xe0\xd9\x02\x8e\x6f\x1a\x3d\x7b\ +\xbf\xa2\xe8\x27\x92\x4f\x73\xeb\xd5\x63\x0d\x40\xa5\xdf\x43\x7f\ +\xf1\x06\xa0\x9c\x78\x95\x20\x06\x3b\xb3\x9e\xda\xf2\x34\x92\x65\ +\x4a\x57\x6c\x33\xbd\x73\xf3\x12\x7f\xaa\x6c\x3f\x97\xe3\x9b\x4e\ +\x4f\x69\xee\x32\xc8\xa7\xb9\xf5\xa2\x06\xa0\xda\xb3\x9e\x87\xbf\ +\x34\x11\x7b\x47\x90\xe2\x5f\x00\x4f\x58\xde\x45\x24\xcb\x14\x7a\ +\xd2\xfb\x66\xf0\x84\x7f\x5e\xe2\x6f\xcb\x96\xb3\x36\x08\xa3\x7d\ +\x19\xc7\x37\x85\x9e\xb1\x74\x11\xf9\x34\xb7\x5e\x3d\xd1\x33\x7c\ +\xb1\x06\xa0\x44\xf1\x2f\x8e\xe7\x27\x84\x8f\x92\x2c\x53\xe8\xb5\ +\xba\x4f\xc9\x5b\xfc\xcd\xe9\x3b\x77\x70\x7c\x53\xb8\x45\xb0\xf4\ +\xde\x47\x3e\xcd\xad\x97\xec\xed\xbd\x58\x03\x40\xf1\x2f\x90\xe7\ +\x27\x85\xcb\x49\x96\xe9\xf2\xe2\xef\x67\xe7\x2d\xfe\x34\xd3\xfb\ +\x17\xe2\x25\x6d\x8b\x4c\x79\x5f\x23\x9f\x16\xdc\x5b\x6d\xe1\x67\ +\xb0\xb3\xed\x25\x59\xad\x8d\x64\x39\xc2\xe2\x2f\x9d\xdf\xe8\xfa\ +\xde\xfb\xe6\x35\xfe\xee\x5c\xb4\xc8\xb9\x89\x78\x49\xd1\x22\x53\ +\x96\x73\x35\xf9\x14\x8f\xe2\x5f\x40\x2f\x58\x0c\x84\x64\x99\x2a\ +\xef\xc2\xdc\xdf\x76\x32\xdd\x3f\x21\x5e\x52\xf5\xb6\xc9\x75\xe4\ +\x53\x3c\x06\xa7\x80\x5e\xbf\x06\x80\x64\x39\x3a\xcf\xff\xff\x2e\ +\xdb\xb4\x69\x5f\x29\xef\xf1\xe7\x79\xde\xa4\x30\xdd\xef\x11\x2f\ +\xe9\xf0\x54\xcb\xfb\x15\xf9\x14\x8f\xc1\x29\xa0\x77\x70\x93\x19\ +\x92\x65\x3a\xbc\x96\x7b\x66\x51\xe2\x4f\x98\xdd\x73\x88\x97\x94\ +\xdc\x76\x32\xbd\x1f\x91\x4f\x29\xfe\x0c\x4e\x01\xbd\x23\x3d\x04\ +\x48\xb2\x1c\xf1\xfe\xec\x96\xf7\xae\xc2\x35\x9f\x96\xf7\x7e\xe2\ +\x25\x05\x57\x9e\x2c\xe7\xcb\xe4\x53\x8a\x3f\x83\x53\x40\x4f\x95\ +\xee\x47\x48\x96\x63\x2e\xfe\xd2\xfb\xad\x98\x77\x4e\x2c\x5c\xf3\ +\xd9\xb2\x1f\xb8\xdc\x2d\x28\xe2\x65\xc4\x9e\xe9\xbd\x93\x7c\x4a\ +\xf1\x67\x70\x0a\xe8\x1d\xbe\x10\x10\xc9\x72\x0c\x9e\xe9\x3e\xaf\ +\xb8\xf1\x17\x6c\x5d\x4c\xbc\x8c\xd7\x73\x5f\x40\x3e\x2d\x66\xf1\ +\x4f\xfc\xf6\x1f\x83\x9d\x4f\x2f\xbe\x14\x30\xc9\x72\x2c\xde\xf7\ +\x75\x5d\x9f\x2a\x6a\xfc\x6d\xdd\x7a\x7e\x59\xb3\x9c\x2b\x89\x97\ +\xf1\x79\x0d\xe9\x9d\x45\x3e\x2d\x9c\x17\x2d\xfd\x9f\x78\x91\xa0\ +\x1a\x83\x9d\x3f\xaf\xd9\xec\x6c\x08\x36\x03\x22\x59\x8e\xcb\x73\ +\xb6\x14\x3d\x9e\x35\xd3\x55\x88\x97\xf1\x78\xaa\xf4\x7e\xd7\x6c\ +\x5e\xb0\x9e\x7c\x5a\xb8\xe2\x5f\x4a\xd4\x00\xc4\xf6\x13\xae\x33\ +\xd8\xf9\xf4\x14\xd9\xfe\x3c\xc9\x72\x0c\x9e\xe9\xfe\x2b\xf1\x77\ +\xa7\x27\x64\xfb\x63\xc4\xcb\x18\x3c\xd3\xfb\x30\xf1\x57\xb8\xe2\ +\x1f\xed\xf7\xd3\xbb\x01\x08\xbf\x5c\x0d\xcf\xfe\xeb\x0c\x76\x3e\ +\x3d\x55\xb6\xff\x98\x64\x39\xe2\x33\x2f\xcb\xb9\x45\x91\xdd\x07\ +\x11\x7f\x77\x7a\x8a\x6e\x3e\x4e\x98\xf6\xad\xc4\xcb\x68\x3d\x61\ +\xb9\x26\xf1\x57\xa8\xe2\x5f\x0e\x77\xfb\x9d\xec\xb9\xf4\x7f\xf8\ +\xe5\x4a\x78\xf6\x5f\x8b\xed\x2d\xcc\x60\xe7\xcc\xdb\x2a\x94\x13\ +\x55\xc3\xfe\x5f\x92\xe5\x48\xcf\xbc\xf6\x11\x7f\x77\xf5\x84\xd1\ +\xbe\x98\x78\x19\xa9\xf7\xcb\xe8\xf9\x13\xe2\xaf\x10\x5e\x25\xfc\ +\x1c\x6a\x00\xfa\x75\x0a\xeb\x63\x0d\x40\x8d\xc1\xce\x75\xf2\x7d\ +\x35\xc9\x72\x34\x5e\xb0\xf0\xca\xe2\xe2\x62\x85\xf8\xbb\xab\xb7\ +\x63\xc7\x62\x4d\xb3\xdc\x9f\x10\x2f\x23\xf2\xc2\xb7\x4f\x88\xbf\ +\x42\x78\xd5\xb0\x9e\x47\x0d\x40\xa9\xdf\x3d\x82\x4a\xac\x01\x98\ +\x66\xb0\xf3\xed\x29\xad\xee\x71\xaa\xe5\xdd\x48\xb2\x1c\xbe\xa7\ +\xb6\xba\x0a\xf1\xb7\xbc\x27\xcc\x6e\x93\x78\x19\x89\xe7\x9f\xfd\ +\xef\xad\x11\x7f\x85\xf0\xa2\x1a\x1e\x35\x00\x93\xbd\x2e\xfd\x97\ +\xc2\x0e\x21\x6a\x00\xaa\x0c\x76\x51\x92\xaf\xf7\x4c\x92\xe5\xd0\ +\xbd\x8f\x12\x7f\xbd\x3d\xd5\xf4\x3e\x49\xbc\x0c\xd9\x6b\x39\x4b\ +\xc4\x5f\x21\xbc\xe8\xea\x7d\xd4\x00\x94\x7b\x15\xff\x89\xb0\x3b\ +\x98\x8a\xdd\x2f\x60\xb0\x0b\xe2\xe9\xba\x3e\xa1\x99\xde\x97\x48\ +\x96\xc3\xf2\x9c\x5b\x9b\x0b\x9d\x93\x89\xbf\xde\x9e\x2a\x3b\x8f\ +\x54\xa5\x73\x1b\xf1\x32\x2c\xcf\xfd\x04\xf1\x57\x18\xaf\x1e\x6b\ +\x00\x2a\xfd\x1e\xfa\x8b\x37\x00\xe5\xc4\xab\x04\x31\xd8\xb9\xf1\ +\xb4\xd6\x9e\x87\x68\xd2\xbb\x81\x64\x39\x78\x4f\x58\xde\xcb\x89\ +\xbf\xc4\xbb\x54\x5e\x4c\xfc\x0d\xc1\x93\xce\xb5\xaa\x65\xdf\x9f\ +\xf8\x2b\x8c\x17\x35\x00\xd5\x9e\xf5\x3c\xfc\xa5\x89\xd8\x3b\x82\ +\x14\xff\x82\x7a\xc2\xf4\xb6\xaa\x96\x77\x3b\xc9\x77\x90\x9e\xfb\ +\x93\x99\x19\xaf\x4a\xfc\x25\xf3\xe6\x6c\xfb\x1e\x7e\xb1\xba\x86\ +\xf8\x1b\xa4\xe7\xdc\xaa\x9a\xee\x1f\x11\x7f\x85\xf2\xea\x89\x9e\ +\xe1\x8b\x35\x00\x25\x8a\x3f\x5e\x70\x8f\xd0\x4f\x1a\x07\x48\xbe\ +\x83\xf1\x44\xcb\xd3\x89\xbf\x95\x79\x0d\xd3\x5b\x20\xfe\x06\x56\ +\xfc\xf7\xab\x96\xdb\x20\xfe\x0a\xe7\x25\x7b\x7b\x2f\xd6\x00\x50\ +\xfc\xf1\xee\xbc\x12\x60\x79\xed\xf8\x95\x00\x92\xef\x2a\x8b\xbf\ +\xe5\x7c\x8a\xf8\x5b\x9d\xe7\xc7\xe0\xe7\x88\xbf\xb5\x79\xfe\x1c\ +\xfe\xbd\x66\x3a\x4d\xe2\x0f\xaf\x17\xb0\xaa\xc2\xcf\x60\xe7\xdb\ +\x53\xa5\xbb\x2d\x78\x3d\x90\xe4\xbb\xca\xe4\x2b\x9d\xdb\x14\xa3\ +\x7d\x2a\xf1\xb7\x3a\xaf\x61\x76\x1e\x13\x34\xa1\xc4\xdf\xea\xef\ +\xf9\x6b\x46\x67\x13\xf1\x87\x37\x94\x1f\x06\x3b\xff\xde\x8c\x68\ +\x6d\x54\x65\xfb\x3f\x49\xbe\xab\x39\xfb\xea\xfc\x25\xf1\xb7\x36\ +\x4f\x35\x3a\x6f\xa0\xf8\xaf\x22\xf6\x4c\xe7\x33\x8d\x86\xf3\x00\ +\xe2\x0f\x8f\xe2\x8f\xb7\x26\x6f\xcb\x96\xb3\x36\xa8\xc6\xd2\x0b\ +\x54\xc3\xb9\x99\xe4\x9b\xf8\xec\xeb\x9a\x6d\x9a\x7a\x3f\xe2\x6f\ +\x6d\xde\x36\xa1\x9c\xa4\x98\xce\x75\x14\xff\xa4\x71\xe7\xdd\xa0\ +\x9a\xde\xee\x8d\x1b\x4f\x9b\x20\xff\xe1\x51\xfc\xf1\x06\xe6\xcd\ +\x19\xde\x03\x85\xf4\xde\x4b\xf2\x4d\xe0\xe9\x6d\x97\xf8\x1b\x8c\ +\xa7\xca\xf6\x79\x14\xff\xbe\x9f\x03\xc2\xf2\xde\x26\x16\x76\xdf\ +\x87\x7c\x85\x47\xf1\xc7\x1b\x9a\xd7\x90\xee\xd3\xfd\x84\xf3\x7d\ +\x92\xef\x91\x2e\xbf\x76\xbe\x40\xbc\x0c\xce\xdb\xbc\xf9\x8c\x63\ +\x34\xe9\x7e\x85\xe2\x7f\xc4\xb3\xfe\x6f\x6a\xad\xee\x53\x88\x17\ +\x3c\x8a\x3f\xde\x48\x3c\xcf\xf3\x26\x85\x74\x9f\x2d\xa4\xf3\x1b\ +\x8a\xff\xff\x7d\x14\xd3\xb9\x5d\x69\xb4\x9e\x42\xbc\x0c\xd6\x6b\ +\x98\xde\xff\x53\xa5\x73\x07\xc5\xff\x2e\xb7\x99\xae\x0b\x2e\xf7\ +\xef\xdb\xb7\xef\x68\xe2\x05\x8f\xe2\x8f\x37\x72\x6f\xd6\xec\x1c\ +\xef\x27\xa2\x37\x2d\x97\x9c\x8b\xf8\xf4\xb6\x6a\xd8\x6f\x20\x5e\ +\x86\xe3\xf9\x63\xfc\x46\x8a\xff\x9d\x6f\x97\x68\x96\xfb\x57\xca\ +\xe2\xe2\x3d\x89\x17\xbc\x35\xd4\xf4\x75\x0c\x0e\xde\x60\xd6\x0d\ +\x30\xba\x1b\xe3\x1b\xb9\x14\xb1\xf8\x07\x0f\xab\x05\x0f\xad\x11\ +\x2f\xc3\xf1\xd4\x9d\xe7\xde\x4b\xb5\xbc\xff\x29\x72\xf1\x17\xd2\ +\xf9\x80\x66\x75\x4f\x21\x5e\xf0\xd6\xe0\x45\x4b\xff\x27\x5e\x24\ +\xa8\xc6\x60\xe3\x25\xf9\x51\x0d\x67\x87\x30\xec\xef\x16\xf2\xd5\ +\x2d\x7d\xe9\x5c\xe2\x65\xb8\x9e\xb0\xdc\xbd\x85\x2c\xfe\xa6\xf7\ +\xa5\x86\x74\x9e\x4a\xbc\xe0\x0d\xa0\xf8\x97\x12\x35\x00\xb1\xfd\ +\x84\xeb\x0c\x36\x5e\x52\x6f\xfb\xf6\x2d\xc7\x2a\x46\x7b\xb7\x62\ +\x74\x7e\x52\x94\xe2\x1f\xac\x95\xb0\x79\xf3\x19\xf7\x24\x5e\x86\ +\xeb\x05\xf7\xbb\x55\xcb\xfd\x46\x51\x8a\xbf\x2a\x9d\xff\xf6\xbf\ +\x23\x88\x17\xbc\x01\x15\xff\x68\xbf\x9f\xde\x0d\x40\xf8\xe5\x6a\ +\x78\xf6\x5f\x67\xb0\xf1\x56\xea\x6d\xdb\xf6\xf4\x7b\x09\xd3\x7d\ +\x86\x9f\xc8\x7e\x99\xe7\xe2\xaf\x18\xf6\x1d\x4a\x63\xe7\x66\xe2\ +\x65\x34\x5e\x43\xba\x4f\xce\xff\x5e\x15\xce\x55\xc1\x9e\x1c\xc1\ +\x36\xdd\xc4\x0b\xde\x80\x8a\x7f\x39\xdc\xed\x77\xb2\xe7\xd2\xff\ +\xe1\x97\x2b\xe1\xd9\x7f\x2d\xb6\xb7\x30\x83\x8d\xb7\x62\x2f\xd8\ +\x09\xcf\x4f\x6a\xcf\x09\x9e\x5a\xce\xe3\x03\x5c\xaa\xd1\x7e\x2b\ +\xf1\x32\x5a\x4f\xb5\xbc\x7f\xcc\x65\xf1\x97\xde\x4f\x35\xcb\xdd\ +\xe3\x17\xfe\x29\xe2\x05\x6f\x80\x5e\x25\xfc\x1c\x6a\x00\xfa\x75\ +\x0a\xeb\x63\x0d\x40\x8d\xc1\xc6\x5b\xab\xa7\xeb\x7b\x6b\xc2\xf2\ +\x9e\xdb\xaf\x11\xc8\x54\x32\x37\xec\xeb\x77\x68\xe6\x83\x38\xbe\ +\xa3\xf5\x82\xb7\x4f\x82\x7d\x2a\x72\x53\xfc\xfd\xc2\x2f\x4c\xef\ +\xdc\xad\x5b\xcf\x2f\x73\x7c\xf1\x06\xec\x55\xc3\x7a\x1e\x35\x00\ +\xa5\x7e\xf7\x08\x2a\xb1\x06\x60\x9a\xc1\xc6\x1b\xa4\xb7\xb0\xb0\ +\x30\xad\x99\xee\xb3\x54\xcb\xf9\x45\xe6\x2f\xe3\xea\xb6\xcd\xf1\ +\x1d\x8f\x27\x2c\xc7\xcd\x7e\xf1\x77\xae\x12\x96\xdb\xed\x75\xc6\ +\x4f\xbc\xe0\xad\xc1\x8b\x6a\x78\xd4\x00\x4c\xf6\xba\xf4\x5f\x0a\ +\x3b\x84\xa8\x01\xa8\x32\xd8\x78\xc3\xf2\x16\x17\x17\x2b\xc1\x42\ +\x26\xaa\x74\x7f\x98\xc5\xe2\xaf\x4a\xfb\x5f\x38\xbe\xe3\xf5\x54\ +\xbd\xf3\xc1\x6c\x16\x7f\xf7\x3b\x7e\x03\x33\xbf\x69\xd3\xbe\x12\ +\xc7\x17\x6f\x48\x5e\x74\xf5\x3e\x6a\x00\xca\xbd\x8a\xff\x44\xd8\ +\x1d\x4c\xc5\xee\x17\x30\xd8\x78\x43\xf7\xe6\xe6\x66\x26\xd5\x66\ +\x7b\x49\x18\x9d\x6f\x66\x26\x99\xfb\xff\xae\x3b\x76\x2c\xd6\x38\ +\xbe\xe3\xf5\xb6\x0a\xe5\x44\x21\xed\xcb\xb3\x52\xfc\xfd\xb3\xfd\ +\xff\xd0\xac\xee\x76\x8e\x2f\xde\x08\xbc\x7a\xac\x01\xa8\xf4\x7b\ +\xe8\x2f\xde\x00\x94\x13\xaf\x12\xc4\x60\xe3\x0d\x72\xe3\x97\xc6\ +\xe2\x0e\xd5\xb0\x3f\xba\xdc\x53\xde\xe9\x39\xf3\x77\x7e\xd8\x6c\ +\x76\xef\xc7\xf1\x4d\x87\x37\xdb\x30\x1f\xa1\x4a\xef\xc7\x69\x8d\ +\x17\xc5\xb0\x6f\xd3\x4c\xef\x9f\xd4\x96\xf3\x78\x8e\x2f\xde\x08\ +\xbd\xa8\x01\xa8\xf6\xac\xe7\xe1\x2f\x4d\xc4\xde\x11\xa4\xf8\xe3\ +\x8d\xd5\x0b\x56\x3b\xd3\x2c\xf7\x35\x7e\xe2\xfc\xdf\x74\x15\xff\ +\xce\x0f\x54\xab\x7d\x12\xc7\x37\x5d\x9e\x22\xbb\x0f\xd2\x2c\xe7\ +\xca\x34\x15\xff\x60\x65\x48\xbf\x99\x7d\xd5\xac\xb1\x78\x22\xc7\ +\x17\x6f\x0c\x5e\x3d\xd1\x33\x7c\xb1\x06\xa0\x44\xf1\xc7\x4b\x93\ +\x37\x67\xdb\xf7\xf0\x1b\x81\xf3\xfc\xe4\x7a\x79\x0a\x2e\xfb\x5f\ +\xaa\xb4\xba\xc7\x71\x7c\xd3\xe9\x05\x5b\xe1\x0a\xcb\xfb\x42\x1a\ +\x16\x85\x12\xfa\xd2\x9e\x73\xce\x51\xee\xcd\xf1\xc5\x1b\xa3\x97\ +\xec\xed\xbd\x58\x03\x40\xf1\xc7\x4b\xad\xa7\x5a\xee\x26\xcd\xf4\ +\xde\xa9\x5a\xde\xef\x47\x7a\x26\x67\xd8\x77\x08\xa3\xfd\xea\x33\ +\xcf\xdc\x33\xc5\xf1\x48\xb7\x17\xec\x52\xe9\x1f\xbf\x57\xf5\xdb\ +\x39\x70\xe0\xf1\x22\x9d\x9b\x82\xf5\x20\x94\xc6\xae\xa7\x72\x3c\ +\xf0\x32\xe5\xad\xb6\xf0\x33\xd8\x78\xe3\xf0\x66\x2c\xef\xde\x7e\ +\xd2\xbd\xd0\x4f\xda\x97\x0d\xbd\xf8\xcb\xce\x77\xe7\xf4\x5d\x67\ +\x73\x3c\xb2\xe5\x69\xad\xee\x53\xfc\x46\xf1\xbf\x86\x5e\xfc\x4d\ +\xef\x4b\x8a\xb1\x74\xde\x8e\x1d\xda\xfd\x39\x1e\x78\x59\xf7\x18\ +\x1c\xbc\x4c\x79\x6a\x73\xe7\xd3\x84\x6e\xbf\x45\x18\xce\x8d\x83\ +\x2d\xfe\x9d\x2b\x82\xcb\xb8\x3b\x76\x6c\xbd\x27\xc7\x23\x9b\x5e\ +\xb0\x6f\x40\xc3\x74\x17\xfd\xe3\xfa\xfd\x01\x17\xff\x9f\x0b\xcb\ +\xbb\x48\x31\xda\xa7\x72\x3c\xf0\x28\xfe\x0c\x36\xde\x98\xbd\xd9\ +\xd9\xed\xc7\x2b\x72\x69\x97\x66\xba\x1f\xd4\x2c\xe7\xd6\xd5\x14\ +\x7f\xc5\xb4\x6f\x11\xd2\xfe\xd7\xb9\xe6\xae\x26\x1b\xfb\xe4\xca\ +\x5b\x27\xa4\xbb\x5d\x95\x9d\xf7\xab\x86\x73\xf3\x6a\x8a\x7f\xb0\ +\xea\x60\xb0\xfc\x70\x43\xba\x4f\x0f\xd6\xe7\xe7\x78\xe0\x51\xfc\ +\x19\x6c\xbc\x14\x7a\xc1\x4a\x83\x6a\xcb\x99\xf1\x9b\x81\xbf\x10\ +\x96\xf3\x71\x61\x7a\x3f\x3a\xbc\x29\x50\xa5\xf7\xbb\xf0\xa9\xf1\ +\x8f\x6a\xa6\xf3\xf2\xb9\xe6\x62\x63\xfb\x76\x71\x5f\xc6\x2f\xdf\ +\xde\xc1\x46\xd1\xd8\xa5\xa8\xb2\xfd\x8a\x3b\x9b\x45\xef\x72\x21\ +\x9d\xdf\xc4\x62\xe3\x80\x26\xbd\x1b\xfc\x62\xff\x5d\xff\x3f\xbf\ +\x5f\x33\xbd\x17\x06\xcf\x9e\x04\xcf\x16\x30\x7e\x78\x14\x7f\x06\ +\x1b\x2f\xa3\x5e\xb3\x79\xc1\xfa\xf9\xf9\xf3\xeb\xc1\x0a\x84\x8c\ +\x1f\xde\xe1\xb7\x0b\xc2\xe5\x78\xd7\x31\x7e\x78\x14\x7f\x06\x07\ +\x0f\x0f\x0f\x0f\x0f\x8f\xe2\xcf\x60\xe3\xe1\xe1\xe1\xe1\xe1\xe5\ +\xa3\xf8\x27\x7e\xfb\x8f\xc1\xc6\xc3\xc3\xc3\xc3\xc3\xcb\x85\x17\ +\x2d\xfd\x9f\x78\x91\xa0\x1a\x83\x8d\x87\x87\x87\x87\x87\x97\xf9\ +\xe2\x5f\x4a\xd4\x00\xc4\xf6\x13\xae\x33\xd8\x78\x78\x78\x78\x78\ +\x78\x99\x2e\xfe\xd1\x7e\x3f\xbd\x1b\x80\xf0\xcb\xd5\xf0\xec\xbf\ +\xce\x60\xe3\xe1\xe1\xe1\xe1\xe1\x65\xb6\xf8\x97\xc3\xdd\x7e\x27\ +\x7b\x2e\xfd\x1f\x7e\xb9\x12\x9e\xfd\xd7\x62\x7b\x0b\x33\xd8\x78\ +\x78\x78\x78\x78\x78\xd9\xf2\x2a\xe1\xe7\x50\x03\xd0\xaf\x53\x58\ +\x1f\x6b\x00\x6a\x0c\x36\x1e\x1e\x1e\x1e\x1e\x5e\xe6\xbc\x6a\x58\ +\xcf\xa3\x06\xa0\xd4\xef\x1e\x41\x25\xd6\x00\x4c\x33\xd8\x78\x78\ +\x78\x78\x78\x78\x99\xf3\xa2\x1a\x1e\x35\x00\x93\xbd\x2e\xfd\x97\ +\xc2\x0e\x21\x6a\x00\xaa\x0c\x36\x1e\x1e\x1e\x1e\x1e\x5e\xe6\xbc\ +\xe8\xea\x7d\xd4\x00\x94\x7b\x15\xff\x89\xb0\x3b\x98\x8a\xdd\x2f\ +\x60\xb0\xf1\xf0\xf0\xf0\xf0\xf0\xb2\xe7\xd5\x63\x0d\x40\xa5\xdf\ +\x43\x7f\xf1\x06\xa0\x9c\x78\x95\x20\x06\x1b\x0f\x0f\x0f\x0f\x0f\ +\x2f\x6d\x5e\xd4\x00\x54\x7b\xd6\xf3\xf0\x97\x26\x62\xef\x08\x52\ +\xfc\xf1\xf0\xf0\xf0\xf0\xf0\xb2\xeb\xd5\x13\x3d\xc3\x17\x6b\x00\ +\x4a\x14\x7f\x3c\x3c\x3c\x3c\x3c\xbc\xcc\x7b\xc9\xde\xde\x8b\x35\ +\x00\x14\x7f\x3c\x3c\x3c\x3c\x3c\xbc\xa2\x78\xab\x2d\xfc\x0c\x36\ +\x1e\x1e\x1e\x1e\x1e\x5e\x3e\x3c\x06\x07\x0f\x0f\x0f\x0f\x0f\x8f\ +\xe2\xcf\xe0\xe0\xe1\xe1\xe1\xe1\xe1\x51\xfc\xef\xfa\x87\xc7\xf7\ +\x08\xa8\x0f\x60\xb9\x60\x3c\x3c\x3c\x3c\x3c\x3c\xbc\x11\x7a\xab\ +\xf9\xc3\xe3\x7b\x04\xd4\x06\xb0\x5c\x30\x1e\x1e\x1e\x1e\x1e\x1e\ +\xde\x08\xbd\xd5\xfc\xe1\xd5\xd8\xfa\xc2\xd3\x03\x58\x2e\x18\x0f\ +\x0f\x0f\x0f\x0f\x0f\x6f\x84\xde\x4a\xff\xf0\x75\xb1\x3d\x02\xd6\ +\xc7\x36\x17\x58\x87\x87\x87\x87\x87\x87\x87\x97\x0d\x2f\x32\x57\ +\xf2\x87\x97\x63\x7b\x04\x54\xd6\xb8\x5c\x30\x1e\x1e\x1e\x1e\x1e\ +\x1e\xde\x78\xbc\x89\xa4\x8b\x04\xad\x8b\xed\x11\x10\x7d\x26\xd7\ +\xf8\x87\xe3\xe1\xe1\xe1\xe1\xe1\xe1\x8d\xde\x2b\x25\x6a\x00\x62\ +\x5f\x9e\x8c\x7d\x4a\x03\xf8\xc3\xf1\xf0\xf0\xf0\xf0\xf0\xf0\xc6\ +\xe3\x25\x6a\x00\x26\x0e\xff\x1c\xb5\x86\x1f\x3c\x3c\x3c\x3c\x3c\ +\x3c\xbc\x54\x78\xeb\xfa\x75\x0b\x47\xc7\x3e\xeb\xd6\xf8\x87\xe3\ +\xe1\xe1\xe1\xe1\xe1\xe1\xa5\xc4\xfb\xff\x01\x0a\x14\x31\x69\x9b\ +\xf3\x10\xa8\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x07\xca\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x01\x04\x00\x00\x01\x04\x08\x06\x00\x00\x00\xce\x08\x4a\x0a\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x04\x67\x41\x4d\x41\x00\x00\xb1\x8f\x0b\xfc\x61\x05\x00\x00\x00\ +\x09\x70\x48\x59\x73\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7\x6f\ +\xa8\x64\x00\x00\x07\x5f\x49\x44\x41\x54\x78\x5e\xed\xdc\x4d\x88\ +\xdd\x57\x1d\xc7\xe1\xab\x4d\x9b\xa0\x22\x9a\xf7\xa4\x69\xa6\x25\ +\x2f\x77\x3a\x58\xc4\x85\x6b\x2d\xba\x70\xd1\x56\xa9\x0b\xa1\x2b\ +\xdd\xd4\x95\xe0\xc2\x97\x9d\xdb\x42\x40\x8c\x25\x62\x0b\xb5\x69\ +\xd0\xbe\x10\x15\x69\x34\xe9\xb4\x21\x49\x33\xb4\xe9\xcc\xa4\xe0\ +\xa6\xad\xe2\xc2\x8d\x0b\xb1\x54\x11\x54\xc4\xda\x9c\xe3\xb9\x93\ +\xd3\x9f\xc4\x9c\x4c\xe7\xe5\x26\xde\xff\xbd\xcf\x07\x1e\xc8\x72\ +\xce\xe5\x9c\x2f\x33\x79\xeb\x49\x92\x24\x49\x92\x24\x49\x92\x24\ +\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\ +\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\ +\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\ +\x49\x92\x24\x49\x92\x24\x49\x92\x74\x8d\xd2\x63\xbd\xdd\xe9\x58\ +\xef\xf3\xe9\x68\xef\x5b\xe9\x89\xde\x91\xe2\x68\x7e\xa2\x77\x7c\ +\x1c\x95\xb3\x1d\xca\xc7\x7b\x37\xd5\xa3\x4b\x1a\x94\x1e\xef\xdd\ +\x55\x06\xe0\xbb\xe5\x81\xfc\xb6\x3c\x94\x3c\x49\xca\x99\x9f\x36\ +\x0a\x52\xa9\x8c\xc0\xe7\xca\x83\x98\x6b\x3d\x94\x49\x62\x14\x34\ +\xd1\x95\x1f\x09\x0e\x96\x31\x38\xdd\x7a\x1c\x93\xca\x28\x68\x22\ +\x2b\x17\xff\xab\xc5\x3f\x5b\x8f\x62\xd2\x19\x05\x4d\x4c\xf9\xd1\ +\xde\xcd\xe5\xbb\x82\x1f\xb7\x1e\x02\xff\x65\x14\x34\xf6\x95\x31\ +\xf8\x40\x19\x83\x53\xad\x07\xc0\xd5\x8c\x82\xc6\xb6\xc1\xc5\x2e\ +\x63\xf0\x6c\xeb\xe2\x73\x6d\x46\x41\x63\x59\x19\x83\xc3\xad\x0b\ +\xcf\x7b\x33\x0a\x1a\xab\xca\x18\x7c\xb1\x75\xd1\x59\x39\xa3\xa0\ +\xb1\x28\x1d\xeb\x6d\x29\x97\xf9\xcd\xd6\x25\x67\x75\x8c\x82\x3a\ +\x5f\xb9\xc4\x3f\x6c\x5d\x6e\xd6\xc6\x28\xa8\xb3\xa5\xc7\x7a\x53\ +\xe5\xc7\x85\x7f\xb7\x2e\x36\x6b\x67\x14\xd4\xc9\xca\xc5\x7d\xb8\ +\x75\xa1\x59\x3f\xa3\xa0\x4e\x95\xbe\xdf\xdb\x58\xbe\x3b\xf8\x4b\ +\xeb\x32\x33\x1c\x46\x41\x9d\xc9\x9f\x2c\xdc\x18\x46\x41\x9d\xa8\ +\x0c\xc2\x23\xad\x0b\xcc\xf0\x19\x05\x8d\x7c\xe5\x92\x4e\xdc\xff\ +\x69\xf0\xff\x64\x14\x34\xb2\xe5\xa3\xbd\x4d\xe5\x82\x5e\x6a\x5d\ +\x5c\xae\x1f\xa3\xa0\x91\x6c\xf0\x3f\x1f\xb5\x2e\x2c\xd7\x9f\x51\ +\xd0\xc8\x55\x2e\xe5\xdd\xad\xcb\xca\x8d\x61\x14\x34\x52\x95\x0b\ +\x79\x5f\xeb\xa2\x72\xe3\x18\x05\x8d\x4c\xe5\x47\x86\x07\x5a\x97\ +\x74\xc5\x9e\xde\x98\xf3\x89\x8f\xe6\x7c\x7a\x77\xce\x73\xb7\xe7\ +\xfc\xca\x81\x9c\xe7\x0f\xe6\xbc\x38\x0d\xdd\x53\xee\x6e\x7a\xe5\ +\xc0\xa5\x34\x77\xc7\xdf\xd3\xd9\xdb\x7e\x9f\x9e\xdf\xf5\xf3\xf4\ +\xdc\xb6\xfb\x73\xee\xbd\xbf\x3e\x99\xf1\x6e\x4d\x83\xf0\xe4\xcd\ +\x39\x9f\xdc\x9a\xf3\x4b\xfb\xda\x1f\x2a\x8c\x99\xf4\xd2\xbe\xb7\ +\xd3\xe9\xdd\x73\xe9\xd4\x96\x4f\xd6\xa7\x33\x9e\xad\x6a\x10\x06\ +\x43\xf0\xfc\xae\x9c\x17\xfa\xcd\x0f\x0d\xc6\x5e\xb9\xfb\xe9\xcc\ +\x9e\x37\xd2\xa9\xad\x9f\xa8\x4f\x68\xbc\x5a\xd1\x20\x1c\x2b\x4e\ +\x6c\xf6\xa3\x00\x54\x69\xfe\x60\x4a\x2f\xec\xfe\x45\x3e\xd7\xdb\ +\x50\x9f\xd2\x78\xf4\x9e\x83\xf0\x93\x0d\x39\x9f\xbb\xad\xf9\xa1\ +\xc0\xa4\x4b\xe7\xa7\xde\xca\xb3\x5b\xa6\xeb\x73\xea\x7e\xcb\x0e\ +\xc2\x53\xb7\xe4\xfc\xb2\xdf\x27\x80\xe5\xa4\x97\xf7\xbd\x9d\x5e\ +\xd8\xfe\x99\xfa\xa4\xba\xdd\x35\x07\xe1\x99\x8d\x39\x5f\x38\xd0\ +\xfc\x00\x80\x2b\xa5\x0b\xfb\x2f\xa5\x53\x3b\xee\xad\xcf\xaa\xbb\ +\x35\x07\x61\xf0\x63\xc2\x85\xfd\xcd\x83\x03\x6d\x65\x14\xde\xe9\ +\xfc\x9f\x42\x5c\x35\x08\xc7\xde\x77\xf9\xef\x13\x34\x0e\x0c\x2c\ +\x2f\xcd\xdd\xfe\xb7\x7c\x6e\xdb\x87\xea\xf3\xea\x5e\x57\x0d\xc2\ +\x73\xdb\x9b\x07\x05\x56\x26\x9d\xb9\x75\xa1\x3e\xaf\xee\x75\xc5\ +\x20\x3c\xb3\xa9\x79\x40\x60\x75\xd2\xc9\x1d\x5f\xaa\x4f\xac\x5b\ +\x5d\x31\x08\xe7\xa7\x9a\x87\x03\x56\xe9\xfc\xd4\x5f\xeb\x13\xeb\ +\x56\x31\x08\x3f\xfd\x60\xfb\x60\xc0\x9a\xa4\xd9\xed\x5f\xaf\xcf\ +\xac\x3b\xc5\x20\x9c\xd9\xd3\x3c\x14\xb0\x36\xe9\xc5\xbd\x7f\xaa\ +\xcf\xac\x3b\x2d\x0d\xc2\xe0\x8f\x19\x1b\x07\x02\xd6\x61\xf0\xef\ +\x1e\x4e\x6d\x9e\xa9\x4f\xad\x1b\x2d\x0d\xc2\xe0\x9f\x2f\xb7\x0e\ +\x04\xac\x4b\x9a\xdd\xf9\x54\x7d\x6a\xdd\x68\x69\x10\xce\xdc\xda\ +\x3c\x0c\xb0\x3e\xe9\xec\xde\x3f\xd4\xa7\xd6\x8d\x96\x06\xc1\x5f\ +\x51\x86\xeb\x62\xf0\x57\x9a\xeb\x53\xeb\x46\xf9\xc9\x8d\x0f\xb6\ +\x0e\x02\x0c\x47\xfa\xd5\xce\xa9\xfa\xdc\x46\xbf\x74\x62\xf3\x77\ +\x5a\x87\x00\x86\x23\xcd\x6e\xfb\x4a\x7d\x6e\xa3\x5f\x3a\xb9\xf5\ +\xa1\xd6\x21\x80\xe1\x48\xb3\x3b\xbe\x5d\x9f\xdb\xe8\x57\xbe\xd8\ +\xc3\xad\x43\x00\xc3\x91\x66\x77\x1e\xaa\xcf\x6d\xf4\x2b\x5f\xec\ +\x91\xd6\x21\x80\xe1\x18\xbc\xb1\xfa\xdc\x46\x3f\x83\x00\xd7\x97\ +\x41\x00\x82\x41\x00\x82\x41\x00\x82\x41\x00\x82\x41\x00\x82\x41\ +\x00\x82\x41\x00\x82\x41\x00\x82\x41\x00\x82\x41\x00\x82\x41\x00\ +\x82\x41\x00\x82\x41\x00\x82\x41\x00\x82\x41\x00\x82\x41\x00\x82\ +\x41\x00\x82\x41\x00\x82\x41\x00\x42\xb7\x06\x61\xee\xf6\xaf\xb5\ +\x0e\x01\x0c\xc7\xe0\x8d\xd5\xe7\x36\xfa\xa5\x85\xfe\x03\xad\x43\ +\x00\xc3\x31\x78\x63\xf5\xb9\x8d\x7e\x06\x01\xae\x2f\x83\x00\x04\ +\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\ +\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\ +\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\ +\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\ +\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\ +\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\ +\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\ +\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\ +\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\ +\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\ +\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\ +\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\ +\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\ +\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\ +\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\ +\x83\x00\x04\x83\x00\x04\x83\x00\x84\x6e\x0d\xc2\x62\xff\xbe\xd6\ +\x21\x80\xe1\x28\x6f\xec\xde\xfa\xdc\x46\xbf\x34\xdf\xbf\xbb\x75\ +\x08\x60\x48\x2e\xf6\x3f\x5d\x9f\xdb\xe8\x97\x2e\xf6\xef\x6a\x1e\ +\x02\x18\x8a\xb4\x38\xfd\xb1\xfa\xdc\x46\xbf\x7c\x6e\x6a\x53\xf9\ +\x82\xdf\x69\x1d\x04\x58\x9f\xa5\xb7\xf5\xda\xcc\x2d\xf5\xb9\x75\ +\xa3\xb4\x30\xfd\x9b\xd6\x61\x80\xf5\x49\x8b\xfd\xd7\xeb\x33\xeb\ +\x4e\x65\x10\x1e\x69\x1d\x06\x58\x9f\xb4\xd0\x3f\x52\x9f\x59\x77\ +\x2a\xdf\xd6\xdc\xdf\x3a\x0c\xb0\x3e\x83\x3f\xc5\xab\xcf\xac\x3b\ +\xa5\xdf\xed\xdf\x58\xbe\xf0\x3f\xb7\x0e\x04\xac\x4d\x79\x53\x6f\ +\x75\xee\xf7\x0f\xde\xad\x7c\x97\xf0\x70\xeb\x50\xc0\xda\x94\x1f\ +\x17\xbe\x57\x9f\x57\xf7\xca\xaf\xce\xec\x2d\x07\xf8\x57\xeb\x60\ +\xc0\xea\x0c\xde\x52\x9a\xdf\xbf\xa7\x3e\xaf\x6e\x56\x0e\xf1\x83\ +\xd6\xe1\x80\xd5\x49\x0b\xd3\x87\xeb\xb3\xea\x6e\xf9\xd7\x1f\xff\ +\x48\x39\xc8\x9b\xad\x03\x02\x2b\x93\x16\xfb\x7f\x2c\xdf\x1d\x7c\ +\xb8\x3e\xab\x6e\x97\xe7\xef\xfc\x42\x19\x85\xd4\x3a\x28\xb0\xbc\ +\xc1\xdb\x29\xee\xa9\xcf\x69\x3c\x1a\xfc\x66\x48\xeb\xb0\xc0\xf2\ +\xca\x18\x1c\xaa\xcf\x68\x7c\xca\xc7\x7b\x37\x95\x83\x3d\xdb\x3a\ +\x30\xd0\x56\xde\xcc\xcf\x06\x6f\xa7\x3e\xa3\xf1\xea\xf2\xbf\x71\ +\xe8\xff\xb2\x75\x70\xe0\x4a\x65\x0c\x4e\x74\xf6\xef\x1c\xac\xb4\ +\x7c\xee\x53\x1b\xca\x41\x7f\xd4\xfa\x00\x80\xcb\xca\x8f\xd8\x8f\ +\x8e\xed\x77\x06\xad\xca\xa1\x1f\x2c\x87\xfe\xc7\xff\x7e\x10\x30\ +\xc9\x96\xde\xc4\x42\xff\xcb\xf5\x99\x4c\x56\xe9\xe2\xfe\x7d\xe5\ +\x03\x38\xd9\xfa\x60\x60\xd2\x0c\x7e\x9c\x4e\xf3\x07\xef\xa8\xcf\ +\x63\x72\xcb\x8b\x77\x7e\xb6\xac\xe2\x8b\xad\x0f\x09\xc6\x5d\x5a\ +\x9c\x3e\x3b\xf8\x5f\xc6\xea\x73\xd0\xbb\xa5\xf9\x99\x99\xb2\x92\ +\x0f\x15\xaf\xb7\x3e\x38\x18\x17\xe5\x8e\xbf\x36\xb8\xeb\xf9\xd5\ +\x83\xd3\xf5\xfa\x6b\xb9\xd2\xc5\xe9\x5d\x69\x61\xfa\x9e\xf2\xa1\ +\x7d\x73\xf0\x8f\xa4\xca\xaf\x1f\x2f\x1f\xe4\x71\xe8\x9a\xc1\xdd\ +\x5d\xba\xc3\x8b\xfd\x6f\x0c\xee\x74\x5e\x98\xd9\x59\xaf\xb9\x24\ +\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\ +\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\ +\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\ +\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\ +\x57\xd6\xeb\xfd\x07\x85\x1a\x3c\xaf\xcc\x24\x67\x3a\x00\x00\x00\ +\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x04\xcf\ +\x00\ +\x00\x80\x9c\x78\x9c\xed\x9c\xcf\x6b\x24\x45\x14\xc7\x9f\x5e\x12\ +\x2f\x9e\x3c\x04\xf4\xb0\xa0\xec\x76\xcf\x8c\xe0\xc5\xfb\x5e\x3c\ +\x09\x3a\x87\x2c\x98\x08\xf1\x5f\x11\x84\x2c\x1b\x14\x16\xf7\xa0\ +\x92\xee\xc9\x7f\x20\xb8\xe8\xbf\xe0\xc9\xff\x41\x44\xd9\x55\x82\ +\x2e\xa2\x97\x85\x35\xe5\xab\x9e\xaa\xf4\xeb\x97\xea\x9f\x93\xe9\ +\x9e\xe9\x7c\x3f\x50\xcc\x4e\x4f\xd7\xb7\xde\x7b\xf5\xaa\xba\xaa\ +\x7a\x09\xd1\x4b\xf4\x32\xdd\xbd\x4b\xfc\x79\x8b\x22\xfe\xbc\x4d\ +\x44\x7b\x7b\xee\xfb\x2b\x44\x1f\xf0\xb5\x88\xaf\xf1\x07\x7d\x4a\ +\xcb\xeb\x00\x00\x00\x00\x00\x63\xc3\x10\xed\x72\xb9\xc7\x65\x9f\ +\xcb\xce\xd0\xf6\xf4\x85\xf0\xfb\x21\x17\xe3\xca\xfb\x43\xdb\xb5\ +\x6e\x4a\xfc\xb6\xe5\xbe\xfd\x6d\x68\xfb\xd6\x0d\xfb\xf8\x89\xf2\ +\xfb\xc4\xc5\xe3\x26\xf8\x6e\xfb\xfe\x07\xe7\xf7\xb7\x37\xc5\x6f\ +\x8b\xf3\xfd\x0b\xd1\xef\x07\x43\xdb\xd4\x27\xec\xef\xa1\xca\xfb\ +\xfd\xa1\x6d\xea\x0b\xd5\xf7\xdf\x89\xf9\xee\x46\x3c\xef\x44\xdf\ +\x1f\x73\x79\x55\xc4\xe2\x78\xec\x31\x50\x7d\x3f\x77\xd7\x0e\xc4\ +\x38\xf8\x70\x68\x1b\xd7\x89\xea\xfb\x5d\x77\x6d\x47\x3c\xff\x1f\ +\x8c\x35\x07\x5c\xdf\x7b\x3f\xf7\xd5\x6f\x32\x07\x46\x37\x0e\x02\ +\xcf\xbb\xb9\xfa\x7d\x47\xfd\x3e\x8a\x18\x94\xac\x6f\x83\x6b\xdb\ +\xb1\xc5\x20\xd0\xe7\xb5\xeb\xfa\x40\x0c\xb6\x6a\x3e\x14\xfd\x7d\ +\xa0\xfc\x68\xbc\xae\x57\x31\xd8\xe8\x75\x81\xf2\x57\xfb\xec\x73\ +\xb8\xf5\xba\x5e\xc5\x60\xa3\xc6\x81\xf2\x59\xef\x5b\xbd\xbd\x07\ +\x5d\xfc\x56\xed\x6c\xd4\xba\x40\xf8\xad\xfb\xd8\xe7\xf7\xca\x3e\ +\xab\xf6\xae\x6d\x1c\x04\xf2\x34\x54\x82\x67\x4e\x25\x73\xb8\xed\ +\xe3\x47\x62\xcd\xb2\x96\x7d\xab\x8a\x41\xeb\x1c\x28\xb1\xbd\xaa\ +\x3c\x90\xb1\xa8\x9a\xc3\xb9\x1c\x99\x1e\xf6\x6e\x5d\xdb\x29\xb1\ +\xdd\xe7\xa9\x2e\x65\xe3\xf8\xa1\xaa\x7b\x99\xdf\x3d\xfa\xef\xe7\ +\x81\x79\xfd\xdd\x85\x7a\x87\x65\xb6\x07\xee\xdd\x71\x7d\x5e\x36\ +\x8f\x5f\x79\x6e\x0b\xbb\xd6\x3a\x3f\x3b\xdb\xe6\x6d\xc7\x98\xb0\ +\xaf\xf5\x59\xa2\x59\xee\x4b\x1f\x57\x8d\xef\x55\xc7\xe6\xba\xe9\ +\x1a\x37\x57\x57\xe6\x4e\x69\xde\x89\x31\x30\xaa\x7d\x9b\xf2\xab\ +\x6a\xbd\xba\x51\xcf\xe8\xeb\xc0\x04\xce\x28\x2a\xee\x1d\xdd\xde\ +\xdd\x04\xce\x28\x6a\xee\x1f\x55\x0e\xb4\x7d\xae\xa9\x1c\xd8\xea\ +\x73\xdc\x36\xb9\xaf\xea\xf5\xb2\x16\x58\x27\xca\xf7\x46\xb9\x2f\ +\xea\x7a\xff\x3f\x37\x5b\xf6\xee\xd6\xf9\x7d\x28\x9e\xf7\x5d\xd6\ +\x5a\x47\xa2\xae\x9f\x0b\x37\x3a\x0e\x26\xdf\x1b\x3c\x52\xb6\x77\ +\x59\x2f\x79\xff\x1f\x07\xe2\x50\xb9\xbf\x1a\x02\x13\xde\x1b\xfc\ +\xe8\xf2\xa0\xcb\x7a\xc9\xfb\xff\x91\xf3\xb3\x6c\xbf\x75\x3c\x74\ +\x1c\x02\xbe\x7f\xef\x3e\x3b\xbf\x83\xd4\xf3\x9f\xb9\xba\x9f\xd0\ +\x7b\x8a\xc1\xfe\x6f\x83\x29\xae\x6d\xef\x0b\xdb\x3b\x9f\x31\x34\ +\x99\xff\x45\x4c\x06\x7b\xcf\x6d\x8a\xef\x20\x4e\xdc\xf7\x95\xcf\ +\xda\xb6\xe5\xf9\x67\x4a\xf6\x35\x66\xc5\x35\xdc\x16\xf9\x7f\x24\ +\xfb\x5e\x5c\xef\x7c\xd6\xa6\x72\x6a\x5b\xfc\xbf\x62\xa7\x8b\xc1\ +\x89\xfb\xfd\xb3\xa6\x31\x70\xe3\xb9\xd3\xba\xa1\x4f\x9a\xf4\x93\ +\xe9\x70\xa6\xb1\x09\xf3\x5a\x1d\x81\x67\x5e\x93\x33\x8d\x8d\xce\ +\xe5\xa6\x04\x7c\xaf\x7b\x07\x37\x1a\xff\xdb\xfa\xee\xea\x8c\xc2\ +\xff\x2e\xbe\xbb\x7a\x63\xf1\xff\x5e\x5b\xdf\x5d\xbd\xb1\xf8\xdf\ +\x69\x5e\x36\x1d\xdf\x37\x8c\x05\xb3\xc2\xb9\x39\x00\x00\x00\x00\ +\x40\x5f\xd8\xbf\x13\xb0\xc7\xe5\x1d\xea\xef\xef\x04\xdc\x3a\xa3\ +\xdd\xb7\xcf\x68\xfe\xd6\x97\xd7\x73\x96\x7d\xfb\x1b\x7a\x6d\x7a\ +\x46\xef\xc6\x67\xf4\x9e\x3c\x32\xff\x93\xde\x34\xab\xea\x4e\x52\ +\xfa\x58\x6a\x72\x3b\xbf\xf0\xb5\x4c\xbb\xab\xbe\xd5\xd5\xc7\xfb\ +\xf1\x82\x5e\xc4\x09\xfd\x37\x2d\x68\x9b\x96\xfa\x45\xcd\x68\x41\ +\xcf\xa3\x94\x2e\x26\x0b\xba\x98\x2d\xc8\x48\x6d\xfb\xbd\xa9\xbe\ +\xb4\x97\xb5\xfe\x62\xcd\xe7\xd6\x56\xab\xe1\x75\xa5\xf6\x9d\x84\ +\x5e\x34\xd7\xcf\xed\xf5\x7a\xb6\xb0\xbe\x89\xd3\xbc\x78\x6d\x6e\ +\xdf\x96\x2c\x4e\xf5\xfa\xce\x66\xb6\x57\xda\x17\x2a\xb6\xcd\x4c\ +\x3f\x75\xed\xa7\x74\x5e\xad\x9f\xdb\x6c\xb5\x6d\xbd\x78\x59\x2f\ +\xfb\xf7\x44\xc5\x7a\xea\xf4\xa3\x64\xa9\xcf\x31\xfc\xb5\x5c\xdf\ +\xe5\x5a\x2a\xb4\x85\xae\xd4\x9e\xb0\x9e\x2f\xf6\x7b\x9c\xdb\xff\ +\x73\x95\xfe\x9d\x94\x9e\x4d\x45\x7c\xad\x7d\x13\xd1\x9e\xd3\xba\ +\x60\x7b\x2f\xb2\xbe\x50\xfa\x79\xbf\x85\x6d\xb7\xf9\x9c\xf9\x99\ +\xe4\x36\xcf\x16\x45\xdb\xad\x76\x74\xca\xda\xa7\x79\x7c\x26\x42\ +\x7f\x99\x77\x57\xf5\xb9\xff\x9f\x4e\x73\x3f\x2f\x6d\xf6\x31\x90\ +\x25\x72\xb1\xb9\xd4\xe7\xb1\x50\x9d\x3b\xd9\xb8\x39\x8f\x93\x62\ +\xbc\xad\xad\x5e\x33\x4e\x96\x71\xc9\xf4\x4f\xf3\xfc\x9f\x2c\xea\ +\x62\xe3\xec\x4f\xe9\x6f\x1d\xeb\x42\x4c\x6c\xcc\x4f\xf3\x78\x4c\ +\x54\xff\x58\x8d\x37\xbe\xa2\xd7\x4b\xf5\x17\xf4\x2c\x4e\xc3\xf9\ +\x6e\x75\xad\xcd\x3e\x56\x5e\x57\xd8\xf3\x7b\x5d\xde\xb3\xf6\x13\ +\x11\x8b\xcb\xb1\x1f\x8b\x5c\xf4\x7e\xf9\xdc\xcd\x62\x94\xd4\xc5\ +\x26\xcf\x9f\xc8\xcd\x2f\x91\xcc\xbd\x24\x1f\x07\xfe\x9a\xd7\x9d\ +\xa5\x4d\xb4\x85\x0f\x09\xfd\xe3\xc7\xee\x2c\x2d\xea\x4b\xcd\xd9\ +\xb2\x5f\xff\x6d\xae\x9d\xfb\x60\xeb\xc5\x76\xae\x12\xed\xf8\xe2\ +\xe7\x4f\x6e\xef\x37\xbe\xef\xeb\xae\x73\x3d\x6b\xfc\xc4\xf5\xff\ +\xe0\xf9\xe4\xdc\x16\x39\x87\xd6\xe7\x62\xe3\x36\x4a\x34\x57\xd1\ +\x2e\xb6\x71\xbd\x9a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\xc8\xf9\x1f\x5d\x48\xbb\x77\ " qt_resource_name = "\ @@ -87,17 +1620,37 @@ \x06\x01\x21\x3e\ \x00\x48\ \x00\x79\x00\x64\x00\x72\x00\x6f\x00\x53\x00\x45\x00\x44\x00\x50\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ +\x00\x05\ +\x00\x6f\xa6\x53\ +\x00\x69\ +\x00\x63\x00\x6f\x00\x6e\x00\x73\ \x00\x08\ \x0a\x61\x5a\xa7\ \x00\x69\ \x00\x63\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0a\ +\x0c\xf7\x1b\xc7\ +\x00\x63\ +\x00\x6f\x00\x6e\x00\x66\x00\x69\x00\x67\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0a\ +\x0a\xc8\xfb\x07\ +\x00\x66\ +\x00\x6f\x00\x6c\x00\x64\x00\x65\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0a\ +\x04\xa1\x18\x1f\ +\x00\x63\ +\x00\x75\x00\x65\x00\x6e\x00\x63\x00\x61\x00\x2e\x00\x69\x00\x63\x00\x6f\ " qt_resource_struct = "\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ -\x00\x00\x00\x14\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\ -\x00\x00\x00\x36\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x00\x14\x00\x02\x00\x00\x00\x02\x00\x00\x00\x03\ +\x00\x00\x00\x36\x00\x02\x00\x00\x00\x03\x00\x00\x00\x05\ +\x00\x00\x00\x46\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x00\x90\x00\x01\x00\x00\x00\x01\x00\x00\x5e\xb0\ +\x00\x00\x00\x76\x00\x00\x00\x00\x00\x01\x00\x00\x56\xe2\ +\x00\x00\x00\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x04\x0e\ " def qInitResources(): diff --git a/qgisplugin/resources_rc.py b/qgisplugin/resources_rc.py new file mode 100644 index 0000000..5d4eb4d --- /dev/null +++ b/qgisplugin/resources_rc.py @@ -0,0 +1,1662 @@ +# -*- coding: utf-8 -*- + +# Resource object code +# +# Created by: The Resource Compiler for PyQt4 (Qt v4.8.7) +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore + +qt_resource_data = "\ +\x00\x00\x04\x0a\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x17\x00\x00\x00\x18\x08\x06\x00\x00\x00\x11\x7c\x66\x75\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ +\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\ +\x00\x9a\x9c\x18\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xd9\x02\x15\ +\x16\x11\x2c\x9d\x48\x83\xbb\x00\x00\x03\x8a\x49\x44\x41\x54\x48\ +\xc7\xad\x95\x4b\x68\x5c\x55\x18\xc7\x7f\xe7\xdc\x7b\x67\xe6\xce\ +\x4c\x66\x26\x49\xd3\x24\x26\xa6\xc6\xf8\x40\x21\xa5\x04\xb3\x28\ +\xda\x98\x20\xa5\x0b\xad\x55\xa8\x2b\xc5\x50\x1f\xa0\x6e\x34\x2b\ +\x45\x30\x14\x02\xba\x52\x69\x15\x17\x66\x63\x45\x97\x95\xa0\xad\ +\x0b\xfb\xc0\x06\x25\xb6\x71\x61\x12\x41\x50\xdb\x2a\x21\xd1\xe2\ +\x24\xf3\x9e\xc9\xcc\xbd\xe7\x1c\x17\x35\x43\x1e\x33\x21\xb6\xfd\ +\x56\x87\xf3\x9d\xfb\xfb\x1e\xf7\xff\x9d\x23\x8c\x31\x43\x95\xf4\ +\x85\x1e\x3f\x3b\x35\xac\xfd\xcc\x43\xdc\xa4\x49\x3b\xfe\x9d\x1d\ +\xdb\x7b\x22\x90\x78\xf8\xb2\x28\xa7\xbe\x7d\xc1\x4b\x9d\x79\xdf\ +\x18\x15\xe5\x16\x99\x10\x56\xde\x69\xdc\x3f\x22\xfd\xec\xd4\xf0\ +\xad\x04\x03\x18\xa3\xa2\x7e\x76\x6a\x58\xde\x68\x2b\xb4\x36\xf8\ +\xbe\xc6\x18\x53\xdb\xef\xe7\xfa\xec\xed\x67\x63\x10\x42\x00\xf0\ +\xfb\xd5\x65\x2a\x15\x45\xc7\x6d\x0d\x00\xc4\xa2\xc1\xaa\x6f\x0d\ +\x3e\x6c\xab\xc2\x1c\x56\xa4\x77\x4b\xb0\xf2\x35\x15\x5f\x21\x85\ +\xe0\xc8\x6b\x5f\x92\x2d\x37\x33\x39\xf9\x03\x27\x8e\x1f\xa2\xf7\ +\xbe\x9d\x04\x1c\x0b\x37\xe4\xac\xff\xa6\x30\x87\xbd\xba\x00\x6a\ +\x06\x79\xe5\xf5\xaf\x89\xd9\x92\xc5\xcc\x0a\xd9\x7c\x19\xcf\xe9\ +\xe2\xe4\xa9\x2f\x78\x7c\xff\x01\x72\x85\x0a\x2b\x65\x1f\xa5\x4c\ +\xb5\xb2\x55\x16\x80\xbd\x31\xda\xda\x20\x1f\x7d\x3e\xcd\xc2\xfd\ +\x59\xa6\x93\x39\x92\xd1\x22\xea\x9b\x16\xce\x9d\x3f\xce\xe0\x83\ +\x03\x24\x82\x59\x3a\xdb\x7b\x88\xc7\x82\x68\x63\x58\xc9\xcc\x62\ +\x8c\x21\x18\xb0\x6a\xc3\x37\x06\x49\x16\xff\x24\x6b\xa5\x49\xbb\ +\x25\xbc\xa2\xa6\x21\xbb\x40\x7f\xdf\x00\x83\xbd\x01\x8e\x3c\xd5\ +\x45\xd7\x8e\x6b\x9c\x9c\x98\x25\x1a\xb6\xe8\xbe\x3d\xc2\xdd\x77\ +\x44\x48\xc4\x1c\x22\xe1\xeb\x58\x59\xaf\xcf\xd3\x33\x29\x2e\x34\ +\x2d\x91\x93\x3e\xbe\x34\x78\x01\xc5\xe2\x61\xc5\xae\x72\x8e\x70\ +\xc8\xc2\x0d\x5a\xbc\xf5\xee\x2f\x9c\xfa\x3e\x86\x69\x7a\x8e\xcf\ +\x26\xe6\xf9\x63\xa1\x44\xa1\xa4\xd0\xda\x6c\x0d\x2f\x15\x7c\xb4\ +\x67\x28\x59\x0a\xcf\xd6\x54\xe2\x06\x13\x87\x2b\x6f\x68\xa6\x27\ +\xaf\x31\x32\x36\xc7\xb2\x7f\x17\xef\x7d\x7c\x8c\x33\x67\xcf\x12\ +\x70\x24\x4a\x69\xd6\x6a\x46\xd6\xd3\x70\x72\xa9\x82\x67\x34\x45\ +\xad\x28\xdb\x1a\x15\x34\x98\xff\x46\xed\xef\x37\x0d\x99\xbf\x4a\ +\x3c\x30\x38\xc0\xc8\x4b\xaf\x92\x5a\x9c\xe2\xe0\x23\x6d\x74\xb4\ +\xba\x84\x5d\x0b\x29\x45\x7d\xb8\x94\x82\x96\xb6\x10\xf3\xc5\x12\ +\x2a\xef\x53\x11\x1a\x63\xad\x3f\x93\x19\x85\xf1\xb1\x77\x58\x5a\ +\xf8\x99\x97\x9f\xe9\xa6\x75\x47\x90\xc6\xb8\x43\xd8\xb5\xb6\xce\ +\xfc\xfa\xfd\x00\xfb\x3e\xf4\xc8\x05\x35\xba\x5e\xeb\x46\x21\xf9\ +\xcf\x0a\xa9\x8c\x87\xe3\x48\xdc\x90\xb5\x6e\x98\x6a\xaa\x65\xf2\ +\x52\x92\x43\x2f\x5e\xc2\x8c\x02\x1a\x10\xf5\x07\xac\xc3\x75\x70\ +\x83\x92\x80\xb3\xf9\xd0\x26\xf8\x8f\xb3\x29\xc6\x3e\xb8\x8c\x19\ +\x35\x75\x6b\x7b\x7e\x3c\xca\x45\x0c\x7e\x49\x31\xf4\x58\x3b\xf7\ +\xf6\x34\x90\x88\x39\x04\x1c\x59\x1f\xfe\xdb\xd5\x3c\x5f\x9d\x4b\ +\x32\xfd\x44\xb2\xba\xd7\xfa\xb6\x60\xcf\xde\x16\xdc\x90\x45\x4c\ +\x4a\x2a\x9e\x62\xfe\x4e\xc5\xc8\xc1\x4e\xda\x76\x86\xe8\xe9\x0a\ +\xe3\xd8\x92\x58\xd4\xc6\xb2\x44\x6d\x78\x2a\x53\xe1\xca\x7c\x99\ +\x63\x5d\xbf\x56\x9d\xbd\x9f\x44\x18\x7a\xba\x95\x27\x0f\xb4\xd3\ +\xdc\x18\xc0\xf3\x0d\x52\x40\xd8\xb5\xb0\xa4\x20\x14\xb2\x70\x6c\ +\x81\x63\xcb\xaa\x42\xd6\xfd\xb7\xf4\xec\xa3\x06\xa0\x50\x52\xd8\ +\x4e\x1b\x7e\x4a\xd3\x31\xf9\x29\xcf\xfe\xd4\x49\x7f\x5f\x13\xfb\ +\xfa\x9b\x71\x43\x92\x58\xd4\x21\x18\x90\xac\xde\xb0\x42\x50\x13\ +\x58\x33\xf3\x88\x6b\xa1\xfd\x65\x96\xf2\x79\xc6\x43\x7b\xd8\x75\ +\x38\xcc\x3d\xdd\xd1\xaa\xcf\x71\xe4\xff\x7f\x91\x56\x33\xaf\xea\ +\x37\xe7\xa1\x94\x21\x16\xb5\xd1\x06\x2c\x29\x36\xf5\x72\x9b\x96\ +\x95\xc0\xc4\xda\x9d\x78\x83\x43\x53\x22\x80\x65\x09\x1c\xfb\x86\ +\xc1\x00\xe7\x25\x70\x14\x48\x6f\x1e\x22\x51\xe3\x75\xd9\xb6\xa5\ +\x81\xa3\x32\xb1\xfb\xf4\x0c\x30\xb8\xb1\x82\x9b\xb0\x09\x60\x30\ +\xb1\xfb\xf4\xcc\xbf\xa0\xe9\x6e\xae\x5a\xdf\x4b\x81\x00\x00\x00\ +\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x52\xd0\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x02\x00\x00\x00\x02\x00\x08\x06\x00\x00\x00\xf4\x78\xd4\xfa\ +\x00\x00\x52\x97\x49\x44\x41\x54\x78\xda\xed\xdd\x09\x9c\x24\x65\ +\x7d\xf8\x7f\x96\xe9\x99\xee\xed\x69\x1b\x59\x45\x44\x11\x2f\xf0\ +\x02\x5d\x8d\xbf\xe0\x85\xd9\x45\xc0\xbd\x66\xa6\xea\xa9\xee\xaa\ +\xa7\xaa\x67\x76\x67\xba\xba\xaa\x7a\x77\x01\x23\xa8\xf1\xe5\x95\ +\x8d\x47\x34\x28\x31\x89\x47\x12\x8f\xa8\xaf\x68\x62\xbc\xa3\x46\ +\xe3\x1d\x11\xef\x78\x45\x85\xa8\xa0\x88\x07\x8a\x10\xc1\x20\x88\ +\x2c\xec\xff\x5f\xb5\x54\x6d\x8a\x65\xb6\xbb\x66\xa6\x8f\x3a\x3e\ +\xf3\x7a\xf5\x0b\x8f\x9e\xf7\xb2\x4f\x7d\x9f\xef\xf7\x5b\xd7\xf3\ +\x1c\x75\x14\x3f\xfc\xf0\xc3\x0f\x3f\xfc\xf0\xc3\xcf\x4a\x7f\xce\ +\x3e\x7b\xf3\x3a\xff\x73\x74\xec\xb3\x0e\x0f\x0f\x0f\x0f\x0f\x0f\ +\x2f\x5b\xde\x4a\xff\xf0\x89\xc3\x3f\x78\x78\x78\x78\x78\x78\x78\ +\xd9\xf2\x56\xda\x75\x94\xfc\xcf\x64\xec\x53\x5a\x6d\xf7\x81\x87\ +\x87\x87\x87\x87\x87\x37\x7a\x6f\x35\x7f\x78\xf0\x07\x4e\xc5\x3e\ +\x93\x6b\xfc\xcb\xe0\xe1\xe1\xe1\xe1\xe1\xe1\x8d\xd0\x5b\xcd\x1f\ +\x5e\xf6\x3f\x95\xd8\xa7\xbc\xc6\xbf\x0c\x1e\x1e\x1e\x1e\x1e\x1e\ +\xde\x08\xbd\xd5\xfc\xe1\xc1\x1f\xb8\x3e\xf6\xa9\xac\xf1\x2f\x83\ +\x87\x87\x87\x87\x87\x87\x37\x42\x2f\x32\x93\x7e\x31\x78\xba\xb0\ +\xea\x7f\xa6\x63\x9f\xe0\xbf\x1f\xbd\xca\x3f\x18\x0f\x0f\x0f\x0f\ +\x0f\x0f\x6f\xf4\xde\xba\xf0\xa1\xc1\xa3\x93\xfe\xe1\xc1\x1f\x58\ +\x8b\x7d\xa6\xd7\xf8\x97\xc1\xc3\xc3\xc3\xc3\xc3\xc3\x1b\xad\x17\ +\x3d\x40\xd8\xbf\x01\x88\xfd\xe1\xf5\xd8\xa7\xb6\xc6\xbf\x4c\x0d\ +\x0f\x0f\x0f\x0f\x0f\x0f\x6f\xa4\xde\xba\xd8\x5b\x03\xbd\x1b\x80\ +\xf0\xcb\xd5\xd8\xbf\xc0\x31\xe1\x3f\xd7\xf2\x97\x89\x9c\x63\xf0\ +\xf0\xf0\xf0\xf0\xf0\xf0\x46\xe2\x45\x0f\x10\x4e\xc5\x1a\x80\x75\ +\xbd\xbe\x5c\x89\x5d\x7a\xa8\x33\xd8\x78\x78\x78\x78\x78\x78\x99\ +\xf4\xa2\xb7\x06\x0e\x35\x00\xfd\x3a\x85\xf5\x87\xdd\x7b\x60\xb0\ +\xf1\xf0\xf0\xf0\xf0\xf0\xb2\xe5\x55\x63\x6f\x0d\x04\x0d\x40\xa9\ +\xdf\x3d\x82\x4a\xac\x01\x98\x66\xb0\xf1\xf0\xf0\xf0\xf0\xf0\x32\ +\xe7\x45\x35\x3c\x6a\x00\x26\x7b\x5d\xfa\x2f\x85\x1d\x42\xd4\x00\ +\x54\x19\x6c\x3c\x3c\x3c\x3c\x3c\xbc\xcc\x79\xf1\xb7\x06\xd6\xf7\ +\x5c\x34\x28\x7c\x28\x60\x32\xd6\x00\x54\x18\x6c\x3c\x3c\x3c\x3c\ +\x3c\xbc\x4c\x7a\xf5\x58\x03\x50\xe9\xf7\xd0\x5f\xbc\x01\x58\xcb\ +\x72\x85\x1c\x3c\x3c\x3c\x3c\x3c\x3c\xbc\xf1\x7a\x51\x03\x50\xed\ +\x59\xcf\xc3\x5f\x9a\x88\xbd\x23\x48\xf1\xc7\xc3\xc3\xc3\xc3\xc3\ +\xcb\xae\x57\x4f\xf4\x0c\x5f\xac\x01\x28\x51\xfc\xf1\xf0\xf0\xf0\ +\xf0\xf0\x32\xef\x25\x7b\x7b\x2f\xd6\x00\x50\xfc\xf1\xf0\xf0\xf0\ +\xf0\xf0\x8a\xe2\xad\x71\x47\x21\x06\x1b\x0f\x0f\x0f\x0f\x0f\x2f\ +\xe3\x1e\x83\x83\x87\x87\x87\x87\x87\x47\xf1\x67\x70\xf0\xf0\xf0\ +\xf0\xf0\xf0\x28\xfe\x0c\x36\x1e\x1e\x1e\x1e\x1e\x1e\xc5\x9f\xc1\ +\xc6\xc3\xc3\xc3\xc3\xc3\xa3\xf8\xe3\xe1\xe1\xe1\xe1\xe1\xe1\x51\ +\xfc\xf1\xf0\xf0\xf0\xf0\xf0\xf0\xd2\x58\xfc\x13\xbf\xfd\xc7\x60\ +\xe3\xe1\xe1\xe1\xe1\xe1\xe5\xc2\x8b\x96\xfe\x4f\xbc\x48\x50\x8d\ +\xc1\xc6\xc3\xc3\xc3\xc3\xc3\xcb\x7c\xf1\x2f\x25\x6a\x00\x62\xfb\ +\x09\xd7\x19\x6c\x3c\x3c\x3c\x3c\x3c\xbc\x4c\x17\xff\x68\xbf\x9f\ +\xde\x0d\x40\xf8\xe5\x6a\x78\xf6\x5f\x67\xb0\xf1\xf0\xf0\xf0\xf0\ +\xf0\x32\x5b\xfc\xcb\xe1\x6e\xbf\x93\x3d\x97\xfe\x0f\xbf\x5c\x09\ +\xcf\xfe\x6b\xb1\xbd\x85\x19\x6c\x3c\x3c\x3c\x3c\x3c\xbc\x6c\x79\ +\x95\xf0\x73\xa8\x01\xe8\xd7\x29\xac\x8f\x35\x00\x35\x06\x1b\x0f\ +\x0f\x0f\x0f\x0f\x2f\x73\x5e\x35\xac\xe7\x51\x03\x50\xea\x77\x8f\ +\xa0\x12\x6b\x00\xa6\x19\x6c\x3c\x3c\x3c\x3c\x3c\xbc\xcc\x79\x51\ +\x0d\x8f\x1a\x80\xc9\x5e\x97\xfe\x4b\x61\x87\x10\x35\x00\x55\x06\ +\x1b\x0f\x0f\x0f\x0f\x0f\x2f\x73\x5e\x74\xf5\x3e\x6a\x00\xca\xbd\ +\x8a\xff\x44\xd8\x1d\x4c\xc5\xee\x17\x30\xd8\x78\x78\x78\x78\x78\ +\x78\xd9\xf3\xea\xb1\x06\xa0\xd2\xef\xa1\xbf\x78\x03\x50\x4e\xbc\ +\x4a\x10\x83\x8d\x87\x87\x87\x87\x87\x97\x36\x2f\x6a\x00\xaa\x3d\ +\xeb\x79\xf8\x4b\x13\xb1\x77\x04\x29\xfe\x78\x78\x78\x78\x78\x78\ +\xd9\xf5\xea\x89\x9e\xe1\x8b\x35\x00\x25\x8a\x3f\x1e\x1e\x1e\x1e\ +\x1e\x5e\xe6\xbd\x64\x6f\xef\xc5\x1a\x00\x8a\x3f\x1e\x1e\x1e\x1e\ +\x1e\x5e\x51\xbc\xd5\x16\x7e\x06\x1b\x0f\x0f\x0f\x0f\x0f\x2f\x1f\ +\x1e\x83\x83\x87\x87\x87\x87\x87\x47\xf1\x67\x70\xf0\xf0\xf0\xf0\ +\xf0\xf0\x28\xfe\x0c\x36\x1e\x1e\x1e\x1e\x1e\x1e\xc5\x9f\xc1\xc6\ +\xc3\xc3\xc3\xc3\xc3\xa3\xf8\xe3\xe1\xe1\xe1\xe1\xe1\xe1\x51\xfc\ +\xf1\xf0\xf0\xf0\xf0\xf0\xf0\xd2\x58\xfc\x13\xbf\xfd\xc7\x60\xe3\ +\xe1\xe1\xe1\xe1\xe1\xe5\xc2\x8b\x96\xfe\x4f\xbc\x48\x50\x8d\xc1\ +\xc6\xc3\x1b\xaf\xb7\x75\xeb\xf9\x65\x45\x76\x1f\xa4\x5a\xdd\xd3\ +\x85\xe9\xee\x68\x98\xee\xa2\x66\xba\xcf\x12\xa6\xf7\x32\xcd\x72\ +\x5f\xa7\x99\xde\x3b\x34\xcb\xfb\xa0\x6a\x3a\x9f\x51\x2d\xe7\x3f\ +\xfd\xff\x7c\xb9\x2a\xbd\x1f\x0b\xd3\xb9\x56\x18\xce\x8d\xc2\xb4\ +\x6f\x51\x0c\xfb\x36\xff\x73\x87\xff\xff\xfd\x7f\xf1\x8f\x2a\x9d\ +\x3b\xfc\xcf\x6d\xfe\xef\xdd\xa2\x49\xef\x06\xff\x9f\xbf\xd0\x2c\ +\xe7\xaa\xc0\xf0\x3f\x5f\x0d\xcc\xc0\x16\x96\xfb\x0e\xd5\xe8\xbc\ +\x41\x95\xed\x57\xaa\x46\xfb\xf9\x8a\xd1\xde\xed\xff\xb3\xa9\xea\ +\xce\x13\x74\xdd\x3b\x49\xd7\xf5\x29\x8e\x2f\x1e\x5e\xaa\x8b\x7f\ +\x29\x51\x03\x10\xdb\x4f\xb8\xce\x60\xe3\xe1\x0d\xdf\xdb\xbc\xf9\ +\x8c\x63\x94\x46\xeb\x89\x7e\x81\xfd\x63\xd5\xb0\xff\xce\x2f\xd6\ +\x1f\xf7\x8b\xfb\x77\x34\xe9\xfc\xfa\xf0\xa2\x9d\xe4\xe3\x17\xff\ +\xbb\x7d\x56\xe3\xac\xc4\x53\x2d\xef\x7f\x82\x7f\x67\x55\xba\x1f\ +\xf1\x9b\x93\xd7\xfa\xcd\x83\xab\xb4\xdc\x47\xfb\x7f\xc5\x75\xc4\ +\x0b\x1e\xde\x58\x8b\x7f\xb4\xdf\x4f\xef\x06\x20\xfc\x72\x35\x3c\ +\xfb\xaf\x33\xd8\x78\x78\xc3\xf3\xfc\xc2\xf9\x54\xff\x4c\xfa\xcd\ +\x07\xcf\xd6\x47\x58\xac\x47\xea\x49\xe7\x1a\xff\x77\xfe\xd6\x6f\ +\x10\x9e\x44\xbc\xe0\xe1\x8d\xbc\xf8\x97\xc3\xdd\x7e\x27\x7b\x2e\ +\xfd\x1f\x7e\xb9\x12\x9e\xfd\xd7\x62\x7b\x0b\x33\xd8\x78\x78\x83\ +\xf3\xd6\x09\xcb\x35\x55\xcb\xfd\x46\xea\x8a\xf5\xd0\x3d\xfb\x5b\ +\x8a\xb1\xb4\xb8\x79\xf3\x19\xf7\x24\x5e\xf0\xf0\x86\xee\x55\xc2\ +\xcf\xa1\x06\xa0\x5f\xa7\xb0\x3e\xd6\x00\xd4\x18\x6c\x3c\xbc\xc1\ +\x79\x0d\xe9\x3e\x59\xb3\x9c\xaf\x67\xa3\x58\x0f\xcf\x53\x64\xfb\ +\x1b\x6a\x73\xe7\xd3\x88\x17\x3c\xbc\xa1\x79\xd5\xb0\x9e\x47\x0d\ +\x40\xa9\xdf\x3d\x82\x4a\xac\x01\x98\x66\xb0\xf1\xf0\x06\xe3\x05\ +\x0f\xf2\x69\x96\xfb\x57\xc1\x43\x77\x45\x2f\xfe\xd1\x27\x1c\x8b\ +\x57\x79\x9e\x37\x49\xbc\xe0\xe1\x0d\xd4\x8b\x6a\x78\xd4\x00\x4c\ +\xf6\xba\xf4\x5f\x0a\x3b\x84\xa8\x01\xa8\x32\xd8\x78\x78\x83\xf1\ +\xc4\xbc\x73\xa2\x26\xdd\xaf\x64\xb9\x58\x0f\xd3\x13\x96\xf3\x65\ +\x31\xef\x9e\x40\xbc\xe0\xe1\x0d\xc4\x8b\xae\xde\x47\x0d\x40\xb9\ +\x57\xf1\x9f\x08\xbb\x83\xa9\xd8\xfd\x02\x06\x1b\x0f\x6f\x00\x9e\ +\x5f\xe0\x1e\xa1\x5a\xce\xcf\x28\xfe\xbd\x3d\x7f\x8c\xae\x0e\xc6\ +\x8a\xf8\xc3\xc3\x5b\xb3\x57\x8f\x35\x00\x95\x7e\x0f\xfd\xc5\x1b\ +\x80\x72\xe2\x55\x82\x18\x6c\x3c\xbc\x04\xc5\xdf\xfb\x15\xc5\x3f\ +\xb1\xf7\x4b\x55\x3a\x0f\x23\xfe\xf0\xf0\xd6\xe4\x45\x0d\x40\xb5\ +\x67\x3d\x0f\x7f\x69\x22\xf6\x8e\x20\xc5\x1f\x0f\x6f\x00\xde\x9c\ +\x69\xdf\x2f\x3c\xab\xa5\xf8\xaf\xc0\x0b\x16\x30\x9a\x35\x3b\xc7\ +\x13\x7f\x78\x78\xab\xf6\xea\x89\x9e\xe1\x8b\x35\x00\x25\x8a\x3f\ +\x1e\xde\x60\xbc\xe0\xa1\x36\x4d\x3a\x5f\xa4\xf8\xaf\x7a\xdd\x80\ +\x4b\x37\x6d\xda\x57\x22\xfe\xf0\xf0\x56\xe5\x25\x7b\x7b\x2f\xd6\ +\x00\x50\xfc\xf1\xf0\x06\xe4\x69\xa6\xfb\x17\x14\xff\x35\x7a\xa6\ +\xf3\x12\xe2\x0f\x0f\x6f\x88\xde\x6a\x0b\x3f\x83\x8d\x87\xb7\xfc\ +\x4f\xc3\xdc\xfd\x38\xd5\xf2\x6e\xa7\xf8\xaf\xd5\x73\xf6\x2b\x8d\ +\xf9\x27\x11\x7f\x78\x78\xc3\xf7\x18\x1c\x3c\xbc\x01\x78\xaa\xe9\ +\x7e\x9e\xe2\x3f\x18\x4f\x95\xf6\xa5\xc4\x1f\x1e\x1e\xc5\x1f\x0f\ +\x2f\xfd\xc5\x5f\xba\xdb\x28\xfe\x03\x5e\x31\xb0\xb9\xa4\x12\x7f\ +\x78\x78\x14\x7f\x3c\xbc\x54\x7b\xaa\xe9\x7c\x8e\xe2\x3f\x68\xaf\ +\x73\x09\xf1\x87\x87\x47\xf1\xc7\xc3\x4b\x6f\xf1\xd7\xbd\xc7\x50\ +\xac\x87\xe3\x1d\x69\x6d\x00\xe2\x0f\x0f\x8f\xe2\x8f\x87\x37\x76\ +\x4f\x95\xf6\xc5\x14\xeb\x21\x79\xa6\xf3\x12\xe2\x0f\x0f\x8f\xe2\ +\x8f\x87\x97\x4a\x4f\x98\x9d\xef\x51\xac\x87\xe4\x49\xe7\xdb\xc4\ +\x1f\x1e\xde\x60\x8a\x7f\xe2\xb7\xff\x18\x6c\x3c\xbc\xfe\xde\x8c\ +\x66\x3c\x9c\x62\x3d\x5c\x4f\x2c\xec\xbe\x0f\xf1\x87\x87\xb7\x26\ +\x2f\x5a\xfa\x3f\xf1\x22\x41\x35\x06\x1b\x0f\xaf\xb7\xa7\xe8\xbb\ +\xe6\x29\xd6\xc3\xf5\x84\xe9\xce\x11\x7f\x78\x78\x6b\x2a\xfe\xa5\ +\x44\x0d\x40\x6c\x3f\xe1\x3a\x83\x8d\x87\xd7\xdb\x53\x65\xfb\xcf\ +\x29\xd6\xc3\xf6\xdc\x17\x10\x7f\x78\x78\xab\x2e\xfe\xd1\x7e\x3f\ +\xbd\x1b\x80\xf0\xcb\xd5\xf0\xec\xbf\xce\x60\xe3\xe1\xf5\xf6\x84\ +\x61\xbf\x9d\x62\x3d\x5c\x4f\x98\xee\x9b\x89\x3f\x3c\xbc\x55\x15\ +\xff\x72\xb8\xdb\xef\x64\xcf\xa5\xff\xc3\x2f\x57\xc2\xb3\xff\x5a\ +\x6c\x6f\x61\x06\x1b\x0f\xef\x08\x9e\x7f\x76\xfa\x49\x8a\xf5\xd0\ +\xbd\x8f\x12\x7f\x78\x78\x2b\xf6\x2a\xe1\xe7\x50\x03\xd0\xaf\x53\ +\x58\x1f\x6b\x00\x6a\x0c\x36\x1e\x5e\x6f\x4f\xb5\xbc\xff\xa2\x58\ +\x0f\xd9\x93\xde\xd7\x88\x3f\x3c\xbc\x15\x79\xd5\xb0\x9e\x47\x0d\ +\x40\xa9\xdf\x3d\x82\x4a\xac\x01\x98\x66\xb0\xf1\xf0\xfa\x7b\x7e\ +\x81\xfa\x25\xc5\x7a\xd8\x5b\x04\x7b\x3f\x25\xfe\xf0\xf0\x12\x7b\ +\x51\x0d\x8f\x1a\x80\xc9\x5e\x97\xfe\x4b\x61\x87\x10\x35\x00\x55\ +\x06\x1b\x0f\xaf\xbf\xb7\x6f\xdf\xbe\xa3\xa3\xdd\xff\x28\xd6\xc3\ +\xf4\x9c\x5b\x89\x3f\x3c\xbc\x44\x5e\x74\xf5\x3e\x6a\x00\xca\xbd\ +\x8a\xff\x44\xd8\x1d\x4c\xc5\xee\x17\x30\xd8\x78\x78\x09\xbc\x66\ +\xb3\x7d\x1c\xc5\x7a\x34\xde\xdc\xc2\xfc\x06\xe2\x0f\x0f\xaf\xaf\ +\x57\x8f\x35\x00\x95\x7e\x0f\xfd\xc5\x1b\x80\x72\xe2\x55\x82\x18\ +\x6c\x3c\xbc\xa3\x1a\xa6\x73\x2a\xc5\x7a\x34\xde\xac\xd6\xfa\x03\ +\xe2\x0f\x0f\xaf\xaf\x17\x35\x00\xd5\x9e\xf5\x3c\xfc\xa5\x89\xd8\ +\x3b\x82\x14\x7f\x3c\xbc\x15\x78\x5a\xcb\x3d\x93\x62\x3d\x1a\x6f\ +\x56\xdf\xb5\x95\xf8\xc3\xc3\xeb\xeb\xd5\x13\x3d\xc3\x17\x6b\x00\ +\x4a\x14\x7f\x3c\xbc\x95\x7b\xc2\x72\x4d\x8a\xf5\x68\x3c\xd5\x58\ +\xdc\x49\xfc\xe1\xe1\xf5\xf5\x92\xbd\xbd\x17\x6b\x00\x28\xfe\x78\ +\x78\xab\xf0\x84\xe9\x3e\x83\x62\x3d\x1a\x4f\x35\x96\x2e\x24\xfe\ +\xf0\xf0\x06\xe4\xad\xb6\xf0\x33\xd8\x78\x78\xe1\x2d\x00\xd3\xfd\ +\x73\x8a\xf5\x68\x3c\x55\xb6\x5f\x41\xfc\xe1\xe1\xb1\x45\x30\x1e\ +\x5e\x2a\x3c\x4d\x3a\x6f\xa2\x58\x8f\xc6\x13\x66\xe7\xef\x88\x3f\ +\x3c\x3c\x8a\x3f\x1e\x5e\x2a\x3c\x21\xdd\x0f\x51\xac\x47\xe4\x99\ +\xee\xfb\x88\x3f\x3c\x3c\x8a\x3f\x1e\x5e\x2a\x3c\x61\x39\x5f\xa6\ +\x58\x8f\xc8\x93\xce\xa5\xc4\x1f\x1e\x1e\xc5\x1f\x0f\x2f\x15\x9e\ +\x66\x39\x57\x51\xac\x47\xe3\xa9\xd2\xf9\x01\xf1\x87\x87\x47\xf1\ +\xc7\xc3\x4b\x85\xe7\x37\x00\x37\x53\xac\x47\xe3\xa9\x96\x77\x23\ +\xf1\x87\x87\x47\xf1\xc7\xc3\x1b\xbb\xb7\xb0\xb0\x30\x4d\xb1\x1e\ +\xad\xb7\x75\xeb\xf9\x65\xe2\x0f\x0f\x6f\xf5\xc5\x3f\xf1\xdb\x7f\ +\x0c\x36\x1e\xde\x91\x7f\x84\xd5\x3d\x99\x62\x3d\x5a\x4f\x91\x7b\ +\x1e\x40\xfc\xe1\xe1\xad\xae\xf0\x87\xeb\xfe\x24\x5e\x24\xa8\xc6\ +\x60\xe3\xe1\x2d\xef\xcd\x19\x3b\xcf\xa2\x58\x8f\xd6\x53\x5b\xce\ +\xe3\x89\x3f\x3c\xbc\x55\x15\xff\x52\xa2\x06\x20\xb6\x9f\x70\x9d\ +\xc1\xc6\xc3\x5b\xde\x9b\x33\x96\x5a\x14\xeb\x51\x7b\xdd\xed\xc4\ +\x1f\x1e\xde\x8a\x8b\x7f\xb4\xdf\x4f\xef\x06\x20\xfc\x72\x35\x3c\ +\xfb\xaf\x33\xd8\x78\x78\xcb\x7b\x73\xfa\xe2\x33\x28\xd6\x23\xf6\ +\x5a\xce\x12\xf1\x87\x87\xb7\xa2\xe2\x5f\x0e\x77\xfb\x9d\xec\xb9\ +\xf4\x7f\xf8\xe5\x4a\x78\xf6\x5f\x8b\xed\x2d\xcc\x60\xe3\xe1\x1d\ +\xe6\xa9\x86\xfd\x32\x8a\xf5\x68\x3d\x61\x79\xcf\x25\xfe\xf0\xf0\ +\x12\x7b\x95\xf0\x73\xa8\x01\xe8\xd7\x29\xac\x8f\x35\x00\x35\x06\ +\x1b\x0f\x6f\x79\x4f\x48\xfb\xef\x29\xd6\xa3\xf5\x84\xe9\xfe\x25\ +\xf1\x87\x87\x97\xc8\xab\x86\xf5\x3c\x6a\x00\x4a\xfd\xee\x11\x54\ +\x62\x0d\xc0\x34\x83\x8d\x87\x77\x64\xcf\x3f\x1b\x7d\x37\xc5\x7a\ +\xc4\x9e\xe9\xbd\x83\xf8\xc3\xc3\xeb\xeb\x45\x35\x3c\x6a\x00\x26\ +\x7b\x5d\xfa\x2f\x85\x1d\x42\xd4\x00\x54\x19\x6c\x3c\xbc\xde\x9e\ +\xb0\xdc\xff\xa0\x58\x8f\xda\x73\x3f\x49\xfc\xe1\xe1\xf5\xf4\xa2\ +\xab\xf7\x51\x03\x50\xee\x55\xfc\x27\xc2\xee\x60\x2a\x76\xbf\x80\ +\xc1\xc6\xc3\xeb\xe3\xf9\x85\xec\x32\x8a\xf5\xa8\x3d\xfb\x3b\xc4\ +\x1f\x1e\x5e\x4f\xaf\x1e\x6b\x00\x2a\xfd\x1e\xfa\x8b\x37\x00\xe5\ +\xc4\xab\x04\x31\xd8\x78\x05\xf7\x34\xe9\x5c\x4f\xb1\x1e\xad\xa7\ +\x98\xf6\x2f\x89\x3f\x3c\xbc\x9e\x5e\xd4\x00\x54\x7b\xd6\xf3\xf0\ +\x97\x26\x62\xef\x08\x52\xfc\xf1\xf0\x12\x78\x9b\x36\xed\x2b\xf9\ +\x45\xe9\x00\xc5\x7a\xd4\x9e\xbd\x7f\xf3\xe6\x33\xee\x49\x3c\xe3\ +\xe1\x1d\xd1\xab\x27\x7a\x86\x2f\xd6\x00\x94\x28\xfe\x78\x78\xc9\ +\x3d\x31\xef\x9e\x40\xb1\x1e\x8f\xb7\x4d\x35\x1e\x4c\x3c\xe3\xe1\ +\x1d\xd1\x4b\xf6\xf6\x5e\xac\x01\xa0\xf8\xe3\xe1\xad\xc0\x13\x46\ +\x77\x23\xc5\x7a\x3c\x5e\xa3\xe5\x9e\x46\x3c\xe3\xe1\xad\xd1\x5b\ +\x6d\xe1\x67\xb0\xf1\x8a\xee\x35\xa4\xfb\x74\x8a\xf5\x98\xbc\x96\ +\x7b\x26\xf1\x8c\x87\xc7\x16\xc1\x78\x78\x63\xf1\x1a\xa6\xb7\x40\ +\xb1\x1e\x93\x27\x3d\x49\x3c\xe3\xe1\x51\xfc\xf1\xf0\xc6\xe2\x69\ +\xa6\xfb\x2c\x8a\xf5\x78\x3c\x61\xba\xcf\x20\x9e\xf1\xf0\x28\xfe\ +\x78\x78\x63\xf1\x84\xe5\x5d\x44\xb1\x1e\x8f\x27\x4c\xef\x65\xc4\ +\x33\x1e\x1e\xc5\x1f\x0f\x6f\x2c\x9e\x5f\x84\xde\x4a\xb1\x1e\x9b\ +\xf7\x46\xe2\x19\x0f\x8f\xe2\x8f\x87\x37\x16\xcf\x2f\x42\x1f\xa5\ +\x58\x8f\xcd\xfb\x20\xf1\x8c\x87\x47\xf1\xc7\xc3\x1b\x8b\xa7\x49\ +\xef\x6b\x14\xeb\x31\x79\xa6\xf7\x25\xe2\x19\x0f\x6f\xd5\x35\x7d\ +\x1d\x83\x93\x51\x6f\x76\x76\xfb\x06\x45\xb1\x4e\x53\x1a\xad\xa7\ +\xcc\xea\xf3\x9b\x94\xc6\xfc\x93\x84\xb5\xf4\x60\x5d\xd7\xa7\x18\ +\xbf\xd1\x79\x7e\x03\xf0\x53\x8a\xf5\x78\x3c\x61\x7a\x3f\x22\x9e\ +\x47\xe7\x2d\x2c\xb4\xca\x62\xde\x39\xb1\x61\x3a\xa7\x2a\x2d\xe7\ +\xb1\xcd\xf9\xee\xa3\x82\x85\xb0\xfc\x9c\x33\xc1\xf8\x65\xca\x8b\ +\x96\xfe\x4f\xbc\x48\x50\x8d\xc1\x1e\xaf\xd7\x9c\xdf\xfd\x70\x3f\ +\xe1\x3d\x53\xb3\xdc\xf7\x2a\x46\xe7\x2a\xc5\xb0\xef\x38\x42\xb2\ +\x3c\xa0\x59\xce\x55\x42\x3a\x1f\x10\xd2\x7d\xb6\x30\x76\x9f\xc6\ +\xf8\x0d\xcf\xf3\xc7\xfa\x56\x8a\xf5\x78\x3c\x21\xbd\xdf\x12\xcf\ +\xc3\xf3\x66\x35\xeb\x74\x45\x5f\x7a\xbe\x30\xec\x0f\xaa\xd2\xfd\ +\xa1\x6a\x79\xb7\x2f\x7f\x2c\x9c\xfd\xfe\x3f\xbf\xaf\x99\xde\x3b\ +\x85\xe5\xee\xd5\x5a\x7b\x1e\xc2\xf8\xa5\xba\xf8\x97\x12\x35\x00\ +\xb1\xfd\x84\xeb\x0c\xf6\xe8\x3d\x65\x71\xf1\x9e\xfe\xc4\xba\xd0\ +\x9f\x78\xdf\x5d\xdb\x99\x92\xfb\x3d\x61\x79\xcf\x55\x77\x9e\x7b\ +\x2f\x8e\xc7\xe0\xbc\xb9\x85\xf9\x0d\x14\xeb\xf1\x7a\x0b\x0b\x0b\ +\xd3\xc4\xf3\xe0\xbc\x1d\x9a\xf9\x20\xd5\x68\xff\xa9\x30\x3b\xdf\ +\x5b\xdb\xf1\x75\xbe\xee\xe7\x9d\xf3\xb6\x69\xea\xfd\x38\x1e\xa9\ +\x2a\xfe\xd1\x7e\x3f\xbd\x1b\x80\xf0\xcb\xd5\xf0\xec\xbf\xce\x60\ +\x8f\xce\x3b\x58\xf8\x4d\xf7\x2f\x54\xcb\xb9\x69\xb0\xc9\xd7\xb9\ +\xd9\x37\x2f\x6e\x36\x3b\x1b\x38\x1e\x03\xb8\x0d\xa3\xb5\xfe\x80\ +\x62\x3d\x5e\xaf\xb9\xe0\x3c\x98\xfc\x32\x80\x2b\x59\xda\xe2\xbd\ +\x15\xd9\x7e\x8d\x30\xed\x5b\x06\x7a\x7c\x0d\xe7\x46\x55\xb6\xff\ +\x62\xc7\x0e\xed\xfe\x1c\x8f\xb1\x17\xff\x72\xb8\xdb\xef\x64\xcf\ +\xa5\xff\xc3\x2f\x57\xc2\xb3\xff\x5a\x6c\x6f\x61\x06\x7b\xc8\x9e\ +\xb0\xba\xbb\x96\xdb\x5e\x76\x90\xc9\x57\xb5\xbc\xff\x11\xfa\xd2\ +\x5e\x8e\xc7\xda\x3c\xb5\xb1\xb0\x8d\x62\x3d\x5e\x4f\xcc\x3b\x4f\ +\x24\xbf\xac\xcd\x13\x96\xe3\x0a\xc3\xbe\x61\xa8\xc7\xd7\xb0\x7f\ +\x21\x2c\xd7\xe0\x78\x8c\xcd\xab\x84\x9f\x43\x0d\x40\xbf\x4e\x61\ +\x7d\xac\x01\xa8\x31\xd8\xc3\xf5\x76\xb4\xf6\x1c\xeb\x9f\xf5\xff\ +\xeb\x28\x93\xaf\xdf\x99\x7f\x7a\x87\xda\x3a\x95\xe3\xb1\x3a\x4f\ +\x35\x16\x77\x52\xac\xc7\xeb\x09\xe9\x28\xe4\x97\xd5\x79\xba\xee\ +\x9d\xa4\x59\xee\x27\x47\x79\x7c\x55\xcb\xf9\x27\x5d\xdf\x5b\xe3\ +\x78\x8c\xd4\xab\x86\xf5\x3c\x6a\x00\x4a\xfd\xee\x11\x54\x62\x0d\ +\xc0\x34\x83\x3d\x5c\xcf\x9f\x18\x8f\xd0\x2c\xe7\xca\xb1\x24\x5f\ +\xe9\xdc\xe4\x9f\x01\xec\xe6\x78\xac\xdc\x53\x8d\xa5\x0b\x29\xd6\ +\xe3\xf5\x14\x63\xe9\x3c\xf2\xcb\x8a\xbd\x75\xaa\xe9\xed\xd6\x4c\ +\xef\x7f\xc7\x71\x7c\x83\x67\x9a\x14\xd9\x7d\x10\xc7\x63\x24\x5e\ +\x54\xc3\xa3\x06\x60\xb2\xd7\xa5\xff\x52\xd8\x21\x44\x0d\x40\x95\ +\xc1\x1e\xae\xa7\xb6\x9c\xc7\x07\x97\xe4\xc7\x9d\x7c\xfd\x84\xf0\ +\x49\xad\x65\x3f\x90\xe3\x9b\xdc\x53\x65\xfb\x15\x14\xeb\xf1\x7a\ +\xfe\x31\x78\x29\xf9\x25\xf9\x4f\x50\x78\xfd\x86\xff\x53\x63\x3f\ +\xbe\xd2\xb9\x26\x78\x8d\x90\xfc\x32\x54\x2f\xba\x7a\x1f\x35\x00\ +\xe5\x5e\xc5\x7f\x22\xec\x0e\xa6\x62\xf7\x0b\x18\xec\x21\x7a\x0d\ +\x73\xf7\xe3\x34\xe9\xdd\x90\x96\xe4\x7b\xe7\x43\x87\xee\x9e\xe0\ +\x0c\x81\xe3\xdb\xdf\x13\x66\xe7\xef\x28\xd6\x63\xf6\xe4\xd2\xdf\ +\x93\x5f\x92\x9d\xf5\x07\xaf\xe8\x45\x0f\x16\xa7\xe4\xf8\xfe\x32\ +\xb8\xfa\x49\x7e\x19\x9a\x57\x8f\x35\x00\x95\x7e\x0f\xfd\xc5\x1b\ +\x80\x72\xe2\x55\x82\x18\xec\x55\x79\x4a\xcb\x7d\xf4\x72\x0f\xfb\ +\xa5\x61\x72\xaa\xa6\xf3\x99\xe8\xe9\x6a\x8e\xef\x91\x3d\xcd\x74\ +\xdf\x47\xb1\x1e\xaf\xa7\x48\xfb\x7d\xe4\x97\xde\x3f\xc1\x5c\x0e\ +\xe6\x74\x2a\x8f\x6f\x70\x25\x60\xa1\x73\x32\xf9\x65\x28\x5e\xd4\ +\x00\x54\x7b\xd6\xf3\xf0\x97\x26\x62\xef\x08\x52\xfc\x87\x79\xd9\ +\x5f\x3a\x0f\x0b\xbb\xdf\x54\x2f\xb2\x22\x4c\xef\xdc\xf8\xd5\x00\ +\x8e\xef\x5d\x3d\x3f\x79\x5d\x4a\xb1\x1e\xaf\xa7\xc8\xf6\x25\xe4\ +\x97\x23\x9f\xf5\x6b\x96\x7b\x5e\x30\x97\xd3\x7c\x7c\x55\xcb\xb9\ +\x3a\x78\x20\x91\xfc\x32\x70\xaf\x9e\xe8\x19\xbe\x58\x03\x50\xa2\ +\xf8\x0f\xd7\x0b\xee\xb3\xfb\x93\xf2\x27\x59\x49\xbe\xc2\x72\xff\ +\x23\x58\xd9\x8b\xe3\x7b\x77\xcf\x6f\xe4\x7e\x40\xb1\x1e\xaf\xe7\ +\x7f\x2e\x23\xbf\x2c\x77\x92\xe1\x3e\x54\x93\xde\x67\x33\xf3\x36\ +\x87\xe9\x5d\xa1\x28\xad\x93\xc9\x2f\x03\xf5\x92\xbd\xbd\x17\x6b\ +\x00\x28\xfe\x43\xf4\xc4\xc2\xee\xfb\x1c\xa9\x68\xa4\xfb\x55\x2b\ +\xef\xb7\x8a\xd1\xfe\x93\xcd\x9b\xcf\xb8\x27\xc7\x37\x6a\xe4\xf6\ +\x3c\x24\x78\x8a\x9a\x62\x3d\x66\x4f\x7a\x37\x1c\xe9\x76\x55\x41\ +\xf3\xd5\x3a\x61\xba\xcf\x08\x16\xfd\xca\xdc\xf1\x35\xda\x97\x6d\ +\x55\xf4\x07\x92\x5f\x46\xec\xad\xb6\xf0\x33\xd8\xc9\xbd\xf9\xf9\ +\xf3\xeb\x7e\xb2\xfa\x66\x96\x93\xaf\xdf\x04\x7c\x41\xd1\xcd\xc7\ +\x15\xf5\xf8\x06\x85\x46\x33\xdd\xe7\xa9\x96\xfb\x0d\x8a\x75\xba\ +\xbc\x83\xc7\xc4\x3f\x36\xfd\x9a\x81\x3c\xe7\xab\xe0\x5e\xba\xb0\ +\xbc\xcf\x65\xf9\xf8\xaa\xb2\xf3\xe5\x2d\x5b\xd4\xe3\xa9\x1f\xe3\ +\xf1\x18\x9c\x21\x78\x5b\xb7\x9e\x5f\x3e\x78\x29\x3d\x17\xc9\x37\ +\x58\x2a\xd4\xbd\x60\xdf\xbe\x7d\x47\x17\xe1\xf8\x6e\x53\x8d\x07\ +\xfb\x67\x53\xe7\x0b\xcb\xf9\x32\xc5\x3a\x23\x9e\xe9\x7d\x29\x78\ +\x7e\xa5\x28\x7b\x5f\x04\x73\xf1\xce\x8d\xc2\xee\x7a\xd6\x9f\xd5\ +\xe3\xab\x4a\xf7\xa3\x9b\x36\xed\x2b\x51\x3f\x28\xfe\xb9\x98\x9c\ +\x9a\xe5\xbe\x27\x6f\xc9\x57\x35\xdd\xcf\x07\x0f\x33\xe6\xf1\xf8\ +\x6e\xd9\x72\xd6\x06\x45\x5f\xb4\x84\x61\xff\x9b\xff\x77\xbc\x8d\ +\xe2\x9a\x4d\x4f\xb5\xbc\xdf\x07\x6f\x6a\xa8\x2d\x67\x66\x6e\x6e\ +\x66\x32\xaf\x0f\x14\x07\x73\x31\x6f\xc7\x57\x58\xde\xdb\xa8\x1f\ +\x14\xff\xcc\x7b\x7e\xf1\x7f\x4d\x7e\x2f\xbb\x3a\xb7\xf8\x09\xf6\ +\x59\xfd\xae\x06\x64\xe5\xf8\xce\x6a\xc6\x69\xaa\x61\xbf\x4a\x98\ +\x9d\x5f\x50\x5c\x73\xb6\x62\xa0\x69\xff\x5c\x35\x96\x2e\x52\x14\ +\xeb\xb4\x3c\xe4\x97\x83\x27\x16\xfe\xdc\x3b\x38\x07\xf3\x7a\x7c\ +\x4d\xf7\xcf\xa9\x47\x14\xff\xec\x16\x7f\x7f\x82\x16\x22\xf9\x4a\ +\xe7\x8b\xcd\xf9\xdd\x0f\xcf\xe2\xf1\xdd\xb8\xf1\xb4\x89\xb9\xe6\ +\x62\x43\x18\x9d\x8f\x29\x86\x7d\x07\xc5\x35\xe7\xeb\x06\x98\xce\ +\xed\x7e\x93\xf7\xd1\x86\xe1\x6c\x3d\xaa\xcf\x82\x57\x69\x8d\xe7\ +\x60\xae\x05\x73\xae\x08\xc7\x57\x58\x6e\x97\x7a\x44\xf1\xcf\x9c\ +\x27\x5a\x9e\xee\x07\xf0\x81\xa2\x24\x5f\x55\x7a\xbf\xf3\x1b\x9e\ +\x3f\xd1\x75\x7d\x22\x0b\xc7\x37\xd8\x47\x3e\xd8\xaf\x5c\x95\x9d\ +\x1f\x50\x5c\x8b\xe9\xa9\xd2\xf9\xef\x60\x4d\xfc\x99\x19\xaf\x9a\ +\x85\xfc\x12\xcc\x2d\xff\xdf\xfb\x39\x07\xe7\x5a\x41\x8e\xaf\x6a\ +\x79\xb7\x0b\xd3\xdb\x4a\x3d\xa2\xf8\x67\xa7\xf8\xcf\x3b\x4f\x5c\ +\x6e\x92\x16\x21\xf9\x06\x0f\xcb\xf9\x45\xf5\x91\x69\x3d\xbe\xb3\ +\x66\xe7\x78\x61\x79\x2f\xf7\xcf\xa0\x7e\x4d\x31\xc4\x3b\xb4\x3d\ +\xb6\xe9\xbd\x2c\x78\x4d\x37\xad\xf9\xe5\xe0\x86\x61\xa6\xf7\xa5\ +\x42\x1e\xdf\x60\xd3\x22\xa3\xbb\x91\x7a\x34\xd8\xe2\x9f\xf8\xed\ +\x3f\x06\x7b\x05\x97\xfd\x0f\x2e\xf4\x73\xf7\x55\xfe\x8a\x95\x7c\ +\x9d\x5b\x55\x69\xef\x0b\x1e\xa6\x4b\xcb\xf1\x3d\xb8\x09\x8a\xe9\ +\xfc\x6d\xd4\x98\x51\x0c\xf1\x96\xbd\x8a\x25\xbd\xd7\x1f\xbe\x29\ +\xd6\x38\xf3\x4b\x70\xd6\xef\x37\xac\xcf\xed\x75\xd6\x5f\x8c\xe3\ +\xeb\xfe\x44\xd7\xf7\xde\x97\x7a\x34\x10\x2f\x5a\xfa\x3f\xf1\x22\ +\x41\x35\x06\xbb\xbf\x17\xec\x73\xed\x9f\x59\x7e\x9b\xe4\x1b\x6d\ +\xd4\xd2\xf9\xba\xd2\x68\x3d\x71\x9c\xc7\xf7\xe0\xbb\xd1\xa6\xf7\ +\x56\xbf\x29\xd9\x4f\x31\xc4\x4b\x76\x3b\xcb\xb9\x4d\x33\xdd\xb7\ +\x04\xab\xe9\x8d\x33\xbf\x04\xbb\xe5\x69\xd2\xfd\x0a\xc7\x37\x7a\ +\xd6\xc8\xfd\x8a\x10\xdd\x69\x8a\xff\x9a\x8b\x7f\x29\x51\x03\x10\ +\xdb\x4f\xb8\xce\x60\xf7\xfe\xb9\xf3\x75\x3f\xef\x83\x24\x5f\xe7\ +\xf0\x87\xae\x7e\xef\x17\xdf\x17\x8e\xfa\xbd\xde\x60\x41\x98\xe0\ +\x55\xa2\xe0\x1e\x22\xc7\x03\x6f\x95\x57\xb2\xf6\x0b\xc3\x7e\xfb\ +\x0e\xd1\x7a\xf4\x28\xf3\xcb\xc1\x7b\xfd\xa6\xfb\xbc\xe0\x4a\x1a\ +\xc7\xe3\xf0\xe6\xcc\x7e\x0f\xc5\x7f\x4d\xc5\x3f\xda\xef\xa7\x77\ +\x03\x10\x7e\xb9\x1a\x9e\xfd\xd7\x19\xec\xbe\x4f\xfc\xff\x39\xc9\ +\xb7\x97\xe7\x7c\x3d\xd8\x01\x71\xd8\xc7\x43\xcc\xbb\x27\x68\x96\ +\xfb\x77\xcb\xbd\xbf\xcf\xf1\xc0\x5b\xdd\x0a\x98\xf6\x6d\x42\xb7\ +\xdf\xb4\x5d\xd5\x1f\x3a\xec\xfc\x22\x8c\xdd\xa7\xa9\x96\xf3\x9f\ +\x1c\x8f\x23\x7b\xaa\xd1\x7e\x31\xf5\x68\x55\xc5\xbf\x1c\xee\xf6\ +\x3b\xd9\x73\xe9\xff\xf0\xcb\x95\xf0\xec\xbf\x16\xdb\x5b\x98\xc1\ +\x5e\xae\xe8\x98\xdd\x26\x93\x33\xc9\xba\x01\xde\xef\x85\xe5\xbe\ +\xa8\xdf\xd5\x80\xd5\x1c\x8f\x60\xa9\xe5\x83\x0f\xf7\x2d\xb3\x1a\ +\x1a\xc7\x03\x6f\x20\x1b\x0f\x05\xbb\xea\x99\xce\x4b\x82\x5b\x7d\ +\x83\xce\x2f\xc1\x9c\xf0\x1b\xd7\x17\x1c\x5c\xbc\x88\xe3\xd1\xfb\ +\x55\x4e\xc3\xbe\x43\xd1\x17\x75\xea\xd1\x8a\xbc\x4a\xf8\x39\xd4\ +\x00\xf4\xeb\x14\xd6\xc7\x1a\x80\x1a\x83\x7d\x84\xe2\xef\x77\xec\ +\xf1\xed\x36\x49\x96\x49\x5e\xed\x71\xbf\x71\xf8\x53\xbd\x6b\x7b\ +\x35\xca\xdd\xe3\x27\xce\x5f\x91\x2c\xf1\x46\xe4\xfd\x52\x6b\x79\ +\x5e\xfc\x95\xd7\xb5\xe4\x97\xe0\xca\x58\x70\x85\x8c\xe3\xb1\x82\ +\xe5\x82\x2d\xef\xc6\x95\xac\x44\x5a\xf0\xe2\x5f\x0d\xeb\x79\xd4\ +\x00\x94\xfa\xdd\x23\xa8\xc4\x1a\x80\x69\x8a\xff\x91\x1e\xfa\xf3\ +\x8e\x09\xb6\xb1\x64\x72\xae\x66\xdd\x00\xe7\x36\x61\xb9\x7f\xe6\ +\x79\xde\xe4\x6a\x8f\x47\x43\x7a\x67\xf9\xc5\xff\x3b\x24\x4b\xbc\ +\x71\x78\x7e\x11\xfa\x2f\xad\xe5\x9e\xb9\xda\xfc\x12\x9e\xf5\xff\ +\x69\xd2\xb3\x7e\x8e\xc7\x61\xcb\x05\x9b\xce\x65\x2b\xb9\x1a\x53\ +\xd0\xe2\x1f\xd5\xf0\xa8\x01\x98\xec\x75\xe9\xbf\x14\x76\x08\x51\ +\x03\x50\xa5\xf8\x1f\xf1\x67\x9d\x66\x7a\x1f\x66\x72\xae\xd5\x73\ +\xbe\xa5\xb4\x9c\xc7\xae\xec\xd5\x28\xef\xa4\x60\x8d\x77\xc6\x0f\ +\x2f\x1d\x9e\xfb\x1e\x31\xef\x9c\xb8\x92\xfc\x12\x5c\x01\x63\x57\ +\xc9\x81\xec\x02\xf9\x2f\xd4\xa3\x9e\x6f\xef\xd5\x62\x0d\x40\xb9\ +\x57\xf1\x9f\x08\xbb\x83\xa9\xd8\xfd\x02\x8a\xff\x91\x1e\xfa\xb3\ +\xdc\x17\x30\x39\x07\xf9\xb4\xf5\xd2\x45\xdb\xb6\x3d\xfd\xb8\x5e\ +\xc7\x23\xb8\x5a\x10\x3e\x1d\x7d\x33\xe3\x87\x97\x26\x2f\xbc\x0d\ +\xf8\x9c\xe0\xac\xbe\x57\x7e\x09\x62\x38\xb8\xf2\xb5\xd2\x4d\xa6\ +\x38\x1e\x3d\x96\x0b\x36\xdd\x67\x50\xfc\x97\xf5\xea\xb1\x06\xa0\ +\xd2\xef\xa1\xbf\x78\x03\x50\x4e\xbc\x4a\x50\x11\x8b\x7f\xcb\x3d\ +\x33\xfe\x7a\x19\x93\x73\x40\x9e\xd1\xbe\x6c\x56\x9f\xdf\xb4\xdc\ +\xf1\xd0\x5a\xdd\xa7\x04\x97\xfc\x18\x3f\xbc\x34\x7b\xc1\x6d\x81\ +\x39\x63\xe7\x59\xcb\xe5\x97\xe0\x4a\x57\x70\xc5\x8b\xf1\x1b\xf0\ +\x33\x45\xc1\xed\xc4\x79\xe7\x89\x14\xff\xbb\x79\x51\x03\x50\xed\ +\x59\xcf\xc3\x5f\x9a\x88\xbd\x23\x48\xf1\x3f\xe2\x7d\xff\xbd\xf7\ +\x8d\xaf\xf4\xc7\xe4\x1c\xb4\x67\xef\xd7\x4c\xe7\xe5\xba\xae\x4f\ +\x05\xe3\x3d\x67\xdb\xf7\x08\x56\xf0\x5b\x6e\x5f\x05\xc6\x0f\x2f\ +\x8d\xde\xc1\x4d\xa5\x64\xfb\x0d\x73\x73\x3b\xee\x17\xe4\x97\x85\ +\x85\x56\x39\x78\x7b\x20\xbe\x18\x15\xe3\x37\xe0\x67\x8a\x2c\xe7\ +\xea\x66\xb3\xb3\x81\xe2\x7f\xb7\x35\x7b\xa6\x93\x2e\xf8\x33\x11\ +\x3e\x03\x40\xf1\xef\xbd\xd8\xcf\xa7\x99\x9c\x23\xd8\xa8\xc5\xf2\ +\xbe\x1b\xec\x04\x16\x4c\x6c\xc6\x0f\x2f\xa3\xcd\xec\xd5\x5a\xcb\ +\x73\x0e\x3e\x2c\xc8\xf8\x0d\xdf\x33\xbd\x0f\x53\xfc\xef\xe2\xd5\ +\x56\xb2\xdc\xef\x04\xc5\xbf\xcf\x2b\x7f\x96\xfb\x22\x26\x27\x1e\ +\x1e\x1e\x5e\x3a\x3d\x61\xba\x17\x50\xfc\x57\xe8\xad\xb6\xf0\x17\ +\xa9\xf8\x37\xa4\xfb\xe4\xe8\xbe\x3f\x93\x13\x0f\x0f\x0f\x2f\x95\ +\xcf\x60\xfc\x7e\x56\x5f\xf8\x23\x8a\x3f\x5b\x04\x0f\xcc\x0b\xde\ +\xf7\x57\xa5\xf7\x63\x26\x27\x1e\x1e\x1e\x5e\xda\xbd\xce\x15\xe1\ +\xf3\x17\x14\x7f\x8a\xff\xda\x3d\xcd\xf4\xde\xc9\xe4\xc4\xc3\xc3\ +\xc3\xcb\x86\xa7\x1a\xf6\x3f\x52\xfc\x29\xfe\x6b\xf6\x1a\xa6\xb7\ +\xc0\xe4\xc4\xc3\xc3\xc3\xcb\xda\xde\x0d\x1d\x8d\xfa\x46\xf1\x5f\ +\xb5\x17\xac\x38\x17\xac\x39\xcd\x64\xc2\xc3\xc3\xc3\xcb\x98\x27\ +\x9d\xeb\x66\xcd\xce\xf1\xd4\x37\x8a\xff\x6a\xbc\x75\x7e\x10\x7d\ +\x86\xc9\x84\x87\x87\x87\x97\x51\x2f\xf6\x6a\x20\xf5\x8d\xe2\x9f\ +\xfc\xbe\xbf\xe5\x9c\xcf\x64\xc2\xc3\xc3\xc3\xcb\xb6\xd7\x30\x5d\ +\x9b\xfa\xb6\x86\xb7\xff\x8a\x36\x38\x8a\xd1\x39\x45\x98\xf6\x2d\ +\x4c\x26\x3c\x3c\x3c\xbc\x8c\xef\x15\x20\x9d\xdf\x28\x72\xcf\x03\ +\xa8\x6f\xff\x57\xf8\xc3\x75\x7f\x12\x2f\x12\x54\x2b\xca\xe0\x6c\ +\xdc\x78\xda\x84\x22\xdb\x9f\x67\x32\xe1\xe1\xe1\xe1\xe5\xc3\x13\ +\x96\xf3\x71\x8a\xff\xa1\xe2\x5f\x4a\xd4\x00\xc4\xf6\x13\xae\x17\ +\x65\x51\x05\xc5\x68\x3f\x8b\xc9\x84\x87\x87\x87\x97\x2f\xef\xf0\ +\x5b\x01\x05\x2d\xfe\xd1\x7e\x3f\xbd\x1b\x80\xf0\xcb\xd5\xf0\xec\ +\xbf\x5e\x88\xe2\xaf\xb4\x1e\x25\xa4\x73\x13\x93\x09\x0f\x0f\x0f\ +\x2f\x67\x9e\xf4\x6e\x10\xf3\xee\x09\x05\x2e\xfe\xe5\x70\xb7\xdf\ +\xc9\x9e\x4b\xff\x87\x5f\xae\x84\x67\xff\xb5\xd8\xde\xc2\xb9\x5e\ +\x54\x41\xd5\xed\x7f\x67\x32\xe1\xe1\xe1\xe1\xe5\x74\xaf\x00\xe9\ +\xbd\xb7\xa0\x7b\x05\x54\xc2\xcf\xa1\x06\xa0\x5f\xa7\xb0\x3e\xd6\ +\x00\xd4\xf2\x5e\xfc\xe7\x9a\xbb\x9a\x4c\x26\x3c\x3c\x3c\xbc\x7c\ +\x7b\x6a\x73\x71\xb6\x60\xc5\xbf\x1a\xd6\xf3\xa8\x01\x28\xf5\xbb\ +\x47\x50\x89\x35\x00\xd3\x79\x2f\xfe\x9b\x37\x9f\x71\x4f\x21\xed\ +\xcb\x99\x4c\x78\x78\x78\x78\x39\xf7\x8c\xce\x37\x0b\x54\xfc\xa3\ +\x1a\x1e\x35\x00\x93\xbd\x2e\xfd\x97\xc2\x0e\x21\x6a\x00\xaa\x45\ +\x58\x4b\x79\xce\xd8\x25\x99\x4c\x78\x78\x78\x78\x05\xd9\x2b\xa0\ +\xb1\x4b\x14\xa0\xf8\x47\x57\xef\xa3\x06\xa0\xdc\xab\xf8\x4f\x84\ +\xdd\xc1\x54\xec\x7e\x41\x21\x36\x52\x50\x65\xfb\xd3\x4c\x26\x3c\ +\x3c\x3c\xbc\x82\x78\xb2\xf3\x91\x02\xd4\xb7\x7a\xac\x01\xa8\xf4\ +\x7b\xe8\x2f\xde\x00\x94\x13\xaf\x12\x94\xf1\xe2\xbf\x5d\xd5\x1f\ +\xa1\x18\xf6\x1d\x4c\x26\x3c\x3c\x3c\xbc\xa2\x78\xce\xfe\x19\xcb\ +\xbb\x77\xce\xeb\x5b\xd4\x00\x54\x7b\xd6\xf3\xf0\x97\x26\x62\xef\ +\x08\x16\xa2\xf8\x1f\x3c\xfb\x37\xda\x17\x30\x99\xf0\xf0\xf0\xf0\ +\x8a\xe5\x09\xcb\x6b\xe7\xbc\xbe\xd5\x13\x3d\xc3\x17\x6b\x00\x4a\ +\x45\x2a\xfe\xc1\x7f\xf7\x03\xe1\x03\x4c\x26\x3c\x3c\x3c\xbc\xc2\ +\x6d\x14\xf4\xce\x9c\xd7\xb7\xda\x4a\x96\xfb\x9d\x28\x5a\xf1\x0f\ +\xfe\x77\xd5\x72\x7e\xc1\x64\xc2\xc3\xc3\xc3\x2b\x96\xa7\x4a\xef\ +\xc7\xec\x85\x73\xd4\x0a\x76\x05\xca\xd9\xe0\x88\x85\xdd\xf7\x61\ +\x32\xe1\xe1\xe1\xe1\x15\xd3\x9b\x9f\x3f\xbf\x5e\xe8\xe2\xbf\x96\ +\x9f\xac\x0f\x4e\x43\xba\x4f\x66\x32\xe1\xe1\xe1\xe1\x15\xd3\x6b\ +\x98\xbb\x1f\x47\xf1\x2f\x60\xf1\x0f\x7e\xd4\x96\xa7\x31\x99\xf0\ +\xf0\xf0\xf0\x8a\xea\x75\xb7\x53\xfc\x0b\x58\xfc\x83\x1f\xad\xe5\ +\x2c\x31\x99\xf0\xf0\xf0\xf0\x8a\xe9\x09\xcb\x35\x29\xfe\x05\x2c\ +\xfe\x07\x6f\x01\x98\xae\xcd\x64\xc2\xc3\xc3\xc3\x2b\xa8\x27\xdd\ +\x16\xc5\xbf\x80\xc5\x3f\xf8\x11\x96\x33\xcf\x64\xc2\xc3\xc3\xc3\ +\x2b\xaa\xe7\x36\x28\xfe\x05\x7d\x15\x42\xb3\x9c\x2d\x4c\x26\x3c\ +\x3c\x3c\xbc\x82\x7a\x2d\xf7\xcc\xa2\x16\xff\xc4\x6f\xff\xe5\x75\ +\x70\x1a\xa6\x73\x2a\x93\x09\x0f\x0f\x0f\xaf\xa8\x5e\xf7\x94\xa2\ +\x15\xff\xd8\xd2\xff\x89\x17\x09\xaa\xe5\x71\x70\x74\x5d\x9f\x52\ +\x2d\xef\x76\x26\x13\x1e\x1e\x1e\x5e\xd1\x3c\xe7\xd6\x33\xcf\xdc\ +\x33\x55\xc0\xe2\x5f\x4a\xd4\x00\xc4\xf6\x13\xae\xe7\x75\x70\xfc\ +\x20\xf8\x16\x93\x09\x0f\x0f\x0f\xaf\x60\x9e\x74\xbf\x52\xc0\xe2\ +\x1f\xed\xf7\xd3\xbb\x01\x08\xbf\x5c\x0d\xcf\xfe\xeb\x79\x1d\x1c\ +\x61\x7a\x7f\xcd\x64\xc2\xc3\xc3\xc3\x2b\x98\x27\xed\xbf\x29\x58\ +\xf1\x2f\x87\xbb\xfd\x4e\xf6\x5c\xfa\x3f\xfc\x72\x25\x3c\xfb\xaf\ +\xc5\xf6\x16\xce\xdd\xe0\x34\xa4\xfb\x74\x26\x13\x1e\x1e\x1e\x5e\ +\xb1\x3c\xc5\xd8\x35\x53\x90\xe2\x7f\x74\x58\xcf\x2b\xf1\x06\xa0\ +\x5f\xa7\xb0\x3e\xd6\x00\xd4\xf2\x3a\x38\xc1\x3d\x20\xc5\x74\xae\ +\x63\x32\xe1\xe1\xe1\xe1\x15\xc4\x33\xec\x5f\x6c\xd9\x72\xd6\x86\ +\x82\x14\xff\x6a\x58\xcf\xa3\x06\xa0\xd4\xef\x1e\x41\x25\xd6\x00\ +\x4c\xe7\x7c\x70\xea\xaa\xd1\xfe\x1b\x26\x13\x1e\x1e\x1e\x5e\x31\ +\x3c\xd5\x58\x7a\x75\x41\x8a\x7f\x54\xc3\xa3\x06\x60\xb2\xd7\xa5\ +\xff\x52\xd8\x21\x44\x0d\x40\x35\xef\xc5\x3f\x70\x76\xa8\xad\x53\ +\x85\x69\xef\x67\x32\xe1\xe1\xe1\xe1\xe5\xdb\x53\x0c\xfb\xb6\x99\ +\x86\x7c\x54\x01\x8a\x7f\x74\xf5\x3e\x6a\x00\xca\xbd\x8a\xff\x44\ +\xd8\x1d\x4c\xc5\xee\x17\xe4\xbe\xf8\x47\x1f\xd5\xb0\xdf\xc2\x64\ +\xc2\xc3\xc3\xc3\xcb\xb9\x27\xdb\xff\x50\x80\xe2\x1f\x3d\xb7\x17\ +\x35\x00\x95\x7e\x0f\xfd\xc5\x1b\x80\x72\xe2\x55\x82\x72\xb2\x68\ +\x50\xb3\xd9\xbd\x9f\x6a\x39\x37\x31\x99\xf0\xf0\xf0\xf0\xf2\xe9\ +\xf9\x27\x7a\xff\x3b\xa3\x99\x0f\x29\xc8\xc9\x6d\xd4\x00\x54\x7b\ +\xd6\xf3\xf0\x97\x26\x62\xef\x08\x16\xaa\xf8\x47\x9e\x66\xb9\x7b\ +\x98\x4c\x78\x78\x78\x78\xf9\xf4\x14\xa3\xfd\xcc\x02\x5d\xd9\xae\ +\x27\x7a\x86\x2f\xd6\x00\x94\x8a\x5a\xfc\xc3\x9f\x75\x9a\xe5\xfc\ +\x3b\x93\x09\x0f\x0f\x0f\x2f\x6f\xc5\xdf\xfe\x78\x91\x6e\x6b\x27\ +\x7e\x7b\x2f\xd6\x00\x14\xb9\xf8\x1f\xfc\xd9\xd1\xda\x73\xac\xdf\ +\x04\x5c\xc9\x64\xc2\xc3\xc3\xc3\xcb\x8b\x67\xff\x48\xd3\x16\xef\ +\x5d\xf4\xfa\x76\xc4\x67\x00\x8e\x5a\xe5\x4f\x1e\x07\xa7\x39\xbf\ +\xfb\xe1\x9a\x74\xae\x65\x32\xe1\xe1\xe1\xe1\x65\xfc\xcc\xdf\x74\ +\xae\xf3\xcf\xfe\x1f\x41\x7d\x1b\xf0\x4f\x9e\x07\x47\x69\xb9\x8f\ +\xf6\x9b\x80\xeb\x98\x4c\x78\x78\x78\x78\x19\xf5\x0c\xfb\x7a\x4d\ +\xb6\x1f\x4b\x7d\xa3\xf8\xaf\xd8\x6b\xce\x77\x1f\xe5\x37\x01\xd7\ +\x30\x99\xf0\xf0\xf0\xf0\x32\xe7\x5d\xd3\x68\xb9\xa7\x51\xdf\x28\ +\xfe\xab\xf6\x54\xe9\x3e\x54\x95\xde\x8f\x99\x4c\x78\x78\x78\x78\ +\x59\x79\xe0\xcf\xf9\x89\x62\x74\x4e\xa1\xbe\x51\xfc\xd7\xec\xed\ +\x10\xf3\x8f\x14\x66\xe7\x0a\x26\x27\x1e\x1e\x1e\x5e\xea\xbd\x2b\ +\x54\xab\x7d\x12\xf5\x8d\xe2\x3f\x30\x6f\x9b\xda\x3c\x45\x18\xed\ +\xcb\x98\x9c\x78\x78\x78\x78\xa9\xbd\xe7\xff\xdd\x19\x63\xe9\x04\ +\xea\x1b\xc5\x7f\xe0\xde\xec\x6c\xe3\x81\x7e\xd0\x7d\x95\xc9\x89\ +\x87\x87\x87\x97\x36\xaf\xf3\x75\x5e\xf5\x5b\x91\xb9\x8e\xc1\x59\ +\xa1\x37\x67\xdb\xf7\x10\x96\xf7\x39\x26\x27\x1e\x1e\x1e\x5e\x4a\ +\xee\xf9\xcb\xf6\xe7\x67\x77\xed\x3c\x86\xe2\x9f\xac\xf0\x87\xeb\ +\xfe\x24\x5e\x24\xa8\x46\xf1\xff\x3f\x6f\x66\xc6\xab\x0a\xcb\xf9\ +\x38\x93\x13\x0f\x0f\x0f\x6f\xdc\x0f\xfc\x75\x3e\x25\x44\x77\x9a\ +\xe2\x9f\xb8\xf8\x97\x12\x35\x00\xb1\xfd\x84\xeb\x14\xff\xbb\xfe\ +\xe8\xba\x3e\x25\xa4\xf3\x01\x26\x27\x1e\x1e\x1e\xde\x98\x3c\xd9\ +\xf9\x90\xaa\x2a\x15\x8a\x7f\xe2\xe2\x1f\xed\xf7\xd3\xbb\x01\x08\ +\xbf\x5c\x0d\xcf\xfe\xeb\x14\xff\xbb\xff\x6c\xda\xb4\xaf\xa4\x99\ +\xde\x3b\x98\x9c\x78\x78\x78\x78\xa3\x7e\xe0\xaf\xf3\xae\x33\xcf\ +\xdc\x33\x45\x3d\x4a\x5c\xfc\xcb\xe1\x6e\xbf\x93\x3d\x97\xfe\x0f\ +\xbf\x5c\x09\xcf\xfe\x6b\xb1\xbd\x85\x29\xfe\x87\xfd\xec\xdb\xb7\ +\xef\x68\x3f\x38\xdf\xc8\xe4\xc4\xc3\xc3\xc3\x1b\x8d\xa7\x1a\xf6\ +\x5b\x96\x96\x76\x95\xa8\x47\x89\xbd\x4a\xf8\x39\xd4\x00\xf4\xeb\ +\x14\xd6\xc7\x1a\x80\x1a\xc5\xbf\xf7\x8f\x1f\xa4\xaf\x66\x72\xe2\ +\xe1\xe1\xe1\x0d\xbd\xf8\xbf\x96\x7a\xb4\x22\xaf\x1a\xd6\xf3\xa8\ +\x01\x28\xf5\xbb\x47\x50\x89\x35\x00\xd3\x0c\x76\xc2\x26\xc0\xec\ +\xbc\x94\xc9\x8e\x87\x87\x87\x37\xb4\xe2\xff\x17\xd4\xa3\x15\x79\ +\x51\x0d\x8f\x1a\x80\xc9\x5e\x97\xfe\x4b\x61\x87\x10\x35\x00\x55\ +\x06\x7b\x65\x9e\x6a\xb4\x5f\xc4\x64\xc7\xc3\xc3\xc3\x1b\x70\xf1\ +\xd7\xdb\x2f\xa0\x1e\xad\xc8\x8b\xae\xde\x47\x0d\x40\xb9\x57\xf1\ +\x9f\x08\xbb\x83\xa9\xd8\xfd\x02\x06\x7b\x15\x9e\x6a\x2c\x5d\xe8\ +\x07\xec\x01\x26\x3b\x1e\x1e\x1e\xde\x9a\xbd\x03\xfe\x89\xd5\x05\ +\xd4\xa3\x15\x7b\xf5\x58\x03\x50\xe9\xf7\xd0\x5f\xbc\x01\x28\x27\ +\x5e\x25\x88\xc1\x5e\xd6\x13\x96\xb7\xa8\x5a\xde\xed\x4c\x76\x3c\ +\x3c\x3c\xbc\xd5\x79\x8a\xe9\xdc\xae\x18\x76\x97\xe2\xbf\x2a\x2f\ +\x6a\x00\xaa\x3d\xeb\x79\xf8\x4b\x13\xb1\x77\x04\x29\xfe\x03\xf0\ +\x34\xcb\x6d\xf8\x4d\xc0\xef\x99\xec\x78\x78\x78\x78\x2b\x2e\xfe\ +\xbf\x57\x8d\xa5\x05\x8a\xff\xaa\xbd\x7a\xa2\x67\xf8\x62\x0d\x40\ +\x89\xe2\x3f\x58\x4f\x95\xee\x36\xd5\x72\x6e\x61\xb2\xe3\xe1\xe1\ +\xe1\x25\x2d\xfe\xf6\xef\xe6\x9a\x8b\x0d\x8a\xff\x9a\xbc\xda\x4a\ +\x96\xfb\x9d\xa0\xf8\x0f\xc7\x6b\xc8\xee\x66\xbf\x09\xb8\x89\xc9\ +\x8e\x87\x87\x87\xd7\xc7\x93\xce\x4d\x73\xfa\xae\x6d\xd4\x8f\x11\ +\x79\xab\x2d\xfc\x0c\x76\x72\xaf\x61\xba\x4f\xd0\xa4\xf3\x6b\x26\ +\x3b\x1e\x1e\x1e\xde\x11\x3c\xc3\xbe\x61\x56\x5f\x3c\x93\xfa\x31\ +\x1e\x8f\xc1\x19\xa2\x27\x8c\xee\x46\xbf\x09\xb8\x96\xc9\x8e\x87\ +\x87\x87\x77\xb7\xe2\xff\x2b\xa5\x31\xff\x24\xea\x07\xc5\x3f\xb7\ +\x5e\x73\x7e\xf7\xc3\x55\xcb\xf9\x19\xc9\x03\x0f\x0f\x0f\xef\xd0\ +\xba\xfe\x3f\x57\xf5\x9d\x8f\xa7\x7e\x50\xfc\x73\xef\x35\xe6\xed\ +\x87\x2a\x46\xe7\x2a\x92\x07\x1e\x1e\x5e\xe1\x1f\xf8\x33\xec\xab\ +\x66\xc4\xfc\x69\xd4\x0f\x8a\x7f\x61\xbc\xb9\x39\xf3\x91\x8a\xd1\ +\xfe\x3e\xc9\x03\x0f\x0f\xaf\xb8\x5e\xe7\x7b\xdb\x85\xf1\x30\xea\ +\x07\xc5\xbf\x70\xde\xec\x6c\xe3\xa1\xc2\x70\xbe\x4d\xf2\xc0\xc3\ +\xc3\x2b\xdc\x99\xbf\xb4\xff\x6b\x76\xb6\xf9\x10\xea\x07\xc5\xbf\ +\xb0\xde\xdc\xc2\xfc\x06\xcd\xf4\xbe\x44\xf2\xc0\xc3\xc3\x2b\xce\ +\x3d\xff\xf6\x57\xb6\x6b\xea\x03\xa8\x1f\xe3\x2b\xfe\x89\xdf\xfe\ +\x63\xb0\x87\xeb\xe9\xfa\xde\x9a\x6a\x3a\x9f\x21\x79\xe0\x8d\xd2\ +\x53\xa5\x73\x9b\x66\x39\xfb\x19\x3f\xbc\xd1\xde\xf3\x6f\x7f\x6e\ +\x66\xa6\x71\x02\xf5\x63\x6c\x5e\xb4\xf4\x7f\xe2\x45\x82\x6a\x0c\ +\xf6\x70\xbd\xc5\xc5\xc5\x8a\x2a\xdd\x8f\x90\x3c\xf0\xd6\xe6\x39\ +\xfb\xfd\xef\x5f\xa6\x59\xee\x7b\x84\xe9\xbe\x52\x58\xce\xb9\x8a\ +\xbe\xa8\xcf\x36\x77\x3d\x6d\x46\x58\x8f\xdd\x26\x94\x93\xce\x39\ +\x47\xb9\xf7\xc6\x8d\xa7\x4d\xc4\xc2\x6f\xdd\xd6\xad\xe7\x97\x77\ +\xb4\xf6\x1c\xdb\x5c\xe8\x9c\x2c\xe6\x9d\x27\xfa\xd6\xac\x6f\x9c\ +\xa7\x5a\xce\xc5\xfe\x7f\x7e\xbf\x6f\x7d\xcf\x6f\x18\xee\xe0\x78\ +\xe0\xad\x6d\x91\x9f\xf6\xc7\xe6\xe6\x76\x1c\x47\xfd\x18\x6b\xf1\ +\x2f\x25\x6a\x00\x62\xfb\x09\xd7\x19\xec\xe1\x7b\x9e\xe7\x4d\x06\ +\x89\x9b\xe4\x81\x97\xd4\x13\xa6\x77\x85\xb0\xbc\xb7\x69\x2d\xcf\ +\x6b\x98\xbb\x1f\x17\x14\xf2\x61\xc5\xb3\x10\xdd\x69\xb5\xb9\x6b\ +\x93\x62\x2c\x3d\x4b\x91\xed\x77\x0b\xd3\xbe\x9a\xe3\x81\xb7\x82\ +\x57\xfd\x3e\x30\x3b\xbb\x7d\x03\xf9\x7e\xac\xc5\x3f\xda\xef\xa7\ +\x77\x03\x10\x7e\xb9\x1a\x9e\xfd\xd7\x19\xec\xd1\x78\xba\xae\x4f\ +\x1c\x4c\xe8\x24\x0f\xbc\x65\x3c\x21\xbd\xdf\x0a\xe9\x7c\x20\x28\ +\xf8\xba\xee\x9d\x34\xee\x78\x16\x56\xf7\x64\xbf\x09\x39\x37\xb8\ +\x7a\xa5\x4a\xef\x77\x1c\x5f\xbc\xe5\x3c\xd5\xb0\xff\x69\xcb\x96\ +\xb3\x8f\x25\xdf\x8f\xb5\xf8\x97\xc3\xdd\x7e\x27\x7b\x2e\xfd\x1f\ +\x7e\xb9\x12\x9e\xfd\xd7\x62\x7b\x0b\x33\xd8\xa3\xf1\xd6\x69\xd2\ +\x7b\x3d\xc9\x03\x2f\xbc\xac\x7f\xab\x5f\xf8\xdf\xdb\x30\x1d\x63\ +\x66\xc6\xab\xa6\x35\x9e\xe7\x6c\xfb\x1e\x0d\xd3\x5b\xd0\x4c\xef\ +\xc3\x77\x3e\x5f\xc0\xf1\xc5\x3b\x78\xd9\xff\x8d\x9b\x37\x9f\x71\ +\x0c\xf9\x7e\xac\x5e\x25\xfc\x1c\x6a\x00\xfa\x75\x0a\xeb\x63\x0d\ +\x40\x8d\xc1\x1e\xbd\x27\x2c\xef\x22\x92\x51\x71\xbd\xe0\x5e\xbe\ +\x7f\x76\xfd\xcc\x66\xb3\xb3\x21\x6b\xf1\x3c\x6b\x76\x8e\xf7\xe3\ +\xf7\xb9\xc1\x2d\x0a\x8e\x6f\xa1\x9f\xf6\xff\x2b\xf2\xfd\xd8\xbd\ +\x6a\x58\xcf\xa3\x06\xa0\xd4\xef\x1e\x41\x25\xd6\x00\x4c\x33\xd8\ +\xe3\xf3\x54\xd9\x7e\x19\xc9\xa8\x68\x9e\xf3\x31\xad\xe5\x9e\x9d\ +\x93\x78\x5e\xa7\xb6\x9c\x19\x4d\x7a\x9f\xe5\xf8\x16\xee\xb2\xff\ +\xcb\xc8\xf7\x63\xf7\xa2\x1a\x1e\x35\x00\x93\xbd\x2e\xfd\x97\xc2\ +\x0e\x21\x6a\x00\xaa\x0c\xf6\xf8\x3d\x45\x5f\x7a\x3e\xc9\x28\xf7\ +\xde\x81\xe0\x21\x29\x55\xf7\x1e\x93\xd7\x78\x9e\xd3\x76\x6e\x0e\ +\x9e\x02\x27\x5e\x0a\xf0\xaa\x9f\xde\x7e\x1e\xf9\x7e\xec\x5e\x74\ +\xf5\x3e\x6a\x00\xca\xbd\x8a\xff\x44\xd8\x1d\x4c\xc5\xee\x17\x30\ +\xd8\x29\xf1\x54\x69\xbf\x87\x64\x94\xd3\x33\x25\xdd\xfe\xf7\x39\ +\x6d\xd7\x93\x8b\x12\xcf\x73\xc6\xc2\xd9\xc2\xec\x5c\x42\xbc\xe4\ +\x75\x85\xbf\xf6\xbb\xc9\xf7\xa9\xf0\xea\xb1\x06\xa0\xd2\xef\xa1\ +\xbf\x78\x03\x50\x4e\xbc\x4a\x10\x83\x3d\x74\x2f\x78\x7a\x56\xb5\ +\x9c\x5f\x90\x8c\x72\xe6\x49\xfb\x72\xb5\xb1\x38\x57\xd4\xf9\xa1\ +\xb6\xba\x8a\x66\x39\x57\x12\x2f\xb9\xf3\xae\x99\x9b\x9b\x99\x24\ +\xdf\x8f\xdd\x8b\x1a\x80\x6a\xcf\x7a\x1e\xfe\xd2\x44\xec\x1d\x41\ +\x8a\x7f\x8a\x3c\xd5\x70\x76\x90\x8c\xf2\xe3\xf9\xc7\xf3\xe6\xe0\ +\x12\xe9\x96\x2d\x67\x6d\x28\xfa\xfc\xd0\x75\x7d\x4a\x33\xbd\x17\ +\x06\x6f\x3a\x10\x2f\x79\xf2\x9c\x2d\xe4\xfb\xb1\x7b\xf5\x44\xcf\ +\xf0\xc5\x1a\x80\x12\xc5\x3f\x7d\x9e\xb0\xdc\x7f\x26\x19\xe5\xc3\ +\x53\xf4\xce\xa7\x66\x35\xe3\x34\xe6\xc7\x5d\x7f\xfc\xf1\x79\x84\ +\x26\x9d\x4b\x89\x97\x7c\x78\x7e\xce\x7a\x3b\xf9\x7e\xec\x5e\x6d\ +\x25\xcb\xfd\x4e\x50\xfc\xd3\xe7\x2d\x2c\x2c\x4c\x07\x8b\xbf\x90\ +\x8c\xb2\xed\x29\xa6\x7d\x8b\x6a\x2c\x5d\xc8\xfc\x38\xf2\xcf\xbe\ +\x7d\xfb\x8e\x0e\x5e\x1d\x5c\x6e\x0d\x01\xe2\x2f\x5b\x9e\x6a\x39\ +\x37\x35\x9b\x17\xac\x27\xdf\x67\xc0\x5b\x6d\xe1\x67\xb0\x87\xef\ +\xf9\x9d\xb4\x49\x32\xca\x7a\xf1\x77\xbe\x33\xab\x59\xa7\x13\xcf\ +\xc9\x7e\xd4\x96\xf3\x78\xbf\x09\xf8\x01\xf1\x97\x6d\x4f\xb4\x3c\ +\x9d\x78\xce\x96\xc7\xe0\xa4\xcc\x0b\x36\x62\x21\x19\x65\xb8\xf8\ +\xcb\xce\x3b\xb7\x6f\x17\xf7\x25\x9e\x57\xf6\x33\x3f\x7f\x7e\x5d\ +\x33\xdd\x0f\x12\x7f\x59\xf6\xdc\xf7\x10\xcf\x14\x7f\xbc\x55\x3f\ +\x20\xb5\xb7\xb6\x92\xf5\xd5\x49\x46\xe9\xf1\x54\xcb\xbb\x5d\x31\ +\xec\xe7\x10\xcf\xab\xf7\x82\xe5\x63\x83\xc5\x64\x0e\xae\x91\x40\ +\xfc\x65\xd0\x73\x6e\x3e\xd2\xd2\xd5\xe4\x7b\x8a\x3f\x5e\x1f\x2f\ +\x58\xfb\x9d\x64\x94\xc5\xe2\xef\xdc\x34\xd7\x5c\x6c\x10\xcf\x83\ +\xf1\xd4\xe6\x52\x5b\x98\xf6\xad\xc4\x5f\xf6\x3c\xb5\xe5\x69\xc4\ +\x33\xc5\x1f\x6f\x15\x9e\x66\x7a\xef\x24\x19\x65\xae\xf8\xff\x62\ +\x46\x5f\x78\x0a\xf1\x3c\xe0\x57\x61\x4d\xf7\x8f\x34\xe9\xfc\x9a\ +\xf8\xcb\x96\x77\xf8\xdb\x00\xc4\x33\xc5\x1f\x2f\x81\xe7\x79\xde\ +\xa4\x6a\x79\x37\x92\x8c\xb2\xe4\xb9\x3f\x99\x6b\x2c\x3c\x8e\x78\ +\x1e\xd2\x03\xb1\x46\x77\xa3\x3f\x27\x7e\x45\xfc\x65\xc8\xf3\x9b\ +\xb6\x4d\x9b\xf6\x95\x88\x67\x8a\x3f\xde\x4a\xde\x8b\x6e\xb9\x67\ +\x93\x8c\x32\x74\xe6\x2f\xdd\x1f\xce\x35\xe4\xa9\xc4\xf3\x70\xbd\ +\x83\xeb\x05\x58\xde\xcf\x89\xbf\xec\x78\x0d\xd9\xdd\x4c\x3c\xa7\ +\xaf\xf8\x27\x7e\xfb\x8f\xc1\x1e\xbd\x27\x4c\xef\xaf\x49\x1e\x99\ +\xb9\xec\x7f\x35\xc5\x7f\x74\x9e\x2a\x3b\x8f\xec\x77\x25\x80\x78\ +\x4e\xd5\x95\xb1\x8b\x89\xe7\x54\x79\xd1\xd2\xff\x89\x17\x09\xaa\ +\x31\xd8\xa3\xf5\xe2\xef\x41\x93\x8c\xd2\x7d\xcf\x9f\xcb\xfe\xa3\ +\xf7\x82\xdb\x01\x47\x7a\x26\x80\x78\x4e\x97\xa7\x4a\xfb\xbf\x89\ +\xe7\x54\x15\xff\x52\xa2\x06\x20\xb6\x9f\x70\x9d\xc1\x1e\x9d\xd7\ +\x5c\x70\x1e\x4c\xf2\xc8\xc6\xd3\xfe\x3c\xf0\x37\x3e\xaf\x21\x9d\ +\xa7\x1e\xbe\x87\x00\xf1\x9c\x4e\x6f\x87\xda\x3a\x95\x78\x4e\x45\ +\xf1\x8f\xf6\xfb\xe9\xdd\x00\x84\x5f\xae\x86\x67\xff\x75\x06\x7b\ +\x74\x9e\xb0\xdc\x2e\xc9\x23\xfd\xef\xf9\xf3\xaa\xdf\xf8\x3d\x4d\ +\xba\x2d\xff\x78\x1c\x20\x9e\x53\xbe\xe5\xb5\x6c\x9f\x47\x3c\x8f\ +\xbd\xf8\x97\xc3\xdd\x7e\x27\x7b\x2e\xfd\x1f\x7e\xb9\x12\x9e\xfd\ +\xd7\x62\x7b\x0b\x33\xd8\x23\xf0\x84\xf4\xde\x4b\xf2\x48\xf9\x0a\ +\x7f\x2c\xf2\x93\x1a\x4f\x98\xee\x4b\x88\xe7\x74\x7b\x8a\xb4\xdf\ +\x47\x3c\x8f\xd5\xab\x84\x9f\x43\x0d\x40\xbf\x4e\x61\x7d\xac\x01\ +\xa8\x31\xd8\x23\xf3\xd6\x69\xd2\xb9\x9e\xe4\x91\xee\xe5\x7d\x89\ +\xe7\x74\xad\x18\xa8\xe8\xf6\xc7\x89\xe7\x14\x7b\xd2\xb9\x96\x78\ +\x1e\x9b\x57\x0d\xeb\x79\xd4\x00\x94\xfa\xdd\x23\xa8\xc4\x1a\x80\ +\x69\x06\x7b\x74\x9e\xd2\x72\x1e\x4b\xf2\x48\xf7\xc6\x3e\xac\xed\ +\x9f\x3e\x6f\xab\xa2\x3f\x50\x95\x9d\x1f\x13\xcf\x29\xde\x22\xd8\ +\xd8\x7d\x1a\xf1\x3c\x72\x2f\xaa\xe1\x51\x03\x30\xd9\xeb\xd2\x7f\ +\x29\xec\x10\xa2\x06\xa0\xca\x60\x8f\xd6\x13\xa6\xfb\x0c\x92\x47\ +\x7a\xb7\xf4\x65\x57\xbf\xf4\x7a\x73\xc6\xce\xb3\x34\xcb\xd9\x4f\ +\x3c\xa7\xd3\x13\xa6\x77\x2e\xf1\x3c\x52\x2f\xba\x7a\x1f\x35\x00\ +\xe5\x5e\xc5\x7f\x22\xec\x0e\xa6\x62\xf7\x0b\x18\xec\x11\x7b\xc1\ +\x0e\x5a\x24\x8f\x74\x7a\x8a\xb1\xf4\x2c\xe2\x39\xdd\x9e\x3f\x7f\ +\xfe\x94\x78\x4e\xa7\x27\x2c\xef\x5d\xc4\xf3\x48\xbd\x7a\xac\x01\ +\xa8\xf4\x7b\xe8\x2f\xde\x00\x94\x13\xaf\x12\xc4\x60\x0f\xd4\xd3\ +\xa4\x73\x0d\xc9\x23\x7d\x9e\x2a\xdb\x9f\x26\x9e\xd3\xef\xe9\xba\ +\x3e\xa1\x49\xf7\x2b\xc4\x73\xfa\x3c\xd5\x72\x7e\x46\x3c\x8f\xd4\ +\x8b\x1a\x80\x6a\xcf\x7a\x1e\xfe\xd2\x44\xec\x1d\x41\x8a\xff\x18\ +\xbc\x39\xc3\x7d\x08\xc9\x23\x85\xc5\xdf\x70\x6e\x9e\xd5\x8c\xd3\ +\x88\xe7\x6c\x78\x0d\xb3\xf3\x18\x55\x3a\xb7\x11\xcf\xe9\xf3\x74\ +\xdd\x3b\x89\x78\x1e\x99\x57\x4f\xf4\x0c\x5f\xac\x01\x28\x51\xfc\ +\xc7\xe7\x09\xdd\xb6\x49\x1e\xe9\xf3\x14\xbd\xfd\x3c\xe2\x39\x5b\ +\x9e\x30\xbd\x97\x11\xcf\xe9\xf3\x82\x2d\xce\x89\xe7\x91\x79\xc9\ +\xde\xde\x8b\x35\x00\x14\xff\x31\x7a\x42\xb6\xff\x96\xe4\x91\x32\ +\x4f\xda\x97\x6f\xd9\x72\xd6\x06\xe2\x39\x5b\x5e\xb3\x79\xc1\xfa\ +\x60\x77\x46\xe2\x39\x5d\x9e\x6a\x39\x17\x13\xcf\x29\xf3\x56\x5b\ +\xf8\x19\xec\xc1\x7a\x8a\x61\x7f\x99\xe4\x91\xb2\x15\xcc\x1a\x8b\ +\x73\xc4\x73\x36\x3d\x61\xb9\x26\xf1\x9c\x2e\x4f\x35\x9d\x4b\x88\ +\x67\xb6\x08\xc6\x3b\xcc\xdb\xbe\x7d\xcb\xb1\xc1\xbd\x66\x92\x47\ +\x8a\x8a\xbf\x6e\xff\x3b\xf1\x9c\x6d\x4f\x93\xce\x17\x89\xe7\x14\ +\x79\xa6\xf7\xbf\xfe\x61\x59\x47\x3c\x53\xfc\xf1\x62\xde\x5c\x63\ +\xfe\x0f\x49\x1e\xa9\xf2\x0e\x28\x8d\xf9\x27\x11\xcf\xd9\xf6\xfc\ +\xe3\xf8\x34\xe2\x39\x6d\x5e\xf7\x14\xe2\x99\xe2\x8f\x17\xf3\xd4\ +\x66\x7b\x89\xe4\x91\x22\xcf\xe8\x7c\x80\x78\xce\x87\x27\x2c\xf7\ +\xb3\xcc\x8f\xf4\x78\x42\x7a\x3a\xf1\x4c\xf1\xc7\x8b\x79\x9a\xe9\ +\xbc\x9c\xe4\x91\x1e\x4f\xd5\xbd\xc7\x10\xcf\xf9\xf0\xd4\xc6\xd2\ +\x76\xe6\x47\x8a\x3c\x63\xe9\x22\xe2\x99\xe2\x8f\x17\x5f\xc1\xcc\ +\x74\xff\x95\xe4\x91\x16\xcf\xf9\x18\xf1\x9c\x2f\x4f\x91\xed\x6f\ +\x30\x3f\x52\xe2\xc9\xce\x87\x89\x67\x8a\x3f\x5e\xcc\x13\xa6\x77\ +\x05\xc9\x23\x25\x5e\xcb\x3d\x9b\x78\xce\x97\xa7\x36\x97\xda\xcc\ +\x8f\x74\x78\xaa\xb4\x7f\x40\x3c\x8f\xbf\xf8\x27\x7e\xfb\x8f\xc1\ +\x1e\xfa\xf2\xa5\x53\xaa\xe5\xdd\x4e\xf2\x18\xbf\xe7\xff\xf3\x32\ +\xe2\x39\x7f\xde\x96\x2d\x67\x1f\xeb\x1f\xdf\x9f\x33\x3f\xd2\xe0\ +\xd9\xfb\x67\x67\xb7\x6f\x20\x9e\xc7\xe6\x45\x4b\xff\x27\x5e\x24\ +\xa8\xc6\x60\x0f\xcf\x6b\xce\x77\x1f\x45\xf2\x48\xc9\x96\xa5\xa6\ +\xf7\x4c\xe2\x39\x9f\x5e\x92\xd5\x01\x99\x1f\xa3\xf1\xfc\xcf\xa3\ +\x88\xe7\xb1\x15\xff\x52\xa2\x06\x20\xb6\x9f\x70\x9d\xc1\x1e\x9e\ +\xa7\xb6\xba\x0a\xc9\x23\x0d\x9e\x73\x6b\xb3\xd9\xd9\x40\x3c\xe7\ +\xd3\x53\x64\xf7\x41\xfe\x71\x3e\xc0\xfc\x48\x85\x37\x4b\x3c\x8f\ +\xa5\xf8\x47\xfb\xfd\xf4\x6e\x00\xc2\x2f\x57\xc3\xb3\xff\x3a\x83\ +\x3d\x3c\x4f\x33\xdd\x67\x91\x3c\x52\xb0\x5f\xb9\xf4\xde\x4b\x3c\ +\xe7\xbc\xd9\x36\x9d\x4b\x98\x1f\x69\xb8\xd2\xe6\x5e\x40\x3c\x8f\ +\xbc\xf8\x97\xc3\xdd\x7e\x27\x7b\x2e\xfd\x1f\x7e\xb9\x12\x9e\xfd\ +\xd7\x62\x7b\x0b\x33\xd8\x43\xf0\x34\xe9\xbd\x9e\xe4\x31\x7e\xef\ +\x48\x1b\x95\x10\xcf\xf9\xf1\x84\xe9\x9d\xcb\xfc\x48\x41\xb3\x6d\ +\x7a\xaf\x25\x9e\x47\xea\x55\xc2\xcf\xa1\x06\xa0\x5f\xa7\xb0\x3e\ +\xd6\x00\xd4\x18\xec\xe1\x79\xaa\x74\x3f\x42\xf2\x18\xaf\xe7\x9f\ +\xfd\xff\x76\x66\xc6\xab\x12\xcf\xf9\xf6\x66\xcd\xce\xf1\xfd\x1e\ +\xb8\x65\x7e\x8c\xc0\x33\xbd\x0f\x13\xcf\x23\xf3\xaa\x61\x3d\x8f\ +\x1a\x80\x52\xbf\x7b\x04\x95\x58\x03\x30\xcd\x60\x0f\xd7\xd3\x2c\ +\xf7\x3b\x24\x8f\xf1\x7a\x42\x3a\x1f\x20\x9e\x8b\xe1\x09\xcb\xfb\ +\x02\xf3\x63\xcc\x9e\x74\xbe\x4d\x3c\x8f\xc4\x8b\x6a\x78\xd4\x00\ +\x4c\xf6\xba\xf4\x5f\x0a\x3b\x84\xa8\x01\xa8\x32\xd8\xc3\xf7\xfc\ +\xe2\xf3\x1b\x92\xc7\x98\xbd\x96\xe7\x11\xcf\xc5\xf0\xfc\xb3\xcf\ +\x17\x32\x3f\xc6\xec\x49\xef\x06\xe2\x79\xe8\x5e\x74\xf5\x3e\x6a\ +\x00\xca\xbd\x8a\xff\x44\xd8\x1d\x4c\xc5\xee\x17\x30\xd8\x43\xf6\ +\x74\x7d\x6f\x8d\xe4\x31\x7e\x4f\x91\x7b\x1e\x40\x3c\x17\xc3\x53\ +\x5b\xce\xe3\x99\x1f\xe3\xf7\x16\x16\x16\xa6\x89\xe7\xa1\x7a\xf5\ +\x58\x03\x50\xe9\xf7\xd0\x5f\xbc\x01\x28\x27\x5e\x25\x88\xc1\x5e\ +\x93\x17\xec\x8c\x45\xf2\x18\xaf\x17\xac\xc2\x48\x3c\x17\xca\x5b\ +\x17\x9c\x81\x32\x3f\xc6\xeb\x35\x17\x3a\x27\x13\xcf\x43\xf5\xa2\ +\x06\xa0\xda\xb3\x9e\x87\xbf\x34\x11\x7b\x47\x90\xe2\x3f\x22\xaf\ +\x21\x9d\xa7\x92\x3c\xc6\xeb\x09\xcb\x7b\x1b\xf1\x5c\x2c\x2f\x7a\ +\xf0\x96\xf9\x31\x3e\x4f\xb5\xbc\x33\x88\xe7\xa1\x7a\xf5\x44\xcf\ +\xf0\xc5\x1a\x80\x12\xc5\x7f\x44\x97\x21\xa5\xf3\x30\xcd\x74\x9f\ +\x17\x3c\x0c\x43\xf2\x18\xb3\xb7\xcc\xfd\x7f\xe2\x39\xdf\x9e\x66\ +\x3a\xcf\x67\x7e\x8c\xd9\x0b\x72\x9f\x9f\x03\x83\x5c\x48\x3c\x0f\ +\xc5\x4b\xf6\xf6\x5e\xac\x01\xa0\xf8\x0f\xd1\x13\x46\x77\xa3\x9f\ +\x78\x5e\xe2\x77\xbe\xdf\x25\x79\xa4\xc7\x6b\x98\xbb\x1f\x47\x3c\ +\x17\x6c\x8b\xe0\xe6\xe2\x2c\xf3\x23\x3d\x9e\x62\x3a\x97\xab\x86\ +\x7d\xd1\x9c\xd8\xf9\x14\xe2\x79\xc4\xde\x6a\x0b\x3f\x83\xdd\xd7\ +\x5b\xd7\x30\xdd\x27\x08\xd3\x7d\xa5\x66\x39\x57\x32\xd9\xd3\xe8\ +\x39\xfb\xb7\x6e\x3d\xbf\x4c\x3c\x17\xcb\xdb\xa1\xc9\x93\x99\x1f\ +\xe9\xf4\x54\xe9\xfc\xd0\xff\xe7\xab\x82\xdc\x19\xe4\x50\xe2\x79\ +\x74\x1e\x83\xb3\x46\x4f\xd7\xf5\x89\x86\xec\x6e\xd6\x2c\xf7\x35\ +\x9a\xf4\x7e\xca\x64\x4f\xb7\x17\xdf\xfd\x8f\x78\x2e\x96\x27\x0c\ +\xfb\x57\xcc\x8f\x94\x7b\x07\x73\xa8\xfb\x9a\x20\xa7\x06\xb9\x95\ +\x78\xa6\xf8\xa7\xce\xf3\x3c\x6f\x52\x98\xde\x56\x3f\x60\xdf\xa8\ +\x5a\xde\xaf\x98\xec\x59\xf2\xdc\xf7\x10\xcf\xc5\xf4\x14\xd9\xbe\ +\x84\xf9\x91\x1d\xef\x60\x6e\x95\xce\x9b\x82\x5c\x1b\xe4\x5c\xe2\ +\x99\xe2\x3f\x36\x6f\xfb\xf6\xc6\x7d\x34\xd3\x15\xc2\x72\xdf\x1e\ +\x7f\xa5\x88\xc9\x9e\x2d\x2f\xb8\x3d\x43\x3c\x17\xd3\xd3\x4c\xe7\ +\xad\xcc\x8f\xac\x3e\x40\xe8\xdd\x10\xe4\x5e\xff\xf7\x84\x10\xdd\ +\x69\xe2\x99\xe2\x3f\x74\x6f\xab\x50\x4e\x14\x7a\xbb\x23\xa4\xfd\ +\xaf\xc1\xda\xf1\x4c\xce\xec\x7b\xc2\x72\xce\x25\x79\x14\xd3\xf3\ +\x0b\xc8\x8b\x98\x1f\xd9\xf7\x54\xc3\xb9\xf9\x60\x4e\xf6\x73\x73\ +\x90\xa3\x99\x1f\x14\xff\x81\x79\xb3\xb3\x8d\x07\x2a\x46\x7b\xaf\ +\x30\x3a\x1f\x13\xa6\x7d\x2b\x93\x33\x67\x4f\x1f\xeb\x8b\x3a\xc5\ +\xb0\x98\x9e\xb0\xba\xbb\x98\x1f\x79\xf3\xec\x5b\x35\xcb\xf9\x48\ +\xc3\x74\x6d\x75\xe7\xb9\xf7\x62\x7e\x50\xfc\x57\xec\xe9\xfa\xde\ +\xfb\xfa\x41\xb4\x57\x35\xdb\x9f\xf5\x03\x6a\x3f\x93\x33\xbf\xde\ +\x6c\x73\xd7\xd3\x28\x86\xc5\xf4\x54\xe9\x6e\x63\x7e\xe4\xd9\x73\ +\xf6\xfb\xff\xfc\xb4\xb0\xdc\xbd\x62\xde\x3d\x81\xf9\x71\x37\x73\ +\x1d\xc9\x23\xfc\xd1\x5a\xf6\x03\xfd\x60\xb9\x50\x35\xdd\xcf\xab\ +\xd2\xb9\x83\xc9\x54\x0c\x6f\x46\x58\x8f\xa5\x18\x16\xd3\x53\xad\ +\xee\xe9\xcc\x8f\xc2\x78\x07\xc2\x5d\x20\x2f\x54\x64\xf7\x41\x05\ +\x9f\x1f\xd1\xd2\xff\x89\x17\x09\xaa\xe5\x71\x70\x9a\xf3\xbb\x1f\ +\xee\x07\xc5\xf3\xfd\x4e\xf1\xeb\x4c\xa6\x62\x7a\xdb\x84\x72\x12\ +\xc5\xb0\x98\x9e\xd6\xda\xf3\x10\xe6\x47\x51\xbd\x20\xe7\xbb\x2f\ +\xf0\x7f\xf7\x51\x05\x2c\xfe\xa5\x44\x0d\x40\x6c\x3f\xe1\x7a\x5e\ +\x06\x47\x69\x39\x8f\x0d\x56\xe3\x0b\xde\xff\x66\x32\xe1\x9d\x73\ +\x8e\x72\x6f\x8a\x61\x31\xbd\xe0\xb2\x30\xf3\x03\x4f\x98\x9d\xef\ +\xa9\xb2\xfd\x4a\xa5\xb1\xeb\xa9\x05\x28\xfe\xd1\x7e\x3f\xbd\x1b\ +\x80\xf0\xcb\xd5\xf0\xec\xbf\x9e\xe1\xc9\xbe\x4e\xcc\x3b\x4f\xf4\ +\x0f\xf6\xab\x7a\xad\xc6\xc7\x64\x2a\xa6\xb7\x71\xe3\x69\x13\x14\ +\xc3\x62\x7a\xcd\x66\x67\x03\xf3\x03\xef\xae\xab\x10\xba\x3f\x54\ +\x2d\xe7\x62\xd5\xf2\x9e\x74\xd4\x0a\x56\x21\xcc\x48\xf1\x2f\x87\ +\xbb\xfd\x4e\xf6\x5c\xfa\x3f\xfc\x72\x25\x3c\xfb\xaf\xc5\xf6\x16\ +\xce\xc4\x64\x0f\x56\x8c\xd2\x5a\xee\x99\xc2\xf4\x5e\xeb\x1f\xcc\ +\x9f\x11\xfc\x78\xcb\x4f\x76\xe7\x36\x8a\x61\x71\xbd\x60\x3f\x7a\ +\xe6\x07\x5e\x0f\xef\xe7\x9a\xe5\xbe\xce\xff\xff\x9e\xd6\x6b\x15\ +\xc2\x8c\xcc\x8f\x4a\xf8\x39\xd4\x00\xf4\xeb\x14\xd6\xc7\x1a\x80\ +\x5a\xda\x27\xbb\xaa\x2a\x95\xe0\xa9\x5e\x61\xba\x6f\x5e\xc9\x6a\ +\x7c\x04\x7f\x91\x3d\x67\x3f\xc5\xb0\xb8\x9e\xae\xef\xad\x31\x3f\ +\xf0\x12\x79\xd2\xb9\x4e\x58\xde\x3f\x68\x56\x77\xbb\xdf\x0c\x4c\ +\x65\x6c\x7e\x54\xc3\x7a\x1e\x35\x00\xa5\x7e\xf7\x08\x2a\xb1\x06\ +\x60\x3a\xcd\x93\x5d\x6d\xec\xdc\xe2\x17\xfd\xb7\xf9\x45\xff\x46\ +\x82\x15\x6f\xa5\x5e\xce\x2e\xf3\xe1\xad\xc0\x5b\xee\x16\x00\xf3\ +\x03\xaf\xef\xc2\x43\x7e\xad\x11\xa6\xf7\x56\xcd\xe8\x6c\xca\xc0\ +\xfc\x88\x6a\x78\xd4\x00\x4c\xf6\xba\xf4\x5f\x0a\x3b\x84\xa8\x01\ +\xa8\xa6\x75\xb2\xcf\x19\x4b\x2d\x61\xda\xdf\x22\x58\xf1\xd6\xe2\ +\xc5\x77\x02\xa4\xb8\x16\xcb\x3b\xfc\x21\x40\xe6\x07\xde\x8a\x3d\ +\xa3\xf3\x4d\x45\x5f\xb4\x52\x3a\x3f\xa2\xab\xf7\x51\x03\x50\xee\ +\x55\xfc\x27\xc2\xee\x60\x2a\x76\xbf\x20\x75\x93\x5d\xd5\x17\x9e\ +\xa0\x18\xed\x2f\x10\xac\x78\x83\xf0\x76\xb4\xf6\x1c\x4b\x31\x2c\ +\xa6\xa7\x4a\xf7\xa1\xcc\x0f\xbc\x41\x78\x8a\x6c\x7f\xbe\xd1\x72\ +\x4f\x4b\xd9\xfc\xa8\xc7\x1a\x80\x4a\xbf\x87\xfe\xe2\x0d\x40\x39\ +\xf1\x2a\x41\xa3\x2c\xfe\x46\xfb\xf9\x2c\xc7\x8b\x37\x48\xaf\xb9\ +\xd0\x39\x99\x62\x58\x4c\x2f\xd8\x6f\x9e\xf9\x81\x37\xc0\x67\x8a\ +\xfc\xda\xe4\x5e\x90\xa2\xf9\x11\x35\x00\xd5\x9e\xf5\x3c\xfc\xa5\ +\x89\xd8\x3b\x82\xa9\x2a\xfe\x5b\xb6\xcc\x9d\xa0\xea\x9d\x0f\x12\ +\xac\x78\x83\xf6\x82\x57\x44\x29\x86\xc5\xf4\x84\x74\x66\x99\x1f\ +\x78\x83\xf7\xdc\xf7\x34\x9b\x17\xac\x4f\xc1\xfc\xa8\x27\x7a\x86\ +\x2f\xd6\x00\x94\xd2\x56\xfc\x83\x95\xda\x84\xd1\xfe\x0a\xc1\x85\ +\x37\x24\x6f\x96\x62\x58\x4c\x4f\x95\x8b\x7b\x98\x1f\x78\xc3\xf0\ +\x82\x65\x87\x75\xdd\x3b\x66\xcc\xf3\xa3\xb6\x92\xe5\x7e\x27\xd2\ +\x56\xfc\x77\xec\xd0\xee\x2f\x0c\xfb\x6b\x04\x17\xde\xf0\x3c\xf7\ +\x3c\x8a\x61\x31\x3d\xd5\xb0\x5f\xc1\xfc\xc0\x1b\x96\x27\x2c\xe7\ +\xcb\xc1\x5a\x13\xa9\x9f\x1f\xab\x2d\xfc\xc3\xbd\xec\x7f\xd6\x06\ +\x21\xdb\x9f\x24\xb8\xf0\x86\xe9\x05\xab\x7e\x51\x0c\x8b\xe9\xa9\ +\xd2\xfe\x67\xe6\x07\xde\x70\x3d\xe7\xdf\xf6\xed\xdb\x77\x74\x56\ +\xe6\x47\x9a\x1e\xf8\xbb\x98\xe0\xc2\x1b\x81\xf7\x7e\x8a\x61\x31\ +\x3d\xde\x26\xc2\x1b\x89\x67\x3a\x2f\xa1\xf8\xaf\xa4\xf8\x37\x16\ +\xb6\x29\x86\x7d\x07\xc1\x85\x37\x6c\x4f\x98\xee\xf7\x28\x86\xc5\ +\xf4\x84\x61\x5f\xcf\xfc\xc0\x1b\xb6\x17\x6c\x2f\xaf\x9a\xee\x1f\ +\x51\xfc\x13\x78\xe7\x9c\x33\x77\x1f\x61\x76\xae\x20\xb8\xf0\x46\ +\x32\x39\x2d\xef\x76\x21\xba\xd3\x14\xd7\x62\x79\x33\x0d\x79\x0a\ +\xf3\x03\x6f\x54\x9e\x7f\x42\xfb\xfd\x6d\xdb\x9e\x7e\x1c\xc5\xbf\ +\xdf\x65\x39\x7d\xe9\x85\x04\x17\xde\x28\x3d\xb5\xb9\x6b\x13\xc5\ +\xb5\x58\x5e\xc3\x70\xb6\x32\x3f\xf0\x46\xe9\x29\x7a\xfb\x79\x14\ +\xff\x1e\xde\xdc\xdc\x8e\xfb\x09\xc3\xfe\x1f\x82\x0b\x6f\x94\x9e\ +\x62\x2c\x3d\x8b\xe2\x5a\x2c\x4f\x58\xee\x8b\x98\x1f\x78\x23\xf5\ +\x0c\xfb\x57\xdb\xb7\x37\xee\x43\xf1\x3f\x82\xa7\xca\xf6\xb3\x09\ +\x2e\xbc\x91\x77\xe6\xb2\xfd\x6e\x8a\x6b\xb1\x3c\x61\x39\x1f\x67\ +\x7e\xe0\x8d\xdc\x6b\xb9\xdd\xb4\x14\xff\xc4\x6f\xff\x8d\x6a\x72\ +\x6a\x96\xfb\x1d\x82\x0b\x6f\xf4\x9e\x7d\x35\xc5\xb5\x38\x5e\xf0\ +\x5a\x96\x90\xce\x6f\x98\x1f\x78\x23\xf7\xa4\xf7\xb5\x14\xcc\x8f\ +\x68\xe9\xff\xc4\x8b\x04\xd5\x86\x3d\x39\xe7\xac\xce\x46\x82\x0b\ +\x6f\x5c\x9e\xb0\xba\x27\x53\x5c\x8b\xe1\x45\x7b\x00\x30\x3f\xf0\ +\xc6\xe1\xa9\xd2\x79\xd8\x98\x8b\x7f\x29\x51\x03\x10\xdb\x4f\xb8\ +\x3e\xfc\x7b\x72\xde\xf3\x09\x2e\xbc\x71\x79\xc2\xf4\xce\xa5\xb8\ +\x16\xc3\x13\x96\xfb\x67\xcc\x0f\xbc\x71\x79\x42\xba\xcf\x1e\x63\ +\xf1\x8f\xf6\xfb\xe9\xdd\x00\x84\x5f\xae\x86\x67\xff\xf5\x61\x4f\ +\x4e\xd5\xf4\x3e\x49\x70\xe1\x8d\xcb\x53\xa5\xfb\x11\x8a\x6b\x31\ +\xbc\x60\x89\x56\xe6\x07\xde\xb8\xbc\x24\xb9\x66\x48\xc5\xbf\x1c\ +\xee\xf6\x3b\xd9\x73\xe9\xff\xf0\xcb\x95\xf0\xec\xbf\x16\xdb\x5b\ +\x78\x68\x93\x53\xb5\xbc\x1b\x09\x2e\xbc\xf1\x5d\x96\xf3\x7e\x37\ +\x67\xdb\xf7\xa0\xb8\xe6\xdb\x6b\x36\xbb\xf7\xf7\x8f\xf7\x01\xe6\ +\x07\xde\xd8\x3c\xe9\x5c\x37\x86\xf9\x51\x09\x3f\x87\x1a\x80\x7e\ +\x9d\xc2\xfa\x58\x03\x50\x1b\xe6\xe4\x14\xf3\xce\x89\x04\x17\xde\ +\xb8\xbd\x86\xe9\x2d\x50\x5c\xf3\xed\x09\xd3\x7b\x26\xf3\x03\x6f\ +\xdc\x5e\xb3\xd9\x3e\x6e\x84\xf3\xa3\x1a\xd6\xf3\xa8\x01\x28\xf5\ +\xbb\x47\x50\x89\x35\x00\xd3\xc3\x9e\x9c\xfe\xd9\xff\x19\x04\x17\ +\xde\xd8\xb7\xf0\x94\xee\x87\x28\xae\xf9\xf6\xfc\xb3\xaf\x2f\x32\ +\x3f\xf0\xc6\xed\x09\xc3\xfd\xc3\x11\xcd\x8f\xa8\x86\x47\x0d\xc0\ +\x64\xaf\x4b\xff\xa5\xb0\x43\x88\x1a\x80\xea\x28\x26\xa7\x3f\x20\ +\x2a\xc1\x85\x37\x6e\x4f\x95\xce\x6d\xb3\x66\xe7\x78\x8a\x6b\x3e\ +\xbd\xe0\xe9\x6b\xe6\x07\x5e\x3a\xbc\xee\xf6\x11\xcc\x8f\xe8\xea\ +\x7d\xd4\x00\x94\x7b\x15\xff\x89\xb0\x3b\x98\x8a\xdd\x2f\x18\xc9\ +\xe4\xd4\xa4\xdb\x22\xb8\xf0\x52\xd1\x99\x5b\xde\x73\x29\xae\xf9\ +\xf4\x84\xe9\xbe\x92\xf9\x81\x97\x0e\xcf\x6d\x8c\x60\x7e\xd4\x63\ +\x0d\x40\xa5\xdf\x43\x7f\xf1\x06\xa0\x9c\x78\x95\xa0\x01\x4c\xce\ +\x86\xd9\xb5\x08\x2e\xbc\x34\x78\xc2\xf4\xae\xf0\x43\x72\x1d\xc5\ +\x35\x5f\x9e\xe7\x79\x93\x9a\x74\xae\x65\x7e\xe0\xa5\xc1\x53\x5b\ +\x9e\x36\x82\xf9\x11\x35\x00\xd5\x9e\xf5\x3c\xfc\xa5\x89\xd8\x3b\ +\x82\xeb\x46\x39\x39\xfd\x01\x99\x25\xb8\xf0\xd2\x33\x39\x9d\x19\ +\x8a\x6b\xbe\x3c\x61\x75\x77\x31\x3f\xf0\xd2\xe2\x35\xa4\xfb\xf4\ +\x11\xcc\x8f\x7a\xa2\x67\xf8\x62\x0d\x40\x69\xd4\xc5\xff\xce\x87\ +\x00\xbb\xa7\x13\x5c\x78\xa9\xf1\xa4\xf7\x59\x8a\x6b\xbe\x3c\xff\ +\xec\xff\xdb\xcc\x0f\xbc\xd4\x78\xd2\x7b\xfc\x08\xe6\x47\x6d\x25\ +\xcb\xfd\x4e\x8c\xa3\xf8\x07\x3f\x73\xa6\x7d\x3f\x82\x0b\x2f\x4d\ +\xde\x9c\xb6\x73\x33\xc5\x35\x1f\x9e\x30\xbd\xad\xcc\x0f\xbc\x34\ +\x79\xdb\x54\xe3\xc1\xa9\x99\x6f\xab\x2d\xfc\x03\x9c\xec\xeb\x54\ +\xcb\xfb\x3d\xc1\x85\x97\x1a\x4f\xb6\x3f\x46\x71\xcd\x87\x77\xf8\ +\xca\x7f\xcc\x0f\xbc\x71\x7a\x8a\x69\xff\x36\xad\xf3\x6d\x6c\x7f\ +\xb8\x2a\x9d\x1f\x10\x5c\x78\x69\xf2\xe6\x8c\x85\xb3\x29\xae\x19\ +\x2f\xfe\xa6\xbb\x83\x78\xc6\x4b\x95\x67\xb4\x2f\xa3\xf8\xdf\xbd\ +\x4b\xff\x04\xc1\x85\x97\x2e\xaf\x73\x09\xc5\x35\xbb\x5e\xb0\xed\ +\xaf\x6a\xb9\xdf\x20\x9e\xf1\x52\xe5\xc9\xce\x47\x29\xfe\x87\x79\ +\x42\xef\xbc\x89\xe0\xc2\x4b\x9b\xa7\xb6\xba\x0a\xc5\x35\x9b\x9e\ +\xd6\xea\x76\x88\x67\xbc\xd4\x79\xd2\x7e\x3d\xc5\xff\x30\x4f\xd1\ +\x97\x9e\x4f\x70\xe1\xa5\xcd\x0b\xd6\x05\xd0\x75\x7d\x8a\xe2\x9a\ +\x2d\x6f\x7e\xfe\xfc\xba\x7f\xfc\x7e\x49\x3c\xe3\xa5\xcd\x53\x8c\ +\xf6\x85\x14\xff\xc3\xbc\x39\x63\x97\x24\xb8\xf0\x52\xe9\x99\xde\ +\x0b\x29\xae\xd9\xf2\xfc\xc6\xed\xaf\x89\x67\xbc\x34\x7a\x0d\xc3\ +\x3d\x87\xe2\x7f\x98\x37\xd7\x98\xff\x03\x82\x0b\x2f\x9d\x9e\x73\ +\xab\xff\xcf\x47\x50\x5c\xb3\xe1\x05\xeb\x8a\xa8\xd2\xb9\x83\x78\ +\xc6\x4b\xa3\x17\xec\x7e\x9b\x86\xe2\x9f\xf8\xed\xbf\x51\x4c\xf6\ +\x2d\x5b\xce\x3e\x36\xfe\x2a\x20\xc1\x85\x97\x2a\x4f\x3a\x97\x06\ +\x0f\x95\x51\xac\xd3\xed\x05\xb7\x6b\x82\x45\x7f\x88\x67\xbc\x54\ +\x16\x7f\xe9\xfd\xf6\xa8\xd8\x52\xe3\x63\x9a\x6f\xd1\xd2\xff\x89\ +\x17\x09\xaa\x8d\x62\xb2\xfb\x0d\xc0\x77\x09\x2e\x3c\x36\x0a\xc2\ +\x5b\xf5\xdb\x44\xa6\xf3\x2a\xe2\x19\x2f\xb5\x9e\xf4\xbe\x96\x82\ +\xe2\x5f\x4a\xd4\x00\xc4\xf6\x13\xae\x8f\x62\xb2\x6b\xa6\xf7\x6e\ +\x82\x0b\x2f\xad\x5e\xb0\x5d\xb0\xda\x72\x1e\x4f\xb1\x4e\x69\xf1\ +\x97\x9d\xb3\xfd\xe3\x79\x80\x78\xc6\x4b\xab\xe7\x9f\xe4\xfe\xe3\ +\x98\x8b\x7f\xb4\xdf\x4f\xef\x06\x20\xfc\x72\x35\x3c\xfb\xaf\x8f\ +\x62\xb2\x6b\x96\xfb\xa7\x04\x17\x5e\xaa\x37\x0a\x92\xce\x0f\x82\ +\x27\xcc\x29\xd6\xe9\xf2\x66\x8c\xa5\x13\xfc\xe3\x79\x0d\xf1\x8c\ +\x97\x66\x6f\xb9\xab\x88\x23\x2c\xfe\xe5\x70\xb7\xdf\xc9\x9e\x4b\ +\xff\x87\x5f\xae\x84\x67\xff\xb5\xd8\xde\xc2\x43\x9d\xec\xc1\x16\ +\x89\x04\x17\x5e\xea\x3d\xd3\xfd\xe0\xe6\xcd\x67\x1c\x43\xb1\x4e\ +\x87\x77\xe6\x99\x7b\xa6\x84\xd1\xb9\x94\x78\xc6\x4b\xbf\xd7\xdd\ +\x3e\xa6\xf9\x56\x09\x3f\x87\x1a\x80\x7e\x9d\xc2\xfa\x58\x03\x50\ +\x1b\xc5\x64\xf7\x07\xe7\x14\x82\x0b\x2f\x0b\x9e\x6a\xd8\x2f\xa3\ +\x58\xa7\xc3\x13\xd2\x7e\x1d\xf1\x8c\x97\x05\xaf\xd9\xec\xde\x7f\ +\x0c\xf3\xad\x1a\xd6\xf3\xa8\x01\x28\xf5\xbb\x47\x50\x89\x35\x00\ +\xd3\xa3\x9a\xec\xc1\x53\xd6\xc1\x53\x92\x04\x17\x5e\x06\xbc\x03\ +\x6a\x73\xa9\x4d\xb1\x1e\xaf\xa7\x18\xed\x67\x12\xcf\x78\x99\xf0\ +\xa4\x73\xfd\x18\xe6\x5b\x54\xc3\xa3\x06\x60\xb2\xd7\xa5\xff\x52\ +\xd8\x21\x44\x0d\x40\x75\xd4\x93\xdd\x1f\xa4\x2f\x12\x5c\x78\xd9\ +\xf0\xec\x60\x7d\x80\xa7\x52\xac\xc7\xe3\xcd\x35\x17\x1b\x8a\xe9\ +\xdc\x4e\x3c\xe3\x65\xc1\x13\x96\xf3\xa9\x11\xcf\xb7\xe8\xea\x7d\ +\xd4\x00\x94\x7b\x15\xff\x89\xb0\x3b\x98\x8a\xdd\x2f\x18\xf9\x64\ +\xd7\x2c\xf7\x75\x04\x17\x5e\x66\x3c\xe9\xfc\x5a\x18\xdd\x8d\x14\ +\xeb\xd1\x7a\x6a\x63\xd7\x39\xaa\xe1\xdc\x4c\x3c\xe3\x65\xc8\x7b\ +\xd5\x88\xe7\x5b\x3d\xd6\x00\x54\xfa\x3d\xf4\x17\x6f\x00\xca\x89\ +\x57\x09\x1a\xf0\x5f\x46\x58\x5e\x9b\xe0\xc2\xcb\x94\x27\x9d\x6b\ +\xfb\xad\x14\x48\xf1\x1f\xe0\x99\xbf\xb6\xf3\xa9\xfe\x99\xff\x6f\ +\x88\x3f\xbc\x2c\x79\x0d\xb3\x6b\x8d\x78\xbe\x45\x0d\x40\xb5\x67\ +\x3d\x0f\x7f\x69\x22\xf6\x8e\xe0\xba\x71\x4d\xf6\x86\xd9\x79\x0c\ +\xc1\x85\x97\x41\xef\xe7\x2c\x17\x3c\x8a\x33\xff\xc5\x33\x84\x61\ +\x5f\x4f\xfc\xe1\x65\xcd\x6b\x2e\x74\x4e\x1e\xf1\x7c\xab\x27\x7a\ +\x86\x2f\xd6\x00\x94\xc6\x59\xfc\x83\x9f\x4d\x9b\xf6\x95\x34\xcb\ +\xb9\x99\xe0\xc2\xcb\x9a\xa7\x5a\xde\xaf\x8e\x74\x3b\x80\xe2\x3f\ +\x98\xcb\xfe\x9c\xf9\xe3\x65\xd2\x93\xce\xaf\xc7\x30\xdf\x6a\x2b\ +\x59\xee\x77\x62\xdc\xc5\x3f\xf6\x20\xe0\xe7\x09\x2e\xbc\x4c\x7a\ +\xfe\x44\x6f\x48\xe7\xa9\x14\xff\xc1\x3f\xf0\xc7\x3d\x7f\xbc\xec\ +\x7a\xee\x27\x52\x3b\xdf\x56\x5b\xf8\x87\xf8\x5e\xef\xdf\x10\x5c\ +\x78\xd9\xf5\x9c\x5b\xa3\xfb\x7d\x14\xff\xc1\xbc\xea\xc7\xd3\xfe\ +\x78\x59\xf6\x84\xe5\xbe\x34\x0b\xf3\x2d\x15\xc9\x63\xce\x58\x5a\ +\x20\xb8\xf0\x32\xee\x1d\x10\x96\xf3\x62\x56\x0c\x5c\xe3\x0a\x7f\ +\xd2\x7e\x3d\xf1\x87\x97\x7d\xaf\xbb\x9d\xe2\x9f\xd0\x9b\xd1\x8c\ +\x87\x13\x5c\x78\x79\xf0\x14\xdd\xfe\xf8\x56\x45\x7f\x20\xc5\x7f\ +\x65\x3f\x07\xd7\xf6\x67\x79\x5f\xbc\x9c\x9c\x0c\x6c\x37\x9d\x7b\ +\x51\xfc\x57\xe0\xa9\xd2\xf9\x31\xc1\x85\x97\x07\x4f\x31\xec\xab\ +\xd4\xe6\xce\xa7\x51\xfc\x93\xfd\x84\xbb\xfa\xb1\xb1\x0f\x5e\x2e\ +\xbc\x60\x9b\x7b\x8a\xff\x0a\x3d\xd5\x72\xdf\x4e\x70\xe1\xe5\xc7\ +\x73\xf6\x07\xbb\x5d\xea\xba\x3e\x41\xf1\x5f\xfe\xc7\xf3\xbc\x49\ +\x7f\xac\x5e\xe5\x37\x4c\x77\x10\x2f\x78\xb9\xf1\xa4\xfd\x0f\x14\ +\xff\x15\x7a\xc2\x72\x1d\x82\x0b\x2f\x7f\x8b\x06\xb9\x5f\x51\x5a\ +\xee\xa3\x29\xfe\x77\xfd\x51\xad\xee\xe9\x9a\x74\xbe\x4d\xbc\xe0\ +\xe5\xce\xd3\xdb\x1d\x8a\xff\x0a\xbd\xa4\x3b\x03\x12\xac\x78\x59\ +\xf3\x54\xe9\xdc\x26\x4c\xef\x65\xcd\xe6\x05\xeb\x8b\x5e\xfc\xe7\ +\x6c\xfb\x1e\x9a\xe5\xfe\x95\x3f\x26\x77\x10\x2f\x78\x79\xf4\xb6\ +\xab\xfa\x23\xd2\x58\xfc\x13\xbf\xfd\x37\xae\xe4\xa1\x5a\xce\xcf\ +\x08\x2e\xbc\xbc\x7a\x7e\x7c\x5f\x2d\x2c\xd7\x2c\x62\xf1\x0f\x76\ +\xfe\xd4\x5a\xdd\x8e\x3f\x0e\xbf\x24\x5e\xf0\xf2\xea\x29\x46\xfb\ +\xca\x14\xce\xdf\x68\xe9\xff\xc4\x8b\x04\xd5\xc6\x91\x3c\x44\xc2\ +\xe7\x00\x08\x56\xbc\x4c\x7b\xd2\xf9\xa2\xff\x3b\x4f\x2b\x4a\xf1\ +\x17\xa6\xbb\x43\xb5\xdc\x6f\x10\x2f\x78\xb9\xf7\x74\xfb\x2d\x29\ +\x2c\xfe\xa5\x44\x0d\x40\x6c\x3f\xe1\xfa\x38\x92\xc7\x72\x1b\x03\ +\x11\x5c\x78\x79\xf5\xfc\x86\xf7\xb3\x6a\x63\x69\x7b\x5e\x8b\xbf\ +\x30\xbd\xad\x9a\xe9\x7d\x89\x78\xc1\x2b\x8a\xa7\xc8\xa5\x5d\x29\ +\x2b\xfe\xd1\x7e\x3f\xbd\x1b\x80\xf0\xcb\xd5\xf0\xec\xbf\x3e\x8e\ +\xe4\xa1\xc8\x3d\x0f\x20\xb8\xf0\x0a\xe7\xc9\xce\xd7\xd5\xe6\x52\ +\x7b\xcb\x96\xb3\x8f\xcd\x7a\xf1\x3f\xf8\x64\xbf\xd5\xdd\x15\x3c\ +\xe0\xc7\xf1\xc5\x2b\x54\xf1\x37\xec\x3b\x94\x56\xf7\xb8\x14\x15\ +\xff\x72\xb8\xdb\xef\x64\xcf\xa5\xff\xc3\x2f\x57\xc2\xb3\xff\x5a\ +\x6c\x6f\xe1\x91\x27\x23\x55\x3a\xff\x4d\x70\xe1\x15\xd4\xfb\x79\ +\xf0\xb0\xa0\x22\xbb\x0f\xca\x5a\xf1\xf7\xe7\xed\xc3\xfc\x7f\xff\ +\x57\x05\x1b\x24\x71\x7c\xf1\x0a\xe9\x49\xef\x6b\x29\x6a\xde\x2b\ +\xe1\xe7\x50\x03\xd0\xaf\x53\x58\x1f\x6b\x00\x6a\xe3\x3a\x13\xd1\ +\x2c\xe7\x6f\x08\x2e\xbc\x82\x7b\x07\x54\xd3\xb9\xc4\x6f\x06\xce\ +\x9d\x35\x3b\xc7\xa7\xb5\xf8\x37\x9b\xdd\xfb\x0b\xd3\xbd\xe0\xf0\ +\xcb\xfc\x1c\x5f\xbc\x22\x7a\xc2\xf2\x5e\x9e\x92\xe2\x5f\x0d\xeb\ +\x79\xd4\x00\x94\xfa\xdd\x23\xa8\xc4\x1a\x80\xe9\xf1\x3e\x30\xe4\ +\x6d\x25\xb8\xf0\xf0\x0e\xad\x2a\x76\xbb\x9f\x58\xbe\xe0\x17\xd9\ +\x17\xaa\x2d\xe7\xf1\xfe\x14\x59\x37\xae\xe2\x1f\x3c\xc9\x2f\xe6\ +\x9d\x27\xfa\x73\xf4\xc5\xc1\xfa\x06\x41\xa3\xc2\xf1\xc5\xc3\x8b\ +\xe6\xaa\xbb\x29\x05\xc5\x3f\xaa\xe1\x51\x03\x30\xd9\xeb\xd2\x7f\ +\x29\xec\x10\xa2\x06\xa0\x3a\xee\x7b\x90\x8b\x8b\x8b\x15\xd5\x72\ +\x6e\x21\xb8\xf0\xf0\x96\xdf\x7e\x58\x95\xee\x47\x34\xd3\x79\xbe\ +\xda\x5c\x9c\x9d\x9d\x6d\x3c\x74\x58\xc5\x7f\xa6\x21\x4f\x69\x18\ +\xce\x56\x61\xb9\x2f\x12\x96\xf3\x71\x21\x9d\xdf\x70\x3c\xf0\xf0\ +\x96\x2b\xfe\xde\x8d\x9b\x36\xed\x2b\x8d\xb9\xf8\x47\x57\xef\xa3\ +\x06\xa0\xdc\xab\xf8\x4f\x84\xdd\xc1\x54\xec\x7e\x41\x2a\x1e\x40\ +\xd2\x2c\xe7\x23\x04\x17\x1e\x5e\x62\xef\x5a\x45\xb6\x2f\xf1\x9b\ +\x82\xb7\xde\x59\xac\xbb\xbb\xfc\x26\x61\xdb\xc1\xd5\xf6\x5a\x7b\ +\x1e\x22\xe6\xdd\x13\x9a\xcd\xce\x86\x85\x85\x85\x69\x5d\xdf\x5b\ +\x0b\xfe\x73\xf0\xbf\xf9\xdf\x79\x68\xc3\x74\x9f\xe0\x17\xf6\x59\ +\x55\x2e\xee\x51\x0d\xfb\x15\xaa\xb4\xff\x59\x31\xda\x5f\x10\x86\ +\x7d\x3d\xc7\x03\x0f\x2f\x99\x27\x2c\xef\x5d\x29\x78\x66\xa7\x1e\ +\x6b\x00\x2a\xfd\x1e\xfa\x8b\x37\x00\xe5\xc4\xab\x04\x8d\xe0\x2f\ +\x13\xec\x07\x4e\x70\xe1\xe1\xe1\xe1\xe1\x65\xc2\x93\xee\xce\x14\ +\x3c\xb0\x1b\x35\x00\xd5\x9e\xf5\x3c\xfc\xa5\x89\xd8\x3b\x82\xa9\ +\x29\xfe\xc1\xef\xcf\xcd\x99\x8f\x24\xb8\xf0\xf0\xf0\xf0\xf0\xd2\ +\xee\x05\xcf\xe9\xa8\x3b\xcf\xbd\x57\x0a\xde\xd6\xa9\x27\x7a\x86\ +\x2f\xd6\x00\x94\xd2\x56\xfc\x23\x4b\x91\xed\x6f\x10\x5c\x78\x78\ +\x78\x78\x78\x69\xf6\x84\xe5\x7d\x2e\x25\xaf\xea\xd6\x56\xb2\xdc\ +\xef\x44\x5a\x8b\x7f\xf0\x11\x86\xfd\x52\x82\x0b\x0f\x0f\x0f\x0f\ +\x2f\xe5\xde\x85\x99\x5a\x9e\x7b\xb5\x85\x7f\x94\x7f\x19\x4d\xda\ +\x8f\x26\xb8\xf0\xf0\xf0\xf0\xf0\xd2\xec\x35\x17\x9c\x07\x67\x75\ +\x97\xcf\x54\x2f\x37\x2a\x4c\xf7\x7b\x04\x2b\x1e\x1e\x1e\x1e\x5e\ +\x3a\xd7\xe9\x70\xbf\x41\xf1\x1f\x92\x17\x2c\x8b\x4a\xb0\xe2\xe1\ +\xe1\xe1\xe1\xa5\xd2\x33\xdd\xe7\x51\xfc\x87\xe4\x35\xcc\xce\x63\ +\x08\x56\x3c\x3c\x3c\x3c\xbc\x34\x7a\xcd\x85\xce\xc9\x14\xff\x61\ +\x6e\x11\x6c\x3a\x97\x11\xac\x78\x78\x78\x78\x78\xa9\xf2\x96\xd9\ +\xfc\x87\xe2\x3f\x60\x4f\x48\xf7\xd9\x04\x2b\x1e\x1e\x1e\x1e\x5e\ +\x9a\x3c\x61\xb9\x7b\x29\xfe\x43\xf6\x76\xb4\xf6\x1c\x2b\xa4\xf7\ +\x5b\x82\x15\x0f\x0f\x0f\x0f\x2f\x15\x9e\x74\x7e\x1d\x2c\xab\x9d\ +\xa5\xe2\x9f\xf8\xed\xbf\xb4\xfd\x65\x84\xe5\x5d\x44\xb0\xe2\xe1\ +\xe1\xe1\xe1\xa5\xc3\x73\xff\x34\x2b\xc5\x3f\xb6\xf4\x7f\xe2\x45\ +\x82\x6a\x69\xfa\xcb\x04\x57\x01\xfc\x8e\xeb\x7a\x82\x15\x0f\x0f\ +\x0f\x0f\x6f\xcc\xde\xcf\x83\x8d\xb5\x32\x54\xfc\x4b\x89\x1a\x80\ +\xd8\x7e\xc2\xf5\xb4\xfd\x65\x84\xe5\xb5\x09\x56\x3c\x3c\x3c\x3c\ +\xbc\x71\x7a\xc2\xec\x36\x33\x54\xfc\xa3\xfd\x7e\x7a\x37\x00\xe1\ +\x97\xab\xe1\xd9\x7f\x3d\x85\x7f\x99\xa3\x55\xc3\xfe\x28\xc1\x8a\ +\x87\x87\x87\x87\x37\x96\xe2\x6f\xb9\xff\x9c\xa1\xe2\x5f\x0e\x77\ +\xfb\x9d\xec\xb9\xf4\x7f\xf8\xe5\x4a\x78\xf6\x5f\x8b\xed\x2d\x9c\ +\x9a\xe2\x1f\xfc\xfe\x56\x45\x7f\xa0\x62\xd8\x57\x11\xac\x78\x78\ +\x78\x78\x78\xa3\x3d\xf3\x77\x2e\x0b\x1e\xfc\xcb\x40\xf1\x3f\x3a\ +\xac\xe7\x95\x78\x03\xd0\xaf\x53\x58\x1f\x6b\x00\x6a\x69\x2b\xfe\ +\x91\x35\xab\x59\xa7\x2b\xa6\xf3\x6b\x82\x15\x0f\x0f\x0f\x0f\x6f\ +\x24\x9e\x74\xae\x09\xd6\xfc\xcf\x48\xf1\xaf\x86\xf5\x3c\x6a\x00\ +\x4a\xfd\xee\x11\x54\x62\x0d\xc0\x74\x5a\x8b\xff\xff\x6d\x14\xe4\ +\x9c\xae\x49\xef\x86\xa2\x07\x6b\xb0\x0f\xb5\x66\x39\x57\x09\xcb\ +\xf9\x94\xb0\xdc\xff\x60\xb2\xe3\xe1\xe1\xad\xd5\x0b\xf2\x89\x2a\ +\xbd\x8f\x09\xd3\xbb\xc2\xcf\x2f\xfb\x29\xfe\xce\xb5\x0d\xd3\x39\ +\x35\x23\xc5\x3f\xaa\xe1\x51\x03\x30\xd9\xeb\xd2\x7f\x29\xec\x10\ +\xa2\x06\xa0\x9a\xf6\xe2\x1f\x79\x4a\xcb\x7d\xb4\xdf\x04\xfc\x34\ +\xef\x93\xd3\x9f\x88\xbf\xf3\xff\xbf\xcb\x85\x74\x3f\xa4\x59\xee\ +\x5f\xf9\x9f\xf3\x54\xe9\x6e\x53\xa5\xf3\x30\xcf\xf3\x26\xa3\xf1\ +\x6a\x36\x2f\x58\xef\x7f\xf7\xc7\x24\x37\x3c\x3c\xbc\xd5\x7b\xce\ +\x95\x8b\x8b\x8b\x95\x28\xaf\x6c\xda\xb4\xaf\xa4\xb5\xf6\x3c\x44\ +\x98\xdd\x73\x54\xd3\xdb\xad\x5a\xce\xc5\x42\x3a\x1f\xf0\x8b\xe2\ +\xb7\x85\x69\xdf\x92\xff\xf1\x73\xae\xd4\xac\xee\x29\x19\x29\xfe\ +\xd1\xd5\xfb\xa8\x01\x28\xf7\x2a\xfe\x13\x61\x77\x30\x15\xbb\x5f\ +\x90\x89\xe2\x1f\xfd\xe8\xfa\xde\xfb\xfa\x4d\xc0\x67\x33\x3f\x39\ +\xa5\x77\x83\x30\x3a\xdf\x54\x65\xe7\xfd\xaa\xb4\xff\x52\x95\xed\ +\xf3\xe6\xf4\x5d\xdb\x54\xab\x7d\x92\xff\xd7\x4c\xbc\x75\xb3\x30\ +\xdd\x39\x92\x1b\x1e\x1e\xde\x6a\x3d\xff\xac\x7f\xeb\x4a\xf2\xf3\ +\x8c\x66\x3c\x7c\x56\xdf\xb5\x55\xe8\x4b\xbb\x35\xb3\xf3\xd2\xe0\ +\x21\x39\x4d\xba\x5f\x89\xbf\xb6\x9d\xe1\xe2\xff\xef\xcd\x66\x67\ +\x43\x46\x8a\x7f\xf4\xdc\x5e\xd4\x00\x54\xfa\x3d\xf4\x17\x6f\x00\ +\xca\x89\x57\x09\x4a\xd9\xa2\x41\xba\xae\x4f\x68\xa6\xfb\x27\x7e\ +\x67\x7a\x4b\xaa\x83\x4b\x3a\xd7\xf8\x9f\x4b\x85\xe5\xbd\xcd\x9f\ +\x24\x2f\x6a\x98\x5d\x4b\xb5\xba\xa7\x2b\xad\xee\x71\x83\x1c\x3f\ +\xff\xcf\xfa\x10\xc9\x0d\x0f\x0f\x6f\xc5\xc5\xdf\xf2\xde\x35\xc8\ +\xfc\xac\xeb\xde\x31\x6a\xcb\x79\x7c\xc3\x74\x8c\x60\xd7\x3c\xff\ +\x04\xe5\xcd\x07\x4f\xd8\xee\xbc\x72\x7b\x20\xad\xe3\xe7\xd7\x92\ +\x9b\x82\x2b\xad\xc1\xc9\x57\x86\x8a\xff\x31\xb1\x06\xa0\xda\xb3\ +\x9e\x87\xbf\x34\x11\x7b\x47\x30\x93\xc5\x3f\xfe\xa3\xc8\xee\x83\ +\x54\xcb\xfd\x97\x78\x60\x8d\x36\xb8\x9c\xfd\xaa\x74\x7f\xe8\x07\ +\xce\x27\xfc\xff\xed\x6f\xfd\x80\x7f\x96\xff\xbf\xab\xc1\xad\x8a\ +\x99\x19\xaf\x3a\xaa\xf1\xdb\x21\xe6\x1f\x29\xa4\x73\x13\xc9\x0d\ +\x0f\x0f\x2f\xb1\x27\xbd\x1b\x82\x2b\xaa\xa3\xca\xf7\xc1\x6d\x06\ +\xc5\x68\x9f\xaa\x1a\x4b\x52\xd1\xdb\xcf\x53\x0d\xfb\x0d\x42\x76\ +\x3e\xa1\x18\xf6\x95\xaa\x74\x6e\x1b\xc7\xf8\x05\xcf\x54\x09\xd3\ +\x7b\xeb\x9c\x69\xdf\x2f\x23\xaf\xfa\x1d\xbd\xcc\x9a\x3d\xd3\x49\ +\x17\xfc\x99\x08\x9f\x01\xc8\x7c\xf1\xbf\xeb\x16\xc2\xce\xa9\x41\ +\xa7\x19\xec\x1f\x30\xf8\xc9\x64\xdf\x22\xa4\x7d\xb9\x30\xec\x8f\ +\xa8\x46\xfb\x75\x7e\x00\x5f\xd8\x30\x9c\xad\x7e\xe1\x7f\x68\x70\ +\xaf\x2c\x2d\xe3\xe7\x4f\xaa\xe7\x90\xdc\xf0\xf0\xf0\x12\x3f\x50\ +\x6c\x3a\x6e\x5a\xf2\x7d\x70\x55\x37\x38\xa1\x6b\x48\xef\x2c\x61\ +\xb9\x5d\x3f\x9f\xbf\xd2\x3f\xa1\x7a\x9f\x7f\x92\xf5\xad\x3b\xcf\ +\xce\x07\xbe\xab\xdf\x0d\xfe\x89\xdb\x6b\x82\x3c\x9e\xa1\xe5\x7d\ +\x97\xf3\x6a\x2b\x59\xee\x77\x22\x6f\xc5\x3f\xee\xcd\xcc\x34\x4e\ +\x50\x8c\x45\x5b\x18\x9d\x77\x29\xa6\x7d\x4d\xd2\x60\xf0\xbb\xc0\ +\xff\xf1\xff\xf9\x55\xcd\xf4\xde\xe9\x77\x83\x2f\xd3\x5a\xce\x92\ +\x66\x74\x36\x6d\x17\xc6\xc3\x36\x6f\x3e\xe3\x9e\x59\x08\x86\xe0\ +\xdf\x53\x91\xf6\x97\x48\x6e\x78\x78\x78\x09\xbc\x4f\x67\x29\xdf\ +\xcf\x9a\x9d\xe3\x1b\xd2\x7d\xb2\x26\xdd\x9d\x7e\x8e\x7e\xb1\x9f\ +\xab\xff\x49\xc8\xce\x57\x15\xd3\xb9\x2e\xe9\xf8\x05\x57\x6b\x85\ +\xe5\xfd\x83\xff\x3d\x11\x7f\xe8\x31\xc3\xc5\x3f\xb9\xb7\xda\xc2\ +\x9f\xe5\xc1\x69\x36\xbb\xf7\x6b\xc8\xee\x66\x61\x75\x77\xf9\x41\ +\xf3\xcc\xe0\x9e\x54\xf0\xec\x80\xdf\xf9\xed\xf1\x3f\x8d\x86\xe9\ +\xfd\x3f\x65\x71\xf1\x9e\x79\xf9\xfb\x2a\x86\xfd\x88\x5e\xcf\x45\ +\x90\x2c\xf1\xf0\xf0\x82\x2b\xa5\xc1\xfb\xed\x79\xc9\xf7\x8a\xa2\ +\x9f\xa8\x36\x16\xcf\xf0\x73\xbb\xd0\x5a\x9e\xe7\xff\x1d\x2f\xf4\ +\x3f\xcf\x09\xee\xe9\x07\xcf\x5d\x69\xad\xee\x53\x82\x07\xfb\xf2\ +\x56\xdf\x0a\xb5\x45\x30\x5e\x32\x2f\x0c\x7e\x92\x25\x1e\x1e\xde\ +\x91\x76\xb5\xdb\x43\x3e\xa5\xf8\x33\x38\x39\xf4\xf6\xed\xdb\x77\ +\xb4\x6a\x3a\x97\x90\x2c\xf1\xf0\xf0\x96\x29\xfe\x9f\x38\xd2\x6b\ +\xc6\xe4\x53\x8a\x3f\x83\x9d\x03\x2f\x78\x98\x46\x48\xe7\x37\x24\ +\x4b\x3c\x3c\xbc\xd8\x6b\xc9\xbf\x6e\x36\xbb\xf7\x27\x9f\x52\xfc\ +\x19\x9c\x9c\x7b\x0d\xd3\x5d\x24\x59\xe2\xe1\xe1\x1d\xbe\xa5\x2d\ +\xf9\x94\xe2\xcf\xe0\x14\xc0\x0b\xd7\x48\x20\x59\xe2\xe1\x15\xdd\ +\x33\xdd\xb7\x90\x4f\x29\xfe\x0c\x4e\x81\xbc\x60\x55\x2e\x61\x7a\ +\x3f\x22\x59\xe2\xe1\x15\xf9\xcc\xdf\xfd\xde\xc2\xc2\xc2\x34\xf9\ +\xb4\x78\xc5\x3f\xf1\xdb\x7f\x0c\x76\x3e\xbd\x60\xe9\xe1\x68\x95\ +\x2d\x92\x25\x1e\x5e\xb1\xbc\x60\x63\x31\xa5\xe5\x3c\x96\x7c\x5a\ +\x38\x2f\x5a\xfa\x3f\xf1\x22\x41\x35\x06\x3b\x9f\x9e\x9f\x28\x2e\ +\x24\x59\xe2\xe1\x15\xcf\x0b\x56\xd5\x23\x9f\x16\xb2\xf8\x97\x12\ +\x35\x00\xb1\xfd\x84\xeb\x0c\x76\x7e\x3d\x55\xef\x7c\x90\x64\x89\ +\x87\x57\x20\xcf\xf4\xde\x41\xfe\x2b\x64\xf1\x8f\xf6\xfb\xe9\xdd\ +\x00\x84\x5f\xae\x86\x67\xff\x75\x06\x3b\xbf\x5e\xb0\x5a\x96\x30\ +\x3b\x57\x90\x2c\xf1\xf0\x8a\xe0\xb9\xdf\x39\x7c\x43\x32\xf2\x69\ +\x21\x8a\x7f\x39\xdc\xed\x77\xb2\xe7\xd2\xff\xe1\x97\x2b\xe1\xd9\ +\x7f\x2d\xb6\xb7\x30\x83\x9d\x53\x4f\xd5\x77\xfe\x61\xaf\x8d\x35\ +\x48\xbe\x78\x78\xd9\xf7\x54\xcb\xbb\x51\xb3\xba\xa7\x90\xff\x0a\ +\xe7\x55\xc2\xcf\xa1\x06\xa0\x5f\xa7\xb0\x3e\xd6\x00\xd4\x18\xec\ +\xfc\x7b\x6a\xcb\xd3\x0e\xdf\x3e\x99\xe4\x8b\x87\x97\x93\xe2\x2f\ +\x9d\x3b\xfc\xe2\xbf\x9d\xfc\x57\x38\xaf\x1a\xd6\xf3\xa8\x01\x28\ +\xf5\xbb\x47\x50\x89\x35\x00\xd3\x0c\x76\x71\x3c\xcd\xf4\xf6\x91\ +\x2c\xf1\xf0\xf2\xe7\x09\xcb\x7b\x2e\xf9\xaf\x70\x5e\x54\xc3\xa3\ +\x06\x60\xb2\xd7\xa5\xff\x52\xd8\x21\x44\x0d\x40\x95\xc1\x2e\x9c\ +\xb7\xce\x6f\x02\xde\x4d\xf2\xc5\xc3\xcb\x8f\xa7\x5a\xde\x3f\x92\ +\xff\x0a\xe7\x45\x57\xef\xa3\x06\xa0\xdc\xab\xf8\x4f\x84\xdd\xc1\ +\x54\xec\x7e\x01\x83\x5d\x40\xaf\xd9\xbc\x60\xbd\x9f\x34\xbe\x4a\ +\xf2\xc5\xc3\xcb\xc5\x99\xff\x17\xb6\x6e\x3d\xbf\x4c\xfe\x2b\x9c\ +\x57\x8f\x35\x00\x95\x7e\x0f\xfd\xc5\x1b\x80\x72\xe2\x55\x82\x18\ +\xec\x5c\x7a\xba\xbe\xf7\xbe\xaa\xe5\x5c\x4d\xf2\xc5\xc3\xcb\xb2\ +\xe7\x5c\xd9\x6c\xb6\x8f\x23\xff\x15\xd2\x8b\x1a\x80\x6a\xcf\x7a\ +\x1e\xfe\xd2\x44\xec\x1d\x41\x8a\x3f\xde\x51\x0d\xd3\x39\x55\x93\ +\xde\x0d\x24\x5f\x3c\xbc\x0c\x7a\xd2\xb9\x3e\xfe\xc4\x3f\xf9\xaf\ +\x70\x5e\x3d\xd1\x33\x7c\xb1\x06\xa0\x44\xf1\xc7\x8b\xff\xa8\x96\ +\xbb\xc9\x3f\x8b\xb8\x95\xe4\x8b\x87\x97\xa5\x7b\xfe\xce\x2d\xaa\ +\xe5\x3d\x89\xfc\x57\x68\x2f\xd9\xdb\x7b\xb1\x06\x80\xe2\x8f\x77\ +\xb7\x1f\x21\x3d\x5d\x31\xec\x3b\x48\xbe\x78\x78\x99\x78\xe0\xef\ +\x76\x61\xba\x73\xe4\x3f\xbc\xa4\xc0\xaa\x0a\x3f\x83\x5d\x1c\x4f\ +\x31\x96\x9e\x49\xf2\xc5\xc3\x4b\xbd\x77\xa0\x61\xba\x36\xf9\x0f\ +\xef\xa8\x61\xff\x30\xd8\xc5\xf2\x54\xa3\xfd\x67\x24\x5f\x3c\xbc\ +\x54\x7b\x17\x92\xaf\xf0\x28\xfe\x78\x43\xf1\x34\xd3\x79\x39\xc9\ +\x17\x0f\x2f\x85\x9e\xe9\xed\x23\x5f\xe1\x51\xfc\xf1\x86\xea\xf9\ +\xc9\xe6\xd5\x24\x5f\x3c\xbc\xf4\x78\xc2\xf2\x2e\x22\x5f\xe1\x51\ +\xfc\xf1\x46\xe2\x69\x96\xfb\x1a\x92\x2f\x1e\x5e\x2a\xbc\x57\x93\ +\xaf\xf0\x28\xfe\x78\x23\xf5\x34\xcb\xf9\x1b\x92\x2f\x1e\xde\x18\ +\xcf\xfc\x4d\xf7\x2f\xc9\x57\x78\x14\x7f\xbc\xb1\x78\xaa\xe5\x5c\ +\x4c\x32\xc7\xc3\xe3\xb2\x3f\x5e\xb6\x8a\x7f\xe2\xb7\xff\x18\x6c\ +\xbc\x5e\x3f\x7e\xe2\x7a\x05\xc9\x1c\x0f\x6f\xa4\xc5\xff\xe5\xe4\ +\x2b\xbc\xd5\x16\xfe\x70\xdd\x9f\xc4\x8b\x04\xd5\x18\x6c\xbc\x23\ +\xfd\x04\xef\x1d\x93\xcc\xf1\xf0\x46\xe7\xf9\x0d\x40\x9b\x7c\x85\ +\xb7\xca\xe2\x5f\x4a\xd4\x00\xc4\xf6\x13\xae\x33\xd8\x78\x47\xfa\ +\xd1\xa4\x73\x29\xc9\x1c\x0f\x6f\x74\x9e\xdf\x00\x7c\x8e\x7c\x85\ +\xb7\x8a\xe2\x1f\xed\xf7\xd3\xbb\x01\x08\xbf\x5c\x0d\xcf\xfe\xeb\ +\x0c\x36\xde\xf2\x0f\x02\x76\x4f\x21\x99\xe3\xe1\x8d\xde\x9b\x11\ +\xad\x8d\xe4\x2b\xbc\x15\x14\xff\x72\xb8\xdb\xef\x64\xcf\xa5\xff\ +\xc3\x2f\x57\xc2\xb3\xff\x5a\x6c\x6f\x61\x06\x1b\xef\xae\x0d\x80\ +\xe9\xfe\x39\xc9\x1c\x0f\x6f\xf4\x9e\x2a\xdb\xaf\x24\x5f\xe1\x25\ +\xf4\x2a\xe1\xe7\x50\x03\xd0\xaf\x53\x58\x1f\x6b\x00\x6a\x0c\x36\ +\xde\xe1\x3f\xfb\xf6\xed\x3b\x5a\x93\xde\x4f\x49\xe6\x78\x78\xe3\ +\xf0\x3a\x3f\xdb\xbe\x7d\xcb\xb1\xe4\x2b\xbc\x3e\x5e\x35\xac\xe7\ +\x51\x03\x50\xea\x77\x8f\xa0\x12\x6b\x00\xa6\x19\x6c\xbc\x65\x1f\ +\xfe\x33\x9c\xad\x24\x73\x3c\xbc\xf1\x79\x8a\xbe\xa4\x90\xaf\xf0\ +\xfa\x3c\xc3\x37\x1d\x6b\x00\x26\x7b\x5d\xfa\x2f\x85\x1d\x42\xd4\ +\x00\x54\x19\x6c\xbc\x23\x79\xc2\xe8\xbc\x97\x64\x8e\x87\x37\x3e\ +\x4f\x58\xee\x3b\xc9\x57\x78\x47\xf0\xa2\xab\xf7\x51\x03\x50\xee\ +\x55\xfc\x27\xc2\xee\x60\x2a\x76\xbf\x80\xc1\xc6\x5b\xd6\xdb\xae\ +\xa9\x0f\x50\x0c\xe7\x77\x24\x73\x3c\xbc\xf1\x79\xaa\xf4\x7e\xa7\ +\xeb\xde\x31\xe4\x2b\xbc\x65\xbc\x7a\xac\x01\xa8\xf4\x7b\xe8\x2f\ +\xde\x00\x94\x13\xaf\x12\xc4\x60\x17\xd2\x53\x8d\xa5\x0b\x49\xe6\ +\x78\x78\xe3\xf7\x84\xe5\x76\xc9\x57\x78\xcb\x78\x51\x03\x50\xed\ +\x59\xcf\xc3\x5f\x9a\x88\xbd\x23\x48\xf1\xc7\xeb\xe9\x09\xc3\xfe\ +\x1a\xc9\x17\x0f\x6f\xfc\x9e\xb0\x9c\x2f\x93\xaf\xf0\x96\xf1\xea\ +\x89\x9e\xe1\x8b\x35\x00\x25\x8a\x3f\x5e\x3f\x4f\xd5\x17\x9e\x40\ +\xf2\xc5\xc3\x4b\x8f\xa7\xca\xce\x23\xc9\x57\x78\x87\x79\xc9\xde\ +\xde\x8b\x35\x00\x14\x7f\xbc\xbe\x9e\x90\xf6\x6b\x48\xbe\x78\x78\ +\xe9\xf1\x84\xe9\xbe\x92\x7c\x85\xb7\x2a\x6f\xb5\x85\x9f\xc1\x2e\ +\x9e\x77\xd6\x59\x33\xf7\xf2\x93\xd1\xb5\x24\x5f\x3c\xbc\xf4\x78\ +\xaa\xe5\xfc\x42\xd7\xf5\x09\xf2\x15\x1e\x5b\x04\xe3\x0d\xcd\x53\ +\x8d\x25\x49\xf2\xc5\xc3\x4b\x9f\x27\x4c\x77\x07\xf9\x0a\x8f\xe2\ +\x8f\x37\x34\x4f\x33\xdd\xf7\x93\x7c\xf1\xf0\x52\xb8\x45\xb0\xf4\ +\xde\x4b\xbe\xc2\xa3\xf8\xe3\x0d\xc5\xdb\x21\xed\xfb\xa8\xd2\xb9\ +\x8d\xe4\x8b\x87\x97\x3e\x4f\xb5\xbc\xdf\xab\x3b\xcf\xbd\x17\xf9\ +\x0a\x8f\xe2\x8f\x37\x70\x4f\xb3\xdc\x3f\x26\xf9\xe2\xe1\xa5\xd7\ +\xf3\x7f\xf7\x8f\xc9\x57\x78\x14\x7f\xbc\x81\x7b\x9a\xe5\x7c\x8b\ +\xe4\x8b\x87\x97\x62\xcf\x70\xbe\x4d\xbe\xc2\xa3\xf8\xe3\x0d\xd4\ +\x6b\x98\xbb\x1f\x47\xf2\xc5\xc3\x4b\xbf\x37\x27\x76\x3e\x85\xfc\ +\x87\x97\xc0\x5c\xc7\xe0\xe0\x25\xf2\x34\xcb\x7d\x0d\xc9\x17\x0f\ +\x2f\xfd\x9e\x6a\xd8\x7f\x47\xfe\xc3\xeb\x55\xf8\xc3\x75\x7f\x12\ +\x2f\x12\x54\x63\xb0\x8b\xeb\xe9\xba\x3e\xa5\x49\xe7\x7a\x92\x2f\ +\x1e\x5e\x06\x3c\xc3\xbe\x7e\x61\xa1\x55\x26\xff\xe1\x1d\xa1\xf8\ +\x97\x12\x35\x00\xb1\xfd\x84\xeb\x0c\x76\x71\x3d\xff\xec\xbf\x41\ +\xf2\xc5\xc3\xcb\xd0\x2e\x81\x2d\x4f\x23\xff\xe1\x2d\x53\xfc\xa3\ +\xfd\x7e\x7a\x37\x00\xe1\x97\xab\xe1\xd9\x7f\x9d\xc1\x2e\xae\xa7\ +\x59\xce\xbf\x91\x7c\xf1\xf0\xb2\xe3\x09\xe9\x7e\x88\xfc\x87\x77\ +\x58\x3d\x2f\x87\xbb\xfd\x4e\xf6\x5c\xfa\x3f\xfc\x72\x25\x3c\xfb\ +\xaf\xc5\xf6\x16\x66\xb0\x0b\xe6\x89\x79\xf7\x04\xd5\xf2\x6e\x27\ +\xf9\xe2\xe1\x65\xc9\x73\xf6\xcf\x9a\x9d\xe3\xc9\x7f\x78\xa1\x57\ +\x09\x3f\x87\x1a\x80\x7e\x9d\xc2\xfa\x58\x03\x50\x63\xb0\x8b\xe9\ +\x69\xa6\xfb\x27\x24\x5f\x3c\xbc\xec\x79\x42\xba\xcf\x26\xff\xe1\ +\x85\x57\xf2\xd7\xc7\x1a\x80\x52\xbf\x7b\x04\x95\x58\x03\x30\xcd\ +\x60\x17\xd7\xf3\x13\xc9\xe5\x24\x5f\x3c\xbc\xec\x79\xfe\xff\x77\ +\x19\xf9\xaf\xf0\x5e\x54\xc3\xa3\x06\x60\xb2\xd7\xa5\xff\x52\xd8\ +\x21\x44\x0d\x40\x95\xc1\x2e\xae\xd7\x30\xdd\x27\x90\x7c\xf1\xf0\ +\xb2\xbc\x4b\x60\xf7\x74\xf2\x5f\x61\xbd\xe8\xea\x7d\xd4\x00\x94\ +\x7b\x15\xff\x89\xb0\x3b\x98\x8a\xdd\x2f\x60\xb0\x0b\xec\x69\xd2\ +\xfb\x7b\x92\x2f\x1e\x5e\x76\x3d\xff\x7b\x7f\x4b\xfe\x2b\xac\x57\ +\x8f\x35\x00\x95\x7e\x0f\xfd\xc5\x1b\x80\x72\xe2\x55\x82\x18\xec\ +\x5c\x7a\xcd\xe6\x05\xeb\x55\xcb\xbb\x91\xe4\x8b\x87\x97\x61\x4f\ +\x7a\x37\x2c\x2e\x2e\x56\xc8\x7f\x85\xf4\xa2\x06\xa0\xda\xb3\x9e\ +\x87\xbf\x34\x11\x7b\x47\x90\xe2\x5f\x70\x4f\x93\x6e\x8b\xe4\x8b\ +\x87\x97\x7d\x4f\x58\xae\x49\xfe\x2b\xa4\x57\x4f\xf4\x0c\x5f\xac\ +\x01\x28\x51\xfc\xf1\xee\x7c\xf8\xcf\xfd\x04\xc9\x17\x0f\x2f\xfb\ +\x9e\xb0\x9c\x8f\x93\xff\x0a\xe9\x25\x7b\x7b\x2f\xd6\x00\x50\xfc\ +\xf1\x8e\x52\xe4\x9e\x07\xa8\xd2\xb9\x83\xe4\x8b\x87\x97\x7d\x2f\ +\x98\xcb\xb3\x0d\xf3\x11\xe4\x3f\xbc\x23\x3e\x03\x70\xd4\x2a\x7f\ +\x18\xec\xfc\x79\x9a\xe9\xbd\x90\xe4\x8b\x87\x97\x1f\x4f\x91\xf6\ +\x4b\xc8\x7f\x78\x03\xfd\x61\xb0\x73\xe9\xad\xd3\x2c\xe7\x4a\x92\ +\x2f\x1e\x5e\x7e\x3c\xc5\x68\x5f\x49\xfe\xc3\xa3\xf8\xe3\xf5\x3e\ +\xfb\x6f\x79\x7f\x44\xf2\xc5\xc3\xcb\x9f\x37\xa7\x2f\x3e\x9d\xfc\ +\x87\x47\xf1\xc7\xeb\x71\xf9\xdf\x7d\x0b\xc9\x12\x0f\x2f\x7f\x9e\ +\xb0\xdc\xb7\x90\xff\xf0\x28\xfe\x78\xcb\xfe\x2c\x2c\x2c\x4c\xab\ +\x96\x73\x13\xc9\x12\x0f\x2f\x87\x5b\x04\xfb\x73\x3b\x98\xe3\xe4\ +\x3f\x3c\x8a\x3f\xde\x32\x97\xff\x3b\x6d\x92\x25\x1e\x5e\x7e\x3d\ +\x61\x75\x77\x91\xff\xf0\x18\x1c\xbc\xbb\x79\x8a\x6c\x7f\x9e\x64\ +\x89\x87\x97\x5f\x4f\x58\xee\x7f\x90\xff\xf0\x42\x73\x1d\x83\x83\ +\x77\xd0\x9b\x11\xad\x8d\x24\x4b\x3c\xbc\xdc\x7b\x07\x9a\x0b\xce\ +\x83\xc9\x7f\x85\xf6\xa2\xa5\xff\x13\x2f\x12\x54\x63\xb0\xf3\xed\ +\xa9\xb2\xfd\x4a\x92\x25\x1e\x5e\xfe\x3d\x61\x7a\x2f\x26\xff\x15\ +\xba\xf8\x97\x12\x35\x00\xb1\xfd\x84\xeb\x0c\x76\x7e\xbd\xed\xdb\ +\xb7\x1c\xab\x98\xf6\x4f\x49\x96\x78\x78\x45\xf0\x9c\xab\xfc\xe9\ +\xbf\x8e\xfc\x57\xc8\xe2\x1f\xed\xf7\xd3\xbb\x01\x08\xbf\x5c\x0d\ +\xcf\xfe\xeb\x0c\x76\x7e\x3d\xc5\xd8\xa5\x90\x2c\x53\xec\x49\xe7\ +\x3a\xad\xd5\xed\x68\xa6\xf3\x12\xcd\xf4\xde\xe1\xff\xf7\x4b\x55\ +\xcb\xb9\x5a\xb5\xbc\xdb\xc7\xfd\xef\xa7\x4a\xe7\x36\x55\xba\x3f\ +\x54\x4d\xe7\x33\xfe\x99\xe5\x5b\x85\xe5\xbe\xa8\x61\xba\x8b\xfe\ +\xbf\xe3\xf5\x1c\xdf\xf4\x7a\xfe\x77\x9f\x46\xfe\x2b\x5c\xf1\x2f\ +\x87\xbb\xfd\x4e\xf6\x5c\xfa\x3f\xfc\x72\x25\x3c\xfb\xaf\xc5\xf6\ +\x16\x66\xb0\x73\xe8\x29\xb2\xfd\x6e\x92\x65\x7a\x3d\xbf\xb8\xba\ +\xcb\x1d\x47\x5d\xd7\x27\x9a\xcd\xee\xfd\x55\xab\x7b\xba\xda\xea\ +\x2a\x5a\xcb\xf3\x82\x02\xec\x9f\xe1\xbd\xf6\xe0\x31\x95\x9d\x4f\ +\xa8\xb2\xf3\x65\x21\xed\xcb\x85\x69\x5f\xed\x17\xe5\x6b\x85\x74\ +\x7e\xe3\xff\xff\xb7\xc6\x9b\x87\x3b\xff\xf3\xc1\xff\x2d\xd8\xfe\ +\xf9\x97\x7e\x21\xff\x91\xff\x9f\xff\x2b\x68\x34\xfc\xff\xfd\xdf\ +\x54\xcb\x7d\xbb\x6f\xbc\x5e\x95\xed\x97\x2a\xc6\xd2\xf9\xaa\xbe\ +\x68\xce\x69\x3b\x9f\x3a\x63\x2c\x9d\xb0\xdc\x99\x64\xf0\xa3\x9a\ +\xde\x6e\x8e\x6f\x7a\x3d\x3f\x4e\xde\x4e\xfe\x2b\x94\x57\x09\x3f\ +\x87\x1a\x80\x7e\x9d\xc2\xfa\x58\x03\x50\x63\xb0\xf3\xe9\xcd\xcc\ +\x68\x0f\x50\x4c\xfb\x16\x92\x65\x6a\xbd\xaf\xee\xdb\xb7\xef\xe8\ +\xac\xc5\x5f\xf0\xef\xec\x37\x0f\x5f\xe7\xf8\xa6\xd3\x53\x2d\xe7\ +\x96\xf9\xf9\xf3\xeb\xe4\xd3\x42\x78\xd5\xb0\x9e\x47\x0d\x40\xa9\ +\xdf\x3d\x82\x4a\xac\x01\x98\x66\xb0\xf3\xeb\xf9\x67\x75\xcf\x20\ +\x59\xa6\xd6\x3b\x10\x9c\xdd\x67\x35\xfe\xc4\xbc\xf3\xc4\xe0\xef\ +\xc0\xf1\x4d\xa7\x27\x2c\xc7\x25\x9f\xe6\xde\x8b\x6a\x78\xd4\x00\ +\x4c\xf6\xba\xf4\x5f\x0a\x3b\x84\xa8\x01\xa8\x32\xd8\xf9\xf6\x54\ +\xd3\xf9\x1c\xc9\x32\xa5\x8b\xb6\x98\xee\x9b\xb3\x1e\x7f\xc1\x73\ +\x01\x1c\xdf\xb4\x7a\x9d\x4b\xc8\xa7\xb9\xf6\xa2\xab\xf7\x51\x03\ +\x50\xee\x55\xfc\x27\xc2\xee\x60\x2a\x76\xbf\x80\xc1\xce\xb1\xa7\ +\xb4\xba\xc7\x05\x7b\x85\x93\x2c\x53\xe8\x49\xe7\xd7\x33\x96\x77\ +\xef\xac\xc7\x9f\x58\xd8\x7d\x9f\xe0\xd9\x02\x8e\x6f\x1a\x3d\x7b\ +\xbf\xa2\xe8\x27\x92\x4f\x73\xeb\xd5\x63\x0d\x40\xa5\xdf\x43\x7f\ +\xf1\x06\xa0\x9c\x78\x95\x20\x06\x3b\xb3\x9e\xda\xf2\x34\x92\x65\ +\x4a\x57\x6c\x33\xbd\x73\xf3\x12\x7f\xaa\x6c\x3f\x97\xe3\x9b\x4e\ +\x4f\x69\xee\x32\xc8\xa7\xb9\xf5\xa2\x06\xa0\xda\xb3\x9e\x87\xbf\ +\x34\x11\x7b\x47\x90\xe2\x5f\x00\x4f\x58\xde\x45\x24\xcb\x14\x7a\ +\xd2\xfb\x66\xf0\x84\x7f\x5e\xe2\x6f\xcb\x96\xb3\x36\x08\xa3\x7d\ +\x19\xc7\x37\x85\x9e\xb1\x74\x11\xf9\x34\xb7\x5e\x3d\xd1\x33\x7c\ +\xb1\x06\xa0\x44\xf1\x2f\x8e\xe7\x27\x84\x8f\x92\x2c\x53\xe8\xb5\ +\xba\x4f\xc9\x5b\xfc\xcd\xe9\x3b\x77\x70\x7c\x53\xb8\x45\xb0\xf4\ +\xde\x47\x3e\xcd\xad\x97\xec\xed\xbd\x58\x03\x40\xf1\x2f\x90\xe7\ +\x27\x85\xcb\x49\x96\xe9\xf2\xe2\xef\x67\xe7\x2d\xfe\x34\xd3\xfb\ +\x17\xe2\x25\x6d\x8b\x4c\x79\x5f\x23\x9f\x16\xdc\x5b\x6d\xe1\x67\ +\xb0\xb3\xed\x25\x59\xad\x8d\x64\x39\xc2\xe2\x2f\x9d\xdf\xe8\xfa\ +\xde\xfb\xe6\x35\xfe\xee\x5c\xb4\xc8\xb9\x89\x78\x49\xd1\x22\x53\ +\x96\x73\x35\xf9\x14\x8f\xe2\x5f\x40\x2f\x58\x0c\x84\x64\x99\x2a\ +\xef\xc2\xdc\xdf\x76\x32\xdd\x3f\x21\x5e\x52\xf5\xb6\xc9\x75\xe4\ +\x53\x3c\x06\xa7\x80\x5e\xbf\x06\x80\x64\x39\x3a\xcf\xff\xff\x2e\ +\xdb\xb4\x69\x5f\x29\xef\xf1\xe7\x79\xde\xa4\x30\xdd\xef\x11\x2f\ +\xe9\xf0\x54\xcb\xfb\x15\xf9\x14\x8f\xc1\x29\xa0\x77\x70\x93\x19\ +\x92\x65\x3a\xbc\x96\x7b\x66\x51\xe2\x4f\x98\xdd\x73\x88\x97\x94\ +\xdc\x76\x32\xbd\x1f\x91\x4f\x29\xfe\x0c\x4e\x01\xbd\x23\x3d\x04\ +\x48\xb2\x1c\xf1\xfe\xec\x96\xf7\xae\xc2\x35\x9f\x96\xf7\x7e\xe2\ +\x25\x05\x57\x9e\x2c\xe7\xcb\xe4\x53\x8a\x3f\x83\x53\x40\x4f\x95\ +\xee\x47\x48\x96\x63\x2e\xfe\xd2\xfb\xad\x98\x77\x4e\x2c\x5c\xf3\ +\xd9\xb2\x1f\xb8\xdc\x2d\x28\xe2\x65\xc4\x9e\xe9\xbd\x93\x7c\x4a\ +\xf1\x67\x70\x0a\xe8\x1d\xbe\x10\x10\xc9\x72\x0c\x9e\xe9\x3e\xaf\ +\xb8\xf1\x17\x6c\x5d\x4c\xbc\x8c\xd7\x73\x5f\x40\x3e\x2d\x66\xf1\ +\x4f\xfc\xf6\x1f\x83\x9d\x4f\x2f\xbe\x14\x30\xc9\x72\x2c\xde\xf7\ +\x75\x5d\x9f\x2a\x6a\xfc\x6d\xdd\x7a\x7e\x59\xb3\x9c\x2b\x89\x97\ +\xf1\x79\x0d\xe9\x9d\x45\x3e\x2d\x9c\x17\x2d\xfd\x9f\x78\x91\xa0\ +\x1a\x83\x9d\x3f\xaf\xd9\xec\x6c\x08\x36\x03\x22\x59\x8e\xcb\x73\ +\xb6\x14\x3d\x9e\x35\xd3\x55\x88\x97\xf1\x78\xaa\xf4\x7e\xd7\x6c\ +\x5e\xb0\x9e\x7c\x5a\xb8\xe2\x5f\x4a\xd4\x00\xc4\xf6\x13\xae\x33\ +\xd8\xf9\xf4\x14\xd9\xfe\x3c\xc9\x72\x0c\x9e\xe9\xfe\x2b\xf1\x77\ +\xa7\x27\x64\xfb\x63\xc4\xcb\x18\x3c\xd3\xfb\x30\xf1\x57\xb8\xe2\ +\x1f\xed\xf7\xd3\xbb\x01\x08\xbf\x5c\x0d\xcf\xfe\xeb\x0c\x76\x3e\ +\x3d\x55\xb6\xff\x98\x64\x39\xe2\x33\x2f\xcb\xb9\x45\x91\xdd\x07\ +\x11\x7f\x77\x7a\x8a\x6e\x3e\x4e\x98\xf6\xad\xc4\xcb\x68\x3d\x61\ +\xb9\x26\xf1\x57\xa8\xe2\x5f\x0e\x77\xfb\x9d\xec\xb9\xf4\x7f\xf8\ +\xe5\x4a\x78\xf6\x5f\x8b\xed\x2d\xcc\x60\xe7\xcc\xdb\x2a\x94\x13\ +\x55\xc3\xfe\x5f\x92\xe5\x48\xcf\xbc\xf6\x11\x7f\x77\xf5\x84\xd1\ +\xbe\x98\x78\x19\xa9\xf7\xcb\xe8\xf9\x13\xe2\xaf\x10\x5e\x25\xfc\ +\x1c\x6a\x00\xfa\x75\x0a\xeb\x63\x0d\x40\x8d\xc1\xce\x75\xf2\x7d\ +\x35\xc9\x72\x34\x5e\xb0\xf0\xca\xe2\xe2\x62\x85\xf8\xbb\xab\xb7\ +\x63\xc7\x62\x4d\xb3\xdc\x9f\x10\x2f\x23\xf2\xc2\xb7\x4f\x88\xbf\ +\x42\x78\xd5\xb0\x9e\x47\x0d\x40\xa9\xdf\x3d\x82\x4a\xac\x01\x98\ +\x66\xb0\xf3\xed\x29\xad\xee\x71\xaa\xe5\xdd\x48\xb2\x1c\xbe\xa7\ +\xb6\xba\x0a\xf1\xb7\xbc\x27\xcc\x6e\x93\x78\x19\x89\xe7\x9f\xfd\ +\xef\xad\x11\x7f\x85\xf0\xa2\x1a\x1e\x35\x00\x93\xbd\x2e\xfd\x97\ +\xc2\x0e\x21\x6a\x00\xaa\x0c\x76\x51\x92\xaf\xf7\x4c\x92\xe5\xd0\ +\xbd\x8f\x12\x7f\xbd\x3d\xd5\xf4\x3e\x49\xbc\x0c\xd9\x6b\x39\x4b\ +\xc4\x5f\x21\xbc\xe8\xea\x7d\xd4\x00\x94\x7b\x15\xff\x89\xb0\x3b\ +\x98\x8a\xdd\x2f\x60\xb0\x0b\xe2\xe9\xba\x3e\xa1\x99\xde\x97\x48\ +\x96\xc3\xf2\x9c\x5b\x9b\x0b\x9d\x93\x89\xbf\xde\x9e\x2a\x3b\x8f\ +\x54\xa5\x73\x1b\xf1\x32\x2c\xcf\xfd\x04\xf1\x57\x18\xaf\x1e\x6b\ +\x00\x2a\xfd\x1e\xfa\x8b\x37\x00\xe5\xc4\xab\x04\x31\xd8\xb9\xf1\ +\xb4\xd6\x9e\x87\x68\xd2\xbb\x81\x64\x39\x78\x4f\x58\xde\xcb\x89\ +\xbf\xc4\xbb\x54\x5e\x4c\xfc\x0d\xc1\x93\xce\xb5\xaa\x65\xdf\x9f\ +\xf8\x2b\x8c\x17\x35\x00\xd5\x9e\xf5\x3c\xfc\xa5\x89\xd8\x3b\x82\ +\x14\xff\x82\x7a\xc2\xf4\xb6\xaa\x96\x77\x3b\xc9\x77\x90\x9e\xfb\ +\x93\x99\x19\xaf\x4a\xfc\x25\xf3\xe6\x6c\xfb\x1e\x7e\xb1\xba\x86\ +\xf8\x1b\xa4\xe7\xdc\xaa\x9a\xee\x1f\x11\x7f\x85\xf2\xea\x89\x9e\ +\xe1\x8b\x35\x00\x25\x8a\x3f\x5e\x70\x8f\xd0\x4f\x1a\x07\x48\xbe\ +\x83\xf1\x44\xcb\xd3\x89\xbf\x95\x79\x0d\xd3\x5b\x20\xfe\x06\x56\ +\xfc\xf7\xab\x96\xdb\x20\xfe\x0a\xe7\x25\x7b\x7b\x2f\xd6\x00\x50\ +\xfc\xf1\xee\xbc\x12\x60\x79\xed\xf8\x95\x00\x92\xef\x2a\x8b\xbf\ +\xe5\x7c\x8a\xf8\x5b\x9d\xe7\xc7\xe0\xe7\x88\xbf\xb5\x79\xfe\x1c\ +\xfe\xbd\x66\x3a\x4d\xe2\x0f\xaf\x17\xb0\xaa\xc2\xcf\x60\xe7\xdb\ +\x53\xa5\xbb\x2d\x78\x3d\x90\xe4\xbb\xca\xe4\x2b\x9d\xdb\x14\xa3\ +\x7d\x2a\xf1\xb7\x3a\xaf\x61\x76\x1e\x13\x34\xa1\xc4\xdf\xea\xef\ +\xf9\x6b\x46\x67\x13\xf1\x87\x37\x94\x1f\x06\x3b\xff\xde\x8c\x68\ +\x6d\x54\x65\xfb\x3f\x49\xbe\xab\x39\xfb\xea\xfc\x25\xf1\xb7\x36\ +\x4f\x35\x3a\x6f\xa0\xf8\xaf\x22\xf6\x4c\xe7\x33\x8d\x86\xf3\x00\ +\xe2\x0f\x8f\xe2\x8f\xb7\x26\x6f\xcb\x96\xb3\x36\xa8\xc6\xd2\x0b\ +\x54\xc3\xb9\x99\xe4\x9b\xf8\xec\xeb\x9a\x6d\x9a\x7a\x3f\xe2\x6f\ +\x6d\xde\x36\xa1\x9c\xa4\x98\xce\x75\x14\xff\xa4\x71\xe7\xdd\xa0\ +\x9a\xde\xee\x8d\x1b\x4f\x9b\x20\xff\xe1\x51\xfc\xf1\x06\xe6\xcd\ +\x19\xde\x03\x85\xf4\xde\x4b\xf2\x4d\xe0\xe9\x6d\x97\xf8\x1b\x8c\ +\xa7\xca\xf6\x79\x14\xff\xbe\x9f\x03\xc2\xf2\xde\x26\x16\x76\xdf\ +\x87\x7c\x85\x47\xf1\xc7\x1b\x9a\xd7\x90\xee\xd3\xfd\x84\xf3\x7d\ +\x92\xef\x91\x2e\xbf\x76\xbe\x40\xbc\x0c\xce\xdb\xbc\xf9\x8c\x63\ +\x34\xe9\x7e\x85\xe2\x7f\xc4\xb3\xfe\x6f\x6a\xad\xee\x53\x88\x17\ +\x3c\x8a\x3f\xde\x48\x3c\xcf\xf3\x26\x85\x74\x9f\x2d\xa4\xf3\x1b\ +\x8a\xff\xff\x7d\x14\xd3\xb9\x5d\x69\xb4\x9e\x42\xbc\x0c\xd6\x6b\ +\x98\xde\xff\x53\xa5\x73\x07\xc5\xff\x2e\xb7\x99\xae\x0b\x2e\xf7\ +\xef\xdb\xb7\xef\x68\xe2\x05\x8f\xe2\x8f\x37\x72\x6f\xd6\xec\x1c\ +\xef\x27\xa2\x37\x2d\x97\x9c\x8b\xf8\xf4\xb6\x6a\xd8\x6f\x20\x5e\ +\x86\xe3\xf9\x63\xfc\x46\x8a\xff\x9d\x6f\x97\x68\x96\xfb\x57\xca\ +\xe2\xe2\x3d\x89\x17\xbc\x35\xd4\xf4\x75\x0c\x0e\xde\x60\xd6\x0d\ +\x30\xba\x1b\xe3\x1b\xb9\x14\xb1\xf8\x07\x0f\xab\x05\x0f\xad\x11\ +\x2f\xc3\xf1\xd4\x9d\xe7\xde\x4b\xb5\xbc\xff\x29\x72\xf1\x17\xd2\ +\xf9\x80\x66\x75\x4f\x21\x5e\xf0\xd6\xe0\x45\x4b\xff\x27\x5e\x24\ +\xa8\xc6\x60\xe3\x25\xf9\x51\x0d\x67\x87\x30\xec\xef\x16\xf2\xd5\ +\x2d\x7d\xe9\x5c\xe2\x65\xb8\x9e\xb0\xdc\xbd\x85\x2c\xfe\xa6\xf7\ +\xa5\x86\x74\x9e\x4a\xbc\xe0\x0d\xa0\xf8\x97\x12\x35\x00\xb1\xfd\ +\x84\xeb\x0c\x36\x5e\x52\x6f\xfb\xf6\x2d\xc7\x2a\x46\x7b\xb7\x62\ +\x74\x7e\x52\x94\xe2\x1f\xac\x95\xb0\x79\xf3\x19\xf7\x24\x5e\x86\ +\xeb\x05\xf7\xbb\x55\xcb\xfd\x46\x51\x8a\xbf\x2a\x9d\xff\xf6\xbf\ +\x23\x88\x17\xbc\x01\x15\xff\x68\xbf\x9f\xde\x0d\x40\xf8\xe5\x6a\ +\x78\xf6\x5f\x67\xb0\xf1\x56\xea\x6d\xdb\xf6\xf4\x7b\x09\xd3\x7d\ +\x86\x9f\xc8\x7e\x99\xe7\xe2\xaf\x18\xf6\x1d\x4a\x63\xe7\x66\xe2\ +\x65\x34\x5e\x43\xba\x4f\xce\xff\x5e\x15\xce\x55\xc1\x9e\x1c\xc1\ +\x36\xdd\xc4\x0b\xde\x80\x8a\x7f\x39\xdc\xed\x77\xb2\xe7\xd2\xff\ +\xe1\x97\x2b\xe1\xd9\x7f\x2d\xb6\xb7\x30\x83\x8d\xb7\x62\x2f\xd8\ +\x09\xcf\x4f\x6a\xcf\x09\x9e\x5a\xce\xe3\x03\x5c\xaa\xd1\x7e\x2b\ +\xf1\x32\x5a\x4f\xb5\xbc\x7f\xcc\x65\xf1\x97\xde\x4f\x35\xcb\xdd\ +\xe3\x17\xfe\x29\xe2\x05\x6f\x80\x5e\x25\xfc\x1c\x6a\x00\xfa\x75\ +\x0a\xeb\x63\x0d\x40\x8d\xc1\xc6\x5b\xab\xa7\xeb\x7b\x6b\xc2\xf2\ +\x9e\xdb\xaf\x11\xc8\x54\x32\x37\xec\xeb\x77\x68\xe6\x83\x38\xbe\ +\xa3\xf5\x82\xb7\x4f\x82\x7d\x2a\x72\x53\xfc\xfd\xc2\x2f\x4c\xef\ +\xdc\xad\x5b\xcf\x2f\x73\x7c\xf1\x06\xec\x55\xc3\x7a\x1e\x35\x00\ +\xa5\x7e\xf7\x08\x2a\xb1\x06\x60\x9a\xc1\xc6\x1b\xa4\xb7\xb0\xb0\ +\x30\xad\x99\xee\xb3\x54\xcb\xf9\x45\xe6\x2f\xe3\xea\xb6\xcd\xf1\ +\x1d\x8f\x27\x2c\xc7\xcd\x7e\xf1\x77\xae\x12\x96\xdb\xed\x75\xc6\ +\x4f\xbc\xe0\xad\xc1\x8b\x6a\x78\xd4\x00\x4c\xf6\xba\xf4\x5f\x0a\ +\x3b\x84\xa8\x01\xa8\x32\xd8\x78\xc3\xf2\x16\x17\x17\x2b\xc1\x42\ +\x26\xaa\x74\x7f\x98\xc5\xe2\xaf\x4a\xfb\x5f\x38\xbe\xe3\xf5\x54\ +\xbd\xf3\xc1\x6c\x16\x7f\xf7\x3b\x7e\x03\x33\xbf\x69\xd3\xbe\x12\ +\xc7\x17\x6f\x48\x5e\x74\xf5\x3e\x6a\x00\xca\xbd\x8a\xff\x44\xd8\ +\x1d\x4c\xc5\xee\x17\x30\xd8\x78\x43\xf7\xe6\xe6\x66\x26\xd5\x66\ +\x7b\x49\x18\x9d\x6f\x66\x26\x99\xfb\xff\xae\x3b\x76\x2c\xd6\x38\ +\xbe\xe3\xf5\xb6\x0a\xe5\x44\x21\xed\xcb\xb3\x52\xfc\xfd\xb3\xfd\ +\xff\xd0\xac\xee\x76\x8e\x2f\xde\x08\xbc\x7a\xac\x01\xa8\xf4\x7b\ +\xe8\x2f\xde\x00\x94\x13\xaf\x12\xc4\x60\xe3\x0d\x72\xe3\x97\xc6\ +\xe2\x0e\xd5\xb0\x3f\xba\xdc\x53\xde\xe9\x39\xf3\x77\x7e\xd8\x6c\ +\x76\xef\xc7\xf1\x4d\x87\x37\xdb\x30\x1f\xa1\x4a\xef\xc7\x69\x8d\ +\x17\xc5\xb0\x6f\xd3\x4c\xef\x9f\xd4\x96\xf3\x78\x8e\x2f\xde\x08\ +\xbd\xa8\x01\xa8\xf6\xac\xe7\xe1\x2f\x4d\xc4\xde\x11\xa4\xf8\xe3\ +\x8d\xd5\x0b\x56\x3b\xd3\x2c\xf7\x35\x7e\xe2\xfc\xdf\x74\x15\xff\ +\xce\x0f\x54\xab\x7d\x12\xc7\x37\x5d\x9e\x22\xbb\x0f\xd2\x2c\xe7\ +\xca\x34\x15\xff\x60\x65\x48\xbf\x99\x7d\xd5\xac\xb1\x78\x22\xc7\ +\x17\x6f\x0c\x5e\x3d\xd1\x33\x7c\xb1\x06\xa0\x44\xf1\xc7\x4b\x93\ +\x37\x67\xdb\xf7\xf0\x1b\x81\xf3\xfc\xe4\x7a\x79\x0a\x2e\xfb\x5f\ +\xaa\xb4\xba\xc7\x71\x7c\xd3\xe9\x05\x5b\xe1\x0a\xcb\xfb\x42\x1a\ +\x16\x85\x12\xfa\xd2\x9e\x73\xce\x51\xee\xcd\xf1\xc5\x1b\xa3\x97\ +\xec\xed\xbd\x58\x03\x40\xf1\xc7\x4b\xad\xa7\x5a\xee\x26\xcd\xf4\ +\xde\xa9\x5a\xde\xef\x47\x7a\x26\x67\xd8\x77\x08\xa3\xfd\xea\x33\ +\xcf\xdc\x33\xc5\xf1\x48\xb7\x17\xec\x52\xe9\x1f\xbf\x57\xf5\xdb\ +\x39\x70\xe0\xf1\x22\x9d\x9b\x82\xf5\x20\x94\xc6\xae\xa7\x72\x3c\ +\xf0\x32\xe5\xad\xb6\xf0\x33\xd8\x78\xe3\xf0\x66\x2c\xef\xde\x7e\ +\xd2\xbd\xd0\x4f\xda\x97\x0d\xbd\xf8\xcb\xce\x77\xe7\xf4\x5d\x67\ +\x73\x3c\xb2\xe5\x69\xad\xee\x53\xfc\x46\xf1\xbf\x86\x5e\xfc\x4d\ +\xef\x4b\x8a\xb1\x74\xde\x8e\x1d\xda\xfd\x39\x1e\x78\x59\xf7\x18\ +\x1c\xbc\x4c\x79\x6a\x73\xe7\xd3\x84\x6e\xbf\x45\x18\xce\x8d\x83\ +\x2d\xfe\x9d\x2b\x82\xcb\xb8\x3b\x76\x6c\xbd\x27\xc7\x23\x9b\x5e\ +\xb0\x6f\x40\xc3\x74\x17\xfd\xe3\xfa\xfd\x01\x17\xff\x9f\x0b\xcb\ +\xbb\x48\x31\xda\xa7\x72\x3c\xf0\x28\xfe\x0c\x36\xde\x98\xbd\xd9\ +\xd9\xed\xc7\x2b\x72\x69\x97\x66\xba\x1f\xd4\x2c\xe7\xd6\xd5\x14\ +\x7f\xc5\xb4\x6f\x11\xd2\xfe\xd7\xb9\xe6\xae\x26\x1b\xfb\xe4\xca\ +\x5b\x27\xa4\xbb\x5d\x95\x9d\xf7\xab\x86\x73\xf3\x6a\x8a\x7f\xb0\ +\xea\x60\xb0\xfc\x70\x43\xba\x4f\x0f\xd6\xe7\xe7\x78\xe0\x51\xfc\ +\x19\x6c\xbc\x14\x7a\xc1\x4a\x83\x6a\xcb\x99\xf1\x9b\x81\xbf\x10\ +\x96\xf3\x71\x61\x7a\x3f\x3a\xbc\x29\x50\xa5\xf7\xbb\xf0\xa9\xf1\ +\x8f\x6a\xa6\xf3\xf2\xb9\xe6\x62\x63\xfb\x76\x71\x5f\xc6\x2f\xdf\ +\xde\xc1\x46\xd1\xd8\xa5\xa8\xb2\xfd\x8a\x3b\x9b\x45\xef\x72\x21\ +\x9d\xdf\xc4\x62\xe3\x80\x26\xbd\x1b\xfc\x62\xff\x5d\xff\x3f\xbf\ +\x5f\x33\xbd\x17\x06\xcf\x9e\x04\xcf\x16\x30\x7e\x78\x14\x7f\x06\ +\x1b\x2f\xa3\x5e\xb3\x79\xc1\xfa\xf9\xf9\xf3\xeb\xc1\x0a\x84\x8c\ +\x1f\xde\xe1\xb7\x0b\xc2\xe5\x78\xd7\x31\x7e\x78\x14\x7f\x06\x07\ +\x0f\x0f\x0f\x0f\x0f\x8f\xe2\xcf\x60\xe3\xe1\xe1\xe1\xe1\xe1\xe5\ +\xa3\xf8\x27\x7e\xfb\x8f\xc1\xc6\xc3\xc3\xc3\xc3\xc3\xcb\x85\x17\ +\x2d\xfd\x9f\x78\x91\xa0\x1a\x83\x8d\x87\x87\x87\x87\x87\x97\xf9\ +\xe2\x5f\x4a\xd4\x00\xc4\xf6\x13\xae\x33\xd8\x78\x78\x78\x78\x78\ +\x78\x99\x2e\xfe\xd1\x7e\x3f\xbd\x1b\x80\xf0\xcb\xd5\xf0\xec\xbf\ +\xce\x60\xe3\xe1\xe1\xe1\xe1\xe1\x65\xb6\xf8\x97\xc3\xdd\x7e\x27\ +\x7b\x2e\xfd\x1f\x7e\xb9\x12\x9e\xfd\xd7\x62\x7b\x0b\x33\xd8\x78\ +\x78\x78\x78\x78\x78\xd9\xf2\x2a\xe1\xe7\x50\x03\xd0\xaf\x53\x58\ +\x1f\x6b\x00\x6a\x0c\x36\x1e\x1e\x1e\x1e\x1e\x5e\xe6\xbc\x6a\x58\ +\xcf\xa3\x06\xa0\xd4\xef\x1e\x41\x25\xd6\x00\x4c\x33\xd8\x78\x78\ +\x78\x78\x78\x78\x99\xf3\xa2\x1a\x1e\x35\x00\x93\xbd\x2e\xfd\x97\ +\xc2\x0e\x21\x6a\x00\xaa\x0c\x36\x1e\x1e\x1e\x1e\x1e\x5e\xe6\xbc\ +\xe8\xea\x7d\xd4\x00\x94\x7b\x15\xff\x89\xb0\x3b\x98\x8a\xdd\x2f\ +\x60\xb0\xf1\xf0\xf0\xf0\xf0\xf0\xb2\xe7\xd5\x63\x0d\x40\xa5\xdf\ +\x43\x7f\xf1\x06\xa0\x9c\x78\x95\x20\x06\x1b\x0f\x0f\x0f\x0f\x0f\ +\x2f\x6d\x5e\xd4\x00\x54\x7b\xd6\xf3\xf0\x97\x26\x62\xef\x08\x52\ +\xfc\xf1\xf0\xf0\xf0\xf0\xf0\xb2\xeb\xd5\x13\x3d\xc3\x17\x6b\x00\ +\x4a\x14\x7f\x3c\x3c\x3c\x3c\x3c\xbc\xcc\x7b\xc9\xde\xde\x8b\x35\ +\x00\x14\x7f\x3c\x3c\x3c\x3c\x3c\xbc\xa2\x78\xab\x2d\xfc\x0c\x36\ +\x1e\x1e\x1e\x1e\x1e\x5e\x3e\x3c\x06\x07\x0f\x0f\x0f\x0f\x0f\x8f\ +\xe2\xcf\xe0\xe0\xe1\xe1\xe1\xe1\xe1\x51\xfc\xef\xfa\x87\xc7\xf7\ +\x08\xa8\x0f\x60\xb9\x60\x3c\x3c\x3c\x3c\x3c\x3c\xbc\x11\x7a\xab\ +\xf9\xc3\xe3\x7b\x04\xd4\x06\xb0\x5c\x30\x1e\x1e\x1e\x1e\x1e\x1e\ +\xde\x08\xbd\xd5\xfc\xe1\xd5\xd8\xfa\xc2\xd3\x03\x58\x2e\x18\x0f\ +\x0f\x0f\x0f\x0f\x0f\x6f\x84\xde\x4a\xff\xf0\x75\xb1\x3d\x02\xd6\ +\xc7\x36\x17\x58\x87\x87\x87\x87\x87\x87\x87\x97\x0d\x2f\x32\x57\ +\xf2\x87\x97\x63\x7b\x04\x54\xd6\xb8\x5c\x30\x1e\x1e\x1e\x1e\x1e\ +\x1e\xde\x78\xbc\x89\xa4\x8b\x04\xad\x8b\xed\x11\x10\x7d\x26\xd7\ +\xf8\x87\xe3\xe1\xe1\xe1\xe1\xe1\xe1\x8d\xde\x2b\x25\x6a\x00\x62\ +\x5f\x9e\x8c\x7d\x4a\x03\xf8\xc3\xf1\xf0\xf0\xf0\xf0\xf0\xf0\xc6\ +\xe3\x25\x6a\x00\x26\x0e\xff\x1c\xb5\x86\x1f\x3c\x3c\x3c\x3c\x3c\ +\x3c\xbc\x54\x78\xeb\xfa\x75\x0b\x47\xc7\x3e\xeb\xd6\xf8\x87\xe3\ +\xe1\xe1\xe1\xe1\xe1\xe1\xa5\xc4\xfb\xff\x01\x0a\x14\x31\x69\x9b\ +\xf3\x10\xa8\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x07\xca\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x01\x04\x00\x00\x01\x04\x08\x06\x00\x00\x00\xce\x08\x4a\x0a\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x04\x67\x41\x4d\x41\x00\x00\xb1\x8f\x0b\xfc\x61\x05\x00\x00\x00\ +\x09\x70\x48\x59\x73\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7\x6f\ +\xa8\x64\x00\x00\x07\x5f\x49\x44\x41\x54\x78\x5e\xed\xdc\x4d\x88\ +\xdd\x57\x1d\xc7\xe1\xab\x4d\x9b\xa0\x22\x9a\xf7\xa4\x69\xa6\x25\ +\x2f\x77\x3a\x58\xc4\x85\x6b\x2d\xba\x70\xd1\x56\xa9\x0b\xa1\x2b\ +\xdd\xd4\x95\xe0\xc2\x97\x9d\xdb\x42\x40\x8c\x25\x62\x0b\xb5\x69\ +\xd0\xbe\x10\x15\x69\x34\xe9\xb4\x21\x49\x33\xb4\xe9\xcc\xa4\xe0\ +\xa6\xad\xe2\xc2\x8d\x0b\xb1\x54\x11\x54\xc4\xda\x9c\xe3\xb9\x93\ +\xd3\x9f\xc4\x9c\x4c\xe7\xe5\x26\xde\xff\xbd\xcf\x07\x1e\xc8\x72\ +\xce\xe5\x9c\x2f\x33\x79\xeb\x49\x92\x24\x49\x92\x24\x49\x92\x24\ +\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\ +\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\ +\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\ +\x49\x92\x24\x49\x92\x24\x49\x92\x74\x8d\xd2\x63\xbd\xdd\xe9\x58\ +\xef\xf3\xe9\x68\xef\x5b\xe9\x89\xde\x91\xe2\x68\x7e\xa2\x77\x7c\ +\x1c\x95\xb3\x1d\xca\xc7\x7b\x37\xd5\xa3\x4b\x1a\x94\x1e\xef\xdd\ +\x55\x06\xe0\xbb\xe5\x81\xfc\xb6\x3c\x94\x3c\x49\xca\x99\x9f\x36\ +\x0a\x52\xa9\x8c\xc0\xe7\xca\x83\x98\x6b\x3d\x94\x49\x62\x14\x34\ +\xd1\x95\x1f\x09\x0e\x96\x31\x38\xdd\x7a\x1c\x93\xca\x28\x68\x22\ +\x2b\x17\xff\xab\xc5\x3f\x5b\x8f\x62\xd2\x19\x05\x4d\x4c\xf9\xd1\ +\xde\xcd\xe5\xbb\x82\x1f\xb7\x1e\x02\xff\x65\x14\x34\xf6\x95\x31\ +\xf8\x40\x19\x83\x53\xad\x07\xc0\xd5\x8c\x82\xc6\xb6\xc1\xc5\x2e\ +\x63\xf0\x6c\xeb\xe2\x73\x6d\x46\x41\x63\x59\x19\x83\xc3\xad\x0b\ +\xcf\x7b\x33\x0a\x1a\xab\xca\x18\x7c\xb1\x75\xd1\x59\x39\xa3\xa0\ +\xb1\x28\x1d\xeb\x6d\x29\x97\xf9\xcd\xd6\x25\x67\x75\x8c\x82\x3a\ +\x5f\xb9\xc4\x3f\x6c\x5d\x6e\xd6\xc6\x28\xa8\xb3\xa5\xc7\x7a\x53\ +\xe5\xc7\x85\x7f\xb7\x2e\x36\x6b\x67\x14\xd4\xc9\xca\xc5\x7d\xb8\ +\x75\xa1\x59\x3f\xa3\xa0\x4e\x95\xbe\xdf\xdb\x58\xbe\x3b\xf8\x4b\ +\xeb\x32\x33\x1c\x46\x41\x9d\xc9\x9f\x2c\xdc\x18\x46\x41\x9d\xa8\ +\x0c\xc2\x23\xad\x0b\xcc\xf0\x19\x05\x8d\x7c\xe5\x92\x4e\xdc\xff\ +\x69\xf0\xff\x64\x14\x34\xb2\xe5\xa3\xbd\x4d\xe5\x82\x5e\x6a\x5d\ +\x5c\xae\x1f\xa3\xa0\x91\x6c\xf0\x3f\x1f\xb5\x2e\x2c\xd7\x9f\x51\ +\xd0\xc8\x55\x2e\xe5\xdd\xad\xcb\xca\x8d\x61\x14\x34\x52\x95\x0b\ +\x79\x5f\xeb\xa2\x72\xe3\x18\x05\x8d\x4c\xe5\x47\x86\x07\x5a\x97\ +\x74\xc5\x9e\xde\x98\xf3\x89\x8f\xe6\x7c\x7a\x77\xce\x73\xb7\xe7\ +\xfc\xca\x81\x9c\xe7\x0f\xe6\xbc\x38\x0d\xdd\x53\xee\x6e\x7a\xe5\ +\xc0\xa5\x34\x77\xc7\xdf\xd3\xd9\xdb\x7e\x9f\x9e\xdf\xf5\xf3\xf4\ +\xdc\xb6\xfb\x73\xee\xbd\xbf\x3e\x99\xf1\x6e\x4d\x83\xf0\xe4\xcd\ +\x39\x9f\xdc\x9a\xf3\x4b\xfb\xda\x1f\x2a\x8c\x99\xf4\xd2\xbe\xb7\ +\xd3\xe9\xdd\x73\xe9\xd4\x96\x4f\xd6\xa7\x33\x9e\xad\x6a\x10\x06\ +\x43\xf0\xfc\xae\x9c\x17\xfa\xcd\x0f\x0d\xc6\x5e\xb9\xfb\xe9\xcc\ +\x9e\x37\xd2\xa9\xad\x9f\xa8\x4f\x68\xbc\x5a\xd1\x20\x1c\x2b\x4e\ +\x6c\xf6\xa3\x00\x54\x69\xfe\x60\x4a\x2f\xec\xfe\x45\x3e\xd7\xdb\ +\x50\x9f\xd2\x78\xf4\x9e\x83\xf0\x93\x0d\x39\x9f\xbb\xad\xf9\xa1\ +\xc0\xa4\x4b\xe7\xa7\xde\xca\xb3\x5b\xa6\xeb\x73\xea\x7e\xcb\x0e\ +\xc2\x53\xb7\xe4\xfc\xb2\xdf\x27\x80\xe5\xa4\x97\xf7\xbd\x9d\x5e\ +\xd8\xfe\x99\xfa\xa4\xba\xdd\x35\x07\xe1\x99\x8d\x39\x5f\x38\xd0\ +\xfc\x00\x80\x2b\xa5\x0b\xfb\x2f\xa5\x53\x3b\xee\xad\xcf\xaa\xbb\ +\x35\x07\x61\xf0\x63\xc2\x85\xfd\xcd\x83\x03\x6d\x65\x14\xde\xe9\ +\xfc\x9f\x42\x5c\x35\x08\xc7\xde\x77\xf9\xef\x13\x34\x0e\x0c\x2c\ +\x2f\xcd\xdd\xfe\xb7\x7c\x6e\xdb\x87\xea\xf3\xea\x5e\x57\x0d\xc2\ +\x73\xdb\x9b\x07\x05\x56\x26\x9d\xb9\x75\xa1\x3e\xaf\xee\x75\xc5\ +\x20\x3c\xb3\xa9\x79\x40\x60\x75\xd2\xc9\x1d\x5f\xaa\x4f\xac\x5b\ +\x5d\x31\x08\xe7\xa7\x9a\x87\x03\x56\xe9\xfc\xd4\x5f\xeb\x13\xeb\ +\x56\x31\x08\x3f\xfd\x60\xfb\x60\xc0\x9a\xa4\xd9\xed\x5f\xaf\xcf\ +\xac\x3b\xc5\x20\x9c\xd9\xd3\x3c\x14\xb0\x36\xe9\xc5\xbd\x7f\xaa\ +\xcf\xac\x3b\x2d\x0d\xc2\xe0\x8f\x19\x1b\x07\x02\xd6\x61\xf0\xef\ +\x1e\x4e\x6d\x9e\xa9\x4f\xad\x1b\x2d\x0d\xc2\xe0\x9f\x2f\xb7\x0e\ +\x04\xac\x4b\x9a\xdd\xf9\x54\x7d\x6a\xdd\x68\x69\x10\xce\xdc\xda\ +\x3c\x0c\xb0\x3e\xe9\xec\xde\x3f\xd4\xa7\xd6\x8d\x96\x06\xc1\x5f\ +\x51\x86\xeb\x62\xf0\x57\x9a\xeb\x53\xeb\x46\xf9\xc9\x8d\x0f\xb6\ +\x0e\x02\x0c\x47\xfa\xd5\xce\xa9\xfa\xdc\x46\xbf\x74\x62\xf3\x77\ +\x5a\x87\x00\x86\x23\xcd\x6e\xfb\x4a\x7d\x6e\xa3\x5f\x3a\xb9\xf5\ +\xa1\xd6\x21\x80\xe1\x48\xb3\x3b\xbe\x5d\x9f\xdb\xe8\x57\xbe\xd8\ +\xc3\xad\x43\x00\xc3\x91\x66\x77\x1e\xaa\xcf\x6d\xf4\x2b\x5f\xec\ +\x91\xd6\x21\x80\xe1\x18\xbc\xb1\xfa\xdc\x46\x3f\x83\x00\xd7\x97\ +\x41\x00\x82\x41\x00\x82\x41\x00\x82\x41\x00\x82\x41\x00\x82\x41\ +\x00\x82\x41\x00\x82\x41\x00\x82\x41\x00\x82\x41\x00\x82\x41\x00\ +\x82\x41\x00\x82\x41\x00\x82\x41\x00\x82\x41\x00\x82\x41\x00\x82\ +\x41\x00\x82\x41\x00\x82\x41\x00\x42\xb7\x06\x61\xee\xf6\xaf\xb5\ +\x0e\x01\x0c\xc7\xe0\x8d\xd5\xe7\x36\xfa\xa5\x85\xfe\x03\xad\x43\ +\x00\xc3\x31\x78\x63\xf5\xb9\x8d\x7e\x06\x01\xae\x2f\x83\x00\x04\ +\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\ +\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\ +\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\ +\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\ +\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\ +\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\ +\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\ +\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\ +\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\ +\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\ +\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\ +\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\ +\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\ +\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\ +\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\x83\x00\x04\ +\x83\x00\x04\x83\x00\x04\x83\x00\x84\x6e\x0d\xc2\x62\xff\xbe\xd6\ +\x21\x80\xe1\x28\x6f\xec\xde\xfa\xdc\x46\xbf\x34\xdf\xbf\xbb\x75\ +\x08\x60\x48\x2e\xf6\x3f\x5d\x9f\xdb\xe8\x97\x2e\xf6\xef\x6a\x1e\ +\x02\x18\x8a\xb4\x38\xfd\xb1\xfa\xdc\x46\xbf\x7c\x6e\x6a\x53\xf9\ +\x82\xdf\x69\x1d\x04\x58\x9f\xa5\xb7\xf5\xda\xcc\x2d\xf5\xb9\x75\ +\xa3\xb4\x30\xfd\x9b\xd6\x61\x80\xf5\x49\x8b\xfd\xd7\xeb\x33\xeb\ +\x4e\x65\x10\x1e\x69\x1d\x06\x58\x9f\xb4\xd0\x3f\x52\x9f\x59\x77\ +\x2a\xdf\xd6\xdc\xdf\x3a\x0c\xb0\x3e\x83\x3f\xc5\xab\xcf\xac\x3b\ +\xa5\xdf\xed\xdf\x58\xbe\xf0\x3f\xb7\x0e\x04\xac\x4d\x79\x53\x6f\ +\x75\xee\xf7\x0f\xde\xad\x7c\x97\xf0\x70\xeb\x50\xc0\xda\x94\x1f\ +\x17\xbe\x57\x9f\x57\xf7\xca\xaf\xce\xec\x2d\x07\xf8\x57\xeb\x60\ +\xc0\xea\x0c\xde\x52\x9a\xdf\xbf\xa7\x3e\xaf\x6e\x56\x0e\xf1\x83\ +\xd6\xe1\x80\xd5\x49\x0b\xd3\x87\xeb\xb3\xea\x6e\xf9\xd7\x1f\xff\ +\x48\x39\xc8\x9b\xad\x03\x02\x2b\x93\x16\xfb\x7f\x2c\xdf\x1d\x7c\ +\xb8\x3e\xab\x6e\x97\xe7\xef\xfc\x42\x19\x85\xd4\x3a\x28\xb0\xbc\ +\xc1\xdb\x29\xee\xa9\xcf\x69\x3c\x1a\xfc\x66\x48\xeb\xb0\xc0\xf2\ +\xca\x18\x1c\xaa\xcf\x68\x7c\xca\xc7\x7b\x37\x95\x83\x3d\xdb\x3a\ +\x30\xd0\x56\xde\xcc\xcf\x06\x6f\xa7\x3e\xa3\xf1\xea\xf2\xbf\x71\ +\xe8\xff\xb2\x75\x70\xe0\x4a\x65\x0c\x4e\x74\xf6\xef\x1c\xac\xb4\ +\x7c\xee\x53\x1b\xca\x41\x7f\xd4\xfa\x00\x80\xcb\xca\x8f\xd8\x8f\ +\x8e\xed\x77\x06\xad\xca\xa1\x1f\x2c\x87\xfe\xc7\xff\x7e\x10\x30\ +\xc9\x96\xde\xc4\x42\xff\xcb\xf5\x99\x4c\x56\xe9\xe2\xfe\x7d\xe5\ +\x03\x38\xd9\xfa\x60\x60\xd2\x0c\x7e\x9c\x4e\xf3\x07\xef\xa8\xcf\ +\x63\x72\xcb\x8b\x77\x7e\xb6\xac\xe2\x8b\xad\x0f\x09\xc6\x5d\x5a\ +\x9c\x3e\x3b\xf8\x5f\xc6\xea\x73\xd0\xbb\xa5\xf9\x99\x99\xb2\x92\ +\x0f\x15\xaf\xb7\x3e\x38\x18\x17\xe5\x8e\xbf\x36\xb8\xeb\xf9\xd5\ +\x83\xd3\xf5\xfa\x6b\xb9\xd2\xc5\xe9\x5d\x69\x61\xfa\x9e\xf2\xa1\ +\x7d\x73\xf0\x8f\xa4\xca\xaf\x1f\x2f\x1f\xe4\x71\xe8\x9a\xc1\xdd\ +\x5d\xba\xc3\x8b\xfd\x6f\x0c\xee\x74\x5e\x98\xd9\x59\xaf\xb9\x24\ +\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\ +\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\ +\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\ +\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\ +\x57\xd6\xeb\xfd\x07\x85\x1a\x3c\xaf\xcc\x24\x67\x3a\x00\x00\x00\ +\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x04\xcf\ +\x00\ +\x00\x80\x9c\x78\x9c\xed\x9c\xcf\x6b\x24\x45\x14\xc7\x9f\x5e\x12\ +\x2f\x9e\x3c\x04\xf4\xb0\xa0\xec\x76\xcf\x8c\xe0\xc5\xfb\x5e\x3c\ +\x09\x3a\x87\x2c\x98\x08\xf1\x5f\x11\x84\x2c\x1b\x14\x16\xf7\xa0\ +\x92\xee\xc9\x7f\x20\xb8\xe8\xbf\xe0\xc9\xff\x41\x44\xd9\x55\x82\ +\x2e\xa2\x97\x85\x35\xe5\xab\x9e\xaa\xf4\xeb\x97\xea\x9f\x93\xe9\ +\x9e\xe9\x7c\x3f\x50\xcc\x4e\x4f\xd7\xb7\xde\x7b\xf5\xaa\xba\xaa\ +\x7a\x09\xd1\x4b\xf4\x32\xdd\xbd\x4b\xfc\x79\x8b\x22\xfe\xbc\x4d\ +\x44\x7b\x7b\xee\xfb\x2b\x44\x1f\xf0\xb5\x88\xaf\xf1\x07\x7d\x4a\ +\xcb\xeb\x00\x00\x00\x00\x00\x63\xc3\x10\xed\x72\xb9\xc7\x65\x9f\ +\xcb\xce\xd0\xf6\xf4\x85\xf0\xfb\x21\x17\xe3\xca\xfb\x43\xdb\xb5\ +\x6e\x4a\xfc\xb6\xe5\xbe\xfd\x6d\x68\xfb\xd6\x0d\xfb\xf8\x89\xf2\ +\xfb\xc4\xc5\xe3\x26\xf8\x6e\xfb\xfe\x07\xe7\xf7\xb7\x37\xc5\x6f\ +\x8b\xf3\xfd\x0b\xd1\xef\x07\x43\xdb\xd4\x27\xec\xef\xa1\xca\xfb\ +\xfd\xa1\x6d\xea\x0b\xd5\xf7\xdf\x89\xf9\xee\x46\x3c\xef\x44\xdf\ +\x1f\x73\x79\x55\xc4\xe2\x78\xec\x31\x50\x7d\x3f\x77\xd7\x0e\xc4\ +\x38\xf8\x70\x68\x1b\xd7\x89\xea\xfb\x5d\x77\x6d\x47\x3c\xff\x1f\ +\x8c\x35\x07\x5c\xdf\x7b\x3f\xf7\xd5\x6f\x32\x07\x46\x37\x0e\x02\ +\xcf\xbb\xb9\xfa\x7d\x47\xfd\x3e\x8a\x18\x94\xac\x6f\x83\x6b\xdb\ +\xb1\xc5\x20\xd0\xe7\xb5\xeb\xfa\x40\x0c\xb6\x6a\x3e\x14\xfd\x7d\ +\xa0\xfc\x68\xbc\xae\x57\x31\xd8\xe8\x75\x81\xf2\x57\xfb\xec\x73\ +\xb8\xf5\xba\x5e\xc5\x60\xa3\xc6\x81\xf2\x59\xef\x5b\xbd\xbd\x07\ +\x5d\xfc\x56\xed\x6c\xd4\xba\x40\xf8\xad\xfb\xd8\xe7\xf7\xca\x3e\ +\xab\xf6\xae\x6d\x1c\x04\xf2\x34\x54\x82\x67\x4e\x25\x73\xb8\xed\ +\xe3\x47\x62\xcd\xb2\x96\x7d\xab\x8a\x41\xeb\x1c\x28\xb1\xbd\xaa\ +\x3c\x90\xb1\xa8\x9a\xc3\xb9\x1c\x99\x1e\xf6\x6e\x5d\xdb\x29\xb1\ +\xdd\xe7\xa9\x2e\x65\xe3\xf8\xa1\xaa\x7b\x99\xdf\x3d\xfa\xef\xe7\ +\x81\x79\xfd\xdd\x85\x7a\x87\x65\xb6\x07\xee\xdd\x71\x7d\x5e\x36\ +\x8f\x5f\x79\x6e\x0b\xbb\xd6\x3a\x3f\x3b\xdb\xe6\x6d\xc7\x98\xb0\ +\xaf\xf5\x59\xa2\x59\xee\x4b\x1f\x57\x8d\xef\x55\xc7\xe6\xba\xe9\ +\x1a\x37\x57\x57\xe6\x4e\x69\xde\x89\x31\x30\xaa\x7d\x9b\xf2\xab\ +\x6a\xbd\xba\x51\xcf\xe8\xeb\xc0\x04\xce\x28\x2a\xee\x1d\xdd\xde\ +\xdd\x04\xce\x28\x6a\xee\x1f\x55\x0e\xb4\x7d\xae\xa9\x1c\xd8\xea\ +\x73\xdc\x36\xb9\xaf\xea\xf5\xb2\x16\x58\x27\xca\xf7\x46\xb9\x2f\ +\xea\x7a\xff\x3f\x37\x5b\xf6\xee\xd6\xf9\x7d\x28\x9e\xf7\x5d\xd6\ +\x5a\x47\xa2\xae\x9f\x0b\x37\x3a\x0e\x26\xdf\x1b\x3c\x52\xb6\x77\ +\x59\x2f\x79\xff\x1f\x07\xe2\x50\xb9\xbf\x1a\x02\x13\xde\x1b\xfc\ +\xe8\xf2\xa0\xcb\x7a\xc9\xfb\xff\x91\xf3\xb3\x6c\xbf\x75\x3c\x74\ +\x1c\x02\xbe\x7f\xef\x3e\x3b\xbf\x83\xd4\xf3\x9f\xb9\xba\x9f\xd0\ +\x7b\x8a\xc1\xfe\x6f\x83\x29\xae\x6d\xef\x0b\xdb\x3b\x9f\x31\x34\ +\x99\xff\x45\x4c\x06\x7b\xcf\x6d\x8a\xef\x20\x4e\xdc\xf7\x95\xcf\ +\xda\xb6\xe5\xf9\x67\x4a\xf6\x35\x66\xc5\x35\xdc\x16\xf9\x7f\x24\ +\xfb\x5e\x5c\xef\x7c\xd6\xa6\x72\x6a\x5b\xfc\xbf\x62\xa7\x8b\xc1\ +\x89\xfb\xfd\xb3\xa6\x31\x70\xe3\xb9\xd3\xba\xa1\x4f\x9a\xf4\x93\ +\xe9\x70\xa6\xb1\x09\xf3\x5a\x1d\x81\x67\x5e\x93\x33\x8d\x8d\xce\ +\xe5\xa6\x04\x7c\xaf\x7b\x07\x37\x1a\xff\xdb\xfa\xee\xea\x8c\xc2\ +\xff\x2e\xbe\xbb\x7a\x63\xf1\xff\x5e\x5b\xdf\x5d\xbd\xb1\xf8\xdf\ +\x69\x5e\x36\x1d\xdf\x37\x8c\x05\xb3\xc2\xb9\x39\x00\x00\x00\x00\ +\x40\x5f\xd8\xbf\x13\xb0\xc7\xe5\x1d\xea\xef\xef\x04\xdc\x3a\xa3\ +\xdd\xb7\xcf\x68\xfe\xd6\x97\xd7\x73\x96\x7d\xfb\x1b\x7a\x6d\x7a\ +\x46\xef\xc6\x67\xf4\x9e\x3c\x32\xff\x93\xde\x34\xab\xea\x4e\x52\ +\xfa\x58\x6a\x72\x3b\xbf\xf0\xb5\x4c\xbb\xab\xbe\xd5\xd5\xc7\xfb\ +\xf1\x82\x5e\xc4\x09\xfd\x37\x2d\x68\x9b\x96\xfa\x45\xcd\x68\x41\ +\xcf\xa3\x94\x2e\x26\x0b\xba\x98\x2d\xc8\x48\x6d\xfb\xbd\xa9\xbe\ +\xb4\x97\xb5\xfe\x62\xcd\xe7\xd6\x56\xab\xe1\x75\xa5\xf6\x9d\x84\ +\x5e\x34\xd7\xcf\xed\xf5\x7a\xb6\xb0\xbe\x89\xd3\xbc\x78\x6d\x6e\ +\xdf\x96\x2c\x4e\xf5\xfa\xce\x66\xb6\x57\xda\x17\x2a\xb6\xcd\x4c\ +\x3f\x75\xed\xa7\x74\x5e\xad\x9f\xdb\x6c\xb5\x6d\xbd\x78\x59\x2f\ +\xfb\xf7\x44\xc5\x7a\xea\xf4\xa3\x64\xa9\xcf\x31\xfc\xb5\x5c\xdf\ +\xe5\x5a\x2a\xb4\x85\xae\xd4\x9e\xb0\x9e\x2f\xf6\x7b\x9c\xdb\xff\ +\x73\x95\xfe\x9d\x94\x9e\x4d\x45\x7c\xad\x7d\x13\xd1\x9e\xd3\xba\ +\x60\x7b\x2f\xb2\xbe\x50\xfa\x79\xbf\x85\x6d\xb7\xf9\x9c\xf9\x99\ +\xe4\x36\xcf\x16\x45\xdb\xad\x76\x74\xca\xda\xa7\x79\x7c\x26\x42\ +\x7f\x99\x77\x57\xf5\xb9\xff\x9f\x4e\x73\x3f\x2f\x6d\xf6\x31\x90\ +\x25\x72\xb1\xb9\xd4\xe7\xb1\x50\x9d\x3b\xd9\xb8\x39\x8f\x93\x62\ +\xbc\xad\xad\x5e\x33\x4e\x96\x71\xc9\xf4\x4f\xf3\xfc\x9f\x2c\xea\ +\x62\xe3\xec\x4f\xe9\x6f\x1d\xeb\x42\x4c\x6c\xcc\x4f\xf3\x78\x4c\ +\x54\xff\x58\x8d\x37\xbe\xa2\xd7\x4b\xf5\x17\xf4\x2c\x4e\xc3\xf9\ +\x6e\x75\xad\xcd\x3e\x56\x5e\x57\xd8\xf3\x7b\x5d\xde\xb3\xf6\x13\ +\x11\x8b\xcb\xb1\x1f\x8b\x5c\xf4\x7e\xf9\xdc\xcd\x62\x94\xd4\xc5\ +\x26\xcf\x9f\xc8\xcd\x2f\x91\xcc\xbd\x24\x1f\x07\xfe\x9a\xd7\x9d\ +\xa5\x4d\xb4\x85\x0f\x09\xfd\xe3\xc7\xee\x2c\x2d\xea\x4b\xcd\xd9\ +\xb2\x5f\xff\x6d\xae\x9d\xfb\x60\xeb\xc5\x76\xae\x12\xed\xf8\xe2\ +\xe7\x4f\x6e\xef\x37\xbe\xef\xeb\xae\x73\x3d\x6b\xfc\xc4\xf5\xff\ +\xe0\xf9\xe4\xdc\x16\x39\x87\xd6\xe7\x62\xe3\x36\x4a\x34\x57\xd1\ +\x2e\xb6\x71\xbd\x9a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\xc8\xf9\x1f\x5d\x48\xbb\x77\ +" + +qt_resource_name = "\ +\x00\x07\ +\x07\x3b\xe0\xb3\ +\x00\x70\ +\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\x00\x73\ +\x00\x0e\ +\x06\x01\x21\x3e\ +\x00\x48\ +\x00\x79\x00\x64\x00\x72\x00\x6f\x00\x53\x00\x45\x00\x44\x00\x50\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\ +\x00\x05\ +\x00\x6f\xa6\x53\ +\x00\x69\ +\x00\x63\x00\x6f\x00\x6e\x00\x73\ +\x00\x08\ +\x0a\x61\x5a\xa7\ +\x00\x69\ +\x00\x63\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0a\ +\x0c\xf7\x1b\xc7\ +\x00\x63\ +\x00\x6f\x00\x6e\x00\x66\x00\x69\x00\x67\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0a\ +\x0a\xc8\xfb\x07\ +\x00\x66\ +\x00\x6f\x00\x6c\x00\x64\x00\x65\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0a\ +\x04\xa1\x18\x1f\ +\x00\x63\ +\x00\x75\x00\x65\x00\x6e\x00\x63\x00\x61\x00\x2e\x00\x69\x00\x63\x00\x6f\ +" + +qt_resource_struct = "\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ +\x00\x00\x00\x14\x00\x02\x00\x00\x00\x02\x00\x00\x00\x03\ +\x00\x00\x00\x36\x00\x02\x00\x00\x00\x03\x00\x00\x00\x05\ +\x00\x00\x00\x46\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x00\x90\x00\x01\x00\x00\x00\x01\x00\x00\x5e\xb0\ +\x00\x00\x00\x76\x00\x00\x00\x00\x00\x01\x00\x00\x56\xe2\ +\x00\x00\x00\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x04\x0e\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/qgisplugin/scripts/compile-strings.sh b/qgisplugin/scripts/compile-strings.sh old mode 100644 new mode 100755 From bc35831de4ee11f0a0887998b2c51e1672f03b43 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 7 May 2018 15:35:17 -0500 Subject: [PATCH 012/142] Se habilitan botones para cargar y visualizar los mapas DEM y DIR en el modeulo --- qgisplugin/HydroSEDPluginUtils.py | 86 ++++++++++++------- qgisplugin/HydroSEDPlugin_dockwidget.py | 35 +++++++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 45 ++++------ qgisplugin/icons/geomorfologia.ico | Bin 0 -> 32988 bytes 4 files changed, 100 insertions(+), 66 deletions(-) create mode 100644 qgisplugin/icons/geomorfologia.ico diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 13cadf0..364f9d5 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -4,36 +4,56 @@ from wmf import wmf -def cargar_mapa_raster (pathMapaRaster): - - retornoCargaLayerMapaRaster = False - - pathMapaRaster = pathMapaRaster.strip () - - if (os.path.exists (pathMapaRaster)): - - baseNameMapaRaster = os.path.basename (pathMapaRaster) - layerMapaRaster = QgsRasterLayer (pathMapaRaster, baseNameMapaRaster) - QgsMapLayerRegistry.instance ().addMapLayer (layerMapaRaster) - - retornoCargaLayerMapaRaster = layerMapaRaster.isValid () - - return retornoCargaLayerMapaRaster - -def cargar_mapa_dem_wmf (pathMapaDEM, dxp): - - retornoCargaLayerMapaRaster = False - - pathMapaDEM = pathMapaDEM.strip () - - try: - - demWMF = wmf.read_map_raster (pathMapaDEM, isDEMorDIR = True, dxp = dxp, noDataP = -9999) - retornoCargaLayerMapaRaster = True - - except: - - retornoCargaLayerMapaRaster = False - - return retornoCargaLayerMapaRaster - +class controlHS: + + def __init__(self): + self.DEM = 0 + self.DIR = 0 + self.xll = 0 + self.yll = 0 + self.nodata = 0 + + def cargar_mapa_raster (self,pathMapaRaster): + + retornoCargaLayerMapaRaster = False + + pathMapaRaster = pathMapaRaster.strip () + + if (os.path.exists (pathMapaRaster)): + + baseNameMapaRaster = os.path.basename (pathMapaRaster) + layerMapaRaster = QgsRasterLayer (pathMapaRaster, baseNameMapaRaster) + QgsMapLayerRegistry.instance ().addMapLayer (layerMapaRaster) + + retornoCargaLayerMapaRaster = layerMapaRaster.isValid () + + return retornoCargaLayerMapaRaster + + def cargar_mapa_dem_wmf (self,pathMapaDEM, dxp): + + retornoCargaLayerMapaRaster = False + + pathMapaDEM = pathMapaDEM.strip () + + try: + + self.DEM = wmf.read_map_raster (pathMapaDEM, isDEMorDIR = True, dxp = dxp, noDataP = -9999) + retornoCargaLayerMapaRaster = True + + except: + + retornoCargaLayerMapaRaster = False + + return retornoCargaLayerMapaRaster + + + def cargar_mapa_dir_wmf (self,pathMapaDIR, dxp): + retornoCargaLayerMapaRaster = False + pathMapaDIR = pathMapaDIR.strip () + try: + self.DIR = wmf.read_map_raster (pathMapaDIR, isDEMorDIR = True, isDIR = True, dxp = dxp, noDataP = -9999) + retornoCargaLayerMapaRaster = True + except: + self.DIR = 1 + return retornoCargaLayerMapaRaster + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index b85e411..e68bf04 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -31,7 +31,7 @@ import os.path -from HydroSEDPluginUtils import cargar_mapa_raster, cargar_mapa_dem_wmf +import HydroSEDPluginUtils as HSutils FORM_CLASS, _ = uic.loadUiType(os.path.join( os.path.dirname(__file__), 'HydroSEDPlugin_dockwidget_base.ui')) @@ -56,6 +56,7 @@ def __init__(self, iface = None, parent=None): if not (iface is None): self.iface = iface + self.HSutils = HSutils.controlHS() def closeEvent(self, event): @@ -125,7 +126,7 @@ def clickEventVisualizarMapaDEM (): pathMapaDEM = self.lineEditMapaDEM.text ().strip () - flagCargaMapaDEM = cargar_mapa_raster (pathMapaDEM) + flagCargaMapaDEM = self.HSutils.cargar_mapa_raster (pathMapaDEM) if flagCargaMapaDEM: @@ -135,12 +136,27 @@ def clickEventVisualizarMapaDEM (): self.iface.messageBar().pushError (u'Hydro-SED', u'No fue posible cargar el mapa MDE. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.') + def clickEventVisualizarMapaDIR (): + + pathMapaDIR = self.lineEditMapaDIR.text ().strip () + + flagCargaMapaDIR = self.HSutils.cargar_mapa_raster (pathMapaDIR) + + if flagCargaMapaDIR: + + self.iface.messageBar().pushInfo (u'Hydro-SED', u'Se cargó el mapa DIR de forma exitosa') + + else: + + self.iface.messageBar().pushError (u'Hydro-SED', u'No fue posible cargar el mapa DIR. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.') + + def clickEventCargarWMFMapaDEM (): pathMapaDEM = self.lineEditMapaDEM.text ().strip () - dxpMapaDEM = self.spinBox_dxPlano.value () + dxpMapaDEM = self.spinBox_dxPlano.value() - flagCargaMapaDEM_WMF = cargar_mapa_dem_wmf (pathMapaDEM, dxpMapaDEM) + flagCargaMapaDEM_WMF = self.HSutils.cargar_mapa_dem_wmf (pathMapaDEM, dxpMapaDEM) if flagCargaMapaDEM_WMF: @@ -150,6 +166,15 @@ def clickEventCargarWMFMapaDEM (): self.iface.messageBar().pushError (u'Hydro-SED', u'No fue posible cargar el mapa MDE al WMF. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.') + def clickEventCargarWMFMapaDIR(): + pathMapaDIR = self.lineEditMapaDIR.text ().strip () + dxpMapaDIR = self.spinBox_dxPlano.value () + flagCargaMapaDIR_WMF = self.HSutils.cargar_mapa_dir_wmf (pathMapaDIR, dxpMapaDIR) + if flagCargaMapaDIR_WMF: + self.iface.messageBar().pushInfo (u'Hydro-SED', u'Se cargó el mapa DIR al WMF de forma exitosa') + else: + self.iface.messageBar().pushError (u'Hydro-SED', u'No fue posible cargar el mapa DIR al WMF. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.') + def clickEventSelectorBinarioNC (): setupLineEditButtonOpenFileDialog (self.lineEditSelectorBinarioNC, QFileDialog) @@ -175,7 +200,9 @@ def clickEventSelectorOutputCuencaNCTrazadorCuencas (): self.botonSelectorMapaDIR.clicked.connect (clickEventSelectorMapaDIR) self.Boton_verMDE.clicked.connect (clickEventVisualizarMapaDEM) + self.Boton_verDIR.clicked.connect (clickEventVisualizarMapaDIR) self.Boton_MDE2WMF.clicked.connect (clickEventCargarWMFMapaDEM) + self.Boton_DIR2WMF.clicked.connect (clickEventCargarWMFMapaDIR) # self.Boton_verDIR.clicked.connect (clickEventVisualizarMapaDIR) self.botonSelectorBinarioNC.clicked.connect (clickEventSelectorBinarioNC) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 6ab87c7..302f4c1 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -31,7 +31,7 @@ - + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png @@ -114,7 +114,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -219,7 +219,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -303,7 +303,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -360,6 +360,9 @@ <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + Qt::LeftToRight + Valor Dxp @@ -375,29 +378,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - <html><head/><body><p>Establece el DIR y sus propiedades como el mapa base para WMF.</p></body></html> - - - Establecer - - - @@ -421,6 +401,7 @@ labelDEM labelDIR Tabla_PropMDE + layoutWidget_2 @@ -429,7 +410,7 @@ - + :/plugins/HydroSEDPlugin/icons/cuenca.ico:/plugins/HydroSEDPlugin/icons/cuenca.ico @@ -781,6 +762,10 @@ + + + :/plugins/HydroSEDPlugin/icons/geomorfologia.ico:/plugins/HydroSEDPlugin/icons/geomorfologia.ico + Geomorfología @@ -821,6 +806,8 @@ - + + + diff --git a/qgisplugin/icons/geomorfologia.ico b/qgisplugin/icons/geomorfologia.ico new file mode 100644 index 0000000000000000000000000000000000000000..fe61a9d79bcbf8d2e0c44be2a6b21103c7aeaed8 GIT binary patch literal 32988 zcmeHP3vgA{xjyZ+I`q!9RV!z&wRV(ywKG~wa&jUtzB&+Eo{EIzKtj;*4#;(Miq+bg zYMqu&A3C)~gcx$3dGiPl<&h_npuDt$fg~U*)@dDETP#kMI+Q@p>i4g`SF$;rAbDK% zde@m*v-VzlugCZOueJ7G`}llc@?GScIMIiEjPE++Q+z((m@)48*L}VvD6=g0e3Z{u zHrwa>I?C1k7x{c`#XjG4sDs;lOOdGD{0swz0mFb{z%XDKFbo(53GHFkl$? zd@)cE<}zK{8s=YZt+E%@FSD`g|6=~q;nrm>3F{F$Zi=!0`J$oM7*q3{E_RMCG{knM| z%|N%+OJm7C;Fp1ejt=C&9&$mW}){DjJZ-SG*~i8$X|v}$@Mq+k^|X1u=nBCKETxjeGlb& zyo1eifL+NRZ9B5}%RBe>^GY}yqO6zXPWTBs$(qVZAG9t|PFy`3<#H?Li9@k@T_@1# ze^cRh$CTAI`YaBzI{VKx2c$3X4LwxvLOIYrm3)hX-8w7QorM$FS`zFZ@b7(?6@Ib@ zC4WoB!k@rjXdFYybNBPF<{V~Ag7EVWCip+neOLD6`@EPbKGXSyCfz30>pS+yzOtsD zKgb;SA}sEBwft$E z+7D`s8iUr4f%4og;qmYN`lS0HeVDVS-;Xr8@s8wAI903z4-I7J(04T-aP43506rcc zrtXst*n54WvO7lqAkfW@>#-4L!l~t?`5?d0SMJ&e>LhbI;Rom(9I867@7#mDFOF(% zb^Gc*&zyo}t74rie-#5<|JDRq({-iyROa$gIs$&rYXdn4fw$8-qsOQ@(71H&(TAkw zLg#(>5ifHQ-{4n!=$hAuD1N}N_L;!b>)?ZqQ`}ej&M5{^oIBYRCtU|_TvPEd#!k@v zBO!Z@KhQb)k=#z`YnSzr8lP8|uAH?FC|T0n@LbymAJ&J8N66kA-*sIFyCwBJk2rAV zw&c$!ruX|iH3y8ccWIvM%ypdjPxq~iiebk*jh*uEZg%W2=$ZGCyeaN^`A~k(TdwRx z#X;Ps@{>XENby}`ReoRF1@Z})TldMHFhj0=I*wzqdy+58Kk~+U;(*RaTK0sWe880F z&VB|(wxBV1InZ`M@>ezjK5#GLKTWvLp4Yl@0@odV@nHAbHFVs;44wD*dg%Q-RIacS zPvC1L?Vhlw`)T=5?zLSnc2}-v5I6r3>~?TNe@>I%!+p*=3i{DM*XhT;9x`r>T5f!Y zucu?k7O7Xo`nc#Jtm@eZ>4K8IrToNj=R4`}4pgRjAlYdhaP_>;{UsQ?8I=wNj6S$)_DW?pmV(jQvPp*<~svn9jKgagU0OTKwXjmqzB5T$qzVjUfDs6eeC8=ImsXT|7qyH9-lYY91suZ z*n`Uh=>_2?tm>F-UfF#=cB=1fw|<##R4w6mpJ`Bxr=;ai+&F7M#}8m0c%Qfar+Mt< zK;zOjagIJH+zuDsXL;$yTla+TvKpG#DfyFscl;d9{~`0^{pG`->!<5~uw^7eWe=`= zN!BV3Ag4IsaN}Ut_om7{wNKK6GIy=(tZT^kX)YYy$Mc@bt;1aBruIA3b1yDB?#E2H z&&B>p_-P!(!B4_W)z%XDKFbo(5 z3GHFkl!k3>XFs1BL;^fMMW^!~p$Iz!;>7NalY6K!W)h2EM=y%nq|D3+n8p zB?5%F+nBmbZv!akU{ioaJ7;Xf;mj`pY44~75hYlRVe z`rJz1R2b(U7T4I=Yary*jZEHv{boh=Ty6|oAH0y@Tia^H9_%rCAhnHj=Q$m$Zo(gh zym=p!cc6_0RkqAu#gAbePZk0rrGj$)WPUk&FBB892>s5*JG)RBm(w;dnR(cf(>5^~ z!Mm+Cyz72(4fZT2_!*4jkBOLAo_n76nz{SG!SGJ8BY2d_tk>|awHs}%W3m{yO3=^z zI;7Q39>Si9LcB98M8AdD6MsuPaKDbdXfHDPB>LV(@6+R~2Ybr?Nqa4JR&n{;u=S4r zDgWqnxT!3w)BotWKdZfA>fI*wPw#p28n~Q|ch%I-+?7bBPMU{f)%Q*=zx4+8gS=|V z5{zjx_-Kx>q9j_ycEQ~Aj2olDVg+3wcWM;SjOx9s0Z~dJm@4@@e=YW5^ z)4$r|M|(NiYq+e6@%O*~^ceh;&%i&lI|FU@1kkqXm+-51%q|}Xtt9psIeTzASW;ih zg3f)Xp2>2&OWc9}oP8D8R}TD5QJ!pDYs+O3@$-RucCJir;zfB~ww&-Lms!Ax{Z8tA zx7rIw@BG0_cBge3HbVPA)!6913GJ5rA#~#f$QgT-vCoA=_WWbWzqh?g0K0gjvae3{LH3lEnMFA z3YRy)&dD#_u?>Bf^N+|6>$XDpb~TZ(wzPutoi#$PsbD?pV*D0;eK`4lKb3K3VFmxo zwB17HH^K*o#b59q8vl-!@>_B3B}<}g{g31PuM5l4Tu-@uFsGqkSy#?qE*>i?6_4ew z8rYAjHp{NMY%pz`dkq7I0mHy&!2mrcz+Vpf0!ZdL!Dk_X|GRz8C}meKSZy!5r^3GX zq0+0yUI>z+pJwp8S6b5-tPnFpEB*hOuFmXm#x;dCcFEibdu85QJ2|~YBp-0)Q4^G)5_1rP0pY39l#+bXEq5rAK$1H z$HiYuD*1aw32|b6HRdNVtQ#>W9k&N_$5)tq0`tVSFiW;#9kv_uvh^|Rp)bISg zW8bvo(LIg|4$OHyCNO9*q;wOEU`VeH#t{4~C|=-Gv}P-WcSfTjjo zhkhwkZhfmDYA>F;Q|uX!wNUo!81n&q=Rs>O$RiW$>|3!0#q*7~c2qOj4h(3!x0SwI zsA8w0750pDV^1x+@2A&{p0U+ReET)5xqlCN)3~voy6q5``EmZ@!YAx&Yb)80chvFI zyRgRDhc$FlCEp!B&ohM7KI(0IRQ?*aY|0Mt(apc-a?)X2&Z!kAil4daR()?}HG62o z8qvGHPJCPwX9c=^F!|lT6}J~Y&zt7eXEfing5Qx^cTu^xdr{OXOf4VG`S+$@erZX` z<(Ceoj=9$`Fj5TAJc%CQj6wQ;Jx>bx{_U=W$h)gLW2$el?<=6=oZszr_BRXHiJzCO zV)qvR63>1RD<=Mie{qSc%r1uKg_eA5 z6PJ7N{I(IXdI#nLwH5q+Z(V&n@7EdE*mfqZ?~#tch#t?T*@NabMbsDTVhe z&lq?23VXb__&GHFkl!k3>XFs1BL;^fMLKe oU>GnA7zPXjh5^HXVZbn87%&VN1`Gp+0mFb{z%XDK_*^saFFxio-v9sr literal 0 HcmV?d00001 From ad085883c3851e8bb9358a8298760da181d3a99a Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 7 May 2018 15:49:19 -0500 Subject: [PATCH 013/142] Hace que el buscador de carpetas de raster hagan re-busqueda en el ultimo directorio abierto, se pone 12.7m como el valor por defecto del dxp de los mapas --- qgisplugin/HydroSEDPlugin_dockwidget.py | 3 ++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 10 ++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index e68bf04..9387dbc 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -102,7 +102,8 @@ def setupLineEditButtonOpenShapeFileDialog (lineEditHolder, fileDialogHolder): def setupLineEditButtonOpenRasterFileDialog (lineEditHolder, fileDialogHolder): - lineEditHolder.setText (fileDialogHolder.getOpenFileName ()) + lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), 'Open File',"", "*", + QtGui.QFileDialog.DontUseNativeDialog)) def setupLineEditButtonOpenFileDialog (lineEditHolder, fileDialogHolder): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 302f4c1..7c80012 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -355,16 +355,16 @@ - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + Valor en metros del tamano de una celda en el mapa. - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + Valor en metros del tamano de una celda en el mapa. Qt::LeftToRight - Valor Dxp + Valor Dxp [m] @@ -376,6 +376,9 @@ 0 + + 12.699999999999999 + @@ -807,7 +810,6 @@ - From 6ee26508f0dd30ac4d14c0be8f516cf7b3dcd754 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 7 May 2018 15:52:38 -0500 Subject: [PATCH 014/142] se agregan funciones de trazadores (sin ensayar) --- qgisplugin/HydroSEDPluginUtils.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 364f9d5..24a2b5c 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -57,3 +57,8 @@ def cargar_mapa_dir_wmf (self,pathMapaDIR, dxp): self.DIR = 1 return retornoCargaLayerMapaRaster + def trazador_corriente(x,y, name = 'None'): + self.stream = wmf.Stream(x, y, self.DEM, self.DIR, name = name) + + def trazador_cuenca(x,y,name = 'None', TopoNodes = False): + self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR, stream=self.stream, TopoNodes=TopoNodes) From f2fa6eb34bf4b44f4eb573376ba6348445dab6b6 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 7 May 2018 16:06:36 -0500 Subject: [PATCH 015/142] =?UTF-8?q?cambios=20en=20el=20dise=C3=B1o=20del?= =?UTF-8?q?=20trazador=20de=20corrientes=20y=20de=20cuencas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 83 +++++++++++++++----- 1 file changed, 65 insertions(+), 18 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 7c80012..5c54c16 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -27,7 +27,7 @@ - 0 + 1 @@ -425,7 +425,7 @@ 0 0 361 - 641 + 781 @@ -440,7 +440,7 @@ 0 250 359 - 381 + 521 @@ -452,7 +452,7 @@ 10 22 341 - 351 + 421 @@ -477,23 +477,69 @@ - + + + + + Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca + + + Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca + + + Usar ultima corriente + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Si usar o no usar ultima corriente + + + Si usar o no usar ultima corriente + + + + + + true + + + + + + + - Path Corriente: + Ruta divisoria de aguas (*.shp): - + - + true - + 30 @@ -514,23 +560,23 @@ - + - Path Salida (*.shp): + Ruta red hidrica (*.shp): - + - + true - + 30 @@ -560,14 +606,14 @@ - + true - + 30 @@ -647,14 +693,14 @@ - Path Salida (*.shp): + Ruta corriente trazada (*.shp): - + true @@ -810,6 +856,7 @@ + From 3fd5ad080b5fe99a998ae5f5a4a01d6124983de6 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 7 May 2018 16:28:18 -0500 Subject: [PATCH 016/142] Trazador de corrientes funciona pero le falta trabajo en varios aspectos --- qgisplugin/HydroSEDPluginUtils.py | 16 +++++-- qgisplugin/HydroSEDPlugin_dockwidget.py | 32 +++++++------ qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 49 ++++++++++++++++++-- 3 files changed, 75 insertions(+), 22 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 24a2b5c..729536c 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -57,8 +57,16 @@ def cargar_mapa_dir_wmf (self,pathMapaDIR, dxp): self.DIR = 1 return retornoCargaLayerMapaRaster - def trazador_corriente(x,y, name = 'None'): - self.stream = wmf.Stream(x, y, self.DEM, self.DIR, name = name) + def trazador_corriente(self,x,y, path = None): + self.stream = wmf.Stream(x, y, self.DEM, self.DIR) + if path is not None: + self.stream.Save_Stream2Map(path) + + def trazador_cuenca(self,x,y,name = 'None', TopoNodes = False, LastStream = True): + # Traza la cuenca con y sin la ultima corriente. + if LastStream: + self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR, stream=self.stream, TopoNodes=TopoNodes) + else: + self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR, TopoNodes=TopoNodes) + # Mira si guarda el shp de la cuenca. - def trazador_cuenca(x,y,name = 'None', TopoNodes = False): - self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR, stream=self.stream, TopoNodes=TopoNodes) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 9387dbc..3239c8c 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -52,7 +52,7 @@ def __init__(self, iface = None, parent=None): # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.setupUIInputsOutputs () - self.setupUIButtonEvents () + #self.setupUIButtonEvents () if not (iface is None): self.iface = iface @@ -64,11 +64,14 @@ def closeEvent(self, event): event.accept() def handleClickEventEjecutarTrazadorCorrientes (self): - - print wmf - print self.spinBoxLatitudTrazadorCorrientes.value () - print self.spinBoxLongitudTrazadorCorrientes.value () - print self.lineEditSelectorOutputCorrienteShapefileTrazadorCorrientes.text () + x = self.spinBoxLatitudTrazadorCorrientes.value () + y = self.spinBoxLongitudTrazadorCorrientes.value () + OutPath = self.PathCorriente_out.text () + self.HSutils.trazador_corriente(x,y, OutPath) + #print wmf + #print self.spinBoxLatitudTrazadorCorrientes.value () + #print self.spinBoxLongitudTrazadorCorrientes.value () + #print self.PathCorriente_out.text () def handleClickEventEjecutarTrazadorCuencas (self): @@ -182,7 +185,7 @@ def clickEventSelectorBinarioNC (): def clickEventSelectorOutputCorrienteShapefileTrazadorCorrientes (): - setupLineEditButtonSaveFileDialog (self.lineEditSelectorOutputCorrienteShapefileTrazadorCorrientes, QFileDialog) + setupLineEditButtonSaveFileDialog (self.PathCorriente_out, QFileDialog) def clickEventSelectorInputCorrienteShapefileTrazadorCuencas (): @@ -208,14 +211,17 @@ def clickEventSelectorOutputCuencaNCTrazadorCuencas (): self.botonSelectorBinarioNC.clicked.connect (clickEventSelectorBinarioNC) self.botonSelectorOutputCorrienteShapefileTrazadorCorrientes.clicked.connect (clickEventSelectorOutputCorrienteShapefileTrazadorCorrientes) - self.botonInputCorrienteShapefileTrazadorCuencas.clicked.connect (clickEventSelectorInputCorrienteShapefileTrazadorCuencas) - self.botonOutputCuencaShapefileTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaShapefileTrazadorCuencas) - self.botonOutputCuencaNCTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaNCTrazadorCuencas) + + self.botonEjecutarTrazadorCorrientes.clicked.connect (self.handleClickEventEjecutarTrazadorCorrientes) + + #self.botonOutputCuencaShapefileTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaShapefileTrazadorCuencas) + #self.botonOutputCuencaNCTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaNCTrazadorCuencas) - def setupUIButtonEvents (self): + #def setupUIButtonEvents (self): - self.botonEjecutarTrazadorCorrientes.clicked.connect (self.handleClickEventEjecutarTrazadorCorrientes) - self.botonEjecutarTrazadorCuencas.clicked.connect (self.handleClickEventEjecutarTrazadorCuencas) + #self.botonEjecutarTrazadorCorrientes.clicked.connect(self.handleClickEventEjecutarTrazadorCorrientes) + #self.botonEjecutarTrazadorCorrientes.clicked.connect (self.handleClickEventEjecutarTrazadorCorrientes) + #self.botonEjecutarTrazadorCuencas.clicked.connect (self.handleClickEventEjecutarTrazadorCuencas) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 5c54c16..604829d 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -464,7 +464,17 @@ - + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + @@ -474,7 +484,17 @@ - + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + @@ -678,7 +698,17 @@ - + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + @@ -688,7 +718,17 @@ - + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + @@ -856,7 +896,6 @@ - From 9760c784b25bd4e9d411d433f7a6bcfe433d2c42 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 7 May 2018 16:43:39 -0500 Subject: [PATCH 017/142] =?UTF-8?q?se=20cambia=20la=20forma=20de=20funcion?= =?UTF-8?q?ar=20del=20trazador=20de=20corrientes=20para=20que=20sea=20m?= =?UTF-8?q?=C3=A1s=20intuitivo,=20se=20agrega=20icono=20de=20localizaci?= =?UTF-8?q?=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 192 +++++++++++++++---- qgisplugin/icons/coordCapture.png | Bin 0 -> 8589 bytes 2 files changed, 150 insertions(+), 42 deletions(-) create mode 100644 qgisplugin/icons/coordCapture.png diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 604829d..09f372d 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -438,9 +438,9 @@ 0 - 250 + 310 359 - 521 + 471 @@ -457,11 +457,39 @@ - - - Latitud: - - + + + + + Latitud: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png + + + + @@ -686,49 +714,116 @@ 10 22 341 - 221 + 271 - - - Latitud: - - - - - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 - - + + + + + Punto de inicio de trazado de la corriente + + + Punto de inicio de trazado de la corriente + + + Ubicación + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Obtener coordenadas dando click sobre el mapa + + + Obtener coordenadas dando click sobre el mapa + + + + + + + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png + + + + - - - Longitud: - - + + + + + Coordenada en X del punto de inicio. + + + Coordenada en X del punto de inicio. + + + Latitud: + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 - - + + + + + Coordenada en Y del punto de inicio. + + + Coordenada en Y del punto de inicio. + + + Longitud + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + @@ -760,6 +855,12 @@ 16777215 + + Seleccionar la ruta donde se va a guardar la corriente. + + + Seleccionar la ruta donde se va a guardar la corriente. + ... @@ -784,6 +885,12 @@ + + Ejecutar la función de trazado de corriente. + + + Ejecutar la función de trazado de corriente. + Ejecutar Trazador @@ -896,6 +1003,7 @@ + diff --git a/qgisplugin/icons/coordCapture.png b/qgisplugin/icons/coordCapture.png new file mode 100644 index 0000000000000000000000000000000000000000..14ec17e617a219b22db52760938508a2c984da3d GIT binary patch literal 8589 zcmeHs_d6S2*uFhtmLPU$5VJd1Hk)XD=6h%>5#H>-X zf<#r#meRiceBVFg`=0AL*ZthrdCq;VbN_J856@EzGXoX?AAo{_g2fPd(~5$E>R(Dl z!9e{F2C5++{sHv^xS}m|0la*spMK0=c+(K)ihX0)j%qU=h))5HWEHsHBv%jI7)> zc?Cr!n6iqhn!3hy%^OEGjN3Ei1=VRAQ^DYie=$y84EfjZMuht!?ccuU^0D?0VbX)BCQkf8hP#(C~+m z(T|_T#wQ4qQ`0lEbD!rI7MH#(udJ@EZ+zV(Zf)<7$h+V6zVH7yI6OK&IsN(T?ELq| z<)2-K1!W2ffn&p)x;7x*y*|dcbm9j6+Nyf%1V}0El263=vsJ1$>8`C5FY8E41^-ZY`=*6lu;fod z)~gLZeZ7{9@-87kSirD)oyU>iW%%_5$}kmz}7rKFrhRW*!0cyBSuoTDdVMV|!~o zcxtnm1}eZLX`f>;^3K!_2zf4fL!?OKW2psSme%(d;kk4nVT*zpZT8+TQ|ZrZK6uj8MhMHr`u%%*E5JV?=-5CVil6pVYhrBFE3T$o|QU1rQVlAesM zh6_)6X-Ux-Dz|g`X*_Kg!EL^ghGC>9bglF@;e|8(NMuZ1_RVP{JoSkAJ$qkI`wj4! zcSdsc7B9_6#Ip$B$bB{N8B`v{ox#p9BC)>f%edPwat8KMmGz8ZhBOWeRe1}fqc^L_ zl5H6|s|cngE>=<=)#s_HIXZYJ?QnA2Yc|1*yLUBZgEg^5d`Nx} z14+Cy%9pzId&b>bJGmf{SKL_sCu;gdYTT5h2@YR=#*9B$o**m_R=YM+kADP5Nzzz1 z@RK$e5V>5@T>PYo>^)Ll9A5=rR!6c1Nz`ay-O$3-EP|}b$EoUVRq7crr)ojud&ti> zv4m-pq^cBdd3~+qltcH0~c~&grA4Cx-wgYQ#Z*W$7%RU#z-ySAT6F!ydbXf0C)2Qr3#N?g7 z(-$zDG3)Dh`eE3Brkxodp_n&N^1tKa{j2^^!@oxM+imXltV6Yn!-s(O!z+PTWwIAT z(x1nbi4JwurWeDTQsribFohPnV|p|C=JSJ2{+{|En=2{_h4WNJP*Me5OD9~}rL~qa zLgw2#m;c)CsD&l55r@JwB~t@~qiJlonoBnX(XunxhfMM1E#$W3QQ_mbQNR5WqY*ORh`IdFlQ+6LwT4$<{Oe56}Oakmf&2gSC z>2b5ll@7ZJU<*QI$}G2?Y8E_NkP;)>Q*CkEBka256j6%3e$+eVm`g@Zv`jQCA!Hev zb)9c+E>CnUkd&>8Msp&V{#&Y;A}K#O9%rnXwDlp`V7q0ry~ zFgf>z(YDIol3-$=q9kY+{-i$;mDFMJ!pp(o9vk9dCNarB5^Cb; z@Hrdk!wYLq>wn+ZS#9~^oM00TP@9(fQD4nl)FGy!}! z6|@q}v?@Uf9;U6(A%-0 zpy-gkEV$$lV8@4ckO9rbRRg+>DQX5*s@2zu4(`w{A6J05JP=_}{o6a$3WK%O(*AG- zBOO&Ss6MB||dTNzv?j;o>Ke>XbN zN;~O`OqEx{0L{#Humt!f+~5t+ldj&Ed5|ITE|ugE$YD|^#gd~_(olh}KPA#CO`KrL znKH>~H-qwgucvwdtfa2riAhml?c_C3_@2yVTLmhEtCm@%;hQQvfnPzP57In=30$-f zp*Ld~LOHU`MKmd!u*@lw%o=|B3X1NghQQm9P{k}yNMB)|Wtt#igf*p^c@CE5xrx@} zS$_ols_ZbW2gI_3PA0{-B`D{XgTG=@4}e&pj1<}vtA?Sz0~l1Jt~<|(Z%br#vdU0y z!mC0*Boq3QfnLCR@)f{+b*jSD*Cx6`3AVY_&>Q7%gn&d=hdD<;3uobyq3)E2O90f! z+P7X3u|TuShp<$E-{zMbb#Sn!2Ryh23%iCsldi9`5JH>*3(s>ZfIt*Fr~+E5L9h^H zLo6^#N1^+_#f1x8hkmkfaO6rkg29edQ>^Lp!i)QhQKyPs4DGUNJ&@U{vV!$}?nv{($=Zn3VQ;Mvr1+s9nJP zy9i)_Vq$?=vsFnGDiioknL#lnK0QIuroy*T_sJx%K|Iid2T}Abkz712xkx#$Ck%L{ z29jcOG+K8}x&a)k3@N&b!GDkij@weHG{XQIykbAYkcNT%nqsu+;0{AY}#W(|g+Omh$R=n3Pg-wTe(&xNvZs}cfDnX0&g2IckEF6|m0{eH9W*l^8{14(wb8lJQt|@LR(4BEz+%y1uRRL%#9>}z- zg2Js~`H>-ee9M|Ns#jJbKjqWT=-suPA2%V3{hc3e?&iy9=nsxJ(){r)v3>OoE`On^ zOk-wgmPvwbZ!v6V6J0ms>@rVaHR@etydIe~)mR!YNc%^JbO)!~RJEQHb4vFO_ukg% z^JZ?MshCBl59K$qtI=mzd{DIEQ@6ez4Qo%;`Fy2jsTDAsW9VtA1;3#y^p zq==s)im6w}+4yWZiZ`dZgwg|KE30F5>oy)RfUMB zAQjRq&OAnHsVdpWTk70MLgdygNyY;;29RM^Fhbv{>>4f+Stj|#Z+T==Gf-kLG- zQRtg7q>7p5$DtFLaW zh@`DXQC_wSU6$v7pZb7^Bu}wPsv&FACc2~TMMuWlmg2k?fvkv8A_0DXRQGU7-syup zas^;k?G2&VJ9Kh((sxE`Iq0W4(2ejA@B1>U6TxR*AXyI(WR*r@k}4}+?_s#r2zw!c9qG?#h9yDh^sGz+ z3e5tLQcmz}M=C?p<^@>pHwPr14{ps%W$4oP6qfnk9Vr!+A$|yk%#LCGJ|$v%YHbQ{ z`U4@98dDGrIESZ#sfPkY!RQv2@sJnOuH&93U4_YbDb|?gRMjyO4wfJY&{RZOt#Chqfd}qcKO_PB~pcI=?;$F0N-2+Pp1NZF7s4q5K zO7y@2^MnF6gg}`k@6XanQz{QiuHW?^usp7Dq6*u-&~4B14@}4KtrRUT5C0Pb;p%+F zkMPVIU#PimW=p~G)cWL!hZ!ZCnWm|5JxWp94=j!O#CN`S{GOiLUC~2u+Xef)Q!i67 z-xriWs+0NscyjQO;D9?HqSUoiZ`DPH6%jctAE}qQ!9(gQCYtl07!x&{6`%h(1C0h& z=?0<|g{QS2NtZF8nw3jSb^nGXibiY^*zbQ&6cr@(rjgP;9C8g}3~aIbx|x))L`n;Y zR4)G4T`zBtg~{r&&6o+4qbZrLNrEEf6V^ZcXF3X_wpjn6rqBtV$!Cx2s#7jU8sjBn z5&ZONqWD-2+i+2V6lUyqI(X&}P8&z7zfh3w7-_*~HOk`sn-Yzsf5+}yMlVbU!0({U zWAsJ7q?aSlWXMu=nn1tJYWA`lybPB)kympo1Q?S<4`ysNfs9&kORH5VZM026wmC{) zw_tW=(jTgnLPeawQSHtCnK#882IysG@zfSEiD8g?j{(F#uT|P+LvoWV_L$;C%`H^T z|Gn(dz_C`mNZa&drFMDH=%*U9Exm%inf|RUf_~Sv+H~n$3^EiDmdU|_kaEMQ^!U;r z6z*60bX+e-O0$Kn`OzW-mT(2pVy(gk~hgsI~OQK>)ZP{fz=2`ibvzf^PU+Bgcv$4Pkc;=4MjOCvv;M(#(y5ss(pVk@pO;bgrrWljqD0C=@tAl8THR(ll5nf*9^n0@4UIOR#$E~GyQx?LVF1;u<|gT?;+I+ zL-3Dpn|s<;=GpOU*;dza+3~kileMi_wO*L7Zw=5Bg?M{@IZ%eRv;rT8#7c!_^aOb} zM)j}N?EnFJ94v0=<>`Qpj!-iAB<5j5uvR-!qs155)$+qynhkx}7GE~n!QZm;Bz19g zpJ|_FqB2iTZa+4H!A79~Zki+o|Ng!ALbM%r4dlw;VlYOA$ZNUyZ( z72C!YoOoEscrvx$JN>FPi)o2`1Qc%+va#!)7`}r`4?>q)tWV%j!rYqnT%ycad1?{( z>^Ap>4$HTccu_=eg>Mb#hO{nlSRc?bNogrHC{bMP`}=me&Ori@y!oY+3v7cs0&YB( zWU$3-f5`@tLnOc0kt%`1?KpGwC!b5dta>9xKlE_vBnS>XXF$7bs%8uX1HUPsX{o-S39k82JP{EAf4&#Yj~~; zj?xqzR`~ZS;sx4y$Ka%-?9754_Bmf_muZal2JA?4_NU@qe0!?YZx5>@ik%H>JlT3j zwEPS!T-y@g@%pKhww0~Kkn(+&k`UdrAD&03#NV9x)Iv+NGF=8Oo8tf3>0cvm=P#ATXibK@%2S6Yt~!-62o# z59wnqJ|q4TWqqmi98I`nk}xpG41>RK$Qv5tH;$J`7%_MG$r{qD=}Gw)9D3%{!BNG( zx?_&*oqE9_^K7bfTsdQ!#Oqb{^E%;}8l?DT_L&n6vmfLV#*t*Rb7FEX(aP}Wj{N0) zZ#Xlv)Ed({F_i*j(;U$_buHnb=-oakIewv8{^eo*PO>r4;}&tNla#zqec)C?O7@<0 z_jTDxmXmMelO`pP|7vtOUYMhk?|gK;pb1)zULv)+{IaD!_mAZVxncBcevRBeU$e4*VQA0Oy-5ZrkxC7PWrmfX z9PZ@4HIvUjbR$HO%qUKF+T&HJ+*M?)N$8n8`J%Whw8u_2D5!TDa(=tRCm+<#fAM`m zh?YE_qo4@bsp8~vHw!Yi&df>nFyk^K7zf0~nM6w9WIjn9QnLjI`*^&tU4TSNC{eJG zN(RI{JlSG~m(*tY#O)5{yQkUj9gm`~yZej8y6kP3a@9vk0jtA@X(Pp0sdv)j^W?iZ zt_iQP2nsj=sz0~Ht$^Ybj)&YG;0*`3i-gwwIkXsawd#<&N_WT%V;%H}uy$5-DqdA3 zwzqsdnGx>o!8Lv}(nG~=k|`GL_0WZcww*U6K2rnpmL54vz2YCneSsmx<+Dcx4Y+fo zShE=4>JVEp%!!e3MO3McobWd8%dLOw`J*MnuWY{4KseQOi9Lh%$8cq2l6|`CFF?@_ zdO{$BdHjI4yNS_wCtWLp`6XL-Gfg%rz1{(t#9f34Hqj4`^mc|qsF{}a8;^&&kH?cN zkV#yfsFgQ79<=|D(f!9H8K|F48S}$Mc&&EmB1zCV#PM7b5=jSqgIaN-Swlq1zEOb; z;7UvyyBW&slU+aV(T=!B5~l)6TVDHIiO%=s;yV`JN zZQpShla*~Y+wqF(ObNcT<#jX|(o5Un_85&PCl$Rg&Mk@R)q?cS#QqhqRpC+P z>`295KlB$vYT=K`SMYc3L3gFZGpPg~b)l%U@&#B{wBVE+w?mk?rl2>;$I0;`lH3=B zV;exG9px*VzlyXY=U8VLgtnq9It!sI_jx!-bF)JJ<=C~{givFm>*BY6Bss*n1pl%&^b_He2B_ZQ&q=zs+lp@ROnq_BYkBej_# z-QPdc1mrJM0hGtF+%2Ek@cW5l>bq=CWu~%TDoLI{ZOU|`mG8;H6+5wy+72H+iC>fa%iS6jxJpndznJ5vR2EX>K!c9t}F{$N%@G` z`X}P=M#pVeeOdcY&!CAx^*r=dFR1{lQ%Wna#p&kq>+d(EWF z`>M3}6P;2f4hWiG3M37BE+(ebIStq%dv>py?%K(4Qwb*m>l|MB{eC&Y#&`Lrxa#jh zG(>FL^ytT@G*sdD-`a(ae~4*ExSD6e*V|$zwwF{Ieut8VkG3zO$iKf1r|~KKT>Q5F zd*jZZVPkEVSAI*|QK!Nh;TJaKv$T(Au-0f6OiNt8oTcK^G%d5*MlUKcr5~T<=oAWL z^hSQL!s6vo)Gbin#plr_?6_arN|L;G=TAi0WzXB0a+oE9EJS=oJaweR2F`lipluw7 z7mP+phe40o+kl{moGcH4@7xp(>ZSAMBkVoo%{V!s6+^>_>q~HL)BJ7gsmy>!);o2Z z&9S^n={K?*cMMejXDt>VMP` z&W6^t1zl2$Va6|x%s`GhMI^r*8gp>!Cj!gu)yV~ppVmWiw!fG<}6?wo* zie+UFgQc2S5wZ0!@;<*CZh2_jHH5nU=WBcZt@&Tul8qC3$Ih z-ojJYCoT}?W`sPpIM0<(Sg-12oj0*b75UgxvlrbPh)jjf+u>L%Rc>KTUB1ZU^(2wC z^WOc>0vC-=pE0^f!OzR$oVu&`yG{6Czm14&bfV0-3+dSVsHA0HgQ$wt`bz9*&bV8% znGjtQc*B@Uy(`RUmEIVBsGm91z3LLXsAqjt?E3fa{tyCuh9}&(;ab#ATB?H;ybV?z zi)Qx7;Q~`Wkp|hLiJ1a#|3oR(O!EqeI@*P ziP-cP8Vy~&iaw|08xjv{i;A?VYi$_7FmgKBcG#@c>#S@aezoNWf@pb7lnW@MI^`d>EwkJ){-=V$f*HNg!LW;b8L H-Q)iUYz=!^ literal 0 HcmV?d00001 From cef50622a9795692cb30e02a6a3db3138444fed0 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 7 May 2018 16:45:49 -0500 Subject: [PATCH 018/142] Se cambia el comportamiento grafico del trazador de cuencas --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 93 +++++++++++++------- 1 file changed, 60 insertions(+), 33 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 09f372d..b22a286 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -452,7 +452,7 @@ 10 22 341 - 421 + 428 @@ -461,7 +461,7 @@ - Latitud: + Ubicación @@ -479,7 +479,7 @@ - + @@ -492,37 +492,64 @@ - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 - - - - - - - Longitud: - - + + + + + Coordenada en X del punto de inicio. + + + Coordenada en X del punto de inicio. + + + Latitud: + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 - - + + + + + Coordenada en Y del punto de inicio. + + + Coordenada en Y del punto de inicio. + + + Longitud + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + @@ -747,7 +774,7 @@ - + Obtener coordenadas dando click sobre el mapa From dc8eed36ff6ab742dc68c5e9518a3c65868d519e Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 7 May 2018 18:04:16 -0500 Subject: [PATCH 019/142] el trazador de corrientes ya toma las coordenadas desde el mouse, falta que el boton de ejecucion cargue de una el mapa obtenido --- qgisplugin/HydroGetCoordinates.py | 41 ++ qgisplugin/HydroSEDPlugin_dockwidget.py | 26 +- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 1 - qgisplugin/resources.py | 548 ++++++++++++++++++- qgisplugin/resources.qrc | 1 + 5 files changed, 603 insertions(+), 14 deletions(-) create mode 100644 qgisplugin/HydroGetCoordinates.py diff --git a/qgisplugin/HydroGetCoordinates.py b/qgisplugin/HydroGetCoordinates.py new file mode 100644 index 0000000..fcee49b --- /dev/null +++ b/qgisplugin/HydroGetCoordinates.py @@ -0,0 +1,41 @@ +from qgis.gui import QgsMapTool + +class PointTool(QgsMapTool): + def __init__(self, canvas, spinLat, spinLon): + QgsMapTool.__init__(self, canvas) + self.canvas = canvas + self.spinLat = spinLat + self.spinLon = spinLon + + def canvasPressEvent(self, event): + pass + + def canvasMoveEvent(self, event): + x = event.pos().x() + y = event.pos().y() + #point = self.canvas.getCoordinateTransform().toMapCoordinates(x, y) + #self.spinLat.setValue(point.y()) + #self.spinLon.setValue(point.x()) + + def canvasReleaseEvent(self, event): + #Get the click + x = event.pos().x() + y = event.pos().y() + point = self.canvas.getCoordinateTransform().toMapCoordinates(x, y) + self.spinLat.setValue(point.y()) + self.spinLon.setValue(point.x()) + + def activate(self): + pass + + def deactivate(self): + pass + + def isZoomTool(self): + return False + + def isTransient(self): + return False + + def isEditTool(self): + return True diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 3239c8c..714a498 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -32,6 +32,7 @@ import os.path import HydroSEDPluginUtils as HSutils +import HydroGetCoordinates as HSCoord FORM_CLASS, _ = uic.loadUiType(os.path.join( os.path.dirname(__file__), 'HydroSEDPlugin_dockwidget_base.ui')) @@ -57,21 +58,23 @@ def __init__(self, iface = None, parent=None): if not (iface is None): self.iface = iface self.HSutils = HSutils.controlHS() + self.GetCoords = HSCoord.PointTool(self.iface.mapCanvas(), self.spinBoxLatitudTrazadorCorrientes, + self.spinBoxLongitudTrazadorCorrientes) + #self.iface.mapCanvas().setMapTool(GetCoords) def closeEvent(self, event): self.closingPlugin.emit() event.accept() + def handleClickCoordCorrientes(self): + self.iface.mapCanvas().setMapTool(self.GetCoords) + def handleClickEventEjecutarTrazadorCorrientes (self): - x = self.spinBoxLatitudTrazadorCorrientes.value () - y = self.spinBoxLongitudTrazadorCorrientes.value () - OutPath = self.PathCorriente_out.text () - self.HSutils.trazador_corriente(x,y, OutPath) - #print wmf - #print self.spinBoxLatitudTrazadorCorrientes.value () - #print self.spinBoxLongitudTrazadorCorrientes.value () - #print self.PathCorriente_out.text () + y = self.spinBoxLatitudTrazadorCorrientes.value () + x = self.spinBoxLongitudTrazadorCorrientes.value () + OutPath = self.PathCorriente_out.text () + self.HSutils.trazador_corriente(x,y, OutPath) def handleClickEventEjecutarTrazadorCuencas (self): @@ -106,7 +109,7 @@ def setupLineEditButtonOpenShapeFileDialog (lineEditHolder, fileDialogHolder): def setupLineEditButtonOpenRasterFileDialog (lineEditHolder, fileDialogHolder): lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), 'Open File',"", "*", - QtGui.QFileDialog.DontUseNativeDialog)) + QtGui.QFileDialog.DontUseNativeDialog)) def setupLineEditButtonOpenFileDialog (lineEditHolder, fileDialogHolder): @@ -211,9 +214,10 @@ def clickEventSelectorOutputCuencaNCTrazadorCuencas (): self.botonSelectorBinarioNC.clicked.connect (clickEventSelectorBinarioNC) self.botonSelectorOutputCorrienteShapefileTrazadorCorrientes.clicked.connect (clickEventSelectorOutputCorrienteShapefileTrazadorCorrientes) - + self.botonEjecutarTrazadorCorrientes.clicked.connect (self.handleClickEventEjecutarTrazadorCorrientes) - + + self.BotonCoord_corriente.clicked.connect(self.handleClickCoordCorrientes) #self.botonOutputCuencaShapefileTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaShapefileTrazadorCuencas) #self.botonOutputCuencaNCTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaNCTrazadorCuencas) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index b22a286..360388e 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -1030,7 +1030,6 @@ - diff --git a/qgisplugin/resources.py b/qgisplugin/resources.py index 5d4eb4d..06d4d3d 100644 --- a/qgisplugin/resources.py +++ b/qgisplugin/resources.py @@ -1530,6 +1530,545 @@ \x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\ \x57\xd6\xeb\xfd\x07\x85\x1a\x3c\xaf\xcc\x24\x67\x3a\x00\x00\x00\ \x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x21\x8d\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x02\x00\x00\x00\x02\x00\x08\x03\x00\x00\x00\xc3\xa6\x24\xc8\ +\x00\x00\x00\x03\x73\x42\x49\x54\x08\x08\x08\xdb\xe1\x4f\xe0\x00\ +\x00\x00\x09\x70\x48\x59\x73\x00\x00\x9a\x56\x00\x00\x9a\x56\x01\ +\x67\x6f\x13\xc8\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\ +\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x03\x00\x50\x4c\x54\ +\x45\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x0b\x23\xb7\xe1\x00\x00\x00\xff\x74\x52\x4e\x53\x00\x01\x02\ +\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\ +\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\ +\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\ +\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\ +\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\ +\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\ +\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\ +\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\ +\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\ +\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\ +\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\ +\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\ +\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\ +\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\ +\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\ +\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xeb\x08\xd9\x35\ +\x00\x00\x1c\xf4\x49\x44\x41\x54\x18\x19\xed\xc1\x09\x80\x8d\xe5\ +\xe2\x07\xe0\xdf\x39\xb3\xcf\x18\x33\x8c\xfd\x1a\x21\x4b\xf6\xa5\ +\x42\x11\xb2\x16\x89\xea\x26\xdb\x74\x65\xb4\x90\xae\xe2\x92\xa5\ +\x12\xea\xba\x48\x65\xcd\xb5\x37\x42\xb2\x66\x77\x6d\xa1\x88\xf0\ +\x8f\x2c\x33\x93\x2c\x4d\xc3\x58\x66\x32\x63\x66\x98\x39\x73\xce\ +\xef\xaf\xe5\x76\x53\x96\xef\x9c\xf3\xbd\xdf\xfa\x3e\x0f\x20\x49\ +\x92\x24\x49\x92\x24\x49\x96\x17\x5e\xb2\x52\xbd\xa6\xed\xbb\x3c\ +\x37\xf0\xcd\x09\x33\x16\xad\xd9\xbe\x7d\xcd\xa2\x19\x13\xde\x1c\ +\xf8\x5c\x97\xf6\x4d\xeb\x55\x2a\x19\x0e\xc9\xb2\xa2\x1b\xc6\xbd\ +\xb5\xe4\x50\x2e\x6f\x29\xf7\xd0\x92\xb7\xe2\x1a\x46\x43\xb2\x90\ +\xa0\xbb\x1e\x1d\x34\x6b\xc7\x39\x7a\xe1\xdc\x8e\x59\x83\x1e\xbd\ +\x2b\x08\x92\xd9\x55\xed\xf3\x49\xb2\x8b\x3e\x72\x25\x7f\xd2\xa7\ +\x2a\x24\xb3\x2a\xdf\xeb\xa3\x54\xfa\x2d\xf5\xa3\x5e\xe5\x21\x99\ +\x4d\xe9\xee\xb3\x4e\x50\x35\x27\x66\x75\x2f\x0d\xc9\x2c\x62\x9e\ +\x98\x7a\x8c\xaa\x3b\x36\xf5\x89\x18\x48\x86\x17\xfa\xd4\x5a\x17\ +\x05\x71\xad\x7d\x2a\x14\x92\x81\x39\x9a\xce\xca\xa4\x50\x99\xb3\ +\x9a\x3a\x20\x19\x53\x95\xd1\x27\xa9\x81\x93\xa3\xab\x40\x32\x9c\ +\xa2\x7d\x77\x53\x33\xbb\xfb\x16\x85\x64\x20\xc1\x8f\x2d\xcf\xa3\ +\xa6\xf2\x96\x3f\x16\x0c\xc9\x18\xc2\x5f\x49\xa5\x0e\x52\x5f\x09\ +\x87\xa4\xbf\xa8\x61\x17\xa8\x93\x0b\xc3\xa2\x20\xe9\x2b\x66\xf4\ +\x25\xea\xe8\xd2\xe8\x18\x48\xfa\x29\x3d\x21\x9b\x3a\xcb\x9e\x50\ +\x1a\x92\x3e\xee\x98\x76\x95\x06\x70\x75\xda\x1d\x90\xb4\x57\x65\ +\xae\x8b\x06\xe1\x9a\x5b\x05\x92\xb6\x4a\x25\xb8\x69\x20\xee\x84\ +\x52\x90\xb4\x13\xf0\xd2\x25\x1a\xcc\xa5\x97\x02\x20\x69\xa4\xd1\ +\x01\x1a\xd0\x81\x46\x90\xb4\x10\x33\xc3\x43\x43\xf2\xcc\x88\x81\ +\x24\x9a\x23\xfe\x22\x0d\xeb\x62\xbc\x03\x92\x50\x75\x77\xd1\xd0\ +\x76\xd5\x85\x24\x4e\xe1\x89\x05\x34\xb8\x82\x89\x85\x21\x09\xd2\ +\xe5\x0c\x4d\xe0\x4c\x17\x48\x22\x44\x24\xd0\x24\x12\x22\x20\xa9\ +\xae\xe6\x31\x9a\xc6\xb1\x9a\x90\x54\x16\x9f\x4b\x13\xc9\x8d\x87\ +\xa4\xa6\x42\x1f\xd1\x64\x3e\x2a\x04\x49\x35\xb5\x13\x69\x3a\x89\ +\xb5\x21\xa9\xe4\xb9\x2b\x34\xa1\x2b\xcf\x41\x52\x43\xe4\x42\x9a\ +\xd4\xc2\x48\x48\x7e\xab\x93\x44\xd3\x4a\xaa\x03\xc9\x4f\x71\x57\ +\x68\x62\x57\xe2\x20\xf9\x65\x90\x87\xa6\xe6\x19\x04\xc9\x77\x8e\ +\x77\x68\x7a\xef\x38\x20\xf9\x28\x30\x81\x16\x90\x10\x08\xc9\x27\ +\xe1\xeb\x68\x09\xeb\xc2\x21\xf9\x20\x66\x37\x2d\x62\x77\x0c\x24\ +\xaf\xc5\x1e\xa5\x65\x1c\x8d\x85\xe4\xa5\xea\x29\xb4\x90\x94\xea\ +\x90\xbc\x72\x5f\x3a\x2d\x25\xfd\x3e\x48\x5e\x68\x9f\x43\x8b\xc9\ +\x69\x0f\x49\xb1\x76\x2e\x5a\x8e\xab\x1d\x24\x85\x1a\xe5\xd0\x82\ +\x72\x1a\x41\x52\xa4\x5a\x3a\x2d\x29\xbd\x1a\x24\x05\xca\x7e\x4f\ +\x8b\xfa\xbe\x2c\xa4\xdb\x2a\x7a\x84\x96\x75\xa4\x28\xa4\xdb\x08\ +\xdf\x45\x0b\xdb\x15\x0e\xe9\x96\x02\xd7\xd2\xd2\xd6\x06\x42\xba\ +\x05\xc7\x87\xb4\xb8\x0f\x1d\x90\x6e\x6e\x3c\x2d\x6f\x3c\xa4\x9b\ +\x1a\x48\x1b\x18\x08\xe9\x26\xba\x7b\x68\x03\x9e\xee\x90\x6e\xa8\ +\x56\x2e\x6d\x21\xb7\x16\xa4\x1b\x88\x38\x46\x9b\x38\x16\x01\xe9\ +\xcf\x12\x68\x1b\x09\x90\xfe\xa4\x17\x6d\xa4\x17\xa4\x3f\xa8\x91\ +\x43\x1b\xc9\xa9\x01\xe9\x3a\xe1\x47\x69\x2b\x47\xc3\x21\xfd\xde\ +\x3c\xda\xcc\x3c\x48\xbf\xf3\x37\xda\xce\xdf\x20\xfd\xa6\x7a\x0e\ +\x6d\x27\xa7\x3a\xa4\x5f\x85\x1f\xa6\x0d\x1d\x0e\x87\xf4\x8b\x39\ +\xb4\xa5\x39\x90\x7e\xf6\x38\x6d\xea\x71\x48\xd7\x44\xa4\xd0\xa6\ +\x52\x22\x20\x01\xe3\x68\x5b\xe3\x20\xa1\x86\x8b\xb6\xe5\xaa\x01\ +\x69\x3b\x6d\x6c\x3b\x6c\x2f\x8e\xb6\x16\x07\x9b\x8b\x4e\xa3\xad\ +\xa5\x45\xc3\xde\xa6\xd0\xe6\xa6\xc0\xd6\xea\xbb\x69\x73\xee\xfa\ +\xb0\x31\xe7\x1e\xda\xde\x1e\x27\xec\xeb\x79\x4a\x7c\x1e\xb6\x55\ +\x2c\x9d\x12\xd3\x8b\xc1\xae\x66\x52\xba\x66\x26\x6c\xea\x0e\x17\ +\xa5\x6b\x5c\xe5\x61\x4f\x53\x29\xfd\xec\x03\xd8\x52\xa9\x2b\x94\ +\x7e\x76\xb5\x0c\xec\x68\x3c\xa5\x5f\x4d\x80\x0d\x15\xbd\x4c\xe9\ +\x57\xd9\xc5\x60\x3f\x23\xa9\xb3\x82\x4b\x29\xc7\xf6\x6e\xdd\xba\ +\xf7\x58\xca\xa5\x02\xea\xec\x2d\xd8\x4e\x64\x06\xf5\x92\xf3\x7f\ +\x1f\x8f\xec\x76\x77\x61\xfc\x4e\xe1\xbb\xbb\x8d\x5c\x74\x20\x9b\ +\x7a\xb9\x14\x05\xbb\x19\x4c\x5d\x5c\xdd\x3a\xbc\x51\x20\x6e\x22\ +\xa0\xc1\xd0\xcd\x57\xa8\x8b\xe1\xb0\x99\xd0\x34\x6a\x2f\x65\x7c\ +\xab\x30\xdc\x46\x68\x8b\x7f\x9d\xa6\xf6\x2e\x44\xc0\x5e\xfa\x51\ +\x6b\x59\x73\x5b\x38\xa1\x88\xa3\xf9\x9c\x2c\x6a\x6d\x00\x6c\x25\ +\xe8\x34\xb5\xb5\xad\x5b\x38\xbc\x10\xd6\x75\x1b\xb5\x75\x26\x04\ +\x76\xd2\x8b\x5a\xf2\xac\x6a\x04\xaf\x35\x5a\xe5\xa1\x96\xfa\xc0\ +\x46\x1c\x49\xd4\x4e\xc1\xc2\x5a\xf0\x49\xad\x85\x05\xd4\xce\xc9\ +\x00\xd8\x47\x33\x6a\x67\x5d\x65\xf8\xac\xf2\x3a\x6a\xa7\x2d\xec\ +\x63\x16\xb5\x92\xf2\x38\xfc\xf2\x78\x0a\xb5\xf2\x11\x6c\x23\x2c\ +\x93\xda\x70\x8d\x8f\x80\x9f\x22\xc6\xbb\xa8\x8d\x9c\x42\xb0\x8b\ +\x2e\xd4\xc6\xa1\x9a\x50\x41\xcd\x43\xd4\x46\x4f\xd8\xc5\x5a\x6a\ +\x62\x46\x18\x54\x11\x36\x83\x9a\xd8\x02\x9b\x28\xe9\xa2\x06\xb2\ +\xba\x42\x35\x5d\xb3\xa8\x01\x77\x2c\xec\xe1\x15\x6a\xe0\xeb\xca\ +\x50\x51\xe5\xaf\xa9\x81\xa1\xb0\x87\x03\x14\x6f\x7d\x04\x54\x15\ +\xb1\x9e\xe2\x1d\x85\x2d\xd4\xa4\x78\x0b\x82\xa0\xb2\xa0\x05\x14\ +\xef\x1e\xd8\xc1\x38\x0a\x37\xd1\x01\xd5\x39\x26\x52\xb8\x49\xb0\ +\x01\x67\x2a\x45\x1b\x0e\x21\x86\x53\xb4\xf3\x81\xb0\xbe\xd6\x14\ +\x6d\x38\x04\x19\x4e\xd1\x3a\xc0\xfa\xe6\x53\xb0\x89\x10\x66\x22\ +\x05\x5b\x02\xcb\x0b\xc9\xa6\x58\x0b\x1c\x10\xc6\xb1\x80\x62\x5d\ +\x8d\x80\xd5\x35\xa3\x58\xeb\x83\x20\x50\xd0\x7a\x8a\xd5\x16\x56\ +\x37\x92\x42\x7d\x1d\x01\xa1\x22\xbe\xa6\x50\x63\x61\x75\x3b\x29\ +\xd2\xe5\x2a\x10\xac\xca\x65\x8a\xf4\x15\x2c\x2e\x22\x9f\x22\x75\ +\x83\x70\xdd\x28\x92\x3b\x1a\xd6\xd6\x96\x22\xcd\x84\x06\x66\x52\ +\xa4\x8e\xb0\xb6\xb1\x14\xe8\x9b\x30\x68\x20\xec\x1b\x0a\x34\x11\ +\xd6\xb6\x97\xe2\x14\xd4\x81\x26\xea\x14\x50\x9c\x43\xb0\xb4\xa8\ +\x02\x8a\xf3\x1e\x34\xf2\x1e\xc5\xf1\x14\x87\x95\x3d\x4a\x71\xce\ +\x14\x86\x46\x0a\x9f\xa1\x38\x9d\x61\x65\xef\x53\x9c\xae\xd0\x4c\ +\x57\x8a\x33\x1d\x56\x76\x88\xc2\x6c\x81\x86\xb6\x50\x98\x64\x58\ +\x58\x71\x0f\x45\xf1\xd4\x84\x86\x6a\x7a\x28\x4c\x59\x58\xd7\x93\ +\x14\x66\x19\x34\xb5\x8c\xc2\xc4\xc1\xba\xa6\x51\x98\xfa\xd0\x54\ +\x7d\x0a\x33\x07\xd6\xf5\x05\x45\x59\x07\x8d\xad\xa3\x28\xfb\x61\ +\x5d\x17\x29\xca\xfd\xd0\xd8\xfd\x14\xe5\x32\x2c\x2b\x86\xa2\x6c\ +\x83\xe6\xb6\x51\x94\x32\xb0\xaa\xc6\x14\xa5\x2b\x34\xd7\x95\xa2\ +\x3c\x08\xab\xea\x45\x41\xb2\xc2\xa0\xb9\xb0\x2c\x0a\xf2\x3c\xac\ +\x6a\x2c\x05\x99\x03\x1d\xcc\xa1\x20\xef\xc2\xaa\x3e\xa5\x20\xcd\ +\xa1\x83\xe6\x14\x64\x2d\xac\x2a\x91\x62\x9c\x76\x40\x07\x8e\xd3\ +\x14\xe3\x38\x2c\x2a\x30\x9f\x62\x8c\x85\x2e\xc6\x52\x8c\x82\x60\ +\x58\x53\x15\x0a\xd2\x0a\xba\x68\x45\x41\xaa\xc1\x9a\x1e\xa5\x18\ +\x79\x61\xd0\x45\x58\x1e\xc5\xe8\x04\x6b\x1a\x44\x31\x3e\x83\x4e\ +\x3e\xa3\x18\x83\x61\x4d\xb3\x28\xc6\x08\xe8\x64\x04\xc5\x98\x0d\ +\x6b\xda\x49\x31\x1e\x80\x4e\x1e\xa0\x18\x9f\xc3\x9a\xce\x51\x88\ +\xbc\x60\xe8\x24\x38\x8f\x42\x9c\x83\x35\xb9\x28\xc4\x51\xe8\xe6\ +\x28\x85\x70\xc1\x92\x42\x29\xc6\x0a\xe8\x66\x05\xc5\x08\x85\x15\ +\x15\xa7\x18\x63\xa1\x9b\xb1\x14\xa3\x38\xac\xa8\x22\xc5\xe8\x05\ +\xdd\xf4\xa2\x18\x15\x61\x45\x75\x28\x46\x63\xe8\xa6\x31\xc5\xa8\ +\x03\x2b\x6a\x42\x31\x4a\x40\x37\x25\x28\x46\x13\x58\xd1\xc3\x14\ +\x23\x10\xba\x09\xa4\x18\x0f\xc3\x8a\x3a\x53\x88\x1c\xe8\x28\x87\ +\x42\x74\x86\x15\xc5\x53\x88\x34\xe8\x28\x8d\x42\xc4\xc3\x8a\x5e\ +\xa6\x10\xc9\xd0\x51\x32\x85\x78\x19\x56\xf4\x06\x85\xd8\x07\x1d\ +\xed\xa3\x10\x6f\xc0\x8a\xc6\x53\x88\xad\xd0\xd1\x56\x0a\x31\x1e\ +\x56\x34\x9d\x42\x6c\x83\x8e\xb6\x51\x88\xe9\xb0\xa2\x05\x14\x62\ +\x3f\x74\xb4\x9f\x42\x2c\x80\x15\xad\xa2\x10\xc9\xd0\x51\x32\x85\ +\x58\x05\x2b\x5a\x46\x21\xd2\xa0\xa3\x34\x0a\xb1\x0c\x56\x34\x83\ +\x42\xe4\x42\x47\xb9\x14\x62\x06\xac\x68\x0c\xc5\x08\x84\x6e\x02\ +\x29\xc6\x18\x58\xd1\x40\x8a\x51\x12\xba\x29\x49\x31\x06\xc2\x8a\ +\x7a\x52\x8c\x26\xd0\x4d\x13\x8a\xd1\x13\x56\xd4\x81\x62\xc4\x43\ +\x37\xf1\x14\xa3\x03\xac\xe8\x7e\x8a\x31\x0e\xba\x19\x47\x31\xee\ +\x87\x15\x55\xa5\x18\x9f\x42\x37\x9f\x52\x8c\xaa\xb0\xa2\x62\x14\ +\xe3\x18\x74\x73\x8c\x62\x14\x83\x15\x05\x78\x28\x44\x7e\x08\x74\ +\x12\x92\x4f\x21\x3c\x01\xb0\xa4\x0c\x8a\xd1\x0c\x3a\x69\x46\x31\ +\x32\x60\x4d\x49\x14\x63\x24\x74\x32\x92\x62\x24\xc1\x9a\x96\x51\ +\x8c\x1d\xd0\xc9\x0e\x8a\xb1\x0c\xd6\x34\x8c\x62\xe4\x85\x43\x17\ +\xe1\x79\x14\xe3\x35\x58\xd3\x43\x14\xa4\x0d\x74\xd1\x86\x82\xb4\ +\x83\x35\x95\xa0\x20\xe3\xa1\x8b\xf1\x14\xa4\x14\x2c\x2a\x85\x62\ +\xa4\x38\xa1\x03\x67\x0a\xc5\x38\x03\xab\xfa\x94\x82\xb4\x84\x0e\ +\x5a\x52\x90\x35\xb0\xaa\x37\x28\xc8\x87\xd0\xc1\x87\x14\x64\x14\ +\xac\xea\x11\x0a\x72\x39\x02\x9a\x8b\xb8\x4c\x41\x1e\x83\x55\x95\ +\xa6\x28\x3d\xa0\xb9\x1e\x14\xe5\x0e\x58\xd6\x59\x0a\xb2\x13\x9a\ +\xdb\x49\x41\xd2\x61\x5d\x6b\x28\x4a\x53\x68\xac\x29\x45\xd9\x04\ +\xeb\x1a\x45\x51\x36\x42\x63\x1b\x29\xca\x58\x58\x57\x07\x0a\x73\ +\x2f\x34\x75\x2f\x85\xf9\x2b\xac\xab\x50\x1e\x45\xf9\x14\x9a\xfa\ +\x94\xa2\x14\x14\x81\x85\x6d\xa2\x28\x9e\x3a\xd0\x50\x1d\x0f\x45\ +\xd9\x09\x2b\x7b\x85\xc2\xec\x80\x76\x1c\x3b\x28\xcc\x50\x58\x59\ +\x15\x8a\xf3\x34\x34\xf3\x37\x8a\x53\x07\x96\x76\x9c\xc2\x9c\x8b\ +\x86\x46\x8a\x9c\xa7\x30\x3f\xc0\xda\x26\x51\x9c\x29\xd0\xc8\x07\ +\x14\x67\x26\xac\xad\x2d\xc5\x71\xdf\x0d\x4d\x34\x74\x53\x9c\xc7\ +\x60\x6d\xa1\x39\x14\xe7\x58\x04\x34\x10\x99\x4c\x71\xf2\x22\x61\ +\x71\xab\x29\xd0\x87\xd0\xc0\x02\x0a\xb4\x19\x56\xf7\x02\x45\xea\ +\x09\xe1\xe2\x29\xd2\x00\x58\x5d\x39\x8a\x94\x53\x1d\x82\x55\xcf\ +\xa1\x48\x77\xc1\xf2\x0e\x53\xa4\xc3\x91\x10\x2a\xf2\x30\x45\x3a\ +\x01\xeb\x1b\x47\xa1\x36\x07\x43\xa0\x90\x2d\x14\x6a\x0a\xac\xef\ +\x7e\x8a\xb5\xd8\x09\x61\x9c\x4b\x28\x56\x6b\xd8\xc0\x77\x14\x6b\ +\x32\x84\x99\x4e\xb1\x52\x9d\xb0\x81\x91\x14\xec\x35\x08\x32\x8a\ +\x82\x8d\x83\x1d\x54\xa2\x68\xaf\x41\x88\xd1\x14\xad\x26\x6c\x61\ +\x17\x45\x9b\xec\x84\xea\x9c\xd3\x29\xda\x01\xd8\x43\x1f\x0a\xb7\ +\x38\x18\x2a\x0b\x59\x4a\xe1\x5e\x86\x3d\x14\xcd\xa3\x70\x9b\x23\ +\xa1\xaa\xc8\x2d\x14\xce\x55\x02\x36\xb1\x82\xe2\x1d\xa9\x01\x15\ +\xd5\x38\x42\xf1\xd6\xc0\x2e\x1e\xa7\x06\x72\x9e\x81\x6a\x9e\xc9\ +\xa1\x06\x3a\xc3\x2e\x82\x33\xa8\x85\x84\x08\xa8\x22\x22\x81\x5a\ +\xb8\x14\x0a\xdb\xf8\x80\x9a\x38\x56\x1f\x2a\xb8\xfb\x18\x35\x31\ +\x03\xf6\x71\x3f\xb5\x51\x30\x39\x0a\x7e\x8a\x9e\xea\xa6\x36\x1e\ +\x80\x8d\x1c\xa7\x46\xce\x76\x83\x3f\x1c\x3d\xcf\x51\x23\x27\x1c\ +\xb0\x91\x37\xa9\x99\xad\x35\xe1\xb3\xbb\x3f\xa7\x66\x46\xc2\x4e\ +\xee\xa4\x76\x3c\xcb\xea\xc3\x27\xf7\xad\xa5\x86\xee\x84\xad\x6c\ +\xa2\x96\xd6\xdd\x0f\xaf\xb5\xd8\x4a\x2d\x6d\x86\xbd\x74\xa4\xb6\ +\xb6\x75\x8f\x80\x17\x22\x9f\xd9\x4d\x6d\x75\x84\xbd\x38\x4f\x52\ +\x63\xd9\xf3\xdb\x06\x40\x91\x80\x87\x16\xe6\x52\x63\xa7\x9c\xb0\ +\x99\x41\xd4\x5e\xda\xe4\x47\x0a\xe3\x36\x0a\x3f\x32\xf1\x2c\xb5\ +\x37\x18\x76\x53\x34\x97\x7a\x70\xed\x1a\xdd\x3c\x04\x37\x11\xde\ +\x7a\xcc\x97\x05\xd4\x43\x6e\x51\xd8\xce\x4c\xea\x25\xff\xd8\xca\ +\xb1\xbd\x1a\x97\x08\xc2\x6f\x82\x4a\x3c\xf0\xec\x84\xb5\xdf\xb9\ +\xa9\x97\xd9\xb0\x9f\x3a\xd4\xdb\xd5\x0b\x27\x0f\xed\xda\x75\xe8\ +\xe4\x85\xab\xd4\x5b\x5d\xd8\xd0\x0e\x4a\xbf\xda\x09\x3b\x7a\x92\ +\xd2\xaf\x9e\x82\x1d\x05\xfe\x40\xe9\x67\xa9\x41\xb0\xa5\xe1\x94\ +\x7e\xf6\x06\xec\xa9\xc4\x55\x4a\xd7\xe4\x95\x84\x4d\x25\x50\xba\ +\x66\x01\xec\xea\x5e\x4a\xd7\x34\x82\x6d\x7d\x49\x89\x5f\xc1\xbe\ +\x3a\x53\x62\x37\xd8\x97\x33\x99\xb6\x77\x3c\x00\x36\x16\x4f\xdb\ +\x7b\x0e\x76\x16\x9c\x42\x9b\x4b\x0d\x81\xad\xbd\x4c\x9b\x1b\x00\ +\x7b\x0b\xbf\x40\x5b\x4b\x8f\x80\xcd\xbd\x46\x5b\x1b\x01\xbb\x8b\ +\xce\xa2\x8d\x5d\x2e\x02\xdb\x1b\x4b\x1b\x1b\x0f\xa9\xd4\x15\xda\ +\xd6\xd5\xd2\x90\x30\x8d\xb6\xf5\x01\x24\xa0\xbc\x8b\x36\xe5\xaa\ +\x00\xe9\x9a\x04\xda\xd4\x7c\x48\x3f\xa9\xee\xa1\x2d\x79\x6a\x40\ +\xfa\xd9\x0a\xda\xd2\x0a\x48\xbf\x68\x40\x5b\x6a\x00\xe9\x57\x6b\ +\x68\x43\x6b\x20\xfd\x57\x5d\x0f\x6d\xc7\x53\x0f\xd2\x6f\x3e\xa1\ +\xed\x2c\x81\xf4\x3f\x77\x15\xd0\x66\xdc\xd5\x20\xfd\xce\x3c\xda\ +\xcc\x87\x90\x7e\xaf\x42\x3e\x6d\x25\xbf\x22\xa4\xeb\x4c\xa3\xad\ +\x4c\x87\x74\xbd\x32\xb9\xb4\x91\x2b\x7f\x81\xf4\x07\xef\xd0\x46\ +\xde\x85\xf4\x47\xc5\xb2\x68\x1b\xd9\x25\x20\xfd\xc9\x28\xda\xc6\ +\xdb\x90\xfe\x2c\x2a\x83\x36\xf1\x63\x34\xa4\x1b\x18\x42\x9b\x18\ +\x0e\xe9\x46\xc2\xd3\x68\x0b\xe7\x0b\x41\xba\xa1\xbf\xd3\x16\x06\ +\x40\xba\xb1\x90\xef\x69\x03\x3f\x84\x42\xba\x89\xa7\x69\x03\xbd\ +\x20\xdd\x8c\xe3\x00\x2d\xef\xa0\x13\xd2\x4d\xb5\xa0\xe5\xb5\x81\ +\x74\x0b\x6b\x68\x71\x1b\x20\xdd\x4a\xf5\x02\x5a\x9a\xbb\x16\xa4\ +\x5b\xfa\x37\x2d\x6d\x16\xa4\x5b\x2b\x79\x99\x16\x96\x5d\x1a\xd2\ +\x6d\xbc\x4e\x0b\x1b\x01\xe9\x76\xc2\x53\x69\x59\x67\x22\x20\xdd\ +\xd6\x33\xb4\xac\x78\x48\xb7\xe7\x3c\x48\x8b\x3a\xe4\x84\xa4\x40\ +\x1b\x5a\x54\x5b\x48\x8a\x6c\xa0\x25\x6d\x84\xa4\x4c\x2d\x37\x2d\ +\xc8\x5d\x0b\x92\x42\xb3\x68\x41\xb3\x21\x29\x55\x3a\x9b\x96\x93\ +\x5d\x06\x92\x62\xc3\x69\x39\xc3\x21\x29\x17\x9c\x4c\x8b\x49\x0e\ +\x86\xe4\x85\xb6\xb4\x98\xb6\x90\xbc\xb2\x9c\x96\xb2\x1c\x92\x77\ +\xca\xe5\xd0\x42\x72\xca\x41\xf2\xd2\x30\x5a\xc8\x30\x48\xde\x0a\ +\x4e\xa6\x65\x24\x07\x43\xf2\x5a\x5b\x5a\x46\x5b\x48\x3e\x58\x46\ +\x8b\x58\x06\xc9\x17\xe5\x72\x68\x09\x39\xe5\x20\xf9\x64\x18\x2d\ +\x61\x18\x24\xdf\x04\x27\xd1\x02\x92\x82\x21\xf9\xa8\x0d\x2d\xa0\ +\x0d\x24\x9f\x2d\xa3\xe9\x2d\x83\xe4\xbb\x72\x39\x34\xb9\x9c\x72\ +\x90\xfc\x30\x94\x26\x37\x14\x92\x3f\x82\x93\x68\x6a\x49\xc1\x90\ +\xfc\xd2\x86\xa6\xd6\x06\x92\x9f\x96\xd2\xc4\x96\x42\xf2\x57\x6c\ +\x0e\x4d\x2b\x27\x16\x92\xdf\x86\xd2\xb4\x86\x42\xf2\x5f\x70\x12\ +\x4d\x2a\x29\x18\x92\x0a\x5a\xd3\xa4\x5a\x43\x52\xc5\x52\x9a\xd2\ +\x52\x48\xea\x88\xcd\xa6\x09\x65\xc7\x42\x52\xc9\x10\x9a\xd0\x10\ +\x48\x6a\x09\x4e\xa4\xe9\x24\x06\x43\x52\x4d\x6b\x9a\x4e\x6b\x48\ +\x2a\x5a\x42\x93\x59\x02\x49\x4d\xb1\xd9\x34\x95\xec\x58\x48\xaa\ +\x1a\x42\x53\x19\x02\x49\x5d\xc1\x89\x34\x91\xc4\x60\x48\x2a\x7b\ +\x90\x26\xf2\x20\x24\xd5\xcd\xa4\x69\xcc\x84\xa4\xbe\xa8\x54\x9a\ +\x44\x6a\x14\x24\x01\x3a\xd2\x24\x3a\x42\x12\x62\x31\x4d\x61\x31\ +\x24\x31\x4a\x5c\xa4\x09\x5c\x2c\x01\x49\x90\x38\x9a\x40\x1c\x24\ +\x61\xd6\xd1\xf0\xd6\x41\x12\xa7\x5c\x16\x0d\x2e\xab\x1c\x24\x81\ +\x5e\xa4\xc1\xbd\x08\x49\x24\xc7\x4e\x1a\xda\x4e\x07\x24\xa1\xaa\ +\x5e\xa1\x81\x5d\xa9\x0a\xc9\x57\x4e\x28\x32\x94\x06\x36\x14\x8a\ +\x38\x21\x5d\x27\xbc\xd9\x90\x95\x69\x13\xa0\x48\xe0\x01\x1a\xd6\ +\x81\x40\x28\x32\x21\x6d\xe5\x90\x66\xe1\x90\x7e\x52\x29\x6e\xea\ +\x01\x17\xaf\x71\x37\x84\x22\xf5\x5c\x34\x28\x57\x3d\x28\xd2\xd0\ +\xcd\x6b\x5c\x07\xa6\xc6\x55\x82\xad\x15\x6a\x31\x7c\xf5\x05\xfe\ +\xe6\x70\x30\x14\x19\x43\x83\x1a\x03\x45\x82\x0f\xf3\x37\x17\x56\ +\x0f\x6f\x51\x08\x36\xe4\xa8\xda\x73\xfa\x41\x37\xaf\x37\x12\x8a\ +\x84\x26\xd2\x90\x12\x43\xa1\xc8\x48\x5e\xcf\x7d\x70\x7a\xcf\xaa\ +\x0e\xd8\x47\x54\xeb\x37\xd6\x65\xf0\x06\xf2\x6b\x41\x91\x26\x1e\ +\x1a\x90\xa7\x09\x14\xa9\x95\xcf\x1b\xc8\x58\xf7\x46\xeb\x28\x58\ +\x9e\xa3\x7a\xfc\xac\xc3\x6e\xde\xcc\xde\x00\x28\x32\x95\x06\x34\ +\x15\x8a\x04\xec\xe5\xcd\xb8\x0f\xcf\x8a\xaf\xee\x80\x65\x55\xeb\ +\xbf\xf6\x12\x6f\xed\x1f\x50\x24\xf2\x34\x0d\xe7\x74\x24\x14\xf9\ +\x07\x6f\xed\xd2\xda\xfe\xd5\x60\x3d\x45\x3b\xcf\xfa\x9e\xb7\x97\ +\x5b\x09\x8a\x3c\x4c\xc3\x79\x18\x8a\x54\xca\xe5\xed\x7d\x3f\xab\ +\x73\x51\x58\x47\x60\x93\xd1\x7b\xdc\x54\xe6\x33\x07\x14\x99\x4f\ +\x83\x99\x0f\x45\x1c\x9f\x51\x19\xf7\x9e\xd1\x4d\x02\x61\x01\x15\ +\xfb\xac\xc8\xa4\x17\x5e\x80\x22\x31\xe7\x68\x28\xe7\x62\xa0\xc8\ +\x0b\xf4\x42\xe6\x8a\x3e\x15\x61\x6a\xf5\x47\x1f\xa6\x97\x32\xcb\ +\x42\x91\xa7\x68\x28\x4f\x41\x91\xb2\x99\xf4\xd2\xe1\xd1\xf5\x61\ +\x4e\x01\x0f\x4e\x3c\x4d\x1f\xac\x81\x32\x2b\x69\x20\x2b\xa1\xcc\ +\x1a\xfa\xe0\xf4\xc4\x07\x03\x60\x32\x61\x1d\xe7\x5d\xa4\x8f\xba\ +\x43\x91\x32\x97\x68\x18\x97\xca\x40\x91\xee\xf4\xd1\xc5\x79\x1d\ +\xc3\x60\x1a\x45\x9e\x5e\x9e\x43\xdf\x5d\x2c\x0e\x45\x7a\xd3\x30\ +\x7a\x43\x91\xe2\x17\xe9\xbb\x9c\xe5\x4f\x17\x81\x09\x84\x3c\xb1\ +\x32\x8f\xfe\xf9\x18\xca\x6c\xa5\x41\x6c\x85\x32\x1f\xd3\x3f\x79\ +\x2b\x9f\x08\x81\xb1\x35\x9e\x9e\x41\xff\x75\x84\x22\x77\xe6\xd0\ +\x10\x72\xee\x84\x22\x1d\xe9\xbf\x8c\xe9\x8d\x61\x58\x95\x47\x7e\ +\x47\x55\xa4\x46\x41\x91\x01\x34\x84\x01\x50\x24\x2a\x95\xaa\xf8\ +\x6e\x64\x65\x18\x50\x4c\xdf\xdd\x54\xcd\x4c\x28\x12\xb0\x87\x06\ +\xb0\x27\x00\x8a\xcc\xa4\x6a\x76\xf7\x8d\x81\xa1\x38\xda\xac\xc8\ +\xa7\x9a\x5a\x42\x91\x1a\x57\xa9\xbb\xab\x35\xa0\x48\x4b\xaa\x29\ +\x7f\x45\x1b\x07\x8c\x22\xaa\x7f\x12\x55\x76\x22\x1c\x8a\x0c\xa4\ +\xee\x06\x42\x91\xf0\x13\x54\x59\x52\xff\x28\x18\x41\xcd\xe9\xd9\ +\x54\xdf\x7b\x50\xc4\xb9\x9d\x3a\xdb\xee\x84\x22\xef\x51\x7d\xd9\ +\xd3\x6b\x42\x67\x81\x4f\x7e\x46\x21\xdc\x8d\xa0\x48\xf9\x2c\xea\ +\x2a\xab\x3c\x14\x69\xe4\xa6\x10\x9f\x3d\x19\x08\xfd\x94\x7a\x23\ +\x95\xa2\x1c\x09\x86\x22\xf1\xd4\x55\x3c\x14\x09\x3e\x42\x51\x52\ +\xdf\x28\x05\x7d\x54\x99\x93\x4f\x81\x46\x41\x99\xd5\xd4\xd1\x6a\ +\x28\x33\x8a\x02\xe5\xcf\xa9\x02\xed\xd5\xfe\xd8\x4d\xa1\xf2\x6b\ +\x43\x91\x92\x17\xa8\x9b\x0b\x25\xa1\x48\xed\x7c\x0a\xe5\xfe\xb8\ +\x36\xb4\xd5\x70\x95\x87\xa2\xed\x0b\x80\x22\x4f\x50\x37\x4f\x40\ +\x91\x80\x7d\x14\xcd\xb3\xaa\x21\xb4\xd3\x7c\x33\xb5\x30\x18\xca\ +\xcc\xa7\x4e\xe6\x43\x99\xc1\xd4\xc2\xe6\xe6\xd0\x46\xbb\x2f\xa8\ +\x8d\x2b\x95\xa1\x48\x74\x0a\x75\x91\x12\x0d\x45\x2a\x5f\xa1\x36\ +\xbe\x68\x07\xf1\x9a\xef\xa3\x66\xb6\x3b\xa0\x48\x2b\x0f\x75\xe0\ +\x69\x05\x45\x1c\xdb\xa9\x99\x7d\xcd\x21\x56\xa5\x15\xd4\x52\x1f\ +\x28\x33\x99\x3a\x98\x0c\x65\xfa\x50\x4b\x2b\x2a\x41\x9c\xe8\x09\ +\x79\xd4\x54\x56\x2c\x14\x09\x4b\xa2\xe6\x92\xc2\xa0\x48\x6c\x16\ +\x35\x95\x37\x21\x1a\x62\x04\xbe\x78\x91\x5a\x5b\x07\x65\x1a\x16\ +\x50\x63\x05\x0d\xa1\xcc\x3a\x6a\xed\xe2\x8b\x81\x10\xa0\xdd\x51\ +\xea\x20\x0e\xca\x8c\xa6\xc6\x46\x43\x99\x38\xea\xe0\x68\x3b\xa8\ +\xad\xda\x46\xea\x22\xbd\x04\x14\x09\xda\x4f\x4d\xed\x0f\x82\x22\ +\x25\xd2\xa9\x8b\x8d\xd5\xa0\xa6\xc0\x61\x57\xa9\x93\x4f\xa0\x4c\ +\x8d\xab\xd4\xd0\xd5\x1a\x50\xe6\x13\xea\xe4\xea\xb0\x40\xa8\xa6\ +\xf6\x7e\xea\xa7\x13\x94\x19\x48\x0d\x0d\x84\x32\x9d\xa8\x9f\xfd\ +\xb5\xa1\x8e\xa0\x11\xf9\xd4\xd1\x99\x68\x28\xe2\xdc\x4e\xcd\x6c\ +\x77\x42\x91\xe8\x33\xd4\x51\xfe\x88\x20\xa8\xa0\xfe\x41\xea\x6b\ +\x36\x94\x29\x9f\x45\x8d\x64\x95\x87\x32\xb3\xa9\xaf\x83\xf5\xe1\ +\xaf\x90\xb7\x5d\xd4\x5b\x2b\x28\x13\x4f\x8d\xc4\x43\x99\x56\xd4\ +\x9b\xeb\xed\x10\xf8\xa5\xce\x11\xea\xef\x64\x04\x94\x59\x45\x4d\ +\xac\x82\x32\x11\x27\xa9\xbf\x23\x75\xe0\x87\x1e\xb9\xd4\x99\x3b\ +\x79\xc9\xeb\x1d\x0b\x43\x99\x92\x17\xa8\x81\x0b\x25\xa1\x4c\xe1\ +\x8e\xaf\x2f\x49\x76\x53\x67\xb9\x3d\xe0\xab\xa0\x49\xd4\xd3\x8f\ +\xdb\x27\x3f\xdb\x20\x1c\xde\x78\x82\x1a\x78\x02\xde\x08\x6f\xf0\ +\xec\xe4\xed\x3f\x52\x4f\x93\x82\xe0\x93\x52\x3b\xa9\x93\x82\x63\ +\x8b\x87\x3f\x52\x0e\x3e\x98\x4f\xe1\xe6\xc3\x07\xe5\x1e\x19\xbe\ +\xf8\x58\x01\x75\xb2\xb3\x14\x7c\x70\x7f\x2a\x75\x90\xbe\x6d\x62\ +\xaf\x7b\xc2\xe0\xab\xe8\x14\x0a\x96\x12\x0d\x5f\x85\xdd\xd3\x6b\ +\xe2\xb6\x74\xea\x20\xf5\x7e\x78\xad\x6f\x3e\xb5\xe5\x3a\xb2\x68\ +\x48\xbb\xb2\xf0\x53\x2b\x0f\x85\xf2\xb4\x82\x9f\xca\xb6\x1b\xb2\ +\xe8\x88\x8b\xda\xca\xef\x0b\xef\x04\xcf\xa3\x96\x2e\x2e\xef\x7f\ +\x77\x08\x54\x31\x99\x42\x4d\x86\x2a\x42\xee\xee\xbf\xfc\x22\xb5\ +\x34\x2f\x18\x5e\x08\x5d\x47\xcd\x9c\x5f\xd2\xaf\x96\x03\xaa\x09\ +\x4b\xa4\x40\x89\x61\x50\x8d\xa3\x56\xbf\x25\xe7\xa9\x99\xf5\x61\ +\x50\x2c\x62\x0b\xb5\x71\xf6\xe3\x3e\xd5\xa1\xb2\x7a\x79\x14\x26\ +\xaf\x1e\x54\x56\xbd\xcf\xc7\x67\xa9\x8d\x6d\x85\xa0\x50\xe1\xcf\ +\xa9\x81\x1f\x16\x3c\x57\x15\x22\x0c\xa4\x30\x03\x21\x42\xd5\xe7\ +\x16\xfc\x40\x0d\xec\x8a\x82\x22\x45\xbf\xa2\x68\xa7\x13\xe2\x2b\ +\x41\x14\xc7\x46\x0a\xb2\xd1\x01\x51\x2a\xc5\x27\x9c\xa6\x68\xfb\ +\x63\xa0\x40\xf1\x83\x14\xea\xe4\xdc\x9e\x15\x20\x54\xa9\xf3\x14\ +\xe2\x7c\x29\x08\x55\xa1\xe7\xdc\x93\x14\xea\x70\x29\xdc\x56\xe9\ +\xa3\x14\xc7\xb5\xa9\x4f\x39\x88\xd7\x9e\x42\xb4\x87\x78\xe5\xfa\ +\x6c\x72\x51\x9c\xe4\x58\xdc\x46\xd1\x24\x8a\x72\x75\x75\xcf\xa2\ +\xd0\xc6\x24\x0a\x30\x09\xda\x28\xda\x73\xf5\x55\x8a\xf2\x5d\x71\ +\xdc\x52\xe0\x16\x8a\x91\xbd\xa4\x4b\x24\x34\x13\x7a\x88\xaa\x3b\ +\x14\x0a\xcd\x44\x76\x59\x92\x4d\x31\x76\x04\xe3\x56\x3e\xa0\x08\ +\x3f\xce\xef\x14\x06\x4d\xd5\xb8\x42\x95\x5d\xa9\x01\x4d\x85\x75\ +\x9a\xff\x23\x45\x98\x85\x5b\xe8\x47\xf5\x9d\x9f\xf9\x50\x10\x34\ +\xd7\x97\x2a\xeb\x0b\xcd\x05\x3d\x34\xf3\x3c\xd5\xf7\x32\x6e\xaa\ +\xb5\x8b\x2a\xfb\x61\x52\xf3\x00\xe8\xe2\x53\xaa\xea\x53\xe8\x22\ +\xa0\xf9\xa4\x1f\xa8\xb2\x82\xb6\xb8\x89\x2a\x3f\x52\x55\x27\xc6\ +\x35\x72\x40\x2f\xc5\xce\x50\x45\x67\x8a\x41\x2f\x8e\x46\xe3\x4e\ +\x50\x55\x97\xaa\xe2\x86\x8a\x24\x51\x45\x05\x2b\xdb\x38\xa0\xa7\ +\x96\x1e\xaa\xc6\xd3\x12\x7a\x72\xb4\x59\x59\x40\x15\x25\x17\xc1\ +\x8d\x2c\xa1\x7a\xd2\x46\xc7\x42\x6f\xe3\xa8\x9a\x71\xd0\x5b\xec\ +\xe8\x34\xaa\x67\x09\x6e\xe0\x11\xaa\x66\xfb\x53\x41\xd0\x5f\xd0\ +\x3e\xaa\x64\x5f\x10\xf4\x17\xf4\xd4\x76\xaa\xe6\x11\xfc\x49\xc4\ +\x29\xaa\x23\x6b\x4a\x0d\x18\x43\xe5\x6c\xaa\x22\xbb\x32\x8c\xa1\ +\xc6\x94\x2c\xaa\xe3\x54\x04\xfe\xe8\x1d\xaa\xe2\xd0\x0b\x85\x60\ +\x18\xcf\x50\x15\xcf\xc0\x30\x0a\xbd\x70\x88\xaa\x78\x07\x7f\x50\ +\xd7\x45\xff\xe5\x2d\x68\x02\x43\x59\x4c\x15\x2c\x86\xa1\x34\x59\ +\x90\x47\xff\xb9\xea\xe2\x3a\xce\x3d\xf4\xdb\xe9\xa1\x25\x60\x30\ +\xd1\xa7\xe9\xb7\xd3\xd1\x30\x98\x12\x43\x4f\xd3\x6f\x7b\x9c\xf8\ +\xbd\x7e\xf4\x57\x5a\xbf\x20\x18\x4f\x93\x02\xfa\xa9\xa0\x09\x8c\ +\x27\xb8\xdf\x39\xfa\xab\x1f\x7e\xa7\x48\x26\xfd\x93\xf9\x5a\x04\ +\x0c\x69\x24\xfd\x34\x12\x86\x54\xe8\xf5\x4c\xfa\x27\xb3\x08\xfe\ +\x67\x30\xfd\x72\x65\x42\x0c\x0c\x2a\xe0\x0b\xfa\xe5\x8b\x00\x18\ +\x54\xb1\x77\xaf\xd2\x2f\x83\xf1\x9b\xc0\xef\xe9\x87\x82\xd9\xb1\ +\x30\xae\xf2\x97\xe8\x87\x4b\xe5\x61\x5c\xe5\xe6\xba\xe9\x87\xef\ +\x03\xf1\x5f\x9d\xe9\x87\x65\xd5\x60\x68\x5d\xe8\x87\x2e\x30\xb4\ +\x1a\x2b\xe9\x87\xce\xf8\xaf\x5d\xf4\xd9\xd6\x06\x30\xba\x79\xf4\ +\xd9\x3c\x18\xdd\x7d\xdb\xe9\xb3\x5d\xf8\x55\x03\xfa\x6a\x7f\x1b\ +\x18\x5f\xa1\x43\xf4\xd1\xa1\x42\x30\xbe\x76\x07\xe9\xab\x06\xf8\ +\xc5\x42\xfa\xc6\xf5\x5a\x00\xcc\xa0\xfc\x79\xfa\xe4\x7c\x79\x98\ +\x41\xe0\xc8\x02\xfa\x66\x21\x7e\xf6\x17\x17\x7d\xf2\x5d\x23\x98\ +\x44\x93\x3c\xfa\x20\xaf\x09\x4c\xa2\xf1\x49\xfa\xc4\xf5\x17\xfc\ +\xa4\x1f\x7d\x92\x10\x09\xd3\xe8\xe1\xa6\xd7\xdc\x3d\x60\x1a\x51\ +\x0b\xe8\x93\x7e\xf8\xc9\x72\xfa\xe0\x52\x57\x98\x49\x57\x17\xbd\ +\xe4\xea\x0a\x33\xe9\x9e\x49\x1f\x2c\xc7\x35\xce\x74\x7a\xef\xf3\ +\x3b\x60\x2e\x9d\xf2\xe8\x95\xbc\x4e\x30\x97\xf2\x5f\xd0\x7b\xe9\ +\x4e\x00\xf5\xe8\xb5\x82\x37\x02\x60\x36\x2d\x53\xe9\x85\xd4\x96\ +\x30\x9b\x80\x11\x05\xf4\x5a\x3d\x00\x03\xe8\xad\x94\xfb\x60\x42\ +\xd1\x73\xa8\xd8\xdc\x68\x98\xd0\x7d\x29\xf4\xd6\x00\x00\x6b\xe8\ +\xa5\x13\x15\x60\x4e\x6d\x4f\x53\x91\x94\x87\x61\x4e\x15\x4e\xd0\ +\x4b\x6b\x80\x80\x4c\x7a\x27\xa9\x2c\xcc\x2a\xf2\x03\x0f\x6f\x6f\ +\x66\x61\x98\x55\xd9\x24\x7a\x27\x33\x00\x0d\xe9\x9d\xc3\x25\x61\ +\x62\x0f\x7e\xc7\xdb\x38\xd5\x1a\x26\x56\xf2\x30\xbd\xd3\x10\x71\ +\xf4\xca\x85\x3b\x60\x6a\x21\x7f\x5d\xed\xe2\x4d\x15\xac\x7b\x2a\ +\x14\xa6\x76\xc7\x05\x7a\x25\x0e\x03\xe8\x8d\x82\x96\x30\xbd\x12\ +\x2f\x1f\xe0\x0d\x1d\x1c\x58\x0a\xa6\xd7\xb2\x80\xde\x18\x80\x31\ +\xf4\xc6\x60\x58\x42\xad\xf1\xa9\xfc\x83\xb3\xef\xd6\x85\x25\x0c\ +\xa6\x37\xc6\x60\x36\xbd\x70\xd4\x09\xab\x28\xf3\xd0\xe0\xf9\x9b\ +\xf6\x26\xa5\xa5\x25\xed\xdd\xf4\xd1\x90\x76\x65\x61\x15\xce\x44\ +\x7a\x61\x36\x56\xd1\x0b\x7f\x85\x64\x78\x5d\xe9\x85\x55\xd8\x4d\ +\xe5\x8e\x38\x20\x19\x9e\xf3\x5b\x2a\xb7\x1b\xc7\xa9\xdc\x34\x48\ +\x26\x30\x93\xca\x1d\x47\x16\x95\x7b\x0e\x92\x09\xbc\x40\xe5\xb2\ +\x90\x4f\xe5\x7a\x42\x32\x81\x9e\x54\x2e\x1f\xe7\xa9\xdc\x5c\x48\ +\x26\x30\x97\xca\x9d\xc7\xb7\x54\xee\x04\x24\x13\x38\x41\xe5\xbe\ +\xc5\x57\xf4\x42\x35\x48\x86\x57\x8d\x5e\xf8\x0a\x9b\xe8\x85\xcf\ +\x1c\x90\x0c\xce\xf1\x19\xbd\xb0\x09\x4b\xe8\x8d\x3e\x90\x0c\xae\ +\x0f\xbd\xb1\x04\x93\xe9\x8d\xac\x58\x48\x86\x16\x9b\x45\x6f\x4c\ +\x46\x6f\x7a\x65\x5b\x28\x24\x03\x0b\xdd\x46\xaf\xf4\xc6\xbd\xf4\ +\xce\x86\x50\x48\x86\x15\xba\x81\xde\xb9\x17\x61\x05\xf4\xce\x86\ +\x50\x48\x06\x15\xba\x81\xde\x29\x08\x03\x8e\xd2\x4b\x1b\x42\x21\ +\x19\x52\xe8\x06\x7a\xe9\x28\x80\x45\xf4\xd6\x86\x48\x48\x06\x14\ +\xb9\x81\xde\x5a\x04\xe0\x45\x7a\x2d\xb9\x36\x24\xc3\xa9\x9d\x4c\ +\xaf\xbd\x08\xa0\xac\x87\x5e\xcb\xed\x05\xc9\x60\x7a\xe5\xd2\x6b\ +\x9e\xb2\xb8\x66\x2f\x7d\x30\x2f\x1c\x92\x81\x84\xcf\xa3\x0f\xf6\ +\xe2\x27\xc3\xe8\x8b\x6f\xaa\x42\x32\x8c\xaa\xdf\xd0\x17\xc3\xf0\ +\x93\x6a\xf4\x49\xf6\xa0\x40\x48\x86\x10\x38\x28\x9b\x3e\xa9\x86\ +\x9f\x25\xd2\x37\xdf\x34\x81\x64\x00\x4d\xbe\xa1\x6f\x12\xf1\x8b\ +\x81\xf4\x91\x67\x76\x0c\x24\x9d\xc5\xcc\xf6\xd0\x47\x03\xf1\x8b\ +\xc2\x99\xf4\xd5\xc5\x78\x07\x24\x1d\x39\xe2\x2f\xd2\x57\x99\x85\ +\xf1\xab\xf1\xf4\xdd\xe7\xf5\x20\xe9\xa6\xde\xe7\xf4\xdd\x78\xfc\ +\x57\xac\x8b\xbe\xf3\x2c\xad\x09\x49\x17\x35\x97\x7a\xe8\x3b\x57\ +\x2c\x7e\xf3\x11\xfd\xe1\x5e\x54\x15\x92\xe6\xaa\x2e\x72\xd3\x1f\ +\x1f\xe1\x7f\x6a\xbb\xe9\x97\x82\x84\x4a\x90\x34\x55\x29\xa1\x80\ +\x7e\x71\xd7\xc2\xef\x4c\xa7\x9f\x5c\xb3\xcb\x43\xd2\x4c\xf9\xd9\ +\x2e\xfa\xe9\x03\xfc\x5e\x4c\x06\xfd\x95\x3f\xa3\x06\x24\x4d\xd4\ +\x98\x91\x4f\x7f\xa5\x17\xc5\x75\x5e\xa4\x0a\x36\x75\x70\x42\x12\ +\xcc\xd9\x61\x13\x55\xf0\x02\xae\x17\x70\x90\x6a\x38\xde\xbf\x30\ +\x24\x81\x0a\xf7\x3f\x4e\x35\x1c\x70\xe2\x0f\x9a\x51\x1d\x59\x93\ +\x2a\x43\x12\xa4\xf2\xa4\x2c\xaa\xc2\xd3\x18\x7f\xf2\x2e\x55\xe2\ +\x59\xdb\xc6\x01\x49\x75\x8e\x36\x6b\x3d\x54\xc9\x58\xfc\x59\xf0\ +\x3e\xaa\xe6\xdb\xd7\x2b\x40\x52\x55\x85\xd7\xbf\xa5\x6a\xf6\x04\ +\xe1\x06\x2a\x65\x51\x3d\x9e\x1d\xbd\xa3\x20\xa9\x24\xaa\xf7\x0e\ +\x0f\xd5\x93\x59\x11\x37\xd4\x9d\xaa\xba\xb2\xb8\x7d\x20\x24\xbf\ +\x05\xb6\x5f\x7c\x85\xaa\xea\x86\x9b\x98\x4b\x95\x9d\x7b\xbf\x3e\ +\x24\xbf\xd4\x7f\xff\x1c\x55\x36\x17\x37\x13\xb6\x8b\xaa\x3b\xf2\ +\x6a\x25\x48\x3e\xaa\xf4\xea\x11\xaa\x6e\x57\x18\x6e\x2a\x26\x91\ +\x02\x1c\x79\xbb\x81\x03\x92\x97\x1c\x0d\xde\x3e\x42\x01\x12\x63\ +\x70\x0b\x15\xd2\x28\x44\xea\xf4\x87\x82\x21\x29\x16\xfc\xd0\xf4\ +\x54\x0a\x91\x56\x01\xb7\x54\xff\x32\x05\xc9\xfa\xa4\x5b\x34\x24\ +\x05\xa2\xbb\x7d\x92\x45\x41\x2e\xd7\xc7\x6d\x3c\xe4\xa2\x30\xae\ +\xcd\x2f\x95\x83\x74\x4b\xe5\x5e\xda\xec\xa2\x30\xae\x87\x70\x5b\ +\x9d\xf2\x28\xd2\xd1\xc9\x8f\x15\x81\x74\x43\x45\x1e\x9b\x7c\x94\ +\x22\xe5\x75\x82\x02\x0f\x5f\xa1\x58\xee\x7d\x63\xdb\x86\x43\xba\ +\x4e\x78\xdb\xb1\xfb\xdc\x14\xeb\xca\xc3\x50\xa4\x45\x36\x85\xcb\ +\xdb\x31\xe2\x81\x20\x48\x3f\x0b\x7a\x60\xc4\x8e\x3c\x0a\x97\xdd\ +\x02\x0a\x35\xce\xa4\x16\xb2\xd7\x0f\xaa\xef\x84\xcd\x39\xeb\x0f\ +\x5a\x9f\x4d\x2d\x64\x36\x86\x62\xf7\x5c\xa0\x46\x32\x36\x8c\x6c\ +\x57\x0c\x36\x55\xac\xdd\xc8\x0d\x19\xd4\xc8\x85\x7b\xe0\x85\x72\ +\x7b\xa8\xa1\xe3\x0b\xfb\x37\x0a\x81\xad\x84\x34\xea\xbf\xf0\x38\ +\x35\xb4\xa7\x1c\xbc\x12\x3c\x8d\xda\xca\xdb\x3b\x25\xae\x8a\x03\ +\x36\xe0\xa8\x12\x37\x65\x6f\x1e\xb5\x35\x2d\x18\xde\x8a\xcb\xa1\ +\xe6\x32\x36\x8c\x6a\x5f\x06\x16\x56\xa6\xfd\xa8\x0d\x19\xd4\x5c\ +\x4e\x1c\x7c\x50\x2b\x99\xba\xc8\xd8\x31\xad\x6f\xb3\x18\x58\x4c\ +\x4c\xb3\xbe\xd3\x76\x64\x50\x17\xc9\xb5\xe0\x93\xc2\xcb\xa9\x9f\ +\xb3\x9b\xde\xeb\xdd\x28\x12\x16\x10\xd9\xa8\xf7\x7b\x9b\xce\x52\ +\x3f\xcb\x0b\xc3\x57\x83\x0a\xa8\xaf\x53\x6b\xc7\xc6\xd5\x0b\x85\ +\x49\x85\xd6\x8b\x1b\xbb\xf6\x14\xf5\x55\x30\x08\x7e\x68\x96\x46\ +\xfd\xb9\x4f\x6e\x99\x35\xbc\x6b\xa3\x12\x30\x8d\x12\x8d\xba\x0e\ +\x9f\xb5\xe5\xa4\x9b\xfa\x4b\x6b\x06\xbf\x94\xde\x49\xc3\xc8\x3e\ +\xbc\x6a\x62\xff\x47\x6b\x46\xc0\xb0\x22\x6a\x3e\xda\x7f\xe2\xaa\ +\xc3\xd9\x34\x8c\x9d\xa5\xe1\xa7\xc0\x09\x6e\x1a\xcc\xf9\x2f\x17\ +\xbd\xdd\xbb\x65\x8d\x62\x0e\x18\x84\xa3\x58\x8d\x96\xbd\xdf\x5e\ +\xf4\xe5\x79\x1a\x8c\x7b\x42\x20\xfc\x77\xef\x57\x34\x26\x57\xea\ +\x81\xf5\xf3\xc6\x0e\xe8\xde\xaa\x56\x09\x27\x34\xe7\x2c\x51\xab\ +\x55\xf7\x01\x63\xe7\xad\x3f\x90\xea\xa2\x31\x7d\x75\x2f\x54\xe1\ +\x7c\x21\x83\x06\x57\x90\x76\xf0\x3f\xf3\xdf\x19\xf4\x74\xdb\x06\ +\x77\x95\x89\x74\x40\x10\x47\xa1\x32\x77\x35\x68\x13\xf7\x8f\xf1\ +\x09\x1b\xbf\x4e\x2b\xa0\xc1\xa5\x3f\xef\x84\x5a\x8a\xcf\xf1\xd0\ +\x3c\xdc\x99\x29\x47\xbe\xfc\xcf\xd2\x39\x13\x47\x0f\x7a\xbe\xeb\ +\x23\x4d\xeb\x56\x2c\x16\x02\x1f\x84\x14\xab\x58\xb7\x69\xfb\xae\ +\xcf\x0f\x1a\xfd\xfe\x9c\xa5\xff\xd9\x7d\x24\x25\xd3\x4d\xf3\xf0\ +\xcc\x8c\x81\x9a\xee\xfb\x3f\x9a\x59\xfe\xe5\x8c\xf3\xa9\xa7\x8e\ +\x1f\x3b\xb4\x7f\xcf\xe7\xdb\x36\xad\xfb\x74\xe9\xc7\xf3\xe7\xfc\ +\x7b\xea\xfb\xe3\xc7\x8c\x1a\x35\x66\xfc\xfb\x53\xff\x3d\x67\xfe\ +\xc7\x4b\x3f\x5d\xb7\x69\xdb\xe7\x7b\xf6\x1f\x3a\x76\xfc\x54\xea\ +\xf9\x8c\xcb\xf9\x34\xb3\x7d\x0d\xa1\xb2\x80\x97\x2e\x51\x32\x89\ +\x8c\x3e\x4e\xa8\xaf\x64\x02\x25\x33\xf0\xcc\x2e\x06\x31\x9a\x7e\ +\x43\xc9\xf0\x0e\x34\x82\x30\x81\x03\xb2\x28\x19\xda\x8f\x7d\x9d\ +\x10\xa9\xf8\x3f\x33\x29\x19\x56\xfa\x88\x22\x10\x2d\xfa\xb5\x0b\ +\x94\x0c\x29\x6d\x50\x21\x68\x21\x62\x40\x2a\x25\xc3\xf9\xbe\x5f\ +\x28\xb4\x12\xf2\xfc\x09\x4a\x86\xf2\x6d\x7c\x10\xb4\x14\x18\x77\ +\x94\x92\x61\x1c\xee\x16\x00\xad\x39\x9e\xd8\x4f\xc9\x10\xbe\xea\ +\xe4\x80\x2e\x1e\xde\x49\x49\x77\x3b\xdb\x42\x3f\x4d\x97\xe7\x53\ +\xd2\x91\x6b\x79\x53\xe8\xab\xe4\xa0\x44\x4a\x3a\x49\x1a\x5c\x12\ +\x06\xd0\x64\x5e\x0e\x25\xcd\xe5\x7c\xf8\x00\x8c\xa2\xf0\xf3\x7b\ +\x29\x69\x6a\xdf\x0b\x51\x30\x94\xda\x13\xd3\x29\x69\x24\x63\x72\ +\x5d\x18\x4f\x48\xd7\xcd\x1e\x4a\xc2\x79\xb6\x76\x0f\x85\x41\x55\ +\x18\xfd\x03\x25\xa1\xce\xfc\xf3\x4e\x18\x59\x40\x9b\xe9\x69\x94\ +\x04\x39\x37\xf3\xe1\x00\x18\x9e\xb3\xf1\x84\x13\x94\x54\x77\xea\ +\xbd\xa6\x4e\x98\x45\xdd\x91\xdf\x50\x52\xd1\x91\xb7\xea\xc3\x64\ +\x2a\x0d\xde\xed\xa1\xa4\x02\xcf\xde\x21\x55\x61\x4a\x65\xfa\x6e\ +\x76\x51\xf2\x4b\xc1\xd6\x97\xca\xc2\xc4\x8a\xfe\x6d\x65\x2e\x25\ +\x1f\x5d\x5d\xfd\x4c\x0c\x4c\x2f\xe2\x91\x77\xbf\xf6\x50\xf2\x92\ +\xe7\xd0\xfb\x8f\x16\x82\x55\x14\xfb\xeb\xb4\x44\x4a\x8a\x25\x7d\ +\xd0\xb9\x38\xac\xa6\x4c\x8f\xd9\x27\x29\xdd\xd6\xa9\x39\x71\x7f\ +\x81\x55\x55\x88\x5f\x70\x86\xd2\x4d\x9d\x5d\xd8\xbb\x22\xac\xae\ +\xda\x8b\xcb\xd2\x29\xfd\x49\xfa\xb2\x17\xab\xc1\x26\x1c\x75\x5f\ +\x4a\x48\xf4\x50\xfa\x95\x27\x31\xe1\xa5\xba\x0e\xd8\x4c\x54\x8b\ +\x21\xcb\xbe\xa7\xed\x7d\xbf\x6c\x48\x8b\x28\xd8\x56\xa9\x0e\xa3\ +\x36\x5c\xa4\x4d\x5d\xdc\x30\xaa\x43\x29\x48\xa8\xd8\x65\xc2\x8e\ +\x6c\xda\x4a\xf6\x8e\x09\x5d\x2a\x42\xfa\x9f\x80\x5a\xbd\xa6\xef\ +\xbd\x4c\x1b\xb8\xbc\x77\x7a\xaf\x5a\x01\x90\x6e\x24\xb6\xed\xcb\ +\x33\x3e\x4f\xa7\x45\xa5\x7f\x3e\xe3\xe5\xb6\xb1\x90\x6e\xa7\xe4\ +\x83\x7d\xa7\x6c\x3d\x4b\x0b\x39\xbb\x75\x4a\xdf\x07\x4b\x42\xf2\ +\x46\x91\xc6\xbd\xdf\x5d\x7f\xda\x43\x53\xf3\x9c\x5e\xff\x6e\xef\ +\xc6\x45\x20\xf9\xaa\xd0\x3d\x3d\x5e\x9b\xb5\xe9\xdb\xab\x34\x99\ +\xbc\x6f\x37\xcd\x7a\xad\xc7\x3d\x85\x20\xa9\xc2\x51\xe6\xbe\xae\ +\x43\xa6\x6f\x38\x96\x4b\x83\xcb\x4d\xdc\x30\x7d\x68\xd7\xfb\xcb\ +\x38\x20\x09\x51\xa2\xc1\x93\x83\xa6\xae\x39\x7c\x99\x06\x93\x7d\ +\x64\xed\xd4\xc1\x9d\x1b\x96\x84\xa4\x8d\x98\x3a\xad\xbb\xbf\x32\ +\x66\xf6\xea\x3d\x27\x73\xa8\x9b\x9c\x93\x7b\x56\xcf\x1e\x33\xa0\ +\x47\x9b\xba\xc5\x20\xe9\x26\xa2\x42\xc3\x0e\xf1\x43\xde\xfd\xe8\ +\x3f\x5f\x9f\x71\x51\x38\xd7\x99\xaf\x37\x2d\x78\x6f\x68\x7c\x87\ +\x86\x15\x22\x20\x19\x8c\xa3\x68\xd5\x7b\x5b\x74\x8c\xeb\xfb\xea\ +\x5b\x13\xe7\x2c\xdd\xb8\xeb\x9b\x53\xe9\x2e\xfa\xc5\x95\x7e\xea\ +\x9b\x5d\x1b\x97\xce\x99\xf8\xd6\xab\x7d\xe3\x3a\xb6\xb8\xb7\x6a\ +\x51\x07\x24\x53\x09\x2d\x5e\xb1\xce\x03\xed\x9e\x7a\xe6\xd9\xbe\ +\x7f\x1f\xf0\xea\xf0\x37\xdf\xfa\xd7\x84\x89\x53\x67\xcc\x49\x58\ +\xb4\x64\xe5\x9a\x0d\x5b\xb6\x7f\xf1\xc5\xf6\x2d\x1b\xd6\xac\x5c\ +\xb2\x28\x61\xce\x8c\xa9\x13\x27\xfc\xeb\xad\x37\x87\xbf\x3a\xe0\ +\xef\x7d\x9f\x7d\xe6\xa9\x76\x0f\xd4\xa9\x58\x3c\x14\x92\x24\x49\ +\x92\x24\x49\x92\x64\x39\xff\x0f\x1b\xcb\x93\xc1\xa8\xfa\xf9\xac\ +\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x04\xcf\ \x00\ \x00\x80\x9c\x78\x9c\xed\x9c\xcf\x6b\x24\x45\x14\xc7\x9f\x5e\x12\ @@ -1636,6 +2175,10 @@ \x0a\xc8\xfb\x07\ \x00\x66\ \x00\x6f\x00\x6c\x00\x64\x00\x65\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x10\ +\x0d\x91\xc1\x87\ +\x00\x63\ +\x00\x6f\x00\x6f\x00\x72\x00\x64\x00\x43\x00\x61\x00\x70\x00\x74\x00\x75\x00\x72\x00\x65\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x0a\ \x04\xa1\x18\x1f\ \x00\x63\ @@ -1646,11 +2189,12 @@ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ \x00\x00\x00\x14\x00\x02\x00\x00\x00\x02\x00\x00\x00\x03\ -\x00\x00\x00\x36\x00\x02\x00\x00\x00\x03\x00\x00\x00\x05\ +\x00\x00\x00\x36\x00\x02\x00\x00\x00\x04\x00\x00\x00\x05\ \x00\x00\x00\x46\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x00\x90\x00\x01\x00\x00\x00\x01\x00\x00\x5e\xb0\ +\x00\x00\x00\xb6\x00\x01\x00\x00\x00\x01\x00\x00\x80\x41\ \x00\x00\x00\x76\x00\x00\x00\x00\x00\x01\x00\x00\x56\xe2\ \x00\x00\x00\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x04\x0e\ +\x00\x00\x00\x90\x00\x00\x00\x00\x00\x01\x00\x00\x5e\xb0\ " def qInitResources(): diff --git a/qgisplugin/resources.qrc b/qgisplugin/resources.qrc index d456999..2bf9dd7 100644 --- a/qgisplugin/resources.qrc +++ b/qgisplugin/resources.qrc @@ -1,5 +1,6 @@ + icons/coordCapture.png icons/config.png icons/folder.png icons/cuenca.ico From c849a483ba0a67c3a086d75e65eda0c66e9e5939 Mon Sep 17 00:00:00 2001 From: nicolas998 Date: Mon, 7 May 2018 23:38:01 -0500 Subject: [PATCH 020/142] Se mejora la interfaz grafica de trazadores, se hacen cambios sobre el trazador de corrientes, ahora toma coordenadas al clik, carga de una la corriente trazada --- qgisplugin/HydroSEDPluginUtils.py | 144 ++++++++++--------- qgisplugin/HydroSEDPlugin_dockwidget.py | 12 +- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 131 ++++++++++++++--- 3 files changed, 202 insertions(+), 85 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 729536c..44da58d 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -1,72 +1,86 @@ import os.path -from qgis.core import QgsRasterLayer, QgsMapLayerRegistry +from qgis.core import QgsRasterLayer, QgsMapLayerRegistry, QgsVectorLayer from wmf import wmf class controlHS: - - def __init__(self): - self.DEM = 0 - self.DIR = 0 - self.xll = 0 - self.yll = 0 - self.nodata = 0 + + def __init__(self): + self.DEM = 0 + self.DIR = 0 + self.xll = 0 + self.yll = 0 + self.nodata = 0 - def cargar_mapa_raster (self,pathMapaRaster): - - retornoCargaLayerMapaRaster = False - - pathMapaRaster = pathMapaRaster.strip () - - if (os.path.exists (pathMapaRaster)): - - baseNameMapaRaster = os.path.basename (pathMapaRaster) - layerMapaRaster = QgsRasterLayer (pathMapaRaster, baseNameMapaRaster) - QgsMapLayerRegistry.instance ().addMapLayer (layerMapaRaster) - - retornoCargaLayerMapaRaster = layerMapaRaster.isValid () - - return retornoCargaLayerMapaRaster - - def cargar_mapa_dem_wmf (self,pathMapaDEM, dxp): - - retornoCargaLayerMapaRaster = False - - pathMapaDEM = pathMapaDEM.strip () - - try: - - self.DEM = wmf.read_map_raster (pathMapaDEM, isDEMorDIR = True, dxp = dxp, noDataP = -9999) - retornoCargaLayerMapaRaster = True - - except: - - retornoCargaLayerMapaRaster = False - - return retornoCargaLayerMapaRaster - - - def cargar_mapa_dir_wmf (self,pathMapaDIR, dxp): - retornoCargaLayerMapaRaster = False - pathMapaDIR = pathMapaDIR.strip () - try: - self.DIR = wmf.read_map_raster (pathMapaDIR, isDEMorDIR = True, isDIR = True, dxp = dxp, noDataP = -9999) - retornoCargaLayerMapaRaster = True - except: - self.DIR = 1 - return retornoCargaLayerMapaRaster - - def trazador_corriente(self,x,y, path = None): - self.stream = wmf.Stream(x, y, self.DEM, self.DIR) - if path is not None: - self.stream.Save_Stream2Map(path) - - def trazador_cuenca(self,x,y,name = 'None', TopoNodes = False, LastStream = True): - # Traza la cuenca con y sin la ultima corriente. - if LastStream: - self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR, stream=self.stream, TopoNodes=TopoNodes) - else: - self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR, TopoNodes=TopoNodes) - # Mira si guarda el shp de la cuenca. - + def cargar_mapa_raster (self,pathMapaRaster): + + retornoCargaLayerMapaRaster = False + + pathMapaRaster = pathMapaRaster.strip () + + if (os.path.exists (pathMapaRaster)): + + baseNameMapaRaster = os.path.basename (pathMapaRaster) + baseNameMapaRaster = os.path.splitext(baseNameMapaRaster)[0] + layerMapaRaster = QgsRasterLayer (pathMapaRaster, baseNameMapaRaster) + QgsMapLayerRegistry.instance ().addMapLayer (layerMapaRaster) + + retornoCargaLayerMapaRaster = layerMapaRaster.isValid () + + return retornoCargaLayerMapaRaster + + def cargar_mapa_vector(self, pathMapaVector): + #Inicia vandera de cargado y ruta del vector + retornoCargarMapaVector = False + pathMapaVector = pathMapaVector.strip() + #verifica existencia y dado el caso carga + if os.path.exists(pathMapaVector): + baseNameMapaVector = os.path.basename(pathMapaVector) + baseNameMapaVector = os.path.splitext(baseNameMapaVector)[0] + layerMapaVector = QgsVectorLayer(pathMapaVector, baseNameMapaVector, 'ogr') + QgsMapLayerRegistry.instance().addMapLayer(layerMapaVector) + retornoCargarMapaVector = layerMapaVector.isValid() + return retornoCargarMapaVector + + def cargar_mapa_dem_wmf (self,pathMapaDEM, dxp): + + retornoCargaLayerMapaRaster = False + + pathMapaDEM = pathMapaDEM.strip () + + try: + + self.DEM = wmf.read_map_raster (pathMapaDEM, isDEMorDIR = True, dxp = dxp, noDataP = -9999) + retornoCargaLayerMapaRaster = True + + except: + + retornoCargaLayerMapaRaster = False + + return retornoCargaLayerMapaRaster + + + def cargar_mapa_dir_wmf (self,pathMapaDIR, dxp): + retornoCargaLayerMapaRaster = False + pathMapaDIR = pathMapaDIR.strip () + try: + self.DIR = wmf.read_map_raster (pathMapaDIR, isDEMorDIR = True, isDIR = True, dxp = dxp, noDataP = -9999) + retornoCargaLayerMapaRaster = True + except: + self.DIR = 1 + return retornoCargaLayerMapaRaster + + def trazador_corriente(self,x,y, path = None): + self.stream = wmf.Stream(x, y, self.DEM, self.DIR) + if path is not None: + self.stream.Save_Stream2Map(path) + + def trazador_cuenca(self,x,y,name = 'None', TopoNodes = False, LastStream = True): + # Traza la cuenca con y sin la ultima corriente. + if LastStream: + self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR, stream=self.stream, TopoNodes=TopoNodes) + else: + self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR, TopoNodes=TopoNodes) + # Mira si guarda el shp de la cuenca. + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 714a498..829b545 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -71,14 +71,18 @@ def handleClickCoordCorrientes(self): self.iface.mapCanvas().setMapTool(self.GetCoords) def handleClickEventEjecutarTrazadorCorrientes (self): + #Traza la corriente y = self.spinBoxLatitudTrazadorCorrientes.value () x = self.spinBoxLongitudTrazadorCorrientes.value () - OutPath = self.PathCorriente_out.text () - self.HSutils.trazador_corriente(x,y, OutPath) - + OutPath = self.PathCorriente_out.text() + try: + self.HSutils.trazador_corriente(x,y, OutPath) + self.HSutils.cargar_mapa_vector(OutPath) + self.iface.messageBar().pushInfo(u'Hydro-SED',u'Se ha trazado la corriente de forma exitosa') + except: + pass def handleClickEventEjecutarTrazadorCuencas (self): - print wmf print self.spinBoxLatitudTrazadorCuencas.value () print self.spinBoxLongitudTrazadorCuencas.value () diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 360388e..564d47c 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -6,7 +6,7 @@ 0 0 - 407 + 387 869 @@ -42,7 +42,7 @@ 0 0 - 381 + 361 781 @@ -91,6 +91,12 @@ + + + 150 + 16777215 + + true @@ -174,7 +180,7 @@ 10 21 - 363 + 341 397 @@ -196,6 +202,18 @@ + + + 100 + 20 + + + + + 290 + 16777215 + + true @@ -243,6 +261,12 @@ + + + 100 + 16777215 + + <html><head/><body><p>Carga el MDE en el layout de mapas de Qgis.</p></body></html> @@ -253,6 +277,12 @@ + + + 100 + 16777215 + + <html><head/><body><p>Establece el MDE y sus propiedades como el mapa base para WMF.</p></body></html> @@ -280,6 +310,12 @@ + + + 290 + 16777215 + + true @@ -327,6 +363,12 @@ + + + 100 + 16777215 + + <html><head/><body><p>Carga el DIR en el layout de mapas de Qgis.</p></body></html> @@ -337,6 +379,12 @@ + + + 100 + 16777215 + + <html><head/><body><p>Establece el DIR y sus propiedades como el mapa base para WMF.</p></body></html> @@ -376,6 +424,12 @@ 0 + + + 150 + 16777215 + + 12.699999999999999 @@ -404,7 +458,6 @@ labelDEM labelDIR Tabla_PropMDE - layoutWidget_2 @@ -438,9 +491,9 @@ 0 - 310 + 230 359 - 471 + 481 @@ -450,9 +503,9 @@ 10 - 22 + 20 341 - 428 + 362 @@ -551,6 +604,39 @@ + + + + + + Umbral mínimo para determinar red de drenaje en la cuenca + + + Umbral mínimo para determinar red de drenaje en la cuenca + + + Umbral + + + + + + + 2 + + + 10.000000000000000 + + + 100000.000000000000000 + + + 100.000000000000000 + + + + + @@ -726,7 +812,7 @@ - Ejecutar Trazador + Ejecutar y Visualizar @@ -741,7 +827,7 @@ 10 22 341 - 271 + 188 @@ -797,10 +883,10 @@ - Coordenada en X del punto de inicio. + Coordenada en Y del punto de inicio. - Coordenada en X del punto de inicio. + Coordenada en Y del punto de inicio. Latitud: @@ -827,10 +913,10 @@ - Coordenada en Y del punto de inicio. + Coordenada en X del punto de inicio. - Coordenada en Y del punto de inicio. + Coordenada en X del punto de inicio. Longitud @@ -864,7 +950,7 @@ - true + false @@ -919,7 +1005,7 @@ Ejecutar la función de trazado de corriente. - Ejecutar Trazador + Ejecutar y Visualizar @@ -927,6 +1013,19 @@ + + + + 7 + 220 + 341 + 20 + + + + Qt::Horizontal + + From d9d794b2bbdb9bf372e8a86a4b6e9ea7484cc26a Mon Sep 17 00:00:00 2001 From: nicolas998 Date: Mon, 7 May 2018 23:48:14 -0500 Subject: [PATCH 021/142] el trazador de corrientes carga siempre corrientes con un grosor de 0.5 y azules obscuras --- qgisplugin/HydroSEDPluginUtils.py | 9 ++++++++- qgisplugin/HydroSEDPlugin_dockwidget.py | 6 +++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 44da58d..bbd1a7d 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -1,6 +1,7 @@ import os.path from qgis.core import QgsRasterLayer, QgsMapLayerRegistry, QgsVectorLayer +from PyQt4 import QtGui, uic from wmf import wmf @@ -40,8 +41,14 @@ def cargar_mapa_vector(self, pathMapaVector): baseNameMapaVector = os.path.splitext(baseNameMapaVector)[0] layerMapaVector = QgsVectorLayer(pathMapaVector, baseNameMapaVector, 'ogr') QgsMapLayerRegistry.instance().addMapLayer(layerMapaVector) + + symbols = layerMapaVector.rendererV2().symbols() + symbol = symbols[0] + symbol.setColor(QtGui.QColor.fromRgb(50,50,250)) + symbol.setWidth(0.5) + retornoCargarMapaVector = layerMapaVector.isValid() - return retornoCargarMapaVector + return retornoCargarMapaVector, layerMapaVector def cargar_mapa_dem_wmf (self,pathMapaDEM, dxp): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 829b545..69b1d43 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -77,7 +77,11 @@ def handleClickEventEjecutarTrazadorCorrientes (self): OutPath = self.PathCorriente_out.text() try: self.HSutils.trazador_corriente(x,y, OutPath) - self.HSutils.cargar_mapa_vector(OutPath) + ret, layer = self.HSutils.cargar_mapa_vector(OutPath) + + self.iface.mapCanvas().refresh() + self.iface.legendInterface().refreshLayerSymbology(layer) + self.iface.messageBar().pushInfo(u'Hydro-SED',u'Se ha trazado la corriente de forma exitosa') except: pass From 4264fa523185aeab4cd96038e345ea6a5efa88de Mon Sep 17 00:00:00 2001 From: nicolas998 Date: Tue, 8 May 2018 00:13:37 -0500 Subject: [PATCH 022/142] se cambia la forma de la ui para los trazadores, se elimina tanto texto, se incluye boton de play para ejecutar y visualizar --- qgisplugin/HydroSEDPlugin_dockwidget.py | 27 +++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 130 +++++++++---------- qgisplugin/icons/play.png | Bin 0 -> 13660 bytes qgisplugin/resources.qrc | 1 + 4 files changed, 84 insertions(+), 74 deletions(-) create mode 100644 qgisplugin/icons/play.png diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 69b1d43..3260bf0 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -58,8 +58,10 @@ def __init__(self, iface = None, parent=None): if not (iface is None): self.iface = iface self.HSutils = HSutils.controlHS() - self.GetCoords = HSCoord.PointTool(self.iface.mapCanvas(), self.spinBoxLatitudTrazadorCorrientes, + self.GetCoordsCorriente = HSCoord.PointTool(self.iface.mapCanvas(), self.spinBoxLatitudTrazadorCorrientes, self.spinBoxLongitudTrazadorCorrientes) + self.GetCoordsCuenca = HSCoord.PointTool(self.iface.mapCanvas(), self.spinBoxLatitudTrazadorCuencas, + self.spinBoxLongitudTrazadorCuencas) #self.iface.mapCanvas().setMapTool(GetCoords) def closeEvent(self, event): @@ -68,7 +70,11 @@ def closeEvent(self, event): event.accept() def handleClickCoordCorrientes(self): - self.iface.mapCanvas().setMapTool(self.GetCoords) + self.iface.mapCanvas().setMapTool(self.GetCoordsCorriente) + + def handleClickCoordCuencas(self): + self.iface.mapCanvas().setMapTool(self.GetCoordsCuenca) + def handleClickEventEjecutarTrazadorCorrientes (self): #Traza la corriente @@ -87,6 +93,22 @@ def handleClickEventEjecutarTrazadorCorrientes (self): pass def handleClickEventEjecutarTrazadorCuencas (self): + #Obtiene coordenadas + #y = self.spinBoxLatitudTrazadorCuencas.value () + #x = self.spinBoxLongitudTrazadorCuencas.value () + + #OutPathDivisoria = self.PathOutputDivisoria.text() + #try: + #self.HSutils.trazador_corriente(x,y, OutPath) + #ret, layer = self.HSutils.cargar_mapa_vector(OutPath) + + #self.iface.mapCanvas().refresh() + #self.iface.legendInterface().refreshLayerSymbology(layer) + + #self.iface.messageBar().pushInfo(u'Hydro-SED',u'Se ha trazado la corriente de forma exitosa') + #except: + #pass + print wmf print self.spinBoxLatitudTrazadorCuencas.value () print self.spinBoxLongitudTrazadorCuencas.value () @@ -226,6 +248,7 @@ def clickEventSelectorOutputCuencaNCTrazadorCuencas (): self.botonEjecutarTrazadorCorrientes.clicked.connect (self.handleClickEventEjecutarTrazadorCorrientes) self.BotonCoord_corriente.clicked.connect(self.handleClickCoordCorrientes) + self.BotonCoord_cuenca.clicked.connect(self.handleClickCoordCuencas) #self.botonOutputCuencaShapefileTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaShapefileTrazadorCuencas) #self.botonOutputCuencaNCTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaNCTrazadorCuencas) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 564d47c..c0696c3 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -6,7 +6,7 @@ 0 0 - 387 + 389 869 @@ -491,9 +491,9 @@ 0 - 230 + 170 359 - 481 + 331 @@ -505,7 +505,7 @@ 10 20 341 - 362 + 271 @@ -560,7 +560,7 @@ - + 6 @@ -590,7 +590,7 @@ - + 6 @@ -622,7 +622,7 @@ - 2 + 0 10.000000000000000 @@ -635,23 +635,6 @@ - - - - - - - - Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca - - - Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca - - - Usar ultima corriente - - - @@ -665,6 +648,19 @@ + + + + Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca + + + Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca + + + Ultima corriente + + + @@ -681,6 +677,17 @@ + + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + @@ -714,7 +721,11 @@ - ... + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -751,7 +762,11 @@ - ... + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -788,31 +803,11 @@ - ... - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - + - - - - - - Ejecutar y Visualizar + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -827,7 +822,7 @@ 10 22 341 - 188 + 141 @@ -975,26 +970,13 @@ Seleccionar la ruta donde se va a guardar la corriente. - ... - - - - - - - - - - - Qt::Horizontal + - - - 40 - 20 - + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - + @@ -1005,7 +987,11 @@ Ejecutar la función de trazado de corriente. - Ejecutar y Visualizar + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1016,8 +1002,8 @@ - 7 - 220 + 10 + 160 341 20 diff --git a/qgisplugin/icons/play.png b/qgisplugin/icons/play.png new file mode 100644 index 0000000000000000000000000000000000000000..4b740abb4584ff8a370638b405ee7831ef8866d4 GIT binary patch literal 13660 zcmeHuX;hO*^Y4=dk|2_R$f95ft0=NXF(`yZK@fydTtE?mKzw~giQtAHBobg0gs>2z0D{i?dU zy1M$Aqu&LsnyEEM3&XIP{(dXhVVI^T`bQ=}kHMqV6Yw8g;<{Dd*wqIngYbj6-D`~( zhF#B_@ij^V!wA@Sf$M#s|Nq?|6T`R|CdM!shN&_5#bjbkF2)pNOc};hqd_hc<8m>s z7~{$?t{TybnV6W1iN%;$hKbc^s*H)rxR^|g$z+&J4V*AF6H{|BwHQ;&Fg5%D-oP4o z!DOITBRS}g%Vdg~Oc|4@Mq=R?m&@denOqr@t41hbP|RhD#Z0k`DOMv;Kr7=iWn!jG z#+0c6BTQwgxlFZ~sg^O-AQeypGXM=J0TzsbVBig`ffr0xBZbg!_!D!vGA>t*^aHW* zODyJ!Wn8fusS7AzP$uTeWL%jVvVZ7~Cd>wNfc^jiGz8SZ3_t@) zAO##C7E%Z#rdJfL=ky{WP}6ot%R6mKgmKzBXtk#mMv$jo=l^a&3ETl|aQ)}=wak#TSp4h*1Y1n2Wk#F$N&ws4(k2CzU7yhq@ zg7MK0ePh??k?K2nk&*6cV)a7FN@7g3LwS8#vf4wvw>EifG-)agYhP(7_#`YNEc zd}~j`_+osZx2KEp&-=T~M+3?|`qK!G&ba4IPdj%shrCQXSgf{{TqefsyY`&$9e3jcT*dtEcv};>7lY$R)nXw4xjXx$#KM2pB$k2 zOMbDxHfDp@_VIi&`u>l!y3b4s&eziH%E7{}JNgvdJqxpi2luyZium@u5WAo&YWcSF zXy=)<*1i=}1Z)LO^h5oF`bdEgv(Ob~{Pb~hlpj2PoT zoTzx(XG=6X!ngZZUs}Uw2MSKp%&bH8I6ixGfe^brOY}oZn7WIeHp*6S<)0x-y~_r! z#`}5mw^F3e5q+2A1HAdB6sdVb|M~bJZ~jZNRB!*g);slWuW+1bd^O*ctsdR3had9x zygFf(mEw`7I*rBod0rjg_2$~EZ}xzqpQ!lv&D!4O$saf3UnK0i`pff92h|UAA8| z!=z=@a-}X79^kn-A$PliUd_)S`?X&7xc6;`TLzX*6Xm`reI52PfXs8p?I`K1DEWH# z+m#eMY%BiJNXbICB^2CMOS74-jWvZd`2zg92{+Qg)SHoG4BYP&zn5Q1Us;G~XV-ZC z$yLv(yi-6s>+jj#)2E!5Da01x*NrbbFyXnoyf2z?a2d|_^y>rXHu;mkvo?!$tzBio z@XY70KitviK97Q1O}zN$&Ij*xx3c@wiIYokKOQQKP7c(=yNUVhU-tbz?}QKwwlv#N zTSMBPbcQ-xzMXh+!KU%wEQts4INL+wxyd{|{MQ1$zNsp^YRcQ2A4wCPCrp_Y(rZ(s zt=c2*_;q_PmiJ8s0F{uh|59W$gdGEzGZL!6lh7DoQJbr z_T-vH$^r^*%HQ*tz3Y$LEf|tl6u-3}1}XKO3$c;qINSCm?p81!=y@z5Ab7PmU#%xP zAO5JTfF}1KUYvj6Kj|)0~v09d!Oa*hQ173&??}xRMmX{cHLr08`*E| zRqM3ZKmzy@n5r4U44yB3T~T)1tGW|3mMOriSI{kq4}4*Gkt+A5!f5us!h8NlMs z-U&AcW8QZl?VWU%AKBzIkh&->_3*2#filPKVRJ^+dB*dNH?nOm_B}$1rTH|2CmsKYVgRM!LtNG0e)TYpVo;a z9}!rQ3q^1N);HYisu_c)4a0M#8^Fo>h}H-IKiuD&lM20GS|3{yxybCPcJlG)i1nP+ z(EFm*+`i14vkjUZt=_1)8Jf3Sw*jpc&>pgTt6b(_?>HN*aX)&k9-fKT)y=?~;YdeT zjozb&uR+#ZzLBRA85)-y0iaK=Yf%JZ(AeH|XFjbY6S`#A%M6o#6f}a(a!qy?(5C6` zUbm+RC_txUva^t8R0ec)*Bd61+5}#RZtfNl%?Mfk=j$^m5VV1A?v|uN!+A!z&{=ui zl=2tdoGk@3Bk=aVi`N%X1UN)DXG^kdE~dQ#4Ef+$nNY$3OSR^>yUp2Tbo97gyKOW* z@0F5`eVHXXZ{j?jV8L+I0&R?=J@oMDU`rFHaZ83H5xOYRkxPe_sn{3L(Zq3le4{rf z9tARzla$Mr|*P z>y}GSLa$Bsb?Ehk-YTQxLI}YZ=MNkk?RM`>CdMJml}7nO$tCEmIOgQ;M~*`daoOmE zP{KtlkL__!X;0Ru41nH?M$hYo5(C8Z*!3hW!AxXL{R`kbS3tK?n|lY;3x9o z+cfp?S77-{t^3UwRp!tYwawtB9)2h2R%+G1N4;d&w8{>;*KV^$-C&4P%YJhPL|WT+ zuWc?jJC!>407PujZ^5W?gkGm@zBlP(_V@rqYu>+iR3G1gEM?B!2hC|(M!yxKiUzd0 z+qimo2(af%&H5p1P0V_WtZ&A(Vepo~uqrB555EcEnb33PO2+Vl-xy$CcawCXWHzXm zmDMbwy+zJvs-y7f*>VRbNH)RqEX$KMM@m>g`(}Ynh7DW(=2n}_HorYN> z7O=+enkWag1m&pLAgK3Ysw6lR02u_m9^KM&P)-L{2Qs>D<HqQ>=LdY)c^jrHa0?narfT6mc%I(5!bL76u}+Pty?c>@O?)PZUp&QK$E{e`D-!w zbuMpnxfKz?_hC6v1Ss z>owKF6noOwelKs96NrAv7ttOd_gNyRQp=r9c+N2EG%hW{fl-P!(l$xtL9N~#&}RZa zbuWZGfZ~wB2zBC`vn3oY>x#DEUNIP@C@8Iy9PlS^hohr*)(GKdBy$1pAdD}>dF%yV zaJcmON`irx3Ggz+r>^#95kUT7ek9~t`GRJ&o}@`DO7B}3zlkgJ^k%uhcr4#0pO%Zx z5<~e>dpdI&j|EJxV8PZ5lM}$x+EXCp1wvOgW>x&u*o=kz%bjmd={*R1o?`8mLP*KZ zcjNyhqUHJk8_L-}B_o|kLcyExn|hTG*{?o3p3lB z3wmPeIFKC_Wn{(rlV^dJmCNnkJ6ULUf&1Gnx9bcc7XrS@WtF`Ty`5)`Z7%Z3+SeWG z-ygL(ySl&1Aea%@Txk&77UjP5mGdq~WRhder*`+m_Hbf=t47woB&{g4(w{PassE(k zgsj&w^IaiL6XJW=u4hdzip9%~@&V`dsJVJg5`=T+7L^?%2R26a?^ULhD0E<*$Xw)4 zUIFOr7RS9CD-JZvf#6g9pz4?9l&Hlp9-I08rF*A-lM&3nqMa`Zr6mR%;8I*jwIxPk`xtWQ|vvlrj4$Sj9oF{`7{^U2w@u_ZdRcsINwxaDVzz5_e9@!pQlklNG8AVMyo19?pP%)rc5~Zov^dAtBO-a0! zB2_dgktHcLBHBjS5n-!Kz86l1R^O)e5izMz{=nt1u+5L$0bJrN0#|v5!toVr80D?k zR1GsvlS2-byJlK}O5-$ZD~27!_38}AMU*I8m}x3J>QC+f2Z=Kae7~mO_$tJ;=N=`c zLdZmI+s7L}S_*f97W=6>a;K1)2=V>&6(ZU+*>cwRtCsRznnQ|yN{2Z4YfjMG{W>~| z{w??BLM}OfE-5Qv%$}g5fdHnbkLr7$0bDQSJhzPRz;&N5VV%9H=Y16Vy5u5DAvz1o z8om6AXvar-KQ>9^%0A1s9^ z-5fF~{6j{BpP~uI?{DeL`#J;usVciuGcgHs<~(d`FNvr zvz^`8=9bc~B|#ze1+gMgy&wQX=CER&OAcmy%>Yq_@*=m45#&bhM+ysQQxMLoeR!Mo zn$iH&esa*zM(@evK$kB6{lgtDgM~b5O49anH5tF|#Ct*4?ZYR3kpB$)Zxj5aXrH@~ zCYMrNmjYQ2cBl4R$z!O^BAyI5P@R{?(4A%Q8Rc`rRK;^y#yXGYQf50A2!HB+qP0;WU*cX2ReVi z%2s>pAQR|Gy6W3L^Bkcw16yFJ5CNNa*zbN)loy@ET`mwcqsW8*ZlYw#Ycm+k#`gM2 z&jG3@*xRJNdvlwU!-}l1U+3M4JzavlM1$Wjm*T1kxbP4rMR2t}pX0$ZrMP0yH9~lL z=!^Z9mP%lBff^p{Z4Dk{oWh~#IU{>NBXo#FM?rArywLW6;^+2U*fz#V99KPOv`Zy~ zfC7;%4Bs;iee$w+$Y>0hYcH=_Oc6td7yG-Q&tDn?oYQqGdp{((95)7(_e?^wgn_V$ zofVSJ^DJWwKv7-N6AMNmn#-!XlokA(PaGolex$0{3&F=WfJDT2fPQVeD{&lq~IT(+ex0@@d53j#XQVcg>3EKQFU!tnL_#v)c(SnPcO4BRDK< zBiw9^gE+iYmnWY=MhzwBLGjpCI76LJNk;Tzb^(Sq;=KXp;4~|1M?vxPElHd1Nyn?vmRgA)8~G+&2%fKP>6rJW(qRTt!O}6G`aJR^L_qN>j`d$H zV`#ycV;#U$ zX6|TwXUo5n0BabL`$jir546@ot3qjy^gkxq+Y_4|b_}NL2?p!h3~KZNpCx|m@0J;U zEa~JDE(2zH5&IL1|Ep0ER=zfrE!##OPSML@Oy6CQfUt zC2)-`3_}h|{-0a!oeOHv&ZprMKbLIa;y@;Y*#FV|iVTm|ge)6$`tQxQr=#|MptDd? z`gL)o26A0m$@-0A4UokB-*5eXbIAEAGOd}T?W%a!hz`{HvC?@4xW@lM%f=&ckJsOD zUH=D0hoa5s0|2rxa46y3G!fL}(S+KaV*H z<6>{l>V{(n(7A6*yrjskIthM{I?Mki&5#sTOYISUTVmf!`8@ysL{zGgl& zS$JmKR5iLjvhcH#&U}kSj+sR4?@cCeLJ`rAGw)S(gB>LG&LYWTHa9s8VKoDh9d`jfYmwTr4g6Y9cT-NP-GJ7o=CU}#M%ic z-Q4&vNathi1*2O{ZtY7tob6m9ne2((6^0TTM?vr5wkOpFz%~YdVQl%ujp&40!-+He z7FrJDEWx?0DO1q|kT6K}?f>H8g5q>Ahf`j24c)Mv%O$sZVz!2%bkI`}<=%0l8l~ex zeEP2wGvbyajB7c8Q>uTj01gZd-@U4$HL)mFa?;RLj7D#Pma9f);_&Itr4Y@<>p6~w zck1?|yeLfLp3;0_dnPE-X-_f@@?^_l|7UgT)8!34l zgEHT98op+9lr-los`4mb_6h;x3F_NgKL8^*HUiiv;Wm!o1P|AUhEN!5kfgdD)<#Y! zkwicXofb_Jwj$aL*fBK6&FCwTTR2s@d+a%Y5(h8M8`gA`CgeC*Em9ew?NK6F)Ygh} zi8tDD11p~7HNuK%&Uq&FVP~T7xq~xH>EsM{Sx=ZN%DWCby?;*V%f5Y2a#1D6dTyvV zB?ldaFC_m_L~DYGLCuYp^hD&>ORG+Gv{uedNAAk1(o>b7wY(?TAZ-mqORZBW9}hD) zZi{wE7S}YiC`E>%%zMcZMRXAGP9hm3ep&La1*HzNsCFya z{RmOv=J9DGI|wDvrjlT3t1CzxCrqBZIb3aT zf=?@k>w#Dz8~$9jtYWtGe_df*bmkK ztEK#uQYhrbCdxl5&{h9~q^-Wwm&XO^?*$=+)G1`+H2GacIx1thkb?r)lPD9`Y4op` zT0<2hHd|h#NcRAv59yYQQbtg1ZOxG`mB^H@MzHltb1JB)4qd&5x1fyu_jMsDT#-Hu zb1L;qGg3y-Ui{%m;;p&|ie?WG^F-@`Cwmg5oZA{l+emlNjdT%fnMz&^hVIa4-LEP+ znng#`4Nb%;BdErzk^ZKDS_Xbqy^XhC*;oi%PHN{4j)z&BrXoGLyp>8X6ks084=U18 zG3`H%52d77m>QcNUHk16B@30AD(9LUP5BL7n^~;fWYt-8<4fS_-@NAh0^PjAma#IS z7q&+AejZWTxB>8Flg0|E@W|j3=3a6pWx6(|Z0!Ev5qtg|qDytGA*nbN1W}lj^qGS) zh1tR|XgNX4O6cnD)@j-N2^j4pGYhB&NXp8R&NC^~rM(4BafOIAIlU5jPp)I( zZ3l5=C`xk}QS+3I=*GAZF1ggdFS*SF#p3W#w5W@sG?k5i-G|>4Qa7S2_Zp*@FAj*q zLZKEE>lziOY}AC=?4-q~8a(fm`_Au|vy@6P7H0rppft!5k>ilV9OzNmO*BZ`e3Grk-u7YI=X{lswGlCBMB zd9|d9uHw*;2{Y^Kr1P5)VSx4*5mgh3h<=uy;)wDy^X74O3^@uBZpi!zY>hJi*vwtf z@`TpD%$Zvi=?viPGRMV&K3!$$s><(pmorZrt@z_AifX!YQ=d6gN{R-}<6J6(*hc7n zbu%iqIM3MC2;DkvM{Q6xY6FBXGZz+6`@v10^Fr_Ug=Nk}g`MYnLfd|-pk4yIK2Hd3 zfu=PIIEkTx6h}h!^7dSp&v4C8$V`_dH!e&4p7YfpB*4K^G|tVAkS)driN_(gSd&C_qj>W9WH`Q+TMn zv<34y5b5mAGlKR`%u3ma0^|pre#%KI3VI2;@;0cbk4R7~-Hmt4PvM0FB~$^;=_atU zefE-BbtkAgup1MM<;9Bh3xK&>b28)Ru(LBS6iDA;9#-^H$j|%OlHhJBY5K*7HnIYW zYIZyx5X{AS$OqF=j0~qt+6U81VMF%?Ne;OEVH4CMF@)l#NB1-9pnFoozKtkE%2Tut zuf3}AwdJ&oG))^JDR<*8lZS&<4GB}gs|KQBw>DWd{g}0hkZM6MMNoH3?$md#m$-t0 z_9OrTcC0lmElYu;qwf$eK?!N}$uEsR)=L*lrc1SC8*BRXtJ=)opB02D^d{iLvQ$AuhOGVtQO7Huy<-^cBAWY1sPNMppS8pJ^VSgZ`!ESQ3EzL@i zP{EYBTH6`)=@41d879@(t}c?+yJ)xC{V7-yih^-O;978NKFVq%OFN2jz=jOI_kro3W9i3I?bQB|9T}@iQU8%e233Z#kw>*6%4qX&$ znw_Mia8#W=$U5>RIBAmr={6XZN>$>X0typ4cVLik73t_9yWd4Z*?I!M}xo-VMzUBAm2>fh3{h=VS-vs!LJFEYfsoYia&6S|l! zCG+|SHxT>vId31bnoq`suML|0CP}u1h)S98RCNDzo!9ik(7>_l2S4*okwpzGMnB?i zgI|~0-DA+JW`RNvw}Cxxqg7jU&x~GW0bRY@h{I!-uxUE`aT|ISN{>dj#RDBu++qBa zc|2*F5*Hn;#G%qpspGf>-H{A*y3r1Fr7!wI;e4snc<&$qMNHS2p~fzfHY&NdKkN2k z!^ae`x9{Ck5a4?WpW5wlf5K~`ha)Q2`$Vr$;!q~ky%<8K;{xc~5N)Bvp){y_iOU{U zNwFzPJ^QM!<5YZ^C$--a3=qS7C zW^Dwf({H%ZR!SV&;@z$r_k3C6z;r~9Ge1OYC~=8kjqYUz2OQ{*#?bdmbkxmjN<5(p z5id8`2i*+lZi)5+QiRIQ0C=KO%;RXrM7gpF--Q^s8-Vg$Sl-$cJ2_|{hyv1=TYrH6 zU6fn|girGpCVl3sP;jGff^}I1>kjX-UTit487&pvSgzuuSI2O#Qwl;Za#PZd+Ajsg zx-4|jwz>#}p+I<3RNbk>k&qoT^$(|t4QbO^sQbm0Z29*vZkUf(@uv;CvMi7-zYJZQ z@@=3z=U_7Zd~#b_C?!n?PG==iiEBlOkAHo1JVnw7(5_nC;f*bFFq#gWU!=i+n29j? zr8aeuO5xfE@82u(xLQF?)rNhmm4v0%T0zaf8ukS#x0bQxfp#ft?X6yomOLf1(A(Be z3c7;u_iOv{Gk~HprgKp$C=0Ke^Q#Cb{#+&~kJZ7E(Pu+Y`Kk*RcQVg92;11jWEjAAe>m_F-rt zA13}PC5@nmiI79E(NXQVucWNAZ(jtC4=LzFtBH>>3c@6y{`J0(`)n1~04wkzF(h~; zn?DRe$O_#VRgz$Z(4`q&=AS8&4m&RBO16_yGoUc|tSGJXmiHfBDNiCd|| z<6-P=e3XqA*Ipyp&?OEOzYX?7=h{dkMEtsaU*mm>sd9h##3S*+&|2t(66C(2Yj5hm zoubY{?~#9Q2zsyEM*7YSJ`B0hYC-or$}ckgSo2ni)2H}7XQa(}0$-%;#e%KOVmlKO zsen@x_hZLncWo7Xz;^LN=$)dGsSvgue-7@)0V!1b8}~nKik?x{S?VNbzgF-7P=*GU+pR)ym9t!nL^uZZ8t3>b!~887*}?j6RMz zS^CENjW!&wa{sGOPjN1v{h4m{$q-CNkm_Go-dm} zlPukk`IReL6~CZL<7WS|H;1jB9KWgmEOTe#nTM&D&sR`6%n$cZH1sD>d)G{@!{*XN zJL}s9#?I$Q(^lp%>tfJF$W!#k($pk_;%bk!z8f6 zc6@c|qO`@=Qc&>JI4s>4`7-M(35TdZ|J+vb$o(+-fGqYW^-)?d9epJh<&ZG&bPvol z!dL%XJmEUtQAp)j;;ZXU%=3l=et-a}?8cGZ8J$8Y$#D)YtmR6^9fz%K{wP_xI%43X zgBP2xOOgKjdiUw-vD#ZgXI7K literal 0 HcmV?d00001 diff --git a/qgisplugin/resources.qrc b/qgisplugin/resources.qrc index 2bf9dd7..c896ce2 100644 --- a/qgisplugin/resources.qrc +++ b/qgisplugin/resources.qrc @@ -1,5 +1,6 @@ + icons/play.png icons/coordCapture.png icons/config.png icons/folder.png From 0586292df98d8dff77c8e268e8d343d9a3f233c1 Mon Sep 17 00:00:00 2001 From: camilo2046 Date: Tue, 8 May 2018 10:22:05 -0500 Subject: [PATCH 023/142] Se agrega filtro para mapas raster via GdalTools_utils --- qgisplugin/GdalTools_utils.py | 905 ++++++++++++++++++++++++ qgisplugin/HydroSEDPlugin_dockwidget.py | 8 +- 2 files changed, 912 insertions(+), 1 deletion(-) create mode 100755 qgisplugin/GdalTools_utils.py diff --git a/qgisplugin/GdalTools_utils.py b/qgisplugin/GdalTools_utils.py new file mode 100755 index 0000000..268c9b2 --- /dev/null +++ b/qgisplugin/GdalTools_utils.py @@ -0,0 +1,905 @@ +# -*- coding: utf-8 -*- + +""" +*************************************************************************** + GdalTools_utils.py + --------------------- + Date : June 2010 + Copyright : (C) 2010 by Giuseppe Sucameli + Email : brush dot tyler at gmail dot com +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +*************************************************************************** +""" + +__author__ = 'Giuseppe Sucameli' +__date__ = 'June 2010' +__copyright__ = '(C) 2010, Giuseppe Sucameli' +# This will get replaced with a git SHA1 when you do a git archive +__revision__ = '$Format:%H$' + +# Utility functions +# ------------------------------------------------- +# getLastUsedDir() +# setLastUsedDir( QString *file_or_dir path ) +# ------------------------------------------------- + +#import os + +from PyQt4.QtCore import QObject, QSettings +from PyQt4.QtGui import QFileDialog +import platform +import gdal +from qgis.core import QgsProviderRegistry + +#from PyQt4.QtCore import * +#from PyQt4.QtGui import * +#from osgeo import gdal, ogr, osr +#from osgeo.gdalconst import * +#from qgis.core import * +#from qgis.gui import * +# to know the os +#import platform +#import sys +#import string +#import re + + +# Escapes arguments and return them joined in a string +def escapeAndJoin(strList): + joined = '' + for s in strList: + if s.find(" ") is not -1: + escaped = '"' + s.replace('\\', '\\\\').replace('"', '\\"') + '"' + else: + escaped = s + joined += escaped + " " + return joined.strip() + + +# Retrieves last used dir from persistent settings +def getLastUsedDir(): + settings = QSettings() + lastProjectDir = settings.value("/UI/lastProjectDir", u".", type=unicode) + return settings.value("/GdalTools/lastUsedDir", lastProjectDir, type=unicode) + + +# Stores last used dir in persistent settings +def setLastUsedDir(filePath): + settings = QSettings() + fileInfo = QFileInfo(filePath) + if fileInfo.isDir(): + dirPath = fileInfo.filePath() + else: + dirPath = fileInfo.path() + settings.setValue("/GdalTools/lastUsedDir", dirPath) + + +# Retrieves GDAL binaries location +def getGdalBinPath(): + settings = QSettings() + return settings.value("/GdalTools/gdalPath", u"", type=unicode) + + +# Stores GDAL binaries location +def setGdalBinPath(path): + settings = QSettings() + settings.setValue("/GdalTools/gdalPath", path) + + +# Retrieves GDAL python modules location +def getGdalPymodPath(): + settings = QSettings() + return settings.value("/GdalTools/gdalPymodPath", u"", type=unicode) + + +# Stores GDAL python modules location +def setGdalPymodPath(path): + settings = QSettings() + settings.setValue("/GdalTools/gdalPymodPath", path) + + +# Retrieves GDAL help files location +def getHelpPath(): + settings = QSettings() + return settings.value("/GdalTools/helpPath", u"", type=unicode) + + +# Stores GDAL help files location +def setHelpPath(path): + settings = QSettings() + settings.setValue("/GdalTools/helpPath", path) + + +# Retrieves last used encoding from persistent settings +def getLastUsedEncoding(): + settings = QSettings() + return settings.value("/UI/encoding", u"System", type=unicode) + + +# Stores last used encoding in persistent settings +def setLastUsedEncoding(encoding): + settings = QSettings() + settings.setValue("/UI/encoding", encoding) + + +def getRasterExtensions(): + formats = FileFilter.allRastersFilter().split(";;") + extensions = [] + for f in formats: + if string.find(f, "*.bt") is not -1 or string.find(f, "*.mpr") is not -1: # Binary Terrain or ILWIS + continue + extensions.extend(FileFilter.getFilterExtensions(f)) + return extensions + + +def getVectorExtensions(): + formats = FileFilter.allVectorsFilter().split(";;") + extensions = [] + for f in formats: + extensions.extend(FileFilter.getFilterExtensions(f)) + return extensions + + +class LayerRegistry(QObject): + _instance = None + _iface = None + + @staticmethod + def instance(): + if LayerRegistry._instance == None: + LayerRegistry._instance = LayerRegistry() + return LayerRegistry._instance + + @staticmethod + def setIface(iface): + LayerRegistry._iface = iface + + layers = [] + + def __init__(self): + QObject.__init__(self) + if LayerRegistry._instance != None: + return + + LayerRegistry.layers = self.getAllLayers() + LayerRegistry._instance = self + self.connect(QgsMapLayerRegistry.instance(), SIGNAL("removeAll()"), self.removeAllLayers) + self.connect(QgsMapLayerRegistry.instance(), SIGNAL("layerWasAdded(QgsMapLayer *)"), self.layerAdded) + self.connect(QgsMapLayerRegistry.instance(), SIGNAL("layerWillBeRemoved(QString)"), self.removeLayer) + + def getAllLayers(self): + if LayerRegistry._iface and hasattr(LayerRegistry._iface, 'legendInterface'): + return LayerRegistry._iface.legendInterface().layers() + return QgsMapLayerRegistry.instance().mapLayers().values() + + def layerAdded(self, layer): + LayerRegistry.layers.append(layer) + self.emit(SIGNAL("layersChanged")) + + def removeLayer(self, layerId): + LayerRegistry.layers = filter(lambda x: x.id() != layerId, LayerRegistry.layers) + self.emit(SIGNAL("layersChanged")) + + def removeAllLayers(self): + LayerRegistry.layers = [] + self.emit(SIGNAL("layersChanged")) + + @classmethod + def isRaster(self, layer): + # only gdal raster layers + if layer.type() != layer.RasterLayer: + return False + if layer.providerType() != 'gdal': + return False + return True + + def getRasterLayers(self): + return filter(self.isRaster, LayerRegistry.layers) + + @classmethod + def isVector(self, layer): + if layer.type() != layer.VectorLayer: + return False + if layer.providerType() != 'ogr': + return False + return True + + def getVectorLayers(self): + return filter(self.isVector, LayerRegistry.layers) + + +def getRasterFiles(path, recursive=False): + rasters = [] + if not QFileInfo(path).exists(): + return rasters + + # TODO remove *.aux.xml + _filter = getRasterExtensions() + workDir = QDir(path) + workDir.setFilter(QDir.Files | QDir.NoSymLinks | QDir.NoDotAndDotDot) + workDir.setNameFilters(_filter) + files = workDir.entryList() + for f in files: + rasters.append(path + "/" + f) + + if recursive: + for myRoot, myDirs, myFiles in os.walk(unicode(path)): + for dir in myDirs: + workDir = QDir(myRoot + "/" + dir) + workDir.setFilter(QDir.Files | QDir.NoSymLinks | QDir.NoDotAndDotDot) + workDir.setNameFilters(_filter) + workFiles = workDir.entryList() + for f in workFiles: + rasters.append(myRoot + "/" + dir + "/" + f) + + return rasters + + +def fillRasterOutputFormat(aFilter=None, filename=None): + shortName = '' + + if aFilter != None: + supportedRasters = GdalConfig.getSupportedRasters() + filterName = re.sub('^.*\] ', '', FileFilter.getFilterName(aFilter[0])) + if supportedRasters.has_key(filterName): + return supportedRasters[filterName]["SHORTNAME"] + + shortName = GdalConfig.SupportedRasters.long2ShortName(filterName) + + if shortName == '' and filename != None: + shortName = GdalConfig.SupportedRasters.filename2ShortName(filename) + + if shortName == '': + shortName = "GTiff" + + return shortName + + +def fillVectorOutputFormat(aFilter=None, filename=None): + shortName = '' + + if aFilter != None: + supportedVectors = GdalConfig.getSupportedVectors() + filterName = re.sub('^.*\] ', '', FileFilter.getFilterName(aFilter[0])) + if supportedVectors.has_key(filterName): + return supportedVectors[filterName]["SHORTNAME"] + + pass # shortName = GdalConfig.SupportedVectors.long2ShortName(filterName) + + if shortName == '' and filename != None: + pass # shortName = GdalConfig.SupportedVectors.filename2ShortName(filename) + + if shortName == '': + shortName = "ESRI Shapefile" + + return shortName + + +class UnsupportedOGRFormat(Exception): + def __init__(self): + msg = QCoreApplication.translate("GdalTools", "The selected file is not a supported OGR format") + Exception.__init__(self, msg) + + +def getVectorFields(vectorFile): + hds = ogr.Open(unicode(vectorFile).encode('utf8')) + if hds == None: + raise UnsupportedOGRFormat() + + fields = [] + names = [] + + layer = hds.GetLayer(0) + defn = layer.GetLayerDefn() + + for i in range(defn.GetFieldCount()): + fieldDefn = defn.GetFieldDefn(i) + fieldType = fieldDefn.GetType() + if fieldType == 0 or fieldType == 2: + fields.append(fieldDefn) + names.append(fieldDefn.GetName()) + + return (fields, names) + + +# get raster SRS if possible +def getRasterSRS(parent, fileName): + ds = gdal.Open(fileName) + if ds is None: + return '' + + proj = ds.GetProjectionRef() + if proj is None: + return '' + + sr = osr.SpatialReference() + if sr.ImportFromWkt(proj) != gdal.CE_None: + return '' + + name = sr.GetAuthorityName(None) + code = sr.GetAuthorityCode(None) + if name is not None and code is not None: + return '%s:%s' % (name, code) + + return '' + + +# get raster extent using python API - replaces old method which parsed gdalinfo output +def getRasterExtent(parent, fileName): + ds = gdal.Open(fileName) + if ds is None: + return + + x = ds.RasterXSize + y = ds.RasterYSize + + gt = ds.GetGeoTransform() + if gt is None: + xUL = 0 + yUL = 0 + xLR = x + yLR = y + else: + xUL = gt[0] + yUL = gt[3] + xLR = gt[0] + gt[1] * x + gt[2] * y + yLR = gt[3] + gt[4] * x + gt[5] * y + + return QgsRectangle(xUL, yLR, xLR, yUL) + + +# This class is used to replace the QFileDialog class. +# Its static methods are used in place of the respective QFileDialog ones to: +# 1. set the last used directory +# 2. append the selected extension to the file name +# 3. bypass the following bug: +# when you use the 'filter' argument, the dialog is enlarged up to the longest filter length, +# so sometimes the dialog excedes the screen width +class FileDialog: + @classmethod + def getDialog(self, parent=None, caption='', acceptMode=QFileDialog.AcceptOpen, fileMode=QFileDialog.ExistingFile, + filter='', selectedFilter=None, useEncoding=False): + if useEncoding: + dialog = QgsEncodingFileDialog(parent, caption, getLastUsedDir(), filter, getLastUsedEncoding()) + else: + dialog = QFileDialog(parent, caption, getLastUsedDir(), filter) + dialog.setFileMode(fileMode) + dialog.setAcceptMode(acceptMode) + + if selectedFilter is not None: + dialog.selectNameFilter(selectedFilter[0]) + + if not dialog.exec_(): + if useEncoding: + return ('', None) + return '' + + # change the selected filter value + if selectedFilter is not None: + selectedFilter[0] = dialog.selectedNameFilter() + + # save the last used dir and return the selected files + files = dialog.selectedFiles() + if files != '': + setLastUsedDir(files[0]) + + if fileMode != QFileDialog.ExistingFiles: + files = files[0] + # append the extension if not already present + if fileMode == QFileDialog.AnyFile: + firstExt = None + for ext in FileFilter.getFilterExtensions(dialog.selectedNameFilter()): + if FileFilter.filenameMatchesFilterExt(files, ext): + firstExt = None + break + + if firstExt == None: + firstExt = ext + + if firstExt != None: + if firstExt.startswith('*'): + files += firstExt[1:] + + if useEncoding: + encoding = dialog.encoding() + # encoding setted yet by QgsEncodingFileDialog + # setLastUsedEncoding(encoding) + return (files, encoding) + + return files + + @classmethod + def getOpenFileNames(self, parent=None, caption='', filter='', selectedFilter=None, useEncoding=False): + return self.getDialog(parent, caption, QFileDialog.AcceptOpen, QFileDialog.ExistingFiles, filter, + selectedFilter, useEncoding) + + @classmethod + def getOpenFileName(self, parent=None, caption='', filter='', selectedFilter=None, useEncoding=False): + return self.getDialog(parent, caption, QFileDialog.AcceptOpen, QFileDialog.ExistingFile, filter, selectedFilter, + useEncoding) + + @classmethod + def getSaveFileName(self, parent=None, caption='', filter='', selectedFilter=None, useEncoding=False): + return self.getDialog(parent, caption, QFileDialog.AcceptSave, QFileDialog.AnyFile, filter, selectedFilter, + useEncoding) + + @classmethod + def getExistingDirectory(self, parent=None, caption='', useEncoding=False): + return self.getDialog(parent, caption, QFileDialog.AcceptOpen, QFileDialog.DirectoryOnly, '', None, useEncoding) + + +class FileFilter: + @classmethod + def getFilter(self, typeName): + settings = QSettings() + return settings.value("/GdalTools/" + typeName + "FileFilter", u"", type=unicode) + + @classmethod + def setFilter(self, typeName, aFilter): + settings = QSettings() + settings.setValue("/GdalTools/" + typeName + "FileFilter", aFilter) + + # stores the supported raster file filter + rastersFilter = '' + + # Retrieves the filter for supported raster files + @classmethod + def allRastersFilter(self): + if self.rastersFilter == '': + self.rastersFilter = QgsProviderRegistry.instance().fileRasterFilters() + + # workaround for QGis < 1.5 (see #2376) + # removed as this is a core plugin QGis >= 1.9 + + return self.rastersFilter + + # Retrieves the last used filter for raster files + # Note: filter string is in a list + @classmethod + def lastUsedRasterFilter(self): + return [self.getFilter("lastRaster")] + + @classmethod + def setLastUsedRasterFilter(self, aFilter): + self.setFilter("lastRaster", aFilter[0]) + + # stores the supported vectors file filter + vectorsFilter = '' + + # Retrieves the filter for supported vector files + @classmethod + def allVectorsFilter(self): + if self.vectorsFilter == '': + self.vectorsFilter = QgsProviderRegistry.instance().fileVectorFilters() + return self.vectorsFilter + + # Retrieves the last used filter for vector files + # Note: filter string is in a list + @classmethod + def lastUsedVectorFilter(self): + return [self.getFilter("lastVector")] + + @classmethod + def setLastUsedVectorFilter(self, aFilter): + self.setFilter("lastVector", aFilter[0]) + + # Retrieves the extensions list from a filter string + @classmethod + def getFilterExtensions(self, aFilter): + extList = [] + # foreach format in filter string + for f in aFilter.split(";;"): + # gets the list of extensions from the filter + exts = re.sub('\).*$', '', re.sub('^.*\(', '', f)) + # if there is no extensions or the filter matches all, then return an empty list + # otherwise return the list of estensions + if exts != '' and exts != "*" and exts != "*.*": + extList.extend(exts.split(" ")) + return extList + + @classmethod + def getFilterName(self, aFilter): + return string.strip(re.sub('\ \(.*$', '', aFilter)) + + @classmethod + def filenameMatchesFilterExt(self, fileName, ext): + return re.match('.' + str(ext), fileName) is not None + + +# Retrieves gdal information +class GdalConfig: + # retrieves and return the installed gdal version + @classmethod + def version(self): + return Version(gdal.VersionInfo("RELEASE_NAME")) + + @classmethod + def versionNum(self): + return int(gdal.VersionInfo("VERSION_NUM")) + + # store the supported rasters info + supportedRasters = None + + # retrieve the supported rasters info + @classmethod + def getSupportedRasters(self): + if self.supportedRasters != None: + return self.supportedRasters + + # first get the GDAL driver manager + if gdal.GetDriverCount() == 0: + gdal.AllRegister() + + self.supportedRasters = dict() + jp2Driver = None + + # for each loaded GDAL driver + for i in range(gdal.GetDriverCount()): + driver = gdal.GetDriver(i) + + if driver == None: + QgsLogger.warning("unable to get driver " + str(i)) + continue + + # now we need to see if the driver is for something currently + # supported; if not, we give it a miss for the next driver + + longName = string.strip(re.sub('\(.*$', '', driver.LongName)) + shortName = string.strip(re.sub('\(.*$', '', driver.ShortName)) + extensions = '' + + description = driver.GetDescription() + glob = [] + + metadata = driver.GetMetadata() + if metadata.has_key(gdal.DMD_EXTENSION): + extensions = str(metadata[gdal.DMD_EXTENSION]) + + if longName != '': + if extensions != '': + # XXX add check for SDTS; in that case we want (*CATD.DDF) + + # TODO fix and test + # glob.append( QString("*." + extensions.replace("/", " *.")).split(" ")) + glob.append(string.split("*." + string.replace(extensions, "/", " *."), sep=(" "))) + + # Add only the first JP2 driver found to the filter list (it's the one GDAL uses) + if description == "JPEG2000" or description.startswith("JP2"): # JP2ECW, JP2KAK, JP2MrSID + if jp2Driver != None: + continue # skip if already found a JP2 driver + jp2Driver = driver # first JP2 driver found + glob.append("*.j2k") # add alternate extension + elif description == "GTiff": + glob.append("*.tiff") + elif description == "JPEG": + glob.append("*.jpeg") + else: + # USGS DEMs use "*.dem" + if description.startswith("USGSDEM"): + glob.append("*.dem") + elif description.startswith("DTED"): + # DTED use "*.dt0" + glob.append("*.dt0") + elif description.startswith("MrSID"): + # MrSID use "*.sid" + glob.append("*.sid") + else: + continue + + self.supportedRasters[longName] = {'EXTENSIONS': glob, 'LONGNAME': longName, 'SHORTNAME': shortName, + 'DESCRIPTION': description} + + return self.supportedRasters + + # store the supported vectors info + supportedVectors = None + + # retrieve the supported vectors info + @classmethod + def getSupportedVectors(self): + if self.supportedVectors != None: + return self.supportedVectors + + # first get the OGR driver manager + QgsApplication.registerOgrDrivers() + + self.supportedVectors = dict() + + # for each loaded OGR driver + for i in range(ogr.GetDriverCount()): + driver = ogr.GetDriver(i) + + if driver == None: + QgsLogger.warning("unable to get driver " + str(i)) + continue + + driverName = driver.GetName() + longName = '' + glob = [] + + if driverName.startswith("AVCBin"): + pass # myDirectoryDrivers += "Arc/Info Binary Coverage,AVCBin" + elif driverName.startswith("AVCE00"): + longName = "Arc/Info ASCII Coverage" + glob.append("*.e00") + elif driverName.startswith("BNA"): + longName = "Atlas BNA" + glob.append("*.bna") + elif driverName.startswith("CSV"): + longName = "Comma Separated Value" + glob.append("*.csv") + elif driverName.startswith("DODS"): + pass # myProtocolDrivers += "DODS/OPeNDAP,DODS" + elif driverName.startswith("PGeo"): + pass # myDatabaseDrivers += "ESRI Personal GeoDatabase,PGeo" + + # on Windows add a pair to the dict for this driver + if platform.system() == "Windows": + longName = "ESRI Personal GeoDatabase" + glob.append("*.mdb") + elif driverName.startswith("SDE"): + pass # myDatabaseDrivers += "ESRI ArcSDE,SDE" + elif driverName.startswith("ESRI"): + longName = "ESRI Shapefiles" + glob.append("*.shp") + elif driverName.startswith("FMEObjects Gateway"): + longName = "FMEObjects Gateway" + glob.append("*.fdd") + elif driverName.startswith("GeoJSON"): + pass # myProtocolDrivers += "GeoJSON,GeoJSON" + longName = "GeoJSON" + glob.append("*.geojson") + elif driverName.startswith("GeoRSS"): + longName = "GeoRSS" + glob.append("*.xml") + elif driverName.startswith("GML"): + longName = "Geography Markup Language" + glob.append("*.gml") + elif driverName.startswith("GMT"): + longName = "GMT" + glob.append("*.gmt") + elif driverName.startswith("GPX"): + longName = "GPX" + glob.append("*.gpx") + elif driverName.startswith("GRASS"): + pass # myDirectoryDrivers += "Grass Vector,GRASS" + elif driverName.startswith("IDB"): + pass # myDatabaseDrivers += "Informix DataBlade,IDB" + elif driverName.startswith("Interlis 1"): + longName = "INTERLIS 1" + glob.append("*.itf") + glob.append("*.xml") + glob.append("*.ili") + elif driverName.startswith("Interlis 2"): + longName = "INTERLIS 2" + glob.append("*.itf") + glob.append("*.xml") + glob.append("*.ili") + elif driverName.startswith("INGRES"): + pass # myDatabaseDrivers += "INGRES,INGRES" + elif driverName.startswith("KML"): + longName = "KML" + glob.append("*.kml") + elif driverName.startswith("MapInfo File"): + longName = "Mapinfo File" + glob.append("*.mif") + glob.append("*.tab") + elif driverName.startswith("DGN"): + longName = "Microstation DGN" + glob.append("*.dgn") + elif driverName.startswith("MySQL"): + pass # myDatabaseDrivers += "MySQL,MySQL" + elif driverName.startswith("OCI"): + pass # myDatabaseDrivers += "Oracle Spatial,OCI" + elif driverName.startswith("ODBC"): + pass # myDatabaseDrivers += "ODBC,ODBC" + elif driverName.startswith("OGDI"): + pass # myDatabaseDrivers += "OGDI Vectors,OGDI" + elif driverName.startswith("PostgreSQL"): + pass # myDatabaseDrivers += "PostgreSQL,PostgreSQL" + elif driverName.startswith("S57"): + longName = "S-57 Base file" + glob.append("*.000") + elif driverName.startswith("SDTS"): + longName = "Spatial Data Transfer Standard" + glob.append("*catd.ddf") + elif driverName.startswith("SQLite"): + longName = "SQLite" + glob.append("*.sqlite") + elif driverName.startswith("UK .NTF"): + pass # myDirectoryDrivers += "UK. NTF,UK. NTF" + elif driverName.startswith("TIGER"): + pass # myDirectoryDrivers += "U.S. Census TIGER/Line,TIGER" + elif driverName.startswith("VRT"): + longName = "VRT - Virtual Datasource " + glob.append("*.vrt") + elif driverName.startswith("XPlane"): + longName = "X-Plane/Flighgear" + glob.append("apt.dat") + glob.append("nav.dat") + glob.append("fix.dat") + glob.append("awy.dat") + + longName = string.strip(longName) + + if longName == '': + continue + + self.supportedVectors[longName] = {'EXTENSIONS': glob, 'LONGNAME': longName, 'SHORTNAME': driverName} + + return self.supportedVectors + + class SupportedRasters: + dict_long2shortName = dict() + + # retrieve the raster format short name by long format name + @classmethod + def long2ShortName(self, longName): + if longName == '': + return '' + + if self.dict_long2shortName.has_key(longName): + return self.dict_long2shortName[longName] + + # first get the GDAL driver manager + if gdal.GetDriverCount() == 0: + gdal.AllRegister() + + shortName = '' + + # for each loaded GDAL driver + for i in range(gdal.GetDriverCount()): + driver = gdal.GetDriver(i) + if driver == None: + continue + + # if this is the driver we searched for then return its short name + if FileFilter.getFilterName(driver.LongName) == longName: + shortName = FileFilter.getFilterName(driver.ShortName) + self.dict_long2shortName[longName] = shortName + break + + return shortName + + # retrieve the raster format short name by using the file name extension + @classmethod + def filename2ShortName(self, fileName): + if fileName == '': + return '' + + shortName = '' + + # for each raster format search for the file extension + formats = FileFilter.allRastersFilter().split(";;") + for f in formats: + for ext in FileFilter.getFilterExtensions(f): + if FileFilter.filenameMatchesFilterExt(fileName, ext): + longName = FileFilter.getFilterName(f) + shortName = self.long2ShortName(longName) + break + + if not shortName == '': + break + + return shortName + + +# class which allows creating version objects and compare them +class Version: + def __init__(self, ver): + self.vers = ('0', '0', '0') + + if isinstance(ver, Version): + self.vers = ver.vers + elif isinstance(ver, tuple) or isinstance(ver, list): + self.vers = map(str, ver) + elif isinstance(ver, str): + self.vers = self.string2vers(ver) + + @staticmethod + def string2vers(string): + vers = ['0', '0', '0'] + + nums = str(string).split(".") + + if len(nums) > 0: + vers[0] = nums[0] + if len(nums) > 1: + vers[1] = nums[1] + if len(nums) > 2: + vers[2] = nums[2] + + return (vers[0], vers[1], vers[2]) + + def __cmp__(self, other): + if not isinstance(other, Version): + other = Version(other) + + if self.vers > other.vers: + return 1 + if self.vers < other.vers: + return -1 + return 0 + + def __str__(self): + return ".".join(self.vers) + + +def setProcessEnvironment(process): + envvar_list = { + "PATH": getGdalBinPath(), + "PYTHONPATH": getGdalPymodPath(), + "GDAL_FILENAME_IS_UTF8": "NO" + } + + sep = os.pathsep + + for name, val in envvar_list.iteritems(): + if val == None or val == "": + continue + + envval = os.getenv(name) + if envval == None or envval == "": + envval = str(val) + elif (platform.system() == "Windows" and val.lower() not in envval.lower().split(sep)) or \ + (platform.system() != "Windows" and val not in envval.split(sep)): + envval += "%s%s" % (sep, str(val)) + else: + envval = None + + if envval != None: + os.putenv(name, envval) + + +def setMacOSXDefaultEnvironment(): + # fix bug #3170: many GDAL Tools don't work in OS X standalone + + if platform.system() != "Darwin": + return + + # QgsApplication.prefixPath() contains the path to qgis executable (i.e. .../Qgis.app/MacOS) + # get the path to Qgis application folder + qgis_app = u"%s/.." % QgsApplication.prefixPath() + qgis_app = QDir(qgis_app).absolutePath() + + qgis_bin = u"%s/bin" % QgsApplication.prefixPath() # path to QGis bin folder + qgis_python = u"%s/Resources/python" % qgis_app # path to QGis python folder + + # path to the GDAL framework within the Qgis application folder (QGis standalone only) + qgis_standalone_gdal_path = u"%s/Frameworks/GDAL.framework" % qgis_app + + # path to the GDAL framework when installed as external framework + gdal_versionsplit = str(GdalConfig.version()).split('.') + gdal_base_path = u"/Library/Frameworks/GDAL.framework/Versions/%s.%s" % (gdal_versionsplit[0], gdal_versionsplit[1]) + + if os.path.exists(qgis_standalone_gdal_path): # qgis standalone + # GDAL executables are in the QGis bin folder + if getGdalBinPath() == '': + setGdalBinPath(qgis_bin) + # GDAL pymods are in the QGis python folder + if getGdalPymodPath() == '': + setGdalPymodPath(qgis_python) + # GDAL help is in the framework folder + if getHelpPath() == '': + setHelpPath(u"%s/Resources/doc" % qgis_standalone_gdal_path) + + elif os.path.exists(gdal_base_path): + # all GDAL parts are in the GDAL framework folder + if getGdalBinPath() == '': + setGdalBinPath(u"%s/Programs" % gdal_base_path) + if getGdalPymodPath() == '': + setGdalPymodPath( + u"%s/Python/%s.%s/site-packages" % (gdal_base_path, sys.version_info[0], sys.version_info[1])) + if getHelpPath() == '': + setHelpPath(u"%s/Resources/doc" % gdal_base_path) + + +# setup the MacOSX path to both GDAL executables and python modules +if platform.system() == "Darwin": + setMacOSXDefaultEnvironment() diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 3260bf0..45a5f28 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -34,6 +34,8 @@ import HydroSEDPluginUtils as HSutils import HydroGetCoordinates as HSCoord +import GdalTools_utils as GdalTools_utils + FORM_CLASS, _ = uic.loadUiType(os.path.join( os.path.dirname(__file__), 'HydroSEDPlugin_dockwidget_base.ui')) @@ -138,9 +140,13 @@ def setupLineEditButtonOpenShapeFileDialog (lineEditHolder, fileDialogHolder): def setupLineEditButtonOpenRasterFileDialog (lineEditHolder, fileDialogHolder): - lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), 'Open File',"", "*", +# lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), 'Open File',"", "*", +# QtGui.QFileDialog.DontUseNativeDialog)) + + lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), 'Open File',"", GdalTools_utils.FileFilter.allRastersFilter (), QtGui.QFileDialog.DontUseNativeDialog)) + def setupLineEditButtonOpenFileDialog (lineEditHolder, fileDialogHolder): lineEditHolder.setText (fileDialogHolder.getOpenFileName ()) From da2e3c8a36e8c2cc38719ae754fbf6c50c83c244 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 8 May 2018 10:44:33 -0500 Subject: [PATCH 024/142] Se hace el set de las rutas para el trazador de cuencas --- qgisplugin/HydroSEDPluginUtils.py | 2 + qgisplugin/HydroSEDPlugin_dockwidget.py | 51 ++++++++++++-------- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 14 +++--- 3 files changed, 41 insertions(+), 26 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index bbd1a7d..b4d961f 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -79,7 +79,9 @@ def cargar_mapa_dir_wmf (self,pathMapaDIR, dxp): return retornoCargaLayerMapaRaster def trazador_corriente(self,x,y, path = None): + #Traza la corriente en las coordenadas especificadas self.stream = wmf.Stream(x, y, self.DEM, self.DIR) + #Guarda la corriente. if path is not None: self.stream.Save_Stream2Map(path) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 3260bf0..928da26 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -94,10 +94,10 @@ def handleClickEventEjecutarTrazadorCorrientes (self): def handleClickEventEjecutarTrazadorCuencas (self): #Obtiene coordenadas - #y = self.spinBoxLatitudTrazadorCuencas.value () - #x = self.spinBoxLongitudTrazadorCuencas.value () - - #OutPathDivisoria = self.PathOutputDivisoria.text() + y = self.spinBoxLatitudTrazadorCuencas.value () + x = self.spinBoxLongitudTrazadorCuencas.value () + #Paths para guardar la cuenca + OutPathDivisoria = self.PathOutputDivisoria.text() #try: #self.HSutils.trazador_corriente(x,y, OutPath) #ret, layer = self.HSutils.cargar_mapa_vector(OutPath) @@ -213,42 +213,55 @@ def clickEventCargarWMFMapaDIR(): self.iface.messageBar().pushError (u'Hydro-SED', u'No fue posible cargar el mapa DIR al WMF. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.') def clickEventSelectorBinarioNC (): - setupLineEditButtonOpenFileDialog (self.lineEditSelectorBinarioNC, QFileDialog) - def clickEventSelectorOutputCorrienteShapefileTrazadorCorrientes (): - - setupLineEditButtonSaveFileDialog (self.PathCorriente_out, QFileDialog) - - def clickEventSelectorInputCorrienteShapefileTrazadorCuencas (): - -# setupLineEditButtonOpenFileDialog (self.lineEditInputCorrienteShapefileTrazadorCuencas, QFileDialog) - setupLineEditButtonOpenShapeFileDialog (self.lineEditInputCorrienteShapefileTrazadorCuencas, QFileDialog) + def clickEventSelectorOutputCorrienteShapefileTrazadorCorrientes(): + setupLineEditButtonSaveFileDialog(self.PathCorriente_out, QFileDialog) + + def clickEventSelectorInputCorrienteShapefileTrazadorCuencas(): + #Hace set del path para la divisoria + setupLineEditButtonSaveFileDialog(self.PathOutputDivisoria, QFileDialog) + #Obtiene solo el path y el nombre + PathOnly = os.path.dirname(self.PathOutputDivisoria.text().strip()) + #PathOnly = self.PathOutputDivisoria + NameOnly = os.path.basename(self.PathOutputDivisoria.text().strip()) + NameOnly = os.path.splitext(NameOnly)[0] + #Genera las rutas de la red y del nc + PathRed = PathOnly +'/' +NameOnly + '_Red.shp' + PathNC = PathOnly + '/'+NameOnly + 'Topo.nc' + #Hace un set del path de la red y del nc. + self.PathOutputRed.setText(PathRed) + self.PathOutputNETCDF.setText(PathNC) + def clickEventSelectorOutputCuencaShapefileTrazadorCuencas (): - setupLineEditButtonSaveFileDialog (self.lineEditOutputCuencaShapefileTrazadorCuencas, QFileDialog) def clickEventSelectorOutputCuencaNCTrazadorCuencas (): - setupLineEditButtonSaveFileDialog (self.lineEditOutputCuencaNCTrazadorCuencas, QFileDialog) self.botonSelectorMapaDEM.clicked.connect (clickEventSelectorMapaDEM) self.botonSelectorMapaDIR.clicked.connect (clickEventSelectorMapaDIR) - + + #Botones para cargar y visualizar mapas DEM y DIR self.Boton_verMDE.clicked.connect (clickEventVisualizarMapaDEM) self.Boton_verDIR.clicked.connect (clickEventVisualizarMapaDIR) self.Boton_MDE2WMF.clicked.connect (clickEventCargarWMFMapaDEM) self.Boton_DIR2WMF.clicked.connect (clickEventCargarWMFMapaDIR) -# self.Boton_verDIR.clicked.connect (clickEventVisualizarMapaDIR) self.botonSelectorBinarioNC.clicked.connect (clickEventSelectorBinarioNC) + + #Botones para establecer la ruta de guardado del terazador de corrientes yd e cuencas self.botonSelectorOutputCorrienteShapefileTrazadorCorrientes.clicked.connect (clickEventSelectorOutputCorrienteShapefileTrazadorCorrientes) + self.BotonPathDivisoria.clicked.connect(clickEventSelectorInputCorrienteShapefileTrazadorCuencas) - self.botonEjecutarTrazadorCorrientes.clicked.connect (self.handleClickEventEjecutarTrazadorCorrientes) - + #Botones para agarrar coordenadqas de trazado self.BotonCoord_corriente.clicked.connect(self.handleClickCoordCorrientes) self.BotonCoord_cuenca.clicked.connect(self.handleClickCoordCuencas) + + #Botones ejecucion trazadores + self.botonEjecutarTrazadorCorrientes.clicked.connect (self.handleClickEventEjecutarTrazadorCorrientes) + #self.botonOutputCuencaShapefileTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaShapefileTrazadorCuencas) #self.botonOutputCuencaNCTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaNCTrazadorCuencas) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index c0696c3..68e7e87 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -491,7 +491,7 @@ 0 - 170 + 210 359 331 @@ -505,7 +505,7 @@ 10 20 341 - 271 + 310 @@ -702,7 +702,7 @@ - true + false @@ -743,7 +743,7 @@ - true + false @@ -784,7 +784,7 @@ - true + false @@ -822,7 +822,7 @@ 10 22 341 - 141 + 159 @@ -1003,7 +1003,7 @@ 10 - 160 + 190 341 20 From a1c3659cce0ccb9bd41f174dffb7553feee4c2cd Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 8 May 2018 11:22:00 -0500 Subject: [PATCH 025/142] =?UTF-8?q?trazador=20de=20cuencas=20funciona,=20s?= =?UTF-8?q?e=20deben=20hacer=20cambios=20para=20que=20trabaje=20de=20una?= =?UTF-8?q?=20forma=20m=C3=A1s=20limpia=20al=20cargar=20archivos.=20todavi?= =?UTF-8?q?a=20no=20guarda=20el=20.nc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPluginUtils.py | 19 +++--- qgisplugin/HydroSEDPlugin_dockwidget.py | 58 +++++++++--------- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 64 +++++++++++++++++++- 3 files changed, 103 insertions(+), 38 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index b4d961f..e6a1331 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -31,7 +31,7 @@ def cargar_mapa_raster (self,pathMapaRaster): return retornoCargaLayerMapaRaster - def cargar_mapa_vector(self, pathMapaVector): + def cargar_mapa_vector(self, pathMapaVector, color = (50,50,250), width = 0.5): #Inicia vandera de cargado y ruta del vector retornoCargarMapaVector = False pathMapaVector = pathMapaVector.strip() @@ -44,8 +44,8 @@ def cargar_mapa_vector(self, pathMapaVector): symbols = layerMapaVector.rendererV2().symbols() symbol = symbols[0] - symbol.setColor(QtGui.QColor.fromRgb(50,50,250)) - symbol.setWidth(0.5) + symbol.setColor(QtGui.QColor.fromRgb(color[0],color[1],color[2])) + symbol.setWidth(width) retornoCargarMapaVector = layerMapaVector.isValid() return retornoCargarMapaVector, layerMapaVector @@ -85,11 +85,16 @@ def trazador_corriente(self,x,y, path = None): if path is not None: self.stream.Save_Stream2Map(path) - def trazador_cuenca(self,x,y,name = 'None', TopoNodes = False, LastStream = True): + def trazador_cuenca(self,x,y, dxp,umbral,PathDiv, PathRed, PathNC,TopoNodes = False, LastStream = True): # Traza la cuenca con y sin la ultima corriente. if LastStream: - self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR, stream=self.stream, TopoNodes=TopoNodes) + self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR, stream=self.stream) else: - self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR, TopoNodes=TopoNodes) - # Mira si guarda el shp de la cuenca. + self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR) + # Guarda los shapes de divisoria y de red hidrica. + if len(PathDiv)>2: + self.cuenca.Save_Basin2Map(PathDiv, dxp) + if len(PathRed)>2: + self.cuenca.Save_Net2Map(PathRed, dxp, umbral) + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 928da26..0a6c174 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -98,32 +98,24 @@ def handleClickEventEjecutarTrazadorCuencas (self): x = self.spinBoxLongitudTrazadorCuencas.value () #Paths para guardar la cuenca OutPathDivisoria = self.PathOutputDivisoria.text() + OutPathRed = self.PathOutputRed.text() + OutPathNC = self.PathOutputNETCDF.text() #try: - #self.HSutils.trazador_corriente(x,y, OutPath) - #ret, layer = self.HSutils.cargar_mapa_vector(OutPath) - - #self.iface.mapCanvas().refresh() - #self.iface.legendInterface().refreshLayerSymbology(layer) - - #self.iface.messageBar().pushInfo(u'Hydro-SED',u'Se ha trazado la corriente de forma exitosa') + #Traza la cuenca + self.HSutils.trazador_cuenca(x,y, self.spinBox_dxPlano.value(), + self.spinBoxUmbralRed.value(),OutPathDivisoria, OutPathRed, OutPathNC) + #Carga la divisoria + ret, layer = self.HSutils.cargar_mapa_vector(OutPathDivisoria, color = (255,0,0), width = 0.6) + self.iface.mapCanvas().refresh() + self.iface.legendInterface().refreshLayerSymbology(layer) + #Carga la red + ret, layer = self.HSutils.cargar_mapa_vector(OutPathRed, width = 0.4) + self.iface.mapCanvas().refresh() + self.iface.legendInterface().refreshLayerSymbology(layer) + #mensaje de exito + self.iface.messageBar().pushInfo(u'Hydro-SED',u'Se ha trazado la cuenca de forma exitosa') #except: - #pass - - print wmf - print self.spinBoxLatitudTrazadorCuencas.value () - print self.spinBoxLongitudTrazadorCuencas.value () - print self.lineEditInputCorrienteShapefileTrazadorCuencas.text () - print self.lineEditOutputCuencaShapefileTrazadorCuencas.text () - print self.lineEditOutputCuencaNCTrazadorCuencas.text () - - -# from PyQt4.QtGui import QFileDialog -# filename1 = QFileDialog.getOpenFileName() -# filename2 = QFileDialog.getSaveFileName() -# print filename1 -# print filename2 - - + # pass def setupUIInputsOutputs (self): @@ -218,7 +210,7 @@ def clickEventSelectorBinarioNC (): def clickEventSelectorOutputCorrienteShapefileTrazadorCorrientes(): setupLineEditButtonSaveFileDialog(self.PathCorriente_out, QFileDialog) - def clickEventSelectorInputCorrienteShapefileTrazadorCuencas(): + def clickEventSelectorInputCuencaShapefileTrazadorCuencas(): #Hace set del path para la divisoria setupLineEditButtonSaveFileDialog(self.PathOutputDivisoria, QFileDialog) #Obtiene solo el path y el nombre @@ -232,7 +224,14 @@ def clickEventSelectorInputCorrienteShapefileTrazadorCuencas(): #Hace un set del path de la red y del nc. self.PathOutputRed.setText(PathRed) self.PathOutputNETCDF.setText(PathNC) - + + def clickEventSelectorInputRedShapefileTrazadorCuencas(): + #Hace set del path para la red + setupLineEditButtonSaveFileDialog(self.PathOutputRed, QFileDialog) + + def clickEventSelectorInputNC_ShapefileTrazadorCuencas(): + #Hace set del path para el nc + setupLineEditButtonSaveFileDialog(self.PathOutputNETCDF, QFileDialog) def clickEventSelectorOutputCuencaShapefileTrazadorCuencas (): setupLineEditButtonSaveFileDialog (self.lineEditOutputCuencaShapefileTrazadorCuencas, QFileDialog) @@ -253,7 +252,10 @@ def clickEventSelectorOutputCuencaNCTrazadorCuencas (): #Botones para establecer la ruta de guardado del terazador de corrientes yd e cuencas self.botonSelectorOutputCorrienteShapefileTrazadorCorrientes.clicked.connect (clickEventSelectorOutputCorrienteShapefileTrazadorCorrientes) - self.BotonPathDivisoria.clicked.connect(clickEventSelectorInputCorrienteShapefileTrazadorCuencas) + self.BotonPathDivisoria.clicked.connect(clickEventSelectorInputCuencaShapefileTrazadorCuencas) + #Botones para ruta de red y de nc. + self.BotonPathRed.clicked.connect(clickEventSelectorInputRedShapefileTrazadorCuencas) + self.BotonPathNC.clicked.connect(clickEventSelectorInputNC_ShapefileTrazadorCuencas) #Botones para agarrar coordenadqas de trazado self.BotonCoord_corriente.clicked.connect(self.handleClickCoordCorrientes) @@ -261,7 +263,7 @@ def clickEventSelectorOutputCuencaNCTrazadorCuencas (): #Botones ejecucion trazadores self.botonEjecutarTrazadorCorrientes.clicked.connect (self.handleClickEventEjecutarTrazadorCorrientes) - + self.botonEjecutarTrazadorCuencas.clicked.connect(self.handleClickEventEjecutarTrazadorCuencas) #self.botonOutputCuencaShapefileTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaShapefileTrazadorCuencas) #self.botonOutputCuencaNCTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaNCTrazadorCuencas) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 68e7e87..60458d1 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -493,7 +493,7 @@ 0 210 359 - 331 + 451 @@ -505,7 +505,7 @@ 10 20 341 - 310 + 361 @@ -662,7 +662,7 @@ - + Si usar o no usar ultima corriente @@ -690,6 +690,13 @@ + + + + Qt::Horizontal + + + @@ -731,6 +738,13 @@ + + + + Qt::Horizontal + + + @@ -738,6 +752,43 @@ + + + + + + Obtiene automaticamente los nodos topograficos. + + + Obtiene automaticamente los nodos topograficos. + + + Topo Nodes + + + + + + + Obtiene parametros geomorfologicos de la cuenca. + + + GetGeo + + + + + + + Obtiene el ancho del canal en cada tramo. + + + Ancho canal + + + + + @@ -772,6 +823,13 @@ + + + + Qt::Horizontal + + + From 994863b7d1954f5e0cdf6095044a00a32b4114d1 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 8 May 2018 11:49:51 -0500 Subject: [PATCH 026/142] Cambios menores en los trazadores y su comportamiento, sfalta que el de cuencas logre sacarla sin rellenar con el borde rojo --- qgisplugin/HydroSEDPluginUtils.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index e6a1331..1af6da2 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -1,6 +1,6 @@ import os.path -from qgis.core import QgsRasterLayer, QgsMapLayerRegistry, QgsVectorLayer +from qgis.core import QgsRasterLayer, QgsMapLayerRegistry, QgsVectorLayer, QgsFillSymbolV2 from PyQt4 import QtGui, uic from wmf import wmf @@ -46,6 +46,18 @@ def cargar_mapa_vector(self, pathMapaVector, color = (50,50,250), width = 0.5): symbol = symbols[0] symbol.setColor(QtGui.QColor.fromRgb(color[0],color[1],color[2])) symbol.setWidth(width) + #try: + # symbol.setWidth(width) + #except: + # symbol.setBorderWidth(width) + #if layerMapVector.geometryType() == QGis.Polygon: + #Render = layerMapaVector.rendererV2() + #mySymbol1 = QgsFillSymbolV2.createSimple({'color':'blue', + # 'color_border':color, + #'width_border':width, + # 'style':'no', + # 'style_border':'solid'}) + #Render.setSymbol(mySymbol1) retornoCargarMapaVector = layerMapaVector.isValid() return retornoCargarMapaVector, layerMapaVector From 3c35c3d6b292f4b3ad521b14524a0e11c3ed9590 Mon Sep 17 00:00:00 2001 From: camilo2046 Date: Tue, 8 May 2018 15:52:42 -0500 Subject: [PATCH 027/142] Se agrega cambio en estilo al metodo de carga de mapas tipo vector --- qgisplugin/HydroSEDPluginUtils.py | 41 ++++++++++++++++--------- qgisplugin/HydroSEDPlugin_dockwidget.py | 9 ++++-- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 1af6da2..5781baa 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -7,6 +7,9 @@ class controlHS: + TIPO_STYLE_POLIGONO = 1 + TIPO_STYLE_POLILINEA = 2 + def __init__(self): self.DEM = 0 self.DIR = 0 @@ -31,34 +34,44 @@ def cargar_mapa_raster (self,pathMapaRaster): return retornoCargaLayerMapaRaster - def cargar_mapa_vector(self, pathMapaVector, color = (50,50,250), width = 0.5): + def cargar_mapa_vector(self, pathMapaVector, tipo_style, color = (50,50,250), width = 0.5): #Inicia vandera de cargado y ruta del vector retornoCargarMapaVector = False pathMapaVector = pathMapaVector.strip() #verifica existencia y dado el caso carga + if os.path.exists(pathMapaVector): + baseNameMapaVector = os.path.basename(pathMapaVector) baseNameMapaVector = os.path.splitext(baseNameMapaVector)[0] layerMapaVector = QgsVectorLayer(pathMapaVector, baseNameMapaVector, 'ogr') QgsMapLayerRegistry.instance().addMapLayer(layerMapaVector) - - symbols = layerMapaVector.rendererV2().symbols() - symbol = symbols[0] - symbol.setColor(QtGui.QColor.fromRgb(color[0],color[1],color[2])) - symbol.setWidth(width) + + if tipo_style == self.TIPO_STYLE_POLILINEA: + + symbols = layerMapaVector.rendererV2().symbols() + symbol = symbols[0] + symbol.setColor(QtGui.QColor.fromRgb(color[0],color[1],color[2])) + symbol.setWidth(width) + #try: # symbol.setWidth(width) #except: # symbol.setBorderWidth(width) #if layerMapVector.geometryType() == QGis.Polygon: - #Render = layerMapaVector.rendererV2() - #mySymbol1 = QgsFillSymbolV2.createSimple({'color':'blue', - # 'color_border':color, - #'width_border':width, - # 'style':'no', - # 'style_border':'solid'}) - #Render.setSymbol(mySymbol1) - + + elif tipo_style == self.TIPO_STYLE_POLIGONO: + + Render = layerMapaVector.rendererV2() + mySymbol1 = QgsFillSymbolV2.createSimple({'color':'blue', + 'color_border':'#%02x%02x%02x' % color, + 'width_border':str(width), + 'style':'no', + 'style_border':'solid'}) + + Render.setSymbol(mySymbol1) + layerMapaVector.triggerRepaint() + retornoCargarMapaVector = layerMapaVector.isValid() return retornoCargarMapaVector, layerMapaVector diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index bf6e4f8..1a93dae 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -85,7 +85,7 @@ def handleClickEventEjecutarTrazadorCorrientes (self): OutPath = self.PathCorriente_out.text() try: self.HSutils.trazador_corriente(x,y, OutPath) - ret, layer = self.HSutils.cargar_mapa_vector(OutPath) + ret, layer = self.HSutils.cargar_mapa_vector(OutPath, self.HSutils.TIPO_STYLE_POLILINEA) self.iface.mapCanvas().refresh() self.iface.legendInterface().refreshLayerSymbology(layer) @@ -106,14 +106,17 @@ def handleClickEventEjecutarTrazadorCuencas (self): #Traza la cuenca self.HSutils.trazador_cuenca(x,y, self.spinBox_dxPlano.value(), self.spinBoxUmbralRed.value(),OutPathDivisoria, OutPathRed, OutPathNC) + #Carga la divisoria - ret, layer = self.HSutils.cargar_mapa_vector(OutPathDivisoria, color = (255,0,0), width = 0.6) + ret, layer = self.HSutils.cargar_mapa_vector(OutPathDivisoria, self.HSutils.TIPO_STYLE_POLIGONO, color = (255,0,0), width = 0.6) self.iface.mapCanvas().refresh() self.iface.legendInterface().refreshLayerSymbology(layer) + #Carga la red - ret, layer = self.HSutils.cargar_mapa_vector(OutPathRed, width = 0.4) + ret, layer = self.HSutils.cargar_mapa_vector(OutPathRed, self.HSutils.TIPO_STYLE_POLILINEA, width = 0.4) self.iface.mapCanvas().refresh() self.iface.legendInterface().refreshLayerSymbology(layer) + #mensaje de exito self.iface.messageBar().pushInfo(u'Hydro-SED',u'Se ha trazado la cuenca de forma exitosa') #except: From effb2716d521e67dd198d11c7d81df75d1771fb6 Mon Sep 17 00:00:00 2001 From: camilo2046 Date: Wed, 9 May 2018 16:18:37 -0500 Subject: [PATCH 028/142] Se agrega ejemplo de scrollbar en tab de simulacion --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 248 +++++++++++++++++-- 1 file changed, 230 insertions(+), 18 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 60458d1..6f8a814 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -23,15 +23,15 @@ Hydro-SED - + - 1 + 4 - + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png @@ -120,7 +120,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -237,7 +237,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -339,7 +339,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -466,7 +466,7 @@ - + :/plugins/HydroSEDPlugin/icons/cuenca.ico:/plugins/HydroSEDPlugin/icons/cuenca.ico @@ -505,7 +505,7 @@ 10 20 341 - 361 + 367 @@ -537,7 +537,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -683,7 +683,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -731,7 +731,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -816,7 +816,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -864,7 +864,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -924,7 +924,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -1031,7 +1031,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1048,7 +1048,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1166,13 +1166,225 @@ Simulación + + + + 10 + 10 + 341 + 400 + + + + + 0 + 400 + + + + + 16777215 + 400 + + + + Qt::ScrollBarAlwaysOn + + + true + + + + + 0 + 0 + 326 + 730 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + 0 + 100 + + + + + 16777215 + 100 + + + + Grupo 1 + + + + + + TextLabel + + + + + + + + + + + + + + 0 + 300 + + + + + 16777215 + 300 + + + + Grupo 2 + + + + + + TextLabel + + + + + + + + + + TextLabel + + + + + + + + + + TextLabel + + + + + + + + + + TextLabel + + + + + + + + + + + + + + 0 + 300 + + + + + 16777215 + 300 + + + + Grupo 3 + + + + + + TextLabel + + + + + + + + + + TextLabel + + + + + + + + + + TextLabel + + + + + + + + + + TextLabel + + + + + + + + + + + + - - + + + QgsCollapsibleGroupBox + QGroupBox +
qgscollapsiblegroupbox.h
+ 1 +
+
+ From 0df8d578028c6bccf3d98dfae5476f15a2a3d87a Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Fri, 11 May 2018 10:49:13 -0500 Subject: [PATCH 029/142] Se agrega la opcion de que guarde el .cn y se incrementa el umbral maximo para determinar red hidrica, cuando guarda -nc se putea el sistema --- qgisplugin/HydroSEDPluginUtils.py | 5 ++- qgisplugin/HydroSEDPlugin_dockwidget.py | 3 +- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 36 +++++++++++--------- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 5781baa..762525c 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -110,7 +110,7 @@ def trazador_corriente(self,x,y, path = None): if path is not None: self.stream.Save_Stream2Map(path) - def trazador_cuenca(self,x,y, dxp,umbral,PathDiv, PathRed, PathNC,TopoNodes = False, LastStream = True): + def trazador_cuenca(self,x,y, dxp,umbral,PathDiv, PathRed, PathNC,PathDEM, PathDIR,TopoNodes = False, LastStream = True): # Traza la cuenca con y sin la ultima corriente. if LastStream: self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR, stream=self.stream) @@ -121,5 +121,8 @@ def trazador_cuenca(self,x,y, dxp,umbral,PathDiv, PathRed, PathNC,TopoNodes = Fa self.cuenca.Save_Basin2Map(PathDiv, dxp) if len(PathRed)>2: self.cuenca.Save_Net2Map(PathRed, dxp, umbral) + # Guarda el nc de la cuenca + if len(PathNC)>2: + self.cuenca.Save_SimuBasin(PathNC,PathDEM, PathDIR) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 1a93dae..955742a 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -105,7 +105,8 @@ def handleClickEventEjecutarTrazadorCuencas (self): #try: #Traza la cuenca self.HSutils.trazador_cuenca(x,y, self.spinBox_dxPlano.value(), - self.spinBoxUmbralRed.value(),OutPathDivisoria, OutPathRed, OutPathNC) + self.spinBoxUmbralRed.value(),OutPathDivisoria, OutPathRed, OutPathNC, self.lineEditMapaDEM, + self.lineEditMapaDIR) #Carga la divisoria ret, layer = self.HSutils.cargar_mapa_vector(OutPathDivisoria, self.HSutils.TIPO_STYLE_POLIGONO, color = (255,0,0), width = 0.6) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 6f8a814..b37abd4 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -27,11 +27,11 @@ - 4 + 0 - + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png @@ -120,7 +120,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -237,7 +237,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -339,7 +339,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -430,6 +430,9 @@ 16777215 + + 10000.000000000000000 + 12.699999999999999 @@ -466,7 +469,7 @@ - + :/plugins/HydroSEDPlugin/icons/cuenca.ico:/plugins/HydroSEDPlugin/icons/cuenca.ico @@ -537,7 +540,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -683,7 +686,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -731,7 +734,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -816,7 +819,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -864,7 +867,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -924,7 +927,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -1031,7 +1034,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1048,7 +1051,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1198,7 +1201,7 @@ 0 0 - 326 + 323 730 @@ -1385,6 +1388,7 @@ 1 - + + From afbb6e3915aab0fb831dce47fc45683cd8d90f2e Mon Sep 17 00:00:00 2001 From: nicolas998 Date: Mon, 14 May 2018 23:01:19 -0500 Subject: [PATCH 030/142] Trazadores ahora tiene scroll area --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 659 +++++++++++-------- 1 file changed, 368 insertions(+), 291 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index b37abd4..fcbcbe4 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -6,8 +6,8 @@ 0 0 - 389 - 869 + 343 + 839 @@ -27,7 +27,7 @@ - 0 + 1 @@ -42,7 +42,7 @@ 0 0 - 361 + 321 781 @@ -180,7 +180,7 @@ 10 21 - 341 + 301 397 @@ -475,54 +475,315 @@ Trazadores - + 0 0 - 361 - 781 + 320 + 600 - - - - - Corrientes: - - - - - 0 - 210 - 359 - 451 - + + + 320 + 600 + + + + + 300 + 600 + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAlwaysOn + + + true + + + + + 0 + -162 + 368 + 744 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + 300 + 220 + - - Cuencas: + + + 50000 + 50000 + - + - 10 - 20 - 341 + 0 + 30 + 291 + 187 + + + + + + + + + Punto de inicio de trazado de la corriente + + + Punto de inicio de trazado de la corriente + + + Ubicación + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Obtener coordenadas dando click sobre el mapa + + + Obtener coordenadas dando click sobre el mapa + + + + + + + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png + + + + + + + + + + + Coordenada en Y del punto de inicio. + + + Coordenada en Y del punto de inicio. + + + Latitud: + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + + + + + Coordenada en X del punto de inicio. + + + Coordenada en X del punto de inicio. + + + Longitud + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + + + Ruta corriente trazada (*.shp): + + + + + + + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Seleccionar la ruta donde se va a guardar la corriente. + + + Seleccionar la ruta donde se va a guardar la corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + Ejecutar la función de trazado de corriente. + + + Ejecutar la función de trazado de corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png + + + + + + + + + + + 0 + 10 + 171 + 16 + + + + + 13 + 75 + true + + + + Corrientes + + + Qt::PlainText + + + + + + + + + 250 + 500 + + + + + 50000 + 50000 + + + + + + 0 + 30 + 291 367 - + - + - + Ubicación - + Qt::Horizontal @@ -548,9 +809,9 @@ - + - + Coordenada en X del punto de inicio. @@ -578,9 +839,9 @@ - + - + Coordenada en Y del punto de inicio. @@ -608,9 +869,9 @@ - + - + Umbral mínimo para determinar red de drenaje en la cuenca @@ -639,7 +900,7 @@ - + Qt::Horizontal @@ -652,7 +913,7 @@ - + Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca @@ -694,21 +955,21 @@ - + Qt::Horizontal - + Ruta divisoria de aguas (*.shp): - + @@ -742,21 +1003,21 @@ - + Qt::Horizontal - + Ruta red hidrica (*.shp): - + @@ -793,7 +1054,7 @@ - + @@ -827,21 +1088,21 @@ - + Qt::Horizontal - + Path Salida (*.nc): - + @@ -876,190 +1137,58 @@ + + + + 0 + 10 + 171 + 16 + + + + + 13 + 75 + true + + + + Cuencas + + + Qt::PlainText + + - - - - 10 - 22 - 341 - 159 - - - - - - - - - Punto de inicio de trazado de la corriente - - - Punto de inicio de trazado de la corriente - - - Ubicación - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Obtener coordenadas dando click sobre el mapa - - - Obtener coordenadas dando click sobre el mapa - - - - - - - :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png - - - - - - - - - - - Coordenada en Y del punto de inicio. - - - Coordenada en Y del punto de inicio. - - - Latitud: - - - - - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 - - - - - - - - - - - Coordenada en X del punto de inicio. - - - Coordenada en X del punto de inicio. - - - Longitud - - - - - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 - - - - - - - - - Ruta corriente trazada (*.shp): - - - - - - - - - false - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - Seleccionar la ruta donde se va a guardar la corriente. - - - Seleccionar la ruta donde se va a guardar la corriente. - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - Ejecutar la función de trazado de corriente. - - - Ejecutar la función de trazado de corriente. - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - - - - - - + + + + + + + + + :/plugins/HydroSEDPlugin/icons/cuenca.ico:/plugins/HydroSEDPlugin/icons/cuenca.ico + + + Hidrología + + + + + 0 + 0 + 361 + 781 + + + + + + + Corrientes: + @@ -1078,59 +1207,7 @@ - - - Hidrología - - - - - 110 - 520 - 99 - 27 - - - - PushButton - - - - - - -10 - 0 - 381 - 511 - - - - true - - - - - 0 - 0 - 379 - 509 - - - - - - -10 - 0 - 381 - 131 - - - - - - - - + :/plugins/HydroSEDPlugin/icons/geomorfologia.ico:/plugins/HydroSEDPlugin/icons/geomorfologia.ico @@ -1165,7 +1242,7 @@ - + Simulación @@ -1175,13 +1252,13 @@ 10 10 341 - 400 + 800 0 - 400 + 200 @@ -1202,7 +1279,7 @@ 0 0 323 - 730 + 930 @@ -1315,7 +1392,7 @@ 0 - 300 + 500 From 7f3ab385625d2ecbf8000642de21bd1a0f59553c Mon Sep 17 00:00:00 2001 From: nicolas998 Date: Mon, 14 May 2018 23:59:35 -0500 Subject: [PATCH 031/142] Trazadores ponen corriente, cuenca y red en un directorio temporal por defecto si no se indica la carpeta y el nombre del archivo --- qgisplugin/HydroSEDPlugin.py | 8 +++++++- qgisplugin/HydroSEDPluginUtils.py | 13 +++++++------ qgisplugin/HydroSEDPlugin_dockwidget.py | 9 ++++++++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin.py b/qgisplugin/HydroSEDPlugin.py index a170728..1d5a21a 100644 --- a/qgisplugin/HydroSEDPlugin.py +++ b/qgisplugin/HydroSEDPlugin.py @@ -24,7 +24,7 @@ from PyQt4.QtGui import QAction, QIcon # Initialize Qt resources from file resources.py import resources - +import os # Import the code for the DockWidget from HydroSEDPlugin_dockwidget import HydroSEDPluginDockWidget import os.path @@ -230,4 +230,10 @@ def run(self): # TODO: fix to allow choice of dock location self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget) self.dockwidget.show() + + #Crea un directorio temporal + try: + os.makedirs('/tmp/HydroSED') + except: + pass diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 762525c..f0b87d5 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -9,13 +9,16 @@ class controlHS: TIPO_STYLE_POLIGONO = 1 TIPO_STYLE_POLILINEA = 2 - + def __init__(self): self.DEM = 0 self.DIR = 0 self.xll = 0 self.yll = 0 self.nodata = 0 + self.BasinsCount = 0 + self.StreamsCount = 0 + def cargar_mapa_raster (self,pathMapaRaster): @@ -117,12 +120,10 @@ def trazador_cuenca(self,x,y, dxp,umbral,PathDiv, PathRed, PathNC,PathDEM, PathD else: self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR) # Guarda los shapes de divisoria y de red hidrica. - if len(PathDiv)>2: - self.cuenca.Save_Basin2Map(PathDiv, dxp) - if len(PathRed)>2: - self.cuenca.Save_Net2Map(PathRed, dxp, umbral) + self.cuenca.Save_Basin2Map(PathDiv, dxp) + self.cuenca.Save_Net2Map(PathRed, dxp, umbral) # Guarda el nc de la cuenca if len(PathNC)>2: - self.cuenca.Save_SimuBasin(PathNC,PathDEM, PathDIR) + self.cuenca.Save_SimuBasin(PathNC,ruta_dem = PathDEM, ruta_dir = PathDIR) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 955742a..8a6f092 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -82,6 +82,9 @@ def handleClickEventEjecutarTrazadorCorrientes (self): #Traza la corriente y = self.spinBoxLatitudTrazadorCorrientes.value () x = self.spinBoxLongitudTrazadorCorrientes.value () + #Camino a los temporales + if len(self.PathCorriente_out.text()) == 0: + self.PathCorriente_out.setText('/tmp/HydroSED/Corriente.shp') OutPath = self.PathCorriente_out.text() try: self.HSutils.trazador_corriente(x,y, OutPath) @@ -98,11 +101,15 @@ def handleClickEventEjecutarTrazadorCuencas (self): #Obtiene coordenadas y = self.spinBoxLatitudTrazadorCuencas.value () x = self.spinBoxLongitudTrazadorCuencas.value () + #Camino a los temporales + if len(self.PathOutputDivisoria.text()) == 0: + self.PathOutputDivisoria.setText('/tmp/HydroSED/Cuenca.shp') + if len(self.PathOutputRed.text()) == 0: + self.PathOutputRed.setText('/tmp/HydroSED/Cuenca_Red.shp') #Paths para guardar la cuenca OutPathDivisoria = self.PathOutputDivisoria.text() OutPathRed = self.PathOutputRed.text() OutPathNC = self.PathOutputNETCDF.text() - #try: #Traza la cuenca self.HSutils.trazador_cuenca(x,y, self.spinBox_dxPlano.value(), self.spinBoxUmbralRed.value(),OutPathDivisoria, OutPathRed, OutPathNC, self.lineEditMapaDEM, From dc0bf5c33ec5255a0d9df9825466404fc4dbe407 Mon Sep 17 00:00:00 2001 From: nicolas998 Date: Tue, 15 May 2018 22:21:22 -0500 Subject: [PATCH 032/142] =?UTF-8?q?se=20comienza=20a=20hacer=20el=20dise?= =?UTF-8?q?=C3=B1o=20del=20balance=20de=20largo=20plazo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 197 +++++++++++++++---- 1 file changed, 158 insertions(+), 39 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index fcbcbe4..109f4c1 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -6,12 +6,12 @@ 0 0 - 343 + 360 839 - + 0 0 @@ -27,7 +27,7 @@ - 1 + 2 @@ -480,7 +480,7 @@ 0 0 - 320 + 331 600 @@ -492,8 +492,8 @@ - 300 - 600 + 50000 + 50000 @@ -509,8 +509,8 @@ 0 - -162 - 368 + 0 + 318 744 @@ -546,7 +546,7 @@ 0 30 - 291 + 301 187 @@ -768,7 +768,7 @@ 0 30 - 291 + 301 367 @@ -1174,37 +1174,155 @@ Hidrología - + 0 0 - 361 - 781 + 331 + 600 - - - - - Corrientes: - - - - - 10 - 190 - 341 - 20 - - - - Qt::Horizontal - - - - - + + + 320 + 600 + + + + true + + + + + 0 + 0 + 329 + 598 + + + + + + 0 + 10 + 311 + 200 + + + + + 0 + 200 + + + + + 16777215 + 16777215 + + + + Balance Largo Plazo + + + + + + + + + + Lluvia + + + + + + + false + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + ETR + + + + + + + false + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + Choudry + + + + + + + Cenicafe + + + + + + + Turc + + + + + + + Map + + + + + + + + + + @@ -1252,7 +1370,7 @@ 10 10 341 - 800 + 400 @@ -1306,7 +1424,7 @@ 16777215 - 100 + 16777215 @@ -1337,7 +1455,7 @@ 16777215 - 300 + 16777215 @@ -1398,7 +1516,7 @@ 16777215 - 300 + 16777215 @@ -1466,6 +1584,7 @@ + From b9b7ed2488c9972477e833414fe3ea30e1a2cb2e Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 12 Jun 2018 09:44:16 -0500 Subject: [PATCH 033/142] cambios en la interfaz grafica y se pone el primer prototipo de como sera la interfaz para la funcion de balance --- qgisplugin/HydroSEDPlugin_dockwidget.py | 24 +- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 3344 +++++++++++------- 2 files changed, 1983 insertions(+), 1385 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 8a6f092..cb78feb 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -130,37 +130,33 @@ def handleClickEventEjecutarTrazadorCuencas (self): #except: # pass + def setupHidro_Balance(self): + + + def setupUIInputsOutputs (self): def setupLineEditButtonOpenShapeFileDialog (lineEditHolder, fileDialogHolder): - -# lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Shapefiles (*.shp);;")) + '''Hace que cuando se busquen shapes solo se encuetren formatos vectoriales''' lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Shapefiles (*.shp);;")) - if ((os.path.exists (lineEditHolder.text ().strip ())) and (not (self.iface is None))): - self.iface.addVectorLayer (lineEditHolder.text ().strip (), os.path.basename (lineEditHolder.text ()).strip (), "ogr") def setupLineEditButtonOpenRasterFileDialog (lineEditHolder, fileDialogHolder): - -# lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), 'Open File',"", "*", -# QtGui.QFileDialog.DontUseNativeDialog)) - + '''Hace que solo0 se busquen formatos aceptados por GDAL''' lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), 'Open File',"", GdalTools_utils.FileFilter.allRastersFilter (), QtGui.QFileDialog.DontUseNativeDialog)) - def setupLineEditButtonOpenFileDialog (lineEditHolder, fileDialogHolder): - + '''Pone la ruta elegida en el dialogo de texto para cargar''' lineEditHolder.setText (fileDialogHolder.getOpenFileName ()) def setupLineEditButtonSaveFileDialog (lineEditHolder, fileDialogHolder): - + '''Pone la ruta elegida en el dialogo de texto para guardado''' lineEditHolder.setText (fileDialogHolder.getSaveFileName ()) def clickEventSelectorMapaDEM (): - -# setupLineEditButtonOpenFileDialog (self.lineEditMapaDEM, QFileDialog) + '''Evento de click: selecciona mapa DEM''' setupLineEditButtonOpenRasterFileDialog (self.lineEditMapaDEM, QFileDialog) def clickEventSelectorMapaDIR (): @@ -265,7 +261,7 @@ def clickEventSelectorOutputCuencaNCTrazadorCuencas (): self.Boton_MDE2WMF.clicked.connect (clickEventCargarWMFMapaDEM) self.Boton_DIR2WMF.clicked.connect (clickEventCargarWMFMapaDIR) - self.botonSelectorBinarioNC.clicked.connect (clickEventSelectorBinarioNC) + #self.botonSelectorBinarioNC.clicked.connect (clickEventSelectorBinarioNC) #Botones para establecer la ruta de guardado del terazador de corrientes yd e cuencas self.botonSelectorOutputCorrienteShapefileTrazadorCorrientes.clicked.connect (clickEventSelectorOutputCorrienteShapefileTrazadorCorrientes) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 109f4c1..42e2c28 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -6,12 +6,12 @@ 0 0 - 360 - 839 + 458 + 936 - + 0 0 @@ -20,1194 +20,1958 @@ 0.500000000000000 - Hydro-SED + HidroSIG 5.0 - - - 2 - - - - - :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png - - - - - - - - 0 - 0 - 321 - 781 - - - - - - - Configuración General - - - - - 0 - 500 - 381 - 281 - - - - Explorador Binarios *.nc - - - - - 10 - 31 - 361 - 361 - - - - - - - <html><head/><body><p>Seleccionar ruta al archivo .nc con la topología de la cuenca.</p></body></html> - - - <html><head/><body><p>Seleccionar ruta al archivo .nc con la topología de la cuenca.</p></body></html> - - - Path Archivos Binarios *.nc - - - - - - - - - - 150 - 16777215 - - - - true - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - - - - - Variables archivo de cuenca .nc - - - - - - - - - - - - 10 - 400 - 341 - 41 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Cargar Variable - - - - - - - - - - 10 - 21 - 301 - 397 - - - - - - - <html><head/><body><p>Dirección al MDE (modelo digital de elevación), este se usa como base para un proyecto.</p></body></html> - - - <html><head/><body><p>Dirección al MDE (modelo digital de elevación), este se usa como base para un proyecto.</p></body></html> - - - Mapa MDE: - - - - - - - - - - 100 - 20 - - - - - 290 - 16777215 - - - - true - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 100 - 16777215 - - - - <html><head/><body><p>Carga el MDE en el layout de mapas de Qgis.</p></body></html> - - - Visualizar - - - - - - - - 100 - 16777215 - - - - <html><head/><body><p>Establece el MDE y sus propiedades como el mapa base para WMF.</p></body></html> - - - Cargar - - - - - - - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - Mapa DIR: - - - - - - - - - - 290 - 16777215 - - - - true - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 100 - 16777215 - - - - <html><head/><body><p>Carga el DIR en el layout de mapas de Qgis.</p></body></html> - - - Visualizar - - - - - - - - 100 - 16777215 - - - - <html><head/><body><p>Establece el DIR y sus propiedades como el mapa base para WMF.</p></body></html> - - - Cargar - - - - - - - - - - - - - - Valor en metros del tamano de una celda en el mapa. - - - Valor en metros del tamano de una celda en el mapa. - - - Qt::LeftToRight - - - Valor Dxp [m] - - - - - - - - 100 - 0 - - - - - 150 - 16777215 - - - - 10000.000000000000000 - - - 12.699999999999999 - - - - - - - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - Propiedades mapas - - - - - - - - labelDIR_2 - labelDEM - labelDIR - Tabla_PropMDE - - - - - - - - - - :/plugins/HydroSEDPlugin/icons/cuenca.ico:/plugins/HydroSEDPlugin/icons/cuenca.ico - - - Trazadores - - - - - 0 - 0 - 331 - 600 - - - - - 320 - 600 - - + + + - 50000 - 50000 + 16777215 + 100 - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAlwaysOn + + Proyecto de Cuenca - - true - - + - 0 - 0 - 318 - 744 + 10 + 20 + 421 + 81 - - - 0 - 0 - - - - - 16777215 - 16777215 - - - + + + + + + + Ruta + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + Carga el proyecto cuenca a WMF, de manera que puede ser usada para operar con ella. + + + Cargar a WMF + + + + + - - - - 300 - 220 - - - - - 50000 - 50000 - - - - - - 0 - 30 - 301 - 187 - - - - - + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + + 100 + 16777215 + + + + <html><head/><body><p>Carga el MDE en el layout de mapas de Qgis.</p></body></html> + + + Carga el shp de la divisoria del proyecto de cuenca. + + + Ver Divisoria + + + + + + + false + + + + 100 + 16777215 + + + + <html><head/><body><p>Carga el MDE en el layout de mapas de Qgis.</p></body></html> + + + Carga la red hídrica del proyecto cuenca cargado. + + + Ver Red + + + + + + + + + + + + + QFrame::Raised + + + 4 + + + 2 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + 2 + + + + + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png + + + + + + + + 0 + 0 + 430 + 730 + + + + + 430 + 400 + + + + + 50000 + 50000 + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + true + + + + + 0 + 0 + 412 + 1918 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + 300 + 750 + + + + + 50000 + 50000 + + + + + + 0 + 0 + 391 + 471 + + + + + QLayout::SetMinimumSize + - + - Punto de inicio de trazado de la corriente + <html><head/><body><p>Dirección al MDE (modelo digital de elevación), este se usa como base para un proyecto.</p></body></html> - Punto de inicio de trazado de la corriente + <html><head/><body><p>Dirección al MDE (modelo digital de elevación), este se usa como base para un proyecto.</p></body></html> - Ubicación + Mapa MDE: - - - Qt::Horizontal - - - - 40 - 20 - - - + + + + + + 100 + 20 + + + + + 290 + 16777215 + + + + true + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + 100 + 16777215 + + + + <html><head/><body><p>Establece el MDE y sus propiedades como el mapa base para WMF.</p></body></html> + + + Cargar + + + + - - - Obtener coordenadas dando click sobre el mapa - - - Obtener coordenadas dando click sobre el mapa - - - - - - - :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png - - + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 16777215 + + + + <html><head/><body><p>Carga el MDE en el layout de mapas de Qgis.</p></body></html> + + + Visualizar + + + + - - - - - + - Coordenada en Y del punto de inicio. + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Coordenada en Y del punto de inicio. + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Latitud: + Mapa DIR: - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 - - + + + + + + 290 + 16777215 + + + + true + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + 100 + 16777215 + + + + <html><head/><body><p>Establece el DIR y sus propiedades como el mapa base para WMF.</p></body></html> + + + Cargar + + + + - - - - - - - Coordenada en X del punto de inicio. - - - Coordenada en X del punto de inicio. - - - Longitud - - + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 16777215 + + + + <html><head/><body><p>Carga el DIR en el layout de mapas de Qgis.</p></body></html> + + + Visualizar + + + + - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 - - + - - - - - - Ruta corriente trazada (*.shp): - - - - - - - - false - - + + + + + Valor en metros del tamano de una celda en el mapa. + + + Valor en metros del tamano de una celda en el mapa. + + + Qt::LeftToRight + + + Valor Dxp [m] + + + + + + + + 100 + 0 + + + + + 150 + 16777215 + + + + 10000.000000000000000 + + + 12.699999999999999 + + + + - - - - 30 - 0 - - - - - 30 - 16777215 - - + - Seleccionar la ruta donde se va a guardar la corriente. + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Seleccionar la ruta donde se va a guardar la corriente. + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + Propiedades mapas - - - Ejecutar la función de trazado de corriente. - - - Ejecutar la función de trazado de corriente. - - - - - - - :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png - - + - - - - - - - 0 - 10 - 171 - 16 - - - - - 13 - 75 - true - - - - Corrientes - - - Qt::PlainText - - - - - - - - - 250 - 500 - - - - - 50000 - 50000 - - - - - - 0 - 30 - 301 - 367 - - - - - - - - - Ubicación - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - + labelDIR_2 + labelDEM + labelDIR + Tabla_PropMDE + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/cuenca.ico:/plugins/HydroSEDPlugin/icons/cuenca.ico + + + Trazadores + + + + + 0 + 0 + 430 + 730 + + + + + 430 + 400 + + + + + 50000 + 50000 + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + true + + + + + 0 + -16 + 412 + 744 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + 300 + 220 + + + + + 50000 + 50000 + + + + + + 0 + 30 + 381 + 187 + + + - - - - - - - :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png - - + + + + + Punto de inicio de trazado de la corriente + + + Punto de inicio de trazado de la corriente + + + Ubicación + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Obtener coordenadas dando click sobre el mapa + + + Obtener coordenadas dando click sobre el mapa + + + + + + + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png + + + + - - - - - - - Coordenada en X del punto de inicio. - - - Coordenada en X del punto de inicio. - - - Latitud: - - + + + + + Coordenada en Y del punto de inicio. + + + Coordenada en Y del punto de inicio. + + + Latitud: + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 - - + + + + + Coordenada en X del punto de inicio. + + + Coordenada en X del punto de inicio. + + + Longitud + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + - - - - - - - Coordenada en Y del punto de inicio. - - - Coordenada en Y del punto de inicio. - + - Longitud - - - - - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 + Ruta corriente trazada (*.shp): + + + + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Seleccionar la ruta donde se va a guardar la corriente. + + + Seleccionar la ruta donde se va a guardar la corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + Ejecutar la función de trazado de corriente. + + + Ejecutar la función de trazado de corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png + + + + + - - - + + + + + 0 + 10 + 171 + 16 + + + + + 13 + 75 + true + + + + Corrientes + + + Qt::PlainText + + + + + + + + + 250 + 500 + + + + + 50000 + 50000 + + + + + + 0 + 30 + 381 + 367 + + + + + QLayout::SetMinimumSize + - - - Umbral mínimo para determinar red de drenaje en la cuenca - - - Umbral mínimo para determinar red de drenaje en la cuenca - - - Umbral - - + + + + + Ubicación + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png + + + + - - - 0 - - - 10.000000000000000 - - - 100000.000000000000000 - - - 100.000000000000000 - - + + + + + Coordenada en X del punto de inicio. + + + Coordenada en X del punto de inicio. + + + Latitud: + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + - - - Qt::Horizontal - - - - 40 - 20 - - - + + + + + Coordenada en Y del punto de inicio. + + + Coordenada en Y del punto de inicio. + + + Longitud + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + - - - Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca - - - Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca - - - Ultima corriente - - + + + + + Umbral mínimo para determinar red de drenaje en la cuenca + + + Umbral mínimo para determinar red de drenaje en la cuenca + + + Umbral + + + + + + + 0 + + + 10.000000000000000 + + + 100000.000000000000000 + + + 100.000000000000000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca + + + Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca + + + Ultima corriente + + + + + + + Si usar o no usar ultima corriente + + + Si usar o no usar ultima corriente + + + + + + true + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + - - - Si usar o no usar ultima corriente - - - Si usar o no usar ultima corriente - - - - - - true + + + Qt::Horizontal - + - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + Ruta divisoria de aguas (*.shp): - - - - - - Qt::Horizontal - - - - - - - Ruta divisoria de aguas (*.shp): - - - - - - - - false - - + + + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + - - - - 30 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + Qt::Horizontal - - - - - - Qt::Horizontal - - - - - - - Ruta red hidrica (*.shp): - - - - - - - - Obtiene automaticamente los nodos topograficos. - - - Obtiene automaticamente los nodos topograficos. - + - Topo Nodes + Ruta red hidrica (*.shp): - - - Obtiene parametros geomorfologicos de la cuenca. - - - GetGeo - - + + + + + Obtiene automaticamente los nodos topograficos. + + + Obtiene automaticamente los nodos topograficos. + + + Topo Nodes + + + + + + + Obtiene parametros geomorfologicos de la cuenca. + + + GetGeo + + + + + + + Obtiene el ancho del canal en cada tramo. + + + Ancho canal + + + + - - - Obtiene el ancho del canal en cada tramo. - - - Ancho canal - - + + + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + - - - - - - - false + + + Qt::Horizontal - - - - 30 - 0 - - - - - 30 - 16777215 - - + - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + Path Salida (*.nc): - - - - - - Qt::Horizontal - - - - - - - Path Salida (*.nc): - - - - - - - - false - - + + + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + 0 + 10 + 171 + 16 + + + + + 13 + 75 + true + + + + Cuencas + + + Qt::PlainText + + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/cuenca.ico:/plugins/HydroSEDPlugin/icons/cuenca.ico + + + Hidrología + + + + + 0 + 0 + 430 + 730 + + + + + 430 + 400 + + + + + 50000 + 50000 + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + true + + + + + 0 + 0 + 412 + 1918 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + 300 + 1900 + + + + + 50000 + 50000 + + + + + + 0 + 0 + 395 + 290 + + + + + 0 + 290 + + + + + 16777215 + 16777215 + + + + Balance Largo Plazo + + + false + + - - - - 30 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - + + + + + Qt::Horizontal + + + + + + + + 0 + 10 + + + + Datos de entrada: + + + + + + + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Lluvia* [mm/año] + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + false + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + Estimación de la evaporación anual (mm/año), seleccionar metodología o cargar mapa. + + + ETR [mm/año] + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + false + + + false + + + + + + + false + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + Metodología de cálculo Choudry. + + + Choudry + + + + + + + Metodología de cálculo Cenicafe. + + + Cenicafe + + + true + + + + + + + Metodología de cálculo Turc. + + + Turc + + + false + + + + + + + Cargar ETR de un mapa o un valor constante. + + + Map + + + + + + + + + Qt::Horizontal + + + + + + + Resultados: + + + Qt::AutoText + + + + + + + + + Qmed*[m3/s] + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + false + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + false + + + + 40 + 16777215 + + + + Ver + + + + + + + + + + + Escorrentía [mm] + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + false + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + false + + + + 40 + 16777215 + + + + Ver + + + + + + + + + + + ETR [mm/año] + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + false + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + false + + + + 40 + 16777215 + + + + Ver + + + + + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + false + + + + + + + Ejecutar + + + + + + - - - - - - - 0 - 10 - 171 - 16 - - - - - 13 - 75 - true - - - - Cuencas - - - Qt::PlainText - - - - - + + + + + + - - - - - - :/plugins/HydroSEDPlugin/icons/cuenca.ico:/plugins/HydroSEDPlugin/icons/cuenca.ico - - - Hidrología - - - - - 0 - 0 - 331 - 600 - - - - - 320 - 600 - - - - true - - - - - 0 - 0 - 329 - 598 - - - + + + + :/plugins/HydroSEDPlugin/icons/geomorfologia.ico:/plugins/HydroSEDPlugin/icons/geomorfologia.ico + + + Geomorfología + + 0 + 0 + 430 + 730 + + + + + 430 + 400 + + + + + 50000 + 50000 + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + true + + + + + 0 + 0 + 412 + 1918 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + 300 + 1900 + + + + + 50000 + 50000 + + + + + + 0 + 0 + 395 + 200 + + + + + 0 + 200 + + + + + 16777215 + 16777215 + + + + Parametros basicos geomorfologicos + + + false + + + + + + + + + + Lluvia + + + + + + + false + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + ETR + + + + + + + false + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + Choudry + + + + + + + Cenicafe + + + + + + + Turc + + + + + + + Map + + + + + + + + + + + + + + + + + + Simulación + + + + + 10 10 - 311 - 200 + 341 + 400 @@ -1219,358 +1983,197 @@ 16777215 - 16777215 + 400 - - Balance Largo Plazo + + Qt::ScrollBarAlwaysOn + + + true - - - - - + + + + 0 + 0 + 323 + 930 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + 0 + 100 + + + + + 16777215 + 16777215 + + + + Grupo 1 + + - + - Lluvia + TextLabel - - - false - - + + + + + + + + + 0 + 300 + + + + + 16777215 + 16777215 + + + + Grupo 2 + + - + - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + TextLabel - - - - - + + + + - ETR + TextLabel - - - false + + + + + + TextLabel - + + + + - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + TextLabel + + + - - - + + + + + + + 0 + 500 + + + + + 16777215 + 16777215 + + + + Grupo 3 + + - + - Choudry + TextLabel - + + + + - Cenicafe + TextLabel - + + + + - Turc + TextLabel - + + + + - Map + TextLabel + + + - - - - + + + + - - - - - :/plugins/HydroSEDPlugin/icons/geomorfologia.ico:/plugins/HydroSEDPlugin/icons/geomorfologia.ico - - - Geomorfología - - - - - 110 - 50 - 99 - 27 - - - - PushButton - - - - - - 130 - 100 - 99 - 27 - - - - PushButton - - - - - - Simulación - - - - - 10 - 10 - 341 - 400 - - - - - 0 - 200 - - - - - 16777215 - 400 - - - - Qt::ScrollBarAlwaysOn - - - true - - - - - 0 - 0 - 323 - 930 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - - - - 0 - 100 - - - - - 16777215 - 16777215 - - - - Grupo 1 - - - - - - TextLabel - - - - - - - - - - - - - - 0 - 300 - - - - - 16777215 - 16777215 - - - - Grupo 2 - - - - - - TextLabel - - - - - - - - - - TextLabel - - - - - - - - - - TextLabel - - - - - - - - - - TextLabel - - - - - - - - - - - - - - 0 - 500 - - - - - 16777215 - 16777215 - - - - Grupo 3 - - - - - - TextLabel - - - - - - - - - - TextLabel - - - - - - - - - - TextLabel - - - - - - - - - - TextLabel - - - - - - - - - - - - - - + + @@ -1584,7 +2187,6 @@ - From 2c39261e9ff29d9b3cce1976a3074d44efab9869 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 12 Jun 2018 10:56:07 -0500 Subject: [PATCH 034/142] ya funciona la funcion de balance de largo plazo --- qgisplugin/HydroSEDPluginUtils.py | 15 ++- qgisplugin/HydroSEDPlugin_dockwidget.py | 70 ++++++++-- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 131 ++++++++++--------- 3 files changed, 148 insertions(+), 68 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index f0b87d5..980abb2 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -126,4 +126,17 @@ def trazador_cuenca(self,x,y, dxp,umbral,PathDiv, PathRed, PathNC,PathDEM, PathD if len(PathNC)>2: self.cuenca.Save_SimuBasin(PathNC,ruta_dem = PathDEM, ruta_dir = PathDIR) - + def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed): + #Se fija si la lluvia es un path o un valor + try: + Rain = float(PathRain) + except: + Rain, prop = wmf.Butto_Ejec_HidroBalance(PathRain) + Rain = self.cuenca.Transform_Map2Basin(Rain, Path) + #Realiza el balance + self.cuenca.GetQ_Balance(Rain, Tipo_ETR = PathETR) + # Guarda el resultado + if len(PathQmed)>2: + self.cuenca.Save_Net2Map(PathQmed, dxp, umbral, qmed = self.cuenca.CellQmed) + #Retorna el resultado a la salida + return self.cuenca.CellQmed[-1] diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index cb78feb..2dc0f3a 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -55,6 +55,7 @@ def __init__(self, iface = None, parent=None): # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.setupUIInputsOutputs () + self.setupHidro_Balance() #self.setupUIButtonEvents () if not (iface is None): @@ -93,7 +94,7 @@ def handleClickEventEjecutarTrazadorCorrientes (self): self.iface.mapCanvas().refresh() self.iface.legendInterface().refreshLayerSymbology(layer) - self.iface.messageBar().pushInfo(u'Hydro-SED',u'Se ha trazado la corriente de forma exitosa') + self.iface.messageBar().pushInfo(u'HidroSIG',u'Se ha trazado la corriente de forma exitosa') except: pass @@ -126,14 +127,67 @@ def handleClickEventEjecutarTrazadorCuencas (self): self.iface.legendInterface().refreshLayerSymbology(layer) #mensaje de exito - self.iface.messageBar().pushInfo(u'Hydro-SED',u'Se ha trazado la cuenca de forma exitosa') + self.iface.messageBar().pushInfo(u'HidroSIG',u'Se ha trazado la cuenca de forma exitosa') #except: # pass def setupHidro_Balance(self): - - - + + def setupLineEditButtonOpenRasterFileDialog (lineEditHolder, fileDialogHolder): + '''Hace que solo se busquen formatos aceptados por GDAL''' + lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), 'Open File',"", GdalTools_utils.FileFilter.allRastersFilter (), + QtGui.QFileDialog.DontUseNativeDialog)) + def setupLineEditButtonSaveFileDialog (lineEditHolder, fileDialogHolder): + '''Pone la ruta elegida en el dialogo de texto para guardado''' + lineEditHolder.setText (fileDialogHolder.getSaveFileName ()) + + #Funciones para Cargar variables + def clickEventSelectorRaster(): + '''click para seleccionar el raster de lluvia''' + setupLineEditButtonOpenRasterFileDialog(self.PathInHydro_Rain, QFileDialog) + + #Funciones para decir donde se van a guardar las variables. + def clickEventOutQmed(): + '''Habilita la ruta para decir donde se va a guardar la variable de caudal medio''' + setupLineEditButtonSaveFileDialog(self.PathOutHydro_Qmed, QFileDialog) + def clickEventOutRunoff(): + '''Habilita la ruta para decir donde se va a guardar la variable de caudal medio''' + setupLineEditButtonSaveFileDialog(self.PathOutHydro_Runoff, QFileDialog) + def clickEventOutETR(): + '''Habilita la ruta para decir donde se va a guardar la variable de caudal medio''' + setupLineEditButtonSaveFileDialog(self.PathOutHydro_ETR, QFileDialog) + + #Funciones para el calculo de balance + def hadleClickEventEjecutarBalance(): + '''Hace el balance hidrologico una ves que se da click en el boton: Butto_Ejec_HidroBalance''' + #Selecciona el tipo de etr + if self.RadioBalance_ETR_Choudry.isChecked(): + TipoETR = 3 + if self.RadioBalance_ETR_Cenicafe.isChecked(): + TipoETR = 2 + if self.RadioBalance_ETR_Turc.isChecked(): + TipoETR = 1 + #Invoca la funcion + QSalida = self.HSutils.hidologia_balance(self.spinBox_dxPlano.value(), + self.spinBoxUmbralRed.value(), + self.PathInHydro_Rain.text(), + TipoETR, + self.PathOutHydro_Qmed.text()) + #Pone el valor de cadual medio en el cuadro + textoCaudal = '%.3f' % Qsalida + self.ShowResultQmed.setText(textoCaudal) + #Mensaje de exito + self.iface.messageBar().pushInfo(u'HidroSIG:',u'Se ha realizado el balance de caudal con exito.') + + #Botones para variables de entrada + self.Boton_HidroLoadRain.clicked.connect(clickEventSelectorRaster) + #Botones para variables de salida + self.Button_HidroSaveQmed.clicked.connect(clickEventOutQmed) + self.Button_HidroSaveRunoff.clicked.connect(clickEventOutRunoff) + self.Button_HidroSaveETR.clicked.connect(clickEventOutETR) + #Botones para ejecutar + self.Butto_Ejec_HidroBalance.clicked.connect(hadleClickEventEjecutarBalance) + def setupUIInputsOutputs (self): def setupLineEditButtonOpenShapeFileDialog (lineEditHolder, fileDialogHolder): @@ -148,15 +202,15 @@ def setupLineEditButtonOpenRasterFileDialog (lineEditHolder, fileDialogHolder): QtGui.QFileDialog.DontUseNativeDialog)) def setupLineEditButtonOpenFileDialog (lineEditHolder, fileDialogHolder): - '''Pone la ruta elegida en el dialogo de texto para cargar''' + '''Pone la ruta elegida en el dialogo de texto para cargar''' lineEditHolder.setText (fileDialogHolder.getOpenFileName ()) def setupLineEditButtonSaveFileDialog (lineEditHolder, fileDialogHolder): - '''Pone la ruta elegida en el dialogo de texto para guardado''' + '''Pone la ruta elegida en el dialogo de texto para guardado''' lineEditHolder.setText (fileDialogHolder.getSaveFileName ()) def clickEventSelectorMapaDEM (): - '''Evento de click: selecciona mapa DEM''' + '''Evento de click: selecciona mapa DEM''' setupLineEditButtonOpenRasterFileDialog (self.lineEditMapaDEM, QFileDialog) def clickEventSelectorMapaDIR (): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 42e2c28..1d21298 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -1405,14 +1405,14 @@ - + false - + @@ -1450,50 +1450,12 @@ - - - false - - - false - - - - - - - false - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - - - - Metodología de cálculo Choudry. - - - Choudry - - - - - + - Metodología de cálculo Cenicafe. + Metodología de cálculo Turc. - Cenicafe + Turc true @@ -1501,12 +1463,12 @@ - + - Metodología de cálculo Turc. + Metodología de cálculo Cenicafe. - Turc + Cenicafe false @@ -1514,17 +1476,20 @@ - + - Cargar ETR de un mapa o un valor constante. + Metodología de cálculo Choudry. - Map + Choudry + + + @@ -1546,6 +1511,9 @@ + + El valor del caudal calculado en cada tramo hidrológico. + Qmed*[m3/s] @@ -1565,14 +1533,17 @@ - + + + Ruta de guardado + false - + @@ -1583,7 +1554,7 @@ - + false @@ -1593,6 +1564,9 @@ 16777215 + + Visualizar shp con el caudal calculado por tramos. + Ver @@ -1604,6 +1578,9 @@ + + El valor de la escorrentía como un mapa Raster + Escorrentía [mm] @@ -1623,14 +1600,17 @@ - + + + Ruta de guardado + false - + @@ -1641,7 +1621,7 @@ - + false @@ -1651,6 +1631,9 @@ 16777215 + + Visualizar raster con la escorrentia calculada. + Ver @@ -1662,6 +1645,9 @@ + + El valor de la evaporacion estimada como un Raster + ETR [mm/año] @@ -1681,14 +1667,17 @@ - + + + Ruta de guardado + false - + @@ -1699,7 +1688,7 @@ - + false @@ -1709,6 +1698,9 @@ 16777215 + + Visualizar raster con la ETR calculada. + Ver @@ -1716,8 +1708,25 @@ + + + + Qt::Horizontal + + + + + + + El valor del caudal calculado solo a la salida de la cuenca. + + + Q salida [m3/s]: + + + @@ -1734,12 +1743,15 @@ - false + true + + Ejecuta el balance de largo plazo con los parametros dados. + Ejecutar @@ -2187,6 +2199,7 @@ + From e8d58d4b1b4921a8d560394cb2dad1b3efe88c48 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 12 Jun 2018 15:40:48 -0500 Subject: [PATCH 035/142] Funcion de balance a largo plazo trabajando full, solo le faltan correcciones menores --- qgisplugin/HydroSEDPluginUtils.py | 16 ++-- qgisplugin/HydroSEDPlugin_dockwidget.py | 46 ++++++++++-- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 78 +++++++++++++++++--- 3 files changed, 119 insertions(+), 21 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 980abb2..80765f1 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -126,17 +126,23 @@ def trazador_cuenca(self,x,y, dxp,umbral,PathDiv, PathRed, PathNC,PathDEM, PathD if len(PathNC)>2: self.cuenca.Save_SimuBasin(PathNC,ruta_dem = PathDEM, ruta_dir = PathDIR) - def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed): + def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed, PathETROUT, PathRunoff): #Se fija si la lluvia es un path o un valor try: Rain = float(PathRain) except: - Rain, prop = wmf.Butto_Ejec_HidroBalance(PathRain) - Rain = self.cuenca.Transform_Map2Basin(Rain, Path) + Rain, prop = wmf.read_map_raster(PathRain) + Rain = self.cuenca.Transform_Map2Basin(Rain, prop) #Realiza el balance self.cuenca.GetQ_Balance(Rain, Tipo_ETR = PathETR) # Guarda el resultado if len(PathQmed)>2: self.cuenca.Save_Net2Map(PathQmed, dxp, umbral, qmed = self.cuenca.CellQmed) - #Retorna el resultado a la salida - return self.cuenca.CellQmed[-1] + if len(PathETROUT)>2: + self.cuenca.Transform_Basin2Map(self.cuenca.CellETR, PathETROUT) + if len(PathRunoff)>2: + Runoff = Rain - self.cuenca.CellETR + self.cuenca.Transform_Basin2Map(Runoff, PathRunoff) + + #Retorna el resultado a la salida + return self.cuenca.CellQmed[-1] diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 2dc0f3a..0254b88 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -144,7 +144,27 @@ def setupLineEditButtonSaveFileDialog (lineEditHolder, fileDialogHolder): #Funciones para Cargar variables def clickEventSelectorRaster(): '''click para seleccionar el raster de lluvia''' + #Pone el texto de la ruta setupLineEditButtonOpenRasterFileDialog(self.PathInHydro_Rain, QFileDialog) + #Habilita visualizarlo + if len(self.PathInHydro_Rain.text())>2: + self.Button_HidroViewRain.setEnabled(True) + + #Funciones para visualizar variables + def clickEventViewRainfall(): + pathMapaRain = self.PathInHydro_Rain.text().strip() + flagCargaMapaRain = self.HSutils.cargar_mapa_raster(pathMapaRain) + def clickEventViewETR(): + pathMapaETR = self.PathOutHydro_ETR.text().strip() + flagCargaMapaRain = self.HSutils.cargar_mapa_raster(pathMapaETR) + def clickEventViewRunoff(): + pathMapaRain = self.PathOutHydro_Runoff.text().strip() + flagCargaMapaRain = self.HSutils.cargar_mapa_raster(pathMapaRain) + def clickEventViewQmedNetwork(): + OutPathRed = self.PathOutHydro_Qmed.text().strip() + ret, layer = self.HSutils.cargar_mapa_vector(OutPathRed, self.HSutils.TIPO_STYLE_POLILINEA, width = 0.4) + self.iface.mapCanvas().refresh() + self.iface.legendInterface().refreshLayerSymbology(layer) #Funciones para decir donde se van a guardar las variables. def clickEventOutQmed(): @@ -172,12 +192,21 @@ def hadleClickEventEjecutarBalance(): self.spinBoxUmbralRed.value(), self.PathInHydro_Rain.text(), TipoETR, - self.PathOutHydro_Qmed.text()) - #Pone el valor de cadual medio en el cuadro - textoCaudal = '%.3f' % Qsalida - self.ShowResultQmed.setText(textoCaudal) - #Mensaje de exito - self.iface.messageBar().pushInfo(u'HidroSIG:',u'Se ha realizado el balance de caudal con exito.') + self.PathOutHydro_Qmed.text(), + self.PathOutHydro_ETR.text(), + self.PathOutHydro_Runoff.text()) + #Pone el valor de cadual medio en el cuadro + textoCaudal = '%.3f' % QSalida + self.ShowResultQmed.setText(textoCaudal) + #Mensaje de exito + self.iface.messageBar().pushInfo(u'HidroSIG:',u'Se ha realizado el balance de caudal con exito.') + #Habilita botones de visualizacion de variables + if len(self.PathOutHydro_Qmed.text()) > 2: + self.Button_HidroViewQmed.setEnabled(True) + if len(self.PathOutHydro_Runoff.text()) > 2: + self.Button_HidroViewRunoff.setEnabled(True) + if len(self.PathOutHydro_ETR.text()) > 2: + self.Button_HidroViewETR.setEnabled(True) #Botones para variables de entrada self.Boton_HidroLoadRain.clicked.connect(clickEventSelectorRaster) @@ -185,6 +214,11 @@ def hadleClickEventEjecutarBalance(): self.Button_HidroSaveQmed.clicked.connect(clickEventOutQmed) self.Button_HidroSaveRunoff.clicked.connect(clickEventOutRunoff) self.Button_HidroSaveETR.clicked.connect(clickEventOutETR) + #Botones para visualizar variables + self.Button_HidroViewRain.clicked.connect(clickEventViewRainfall) + self.Button_HidroViewQmed.clicked.connect(clickEventViewQmedNetwork) + self.Button_HidroViewETR.clicked.connect(clickEventViewETR) + self.Button_HidroViewRunoff.clicked.connect(clickEventViewRunoff) #Botones para ejecutar self.Butto_Ejec_HidroBalance.clicked.connect(hadleClickEventEjecutarBalance) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 1d21298..5fc576c 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -595,9 +595,9 @@ 0 - -16 + 0 412 - 744 + 753 @@ -617,8 +617,8 @@ - 300 - 220 + 299 + 180 @@ -633,7 +633,7 @@ 0 30 381 - 187 + 161 @@ -744,6 +744,13 @@ + + + + Qt::Horizontal + + + @@ -835,6 +842,13 @@ + + + + Qt::Horizontal + + + @@ -855,7 +869,7 @@ 0 30 381 - 367 + 341 @@ -1351,7 +1365,7 @@ - Balance Largo Plazo + Balance Largo Plazo, Q = A(P-E) false @@ -1374,6 +1388,12 @@ 10 + + + 75 + true + + Datos de entrada: @@ -1422,6 +1442,25 @@ + + + + false + + + + 40 + 16777215 + + + + Visualizar shp con el caudal calculado por tramos. + + + Ver + + + @@ -1499,8 +1538,14 @@ + + + 75 + true + + - Resultados: + Datos de salida: Qt::AutoText @@ -1578,11 +1623,19 @@ + + + 7 + 75 + true + true + + El valor de la escorrentía como un mapa Raster - Escorrentía [mm] + Escorrentía [mm/año] @@ -1719,6 +1772,12 @@ + + + 75 + true + + El valor del caudal calculado solo a la salida de la cuenca. @@ -2199,7 +2258,6 @@ - From b6618a211983e62848691e4d04d739e11ab40f1b Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 12 Jun 2018 16:34:47 -0500 Subject: [PATCH 036/142] =?UTF-8?q?cambios=20menores=20sobre=20la=20interf?= =?UTF-8?q?=C3=A1z=20y=20se=20hace=20un=20borrador=20inicial=20de=20como?= =?UTF-8?q?=20sera=20la=20interfaz=20del=20interpolador=20en=20Hidrologia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 678 ++++++++++++++++++- 1 file changed, 672 insertions(+), 6 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 5fc576c..e61126b 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -1403,6 +1403,9 @@ + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] @@ -1433,6 +1436,9 @@ + + Establecer ruta donde se aloja el mapa de precipitación. + @@ -1453,6 +1459,9 @@ 16777215 + + Visualizar shp con el caudal calculado por tramos. + Visualizar shp con el caudal calculado por tramos. @@ -1467,6 +1476,9 @@ + + Estimación de la evaporación anual (mm/año), seleccionar metodología o cargar mapa. + Estimación de la evaporación anual (mm/año), seleccionar metodología o cargar mapa. @@ -1490,6 +1502,9 @@ + + Metodología de cálculo Turc. + Metodología de cálculo Turc. @@ -1503,6 +1518,9 @@ + + Metodología de cálculo Cenicafe. + Metodología de cálculo Cenicafe. @@ -1516,6 +1534,9 @@ + + Metodología de cálculo Choudry. + Metodología de cálculo Choudry. @@ -1556,6 +1577,9 @@ + + El valor del caudal calculado en cada tramo hidrológico. + El valor del caudal calculado en cada tramo hidrológico. @@ -1609,6 +1633,9 @@ 16777215 + + Visualizar shp con el caudal calculado por tramos. + Visualizar shp con el caudal calculado por tramos. @@ -1625,17 +1652,20 @@ - 7 - 75 - true - true + 11 + 50 + false + false + + El valor de la escorrentía como un mapa Raster [mm/año] + El valor de la escorrentía como un mapa Raster - Escorrentía [mm/año] + Escorrentía @@ -1684,6 +1714,9 @@ 16777215 + + Visualizar raster con la escorrentia calculada. + Visualizar raster con la escorrentia calculada. @@ -1698,11 +1731,14 @@ + + El valor de la evaporacion estimada como un Raster [mm/año] + El valor de la evaporacion estimada como un Raster - ETR [mm/año] + ETR @@ -1751,6 +1787,9 @@ 16777215 + + Visualizar raster con la ETR calculada. + Visualizar raster con la ETR calculada. @@ -1778,6 +1817,9 @@ true + + El valor del caudal calculado solo a la salida de la cuenca. + El valor del caudal calculado solo a la salida de la cuenca. @@ -1808,6 +1850,9 @@ + + Ejecuta el balance de largo plazo con los parametros dados. + Ejecuta el balance de largo plazo con los parametros dados. @@ -1822,6 +1867,626 @@ + + + + 0 + 290 + 395 + 351 + + + + + 0 + 350 + + + + + 16777215 + 16777215 + + + + Interpolación Campo de lluvia + + + false + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 10 + + + + + 75 + true + + + + Datos de entrada: + + + + + + + + + Vectorial con los puntos de los pluviometros a interpolar. + + + Vectorial con los puntos de los pluviometros a interpolar. + + + Pluviómetros + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + false + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + false + + + + 40 + 16777215 + + + + Visualizar puntos de pluviómetros. + + + Ver + + + + + + + + + + + Campo de atributos a partir del cual se realiza la interpolación. + + + Campo de atributos a partir del cual se realiza la interpolación. + + + Campo + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + false + + + + + + + false + + + + 0 + 0 + + + + + 30 + 0 + + + + + 100 + 16777215 + + + + Seleccionar el campo a interpolar. + + + Seleccionar el campo a interpolar. + + + Campo + + + + + + + + + + + + + + + + + + Archivo de excel con las series de tiempo de los puntos a interpolar. + + + Archivo de excel con las series de tiempo de los puntos a interpolar. + + + Archivo excel + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + false + + + + + + + false + + + + 100 + 16777215 + + + + Establecer archivo de excel a utilizar. + + + Establecer archivo de excel a utilizar. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + + + + + + + + Metodología utilizada para la interpolación: IDW (inverse distance weighted), TIN (Triangular irregular network) + + + Metodología utilizada para la interpolación: IDW (inverse distance weighted), TIN (Triangular irregular network) + + + Metodología + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + Metodología de interpolación IDW. + + + Metodología de interpolación IDW. + + + IDW + + + true + + + + + + + Metodología de interpolación TIN. + + + Metodología de interpolación TIN. + + + TIN + + + false + + + + + + + + + + + Exponente para ponderar la distancia en la metodología IDW. + + + Exponente para ponderar la distancia en la metodología IDW. + + + Exponente distancia IDW + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + + 50 + 0 + + + + 2 + + + 1.000000000000000 + + + 20.000000000000000 + + + 1.000000000000000 + + + + + + + + + Qt::Horizontal + + + + + + + + 75 + true + + + + Datos de salida: + + + Qt::AutoText + + + + + + + + + Ruta de guardado del campo de lluvia.tif (en el caso de que sea solo un intervalo). + + + Ruta de guardado del campo de lluvia.tif (en el caso de que sea solo un intervalo). + + + Campo de lluvia + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + Ruta de guardado + + + false + + + + + + + Establecer ruta del raster de lluvia interpolado. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + false + + + + 40 + 16777215 + + + + Visualiza el raster del campo de lluvia interpolado. + + + Ver + + + + + + + + + + + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + + + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + + + Binario de lluvia + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + Ruta de guardado + + + false + + + + + + + Establecer ruta de guardado del binario de lluvia. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + 50 + 0 + + + + Entrada del binario de lluvia a visualizar. + + + 0 + + + 0.000000000000000 + + + 10000000.000000000000000 + + + 1.000000000000000 + + + + + + + false + + + + 40 + 16777215 + + + + Visualiza una entrada del binario de lluvia interpolado. + + + Ver + + + + + + + + + Qt::Horizontal + + + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Ejecutar + + + + + + + + + @@ -2258,6 +2923,7 @@ + From 661ceeab53da148d7c304ad17862cc7ba080de5e Mon Sep 17 00:00:00 2001 From: seospinale Date: Wed, 13 Jun 2018 18:57:09 -0500 Subject: [PATCH 037/142] modificaciones iniciales para no tener que guardar la ruta del DEM y del DIR en el nc --- wmf/cuencas.f90 | 52 ++++++++++++------------ wmf/wmf.py | 105 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 96 insertions(+), 61 deletions(-) diff --git a/wmf/cuencas.f90 b/wmf/cuencas.f90 index f3edefc..accc4d4 100644 --- a/wmf/cuencas.f90 +++ b/wmf/cuencas.f90 @@ -1202,32 +1202,32 @@ subroutine basin_2map_find(basin,map_ncols,map_nrows,nceldas) !Determina los lim map_nrows=fil_max-fil_min+1 end subroutine subroutine basin_2map(basin,var,mapa,map_ncols,map_nrows,map_xll,map_yll,nceldas) !Genera un mapa de la cuenca tomando los limites encontrados por basin_2map_find - !Variables de entrada - integer, intent(in) :: nceldas - integer, intent(in) :: basin(3,nceldas) - real, intent(in) :: var(nceldas) - integer, intent(in) :: map_ncols,map_nrows - !Variables de salida - real, intent(out) :: mapa(map_ncols,map_nrows),map_xll,map_yll - !f2py intent(in) :: nceldas, basin, var, map_ncols, map_nrows - !f2py intent(out) :: mapa,map_xll,map_yll - !Variables locales - integer i,j - integer col_min,col_max,fil_min,fil_max - integer col_rel,fil_rel - !Encuentra la fila columna maxima y minima - col_min=minval(basin(2,:)); col_max=maxval(basin(2,:)) - fil_min=minval(basin(3,:)); fil_max=maxval(basin(3,:)) - !Encuentra el xll y el yll nuevos - map_xll=xll+dx*(col_min-1) - map_yll=yll+dx*(nrows-fil_max) - !Aloja la matriz y comienza a llenarla de datos - mapa=nodata - do i=1,nceldas - col_rel=basin(2,i)-col_min+1 - fil_rel=basin(3,i)-fil_min+1 - mapa(col_rel,fil_rel)=var(i) - enddo + !Variables de entrada + integer, intent(in) :: nceldas + integer, intent(in) :: basin(3,nceldas) + real, intent(in) :: var(nceldas) + integer, intent(in) :: map_ncols,map_nrows + !Variables de salida + real, intent(out) :: mapa(map_ncols,map_nrows),map_xll,map_yll + !f2py intent(in) :: nceldas, basin, var, map_ncols, map_nrows + !f2py intent(out) :: mapa,map_xll,map_yll + !Variables locales + integer i,j + integer col_min,col_max,fil_min,fil_max + integer col_rel,fil_rel + !Encuentra la fila columna maxima y minima + col_min=minval(basin(2,:)); col_max=maxval(basin(2,:)) + fil_min=minval(basin(3,:)); fil_max=maxval(basin(3,:)) + !Encuentra el xll y el yll nuevos + map_xll=xll+dx*(col_min-1) + map_yll=yll+dx*(nrows-fil_max) + !Aloja la matriz y comienza a llenarla de datos + mapa=nodata + do i=1,nceldas + col_rel=basin(2,i)-col_min+1 + fil_rel=basin(3,i)-fil_min+1 + mapa(col_rel,fil_rel)=var(i) + enddo end subroutine subroutine basin_point2var(basin_f,id_coord,xy_coord,res_coord,basin_pts,ncoord,nceldas) !Obtiene el vector basin_pts con los puntos de control !Variables de entrada diff --git a/wmf/wmf.py b/wmf/wmf.py index 0289cd1..4861317 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -1710,7 +1710,7 @@ def Transform_Basin2Map(self, BasinVar, ruta = None, DriverFormat='GTiff', Save_Array2Raster(M, [map_ncols,map_nrows,mxll,myll,cu.dx,cu.nodata], ruta = ruta, EPSG = EPSG, Format = DriverFormat) return M, [map_ncols,map_nrows,mxll,myll,cu.dx,cu.dy,cu.nodata] - + def Transform_Hills2Basin(self,HillsMap): 'Descripcion: A partir de un vector con propiedades de las laderas\n'\ ' obtiene un vector con las propiedades por celda, ojo estas \n'\ @@ -2776,14 +2776,27 @@ def __init__(self,lat=None,lon=None,DEM=None,DIR=None,rute = None, name='NaN',st self.ncells = cu.basin_find(lat,lon,DIR, cu.ncols,cu.nrows) self.structure = cu.basin_cut(self.ncells) - #traza las sub-cuencas + #Obtiene las propiedades para el tamano de la cuenca. + self.DEMvec = self.Transform_Map2Basin(DEM, + [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy]) + self.DIRvec = self.Transform_Map2Basin(DIR, + [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy]) + # self.DEM,prop =self.Transform_Basin2Map(self.DEMvec) + # self.DIR,prop =self.Transform_Basin2Map(self.DIRvec) + # cu.ncols = prop[0] + # cu.nrows = prop[1] + # cu.xll = prop[2] + # cu.yll = prop[3] + #cu.dx = prop[4] + #cu.dy = prop[5] + #traza las sub-cuencas acum=cu.basin_acum(self.structure,self.ncells) cauce,nodos,self.nhills = cu.basin_subbasin_nod(self.structure ,acum,umbral,self.ncells) self.hills_own,sub_basin = cu.basin_subbasin_find(self.structure, nodos,self.nhills,self.ncells) self.hills = cu.basin_subbasin_cut(self.nhills) - models.drena=self.structure + models.drena=self.structure #Determina la cantidad de celdas para alojar if modelType=='cells': N=self.ncells @@ -2889,21 +2902,28 @@ def __Load_SimuBasin(self,ruta, sim_slides = False): models.sim_slides = 1 models.sl_fs = gr.sl_fs models.gullienogullie = gr.sl_gullie - models.sl_gammaw = gr.sl_gammaw - #Asigna dem y DIr a partir de la ruta - try: - DEM = read_map_raster(gr.DEM,True,gr.dxp) - DIR = read_map_raster(gr.DIR,True,gr.dxp) - cu.nodata = -9999.0 - DIR[DIR<=0]=cu.nodata.astype(int) - DIR=cu.dir_reclass_rwatershed(DIR,cu.ncols,cu.nrows) - self.DEM = DEM - self.DIR = DIR - except: - print 'No se encuentran el DEM y el DIR en la ruta:' - print gr.DEM - print gr.DIR - pass + models.sl_gammaw = gr.sl_gammaw + #Nueva metodologia de geoespacial de la cuenca + cu.ncols = gr.ncols + cu.nrows = gr.nrows + cu.xll = gr.xll + cu.yll = gr.yll + cu.dx = gr.dx + cu.dy = gr.dy + #Asigna dem y DIr a partir de la ruta +# try: +# DEM = read_map_raster(gr.DEM,True,gr.dxp) +# DIR = read_map_raster(gr.DIR,True,gr.dxp) +# cu.nodata = -9999.0 +# DIR[DIR<=0]=cu.nodata.astype(int) +# DIR=cu.dir_reclass_rwatershed(DIR,cu.ncols,cu.nrows) +# self.DEM = DEM +# self.DIR = DIR +# except: +# print 'No se encuentran el DEM y el DIR en la ruta:' +# print gr.DEM +# print gr.DIR +# pass #de acuerdo al tipo de modeloe stablece numero de elem if self.modelType[0] is 'c': N = self.ncells @@ -2913,6 +2933,10 @@ def __Load_SimuBasin(self,ruta, sim_slides = False): self.structure = gr.variables['structure'][:] self.hills = gr.variables['hills'][:] self.hills_own = gr.variables['hills_own'][:] + self.DEMvec = gr.variables['DEM'][:] + self.DIRvec = gr.variables['DIR'][:] + self.DEM = self.Transform_Basin2Map(self.DEMvec) + self.DIR = self.Transform_Basin2Map(self.DIRvec) #obtiene las propieades del modelo models.h_coef = np.ones((4,N)) * gr.variables['h_coef'][:] models.v_coef = np.ones((4,N)) * gr.variables['v_coef'][:] @@ -2920,11 +2944,11 @@ def __Load_SimuBasin(self,ruta, sim_slides = False): models.v_exp = np.ones((4,N)) * gr.variables['v_exp'][:] models.max_capilar = np.ones((1,N)) * gr.variables['h1_max'][:] models.max_gravita = np.ones((1,N)) * gr.variables['h3_max'][:] - - if self.modelType[0] is 'c': + #Variable de drena de acuerdo al tipo de modelo + if self.modelType[0] is 'c': models.drena = np.ones((3,N)) *gr.variables['drena'][:] elif self.modelType[0] is 'h': - models.drena = np.ones((1,N)) * gr.variables['drena'][:] + models.drena = np.ones((1,N)) * gr.variables['drena'][:] models.unit_type = np.ones((1,N)) * gr.variables['unit_type'][:] models.hill_long = np.ones((1,N)) * gr.variables['hill_long'][:] models.hill_slope = np.ones((1,N)) * gr.variables['hill_slope'][:] @@ -3898,29 +3922,39 @@ def Save_SimuBasin(self,ruta,ruta_dem = None,ruta_dir = None, SimSlides = False, elif self.modelType[0] is 'h': N = self.nhills #Determina las rutas - if ruta_dem is None: - ruta_dem = 'not rute' - if ruta_dir is None: - ruta_dir = 'not rute' - Dict = {'nombre':self.name,'DEM':ruta_dem, - 'DIR':ruta_dir, - 'modelType':self.modelType,'noData':self.nodata,'umbral':self.umbral, - 'ncells':self.ncells,'nhills':self.nhills, - 'dt':models.dt,'Nelem':N,'dxp':cu.dxp,'retorno':models.retorno, 'storageConst' : models.storage_constant} + #if ruta_dem is None: + # ruta_dem = 'not rute' + #if ruta_dir is None: + # ruta_dir = 'not rute' + Dict = {'nombre':self.name, + 'modelType':self.modelType,'noData':self.nodata,'umbral':self.umbral, + 'ncells':self.ncells,'nhills':self.nhills, + 'dt':models.dt,'Nelem':N,'dxp':cu.dxp,'retorno':models.retorno, + 'storageConst' :models.storage_constant, + 'ncols':cu.ncols, + 'nrows':cu.nrows, + 'xll':cu.xll, + 'yll':cu.yll, + 'dx':cu.dx, + 'dy':cu.dy} if SimSlides: Dict.update({'sl_fs':models.sl_fs, 'sl_gullie':models.sl_gullienogullie, 'sl_gammaw':models.sl_gammaw}) #abre el archivo gr = netcdf.Dataset(ruta,'w',format='NETCDF4') - #Establece tamano de las variables + #Variables del DEM y del DIR + #DEMdim = gr.createDimension('ncols',DEM + #Establece tamano de las variables DimNcell = gr.createDimension('ncell',self.ncells) DimNhill = gr.createDimension('nhills',self.nhills) DimNelem = gr.createDimension('Nelem',N) DimCol3 = gr.createDimension('col3',3) DimCol2 = gr.createDimension('col2',2) DimCol4 = gr.createDimension('col4',4) - DimCol5 = gr.createDimension('col5',5) + DimCol5 = gr.createDimension('col5',5) #Crea variables - VarStruc = gr.createVariable('structure','i4',('col3','ncell'),zlib=True) + VarDEM = gr.createVariable('DEM','f4',('ncell',),zlib = True) + VarDIR = gr.createVariable('DIR','i4',('ncell',),zlib = True) + VarStruc = gr.createVariable('structure','i4',('col3','ncell'),zlib=True) VarHills = gr.createVariable('hills','i4',('col2','nhills'),zlib=True) VarHills_own = gr.createVariable('hills_own','i4',('ncell',),zlib=True) VarH_coef = gr.createVariable('h_coef','f4',('col4','Nelem'),zlib=True) @@ -3952,7 +3986,9 @@ def Save_SimuBasin(self,ruta,ruta_dem = None,ruta_dir = None, SimSlides = False, ZSoil = gr.createVariable('z_soil','f4',('Nelem',),zlib = True) RadSlope = gr.createVariable('rad_slope','f4',('Nelem',),zlib = True) #Asigna valores a las variables - VarStruc[:] = self.structure + VarDEM[:] = self.DEMvec + VarDIR[:] = self.DIRvec + VarStruc[:] = self.structure VarHills[:] = self.hills VarHills_own[:] = self.hills_own VarH_coef[:] = models.h_coef @@ -3963,7 +3999,6 @@ def Save_SimuBasin(self,ruta,ruta_dem = None,ruta_dir = None, SimSlides = False, Var_H3max[:] = models.max_gravita Control[:] = models.control ControlH[:] = models.control_h - drena[:] = models.drena unitType[:] = models.unit_type hill_long[:] = models.hill_long From f514b7034e9847fde8b0d073950a573c4c65e697 Mon Sep 17 00:00:00 2001 From: seospinale Date: Thu, 14 Jun 2018 08:48:30 -0500 Subject: [PATCH 038/142] se quita el optimizador del setup.py --- setup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 95e67a7..5b80f71 100644 --- a/setup.py +++ b/setup.py @@ -3,8 +3,7 @@ from numpy.distutils.core import setup, Extension ext1 = Extension(name = 'cu', - sources = ['wmf/cuencas.f90'], - f2py_options = ['--opt = O3']) + sources = ['wmf/cuencas.f90']) ext2 = Extension(name = 'models', sources = ['wmf/modelosv2.f90']) From 7f81948c52775c40b108027ea83d727543b310c0 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 14 Jun 2018 15:58:54 -0500 Subject: [PATCH 039/142] cambios para hacer ensayos a ver si netCDF4 funciona bien --- ensayo.py | 14 ++++++++++++ wmf/cuencas.f90 | 60 ++++++++++++++++++++++++------------------------- wmf/wmf.py | 43 ++++++++++++++++------------------- 3 files changed, 62 insertions(+), 55 deletions(-) create mode 100644 ensayo.py diff --git a/ensayo.py b/ensayo.py new file mode 100644 index 0000000..7bf3aa1 --- /dev/null +++ b/ensayo.py @@ -0,0 +1,14 @@ +from wmf import wmf + +DEM = wmf.read_map_raster('/home/nicolas/Dropbox/Trabajos/HZ/05_Buey/raster/demFin.tif', isDEMorDIR=True, + dxp = 53., noDataP = -9999) +DIR = wmf.read_map_raster('/home/nicolas/Dropbox/Trabajos/HZ/05_Buey/raster/dirFin.tif', isDEMorDIR=True, + isDIR= True, dxp = 53., noDataP = -9999) + +st = wmf.Stream(-75.5512, 5.8174, DEM, DIR) + +cu = wmf.SimuBasin(-75.5538, 5.7580, DEM, DIR, stream=st, name='buey', umbral=70) + +#print cu.CellSlope +cu.Save_SimuBasin('Ensayo.nc') +#cu = wmf.SimuBasin(rute='Ensayo.nc') diff --git a/wmf/cuencas.f90 b/wmf/cuencas.f90 index accc4d4..76e1bab 100644 --- a/wmf/cuencas.f90 +++ b/wmf/cuencas.f90 @@ -605,57 +605,55 @@ subroutine basin_cut(nceldas,basin_f) !Genera una matriz con la cuenca final print *, 'Error: La variable basin_temp no se encuentra alojada' endif end subroutine -subroutine basin_basics(basin_f,DEM,DIR,nc,nf,nceldas,acum,long,pend,elev) !calcula: acumulada, longitud y pendiente +subroutine basin_basics(basin_f,DEM,DIR,nceldas,acum,long,pend,elev) !calcula: acumulada, longitud y pendiente !variables de entrada - integer, intent(in) :: nceldas,nc,nf - integer, intent(in) :: basin_f(3,nceldas), DIR(nc,nf) - real, intent(in) :: DEM(nc,nf) + integer, intent(in) :: nceldas + integer, intent(in) :: basin_f(3,nceldas), DIR(nceldas) + real, intent(in) :: DEM(nceldas) !variables de salida integer, intent(out) :: acum(nceldas) - real, intent(out) :: long(nceldas),pend(nceldas),elev(nceldas) + real, intent(out) :: long(nceldas),pend(nceldas), elev(nceldas) !f2py intent(in) :: nceldas,nc,nf,basin_f,DEM,DIR !f2py intent(out) :: acum,long,pend,elev integer i,drenaid,col_pos,fil_pos real X(nceldas),Y(nceldas) - !Calcula la elevacion - do i=1,nceldas - elev(i)=DEM(basin_f(2,i),basin_f(3,i)) - end do !Calcula Longitudes, acum y pendiente + elev = DEM acum=1 do i=1,nceldas - !Determina la celda a la que se drena - drenaid=nceldas-basin_f(1,i)+1 - !Obtiene la longitud de la celda - prueba=mod(DIR(basin_f(2,i),basin_f(3,i)),2) - if (prueba.eq.0.0) then - long(i)=dxp - else - long(i)=dxp*sqrt(2.0) - endif - !Calcula el area acumulada - if (basin_f(1,i).ne.0) then - acum(drenaid)=acum(drenaid)+acum(i) - pend(i)=abs(elev(i)-elev(drenaid))/long(i) - else - call drain_colfil(DIR(basin_f(2,i),basin_f(3,i)),col_pos,fil_pos) - pend(i)=abs(elev(i)-DEM(basin_f(2,i)+col_pos,basin_f(3,i)+fil_pos))/long(i) - endif - !Si la pendiente es plana 0, le da un poco de pendiente - if (pend(i).eq.0) pend(i)=0.001 + !Determina la celda a la que se drena + drenaid=nceldas-basin_f(1,i)+1 + !Obtiene la longitud de la celda + prueba=mod(DIR(i),2) + if (prueba.eq.0.0) then + long(i)=dxp + else + long(i)=dxp*sqrt(2.0) + endif + !Calcula el area acumulada + if (basin_f(1,i).ne.0) then + acum(drenaid)=acum(drenaid)+acum(i) + pend(i)=abs(DEM(i)-DEM(drenaid))/long(i) + else + !call drain_colfil(DIR(basin_f(2,i),basin_f(3,i)),col_pos,fil_pos) + !pend(i)=abs(DEM(i)-DEM(basin_f(2,i)+col_pos,basin_f(3,i)+fil_pos))/long(i) + pend(i)=pend(i-1) + endif + !Si la pendiente es plana 0, le da un poco de pendiente + if (pend(i).eq.0) pend(i)=0.001 end do !Calcula escalares genericos de la cuenca area=nceldas*dxp**2/1e6 pend_media=sum(pend)/nceldas - elevacion=sum(elev)/nceldas + elevacion=sum(DEM)/nceldas !Calcula las coordenadas del centroide de la cuenca call basin_coordXY(basin_f,X,Y,nceldas) call QsortC(X) call QsortC(Y) if (mod(nceldas,2).eq.0.0) then - centroX=X(nceldas/2); centroY=Y(nceldas/2) + centroX=X(nceldas/2); centroY=Y(nceldas/2) else - centroX=X((nceldas+1)/2); centroY=Y((nceldas+1)/2) + centroX=X((nceldas+1)/2); centroY=Y((nceldas+1)/2) endif end subroutine subroutine basin_acum(basin_f,nceldas,acum) !calcula: acumulada diff --git a/wmf/wmf.py b/wmf/wmf.py index 4861317..27d4f1b 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -1099,7 +1099,7 @@ def GetGeo_Cell_Basics(self): 'CellHeight : Elevacion de cada una de las celdas [m.s.n.m].\n'\ #obtiene los parametros basicos por celdas acum,longCeld,S0,Elev=cu.basin_basics(self.structure, - self.DEM,self.DIR,cu.ncols,cu.nrows,self.ncells) + self.DEMvec,self.DIRvec,self.ncells) self.CellAcum=acum; self.CellLong=longCeld self.CellSlope=S0; self.CellHeight=Elev #Obtiene el canal en la cuenca @@ -3423,7 +3423,7 @@ def set_Geomorphology(self,umbrales=[30,500],stream_width=None): ' models.elem_area : Area de cada celda (cu.dxp**2) o ladera (nceldasLadera * cu.dxp**2). \n'\ #Obtiene lo basico para luego pasar argumentos acum,hill_long,pend,elev = cu.basin_basics(self.structure, - self.DEM,self.DIR,cu.ncols,cu.nrows,self.ncells) + self.DEMvec,self.DIRvec,self.ncells) #Obtiene la pendiente y la longitud de las corrientes cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( self.structure,acum,umbrales[1],self.ncells) @@ -3894,7 +3894,7 @@ def set_Slides(self,var,VarName): #------------------------------------------------------ # Guardado y Cargado de modelos de cuencas preparados #------------------------------------------------------ - def Save_SimuBasin(self,ruta,ruta_dem = None,ruta_dir = None, SimSlides = False, + def Save_SimuBasin(self,ruta,SimSlides = False, ExtraVar = None): 'Descripcion: guarda una cuenca previamente ejecutada\n'\ '\n'\ @@ -3921,22 +3921,17 @@ def Save_SimuBasin(self,ruta,ruta_dem = None,ruta_dir = None, SimSlides = False, N = self.ncells elif self.modelType[0] is 'h': N = self.nhills - #Determina las rutas - #if ruta_dem is None: - # ruta_dem = 'not rute' - #if ruta_dir is None: - # ruta_dir = 'not rute' - Dict = {'nombre':self.name, - 'modelType':self.modelType,'noData':self.nodata,'umbral':self.umbral, - 'ncells':self.ncells,'nhills':self.nhills, - 'dt':models.dt,'Nelem':N,'dxp':cu.dxp,'retorno':models.retorno, - 'storageConst' :models.storage_constant, - 'ncols':cu.ncols, - 'nrows':cu.nrows, - 'xll':cu.xll, - 'yll':cu.yll, - 'dx':cu.dx, - 'dy':cu.dy} + #Dict = {'nombre':self.name, + #'modelType':self.modelType,'noData':self.nodata,'umbral':self.umbral, + #'ncells':self.ncells,'nhills':self.nhills, + #'dt':models.dt,'Nelem':N,'dxp':cu.dxp,'retorno':models.retorno, + #'storageConst' :models.storage_constant, + #'ncols':cu.ncols, + #'nrows':cu.nrows, + #'xll':cu.xll, + #'yll':cu.yll, + #'dx':cu.dx, + #'dy':cu.dy} if SimSlides: Dict.update({'sl_fs':models.sl_fs, 'sl_gullie':models.sl_gullienogullie, 'sl_gammaw':models.sl_gammaw}) #abre el archivo @@ -3954,7 +3949,7 @@ def Save_SimuBasin(self,ruta,ruta_dem = None,ruta_dir = None, SimSlides = False, #Crea variables VarDEM = gr.createVariable('DEM','f4',('ncell',),zlib = True) VarDIR = gr.createVariable('DIR','i4',('ncell',),zlib = True) - VarStruc = gr.createVariable('structure','i4',('col3','ncell'),zlib=True) + VarStruc = gr.createVariable('structure','i4',('col3','ncell'),zlib=True) VarHills = gr.createVariable('hills','i4',('col2','nhills'),zlib=True) VarHills_own = gr.createVariable('hills_own','i4',('ncell',),zlib=True) VarH_coef = gr.createVariable('h_coef','f4',('col4','Nelem'),zlib=True) @@ -3986,9 +3981,9 @@ def Save_SimuBasin(self,ruta,ruta_dem = None,ruta_dir = None, SimSlides = False, ZSoil = gr.createVariable('z_soil','f4',('Nelem',),zlib = True) RadSlope = gr.createVariable('rad_slope','f4',('Nelem',),zlib = True) #Asigna valores a las variables - VarDEM[:] = self.DEMvec - VarDIR[:] = self.DIRvec - VarStruc[:] = self.structure + VarDEM[:] = self.DEMvec + VarDIR[:] = self.DIRvec + VarStruc[:] = self.structure VarHills[:] = self.hills VarHills_own[:] = self.hills_own VarH_coef[:] = models.h_coef @@ -4024,7 +4019,7 @@ def Save_SimuBasin(self,ruta,ruta_dem = None,ruta_dir = None, SimSlides = False, Var = gr.createVariable(k,ExtraVar[k]['type'],('ncell',),zlib=True) Var[:] = ExtraVar[k]['Data'] #asigna las prop a la cuenca - gr.setncatts(Dict) + #gr.setncatts(Dict) #Cierra el archivo gr.close() #Sale del programa From d6afee8c1763a0543bb5245d05345d0f162cfcc7 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Fri, 15 Jun 2018 09:43:15 -0500 Subject: [PATCH 040/142] ultimos cambios que no se que son --- qgisplugin/HydroSEDPluginUtils.py | 2 +- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 80765f1..c465f28 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -124,7 +124,7 @@ def trazador_cuenca(self,x,y, dxp,umbral,PathDiv, PathRed, PathNC,PathDEM, PathD self.cuenca.Save_Net2Map(PathRed, dxp, umbral) # Guarda el nc de la cuenca if len(PathNC)>2: - self.cuenca.Save_SimuBasin(PathNC,ruta_dem = PathDEM, ruta_dir = PathDIR) + self.cuenca.Save_SimuBasin(PathNC) def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed, PathETROUT, PathRunoff): #Se fija si la lluvia es un path o un valor diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index e61126b..15616b3 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -2923,7 +2923,6 @@ - From d86c8ad6bd2b71339610ad3ab59a5d4a5751859f Mon Sep 17 00:00:00 2001 From: camilo2046 Date: Fri, 15 Jun 2018 09:44:46 -0500 Subject: [PATCH 041/142] Se agrega el panel de NC a WMF en el Tab Configuracion --- qgisplugin/HydroSEDPlugin_dockwidget.py | 73 +- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 306 ++++- qgisplugin/icons/icono-borrar.png | Bin 0 -> 623 bytes qgisplugin/icons/icono-flecha-abajo.png | Bin 0 -> 1076 bytes qgisplugin/icons/icono-flecha-arriba.png | Bin 0 -> 1065 bytes qgisplugin/icons/icono-ver.png | Bin 0 -> 965 bytes qgisplugin/resources.py | 1134 +++++++++++++++++- qgisplugin/resources.qrc | 4 + 8 files changed, 1459 insertions(+), 58 deletions(-) create mode 100644 qgisplugin/icons/icono-borrar.png create mode 100644 qgisplugin/icons/icono-flecha-abajo.png create mode 100644 qgisplugin/icons/icono-flecha-arriba.png create mode 100644 qgisplugin/icons/icono-ver.png diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 0254b88..c3042c8 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -27,7 +27,7 @@ from PyQt4.QtCore import pyqtSignal from qgis.gui import QgsMessageBar -from PyQt4.QtGui import QFileDialog +from PyQt4.QtGui import QFileDialog, QTableWidgetItem import os.path @@ -56,6 +56,7 @@ def __init__(self, iface = None, parent=None): self.setupUi(self) self.setupUIInputsOutputs () self.setupHidro_Balance() + self.setupTableEdicionAlmacenamientoParametrosWMFNC () #self.setupUIButtonEvents () if not (iface is None): @@ -374,6 +375,76 @@ def clickEventSelectorOutputCuencaNCTrazadorCuencas (): #self.botonEjecutarTrazadorCorrientes.clicked.connect (self.handleClickEventEjecutarTrazadorCorrientes) #self.botonEjecutarTrazadorCuencas.clicked.connect (self.handleClickEventEjecutarTrazadorCuencas) + def setupTableEdicionAlmacenamientoParametrosWMFNC (self): + + def handleClickEventButton_Eliminar_Desde_WMF (): + + selectedItems = self.Tabla_Prop_WMF.currentRow () + self.Tabla_Prop_WMF.removeRow (selectedItems) + + def handleClickEventButton_Eliminar_Desde_NC (): + + selectedItems = self.Tabla_Prop_NC.currentRow () + self.Tabla_Prop_NC.removeRow (selectedItems) + + def handleClickEventButton_Actualizar_WMF_Desde_NC (): + +# selectedItems = self.Tabla_Prop_NC.currentRow () + + rows = sorted (set (index.row () for index in self.Tabla_Prop_NC.selectedIndexes ())) + for row in rows: + print('Row %d is selected' % row) + + + listaHeaderTabla1 = ["Parametro", "Valor 1", "Valor 2"] + listaContenidoTabla1 = [["Ejemplo DEM" , "/home/jctrujillo/Downloads/demfin.tif" , "100"], + ["Ejemplo DIR" , "/home/jctrujillo/Downloads/dir.tif" , "200"], + ["Ejemplo Corriente", "/home/jctrujillo/Downloads/Corriente.shp", "300"], + ["Ejemplo Cuenca" , "/home/jctrujillo/Downloads/Cuenca.shp" , "400"], + ["Ejemplo Red 1" , "/home/jctrujillo/Downloads/red1.shp" , "500"], + ["Ejemplo Red 2" , "/home/jctrujillo/Downloads/Red_2.shp" , "600"]] + + listaHeaderTabla2 = ["Parametro", "Valor 1", "Valor 2", "Valor 3", "Valor 4", "Valor 5", "Valor 6"] + listaContenidoTabla2 = [["Ejemplo DEM Edicion" , "/home/jctrujillo/Downloads/demfin.tif" , "100", "1000", "10000", "100000", "1000000"], + ["Ejemplo DIR Edicion" , "/home/jctrujillo/Downloads/dir.tif" , "200", "2000", "20000", "200000", "2000000"], + ["Ejemplo Corriente Edicion", "/home/jctrujillo/Downloads/Corriente.tif", "300", "3000", "30000", "300000", "3000000"], + ["Ejemplo Cuenca Edicion" , "/home/jctrujillo/Downloads/Cuenca.tif" , "400", "4000", "40000", "400000", "4000000"]] + + self.Tabla_Prop_WMF.setRowCount (len (listaContenidoTabla1)) + self.Tabla_Prop_WMF.setColumnCount (len (listaHeaderTabla1)) + + self.Tabla_Prop_NC.setRowCount (len (listaContenidoTabla2)) + self.Tabla_Prop_NC.setColumnCount (len (listaHeaderTabla2)) + + for idxFila in xrange (len (listaContenidoTabla1)): + + for idxColumna in xrange (len (listaHeaderTabla1)): + + self.Tabla_Prop_WMF.setItem (idxFila, idxColumna, QTableWidgetItem (listaContenidoTabla1[idxFila][idxColumna])) + + for idxFila in xrange (len (listaContenidoTabla2)): + + for idxColumna in xrange (len (listaHeaderTabla2)): + + self.Tabla_Prop_NC.setItem (idxFila, idxColumna, QTableWidgetItem (listaContenidoTabla2[idxFila][idxColumna])) + + self.Tabla_Prop_WMF.setHorizontalHeaderLabels (listaHeaderTabla1) + + self.Tabla_Prop_NC.setHorizontalHeaderLabels (listaHeaderTabla2) + + self.Tabla_Prop_WMF.setSelectionMode (QtGui.QAbstractItemView.SingleSelection) + self.Tabla_Prop_WMF.setSelectionBehavior (QtGui.QAbstractItemView.SelectRows) + + self.Tabla_Prop_NC.setSelectionMode (QtGui.QAbstractItemView.SingleSelection) + self.Tabla_Prop_NC.setSelectionBehavior (QtGui.QAbstractItemView.SelectRows) + + self.Button_Eliminar_Desde_WMF.clicked.connect (handleClickEventButton_Eliminar_Desde_WMF) + self.Button_Eliminar_Desde_NC.clicked.connect (handleClickEventButton_Eliminar_Desde_NC) + + self.Button_Actualizar_WMF_Desde_NC.clicked.connect (handleClickEventButton_Actualizar_WMF_Desde_NC) + + print "a" + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 5fc576c..fbb507f 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -6,7 +6,7 @@ 0 0 - 458 + 493 936 @@ -74,7 +74,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -181,11 +181,11 @@ - 2 + 0 - + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png @@ -196,7 +196,7 @@ 0 0 - 430 + 461 730 @@ -225,9 +225,9 @@ 0 - 0 - 412 - 1918 + -40 + 446 + 768 @@ -262,8 +262,8 @@ 0 0 - 391 - 471 + 425 + 711 @@ -322,7 +322,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -424,7 +424,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -526,26 +526,227 @@ - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - Propiedades mapas - - + + + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + Propiedades mapas WMF + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png + + + + - + + + + + + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + Propiedades mapas NC + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png:/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png:/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png + + + + - labelDIR_2 - labelDEM - labelDIR - Tabla_PropMDE @@ -555,7 +756,7 @@ - + :/plugins/HydroSEDPlugin/icons/cuenca.ico:/plugins/HydroSEDPlugin/icons/cuenca.ico @@ -596,8 +797,8 @@ 0 0 - 412 - 753 + 415 + 728 @@ -633,7 +834,7 @@ 0 30 381 - 161 + 168 @@ -677,7 +878,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -791,7 +992,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -808,7 +1009,7 @@ - + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png @@ -869,7 +1070,7 @@ 0 30 381 - 341 + 367 @@ -904,7 +1105,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -1050,7 +1251,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1098,7 +1299,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1183,7 +1384,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1231,7 +1432,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1271,7 +1472,7 @@ - + :/plugins/HydroSEDPlugin/icons/cuenca.ico:/plugins/HydroSEDPlugin/icons/cuenca.ico @@ -1312,7 +1513,7 @@ 0 0 - 412 + 415 1918 @@ -1437,7 +1638,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1593,7 +1794,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1668,7 +1869,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1735,7 +1936,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1871,7 +2072,7 @@ 0 0 - 412 + 415 1918 @@ -1954,7 +2155,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1983,7 +2184,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2068,7 +2269,7 @@ 0 0 - 323 + 326 930 @@ -2257,7 +2458,6 @@ 1 - - + diff --git a/qgisplugin/icons/icono-borrar.png b/qgisplugin/icons/icono-borrar.png new file mode 100644 index 0000000000000000000000000000000000000000..cce51d7926c578ac306dadc78f482e1487d71424 GIT binary patch literal 623 zcmV-#0+9WQP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0t87!K~!i%?b=HVNwNcB?Prd zCD{4^#UcuV2oX%gu)k`doRNx{ebs(23Y- zz%lefdAmd}Vnu$eT$APP17bzK4qX%FZ4O1{2|i;Du8H!t1KHmYBGUuc1f}K`B4b4| zc5RV6c%;lgPcQ{N?jzs%T^_FE!@^JKSLpG2#L5KpgrmqJ524rnghaVDMegDLf8m$A z62X|LfleLtcsYV(UStcw*r`0A68=$r1DzGe4Ay$M~5nrqbu_DBZ_+mwf z6(Lr{7b`-n2(co*SP^1Hh!yeWx+3o(SI33?SwQD0f-w<3S1x<%@kRv6yhvI}y~uN9 zk;l;MCN44pJ>e3v$RzZ-ACV{zAosxaq~GxlZ&UIGa^q94If%rOXG2e#wI3)$;#A=q zT#KY_A2<3(0=csO8d=?Y|Al!pA(d319ewCeiQMg~MT`^*{{Yty+S({rPi6oB002ov JPDHLkV1gGr3NHWv literal 0 HcmV?d00001 diff --git a/qgisplugin/icons/icono-flecha-abajo.png b/qgisplugin/icons/icono-flecha-abajo.png new file mode 100644 index 0000000000000000000000000000000000000000..ee17eb601be42b1c526442cd5e44f63d3724cc69 GIT binary patch literal 1076 zcmV-41k3x0P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1IbB5K~#8N?cGhN z6=fX9@vE7YP)TpAP(le`zzoX>7gjF9l^7_2A-WI(TV$&?iliuJxiAQ{cD1nrB{Zn4 zB&ckmXxIxRDheegS)hec+V{T*?&8`~x-6x@N;=b`R7rOIQS#*(|7GmhcQ*W{*P+vxK-5<1$+YHOvxT zh0E+Ys9~1y7F=c^-PqmT(a+vqMnBEM+2GM&CmXvXm)s z8T|q^$Wk7L%jj>YL6))@F0osohFH={xWuMH4Y8zHzvU8}3pK=&Hp3kS_QNt^DpWQgP;S66%2Z+3&ayec3#uY&Ob(W_7cXqy)?5XG5Sy!+G;+9IBlAE?$s4WbS9qBCbyIcF~Y|BR7y&N=6tbIv*EoO6vfH1scNB_n2Q;*%o)0000Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1HMT_K~#8N?cF!1 z6=@iU@hc`UU`9j{K}1>9#(*fS5eo}J1Qii2c10@@3sEo@Hd^RnC@c(UVPH{V3&m7e zC?*Un%YqgrTobs60rT?~!sYUM?}YEn`DV`lfnR-R-gD2HIg?J4Qc5YMlu}A5rIe~_ zBe4lP@jH4$)uDD+k1zPv%v&siDzMHtgyt_qb6;UEmMWmWxCHNoXlXw>Le;3j_y^wb zf94eI9i;*{0uSH~y)CEF1u9Tu@EqQ-le&PeP&u1`*YJj%mTh}_KxJ$a{)ac*tgfOL zRLXwE8+b#_>n3b(O(kp!>o0cV)7ZYQTbNF8$gWg3+gyjw&}3{Ja6S=WqW`FP`QTU zCA^i6-4)nQNM-7V*miHzI)F-KdsKhITgkFnh0?bX-pZAcZU1JXwAn_y<%Miz_X>9P zOX=!^C-7FP?Cj`p>5h4wgtszPu^FXlIlPsq65F2GspjbW1x1~LtvCBfj`|d^eR;YC zZ{e%zFGSm7cne*1cF9td*%>!)fvavEqO9zPN3z<2C_4ymfvfH}M427YeFtx$tLiT7 z;Aynk;gW~&7QSli7Kc(?j%v4&jmC_OiaLq)7~bD+i~Z9LLBsSPya9%G9V$UZ?XB6> ziYh_p;0-Xe<4_4Y0&jq!?S)Fv4tN6$Z7WoQ>?sW107F{~l_0x}(;HxD%b*f82i^cf zn-7&ByU)-YU}&Yjf~3fX!5d&`;t?ZhSU!#VRqop8)8Tupb~Zi z-Vj5v$9AX`oq;#VQ0$zIN>Qy(2ixUJDn;Ai4KftF16ZZV?#1v18Ol+p6fJ}|$WZ=( zO3^fUgA8Q@REq3@G~OUX(UIPi*>e%SL54CHDrN8C4KsvjFOZJ8`|yStf_)^alwF25 z%nJEF9tA0dMDW#NB jN-3q3Qc9`9YHIopHXJW`gI@3D00000NkvXXu0mjfq`vHh literal 0 HcmV?d00001 diff --git a/qgisplugin/icons/icono-ver.png b/qgisplugin/icons/icono-ver.png new file mode 100644 index 0000000000000000000000000000000000000000..0436a260012abd3d4fdb3b330d7e65d6df5695f9 GIT binary patch literal 965 zcmV;$13LVPP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D16oN$K~!i%?bunU zO;H@j@na@a=8z{ z_WhmCx~;qKf8TTVKGS_zzxw3bt+mfSYp=7`fA364NJvOXNJvOX2x)=gSb%Lff^)cz zC%Agp>G=e<}RIWvoPhR3#H|0=gLMB8zbiv(Xe~&s1E2bs?qp z42w~gFV+XgVSRA9-NYD_B#p2FUtxV%rToP%v_k5%#X(pfP%Ss0*^)T@a1Yi=tL+^o zq2OrgdDNQr${PXY|Rv$;Dmzyz}p~yE1`oeK} z2&+#T?O|ma@_ng=$YwLF2ELhyOQ}ksU$E|w(i`~(U6p(`no3p!-vPvBKde4UJw;qp ziCcYq=aJ1sSPe9l4(0yVYSIB#G{>WT)7Swk`fc2X+T6v_+}~09(luEF|CVayP_;0^ zJGKc{I^rW-yR=5bioY!^L2I1#j)?|d`(dpN!7}Is>f~|>>ZFaVmktDu+qq9cdsZ|Wo#?0)>N&KjTiFQLPIsqd*$#K&wK`x# zo7+XWc7@Q?9t_o4rDq~{&QH(_nTkboKU$qXfR@p? z4LF*Xm=2XJ{(0_0^<`Bu7tx11O%+w(+KBZUN*As7cp7oNRb7WO&{L=1Py3wqvpO4O zrK1&4uXQ!D{sk854OGqdK!b{QZ@sJ59Z;bdy#tQ!pq@sxyz8!2{f;C_XAFRT^jb{1 n!KySuLPA19LPA2yo=oOHb2R9!Arb`&00000NkvXXu0mjf4L`w- literal 0 HcmV?d00001 diff --git a/qgisplugin/resources.py b/qgisplugin/resources.py index 06d4d3d..33b6a0d 100644 --- a/qgisplugin/resources.py +++ b/qgisplugin/resources.py @@ -76,6 +76,1042 @@ \x81\xa3\x32\xb1\xfb\xf4\x0c\x30\xb8\xb1\x82\x9b\xb0\x09\x60\x30\ \xb1\xfb\xf4\xcc\xbf\xa0\xe9\x6e\xae\x5a\xdf\x4b\x81\x00\x00\x00\ \x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x02\x6f\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x32\x00\x00\x00\x32\x08\x06\x00\x00\x00\x1e\x3f\x88\xb1\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x04\x67\x41\x4d\x41\x00\x00\xb1\x8f\x0b\xfc\x61\x05\x00\x00\x00\ +\x09\x70\x48\x59\x73\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7\x6f\ +\xa8\x64\x00\x00\x02\x04\x49\x44\x41\x54\x68\x43\xed\xda\x3b\x48\ +\x1c\x51\x14\xc6\xf1\x55\x51\xa3\x98\x60\xa2\x36\x2a\x41\x92\x26\ +\xda\x08\xb1\xb1\x10\x41\xb0\x10\xd3\xa8\xa5\x55\x2c\x12\xb1\x10\ +\xb4\x0b\x04\x0b\xab\x04\xf2\x28\xad\x2c\x44\x48\x61\x52\x05\x6d\ +\x25\x04\xb5\x48\x25\xd8\xfa\x00\xc5\x22\x0a\x82\x08\x11\x4c\xc4\ +\xe4\x7f\x20\x03\x87\xe1\xde\x71\x87\x71\x66\x16\x3c\x1f\xfc\x9a\ +\xbd\x33\xf7\xde\x6f\x9f\x30\xb3\x85\x1b\x4c\x07\x16\xf0\x13\x7f\ +\x23\x9c\x61\x19\x03\x28\xb9\x4c\xe3\x0f\x5c\x1b\x8f\xb2\x88\x6a\ +\x94\x44\xc6\xe1\xda\x64\xb1\xa4\x4c\xee\x69\xc1\x39\xc2\x9b\x3b\ +\xc2\xae\xc3\x01\xae\x10\x3e\xfe\x19\x72\xcd\x2c\xf4\x86\x0e\xd1\ +\x8d\xa8\xb4\x62\x1d\xfa\xbc\x55\xe4\x9a\x0d\xe8\x0d\x0d\xa3\x98\ +\x34\xe3\x02\xc1\x79\xbf\x91\xeb\x67\x65\x0f\xba\xc8\x5d\x14\x9b\ +\x4d\xe8\x73\xdb\x90\x4a\xe4\xfd\x3f\x86\x97\x11\x4e\xa0\x37\xe3\ +\x3a\xc6\x67\x1b\xfa\x5c\x79\x9b\xba\x8e\x13\x2f\xd0\x89\xd8\x69\ +\xc0\x31\xf4\x42\x79\xbb\x44\x2f\x62\x45\x7e\xac\x5c\x93\xe5\xed\ +\x03\x62\x45\xbe\x0e\x5d\x13\xe5\x6d\x0e\x45\xe5\x09\x3e\x63\x0d\ +\xae\x89\xf2\xb6\x03\xd9\xdf\x10\x22\xd3\x03\xd7\x04\xa5\xe6\x15\ +\x22\x63\x45\x32\x76\x6d\x91\x3b\x78\xa4\xcc\x40\x4f\x30\x05\x3d\ +\xee\x23\xdf\xf9\x5d\x1e\xae\xe3\xc3\xc2\x4f\xe8\x57\xe8\xf1\x7a\ +\xc4\xca\x04\xf4\x84\xa3\xc8\x22\x0f\xa1\xd7\xfd\x84\x44\xb9\x35\ +\x45\xee\xe1\xfe\x7f\xe1\x97\xbb\x12\xc1\x98\xa8\x81\x4e\x1d\xf4\ +\x78\x39\x82\x64\x5e\x64\x0b\xc1\xd8\xa9\x3c\xa0\x12\xfe\x51\x7d\ +\x03\x9d\x15\xe8\x71\xd9\x7c\x10\x2b\xe2\x8b\x15\x21\x56\x84\x58\ +\x11\x5f\xac\x08\xb1\x22\xc4\x8a\xf8\x62\x45\x88\x15\x21\x56\xc4\ +\x17\x2b\x42\xac\x08\xb1\x22\xbe\x58\x11\x62\x45\x88\x15\xf1\xe5\ +\xba\x22\xef\x21\x57\xc7\x85\xfc\x59\x40\xe7\x29\x82\x31\x11\x3e\ +\x57\x2e\x7b\xea\xf1\x46\x04\xc9\xbc\x48\x5a\x49\xbd\xc8\x73\x64\ +\x91\xc7\xd0\xeb\x26\x2e\x32\x02\x3d\xe1\x12\xb2\xc8\x24\xf4\xba\ +\x1f\x91\x28\x0f\x20\xf7\xc0\xf5\xa4\xdf\xf1\x0e\x6f\x53\xf2\x05\ +\x72\xe3\x53\xaf\x39\x88\xc4\x91\x67\x43\x4f\x9a\xb5\x1f\x28\x43\ +\xe2\x54\xe1\x1b\x5c\x8b\xa4\x6d\x1f\x37\xfa\x47\x02\xb9\xb2\xfe\ +\x1a\x59\xdd\x7b\xff\x85\x79\x34\x21\x95\x54\xa0\x1d\x7d\xe8\x4f\ +\x89\xdc\xed\xaa\x45\x8c\x14\x0a\xff\x00\xd7\x0f\xda\xda\x28\x57\ +\x4f\x66\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x04\x34\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x64\x00\x00\x00\x64\x08\x06\x00\x00\x00\x70\xe2\x95\x54\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x04\x67\x41\x4d\x41\x00\x00\xb1\x8f\x0b\xfc\x61\x05\x00\x00\x00\ +\x09\x70\x48\x59\x73\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7\x6f\ +\xa8\x64\x00\x00\x03\xc9\x49\x44\x41\x54\x78\x5e\xed\xdd\x4d\xa8\ +\x15\x65\x1c\xc7\xf1\xab\x99\x95\x50\x49\x6f\xab\x50\x42\x09\x5f\ +\xc0\x0c\xcb\x08\x17\x56\x2e\xc2\x95\x18\x28\x81\x21\xba\x10\x02\ +\x5b\x64\xab\x36\x8a\xa4\x28\x66\xb9\x30\x08\xb4\x76\xb5\xb1\x02\ +\x25\x34\xa8\xac\x24\xa8\x6c\xa1\x68\xd8\x0b\x24\x2a\x0a\x25\x26\ +\x59\xa0\x85\x51\xda\xf7\xbf\x08\xee\xe2\xd7\xbd\xcf\x33\xf3\x9c\ +\xb9\x73\xe6\xfc\xbe\xf0\x59\x7b\xe6\x7f\x0f\x9e\x39\x33\xcf\x3c\ +\x67\xc8\x39\xe7\x9c\x73\xce\x39\xe7\x9c\x73\xce\x75\xa9\x1b\xb1\ +\x00\xcf\x62\x03\x76\xe2\x0d\x6c\xc1\x3a\x3c\x85\xbb\xe0\x7a\xd8\ +\x4d\x58\x85\x83\xb8\x82\xeb\xa3\xb8\x86\x63\x58\x8f\x3b\xe0\x0a\ +\x75\x03\x5e\xc0\xcf\x50\x83\x4f\x71\x19\x2f\xe3\x66\xb8\x9a\xed\ +\x83\x1a\x72\x15\x5f\xe0\x16\xb8\x8a\xcd\x84\x1a\x6c\x1d\x4f\xc2\ +\x55\x6c\x0d\xd4\x50\xeb\xd8\x04\x57\xb1\xed\x50\x43\xad\xe3\x1d\ +\xb8\x8a\xed\x81\x1a\x6a\x1d\x47\xe0\x2a\x76\x18\x6a\xa8\x75\xfc\ +\x0a\x57\xb1\x3a\xa7\xba\x23\x99\x0c\x97\xd9\x78\xfc\x03\x35\xd0\ +\xba\x66\xc3\x65\x76\x0f\xd4\x30\x4b\x58\x04\x97\xd9\x2c\xa8\x61\ +\x96\xf0\x0c\x5c\x66\x8f\x43\x0d\xb3\x84\xb8\x14\xe3\x32\x5b\x06\ +\x35\xcc\x12\x5e\x85\xcb\xec\x39\xa8\x61\x96\xf0\x16\x5c\x66\x1b\ +\xa1\x86\x59\x42\x5c\xc2\x77\x99\xbd\x0e\x35\xcc\x12\xbe\x85\xcb\ +\xec\x3d\xa8\x61\x96\x70\x11\x2e\xb3\x43\x50\xc3\x2c\x65\x22\x5c\ +\x46\xdf\x43\x0d\xb2\x94\x29\x70\x19\xfd\x02\x35\xc8\x52\x1e\x86\ +\xcb\xe8\x6f\xa8\x41\x96\xb2\x18\x2e\xb1\x5b\xa1\x86\x58\xd2\x4a\ +\xb8\xc4\xa6\x42\x0d\xb1\xa4\x58\xbf\xe5\x12\x9b\x0b\x35\xc4\x92\ +\x36\xc3\x25\xf6\x18\xd4\x10\x4b\xda\x0d\x97\xd8\x52\xa8\x21\x96\ +\x14\x5f\x3c\x5d\x62\xab\xa1\x86\x58\xd2\x67\x70\x89\xc5\xfd\x0a\ +\x35\xc4\x92\x4e\xc0\x25\xf6\x12\xd4\x10\x4b\x8a\x05\x14\x2e\xb1\ +\xd7\xa0\x86\x58\xd2\x5f\x70\x89\xc5\x0d\x24\x35\xc4\xd2\x6e\x87\ +\x4b\x68\x3f\xd4\x00\x4b\x9b\x06\x97\x50\x3c\x36\xa0\x06\x58\xda\ +\x7c\xb8\x84\xbe\x83\x1a\x60\x69\xbe\xc0\x98\xd8\x4f\x50\x03\x2c\ +\xcd\x17\x18\x13\xfb\x13\x6a\x80\xa5\x0d\xc4\x05\xc6\x49\x78\x1e\ +\xef\xe3\xe3\x8a\xd4\xf0\x7a\xe1\x47\xa8\x7f\x7f\x34\x1f\x61\x17\ +\x5a\xbf\x46\xf8\x6e\x1c\x85\x3a\xf8\x2e\x8a\xa7\x81\x17\xa2\xb5\ +\xc5\x3b\x47\xbd\xf0\x2e\x3b\x85\x09\x68\x5d\xb1\x8a\x23\xbe\xfd\ +\xaa\x17\xdd\x75\xb1\x0e\xb9\x75\xdd\x06\xf5\x62\x07\xc1\x13\x68\ +\x65\x17\xa0\x5e\x70\x97\xfd\x81\x78\x33\xb6\xb2\xb8\x2d\xaa\x5e\ +\x74\x97\xbd\x89\xd6\x16\x5b\x57\xc4\xfe\x22\xea\x85\x77\xd1\x59\ +\xb4\x7e\x1f\x95\x19\x88\xbd\x45\xd4\x01\x74\x49\xac\x1b\x6b\xf5\ +\x29\xef\xf0\x62\xd7\x1e\x75\x10\x5d\xd2\x77\xab\x56\xde\x86\x3a\ +\x90\x2e\xf8\x0a\xad\xfc\xee\x31\x52\x71\xe6\x71\x12\xea\x80\xfa\ +\xd9\xef\xb8\x0f\x7d\xd9\x3c\xa4\x6c\x36\xd6\x4f\x9e\x46\x5f\xb7\ +\x02\xea\xc0\xfa\xd1\x2b\xe8\x44\xdb\xa0\x0e\xb0\x9f\x7c\x88\xd8\ +\xdd\xae\x13\xc5\x81\x34\x75\x9f\xbc\x17\xe2\x32\x7d\xe7\xf6\x47\ +\x89\x15\x1e\x4d\xdd\x9a\x2d\x29\x3e\xc4\x3b\xbb\x37\xca\x74\x5c\ +\x82\x3a\xf0\x36\x8a\x9d\x4d\x97\xa0\xd3\xc5\x95\xd1\xab\x50\x03\ +\x68\x9b\x17\x31\x10\xc5\x99\x57\xbc\xfb\xd4\x10\xda\x22\x9e\x93\ +\x1f\xa8\xd6\x42\x0d\xa2\x0d\xf6\xa2\x33\x67\x54\x39\x6d\x85\x1a\ +\xc8\x58\xfa\x04\x03\xfb\x0c\xfb\x38\xb4\xe9\x9a\xd7\x37\x18\xf8\ +\xf5\xbe\xf1\x6e\xfc\x00\x6a\x40\x4d\x3a\x8d\x7b\xe1\x28\xd6\x72\ +\x7d\x0a\x35\xa8\x26\x9c\x43\x9c\x92\xbb\x61\xc5\xb3\xe9\xbd\xd8\ +\x16\x76\x34\xb1\x0e\x20\xb6\x34\x77\xa2\xf8\xff\xbb\xc9\x5b\xc0\ +\xf1\x25\xf5\x01\xb8\x11\x8a\xd5\x8f\x4d\x5c\x62\xf9\x0d\x8f\xc0\ +\x25\x14\x5b\xc4\x1e\x87\x1a\x64\x09\xf1\xc7\x78\x14\x2e\xa3\x3b\ +\x11\xfb\xb4\xab\x81\xd6\x11\x5b\x8d\x3f\x04\x57\xa1\xf8\x4c\xf9\ +\x12\x6a\xb0\x55\xc4\x96\x4f\x0f\xc2\xd5\x28\xce\xbe\x3e\x87\x1a\ +\x70\x8e\xf3\x98\x03\x57\xa0\xf8\x9e\x12\x3b\x89\xaa\x41\xa7\x38\ +\x83\xfb\xe1\x0a\x16\xab\x22\x0f\x40\x0d\x7c\x24\x71\xc6\xe6\x6f\ +\xe0\x3d\x2a\x2e\xb3\xe4\xec\x56\xfa\x35\xfc\x7b\x86\x3d\x2e\x7e\ +\xc6\x62\x07\xd4\x1f\x60\xb8\x77\xe1\x5f\x64\x6b\xb0\xd8\x8a\xfc\ +\xff\xf6\x65\x8c\x5f\xfc\x8c\x2b\xc9\xae\xe1\xe2\x76\x70\x7c\xae\ +\xfc\xf7\xd4\xee\x0f\x58\x0e\x37\xc6\xc5\x3a\x5b\xff\x8c\x91\x73\ +\xce\x39\xe7\x9c\x73\xce\x39\xe7\x9c\x73\x8d\x36\x34\xf4\x2f\x69\ +\x25\x23\x66\x6b\xe2\x93\x23\x00\x00\x00\x00\x49\x45\x4e\x44\xae\ +\x42\x60\x82\ +\x00\x00\x04\x29\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x64\x00\x00\x00\x64\x08\x06\x00\x00\x00\x70\xe2\x95\x54\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x04\x67\x41\x4d\x41\x00\x00\xb1\x8f\x0b\xfc\x61\x05\x00\x00\x00\ +\x09\x70\x48\x59\x73\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7\x6f\ +\xa8\x64\x00\x00\x03\xbe\x49\x44\x41\x54\x78\x5e\xed\xdd\x37\xa8\ +\x15\x69\x18\x87\xf1\x2b\x26\x30\x60\x46\x44\x11\x41\x44\x59\xd4\ +\xc6\x80\x28\xac\x11\x0b\x0b\x41\x04\x15\x11\x2d\x76\x45\x2b\x11\ +\x0b\x51\x30\x16\x36\x5a\xe8\x62\x28\x2c\x0c\x68\x61\x60\x51\x61\ +\x0b\xc5\x54\x58\x28\x26\x0c\x2c\xcb\x82\x16\x26\x5c\x13\xb8\x88\ +\x01\xf3\xf3\x16\xc2\xe5\xf2\x7a\xef\x84\xef\xcc\xf9\x66\xce\xff\ +\x81\x5f\x7d\x67\xde\x73\xcf\x99\x39\x93\x4e\x93\x52\x4a\x29\xa5\ +\x94\x52\x4a\x29\xa5\x94\xaa\x6a\x23\xb1\x09\x3b\xf1\x3b\x7a\x43\ +\xd5\xa1\x76\x58\x8f\x2f\xf8\xd6\xcc\x5b\x2c\x82\x2a\xb0\xce\x38\ +\x84\xe6\x2f\x44\x73\x5f\x61\x2f\x96\x2a\xa0\xbe\xb8\x04\xef\x85\ +\x68\x69\x3f\x3a\x42\xd5\xa8\xc1\xf8\x07\xde\xf0\x7f\xe6\x14\xec\ +\x1d\xa5\x02\x37\x02\x0f\xe0\x0d\xbd\x2d\xa7\xd1\x05\x2a\x50\x63\ +\xf0\x1c\xde\xb0\x93\xba\x80\xae\x50\x39\x9b\x80\xd7\xf0\x86\x9c\ +\x96\x6d\x7b\x7a\x40\x65\x6c\x12\xfe\x87\x37\xdc\xac\xae\xa2\x17\ +\x54\xca\x7e\xc5\x1b\x78\x43\xcd\xeb\x26\x6c\x6f\x4d\x25\x6c\x0a\ +\xec\x0b\x9e\x37\xcc\x50\xfe\x46\x7f\xa8\x36\x9a\x88\x5a\xbf\x18\ +\x3f\xdc\x81\xde\x29\xad\x34\x16\xa1\x36\xe0\x49\x5d\x83\x36\xf4\ +\x4e\xa3\xf0\x02\xde\xd0\x6a\xcd\xf6\xbe\xf4\x3d\xa5\x59\xc3\xf1\ +\x0c\xde\xb0\x8a\x72\x16\xfa\x46\x4f\x83\xf0\x08\xde\x90\x8a\x66\ +\x87\x59\xda\xa3\x61\xb3\xcf\x6e\xdb\xb0\x7a\xc3\xa9\x97\x3d\x68\ +\xc8\x3a\xe1\x3c\xbc\xa1\xd4\xdb\x1a\x34\x54\x76\x72\xe9\x30\xbc\ +\x61\xc4\xc0\xce\xa7\x2c\x45\xc3\xb4\x1d\xde\x20\x62\xf2\x19\xb3\ +\x51\xf9\x56\xc2\x1b\x40\x8c\xec\x0b\xea\x38\x54\xb6\xe9\xb0\xff\ +\x3c\x6f\xe5\x63\x65\x7b\x80\x03\x50\xb9\x86\xe2\x25\xbc\x95\x8e\ +\xdd\x15\xd8\x4e\x48\x65\xea\x86\xd8\x76\x6f\xd3\x3a\x80\x4a\x64\ +\x7b\x54\x7f\xc2\x5b\xc9\xb2\x59\x85\xd2\xb7\x11\xde\xca\x95\x91\ +\x6d\xff\x66\xa2\xb4\xd9\x46\xbc\xe5\x85\x6c\x65\xf7\x0a\x76\xf5\ +\x4b\xe9\xea\x83\x27\xf0\x56\xaa\xec\xec\xe8\x70\xe9\x8e\x79\x9d\ +\x84\xb7\x32\x55\xb1\x19\xa5\x69\x39\xbc\x95\xa8\x12\xdb\x9e\xd8\ +\xa9\xe6\xe8\xfb\x05\x45\x9d\x82\xad\x37\xfb\x48\x8e\xfa\x14\xb0\ +\x7d\x79\xba\x05\x6f\xe1\xab\xea\x2f\x44\xdb\x62\x78\x0b\x5d\x75\ +\x76\xc9\x52\x94\xd9\x19\x37\x6f\x81\xab\x6e\x1d\xa2\xac\xec\x87\ +\x47\xb2\xda\x82\x28\x3b\x08\x6f\x81\xab\xee\x37\x44\x99\x1d\xd1\ +\x7d\x07\x6f\xa1\xab\xea\x2e\xec\xe0\x69\xb4\xd9\xe1\x92\x87\xf0\ +\x16\xbe\x6a\xec\x16\x87\x52\x5c\x8e\x6a\xb7\x91\x8d\xc6\x8c\x8c\ +\x8a\x3a\x89\xf5\x18\xde\xdf\x6f\x8b\xfd\xd3\x0d\x41\xc3\xf4\x1f\ +\xbc\x01\x86\x76\x1d\x2a\x41\x45\xed\xad\xd9\xd5\x8a\x2a\x41\xe7\ +\xe0\x0d\x30\xb4\xe3\x50\x09\x3a\x02\x6f\x80\xa1\xed\x85\x4a\xd0\ +\x0e\x78\x03\x0c\x6d\x2b\x54\x82\xec\x29\x0c\xde\x00\x43\x5b\x0b\ +\x95\x20\xbb\x8c\xd3\x1b\x60\x68\xcb\xa0\x12\x34\x07\xde\x00\x43\ +\x9b\x0f\x95\x20\xbb\xcf\xd0\x1b\x60\x68\xa5\xbe\x82\xa4\xc8\x86\ +\xc1\x1b\x60\x68\xe3\xa1\x12\xd4\x13\xde\x00\x43\xb3\x17\x5e\x25\ +\xec\x03\xbc\x21\x86\xd4\x0f\x2a\x61\x76\xe0\xcf\x1b\x62\x48\x1d\ +\xa0\x12\x76\x03\xde\x10\x43\xb1\xc7\x76\xa8\x14\x9d\x81\x37\xc8\ +\x50\xec\x9c\x8d\x4a\x51\xad\x4f\x07\xdb\xe5\x4a\x2a\x45\xdb\xe0\ +\x0d\x32\x14\xbb\x03\x58\xa5\xc8\xee\xc5\xf0\x06\x19\xca\x51\xa8\ +\x14\x2d\x84\x37\xc8\x50\xfe\x80\x4a\xd1\x34\x78\x83\x0c\x65\x03\ +\x54\x8a\xec\x81\x34\xde\x20\x43\xd1\x91\xde\x94\xd9\x73\x11\xbd\ +\x41\x86\x32\x17\x2a\x65\xef\xe1\x0d\x33\x84\x68\x2f\x90\x8e\xb9\ +\xfb\xf0\x86\x19\x82\x7d\x24\xaa\x94\x5d\x86\x37\xcc\x10\xf4\xac\ +\xc5\x0c\xd5\xea\xfe\xf6\x4f\x50\x19\xda\x05\x6f\xa0\x79\x3d\x85\ +\xca\x90\xdd\x08\xe3\x0d\x34\xaf\xdb\x50\x19\x5a\x02\x6f\xa0\x79\ +\x45\x7d\x5f\x60\xcc\x4d\x85\x37\xd0\xbc\x76\x43\x65\xc8\x6e\x00\ +\xf2\x06\x9a\xd7\x6a\xa8\x0c\xd9\x6d\xd6\xb5\x78\x56\xca\x3c\xa8\ +\x8c\xfd\x0b\x6f\xa8\x79\xd8\x3b\x4f\x65\x6c\x1f\xbc\xa1\x66\x75\ +\x0f\x2a\x47\xf6\xb0\x65\xdb\x2b\xf2\x86\x9b\x96\x9d\xa7\x1f\x08\ +\x95\x33\x7b\x2a\xdd\x2c\x5c\x84\x37\xe8\xd6\x7c\xc4\x31\x4c\x86\ +\xaa\x41\xf6\x70\x9b\x15\x38\x01\xfb\xd5\xb6\x96\x47\x84\xed\x41\ +\x9b\x76\x01\x83\x7d\xcb\x5f\x00\xfd\x68\x4b\x1d\xea\x0e\x7b\x94\ +\xab\x7e\x44\x52\x29\xa5\x94\x52\x4a\x29\xa5\x94\x52\x4a\xa9\xc2\ +\x6a\x6a\xfa\x0e\x36\x1c\x2f\x79\x83\x5e\xef\xe5\x00\x00\x00\x00\ +\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x35\x5c\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x06\x40\x00\x00\x06\x40\x08\x03\x00\x00\x00\x16\xd2\x7e\x95\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x04\x67\x41\x4d\x41\x00\x00\xb1\x8f\x0b\xfc\x61\x05\x00\x00\x03\ +\x00\x50\x4c\x54\x45\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x33\x00\x00\x66\x00\x00\x99\x00\x00\xcc\x00\x00\xff\x00\ +\x33\x00\x00\x33\x33\x00\x33\x66\x00\x33\x99\x00\x33\xcc\x00\x33\ +\xff\x00\x66\x00\x00\x66\x33\x00\x66\x66\x00\x66\x99\x00\x66\xcc\ +\x00\x66\xff\x00\x99\x00\x00\x99\x33\x00\x99\x66\x00\x99\x99\x00\ +\x99\xcc\x00\x99\xff\x00\xcc\x00\x00\xcc\x33\x00\xcc\x66\x00\xcc\ +\x99\x00\xcc\xcc\x00\xcc\xff\x00\xff\x00\x00\xff\x33\x00\xff\x66\ +\x00\xff\x99\x00\xff\xcc\x00\xff\xff\x33\x00\x00\x33\x00\x33\x33\ +\x00\x66\x33\x00\x99\x33\x00\xcc\x33\x00\xff\x33\x33\x00\x33\x33\ +\x33\x33\x33\x66\x33\x33\x99\x33\x33\xcc\x33\x33\xff\x33\x66\x00\ +\x33\x66\x33\x33\x66\x66\x33\x66\x99\x33\x66\xcc\x33\x66\xff\x33\ +\x99\x00\x33\x99\x33\x33\x99\x66\x33\x99\x99\x33\x99\xcc\x33\x99\ +\xff\x33\xcc\x00\x33\xcc\x33\x33\xcc\x66\x33\xcc\x99\x33\xcc\xcc\ +\x33\xcc\xff\x33\xff\x00\x33\xff\x33\x33\xff\x66\x33\xff\x99\x33\ +\xff\xcc\x33\xff\xff\x66\x00\x00\x66\x00\x33\x66\x00\x66\x66\x00\ +\x99\x66\x00\xcc\x66\x00\xff\x66\x33\x00\x66\x33\x33\x66\x33\x66\ +\x66\x33\x99\x66\x33\xcc\x66\x33\xff\x66\x66\x00\x66\x66\x33\x66\ +\x66\x66\x66\x66\x99\x66\x66\xcc\x66\x66\xff\x66\x99\x00\x66\x99\ +\x33\x66\x99\x66\x66\x99\x99\x66\x99\xcc\x66\x99\xff\x66\xcc\x00\ +\x66\xcc\x33\x66\xcc\x66\x66\xcc\x99\x66\xcc\xcc\x66\xcc\xff\x66\ +\xff\x00\x66\xff\x33\x66\xff\x66\x66\xff\x99\x66\xff\xcc\x66\xff\ +\xff\x99\x00\x00\x99\x00\x33\x99\x00\x66\x99\x00\x99\x99\x00\xcc\ +\x99\x00\xff\x99\x33\x00\x99\x33\x33\x99\x33\x66\x99\x33\x99\x99\ +\x33\xcc\x99\x33\xff\x99\x66\x00\x99\x66\x33\x99\x66\x66\x99\x66\ +\x99\x99\x66\xcc\x99\x66\xff\x99\x99\x00\x99\x99\x33\x99\x99\x66\ +\x99\x99\x99\x99\x99\xcc\x99\x99\xff\x99\xcc\x00\x99\xcc\x33\x99\ +\xcc\x66\x99\xcc\x99\x99\xcc\xcc\x99\xcc\xff\x99\xff\x00\x99\xff\ +\x33\x99\xff\x66\x99\xff\x99\x99\xff\xcc\x99\xff\xff\xcc\x00\x00\ +\xcc\x00\x33\xcc\x00\x66\xcc\x00\x99\xcc\x00\xcc\xcc\x00\xff\xcc\ +\x33\x00\xcc\x33\x33\xcc\x33\x66\xcc\x33\x99\xcc\x33\xcc\xcc\x33\ +\xff\xcc\x66\x00\xcc\x66\x33\xcc\x66\x66\xcc\x66\x99\xcc\x66\xcc\ +\xcc\x66\xff\xcc\x99\x00\xcc\x99\x33\xcc\x99\x66\xcc\x99\x99\xcc\ +\x99\xcc\xcc\x99\xff\xcc\xcc\x00\xcc\xcc\x33\xcc\xcc\x66\xcc\xcc\ +\x99\xcc\xcc\xcc\xcc\xcc\xff\xcc\xff\x00\xcc\xff\x33\xcc\xff\x66\ +\xcc\xff\x99\xcc\xff\xcc\xcc\xff\xff\xff\x00\x00\xff\x00\x33\xff\ +\x00\x66\xff\x00\x99\xff\x00\xcc\xff\x00\xff\xff\x33\x00\xff\x33\ +\x33\xff\x33\x66\xff\x33\x99\xff\x33\xcc\xff\x33\xff\xff\x66\x00\ +\xff\x66\x33\xff\x66\x66\xff\x66\x99\xff\x66\xcc\xff\x66\xff\xff\ +\x99\x00\xff\x99\x33\xff\x99\x66\xff\x99\x99\xff\x99\xcc\xff\x99\ +\xff\xff\xcc\x00\xff\xcc\x33\xff\xcc\x66\xff\xcc\x99\xff\xcc\xcc\ +\xff\xcc\xff\xff\xff\x00\xff\xff\x33\xff\xff\x66\xff\xff\x99\xff\ +\xff\xcc\xff\xff\xff\xaf\x56\x4d\x1c\x00\x00\x00\x28\x74\x52\x4e\ +\x53\x36\xba\xeb\xfe\x7b\x5b\x9a\xd3\x4b\x6b\x8b\xab\xe2\xc3\xf4\ +\x42\xda\xa2\x93\x83\x62\xca\x52\x73\xb3\x3b\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x48\xd5\xb0\x00\x00\x00\ +\x09\x70\x48\x59\x73\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7\x6f\ +\xa8\x64\x00\x00\x31\xb1\x49\x44\x41\x54\x78\x5e\xed\xdd\xe7\x76\ +\x1c\x59\x72\x85\xd1\x01\x44\x12\x34\x60\x11\xf4\xa0\xde\xff\x41\ +\x35\xea\x3e\xd3\xd3\x86\x06\x11\x95\xe6\xde\xcc\xbd\x7f\x6a\x69\ +\xd8\x44\x55\x44\x7c\x2b\x09\xf7\xaf\xff\x05\x80\x06\x01\x01\xa0\ +\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\ +\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\ +\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\ +\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\ +\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\ +\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\ +\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\ +\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\ +\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\ +\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\ +\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\ +\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\ +\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\ +\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\ +\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\ +\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\ +\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\ +\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\ +\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\ +\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\ +\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\ +\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\ +\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\ +\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\ +\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\ +\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\ +\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\ +\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\ +\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\ +\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\ +\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\ +\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\ +\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\ +\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\ +\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\ +\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\ +\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\ +\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\ +\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\ +\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\ +\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\ +\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\ +\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\ +\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\ +\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\ +\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\ +\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\ +\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\ +\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\ +\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\ +\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\ +\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\ +\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\ +\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\ +\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\ +\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\ +\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\ +\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\ +\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\ +\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\ +\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\ +\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\ +\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\ +\x68\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\ +\x11\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\ +\x10\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\ +\x00\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\ +\x5a\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\ +\x04\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\ +\x04\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\ +\x80\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\ +\x16\x01\x01\xa0\x45\x40\x00\x68\x11\x10\x00\x5a\x04\x04\x80\x16\ +\x01\x01\xa0\x45\x40\xf6\xf1\xee\xe5\xf3\xaf\x1f\x5f\xff\xbf\x8f\ +\x5f\x5f\x3d\x7f\x99\xff\x2b\xc0\x44\x04\x64\x63\x2f\x9f\xbd\x7f\ +\x7b\xff\x3f\xff\x74\xb9\x7b\xf3\xf1\x79\xfe\x7f\x00\x66\x20\x20\ +\xdb\xf9\xd7\xb3\x37\xdf\x4b\xc7\x9f\x5d\xde\xbe\xf6\x34\x02\x4c\ +\x42\x40\x36\xf2\xea\xcd\x6d\x22\xf1\x4b\x9f\x3f\xe6\x7f\x03\x30\ +\x32\x01\xd9\xc2\xd7\xcf\x69\xc3\x53\xdd\x7f\x78\x97\xff\x29\xc0\ +\xa8\x04\x64\x75\xaf\xaa\xf5\xf8\xdd\xbd\xe7\x10\x60\x6c\x02\xb2\ +\xb2\x17\x97\x04\xa1\xe1\xc6\x67\xd5\x81\x81\x09\xc8\x9a\xbe\xf4\ +\x1e\x3e\xfe\xeb\xfe\x55\xfe\x24\x80\xe1\x08\xc8\x7a\x9e\xdf\x25\ +\x03\xd7\xb8\x7d\x96\x3f\x0d\x60\x30\x02\xb2\x96\xe7\x0f\x49\xc0\ +\xb5\x2e\xaf\xf3\x27\x02\x0c\x45\x40\xd6\xf1\xed\xda\x7f\xbc\xfa\ +\x33\x09\x01\x46\x24\x20\xab\x78\x93\xd3\xbf\x14\x09\x01\xc6\x23\ +\x20\x2b\x78\x76\xc5\x57\x5e\xfd\x88\x84\x00\xa3\x11\x90\xc5\xfd\ +\x6b\x89\xcf\x9d\x7f\xc7\xe5\x43\xfe\x03\x00\x43\x10\x90\xa5\xbd\ +\xce\xbd\x5f\x81\x84\x00\x23\x11\x90\x85\xad\xf4\xf8\xf1\x1f\x2f\ +\xf2\x9f\x01\xd8\x9d\x80\x2c\xea\xd3\x0a\x9f\xfd\xf8\x1b\x4f\x21\ +\xc0\x20\x04\x64\x49\xef\x73\xe4\xd7\xe5\x29\x04\x18\x82\x80\x2c\ +\x68\xe5\x7f\xbe\xfa\x2f\x09\x01\x06\x20\x20\xcb\xf9\xd5\x6f\x8b\ +\x5a\x92\x84\x00\xbb\x13\x90\xa5\x7c\x59\xff\xd3\x1f\x7f\xf1\x3e\ +\xff\x5d\x80\x9d\x08\xc8\x42\x9e\xe7\xae\x6f\x48\x42\x80\x5d\x09\ +\xc8\x32\x5e\xe5\xa8\x6f\x4b\x42\x80\x1d\x09\xc8\x22\xbe\xe6\xa2\ +\x6f\x4e\x42\x80\xdd\x08\xc8\x12\x76\xeb\xc7\xbf\xbd\xc9\xdf\x01\ +\x60\x63\x02\xb2\x80\x1d\x3e\xff\xf1\x67\x12\x02\xec\x42\x40\xae\ +\xf7\x25\x87\x7c\x3f\x8f\xf9\x9b\x00\x6c\x48\x40\xae\xf6\x6d\xe3\ +\xaf\xdf\xfd\x2e\x4f\x21\xc0\xe6\x04\xe4\x6a\xb7\xb9\xe1\x3b\x7b\ +\xf4\x56\x02\xdb\x72\x75\xae\xb5\xd9\xcf\x2f\xf9\xa5\x1b\x6f\x26\ +\xb0\x25\x37\xe7\x4a\x4b\xff\xf2\xda\xab\x78\x0a\x01\x36\xe4\xe2\ +\x5c\x67\xcf\x2f\xe0\xfd\x9e\x9b\x6f\xf9\x8b\x01\xac\x4d\x40\xae\ +\xf2\xaf\xdc\xed\x81\x48\x08\xb0\x11\x01\xb9\xca\x38\x9f\x00\xf9\ +\x93\xb7\xef\xf2\xb7\x03\x58\x93\x80\x5c\xe3\x45\x4e\xf6\x68\x24\ +\x04\xd8\x80\x80\x5c\xe1\x65\xee\xf5\x80\x24\x04\x58\x9d\x80\x5c\ +\x61\xcb\xdf\x20\x55\xf6\xf6\x65\xfe\x96\x00\xeb\x10\x90\xbe\xd7\ +\x39\xd5\xa3\x92\x10\x60\x55\x02\xd2\x97\x3b\x3d\xb0\xcf\x12\x02\ +\xac\x47\x40\xda\xde\xe6\x4a\x0f\x4d\x42\x80\xd5\x08\x48\xd7\xfe\ +\x3f\x83\xf7\x69\x24\x04\x58\x89\x80\x74\x0d\xf9\x2d\x20\xdf\x75\ +\xf7\x25\x7f\x65\x80\x25\x09\x48\xd3\xa7\x5c\xe7\x29\x48\x08\xb0\ +\x02\x01\x69\x7a\xc8\x6d\x9e\xc4\xdd\xf3\xfc\xbd\x01\x96\x22\x20\ +\x3d\x53\x3d\x80\xfc\x46\x42\x80\x85\x09\x48\xcf\x64\x0f\x20\xbf\ +\x79\x90\x10\x60\x49\x02\xd2\x32\xf0\x0f\x31\xf9\x19\x4f\x21\xc0\ +\x82\x04\xa4\xe5\x26\x17\x79\x3a\x0f\x9f\xf2\x11\x00\x5c\x4b\x40\ +\x5a\x72\x8e\x67\xe4\x1f\xb2\x80\x85\x08\x48\xc7\xa8\x3f\xc6\xfd\ +\x69\x3c\x85\x00\x8b\x10\x90\x8e\xdb\x9c\xe2\x59\xdd\x4b\x08\x70\ +\x3d\x01\x69\x98\xe5\xa7\x98\xfc\xc4\xfd\xab\x7c\x2c\x00\x5d\x02\ +\xd2\xf0\x98\x2b\x3c\x35\x09\x01\xae\x24\x20\x0d\x39\xc1\xb3\x93\ +\x10\xe0\x2a\x02\x52\xf7\x3c\x07\x78\x7e\xb7\x5f\xf3\x21\x01\xd4\ +\x09\x48\xdd\xfb\x9c\xdf\x23\x90\x10\xa0\x4d\x40\xea\x66\xff\x1a\ +\xac\xbf\x92\x10\xa0\x49\x40\xca\xde\xe5\xf2\x1e\x86\x84\x00\x2d\ +\x02\x52\xf6\x3a\x77\xf7\x40\x6e\x9f\xe5\x63\x03\x78\x3a\x01\x29\ +\x9b\xe2\x77\xa1\x57\x49\x08\x50\x26\x20\x65\x39\xb9\x47\x23\x21\ +\x40\x91\x80\x54\x7d\xcb\xc1\x3d\x1e\x09\x01\x4a\x04\xa4\xea\x6b\ +\xce\xed\x11\x5d\x3e\xe6\x83\x04\xf8\x35\x01\xa9\x7a\x93\x63\x7b\ +\x4c\x12\x02\x3c\x99\x80\x54\xdd\xe5\xd4\x1e\x95\x84\x00\x4f\x24\ +\x20\x55\xb9\xb3\x07\x76\x79\x9d\x0f\x15\xe0\x67\x04\xa4\x2a\x57\ +\xf6\xd0\x24\x04\x78\x02\x01\x29\x7a\x99\x1b\x7b\x70\x12\x02\xfc\ +\x92\x80\x14\x1d\xf9\x8b\xb0\xfe\x42\x42\x80\x5f\x10\x90\xa2\x03\ +\xfe\x20\x93\x1f\xb9\x7c\xc8\xc7\x0c\xf0\x3d\x02\x52\x74\xa4\x9f\ +\xe5\xfe\x4b\x12\x02\xfc\x84\x80\x14\xdd\xe4\xb6\x9e\x85\x84\x00\ +\x3f\x22\x20\x45\x47\xff\x36\x90\x7f\x7a\x91\x8f\x1c\xe0\xaf\x04\ +\xa4\xe8\x3e\x67\xf5\x4c\x24\x04\xf8\x1e\x01\x29\x3a\xd6\xaf\x23\ +\x7c\x2a\x09\x01\xfe\x49\x40\x8a\x2e\x39\xa9\x67\x23\x21\xc0\xdf\ +\x09\x48\x51\xee\xe9\x09\xbd\xcf\x2b\x00\xf0\x3b\x01\x29\xca\x35\ +\x3d\x25\x09\x01\xfe\x4c\x40\x8a\x72\x4b\x4f\x4a\x42\x80\xff\x12\ +\x90\xa2\x5c\xd2\xd3\x92\x10\xe0\x3f\x04\xa4\x28\x77\xf4\xc4\xde\ +\xe4\x95\x00\xce\x4e\x40\x8a\x72\x45\x4f\x4d\x42\x80\xff\x27\x20\ +\x45\xb9\xa1\x27\x27\x21\x80\x80\x94\xe5\x82\x9e\xde\x63\x5e\x0f\ +\xe0\xbc\x04\xa4\x28\xf7\x93\xff\x79\x34\x3b\x70\x72\x8e\x40\x51\ +\xae\x27\xff\x76\x63\x7a\xe0\xd4\x9c\x80\xa2\xdc\x4e\x7e\xe3\x29\ +\x04\xce\xcc\x01\x28\xca\xe5\x24\x6e\xbe\xe5\x85\x01\x4e\x47\x40\ +\x8a\x72\x37\xf9\xc3\xcd\xbb\xbc\x34\xc0\xc9\x08\x48\x51\xae\x26\ +\x7f\xe2\x29\x04\xce\x49\x40\x8a\x72\x33\xf9\x0b\x4f\x21\x70\x46\ +\x02\x52\x94\x8b\xc9\xdf\xbc\x95\x10\x38\x1d\x01\x29\xca\xbd\xe4\ +\x1f\x24\x04\xce\x46\x40\x8a\x72\x2d\xf9\x8e\xb7\x2f\xf3\x22\x01\ +\xa7\x20\x20\x45\xb9\x95\x7c\xd7\x67\x09\x81\x13\x11\x90\xa2\x5c\ +\x4a\x7e\x40\x42\xe0\x3c\x04\xa4\x28\x77\x92\x1f\x92\x10\x38\x0b\ +\x01\x29\xca\x95\xe4\x27\x3e\x7f\xc9\x8b\x05\x1c\x9a\x80\x14\xe5\ +\x46\xf2\x53\x77\x12\x02\x27\x20\x20\x45\xb9\x90\xfc\x82\x84\xc0\ +\xf1\x09\x48\x51\xee\x23\xbf\x74\xf7\x3c\x2f\x19\x70\x50\x02\x52\ +\x94\xeb\xc8\x13\x48\x08\x1c\x9b\x80\x14\xe5\x36\xf2\x24\x12\x02\ +\x47\x26\x20\x45\xb9\x8c\x3c\xd1\xc3\xa7\xbc\x70\xc0\xe1\x08\x48\ +\x51\xee\x22\x4f\xf6\xe0\x29\x04\x0e\x4a\x40\x8a\x72\x15\x29\xf0\ +\x14\x02\xc7\x24\x20\x45\xb9\x89\x94\xdc\xbf\xca\xcb\x07\x1c\x88\ +\x80\x14\xe5\x22\x52\x74\xef\x29\x04\x0e\x47\x40\x8a\x72\x0f\x29\ +\xf3\x14\x02\x47\x23\x20\x45\xb9\x86\x34\x48\x08\x1c\x8b\x80\x14\ +\xe5\x16\xd2\x22\x21\x70\x24\x02\x52\x94\x4b\x48\xd3\xed\xd7\xbc\ +\x90\xc0\xf4\x04\xa4\x28\x77\x90\x36\x09\x81\xa3\x10\x90\xa2\x5c\ +\x41\xae\x20\x21\x70\x0c\x02\x52\x94\x1b\xc8\x55\x6e\x9f\xe5\xe5\ +\x04\x26\x26\x20\x45\xb9\x80\x5c\x49\x42\x60\x7e\x02\x52\x94\xfb\ +\xc7\xd5\x24\x04\x66\x27\x20\x45\xb9\x7e\x2c\xe0\xf6\x63\x5e\x54\ +\x60\x4a\x02\x52\x94\xdb\xc7\x22\x2e\x9e\x42\x60\x62\x02\x52\x94\ +\xcb\xc7\x42\x2e\x9e\x42\x60\x5a\x02\x52\x94\xbb\xc7\x62\x24\x04\ +\x66\x25\x20\x45\xb9\x7a\x2c\xe8\xf2\x3a\x2f\x2e\x30\x15\x01\x29\ +\xca\xcd\x63\x51\x12\x02\x33\x12\x90\xa2\x5c\x3c\x16\x26\x21\x30\ +\x1f\x01\x29\xca\xbd\x63\x71\x12\x02\xb3\x11\x90\xa2\x5c\x3b\x56\ +\x70\xf9\x90\x17\x19\x98\x82\x80\x14\xe5\xd6\xb1\x0a\x09\x81\x99\ +\x08\x48\x51\x2e\x1d\x6b\x91\x10\x98\x86\x80\x14\xe5\xcc\xb1\x9e\ +\x17\x79\xa9\x81\xc1\x09\x48\x51\x8e\x1c\x6b\x92\x10\x98\x82\x80\ +\x14\xe5\xc4\xb1\x2e\x09\x81\x09\x08\x48\x51\x0e\x1c\x6b\x93\x10\ +\x18\x9e\x80\x14\xe5\xbc\xb1\xbe\xf7\x79\xc9\x81\x41\x09\x48\x51\ +\x8e\x1b\x5b\x90\x10\x18\x9a\x80\x14\xe5\xb4\xb1\x0d\x09\x81\x81\ +\x09\x48\x51\x0e\x1b\x5b\x79\x93\x17\x1e\x18\x8e\x80\x14\xe5\xac\ +\xb1\x1d\x09\x81\x41\x09\x48\x51\x8e\x1a\x5b\x92\x10\x18\x92\x80\ +\x14\xe5\xa4\xb1\x2d\x09\x81\x01\x09\x48\x51\x0e\x1a\x5b\x7b\xcc\ +\x1b\x00\x0c\x43\x40\x8a\x72\xce\xd8\x9e\x84\xc0\x60\x04\xa4\x28\ +\xc7\x8c\x3d\x3c\x1a\x57\x18\x89\x8d\x2c\xca\x29\x63\x1f\x8f\xdf\ +\xf2\x3e\x00\xfb\x13\x90\xa2\x1c\x32\xf6\x72\x23\x21\x30\x0a\x01\ +\x29\xca\x19\x63\x3f\x12\x02\x83\x10\x90\xa2\x1c\x31\xf6\x24\x21\ +\x30\x04\x01\x29\xca\x09\x63\x5f\x37\xef\xf2\x7e\x00\xfb\x11\x90\ +\xa2\x1c\x30\xf6\xf6\x56\x42\x60\x6f\x02\x52\x94\xf3\xc5\xfe\x24\ +\x04\x76\x26\x20\x45\x39\x5e\x8c\x40\x42\x60\x57\x02\x52\x94\xd3\ +\xc5\x18\x3e\xbf\xcc\xfb\x02\x6c\x4f\x40\x8a\x72\xb8\x18\x85\x84\ +\xc0\x6e\x04\xa4\x28\x67\x8b\x71\x48\x08\xec\x44\x40\x8a\x72\xb4\ +\x18\xc9\xdd\x97\xbc\x3b\xc0\x96\x04\xa4\x28\x27\x8b\xb1\x48\x08\ +\xec\x40\x40\x8a\x72\xb0\x18\x8d\x84\xc0\xe6\x04\xa4\x28\xe7\x8a\ +\xf1\xdc\x3d\xcf\x7b\x04\x6c\x43\x40\x8a\x72\xac\x18\x91\x84\xc0\ +\xa6\x04\xa4\x28\xa7\x8a\x31\x3d\x48\x08\x6c\x47\x40\x8a\x72\xa8\ +\x18\x95\x84\xc0\x66\x04\xa4\x28\x67\x8a\x71\x3d\x7c\xca\x7b\x05\ +\xac\x4b\x40\x8a\x72\xa4\x18\xd9\xbd\x84\xc0\x16\x04\xa4\x28\x27\ +\x8a\xb1\x79\x0a\x81\x0d\x08\x48\x51\x0e\x14\xa3\xf3\x14\x02\xab\ +\x13\x90\xa2\x9c\x27\xc6\x77\xff\x2a\xef\x19\xb0\x0e\x01\x29\xca\ +\x71\x62\x06\x12\x02\xab\x12\x90\xa2\x9c\x26\xe6\x20\x21\xb0\x22\ +\x01\x29\xca\x61\x62\x16\xb7\x12\x02\x6b\x11\x90\xa2\x9c\x25\xe6\ +\x71\xff\x35\xef\x1d\xb0\x2c\x01\x29\xca\x51\x62\x26\xb7\x12\x02\ +\x6b\x10\x90\xa2\x9c\x24\xe6\x22\x21\xb0\x02\x01\x29\xca\x41\x62\ +\x36\xb7\xcf\xf2\x0e\x02\x4b\x11\x90\xa2\x9c\x23\xe6\x23\x21\xb0\ +\x30\x01\x29\xca\x31\x62\x46\xb7\x1f\xf3\x2e\x02\x4b\x10\x90\xa2\ +\x9c\x22\xe6\x74\xf1\x14\x02\xcb\x11\x90\xa2\x1c\x22\x66\x75\xf1\ +\x14\x02\x4b\x11\x90\xa2\x9c\x21\xe6\x25\x21\xb0\x10\x01\x29\xca\ +\x11\x62\x66\x12\x02\x8b\x10\x90\xa2\x9c\x20\xe6\x76\x79\x9d\xf7\ +\x13\xe8\x13\x90\xa2\x1c\x20\x66\x27\x21\x70\x35\x01\x29\xca\xf9\ +\x61\x7e\x12\x02\x57\x12\x90\xa2\x1c\x1f\x8e\xe0\xf2\x21\xef\x2a\ +\xd0\x21\x20\x45\x39\x3d\x1c\x83\x84\xc0\x15\x04\xa4\x28\x87\x87\ +\xc3\x90\x10\xe8\x12\x90\xa2\x5c\x1d\x0e\xe4\x45\xde\x5b\xa0\x46\ +\x40\x8a\x72\x73\x38\x14\x4f\x21\xd0\x21\x20\x45\xb9\x38\x1c\x8c\ +\xa7\x10\xa8\x13\x90\xa2\xdc\x1b\x0e\x47\x42\xa0\x4a\x40\x8a\x72\ +\x6d\x38\x20\x09\x81\x1a\x01\x29\xca\xad\xe1\x90\xde\xe7\x5d\x06\ +\x9e\x42\x40\x8a\x72\x69\x38\x28\x09\x81\xa7\x13\x90\xa2\xdc\x19\ +\x0e\xeb\x4d\xde\x69\xe0\x57\x04\xa4\x28\x57\x86\x03\x93\x10\x78\ +\x1a\x01\x29\xca\x8d\xe1\xd0\x24\x04\x9e\x42\x40\x8a\x72\x61\x38\ +\x38\x09\x81\x5f\x13\x90\xa2\xdc\x17\x0e\xef\x31\xef\x38\xf0\x23\ +\x02\x52\x94\xeb\xc2\x09\x78\x0a\x81\x9f\x13\x90\xa2\xdc\x16\x4e\ +\xe1\xd1\x7e\xc0\x4f\x58\x90\xa2\x5c\x16\x4e\xe2\xf1\x5b\xde\x78\ +\xe0\x1f\x04\xa4\x28\x77\x85\xd3\xb8\x91\x10\xf8\x01\x01\x29\xca\ +\x55\xe1\x44\x24\x04\xbe\x4f\x40\x8a\x72\x53\x38\x15\x09\x81\xef\ +\x11\x90\xa2\x5c\x14\x4e\xe6\xed\xbb\x0c\x00\xf0\x07\x01\x29\xca\ +\x3d\xe1\x74\x24\x04\xfe\x4e\x40\x8a\x72\x4d\x38\x21\x09\x81\xbf\ +\x12\x90\xa2\xdc\x12\x4e\xe9\xed\xcb\x8c\x01\xf0\x6f\x02\x52\x94\ +\x4b\xc2\x49\x49\x08\xfc\x97\x80\x14\xe5\x8e\x70\x5a\x9f\x25\x04\ +\x42\x40\x8a\x72\x45\x38\x31\x09\x81\xdf\x09\x48\x51\x6e\x08\xa7\ +\x76\xf7\x25\xe3\x00\xa7\x26\x20\x45\xb9\x20\x9c\x9c\x84\x80\x80\ +\x94\xe5\x7e\x70\x7a\x12\x02\x02\x52\x94\xeb\x01\xff\x73\xf7\x3c\ +\x43\x01\x27\x25\x20\x45\xb9\x1d\xf0\x6f\x12\xc2\xb9\x09\x48\x51\ +\x2e\x07\xfc\xe6\x41\x42\x38\x31\x01\x29\xca\xdd\x80\x90\x10\xce\ +\x4b\x40\x8a\x72\x35\xe0\x0f\x0f\x9f\x32\x1c\x70\x32\x02\x52\x94\ +\x9b\x01\x7f\x72\x2f\x21\x9c\x92\x80\x14\xe5\x62\xc0\x5f\x78\x0a\ +\xe1\x8c\x04\xa4\x28\xf7\x02\xfe\xc6\x53\x08\xe7\x23\x20\x45\xb9\ +\x16\xf0\x0f\xf7\xaf\x32\x24\x70\x12\x02\x52\x94\x5b\x01\xdf\x21\ +\x21\x9c\x8b\x80\x14\xe5\x52\xc0\x77\x49\x08\x67\x22\x20\x45\xb9\ +\x13\xf0\x03\xb7\x5f\x33\x2a\x70\x78\x02\x52\x94\x2b\x01\x3f\x74\ +\x2f\x21\x9c\x84\x80\x14\xe5\x46\xc0\x4f\x78\x0a\xe1\x1c\x04\xa4\ +\x28\x17\x02\x7e\x4a\x42\x38\x03\x01\x29\xca\x7d\x80\x5f\xb8\x7d\ +\x96\x91\x81\xc3\x12\x90\xa2\x5c\x07\xf8\x25\x09\xe1\xe8\x04\xa4\ +\x28\xb7\x01\x9e\x40\x42\x38\x36\x01\x29\xca\x65\x80\x27\x91\x10\ +\x8e\x4c\x40\x8a\x72\x17\xe0\x89\x2e\x1f\x33\x3a\x70\x38\x02\x52\ +\x94\xab\x00\x4f\x26\x21\x1c\x95\x80\x14\xe5\x26\x40\x81\x84\x70\ +\x4c\x02\x52\x94\x8b\x00\x25\x97\xd7\x19\x20\x38\x10\x01\x29\xca\ +\x3d\x80\x22\x09\xe1\x78\x04\xa4\x28\xd7\x00\xca\x24\x84\xa3\x11\ +\x90\xa2\xdc\x02\x68\x90\x10\x8e\x45\x40\x8a\x72\x09\xa0\xe5\xf2\ +\x21\x83\x04\x07\x20\x20\x45\xb9\x03\xd0\x24\x21\x1c\x87\x80\x14\ +\xe5\x0a\x40\x9f\x84\x70\x10\x02\x52\x94\x13\x00\xd7\x90\x10\x0e\ +\x41\x40\x8a\x72\x00\xe0\x3a\x2f\x32\x50\x30\x31\x01\x29\xca\xfa\ +\xc3\xb5\x24\x84\xe9\x09\x48\x51\x96\x1f\xae\x27\x21\x4c\x4e\x40\ +\x8a\xb2\xfa\xb0\x84\xf7\x19\x2b\x98\x92\x80\x14\x65\xf1\x61\x19\ +\x12\xc2\xc4\x04\xa4\x28\x6b\x0f\x4b\x91\x10\xa6\x25\x20\x45\x59\ +\x7a\x58\x8e\x84\x30\x29\x01\x29\xca\xca\xc3\x92\xde\x64\xbc\x60\ +\x2a\x02\x52\x94\x85\x87\x65\x49\x08\x13\x12\x90\xa2\xac\x3b\x2c\ +\xed\x31\x23\x06\xd3\x10\x90\xa2\x2c\x3b\x2c\xcf\x53\x08\x93\x11\ +\x90\xa2\xac\x3a\xac\xe1\xd1\x42\x32\x13\xf3\x5a\x94\x45\x87\x75\ +\xdc\x58\x49\xe6\x61\x5a\x8b\xb2\xe6\xb0\x16\x4f\x21\x4c\xc3\xac\ +\x16\x65\xc9\x61\x3d\x37\xdf\x32\x6d\x30\x36\x01\x29\xca\x8a\xc3\ +\x9a\x6e\xde\x65\xde\x60\x64\x02\x52\x94\x05\x87\x75\x79\x0a\x61\ +\x02\x02\x52\x94\xf5\x86\xb5\xbd\xf5\x14\xc2\xe8\x04\xa4\x28\xcb\ +\x0d\xeb\x93\x10\x06\x27\x20\x45\x59\x6d\xd8\xc2\xdb\x97\x99\x3b\ +\x18\x91\x80\x14\x65\xb1\x61\x1b\x12\xc2\xc0\x04\xa4\x28\x6b\x0d\ +\x5b\xf9\x2c\x21\x8c\x4a\x40\x8a\xb2\xd4\xb0\x1d\x09\x61\x50\x02\ +\x52\x94\x95\x86\x2d\x49\x08\x43\x12\x90\xa2\x2c\x34\x6c\xeb\xf3\ +\x97\x4c\x20\x8c\x43\x40\x8a\xb2\xce\xb0\xb5\x3b\x09\x61\x34\x02\ +\x52\x94\x65\x86\xed\xdd\x3d\xcf\x14\xc2\x18\x04\xa4\x28\xab\x0c\ +\x7b\x90\x10\x86\x22\x20\x45\x59\x64\xd8\xc7\x83\x84\x30\x0e\x01\ +\x29\xca\x1a\xc3\x5e\x3c\x85\x30\x0c\x01\x29\xca\x12\xc3\x7e\x1e\ +\x3e\x65\x1a\x61\x5f\x02\x52\x94\x15\x86\x3d\xf9\x87\x2c\x86\x20\ +\x20\x45\x59\x60\xd8\x97\xa7\x10\x06\x20\x20\x45\x59\x5f\xd8\xdb\ +\xfd\xab\xcc\x24\xec\x45\x40\x8a\xb2\xbc\xb0\x3f\x09\x61\x67\x02\ +\x52\x94\xd5\x85\x11\x48\x08\xbb\x12\x90\xa2\x2c\x2e\x8c\x41\x42\ +\xd8\x91\x80\x14\x65\x6d\x61\x14\xb7\x5f\x33\x9b\xb0\x35\x01\x29\ +\xca\xd2\xc2\x38\x24\x84\x9d\x08\x48\x51\x56\x16\x46\x22\x21\xec\ +\x42\x40\x8a\xb2\xb0\x30\x16\x09\x61\x07\x02\x52\x94\x75\x85\xd1\ +\xdc\x3e\xcb\x8c\xc2\x56\x04\xa4\x28\xcb\x0a\xe3\x91\x10\x36\x26\ +\x20\x45\x59\x55\x18\x91\x84\xb0\x29\x01\x29\xca\xa2\xc2\x98\x24\ +\x84\x0d\x09\x48\x51\xd6\x14\x46\x75\xf9\x98\x59\x85\xb5\x09\x48\ +\x51\x96\x14\xc6\x25\x21\x6c\x44\x40\x8a\xb2\xa2\x30\x32\x09\x61\ +\x13\x02\x52\x94\x05\x85\xb1\x5d\x5e\x67\x62\x61\x3d\x02\x52\x94\ +\xf5\x84\xd1\x49\x08\xab\x13\x90\xa2\x2c\x27\x8c\x4f\x42\x58\x99\ +\x80\x14\x65\x35\x61\x06\x12\xc2\xaa\x04\xa4\x28\x8b\x09\x73\xb8\ +\x7c\xc8\xe4\xc2\xf2\x04\xa4\x28\x6b\x09\xb3\x90\x10\x56\x23\x20\ +\x45\x59\x4a\x98\x88\x84\xb0\x0e\x01\x29\xca\x46\xc2\x54\x5e\x64\ +\x7e\x61\x49\x02\x52\x94\x7d\x84\xc9\x48\x08\xcb\x13\x90\xa2\x6c\ +\x23\x4c\x47\x42\x58\x9a\x80\x14\x65\x17\x61\x42\x12\xc2\xb2\x04\ +\xa4\x28\x9b\x08\x53\x7a\x9f\x39\x86\x25\x08\x48\x51\xf6\x10\x26\ +\x25\x21\x2c\x47\x40\x8a\xb2\x85\x30\x2d\x09\x61\x29\x02\x52\x94\ +\x1d\x84\x89\x49\x08\xcb\x10\x90\xa2\x6c\x20\x4c\xed\x4d\xe6\x19\ +\xae\x21\x20\x45\xd9\x3f\x98\x9c\x84\x70\x3d\x01\x29\xca\xf6\xc1\ +\xf4\x24\x84\x6b\x09\x48\x51\x76\x0f\x0e\xe0\x31\x53\x0d\x3d\x02\ +\x52\x94\xcd\x83\x43\x90\x10\xae\x21\x20\x45\xd9\x3b\x38\x88\x47\ +\x37\x80\x36\xc3\x53\x94\xad\x83\xc3\x90\x10\xba\x8c\x4e\x51\x76\ +\x0e\x0e\xe4\xe6\x5b\xc6\x1b\x4a\x04\xa4\x28\x1b\x07\x87\x72\xf3\ +\x2e\x03\x0e\x05\x02\x52\x94\x7d\x83\x83\xf1\x14\x42\x9d\x80\x14\ +\x65\xdb\xe0\x70\x3c\x85\x50\x25\x20\x45\xd9\x35\x38\xa0\xb7\x12\ +\x42\x89\x80\x14\x65\xd3\xe0\x90\x24\x84\x0a\x01\x29\xca\x9e\xc1\ +\x41\x49\x08\x4f\x27\x20\x45\xd9\x32\x38\xac\xcf\x2f\x33\xec\xf0\ +\x0b\x02\x52\x94\x1d\x83\x03\x93\x10\x9e\x46\x40\x8a\xb2\x61\x70\ +\x68\x12\xc2\x53\x08\x48\x51\xf6\x0b\x0e\xee\xf3\x97\x8c\x3c\xfc\ +\x90\x80\x14\x65\xbb\xe0\xf0\xee\x24\x84\x5f\x10\x90\xa2\xec\x16\ +\x9c\x80\x84\xf0\x73\x02\x52\x94\xcd\x82\x53\xb8\x7b\x9e\xc1\x87\ +\xef\x10\x90\xa2\xec\x15\x9c\x84\x84\xf0\x63\x02\x52\x94\xad\x82\ +\xd3\x78\x90\x10\x7e\x40\x40\x8a\xb2\x53\x70\x22\x12\xc2\xf7\x09\ +\x48\x51\x36\x0a\x4e\x45\x42\xf8\x1e\x01\x29\xca\x3e\xc1\xc9\x3c\ +\x7c\xca\x0a\xc0\x1f\x04\xa4\x28\xdb\x04\xa7\x73\xff\x2a\x4b\x00\ +\x21\x20\x45\xd9\x25\x38\xa1\x7b\x4f\x21\xfc\x85\x80\x14\x65\x93\ +\xe0\x94\x3c\x85\xf0\x67\x02\x52\x94\x3d\x82\x93\x92\x10\xfe\x4b\ +\x40\x8a\xb2\x45\x70\x5a\x12\xc2\x7f\x08\x48\x51\x76\x08\x4e\xec\ +\x56\x42\xf8\x8d\x80\x14\x65\x83\xe0\xd4\xee\xbf\x66\x21\x38\x35\ +\x01\x29\xca\xfe\xc0\xc9\xdd\x4a\x08\x02\x52\x95\xed\x81\xd3\xbb\ +\x7d\x96\xa5\xe0\xb4\x04\xa4\x28\xbb\x03\x48\xc8\xe9\x09\x48\x51\ +\x36\x07\xf8\x37\x09\x39\x37\x01\x29\xca\xde\x00\xbf\xb9\xfd\x98\ +\xd5\xe0\x84\x04\xa4\x28\x5b\x03\xc4\xc5\x53\xc8\x69\x09\x48\x51\ +\x76\x06\xf8\xc3\xc5\x53\xc8\x49\x09\x48\x51\x36\x06\xf8\x13\x09\ +\x39\x27\x01\x29\xca\xbe\x00\x7f\x71\x79\x9d\x15\xe1\x44\x04\xa4\ +\x28\xdb\x02\xfc\x8d\x84\x9c\x8f\x80\x14\x65\x57\x80\x7f\x90\x90\ +\xb3\x11\x90\xa2\x6c\x0a\xf0\x1d\x12\x72\x2e\x02\x52\x94\x3d\x01\ +\xbe\xeb\xf2\x21\xab\xc2\x09\x08\x48\x51\xb6\x04\xf8\x01\x09\x39\ +\x0f\x01\x29\xca\x8e\x00\x3f\x26\x21\x27\x21\x20\x45\x59\x10\xe0\ +\x67\x5e\x64\x61\x38\x34\x01\x29\xca\x7a\x00\x3f\xe7\x29\xe4\x04\ +\x04\xa4\x28\xcb\x01\xfc\x8a\xa7\x90\xc3\x13\x90\xa2\xac\x06\xf0\ +\x6b\x12\x72\x70\x02\x52\x94\xc5\x00\x9e\xe2\x7d\x16\x87\x43\x12\ +\x90\xa2\xac\x05\xf0\x34\x12\x72\x60\x02\x52\x94\xa5\x00\x9e\x4a\ +\x42\x0e\x4b\x40\x8a\xb2\x12\xc0\xd3\xbd\xc9\xfa\x70\x30\x02\x52\ +\x94\x85\x00\x2a\x24\xe4\x90\x04\xa4\x28\xeb\x00\xd4\x48\xc8\x01\ +\x09\x48\x51\x96\x01\xa8\x92\x90\xc3\x11\x90\xa2\xac\x02\x50\xf7\ +\x98\x35\xe2\x20\x04\xa4\x28\x8b\x00\x74\x48\xc8\xa1\x08\x48\x51\ +\xd6\x00\xe8\x79\x74\x74\x8e\xc3\x7b\x59\x94\x25\x00\xba\x1e\xbf\ +\x65\x9b\x98\x9d\x80\x14\x65\x05\x80\xbe\x1b\x09\x39\x06\x01\x29\ +\xca\x02\x00\xd7\x90\x90\x43\x10\x90\xa2\x8c\x3f\x70\x1d\x09\x39\ +\x00\x01\x29\xca\xf0\x03\xd7\x7a\xfb\x2e\x5b\xc5\xac\x04\xa4\x28\ +\xa3\x0f\x5c\x4f\x42\x26\x27\x20\x45\x19\x7c\x60\x09\x12\x32\x35\ +\x01\x29\xca\xd8\x03\xcb\x90\x90\x89\x09\x48\x51\x86\x1e\x58\xca\ +\xe7\x97\xd9\x2e\x66\x23\x20\x45\x19\x79\x60\x39\x12\x32\x29\x01\ +\x29\xca\xc0\x03\x4b\x92\x90\x29\x09\x48\x51\xc6\x1d\x58\xd6\xdd\ +\x97\xec\x18\xf3\x10\x90\xa2\x0c\x3b\xb0\x34\x09\x99\x8e\x80\x14\ +\x65\xd4\x81\xe5\x49\xc8\x64\x04\xa4\x28\x83\x0e\xac\xe1\xee\x79\ +\x36\x8d\x19\x08\x48\x51\xc6\x1c\x58\x87\x84\x4c\x44\x40\x8a\x32\ +\xe4\xc0\x5a\x1e\x24\x64\x16\x02\x52\x94\x11\x07\xd6\x23\x21\x93\ +\x10\x90\xa2\x0c\x38\xb0\xa6\x87\x4f\xd9\x38\x46\x26\x20\x45\x19\ +\x6f\x60\x5d\xf7\x12\x32\x3e\x01\x29\xca\x70\x03\x6b\xf3\x14\x32\ +\x3c\x01\x29\xca\x68\x03\xeb\xf3\x14\x32\x38\x01\x29\xca\x60\x03\ +\x5b\xb8\x7f\x95\xcd\x63\x44\x02\x52\x94\xb1\x06\xb6\x21\x21\x03\ +\x13\x90\xa2\x0c\x35\xb0\x15\x09\x19\x96\x80\x14\x65\xa4\x81\xed\ +\xdc\x4a\xc8\x98\x04\xa4\x28\x03\x0d\x6c\xe9\xfe\x6b\x36\x90\x91\ +\x08\x48\x51\xc6\x19\xd8\xd6\xad\x84\x8c\x47\x40\x8a\x32\xcc\xc0\ +\xd6\x24\x64\x38\x02\x52\x94\x51\x06\xb6\x77\xfb\x2c\x7b\xc8\x18\ +\x04\xa4\x28\x83\x0c\xec\x41\x42\x86\x22\x20\x45\x19\x63\x60\x1f\ +\xb7\x1f\xb3\x8b\xec\x4f\x40\x8a\x32\xc4\xc0\x5e\x2e\x9e\x42\x46\ +\x21\x20\x45\x19\x61\x60\x3f\x17\x4f\x21\x63\x10\x90\xa2\x0c\x30\ +\xb0\x27\x09\x19\x82\x80\x14\x65\x7c\x81\x7d\x49\xc8\x00\x04\xa4\ +\x28\xc3\x0b\xec\xed\xf2\x3a\x5b\xc9\x5e\x04\xa4\x28\xa3\x0b\xec\ +\x4f\x42\x76\x26\x20\x45\x19\x5c\x60\x04\x12\xb2\x2b\x01\x29\xca\ +\xd8\x02\x63\x90\x90\x1d\x09\x48\x51\x86\x16\x18\xc5\xe5\x43\xb6\ +\x93\xad\x09\x48\x51\x46\x16\x18\x88\x84\xec\x43\x40\x8a\x32\xaf\ +\xc0\x48\x7c\x77\xfa\x2e\x04\xa4\x28\xe3\x0a\x8c\xc5\x2f\xbe\xdd\ +\x81\x80\x14\x65\x58\x81\xd1\xdc\x7d\xcb\x96\xb2\x15\x01\x29\xca\ +\xa8\x02\xe3\x79\x91\x35\x65\x23\x02\x52\x94\x41\x05\x06\x74\xfb\ +\x25\x8b\xca\x26\x04\xa4\x28\x73\x0a\x0c\xe9\x4d\x36\x95\x2d\x08\ +\x48\x51\xa6\x14\x18\xd3\xbd\xa3\xb6\x1d\xaf\x75\x51\x86\x14\x18\ +\xd5\xd7\x2c\x2b\xab\x13\x90\xa2\x8c\x28\x30\xac\xc7\x6c\x2b\x6b\ +\x13\x90\xa2\x4c\x28\x30\xae\xbb\xac\x2b\x2b\x13\x90\xa2\x0c\x28\ +\x30\xb0\x5b\x97\x6d\x13\x5e\xe6\xa2\xcc\x27\x30\xb2\xcb\xf3\x6c\ +\x2c\x6b\x12\x90\xa2\x8c\x27\x30\xb6\x4f\x59\x59\x56\x24\x20\x45\ +\x19\x4e\x60\x70\x7e\x36\xd6\xfa\x04\xa4\x28\xb3\x09\x8c\xce\x97\ +\xf3\xae\x4e\x40\x8a\x32\x9a\xc0\xf0\x14\x64\x6d\x02\x52\x94\xc9\ +\x04\xc6\xe7\x33\xe9\x2b\x13\x90\xa2\x0c\x26\x30\x81\x97\xd9\x5b\ +\xd6\x21\x20\x45\x99\x4b\x60\x02\x17\x17\x6e\x55\x5e\xde\xa2\xcc\ +\x25\x30\x83\xdb\x2c\x2e\xab\x10\x90\xa2\x8c\x25\x30\x05\x3f\xd5\ +\x64\x4d\x02\x52\x94\xa9\x04\xe6\xf0\x3e\xab\xcb\x0a\x04\xa4\x28\ +\x43\x09\x4c\xc2\x37\x14\xae\x47\x40\x8a\x32\x93\xc0\x2c\xbe\x65\ +\x79\x59\x9c\x80\x14\x65\x24\x81\x59\x3c\x64\x79\x59\x9c\x80\x14\ +\x65\x24\x81\x69\xbc\xc8\xf6\xb2\x34\x01\x29\xca\x44\x02\xf3\xf0\ +\xfd\x84\x2b\x11\x90\xa2\x0c\x24\x30\x8f\xfb\xac\x2f\x0b\x13\x90\ +\xa2\x0c\x24\x30\x91\x0f\xd9\x5f\x96\x25\x20\x45\x99\x47\x60\x26\ +\xd9\x5f\x96\x25\x20\x45\x19\x47\x60\x26\x6f\xb3\xc0\x2c\x4a\x40\ +\x8a\x32\x8e\xc0\x54\xbe\x64\x83\x59\x92\x80\x14\x65\x1a\x81\xa9\ +\xf8\x3c\xfa\x1a\x04\xa4\x28\xd3\x08\xcc\xc5\xaf\x27\x5c\x81\x80\ +\x14\x65\x18\x81\xb9\x78\x04\x59\x81\x80\x14\x65\x18\x81\xc9\xf8\ +\xa1\x8a\xcb\x13\x90\xa2\xcc\x22\x30\x19\xbf\x5b\x6a\x79\x02\x52\ +\x94\x59\x04\x66\xe3\x11\x64\x71\x02\x52\x94\x51\x04\x66\xe3\xa7\ +\xf2\x2e\x4e\x40\x8a\x32\x8a\xc0\x74\xde\x65\x8b\x59\x8a\x80\x14\ +\x65\x12\x81\xe9\xbc\xc9\x16\xb3\x14\x01\x29\xca\x24\x02\xf3\xc9\ +\x16\xb3\x14\x01\x29\xca\x20\x02\xf3\x79\x96\x35\x66\x21\x02\x52\ +\x94\x41\x04\xe6\x73\x97\x35\x66\x21\x02\x52\x94\x41\x04\x26\x94\ +\x35\x66\x21\x02\x52\x94\x39\x04\x26\xe4\xdf\xb0\x96\x25\x20\x45\ +\x99\x43\x60\x42\xfe\x0d\x6b\x59\x02\x52\x94\x39\x04\x66\x94\x3d\ +\x66\x19\x02\x52\x94\x31\x04\x66\xe4\xc7\x99\x2c\x4a\x40\x8a\x32\ +\x86\xc0\x8c\x7c\x2f\xe1\xa2\x04\xa4\x28\x63\x08\xcc\xc8\x8f\xe4\ +\x5d\x94\x80\x14\x65\x0c\x81\x29\x65\x91\x59\x84\x80\x14\x65\x0a\ +\x81\x29\xf9\x24\xc8\x92\x04\xa4\x28\x53\x08\x4c\xe9\x7d\x36\x99\ +\x25\x08\x48\x51\xa6\x10\x98\x92\xef\x04\x59\x92\x80\x14\x65\x0a\ +\x81\x39\x65\x93\x59\x82\x80\x14\x65\x08\x81\x39\x65\x93\x59\x82\ +\x80\x14\x65\x08\x81\x39\x3d\xcf\x2a\xb3\x00\x01\x29\xca\x10\x02\ +\x73\xfa\x98\x55\x66\x01\x02\x52\x94\x21\x04\xe6\xf4\x22\xab\xcc\ +\x02\x04\xa4\x28\x43\x08\xcc\xe9\x31\xab\xcc\x02\x04\xa4\x28\x43\ +\x08\xcc\xc9\xd7\xf1\x2e\x48\x40\x8a\x32\x84\xc0\x9c\xfc\x34\xac\ +\x05\x09\x48\x51\x86\x10\x98\x54\x56\x99\x05\x08\x48\x51\x66\x10\ +\x98\x54\x56\x99\x05\x08\x48\x51\x66\x10\x98\x54\x56\x99\x05\x08\ +\x48\x51\x66\x10\x98\x54\x56\x99\x05\x08\x48\x51\x66\x10\x98\x54\ +\x56\x99\x05\x08\x48\x51\x66\x10\x98\xd4\xb7\xec\x32\xd7\x13\x90\ +\xa2\xcc\x20\x30\x29\x47\x6f\x39\x5e\xcb\xa2\xcc\x20\x30\xa9\xac\ +\x32\x0b\x10\x90\xa2\xcc\x20\x30\xa9\xac\x32\x0b\x10\x90\xa2\xcc\ +\x20\x30\xa9\xac\x32\x0b\x10\x90\xa2\xcc\x20\x30\xa9\xac\x32\x0b\ +\x10\x90\xa2\xcc\x20\x30\xa9\xac\x32\x0b\x10\x90\xa2\xcc\x20\x30\ +\x27\x3f\x4c\x71\x41\x02\x52\x94\x21\x04\xe6\xf4\x39\xab\xcc\x02\ +\x04\xa4\x28\x43\x08\xcc\xc9\x2f\x94\x5a\x90\x80\x14\x65\x08\x81\ +\x39\xf9\x95\xb6\x0b\x12\x90\xa2\x0c\x21\x30\xa7\x67\x59\x65\x16\ +\x20\x20\x45\x19\x42\x60\x4e\x5f\xb2\xca\x2c\x40\x40\x8a\x32\x84\ +\xc0\x9c\xb2\xc9\x2c\x41\x40\x8a\x32\x84\xc0\x94\x2e\xd9\x64\x96\ +\x20\x20\x45\x99\x42\x60\x4a\xbe\x8a\x77\x49\x02\x52\x94\x29\x04\ +\xa6\xe4\x8b\xb0\x96\x24\x20\x45\x99\x42\x60\x4a\x9f\xb2\xc9\x2c\ +\x41\x40\x8a\x32\x85\xc0\x94\xb2\xc8\x2c\x42\x40\x8a\x32\x85\xc0\ +\x8c\xee\xb3\xc8\x2c\x42\x40\x8a\x32\x86\xc0\x8c\xde\x67\x91\x59\ +\x84\x80\x14\x65\x0c\x81\x19\xf9\x14\xc8\xa2\x04\xa4\x28\x63\x08\ +\xcc\x28\x7b\xcc\x32\x04\xa4\x28\x63\x08\x4c\xe8\x6d\xf6\x98\x65\ +\x08\x48\x51\xe6\x10\x98\xd0\xd7\xec\x31\xcb\x10\x90\xa2\xcc\x21\ +\x30\xa1\xac\x31\x0b\x11\x90\xa2\xcc\x21\x30\x1f\x3f\xc7\x64\x61\ +\x02\x52\x94\x41\x04\xe6\xf3\x2a\x6b\xcc\x42\x04\xa4\x28\x83\x08\ +\x4c\xc7\x4f\xe2\x5d\x9a\x80\x14\x65\x12\x81\xe9\xf8\x41\x8a\x4b\ +\x13\x90\xa2\x4c\x22\x30\x1d\xe7\x6e\x69\x5e\xd1\xa2\x4c\x22\x30\ +\x9b\xbb\x2c\x31\x8b\x11\x90\xa2\x8c\x22\x30\x9b\xe7\x59\x62\x16\ +\x23\x20\x45\x19\x45\x60\x32\x0f\xd9\x61\x96\x23\x20\x45\x99\x45\ +\x60\x32\x7e\x8e\xe2\xf2\x04\xa4\x28\xb3\x08\xcc\xc5\x6f\x02\x59\ +\x81\x80\x14\x65\x18\x81\xb9\xf8\x26\xc2\x15\x08\x48\x51\x86\x11\ +\x98\x8a\x2f\xc1\x5a\x83\x80\x14\x65\x1a\x81\xa9\xbc\xcc\x06\xb3\ +\x24\x01\x29\xca\x34\x02\x33\x79\xcc\x02\xb3\x28\x01\x29\xca\x38\ +\x02\x33\xc9\xfe\xb2\x2c\x01\x29\xca\x38\x02\x13\x79\x9d\xfd\x65\ +\x59\x02\x52\x94\x79\x04\xe6\xe1\x7b\x08\x57\x22\x20\x45\x19\x48\ +\x60\x1e\xdf\xb2\xbe\x2c\x4c\x40\x8a\x32\x90\xc0\x34\x3e\x66\x7b\ +\x59\x9a\x80\x14\x65\x22\x81\x59\xf8\x16\x90\xd5\x08\x48\x51\x46\ +\x12\x98\x84\xdf\x43\xb8\x1e\x01\x29\xca\x4c\x02\x93\xf0\x53\xdc\ +\xd7\x23\x20\x45\x99\x49\x60\x0e\xbe\x82\x77\x45\x02\x52\x94\xa1\ +\x04\xa6\xf0\x36\x9b\xcb\x1a\x04\xa4\x28\x53\x09\xcc\xc0\x0f\x71\ +\x5f\x95\x80\x14\x65\x2c\x81\x09\xdc\x66\x6f\x59\x87\x80\x14\x65\ +\x2e\x81\xf1\x5d\x1c\xb8\x75\x79\x7d\x8b\x32\x98\xc0\xf8\xde\x65\ +\x6d\x59\x89\x80\x14\x65\x30\x81\xe1\x7d\xc9\xd6\xb2\x16\x01\x29\ +\xca\x64\x02\xa3\xf3\x3b\xa4\x56\x27\x20\x45\x19\x4d\x60\x6c\x17\ +\xfd\x58\x9f\x80\x14\x65\x38\x81\xa1\x5d\x7c\xfe\x63\x03\x02\x52\ +\x94\xe9\x04\x46\xe6\xfb\x3f\x36\x21\x20\x45\x19\x4f\x60\x60\x9f\ +\xb3\xaf\xac\x4b\x40\x8a\x32\x9f\xc0\xb8\xde\x64\x5d\x59\x99\x80\ +\x14\x65\x40\x81\x61\x3d\xcb\xb6\xb2\x36\x01\x29\xca\x84\x02\x83\ +\xba\xf7\x0b\x6c\x37\x23\x20\x45\x99\x51\x60\x4c\xfe\xf9\x6a\x43\ +\x02\x52\x94\x21\x05\x46\x74\xf9\x94\x4d\x65\x0b\x02\x52\x94\x31\ +\x05\x06\xe4\xf1\x63\x5b\x02\x52\x94\x39\x05\x86\x73\xef\x9b\xcf\ +\x37\x26\x20\x45\x99\x54\x60\x30\x17\xbf\xbc\x76\x73\x02\x52\x94\ +\x59\x05\xc6\xf2\x22\x2b\xca\x86\x04\xa4\x28\xc3\x0a\x8c\xc4\x27\ +\x3f\x76\x21\x20\x45\x19\x57\x60\x1c\x8f\xbe\xf5\x63\x1f\x02\x52\ +\x94\x81\x05\x46\xf1\xe8\x8c\xed\xc5\x2b\x5f\x94\x91\x05\xc6\xf0\ +\x98\xd5\x64\x07\x02\x52\x94\xa1\x05\x46\x20\x1f\xbb\x12\x90\xa2\ +\x8c\x2d\xb0\x3f\x9f\x3a\xdf\x99\x80\x14\x65\x70\x81\xbd\xc9\xc7\ +\xee\x04\xa4\x28\xa3\x0b\xec\x4b\x3e\x06\x20\x20\x45\x19\x5e\x60\ +\x4f\xef\xb3\x90\xec\x4a\x40\x8a\x32\xbe\xc0\x7e\x3c\x7d\x0c\x42\ +\x40\x8a\x32\xc0\xc0\x5e\x3c\x7d\x0c\x43\x40\x8a\x32\xc2\xc0\x3e\ +\xe4\x63\x20\x02\x52\x94\x21\x06\xf6\x20\x1f\x43\x11\x90\xa2\x8c\ +\x31\xb0\x3d\x3f\x71\x77\x30\x02\x52\x94\x41\x06\xb6\x26\x1f\xc3\ +\x11\x90\xa2\x8c\x32\xb0\x2d\xf9\x18\x90\x80\x14\x65\x98\x81\x2d\ +\xc9\xc7\x90\x04\xa4\x28\xe3\x0c\x6c\xe7\x43\xd6\x8f\xc1\x08\x48\ +\x51\x06\x1a\xd8\xc8\x45\x3e\x86\x25\x20\x45\x99\x69\x60\x13\xf2\ +\x31\x32\x01\x29\xca\x54\x03\x1b\x90\x8f\xb1\x09\x48\x51\xe6\x1a\ +\x58\xdd\xe5\x75\xd6\x8e\x41\x09\x48\x51\x26\x1b\x58\x99\x7c\x8c\ +\x4f\x40\x8a\x32\xdb\xc0\xaa\xe4\x63\x06\x02\x52\x94\xe9\x06\x56\ +\x24\x1f\x73\x10\x90\xa2\xcc\x37\xb0\x9a\xcb\xc7\xac\x1b\x83\x13\ +\x90\xa2\x4c\x38\xb0\x12\xf9\x98\x87\x80\x14\x65\xc6\x81\x55\xc8\ +\xc7\x4c\x04\xa4\x28\x53\x0e\xac\xe0\xf6\x59\x16\x8d\x29\x08\x48\ +\x51\xe6\x1c\x58\xdc\xad\xa7\x8f\xc9\x08\x48\x51\x26\x1d\x58\x98\ +\xa7\x8f\xf9\x08\x48\x51\x66\x1d\x58\x94\x7c\xcc\x48\x40\x8a\x32\ +\xed\xc0\x82\xe4\x63\x4e\x02\x52\x94\x79\x07\x16\x73\xfb\x35\xeb\ +\xc5\x64\x04\xa4\x28\x13\x0f\x2c\x44\x3e\xe6\x25\x20\x45\x99\x79\ +\x60\x11\xf2\x31\x33\x01\x29\xca\xd4\x03\x0b\x90\x8f\xb9\x09\x48\ +\x51\xe6\x1e\xb8\xda\xfd\xab\xac\x15\x93\x12\x90\xa2\x4c\x3e\x70\ +\x25\xf9\x98\x9f\x80\x14\x65\xf6\x81\xab\xc8\xc7\x11\x08\x48\x51\ +\xa6\x1f\xb8\xc2\xfd\xa7\x2c\x14\x53\x13\x90\xa2\xcc\x3f\xd0\xe6\ +\xe9\xe3\x28\x04\xa4\x28\x1b\x00\x34\x3d\x78\xfa\x38\x0c\x01\x29\ +\xca\x0e\x00\x2d\x0f\xcf\xb3\x4a\x1c\x80\x80\x14\x65\x0b\x80\x06\ +\x4f\x1f\xc7\x22\x20\x45\xd9\x03\xa0\xec\xce\xd3\xc7\xc1\x08\x48\ +\x51\x36\x01\x28\xf2\x8f\x57\xc7\x23\x20\x45\xd9\x05\xa0\xc4\xd3\ +\xc7\x11\x09\x48\x51\xb6\x01\x28\x90\x8f\x63\x12\x90\xa2\xec\x03\ +\xf0\x64\x77\x5f\xb2\x3e\x1c\x8c\x80\x14\x65\x23\x80\x27\x92\x8f\ +\xe3\x12\x90\xa2\xec\x04\xf0\x24\x9f\xe5\xe3\xc0\x04\xa4\x28\x5b\ +\x01\x3c\xc1\xe7\x97\x59\x1c\x0e\x49\x40\x8a\xb2\x17\xc0\x2f\xc9\ +\xc7\xd1\x09\x48\x51\x36\x03\xf8\x05\xf9\x38\x3e\x01\x29\xca\x6e\ +\x00\x3f\xf5\x56\x3e\x4e\x40\x40\x8a\xb2\x1d\xc0\x4f\xc8\xc7\x39\ +\x08\x48\x51\xf6\x03\xf8\xa1\xb7\xef\xb2\x2e\x1c\x9c\x80\x14\x65\ +\x43\x80\x1f\x90\x8f\xf3\x10\x90\xa2\xec\x08\xf0\x5d\xf2\x71\x26\ +\x02\x52\x94\x2d\x01\xbe\xe3\xe6\x5b\x16\x85\x53\x10\x90\xa2\xec\ +\x09\xf0\x0f\x37\x9e\x3e\x4e\x46\x40\x8a\xb2\x29\xc0\xdf\x78\xfa\ +\x38\x1f\x01\x29\xca\xae\x00\x7f\xf1\xe8\x96\x9c\x90\x37\xbd\x28\ +\xdb\x02\xfc\xc9\x8d\x4b\x72\x4a\xde\xf6\xa2\xec\x0b\xf0\x07\x4f\ +\x1f\x67\xe5\x8d\x2f\xca\xc6\x00\xf1\x26\xbb\xc1\xf9\x08\x48\x51\ +\x76\x06\xf8\xcd\x63\x36\x83\x33\x12\x90\xa2\x6c\x0d\xf0\x6f\x9e\ +\x3e\xce\x4d\x40\x8a\xb2\x37\x80\x7c\x9c\x9e\x80\x14\x65\x73\xe0\ +\xf4\xe4\x03\x01\x29\xca\xee\xc0\xc9\xbd\xcf\x46\x70\x66\x02\x52\ +\x94\xed\x81\x53\x93\x0f\xfe\x9f\x80\x14\x65\x7f\xe0\xc4\xe4\x83\ +\xdf\x09\x48\x51\x36\x08\x4e\x4b\x3e\xf8\x0f\x01\x29\xca\x0e\xc1\ +\x49\xbd\xc8\x26\x80\x80\x94\x65\x8b\xe0\x94\xe4\x83\x3f\x13\x90\ +\xa2\xec\x11\x9c\x90\x7c\xf0\x57\x02\x52\x94\x4d\x82\xd3\xf9\x90\ +\x1d\x80\xff\x10\x90\xa2\xec\x12\x9c\x8c\xa7\x0f\xfe\x49\x40\x8a\ +\xb2\x4d\x70\x2a\x9e\x3e\xf8\x1e\x01\x29\xca\x3e\xc1\x79\x5c\xe4\ +\x83\xef\x13\x90\xa2\xac\x14\x9c\x85\x7c\xf0\x43\x02\x52\x94\xa5\ +\x82\x73\xb8\xbc\xce\xe4\xc3\x3f\x09\x48\x51\xd6\x0a\xce\x40\x3e\ +\xf8\x29\x01\x29\xca\x62\xc1\xf1\xc9\x07\xbf\x20\x20\x45\x59\x2d\ +\x38\x3a\xf9\xe0\x97\x04\xa4\x28\xcb\x05\xc7\x76\xf9\x98\x89\x87\ +\x1f\x13\x90\xa2\xac\x17\x1c\x99\x7c\xf0\x24\x02\x52\x94\x05\x83\ +\xe3\x92\x0f\x9e\x48\x40\x8a\xb2\x62\x70\x54\xf2\xc1\x93\x09\x48\ +\x51\x96\x0c\x8e\xe9\xf6\x59\x26\x1d\x7e\x4d\x40\x8a\xb2\x66\x70\ +\x44\xf2\x41\x89\x80\x14\x65\xd1\xe0\x78\xe4\x83\x22\x01\x29\xca\ +\xaa\xc1\xd1\xc8\x07\x65\x02\x52\x94\x65\x83\x63\xb9\xfd\x9a\x09\ +\x87\xa7\x13\x90\xa2\xac\x1b\x1c\x89\x7c\xd0\x22\x20\x45\x59\x38\ +\x38\x8e\x7b\xf9\xa0\x47\x40\x8a\xb2\x72\x70\x14\xb7\xaf\x32\xdb\ +\x50\x25\x20\x45\x59\x3a\x38\x86\x7b\xf9\xa0\x4f\x40\x8a\xb2\x76\ +\x70\x04\xf2\xc1\x55\x04\xa4\x28\x8b\x07\xf3\x93\x0f\xae\x24\x20\ +\x45\x59\x3d\x98\x9d\x7c\x70\x35\x01\x29\xca\xf2\xc1\xdc\xee\x3f\ +\x65\xa2\xa1\x4f\x40\x8a\xb2\x7e\x30\xb3\x07\xf9\x60\x09\x02\x52\ +\x94\x05\x84\x79\x79\xfa\x60\x21\x02\x52\x94\x15\x84\x59\x79\xfa\ +\x60\x31\x02\x52\x94\x25\x84\x39\x3d\x3c\xcf\x24\xc3\xf5\x04\xa4\ +\x28\x6b\x08\x33\x92\x0f\x16\x25\x20\x45\x59\x44\x98\xcf\x9d\x7c\ +\xb0\x2c\x01\x29\xca\x2a\xc2\x6c\xe4\x83\xc5\x09\x48\x51\x96\x11\ +\xe6\x22\x1f\xac\x40\x40\x8a\xb2\x8e\x30\x93\xbb\x2f\x99\x5f\x58\ +\x92\x80\x14\x65\x21\x61\x1e\xf2\xc1\x4a\x04\xa4\x28\x2b\x09\xb3\ +\x90\x0f\x56\x23\x20\x45\x59\x4a\x98\xc3\xe7\x97\x99\x5c\x58\x9e\ +\x80\x14\x65\x2d\x61\x06\xf2\xc1\xaa\x04\xa4\x28\x8b\x09\xe3\x93\ +\x0f\x56\x26\x20\x45\x59\x4d\x18\xdd\xdb\x77\x99\x59\x58\x8b\x80\ +\x14\x65\x39\x61\x6c\xf2\xc1\x06\x04\xa4\x28\xeb\x09\x23\x93\x0f\ +\x36\x21\x20\x45\x59\x50\x18\x97\x7c\xb0\x11\x01\x29\xca\x8a\xc2\ +\xa8\xe4\x83\xcd\x08\x48\x51\x96\x14\xc6\x74\xf3\x2d\x93\x0a\xeb\ +\x13\x90\xa2\xac\x29\x8c\x48\x3e\xd8\x94\x80\x14\x65\x51\x61\x3c\ +\xf2\xc1\xc6\x04\xa4\x28\xab\x0a\xa3\x79\x94\x0f\xb6\x26\x20\x45\ +\x59\x56\x18\xcb\xa3\x55\x66\x7b\xa6\xae\x28\xeb\x0a\x23\x79\xcc\ +\x78\xc2\xa6\x04\xa4\x28\x0b\x0b\xe3\x90\x0f\x76\x22\x20\x45\x59\ +\x59\x18\xc5\x9b\x8c\x26\x6c\x4e\x40\x8a\xb2\xb4\x30\x06\xf9\x60\ +\x47\x02\x52\x94\xb5\x85\x11\xc8\x07\xbb\x12\x90\xa2\x2c\x2e\xec\ +\x4f\x3e\xd8\x99\x80\x14\x65\x75\x61\x6f\xf2\xc1\xee\x04\xa4\x28\ +\xcb\x0b\xfb\x7a\x9f\x81\x84\x1d\x09\x48\x51\xd6\x17\xf6\x24\x1f\ +\x0c\x41\x40\x8a\xb2\xc0\xb0\x1f\xf9\x60\x10\x02\x52\x94\x15\x86\ +\xbd\xbc\xc8\x28\xc2\xee\x04\xa4\x28\x4b\x0c\xfb\x90\x0f\x06\x22\ +\x20\x45\x59\x63\xd8\x83\x7c\x30\x14\x01\x29\xca\x22\xc3\xf6\x3e\ +\x64\x08\x61\x10\x02\x52\x94\x55\x86\xad\x79\xfa\x60\x38\x02\x52\ +\x94\x65\x86\x6d\x79\xfa\x60\x40\x02\x52\x94\x75\x86\x0d\x5d\xe4\ +\x83\x21\x09\x48\x51\x36\x1a\x36\x23\x1f\x8c\x4a\x40\x8a\xb2\xd3\ +\xb0\x91\xcb\xeb\x8c\x1e\x0c\x47\x40\x8a\xb2\xd5\xb0\x09\xf9\x60\ +\x64\x02\x52\x94\xbd\x86\x0d\xc8\x07\x63\x13\x90\xa2\x6c\x36\xac\ +\x4e\x3e\x18\x9d\x80\x14\x65\xb7\x61\x65\x97\x8f\x19\x39\x18\x96\ +\x80\x14\x65\xbb\x61\x55\xf2\xc1\x0c\x04\xa4\x28\xfb\x0d\x2b\x92\ +\x0f\xe6\x20\x20\x45\xd9\x70\x58\xcd\xe5\x59\x86\x0d\x06\x27\x20\ +\x45\xd9\x71\x58\xc9\xad\xa7\x0f\xa6\x21\x20\x45\xd9\x72\x58\xc5\ +\xad\xa7\x0f\x26\x22\x20\x45\xd9\x73\x58\x81\x7c\x30\x17\x01\x29\ +\xca\xa6\xc3\xe2\xe4\x83\xd9\x08\x48\x51\x76\x1d\x16\x76\xfb\x35\ +\x23\x06\xd3\x10\x90\xa2\x6c\x3b\x2c\x4a\x3e\x98\x91\x80\x14\x65\ +\xdf\x61\x41\xf2\xc1\x9c\x04\xa4\x28\x1b\x0f\x8b\x91\x0f\x66\x25\ +\x20\x45\xd9\x79\x58\xc8\xfd\xab\x8c\x16\x4c\x47\x40\x8a\xb2\xf5\ +\xb0\x08\xf9\x60\x66\x02\x52\x94\xbd\x87\x05\xc8\x07\x73\x13\x90\ +\xa2\x6c\x3e\x5c\xed\xfe\x53\x86\x0a\x26\x25\x20\x45\xd9\x7d\xb8\ +\x92\xa7\x0f\xe6\x27\x20\x45\xd9\x7e\xb8\xca\x83\xa7\x0f\x0e\x40\ +\x40\x8a\xb2\xff\x70\x85\x87\xe7\x19\x27\x98\x9a\x80\x14\xe5\x02\ +\x40\x9b\xa7\x0f\x8e\x42\x40\x8a\x72\x03\xa0\xe9\xce\xd3\x07\x87\ +\x21\x20\x45\xb9\x02\xd0\xe2\x1f\xaf\x38\x12\x01\x29\xca\x1d\x80\ +\x06\x4f\x1f\x1c\x8b\x80\x14\xe5\x12\x40\x99\x7c\x70\x34\x02\x52\ +\x94\x5b\x00\x45\x77\x5f\x32\x42\x70\x18\x02\x52\x94\x6b\x00\x25\ +\xf2\xc1\x11\x09\x48\x51\xee\x01\x14\x7c\x96\x0f\x0e\x49\x40\x8a\ +\x72\x11\xe0\xc9\x3e\xbf\xcc\xf0\xc0\xc1\x08\x48\x51\x6e\x02\x3c\ +\x91\x7c\x70\x5c\x02\x52\x94\xab\x00\x4f\x22\x1f\x1c\x99\x80\x14\ +\xe5\x2e\xc0\x13\xbc\x95\x0f\x0e\x4d\x40\x8a\x72\x19\xe0\x97\xe4\ +\x83\xa3\x13\x90\xa2\xdc\x06\xf8\x85\xb7\xef\x32\x32\x70\x58\x02\ +\x52\x94\xeb\x00\x3f\x25\x1f\x9c\x81\x80\x14\xe5\x3e\xc0\x4f\xdc\ +\xc8\x07\xa7\x20\x20\x45\xb9\x10\xf0\x43\x37\xdf\x32\x2c\x70\x70\ +\x02\x52\x94\x1b\x01\x3f\xe0\xe9\x83\xf3\x10\x90\xa2\x5c\x09\xf8\ +\x2e\x4f\x1f\x9c\x89\x80\x14\xe5\x4e\xc0\x77\x3c\xda\x27\x4e\xc5\ +\xc0\x17\xe5\x52\xc0\x3f\xdc\xd8\x26\x4e\xc6\xc8\x17\xe5\x56\xc0\ +\xdf\x78\xfa\xe0\x7c\x0c\x7d\x51\xae\x05\xfc\xc5\x9b\xcc\x07\x9c\ +\x89\x80\x14\xe5\x5e\xc0\x9f\x3c\x66\x3a\xe0\x5c\x04\xa4\x28\x17\ +\x03\xfe\xe0\xe9\x83\xb3\x12\x90\xa2\xdc\x0c\x08\xf9\xe0\xbc\x04\ +\xa4\x28\x57\x03\x7e\x23\x1f\x9c\x99\x80\x14\xe5\x6e\xc0\xbf\xbd\ +\xcf\x54\xc0\x39\x09\x48\x51\x2e\x07\xc8\x07\xa7\x27\x20\x45\xb9\ +\x1d\x9c\x9e\x7c\x80\x80\x14\xe5\x7a\x70\x72\xf2\x01\x02\x52\x96\ +\xfb\xc1\xa9\xbd\xc8\x34\xc0\xb9\x09\x48\x51\x2e\x08\x27\x26\x1f\ +\xf0\x3b\x01\x29\xca\x0d\xe1\xb4\xe4\x03\xfe\x43\x40\x8a\x72\x45\ +\x38\x29\xf9\x80\xff\x12\x90\xa2\xdc\x11\x4e\x49\x3e\xe0\xcf\x04\ +\xa4\x28\x97\x84\x13\xfa\x90\x19\x00\x7e\x27\x20\x45\xb9\x25\x9c\ +\xcd\x45\x3e\xe0\xef\x04\xa4\x28\xe7\x84\x73\x91\x0f\xf8\x0e\x01\ +\x29\xca\x41\xe1\x4c\x2e\xaf\xf3\xee\x03\x7f\x26\x20\x45\x39\x29\ +\x9c\x87\x7c\xc0\x0f\x08\x48\x51\x8e\x0a\x67\x21\x1f\xf0\x43\x02\ +\x52\x94\xb3\xc2\x39\xc8\x07\xfc\x84\x80\x14\xe5\xb0\x70\x06\x97\ +\x8f\x79\xd7\x81\xef\x11\x90\xa2\x9c\x16\x8e\x4f\x3e\xe0\x17\x04\ +\xa4\x28\xc7\x85\xa3\x93\x0f\xf8\x25\x01\x29\xca\x79\xe1\xd8\xe4\ +\x03\x9e\x40\x40\x8a\x72\x60\x38\xb2\xdb\x67\x79\xb7\x81\x9f\x11\ +\x90\xa2\x9c\x18\x8e\x4b\x3e\xe0\x89\x04\xa4\x28\x47\x86\xa3\x92\ +\x0f\x78\x32\x01\x29\xca\x99\xe1\x98\xe4\x03\x0a\x04\xa4\x28\x87\ +\x86\x23\xba\xfd\x9a\x77\x19\x78\x0a\x01\x29\xca\xa9\xe1\x78\xe4\ +\x03\x8a\x04\xa4\x28\xc7\x86\xa3\xb9\x97\x0f\xa8\x12\x90\xa2\x9c\ +\x1b\x8e\xc5\xd3\x07\x34\x08\x48\x51\x0e\x0e\x47\x22\x1f\xd0\x22\ +\x20\x45\x39\x39\x1c\xc7\xfd\xab\xbc\xb7\x40\x8d\x80\x14\xe5\xe8\ +\x70\x14\xf2\x01\x6d\x02\x52\x94\xb3\xc3\x31\xc8\x07\x5c\x41\x40\ +\x8a\x72\x78\x38\x82\xfb\x4f\x79\x57\x81\x0e\x01\x29\xca\xe9\x61\ +\x7e\x0f\xf2\x01\xd7\x11\x90\xa2\x1c\x1f\x66\xe7\xe9\x03\xae\x26\ +\x20\x45\x39\x3f\xcc\xcd\xd3\x07\x2c\x40\x40\x8a\x72\x80\x98\xd9\ +\xc3\xf3\xbc\x9b\xc0\x35\x04\xa4\x28\x27\x88\x79\xdd\xc9\x07\x2c\ +\x43\x40\x8a\x72\x84\x98\x95\xa7\x0f\x58\x8c\x80\x14\xe5\x0c\x31\ +\x27\x4f\x1f\xb0\x20\x01\x29\xca\x21\x62\x46\xf2\x01\x8b\x12\x90\ +\xa2\x9c\x22\xe6\x73\xf7\x25\xef\x21\xb0\x0c\x01\x29\xca\x31\x62\ +\x36\xf2\x01\x8b\x13\x90\xa2\x9c\x23\xe6\x22\x1f\xb0\x02\x01\x29\ +\xca\x41\x62\x26\x9f\x5f\xe6\xdd\x03\x96\x24\x20\x45\x39\x49\xcc\ +\x43\x3e\x60\x25\x02\x52\x94\xa3\xc4\x2c\xe4\x03\x56\x23\x20\x45\ +\x39\x4b\xcc\xe1\xed\xbb\xbc\x6f\xc0\xf2\x04\xa4\x28\x87\x89\x19\ +\xbc\xf5\xf4\x01\x6b\x12\x90\xa2\x9c\x26\xc6\xe7\xe9\x03\x56\x26\ +\x20\x45\x39\x4e\x8c\x4e\x3e\x60\x75\x02\x52\x94\xf3\xc4\xd8\xe4\ +\x03\x36\x20\x20\x45\x39\x50\x8c\xec\xe6\x5b\xde\x2d\x60\x4d\x02\ +\x52\x94\x13\xc5\xb8\xe4\x03\x36\x22\x20\x45\x39\x52\x8c\x4a\x3e\ +\x60\x33\x02\x52\x94\x33\xc5\x98\x1e\xe5\x03\xb6\x23\x20\x45\x39\ +\x54\x8c\xe8\xd1\x38\xc3\x96\x6c\x5c\x51\x4e\x15\xe3\x79\xcc\x5b\ +\x04\x6c\x44\x40\x8a\x72\xac\x18\xcd\x9b\xbc\x41\xc0\x66\x04\xa4\ +\x28\xe7\x8a\xb1\x78\xfa\x80\x1d\x08\x48\x51\x0e\x16\x23\xf1\xf4\ +\x01\xbb\x10\x90\xa2\x9c\x2c\xc6\x21\x1f\xb0\x13\x01\x29\xca\xd1\ +\x62\x14\xf2\x01\xbb\x11\x90\xa2\x9c\x2d\xc6\x20\x1f\xb0\x23\x01\ +\x29\xca\xe1\x62\x04\xef\xf3\xa6\x00\xbb\x10\x90\xa2\x9c\x2e\xf6\ +\x27\x1f\xb0\x33\x01\x29\xca\xf1\x62\x6f\xf2\x01\xbb\x13\x90\xa2\ +\x9c\x2f\xf6\xf5\x22\x6f\x07\xb0\x23\x01\x29\xca\x01\x63\x4f\xf2\ +\x01\x43\x10\x90\xa2\x9c\x30\xf6\x23\x1f\x30\x08\x01\x29\xca\x11\ +\x63\x2f\x1f\xf2\x46\x00\xbb\x13\x90\xa2\x9c\x31\xf6\xe1\xe9\x03\ +\x06\x22\x20\x45\x39\x64\xec\xc1\xd3\x07\x0c\x45\x40\x8a\x72\xca\ +\xd8\xdc\x45\x3e\x60\x30\x02\x52\x94\x6b\xc6\xc6\xe4\x03\xc6\x23\ +\x20\x45\xb9\x67\x6c\xea\xf2\x3a\x2f\x3f\x30\x10\x01\x29\xca\x45\ +\x63\x43\xf2\x01\x63\x12\x90\xa2\xdc\x34\x36\x23\x1f\x30\x2a\x01\ +\x29\xca\x55\x63\x23\xf2\x01\xe3\x12\x90\xa2\xdc\x35\x36\x71\xf9\ +\x98\x97\x1d\x18\x90\x80\x14\xe5\xb2\xb1\x01\xf9\x80\xb1\x09\x48\ +\x51\x6e\x1b\xab\x93\x0f\x18\x9d\x80\x14\xe5\xba\xb1\xb2\xcb\xb3\ +\xbc\xe0\xc0\xb0\x04\xa4\x28\xf7\x8d\x55\xdd\x7a\xfa\x80\x09\x08\ +\x48\x51\x2e\x1c\x2b\xba\xf5\xf4\x01\x53\x10\x90\xa2\xdc\x38\x56\ +\x23\x1f\x30\x0b\x01\x29\xca\x95\x63\x25\xf2\x01\xf3\x10\x90\xa2\ +\xdc\x39\x56\x71\xfb\x35\x2f\x33\x30\x01\x01\x29\xca\xa5\x63\x05\ +\xf2\x01\x73\x11\x90\xa2\xdc\x3a\x16\x77\x2f\x1f\x30\x19\x01\x29\ +\xca\xb5\x63\x61\xb7\xaf\xf2\x02\x03\xd3\x10\x90\xa2\xdc\x3b\x16\ +\x75\x2f\x1f\x30\x21\x01\x29\xca\xc5\x63\x41\xf2\x01\x73\x12\x90\ +\xa2\xdc\x3c\x16\x23\x1f\x30\x2b\x01\x29\xca\xd5\x63\x21\xf7\x9f\ +\xf2\xc2\x02\xd3\x11\x90\xa2\xdc\x3d\x16\xe1\xe9\x03\x66\x26\x20\ +\x45\xb9\x7c\x2c\xe0\xc1\xd3\x07\x4c\x4d\x40\x8a\x72\xfb\xb8\xda\ +\xc3\xf3\xbc\xa4\xc0\xa4\x04\xa4\x28\xd7\x8f\x2b\x79\xfa\x80\xf9\ +\x09\x48\x51\xee\x1f\x57\xf1\xf4\x01\x47\x20\x20\x45\xb9\x80\x5c\ +\x41\x3e\xe0\x18\x04\xa4\x28\x37\x90\xb6\x3b\xf9\x80\x83\x10\x90\ +\xa2\x5c\x41\x9a\xe4\x03\x8e\x43\x40\x8a\x72\x07\x69\xb9\xfb\x92\ +\x97\x11\x38\x00\x01\x29\xca\x25\xa4\x41\x3e\xe0\x58\x04\xa4\x28\ +\xb7\x90\xb2\xcf\xf2\x01\x07\x23\x20\x45\xb9\x86\x14\x7d\x7e\x99\ +\x17\x10\x38\x0c\x01\x29\xca\x3d\xa4\x44\x3e\xe0\x88\x04\xa4\x28\ +\x17\x91\x02\xf9\x80\x63\x12\x90\xa2\xdc\x44\x9e\x4c\x3e\xe0\xa8\ +\x04\xa4\x28\x57\x91\x27\x7a\xfb\x2e\x2f\x1c\x70\x38\x02\x52\x94\ +\xbb\xc8\x93\xc8\x07\x1c\x99\x80\x14\xe5\x32\xf2\x04\xf2\x01\xc7\ +\x26\x20\x45\xb9\x8d\xfc\xd2\x8d\x7c\xc0\xc1\x09\x48\x51\xae\x23\ +\xbf\x70\xf3\x2d\x2f\x18\x70\x58\x02\x52\x94\xfb\xc8\x4f\x79\xfa\ +\x80\x33\x10\x90\xa2\x5c\x48\x7e\xc2\xd3\x07\x9c\x83\x80\x14\xe5\ +\x46\xf2\x43\x8f\x66\x0a\x4e\xc2\xb2\x17\xe5\x4a\xf2\x03\x37\x26\ +\x0a\x4e\xc3\xba\x17\xe5\x4e\xf2\x5d\x9e\x3e\xe0\x4c\x2c\x7c\x51\ +\x2e\x25\xdf\xf1\x98\xd7\x08\x38\x07\x01\x29\xca\xad\xe4\x1f\xe4\ +\x03\xce\x46\x40\x8a\x72\x2d\xf9\x9b\x37\x79\x7d\x80\xf3\x10\x90\ +\xa2\xdc\x4b\xfe\x42\x3e\xe0\x8c\x04\xa4\x28\x17\x93\x3f\x91\x0f\ +\x38\x27\x01\x29\xca\xcd\xe4\x0f\xef\xf3\xca\x00\x67\x23\x20\x45\ +\xb9\x9a\x84\x7c\xc0\x79\x09\x48\x51\xee\x26\xbf\x91\x0f\x38\x33\ +\x01\x29\xca\xe5\xe4\xdf\xe4\x03\xce\x4d\x40\x8a\x72\x3b\x91\x0f\ +\x38\x3d\x01\x29\xca\xf5\x3c\xbd\x17\x79\x3d\x80\xf3\x12\x90\xa2\ +\xdc\xcf\x93\x93\x0f\x40\x40\xca\x72\x41\x4f\x4d\x3e\x80\xff\x27\ +\x20\x45\xb9\xa1\x27\x26\x1f\xc0\xef\x04\xa4\x28\x57\xf4\xb4\x3e\ +\xe4\x75\x00\x10\x90\xa2\xdc\xd1\x73\xba\xc8\x07\xf0\x5f\x02\x52\ +\x94\x53\x7a\x46\xf2\x01\xfc\x85\x80\x14\xe5\x98\x9e\xcf\xe5\x75\ +\x5e\x01\x80\xdf\x09\x48\xd1\x25\xf7\xf4\x64\xe4\x03\xf8\x07\x01\ +\x29\xba\xcd\x45\x3d\x15\xf9\x00\xbe\x43\x40\x8a\xee\x73\x53\x4f\ +\x44\x3e\x80\xef\x12\x90\xa2\xbb\x5c\xd5\xd3\x90\x0f\xe0\x07\x04\ +\xa4\xe8\x26\x77\xf5\x24\x2e\x1f\xf3\x71\x03\xfc\x9d\x80\x14\xbd\ +\xcf\x65\x3d\x05\xf9\x00\x7e\x42\x40\x8a\x5e\xe7\xb6\x9e\x80\x7c\ +\x00\x3f\x25\x20\x45\x5f\x73\x5d\x0f\xef\xf6\x59\x3e\x62\x80\xef\ +\x13\x90\xa2\x97\xb9\xaf\x07\x27\x1f\xc0\x2f\x09\x48\x55\x2e\xec\ +\xa1\xc9\x07\xf0\x04\x02\x52\x75\xfc\x6f\x45\x97\x0f\xe0\x49\x04\ +\xa4\xea\x73\xce\xec\x51\xc9\x07\xf0\x44\x02\x52\x75\xec\xaf\xe3\ +\xbd\xfd\x9a\x0f\x13\xe0\x57\x04\xa4\xea\x55\x4e\xed\x11\xc9\x07\ +\x50\x20\x20\x65\x39\xb6\xc7\x23\x1f\x40\x89\x80\x94\x1d\xf4\xb3\ +\xe8\xf2\x01\x14\x09\x48\xd9\x21\x7f\x1a\xd6\xfd\xab\x7c\x74\x00\ +\x4f\x25\x20\x65\xcf\x72\x73\x0f\x44\x3e\x80\x06\x01\xa9\xcb\xd5\ +\x3d\x0c\xf9\x00\x5a\x04\xa4\xee\x58\xbf\x94\xf0\xfe\x53\x3e\x2c\ +\x80\x1a\x01\xa9\x7b\x91\xd3\x7b\x04\x0f\xf2\x01\x74\x09\x48\xdd\ +\x97\x1c\xdf\xf9\xc9\x07\x70\x05\x01\x69\x38\xc8\x17\xf2\x3e\x3c\ +\xcf\xc7\x03\xd0\x21\x20\x0d\x87\xf8\x69\x26\x9e\x3e\x80\x2b\x09\ +\x48\xc3\xbb\xdc\xe0\x89\xdd\x79\xfa\x00\xae\x25\x20\x1d\xf7\x39\ +\xc3\xb3\xf2\x8f\x57\xc0\x02\x04\xa4\xe3\x63\x0e\xf1\x9c\x3c\x7d\ +\x00\x8b\x10\x90\x96\x9c\xe2\x19\xc9\x07\xb0\x10\x01\x69\x99\xf6\ +\xd3\xe8\x77\x5f\xf2\x11\x00\x5c\x4b\x40\x7a\x72\x8f\x27\x23\x1f\ +\xc0\x82\x04\xa4\xe7\x6d\x4e\xf2\x4c\xe4\x03\x58\x94\x80\xf4\xbc\ +\xcc\x51\x9e\xc7\xe7\x97\xf9\xab\x03\x2c\x43\x40\x9a\x26\x7b\x04\ +\x91\x0f\x60\x71\x02\xd2\x34\xd5\x37\x13\xca\x07\xb0\x02\x01\xe9\ +\x9a\xe7\x17\x13\xbe\x95\x0f\x60\x0d\x02\xd2\xf5\xaf\x9c\xe7\xd1\ +\xc9\x07\xb0\x12\x01\x69\x9b\xe2\xd7\x82\xbc\x7d\x97\xbf\x2d\xc0\ +\xd2\x04\xa4\x6f\xfc\xdf\x4c\x28\x1f\xc0\x8a\x04\xa4\xef\x53\xce\ +\xf4\xa8\xe4\x03\x58\x95\x80\x5c\xe1\x73\x2e\xf5\x90\x6e\xbe\xe5\ +\x6f\x09\xb0\x0e\x01\xb9\xc6\xb8\xbf\x9a\x50\x3e\x80\xd5\x09\xc8\ +\x35\x5e\xe5\x5c\x8f\x46\x3e\x80\x0d\x08\xc8\x55\x86\xfc\x66\x90\ +\x47\x6f\x2a\xb0\x05\xb7\xe6\x3a\xe3\x7d\x25\xd6\x8d\xb7\x14\xd8\ +\x86\x6b\x73\x9d\xd1\x7e\xa8\xa2\xa7\x0f\x60\x33\xee\xcd\x95\xbe\ +\xe6\x72\x0f\xe1\x4d\xfe\x52\x00\x1b\x10\x90\x6b\xbd\xc9\xf1\xde\ +\xdf\x63\xfe\x46\x00\x9b\x10\x90\xab\xdd\xe5\x7e\xef\xcc\xd3\x07\ +\xb0\x31\x01\xb9\xde\x43\x4e\xf8\x9e\xe4\x03\xd8\x9c\x80\x2c\x60\ +\xf7\x2f\xc5\x92\x0f\x60\x07\x02\xb2\x80\x7f\xed\xfb\x1d\xe9\xf2\ +\x01\xec\x42\x40\x96\xf0\x6e\xc7\x82\xbc\xcf\xdf\x01\x60\x63\x02\ +\xb2\x88\x6f\x7b\x15\x44\x3e\x80\xdd\x08\xc8\x32\xf6\xf9\x57\x2c\ +\xf9\x00\x76\x24\x20\x4b\xd9\xfe\x33\xe9\x2f\xf2\x5f\x06\xd8\x85\ +\x80\x2c\x66\xe3\xef\x07\x91\x0f\x60\x67\x02\xb2\x9c\x2d\x7f\x34\ +\xaf\x7c\x00\xbb\x13\x90\x05\x7d\xc8\x75\x5f\xdd\x87\xfc\x07\x01\ +\x76\x24\x20\x4b\xfa\xb4\xc9\xa7\xd2\x3d\x7d\x00\x43\x10\x90\x65\ +\xad\xff\x89\x10\x4f\x1f\xc0\x20\x04\x64\x61\x2f\x72\xe7\xd7\x71\ +\x91\x0f\x60\x18\x02\xb2\xb4\x97\xf7\x39\xf6\xcb\x93\x0f\x60\x24\ +\x02\xb2\xbc\x95\x1e\x42\x2e\xaf\xf3\xe7\x03\x0c\x41\x40\x56\xf0\ +\x6e\x85\xcf\x84\xc8\x07\x30\x1a\x01\x59\xc5\xab\x85\xbf\x2f\x5d\ +\x3e\x80\xf1\x08\xc8\x4a\x5e\xe7\xf4\x2f\x41\x3e\x80\x11\x09\xc8\ +\x6a\x96\xfa\x65\xe9\x97\x8f\xf9\x03\x01\x86\x22\x20\x2b\x5a\xe2\ +\xb3\xe9\xb7\xcf\xf2\x87\x01\x0c\x46\x40\x56\xf5\xfa\xca\x6f\x4d\ +\x7f\x78\x95\x3f\x08\x60\x38\x02\xb2\xb2\x57\x9f\xd3\x82\xba\xcb\ +\x9b\x77\xf9\x43\x00\x06\x24\x20\xeb\xfb\xd0\xfa\x92\xac\xcf\x1e\ +\x3e\x80\xb1\x09\xc8\x16\x5e\xbe\x28\x7e\x7b\xfa\xdb\xaf\xf9\x5f\ +\x02\x0c\x4b\x40\x36\xf2\xaf\x8f\x6f\x13\x87\x5f\xb9\x7f\xff\x3c\ +\xff\x1b\x80\x91\x09\xc8\x86\xbe\x3d\xbb\xf9\xc5\x93\xc8\xe7\x17\ +\xfe\xe1\x0a\x98\x85\x80\x6c\xed\xdb\xab\x17\x8f\x77\xff\xf8\xac\ +\xc8\xed\xe7\xf7\xcf\x9e\x7b\x33\x80\x99\xb8\x59\xbb\x79\xf7\xf2\ +\xcb\x97\x4f\x9f\xbe\x7c\x79\xf9\x2d\xff\x07\x80\xa9\x08\x08\x00\ +\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\ +\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\ +\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\ +\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\ +\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\ +\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\ +\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\ +\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\ +\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\ +\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\ +\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\ +\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\ +\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\ +\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\ +\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\ +\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\ +\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\ +\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\ +\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\ +\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\ +\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\ +\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\ +\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\ +\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\ +\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\ +\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\ +\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\ +\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\ +\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\ +\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\ +\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\ +\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\ +\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\ +\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\ +\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\ +\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\ +\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\ +\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\ +\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\ +\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\ +\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\ +\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\ +\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\ +\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\ +\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\ +\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\ +\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\ +\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\ +\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\ +\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\ +\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\ +\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\ +\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\ +\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\ +\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\ +\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\ +\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\ +\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\ +\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\ +\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\ +\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\ +\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\ +\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\ +\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\ +\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\ +\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\ +\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\ +\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\ +\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\ +\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\ +\x00\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\ +\xb4\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\ +\x08\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\ +\x08\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\ +\x00\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\ +\x2d\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\ +\x02\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\ +\x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\ +\x40\xc3\xff\xfe\xef\xff\x01\xe5\xf9\xa3\x47\x4e\x17\x0b\xed\x00\ +\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x52\xd0\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -1530,6 +2566,69 @@ \x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\x92\x24\x49\ \x57\xd6\xeb\xfd\x07\x85\x1a\x3c\xaf\xcc\x24\x67\x3a\x00\x00\x00\ \x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x03\xc5\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x34\x00\x00\x00\x34\x08\x06\x00\x00\x00\xc5\x78\x1b\xeb\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x04\x67\x41\x4d\x41\x00\x00\xb1\x8f\x0b\xfc\x61\x05\x00\x00\x00\ +\x09\x70\x48\x59\x73\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7\x6f\ +\xa8\x64\x00\x00\x03\x5a\x49\x44\x41\x54\x68\x43\xed\xd8\x59\xa8\ +\x4d\x51\x1c\xc7\xf1\x63\x26\x53\xe6\x90\x24\x94\x21\x65\x8a\x12\ +\x12\xc9\x93\x88\x12\x9e\x0c\xe5\xc1\x50\x4a\x29\x1e\x84\x52\x78\ +\xa0\x84\xa4\x78\x53\x92\x21\x43\x52\x86\xa2\x10\x22\x64\x16\x99\ +\xa2\xa4\x90\x79\xf6\xfd\x9d\xce\xba\xad\xbb\xef\x7f\xdf\x73\xf6\ +\x3e\xd3\x7d\x58\xbf\xfa\xe4\xda\xad\xb5\xcf\x3e\x6b\xaf\xb3\xd6\ +\x7f\xef\x4c\x48\x48\x48\x48\x48\x48\x48\x48\x48\x08\x69\x81\xe1\ +\x58\x80\x6d\x38\x82\x73\xb8\x8e\x27\xb8\x85\x0b\x38\x86\xdd\x58\ +\x8a\x71\x68\x87\x06\x93\xae\x58\x84\x93\xf8\x8e\x7f\x29\xfc\xc1\ +\x65\xac\x44\x7f\x54\x25\x13\x70\x02\xba\x18\xeb\x22\x8b\x71\x0d\ +\xb3\xd1\x14\x65\xcf\x54\x5c\x81\x75\x21\xa5\xf6\x0c\x8b\x51\x96\ +\x2f\xd6\x07\xc7\x61\x7d\x70\xb9\xdd\xc4\x18\x94\x24\x8d\xb0\x02\ +\x5f\x61\x7d\x58\xa5\xfc\xc5\x2e\xb4\x42\xea\xb4\xc5\x41\x58\x1f\ +\x50\x2d\x37\xa0\xd9\x92\x38\xfd\x70\x0f\xd6\x49\xab\xed\x1d\x26\ +\xa1\xe0\x68\xe9\x7c\x05\xeb\x64\x16\xad\x4a\xc5\xfe\xbe\x74\x8e\ +\x7d\xf8\xe9\x1d\xab\xcf\x37\x4c\x41\xde\xf4\xc5\x4b\x58\x27\x89\ +\xd2\xde\x31\x16\xcd\xf1\x3a\x77\x2c\x2d\x2d\xff\x83\xd0\x13\x7b\ +\x72\xff\xb7\xda\xf9\xf4\xbb\x9e\x8c\xd8\x74\xc1\x0b\x58\x9d\x7d\ +\x6f\x31\x07\x5a\x30\x94\x59\xb0\xda\x25\xb5\x15\x2e\xc3\xa0\x0a\ +\xc3\x6a\xe7\xfb\x82\x91\xa8\x93\x26\x38\x0d\xab\x93\x4f\x6d\xba\ +\xc3\x8f\x46\xd4\x6a\x9b\xd4\x1d\xf8\x51\x29\xa5\x12\x4a\x2b\x9c\ +\xd5\xde\xd1\x7e\xd5\x09\xb5\xb2\x1e\x56\x63\x9f\x4e\xde\x18\xd1\ +\x5c\x85\xd5\x3e\x29\x4d\x33\xeb\xfc\xf3\xf0\x1b\x56\x1f\x47\xa5\ +\x97\x9b\x31\x99\xa1\xc8\x37\x0a\xfa\xc2\x71\x79\x08\xab\x4f\x1a\ +\xed\x61\x65\x1a\xf2\x7d\xa9\x85\xc8\x66\x33\xac\x06\xbe\x99\x88\ +\x4b\xa9\x4a\xa1\x5f\xb0\xee\x90\xd2\x1b\xf9\x06\x5d\x95\x7c\x36\ +\x9a\x4a\x56\x03\xdf\x01\xc4\x65\x3f\xac\x3e\x49\x3d\x45\x5c\x54\ +\x89\x5b\x7d\x7c\xe7\x91\xcd\x44\x58\x0d\x34\x95\x0e\xe5\xfe\xd6\ +\x6a\xd2\x01\x56\x34\xc7\xa3\x7d\xd3\xd8\x01\x2b\xfa\x6d\xdc\x86\ +\xda\xdc\xc5\xd1\xdc\xdf\x51\xfa\xd2\x35\x59\x03\xff\x96\x6a\xe5\ +\x50\xb5\x30\xc2\x3b\xb6\x09\x56\x3a\xe2\x23\x5c\xbb\xb4\x46\xc3\ +\x8a\xbf\x2d\x2c\x41\x6b\x9c\xf5\x8e\x89\x06\x5e\xfb\x61\xad\x0c\ +\xc1\x32\xe8\x04\xea\xe4\x72\x09\xea\xa4\x8d\xac\x97\x0e\x18\x59\ +\x05\xff\x03\x92\xd2\x05\x59\x69\x86\x47\x50\x9b\xf7\x68\x03\x45\ +\x77\x6d\x3c\xf4\x70\x39\x4a\x07\x92\x44\xa5\xbb\xdb\xb9\x4f\x41\ +\x7b\x56\x34\x1a\x9d\xe8\xa8\x15\xea\x39\xb4\xa9\x5b\xd9\x08\xd7\ +\x4e\x77\xa7\x64\xd9\x0e\x77\xe2\xb5\x3a\x60\x44\x9b\xdb\x45\xb8\ +\x76\x85\xd0\xd4\x1e\x0c\x2b\x5a\xaa\xdd\xcf\x40\x65\x56\xdc\x0a\ +\x98\x2a\x7a\x91\xf1\x18\x3a\xb9\xee\xd6\x7c\x58\xd1\xee\xbe\x05\ +\x3f\xe0\x5f\xb8\xe5\x30\xf4\x4e\xc2\x8a\x66\xc5\x07\xa8\x9d\xfe\ +\x1d\x88\x92\x47\x8b\x84\xea\x38\x7d\x88\x46\x6e\x39\xe2\xa2\x22\ +\x77\x03\xb4\x3a\xb9\x97\x27\xda\x67\xb4\x34\xef\x44\x7d\xf3\x5e\ +\x05\xe7\x67\xa8\x8f\x06\x46\xab\x70\xd9\xa2\x95\xc8\x5f\xd1\xf6\ +\x22\x6e\x77\xf7\xa3\x36\xf9\xa6\x8c\xde\x1d\xac\x86\x7b\x84\x50\ +\x65\x50\xb3\xfb\x97\x33\x9a\xf3\x1a\x69\xf7\xa5\x54\xa1\xcf\x40\ +\x31\x73\x5c\x03\xa5\x67\x22\x77\xce\x4f\xd0\x0b\x99\x8a\x45\x73\ +\x3f\x5a\x9d\x3f\x80\x96\xd1\xb8\x0d\x38\x9a\x96\x98\x0e\x95\x2c\ +\xfe\x79\xee\x43\xf5\x65\x55\x32\x17\xd1\x87\x3b\x4d\x15\x55\xe0\ +\xda\x88\xf5\x1a\x4a\x17\xad\xf7\x78\x1a\x71\xbd\x55\x5d\x87\x33\ +\xd0\x53\xa7\xdf\x4f\xfb\x9c\xf6\xb3\x3a\x1b\x64\xa5\xa3\x15\x50\ +\xaf\x75\x35\xb2\xfe\x05\x16\xea\x0d\x54\xcd\xf7\x40\x83\x8a\x76\ +\x6f\xbd\xab\xd6\x1d\x50\xa1\x18\xbd\x03\x8e\xee\xa0\x9e\x46\xb5\ +\xbc\xeb\xae\x55\xfd\x8e\x24\x49\x67\x0c\x80\x7e\xf4\x5a\x4c\xba\ +\xc1\xaa\x34\x42\x42\x42\x42\x42\x42\x42\x42\xca\x9e\x4c\xe6\x3f\ +\x73\x34\xe8\xad\x21\x12\x05\x0a\x00\x00\x00\x00\x49\x45\x4e\x44\ +\xae\x42\x60\x82\ \x00\x00\x21\x8d\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -2167,6 +3266,24 @@ \x0a\x61\x5a\xa7\ \x00\x69\ \x00\x63\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x10\ +\x02\xd9\x93\xe7\ +\x00\x69\ +\x00\x63\x00\x6f\x00\x6e\x00\x6f\x00\x2d\x00\x62\x00\x6f\x00\x72\x00\x72\x00\x61\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x16\ +\x03\x92\xa1\x87\ +\x00\x69\ +\x00\x63\x00\x6f\x00\x6e\x00\x6f\x00\x2d\x00\x66\x00\x6c\x00\x65\x00\x63\x00\x68\x00\x61\x00\x2d\x00\x61\x00\x62\x00\x61\x00\x6a\ +\x00\x6f\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x17\ +\x07\x8e\xd8\xa7\ +\x00\x69\ +\x00\x63\x00\x6f\x00\x6e\x00\x6f\x00\x2d\x00\x66\x00\x6c\x00\x65\x00\x63\x00\x68\x00\x61\x00\x2d\x00\x61\x00\x72\x00\x72\x00\x69\ +\x00\x62\x00\x61\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x08\ +\x02\x8c\x59\xa7\ +\x00\x70\ +\x00\x6c\x00\x61\x00\x79\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x0a\ \x0c\xf7\x1b\xc7\ \x00\x63\ @@ -2175,6 +3292,10 @@ \x0a\xc8\xfb\x07\ \x00\x66\ \x00\x6f\x00\x6c\x00\x64\x00\x65\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0d\ +\x03\x89\xf2\x67\ +\x00\x69\ +\x00\x63\x00\x6f\x00\x6e\x00\x6f\x00\x2d\x00\x76\x00\x65\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x10\ \x0d\x91\xc1\x87\ \x00\x63\ @@ -2189,12 +3310,17 @@ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ \x00\x00\x00\x14\x00\x02\x00\x00\x00\x02\x00\x00\x00\x03\ -\x00\x00\x00\x36\x00\x02\x00\x00\x00\x04\x00\x00\x00\x05\ +\x00\x00\x00\x36\x00\x02\x00\x00\x00\x09\x00\x00\x00\x05\ \x00\x00\x00\x46\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x00\xb6\x00\x01\x00\x00\x00\x01\x00\x00\x80\x41\ -\x00\x00\x00\x76\x00\x00\x00\x00\x00\x01\x00\x00\x56\xe2\ +\x00\x00\x00\xe8\x00\x00\x00\x00\x00\x01\x00\x00\x0e\xe6\ \x00\x00\x00\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x04\x0e\ -\x00\x00\x00\x90\x00\x00\x00\x00\x00\x01\x00\x00\x5e\xb0\ +\x00\x00\x01\x32\x00\x00\x00\x00\x00\x01\x00\x00\x9e\xe8\ +\x00\x00\x00\x82\x00\x00\x00\x00\x00\x01\x00\x00\x06\x81\ +\x00\x00\x01\x78\x00\x01\x00\x00\x00\x01\x00\x00\xc4\x42\ +\x00\x00\x00\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x0a\xb9\ +\x00\x00\x01\x18\x00\x00\x00\x00\x00\x01\x00\x00\x97\x1a\ +\x00\x00\x00\xfe\x00\x00\x00\x00\x00\x01\x00\x00\x44\x46\ +\x00\x00\x01\x52\x00\x00\x00\x00\x00\x01\x00\x00\xa2\xb1\ " def qInitResources(): diff --git a/qgisplugin/resources.qrc b/qgisplugin/resources.qrc index c896ce2..f379941 100644 --- a/qgisplugin/resources.qrc +++ b/qgisplugin/resources.qrc @@ -6,5 +6,9 @@ icons/folder.png icons/cuenca.ico icon.png + icons/icono-borrar.png + icons/icono-flecha-abajo.png + icons/icono-flecha-arriba.png + icons/icono-ver.png From 7f7113fbd2153318db6b1dd1f2a34de2cb67e999 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Fri, 15 Jun 2018 10:08:06 -0500 Subject: [PATCH 042/142] cambios menores sobre la interfaz --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 214 +++++++++++++++---- 1 file changed, 173 insertions(+), 41 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 9d3dad9..1a012b8 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -42,7 +42,7 @@ 10 20 - 421 + 455 81 @@ -74,7 +74,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -93,6 +93,65 @@ + + + + Coordenada en X del punto de inicio. + + + Coordenada en X del punto de inicio. + + + Cuenca: + + + + + + + Coordenada en X del punto de inicio. + + + Coordenada en X del punto de inicio. + + + + + + + + + + Qt::Vertical + + + + + + + Coordenada en X del punto de inicio. + + + Coordenada en X del punto de inicio. + + + Área [km2]: + + + + + + + Coordenada en X del punto de inicio. + + + Coordenada en X del punto de inicio. + + + + + + @@ -154,6 +213,25 @@ + + + + 130 + 90 + 57 + 34 + + + + Coordenada en X del punto de inicio. + + + Coordenada en X del punto de inicio. + + + Cuenca: + + @@ -185,7 +263,7 @@ - + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png @@ -225,8 +303,8 @@ 0 - -40 - 446 + 0 + 443 768 @@ -322,7 +400,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -424,7 +502,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -525,6 +603,58 @@ + + + + + + Valor en metros del tamano de una celda en el mapa. + + + Valor en metros del tamano de una celda en el mapa. + + + Qt::LeftToRight + + + Proyección EPSG + + + + + + + + 100 + 0 + + + + + 150 + 16777215 + + + + 0 + + + 10002.000000000000000 + + + 4326.000000000000000 + + + + + + + + + Qt::Horizontal + + + @@ -571,7 +701,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -594,7 +724,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -650,7 +780,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png:/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png @@ -673,7 +803,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png:/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png @@ -716,7 +846,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -739,7 +869,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -756,7 +886,7 @@ - + :/plugins/HydroSEDPlugin/icons/cuenca.ico:/plugins/HydroSEDPlugin/icons/cuenca.ico @@ -767,7 +897,7 @@ 0 0 - 430 + 461 730 @@ -797,7 +927,7 @@ 0 0 - 415 + 446 728 @@ -833,7 +963,7 @@ 0 30 - 381 + 421 168 @@ -878,7 +1008,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -992,7 +1122,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1009,8 +1139,8 @@ - - :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1069,7 +1199,7 @@ 0 30 - 381 + 421 367 @@ -1105,7 +1235,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -1251,7 +1381,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1299,7 +1429,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1384,7 +1514,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1432,7 +1562,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1472,7 +1602,7 @@ - + :/plugins/HydroSEDPlugin/icons/cuenca.ico:/plugins/HydroSEDPlugin/icons/cuenca.ico @@ -1483,7 +1613,7 @@ 0 0 - 430 + 461 730 @@ -1513,7 +1643,7 @@ 0 0 - 415 + 443 1918 @@ -1549,7 +1679,7 @@ 0 0 - 395 + 431 290 @@ -1644,7 +1774,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1818,7 +1948,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1899,7 +2029,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1972,7 +2102,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2073,7 +2203,7 @@ 0 290 - 395 + 431 351 @@ -2737,7 +2867,7 @@ 0 0 - 415 + 412 1918 @@ -2820,7 +2950,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2849,7 +2979,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2934,7 +3064,7 @@ 0 0 - 326 + 323 930 @@ -3123,6 +3253,8 @@ 1 - + + + From 54b0646dd74529aabf321e4fe80b21e8ffbd0ed3 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Fri, 15 Jun 2018 11:05:43 -0500 Subject: [PATCH 043/142] comenzamos a trabajar en el gestor de cargado y edicion de cuencas en archivos nc --- qgisplugin/HydroSEDPluginUtils.py | 17 ++++++++++- qgisplugin/HydroSEDPlugin_dockwidget.py | 32 ++++++++++++++++++-- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 4 ++- wmf/wmf.py | 24 +++++++-------- 4 files changed, 60 insertions(+), 17 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index c465f28..13f7cf0 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -2,7 +2,7 @@ from qgis.core import QgsRasterLayer, QgsMapLayerRegistry, QgsVectorLayer, QgsFillSymbolV2 from PyQt4 import QtGui, uic - +import netCDF4 from wmf import wmf class controlHS: @@ -18,6 +18,7 @@ def __init__(self): self.nodata = 0 self.BasinsCount = 0 self.StreamsCount = 0 + self.DicBasinNc = {} def cargar_mapa_raster (self,pathMapaRaster): @@ -146,3 +147,17 @@ def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed, PathETROUT #Retorna el resultado a la salida return self.cuenca.CellQmed[-1] + + def Basin_LoadBasin(self, PathNC): + #Cargar la cuenca y sus variables base a WMF + self.cuenca = wmf.SimuBasin(rute = PathNC) + #Cargar las variables de la cuenca a un diccionario. + g = netCDF4.Dataset(PathNC) + for k in g.variables.keys(): + self.DicBasinNc.update({k: + {'nombre':k, + 'tipo':g.variables[k].dtype.name, + 'shape':g.variables[k].shape}}) + g.close() + print self.DicBasinNc.keys() + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index c3042c8..3615039 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -57,6 +57,7 @@ def __init__(self, iface = None, parent=None): self.setupUIInputsOutputs () self.setupHidro_Balance() self.setupTableEdicionAlmacenamientoParametrosWMFNC () + self.setupBasinManager() #self.setupUIButtonEvents () if not (iface is None): @@ -128,10 +129,35 @@ def handleClickEventEjecutarTrazadorCuencas (self): self.iface.legendInterface().refreshLayerSymbology(layer) #mensaje de exito - self.iface.messageBar().pushInfo(u'HidroSIG',u'Se ha trazado la cuenca de forma exitosa') - #except: - # pass + self.iface.messageBar().pushInfo(u'HidroSIG',u'Se ha trazado la cuenca de forma exitosa') + def setupBasinManager(self): + '''Conjunto de herramientas y variables que permiten cargar y actualizar archivos .nc + de cuencas''' + + def setupLineEditButtonOpenBasinFileDialog (lineEditHolder, fileDialogHolder): + '''Busca un proyecto de cuenca ya guardado anteriormente''' + #lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), 'Open File',"", + # QtGui.QFileDialog.DontUseNativeDialog)) + lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "Cargador de cuencas", "*","Cuenca en NetCDF4(*.nc);;", + QtGui.QFileDialog.DontUseNativeDialog)) + + #Funciones para Cargar variables + def clickEventSelectorBasin(): + '''click para seleccionar un proyecto de cuenca''' + #Pone el texto de la ruta + setupLineEditButtonOpenBasinFileDialog(self.lineEditRutaCuenca, QFileDialog) + #Habilita visualizarlo + if len(self.lineEditRutaCuenca.text())>2: + self.ButtonLoadBasinProyect.setEnabled(True) + def clickEventBasin2WMF(): + '''Agrega el proyecto de cuenca a WMF''' + self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip()) + + #Botones para variables de entrada + self.botonSelectorProyectBasin.clicked.connect(clickEventSelectorBasin) + self.ButtonLoadBasinProyect.clicked.connect(clickEventBasin2WMF) + def setupHidro_Balance(self): def setupLineEditButtonOpenRasterFileDialog (lineEditHolder, fileDialogHolder): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 1a012b8..cd831be 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -81,6 +81,9 @@ + + false + Carga el proyecto cuenca a WMF, de manera que puede ser usada para operar con ella. @@ -3254,7 +3257,6 @@ - diff --git a/wmf/wmf.py b/wmf/wmf.py index 27d4f1b..cf249db 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -3921,17 +3921,17 @@ def Save_SimuBasin(self,ruta,SimSlides = False, N = self.ncells elif self.modelType[0] is 'h': N = self.nhills - #Dict = {'nombre':self.name, - #'modelType':self.modelType,'noData':self.nodata,'umbral':self.umbral, - #'ncells':self.ncells,'nhills':self.nhills, - #'dt':models.dt,'Nelem':N,'dxp':cu.dxp,'retorno':models.retorno, - #'storageConst' :models.storage_constant, - #'ncols':cu.ncols, - #'nrows':cu.nrows, - #'xll':cu.xll, - #'yll':cu.yll, - #'dx':cu.dx, - #'dy':cu.dy} + Dict = {'nombre':self.name, + 'modelType':self.modelType,'noData':self.nodata,'umbral':self.umbral, + 'ncells':self.ncells,'nhills':self.nhills, + 'dt':models.dt,'Nelem':N,'dxp':cu.dxp,'retorno':models.retorno, + 'storageConst' :models.storage_constant, + 'ncols':cu.ncols, + 'nrows':cu.nrows, + 'xll':cu.xll, + 'yll':cu.yll, + 'dx':cu.dx, + 'dy':cu.dy} if SimSlides: Dict.update({'sl_fs':models.sl_fs, 'sl_gullie':models.sl_gullienogullie, 'sl_gammaw':models.sl_gammaw}) #abre el archivo @@ -4019,7 +4019,7 @@ def Save_SimuBasin(self,ruta,SimSlides = False, Var = gr.createVariable(k,ExtraVar[k]['type'],('ncell',),zlib=True) Var[:] = ExtraVar[k]['Data'] #asigna las prop a la cuenca - #gr.setncatts(Dict) + gr.setncatts(Dict) #Cierra el archivo gr.close() #Sale del programa From 899eeb439173d881ac775441d93ce67f71b27505 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Fri, 15 Jun 2018 11:13:25 -0500 Subject: [PATCH 044/142] identifica si alguien es mapa raster o no --- qgisplugin/HydroSEDPluginUtils.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 13f7cf0..9f528f2 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -154,10 +154,18 @@ def Basin_LoadBasin(self, PathNC): #Cargar las variables de la cuenca a un diccionario. g = netCDF4.Dataset(PathNC) for k in g.variables.keys(): + #Evalua si tiene la misma cantidad de celdas y puede ser un mapa + shape = g.variables[k].shape + MapaRaster = False + for s in shape: + if s == self.cuenca.ncells: + MapaRaster = True + #Actualiza el diccionario self.DicBasinNc.update({k: {'nombre':k, 'tipo':g.variables[k].dtype.name, - 'shape':g.variables[k].shape}}) + 'shape':g.variables[k].shape, + 'raster':MapaRaster}}) g.close() print self.DicBasinNc.keys() From 299ab8732a57ff42a4bcd41a6586ed6204b9460a Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Fri, 15 Jun 2018 11:16:10 -0500 Subject: [PATCH 045/142] el diccionario de las variables de la cuenca identifica si es rasterizable o no cada variable --- qgisplugin/HydroSEDPluginUtils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 9f528f2..e008c60 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -166,6 +166,7 @@ def Basin_LoadBasin(self, PathNC): 'tipo':g.variables[k].dtype.name, 'shape':g.variables[k].shape, 'raster':MapaRaster}}) + print self.DicBasinNc[k] g.close() - print self.DicBasinNc.keys() + #print self.DicBasinNc.keys() From abe477d3e2521d013281e435fb8e1ce67898b812 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Fri, 15 Jun 2018 11:17:16 -0500 Subject: [PATCH 046/142] a las variables cargadas del netCDF les pone a todas por defecto que son basicas --- qgisplugin/HydroSEDPluginUtils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index e008c60..76c405c 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -165,8 +165,8 @@ def Basin_LoadBasin(self, PathNC): {'nombre':k, 'tipo':g.variables[k].dtype.name, 'shape':g.variables[k].shape, - 'raster':MapaRaster}}) - print self.DicBasinNc[k] + 'raster':MapaRaster, + 'basica': True}}) g.close() - #print self.DicBasinNc.keys() + From 8bcf2d1bd42fbdda95ace6fe0f642dcdee7091fc Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Fri, 15 Jun 2018 13:50:31 -0500 Subject: [PATCH 047/142] Cambios con los cuales se cargan la divisoria y la red hidrica cuando se carga un proyecto de cuenca. --- qgisplugin/HydroSEDPluginUtils.py | 51 +++++++++------- qgisplugin/HydroSEDPlugin_dockwidget.py | 29 ++++++++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 63 ++++++++++++++++---- 3 files changed, 108 insertions(+), 35 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 76c405c..8aee041 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -149,24 +149,33 @@ def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed, PathETROUT return self.cuenca.CellQmed[-1] def Basin_LoadBasin(self, PathNC): - #Cargar la cuenca y sus variables base a WMF - self.cuenca = wmf.SimuBasin(rute = PathNC) - #Cargar las variables de la cuenca a un diccionario. - g = netCDF4.Dataset(PathNC) - for k in g.variables.keys(): - #Evalua si tiene la misma cantidad de celdas y puede ser un mapa - shape = g.variables[k].shape - MapaRaster = False - for s in shape: - if s == self.cuenca.ncells: - MapaRaster = True - #Actualiza el diccionario - self.DicBasinNc.update({k: - {'nombre':k, - 'tipo':g.variables[k].dtype.name, - 'shape':g.variables[k].shape, - 'raster':MapaRaster, - 'basica': True}}) - g.close() - - + #Cargar la cuenca y sus variables base a WMF + self.cuenca = wmf.SimuBasin(rute = PathNC) + #Cargar las variables de la cuenca a un diccionario. + g = netCDF4.Dataset(PathNC) + for k in g.variables.keys(): + #Evalua si tiene la misma cantidad de celdas y puede ser un mapa + shape = g.variables[k].shape + MapaRaster = False + for s in shape: + if s == self.cuenca.ncells: + MapaRaster = True + #Actualiza el diccionario + self.DicBasinNc.update({k: + {'nombre':k, + 'tipo':g.variables[k].dtype.name, + 'shape':g.variables[k].shape, + 'raster':MapaRaster, + 'basica': True}}) + g.close() + #Area de la cuenca + return self.cuenca.ncells*wmf.cu.dxp**2/1e6 + + def Basin_LoadBasinDivisory(self, PathDivisory): + # Guarda los shapes de divisoria y de red hidrica. + self.cuenca.Save_Basin2Map(PathDivisory, wmf.cu.dxp) + + def Basin_LoadBasinNetwork(self, PathNetwork): + # Guarda los shapes de divisoria y de red hidrica. + self.cuenca.Save_Net2Map(PathNetwork, wmf.cu.dxp, self.cuenca.umbral) + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 3615039..e077e79 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -152,11 +152,38 @@ def clickEventSelectorBasin(): self.ButtonLoadBasinProyect.setEnabled(True) def clickEventBasin2WMF(): '''Agrega el proyecto de cuenca a WMF''' - self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip()) + Area = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip()) + #Habilita los botones de visualizacion de red hidrica y divisoria + self.Boton_verDivisoria.setEnabled(True) + self.Boton_verRedHidrica.setEnabled(True) + #Pone el area de la cuenca + texto = '%.1f'%Area + self.LabelBasinArea.setText(texto) + + def clickEventBasinLoadDivisory(): + '''Carga la divisoria de la cuenca cargada a WMF''' + OutPathDivisoria = '/tmp/HydroSED/CuencaCargada.shp' + self.HSutils.Basin_LoadBasinDivisory(OutPathDivisoria) + #Carga la divisoria + ret, layer = self.HSutils.cargar_mapa_vector(OutPathDivisoria, self.HSutils.TIPO_STYLE_POLIGONO, color = (255,0,0), width = 0.6) + self.iface.mapCanvas().refresh() + self.iface.legendInterface().refreshLayerSymbology(layer) + def clickEventBasinLoadNetwork(): + '''Carga la divisoria de la cuenca cargada a WMF''' + OutPathNetwork = '/tmp/HydroSED/RedCargada.shp' + self.HSutils.Basin_LoadBasinNetwork(OutPathNetwork) + #Carga la red + ret, layer = self.HSutils.cargar_mapa_vector(OutPathNetwork, self.HSutils.TIPO_STYLE_POLILINEA, width = 0.4) + self.iface.mapCanvas().refresh() + self.iface.legendInterface().refreshLayerSymbology(layer) #Botones para variables de entrada self.botonSelectorProyectBasin.clicked.connect(clickEventSelectorBasin) self.ButtonLoadBasinProyect.clicked.connect(clickEventBasin2WMF) + #Botones para visualizar polilineas y poligonos + self.Boton_verDivisoria.clicked.connect(clickEventBasinLoadDivisory) + self.Boton_verRedHidrica.clicked.connect(clickEventBasinLoadNetwork) + def setupHidro_Balance(self): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index cd831be..5d12492 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -262,7 +262,7 @@ - 0 + 1 @@ -1203,7 +1203,7 @@ 0 30 421 - 367 + 402 @@ -1378,17 +1378,6 @@ - - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - - @@ -1572,6 +1561,54 @@ + + + + + + Nombre interno que identifica a la cuenca trazada (Cuenca) + + + Nombre: + + + + + + + Cuenca + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + From 0c8f3349cf1493c2833f8187b0bbd171f1940f02 Mon Sep 17 00:00:00 2001 From: camilo2046 Date: Mon, 18 Jun 2018 09:35:43 -0500 Subject: [PATCH 048/142] Se agrega carga de las listas de propiedades de NetCDF --- qgisplugin/HydroSEDPluginUtils.py | 9 ++++ qgisplugin/HydroSEDPlugin_dockwidget.py | 65 +++++++++---------------- 2 files changed, 32 insertions(+), 42 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 76c405c..c74be3b 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -149,6 +149,11 @@ def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed, PathETROUT return self.cuenca.CellQmed[-1] def Basin_LoadBasin(self, PathNC): + # Numero Total de Variables + self.NumDicBasinNcVariables = 0 + # Numero Total de Variables Basicas + self.NumDicBasinNcVariablesBasicas = 0 + #Cargar la cuenca y sus variables base a WMF self.cuenca = wmf.SimuBasin(rute = PathNC) #Cargar las variables de la cuenca a un diccionario. @@ -167,6 +172,10 @@ def Basin_LoadBasin(self, PathNC): 'shape':g.variables[k].shape, 'raster':MapaRaster, 'basica': True}}) + + self.NumDicBasinNcVariables = self.NumDicBasinNcVariables + 1 + self.NumDicBasinNcVariablesBasicas = self.NumDicBasinNcVariablesBasicas + 1 + g.close() diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 3615039..ebdd0a3 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -56,7 +56,6 @@ def __init__(self, iface = None, parent=None): self.setupUi(self) self.setupUIInputsOutputs () self.setupHidro_Balance() - self.setupTableEdicionAlmacenamientoParametrosWMFNC () self.setupBasinManager() #self.setupUIButtonEvents () @@ -153,6 +152,7 @@ def clickEventSelectorBasin(): def clickEventBasin2WMF(): '''Agrega el proyecto de cuenca a WMF''' self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip()) + self.setupTableEdicionAlmacenamientoParametrosWMFNC () #Botones para variables de entrada self.botonSelectorProyectBasin.clicked.connect(clickEventSelectorBasin) @@ -421,57 +421,38 @@ def handleClickEventButton_Actualizar_WMF_Desde_NC (): for row in rows: print('Row %d is selected' % row) + print self.HSutils.DicBasinNc + print self.HSutils.NumDicBasinNcVariables - listaHeaderTabla1 = ["Parametro", "Valor 1", "Valor 2"] - listaContenidoTabla1 = [["Ejemplo DEM" , "/home/jctrujillo/Downloads/demfin.tif" , "100"], - ["Ejemplo DIR" , "/home/jctrujillo/Downloads/dir.tif" , "200"], - ["Ejemplo Corriente", "/home/jctrujillo/Downloads/Corriente.shp", "300"], - ["Ejemplo Cuenca" , "/home/jctrujillo/Downloads/Cuenca.shp" , "400"], - ["Ejemplo Red 1" , "/home/jctrujillo/Downloads/red1.shp" , "500"], - ["Ejemplo Red 2" , "/home/jctrujillo/Downloads/Red_2.shp" , "600"]] + listaHeaderTabla_NC = ["Nombre", "Tipo", "Shape"] + listaHeaderTabla_WMF = ["Nombre", "Tipo", "Shape"] - listaHeaderTabla2 = ["Parametro", "Valor 1", "Valor 2", "Valor 3", "Valor 4", "Valor 5", "Valor 6"] - listaContenidoTabla2 = [["Ejemplo DEM Edicion" , "/home/jctrujillo/Downloads/demfin.tif" , "100", "1000", "10000", "100000", "1000000"], - ["Ejemplo DIR Edicion" , "/home/jctrujillo/Downloads/dir.tif" , "200", "2000", "20000", "200000", "2000000"], - ["Ejemplo Corriente Edicion", "/home/jctrujillo/Downloads/Corriente.tif", "300", "3000", "30000", "300000", "3000000"], - ["Ejemplo Cuenca Edicion" , "/home/jctrujillo/Downloads/Cuenca.tif" , "400", "4000", "40000", "400000", "4000000"]] + self.Tabla_Prop_NC.setRowCount (self.HSutils.NumDicBasinNcVariables) + self.Tabla_Prop_NC.setColumnCount (len (listaHeaderTabla_NC)) + self.Tabla_Prop_NC.setHorizontalHeaderLabels (listaHeaderTabla_NC) - self.Tabla_Prop_WMF.setRowCount (len (listaContenidoTabla1)) - self.Tabla_Prop_WMF.setColumnCount (len (listaHeaderTabla1)) + self.Tabla_Prop_WMF.setRowCount (self.HSutils.NumDicBasinNcVariablesBasicas) + self.Tabla_Prop_WMF.setColumnCount (len (listaHeaderTabla_WMF)) + self.Tabla_Prop_WMF.setHorizontalHeaderLabels (listaHeaderTabla_WMF) - self.Tabla_Prop_NC.setRowCount (len (listaContenidoTabla2)) - self.Tabla_Prop_NC.setColumnCount (len (listaHeaderTabla2)) + idxFila_NC = 0 + idxFila_WMF = 0 - for idxFila in xrange (len (listaContenidoTabla1)): + for keyParam in self.HSutils.DicBasinNc: - for idxColumna in xrange (len (listaHeaderTabla1)): + self.Tabla_Prop_NC.setItem (idxFila_NC, 0, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["nombre"])) + self.Tabla_Prop_NC.setItem (idxFila_NC, 1, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["tipo"])) + self.Tabla_Prop_NC.setItem (idxFila_NC, 2, QTableWidgetItem (str (self.HSutils.DicBasinNc[keyParam]["shape"]))) - self.Tabla_Prop_WMF.setItem (idxFila, idxColumna, QTableWidgetItem (listaContenidoTabla1[idxFila][idxColumna])) + idxFila_NC = idxFila_NC + 1 - for idxFila in xrange (len (listaContenidoTabla2)): - - for idxColumna in xrange (len (listaHeaderTabla2)): - - self.Tabla_Prop_NC.setItem (idxFila, idxColumna, QTableWidgetItem (listaContenidoTabla2[idxFila][idxColumna])) - - self.Tabla_Prop_WMF.setHorizontalHeaderLabels (listaHeaderTabla1) - - self.Tabla_Prop_NC.setHorizontalHeaderLabels (listaHeaderTabla2) - - self.Tabla_Prop_WMF.setSelectionMode (QtGui.QAbstractItemView.SingleSelection) - self.Tabla_Prop_WMF.setSelectionBehavior (QtGui.QAbstractItemView.SelectRows) - - self.Tabla_Prop_NC.setSelectionMode (QtGui.QAbstractItemView.SingleSelection) - self.Tabla_Prop_NC.setSelectionBehavior (QtGui.QAbstractItemView.SelectRows) - - self.Button_Eliminar_Desde_WMF.clicked.connect (handleClickEventButton_Eliminar_Desde_WMF) - self.Button_Eliminar_Desde_NC.clicked.connect (handleClickEventButton_Eliminar_Desde_NC) - - self.Button_Actualizar_WMF_Desde_NC.clicked.connect (handleClickEventButton_Actualizar_WMF_Desde_NC) - - print "a" + if self.HSutils.DicBasinNc[keyParam]["basica"]: + self.Tabla_Prop_WMF.setItem (idxFila_WMF, 0, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["nombre"])) + self.Tabla_Prop_WMF.setItem (idxFila_WMF, 1, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["tipo"])) + self.Tabla_Prop_WMF.setItem (idxFila_WMF, 2, QTableWidgetItem (str (self.HSutils.DicBasinNc[keyParam]["shape"]))) + idxFila_WMF = idxFila_WMF + 1 From 77cea463067fc6b6bae8cee0368f97fec1987bca Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 18 Jun 2018 10:53:18 -0500 Subject: [PATCH 049/142] cambios: ahora carga el EPSG code y este se hace parte del proyecto actual, tambien carga el dx plano y se corrige error por el cual no se estaba tomando el dxplano del spinbox --- ensayo.py | 13 ++++---- qgisplugin/HydroSEDPluginUtils.py | 15 +++++----- qgisplugin/HydroSEDPlugin_dockwidget.py | 29 +++++++++++------- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 31 ++++++++++---------- wmf/wmf.py | 27 ++++++++++++----- 5 files changed, 69 insertions(+), 46 deletions(-) diff --git a/ensayo.py b/ensayo.py index 7bf3aa1..6637510 100644 --- a/ensayo.py +++ b/ensayo.py @@ -1,14 +1,17 @@ from wmf import wmf -DEM = wmf.read_map_raster('/home/nicolas/Dropbox/Trabajos/HZ/05_Buey/raster/demFin.tif', isDEMorDIR=True, +DEM,mierda = wmf.read_map_raster('/home/nicolas/Dropbox/Trabajos/HZ/05_Buey/raster/demFin.tif', isDEMorDIR=True, dxp = 53., noDataP = -9999) -DIR = wmf.read_map_raster('/home/nicolas/Dropbox/Trabajos/HZ/05_Buey/raster/dirFin.tif', isDEMorDIR=True, +DIR,mierda = wmf.read_map_raster('/home/nicolas/Dropbox/Trabajos/HZ/05_Buey/raster/dirFin.tif', isDEMorDIR=True, isDIR= True, dxp = 53., noDataP = -9999) -st = wmf.Stream(-75.5512, 5.8174, DEM, DIR) +#st = wmf.Stream(-75.5512, 5.8174, DEM, DIR) -cu = wmf.SimuBasin(-75.5538, 5.7580, DEM, DIR, stream=st, name='buey', umbral=70) +#cu = wmf.SimuBasin(-75.5538, 5.7580, DEM, DIR, stream=st, name='buey', umbral=70) #print cu.CellSlope -cu.Save_SimuBasin('Ensayo.nc') +#cu.Save_SimuBasin('Ensayo.nc') #cu = wmf.SimuBasin(rute='Ensayo.nc') + +#print epsg +print wmf.Global_EPSG diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 8aee041..44cc1ee 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -84,28 +84,29 @@ def cargar_mapa_dem_wmf (self,pathMapaDEM, dxp): retornoCargaLayerMapaRaster = False pathMapaDEM = pathMapaDEM.strip () - + EPSG_code = -999 try: - self.DEM = wmf.read_map_raster (pathMapaDEM, isDEMorDIR = True, dxp = dxp, noDataP = -9999) + self.DEM, EPSG_code = wmf.read_map_raster (pathMapaDEM, isDEMorDIR = True, dxp = dxp, noDataP = -9999) retornoCargaLayerMapaRaster = True except: retornoCargaLayerMapaRaster = False - return retornoCargaLayerMapaRaster + return retornoCargaLayerMapaRaster, EPSG_code def cargar_mapa_dir_wmf (self,pathMapaDIR, dxp): retornoCargaLayerMapaRaster = False pathMapaDIR = pathMapaDIR.strip () + EPSG_code = -999 try: - self.DIR = wmf.read_map_raster (pathMapaDIR, isDEMorDIR = True, isDIR = True, dxp = dxp, noDataP = -9999) + self.DIR, EPSG_code = wmf.read_map_raster (pathMapaDIR, isDEMorDIR = True, isDIR = True, dxp = dxp, noDataP = -9999) retornoCargaLayerMapaRaster = True except: self.DIR = 1 - return retornoCargaLayerMapaRaster + return retornoCargaLayerMapaRaster, EPSG_code def trazador_corriente(self,x,y, path = None): #Traza la corriente en las coordenadas especificadas @@ -168,8 +169,8 @@ def Basin_LoadBasin(self, PathNC): 'raster':MapaRaster, 'basica': True}}) g.close() - #Area de la cuenca - return self.cuenca.ncells*wmf.cu.dxp**2/1e6 + #Area de la cuenca y codigo EPSG + return self.cuenca.ncells*wmf.cu.dxp**2/1e6, self.cuenca.epsg, wmf.models.dxp def Basin_LoadBasinDivisory(self, PathDivisory): # Guarda los shapes de divisoria y de red hidrica. diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index e077e79..c00fe3d 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -152,13 +152,16 @@ def clickEventSelectorBasin(): self.ButtonLoadBasinProyect.setEnabled(True) def clickEventBasin2WMF(): '''Agrega el proyecto de cuenca a WMF''' - Area = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip()) + Area, EPSG_code, dxp = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip()) #Habilita los botones de visualizacion de red hidrica y divisoria self.Boton_verDivisoria.setEnabled(True) self.Boton_verRedHidrica.setEnabled(True) #Pone el area de la cuenca texto = '%.1f'%Area self.LabelBasinArea.setText(texto) + self.LineEditEPSG.setText(EPSG_code) + self.spinBox_dxPlano.setValue(dxp) + print dxp def clickEventBasinLoadDivisory(): '''Carga la divisoria de la cuenca cargada a WMF''' @@ -336,24 +339,22 @@ def clickEventVisualizarMapaDIR (): def clickEventCargarWMFMapaDEM (): - + '''Carga el mapa dDM base para WMF''' pathMapaDEM = self.lineEditMapaDEM.text ().strip () dxpMapaDEM = self.spinBox_dxPlano.value() - - flagCargaMapaDEM_WMF = self.HSutils.cargar_mapa_dem_wmf (pathMapaDEM, dxpMapaDEM) - + flagCargaMapaDEM_WMF, self.EPSG = self.HSutils.cargar_mapa_dem_wmf (pathMapaDEM, dxpMapaDEM) if flagCargaMapaDEM_WMF: - self.iface.messageBar().pushInfo (u'Hydro-SED', u'Se cargó el mapa MDE al WMF de forma exitosa') - else: - self.iface.messageBar().pushError (u'Hydro-SED', u'No fue posible cargar el mapa MDE al WMF. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.') - + #Pone el nombre del codigo EPSG en el dialogo. + self.LineEditEPSG.setText(self.EPSG) + def clickEventCargarWMFMapaDIR(): + '''Carga el mapa DIR base para WMF''' pathMapaDIR = self.lineEditMapaDIR.text ().strip () dxpMapaDIR = self.spinBox_dxPlano.value () - flagCargaMapaDIR_WMF = self.HSutils.cargar_mapa_dir_wmf (pathMapaDIR, dxpMapaDIR) + flagCargaMapaDIR_WMF, self.EPSG = self.HSutils.cargar_mapa_dir_wmf (pathMapaDIR, dxpMapaDIR) if flagCargaMapaDIR_WMF: self.iface.messageBar().pushInfo (u'Hydro-SED', u'Se cargó el mapa DIR al WMF de forma exitosa') else: @@ -421,7 +422,13 @@ def clickEventSelectorOutputCuencaNCTrazadorCuencas (): self.botonEjecutarTrazadorCuencas.clicked.connect(self.handleClickEventEjecutarTrazadorCuencas) #self.botonOutputCuencaShapefileTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaShapefileTrazadorCuencas) #self.botonOutputCuencaNCTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaNCTrazadorCuencas) - + #self.spinBox_dxPlano.setValue(self.spinBox_dxPlano.valueFromText()) + def set_dxplano(): + self.spinBox_dxPlano.value() + print self.spinBox_dxPlano.value() + self.spinBox_dxPlano.valueChanged.connect(set_dxplano) + + #def setupUIButtonEvents (self): #self.botonEjecutarTrazadorCorrientes.clicked.connect(self.handleClickEventEjecutarTrazadorCorrientes) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 5d12492..76f1d51 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -262,7 +262,7 @@ - 1 + 0 @@ -611,7 +611,7 @@ - Valor en metros del tamano de una celda en el mapa. + Código EPSG de los mapas DEM y DIR cargados para el proyecto. Valor en metros del tamano de una celda en el mapa. @@ -625,27 +625,28 @@ - - + + + Qt::Horizontal + + - 100 - 0 + 40 + 20 + + + + - 150 + 290 16777215 - - 0 - - - 10002.000000000000000 - - - 4326.000000000000000 + + true diff --git a/wmf/wmf.py b/wmf/wmf.py index cf249db..9aaf5ab 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -59,6 +59,8 @@ FlagBasinPolygon = False import random +#Variable codigo EPSG +Global_EPSG = -9999 #----------------------------------------------------------------------- #Ploteo de variables @@ -247,6 +249,9 @@ def read_map_raster(ruta_map,isDEMorDIR=False,dxp=None, noDataP = None,isDIR = F ' de cuencas y tramos.\n' \ #Abre el mapa direction=gdal.Open(ruta_map) + #Proyecction + proj = osgeo.osr.SpatialReference(wkt=direction.GetProjection()) + EPSG_code = proj.GetAttrValue('AUTHORITY',1) #lee la informacion del mapa ncols=direction.RasterXSize nrows=direction.RasterYSize @@ -275,21 +280,24 @@ def read_map_raster(ruta_map,isDEMorDIR=False,dxp=None, noDataP = None,isDIR = F if dxp==None: cu.dxp=30.0 else: - cu.dxp=dxp + cu.dxp=dxp + #Guarda la variable para el proyecto + global Global_EPSG + Global_EPSG = EPSG_code # si es un dir se fija si es de r.watershed if isDIR: if DIRformat == 'r.watershed': Mapa[Mapa<=0] = cu.nodata.astype(int) Mapa = cu.dir_reclass_rwatershed(Mapa.T,cu.ncols,cu.nrows) - return Mapa + return Mapa, EPSG_code if DIRformat == 'opentopo': Mapa[Mapa<=0] = cu.nodata.astype(int) Mapa = cu.dir_reclass_opentopo(Mapa.T,cu.ncols,cu.nrows) - return Mapa + return Mapa, EPSG_code #retorna el mapa - return Mapa.T + return Mapa.T,EPSG_code else: - return Mapa.T,[ncols,nrows,xll,yll,dx,dy,noData] + return Mapa.T,[ncols,nrows,xll,yll,dx,dy,noData],EPSG_code def read_map_points(ruta_map, ListAtr = None): 'Funcion: read_map_points\n'\ @@ -2752,8 +2760,8 @@ def __init__(self,lat=None,lon=None,DEM=None,DIR=None,rute = None, name='NaN',st self.radarPos = [] self.radarMeanRain = [] self.radarCont = 1 - #Si no hay ruta traza la cuenca - if rute is None: + #Si no hay ruta y el global del codigo EPSG existe, traza la cuenca + if rute is None and int(Global_EPSG) > 0: #Si se entrega cauce corrige coordenadas if stream is not None: error=[] @@ -2772,6 +2780,7 @@ def __init__(self,lat=None,lon=None,DEM=None,DIR=None,rute = None, name='NaN',st self.modelType=modelType self.nodata=noData self.umbral = umbral + self.epsg = Global_EPSG #Traza la cuenca self.ncells = cu.basin_find(lat,lon,DIR, cu.ncols,cu.nrows) @@ -2890,6 +2899,7 @@ def __Load_SimuBasin(self,ruta, sim_slides = False): self.umbral = gr.umbral self.ncells = gr.ncells self.nhills = gr.nhills + self.epsg = gr.epsg models.dt = gr.dt models.dxp = gr.dxp models.retorno = gr.retorno @@ -3931,7 +3941,8 @@ def Save_SimuBasin(self,ruta,SimSlides = False, 'xll':cu.xll, 'yll':cu.yll, 'dx':cu.dx, - 'dy':cu.dy} + 'dy':cu.dy, + 'epsg': self.epsg} if SimSlides: Dict.update({'sl_fs':models.sl_fs, 'sl_gullie':models.sl_gullienogullie, 'sl_gammaw':models.sl_gammaw}) #abre el archivo From 43ef6e4456b7aee1afe94faec5374362ac266956 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 18 Jun 2018 13:47:14 -0500 Subject: [PATCH 050/142] habilitado y funcionando el boton que carga mapas desde la tabla de NC --- qgisplugin/HydroSEDPluginUtils.py | 65 ++++----- qgisplugin/HydroSEDPlugin_dockwidget.py | 80 ++++++----- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 139 ++++++++++++------- 3 files changed, 163 insertions(+), 121 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 523ff74..61d264c 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -80,23 +80,16 @@ def cargar_mapa_vector(self, pathMapaVector, tipo_style, color = (50,50,250), wi return retornoCargarMapaVector, layerMapaVector def cargar_mapa_dem_wmf (self,pathMapaDEM, dxp): - retornoCargaLayerMapaRaster = False - pathMapaDEM = pathMapaDEM.strip () EPSG_code = -999 try: - self.DEM, EPSG_code = wmf.read_map_raster (pathMapaDEM, isDEMorDIR = True, dxp = dxp, noDataP = -9999) retornoCargaLayerMapaRaster = True - except: - retornoCargaLayerMapaRaster = False - return retornoCargaLayerMapaRaster, EPSG_code - def cargar_mapa_dir_wmf (self,pathMapaDIR, dxp): retornoCargaLayerMapaRaster = False pathMapaDIR = pathMapaDIR.strip () @@ -154,31 +147,6 @@ def Basin_LoadBasin(self, PathNC): self.NumDicBasinNcVariables = 0 # Numero Total de Variables Basicas self.NumDicBasinNcVariablesBasicas = 0 - - #Cargar la cuenca y sus variables base a WMF - self.cuenca = wmf.SimuBasin(rute = PathNC) - #Cargar las variables de la cuenca a un diccionario. - g = netCDF4.Dataset(PathNC) - for k in g.variables.keys(): - #Evalua si tiene la misma cantidad de celdas y puede ser un mapa - shape = g.variables[k].shape - MapaRaster = False - for s in shape: - if s == self.cuenca.ncells: - MapaRaster = True - #Actualiza el diccionario - self.DicBasinNc.update({k: - {'nombre':k, - 'tipo':g.variables[k].dtype.name, - 'shape':g.variables[k].shape, - 'raster':MapaRaster, - 'basica': True}}) - - self.NumDicBasinNcVariables = self.NumDicBasinNcVariables + 1 - self.NumDicBasinNcVariablesBasicas = self.NumDicBasinNcVariablesBasicas + 1 - - g.close() - #Cargar la cuenca y sus variables base a WMF self.cuenca = wmf.SimuBasin(rute = PathNC) #Cargar las variables de la cuenca a un diccionario. @@ -190,14 +158,19 @@ def Basin_LoadBasin(self, PathNC): for s in shape: if s == self.cuenca.ncells: MapaRaster = True - #Actualiza el diccionario - self.DicBasinNc.update({k: - {'nombre':k, - 'tipo':g.variables[k].dtype.name, - 'shape':g.variables[k].shape, - 'raster':MapaRaster, - 'basica': True}}) + #Actualiza el diccionario + self.DicBasinNc.update({k: + {'nombre':k, + 'tipo':g.variables[k].dtype.name, + 'shape':g.variables[k].shape, + 'raster':MapaRaster, + 'basica': True, + 'categoria': 'Base'}}) + self.NumDicBasinNcVariables = self.NumDicBasinNcVariables + 1 + self.NumDicBasinNcVariablesBasicas = self.NumDicBasinNcVariablesBasicas + 1 g.close() + #Cargar la cuenca y sus variables base a WMF + self.cuenca = wmf.SimuBasin(rute = PathNC) #Area de la cuenca y codigo EPSG return self.cuenca.ncells*wmf.cu.dxp**2/1e6, self.cuenca.epsg, wmf.models.dxp @@ -209,4 +182,16 @@ def Basin_LoadBasinNetwork(self, PathNetwork): # Guarda los shapes de divisoria y de red hidrica. self.cuenca.Save_Net2Map(PathNetwork, wmf.cu.dxp, self.cuenca.umbral) - + def Basin_LoadBasicVariable(self,PathNC, VarName): + '''Toma una variable del diccionario de variables basicas y la carga a Qgis''' + #Lee los datos del nc de la cuenca de la variable indicada + g = netCDF4.Dataset(PathNC) + Data = g.variables[VarName][:] + g.close() + #Transforma a un raster + rutaSalida = '/tmp/HydroSED/Raster_'+VarName+'.tiff' + self.cuenca.Transform_Basin2Map(Data, + ruta = rutaSalida, + EPSG = self.cuenca.epsg) + return rutaSalida + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index a2806d9..6ffa088 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -116,7 +116,11 @@ def handleClickEventEjecutarTrazadorCuencas (self): self.HSutils.trazador_cuenca(x,y, self.spinBox_dxPlano.value(), self.spinBoxUmbralRed.value(),OutPathDivisoria, OutPathRed, OutPathNC, self.lineEditMapaDEM, self.lineEditMapaDIR) - + #Establece a la cuenca trazada como el proyecto actual. + if len(OutPathNC)>2: + self.lineEditRutaCuenca.setText(OutPathNC) + self.ButtonLoadBasinProyect.setEnabled(True) + #Carga la divisoria ret, layer = self.HSutils.cargar_mapa_vector(OutPathDivisoria, self.HSutils.TIPO_STYLE_POLIGONO, color = (255,0,0), width = 0.6) self.iface.mapCanvas().refresh() @@ -312,34 +316,21 @@ def clickEventSelectorMapaDIR (): setupLineEditButtonOpenRasterFileDialog (self.lineEditMapaDIR, QFileDialog) def clickEventVisualizarMapaDEM (): - pathMapaDEM = self.lineEditMapaDEM.text ().strip () - flagCargaMapaDEM = self.HSutils.cargar_mapa_raster (pathMapaDEM) - if flagCargaMapaDEM: - self.iface.messageBar().pushInfo (u'Hydro-SED', u'Se cargó el mapa MDE de forma exitosa') - else: - self.iface.messageBar().pushError (u'Hydro-SED', u'No fue posible cargar el mapa MDE. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.') - + def clickEventVisualizarMapaDIR (): - pathMapaDIR = self.lineEditMapaDIR.text ().strip () - flagCargaMapaDIR = self.HSutils.cargar_mapa_raster (pathMapaDIR) - if flagCargaMapaDIR: - self.iface.messageBar().pushInfo (u'Hydro-SED', u'Se cargó el mapa DIR de forma exitosa') - else: - self.iface.messageBar().pushError (u'Hydro-SED', u'No fue posible cargar el mapa DIR. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.') - def clickEventCargarWMFMapaDEM (): '''Carga el mapa dDM base para WMF''' pathMapaDEM = self.lineEditMapaDEM.text ().strip () @@ -426,42 +417,49 @@ def clickEventSelectorOutputCuencaNCTrazadorCuencas (): #self.botonOutputCuencaNCTrazadorCuencas.clicked.connect (clickEventSelectorOutputCuencaNCTrazadorCuencas) #self.spinBox_dxPlano.setValue(self.spinBox_dxPlano.valueFromText()) def set_dxplano(): + #self.spinBox_dxPlano.valueFromText() self.spinBox_dxPlano.value() print self.spinBox_dxPlano.value() self.spinBox_dxPlano.valueChanged.connect(set_dxplano) - - #def setupUIButtonEvents (self): - - #self.botonEjecutarTrazadorCorrientes.clicked.connect(self.handleClickEventEjecutarTrazadorCorrientes) - #self.botonEjecutarTrazadorCorrientes.clicked.connect (self.handleClickEventEjecutarTrazadorCorrientes) - #self.botonEjecutarTrazadorCuencas.clicked.connect (self.handleClickEventEjecutarTrazadorCuencas) - + def setupTableEdicionAlmacenamientoParametrosWMFNC (self): def handleClickEventButton_Eliminar_Desde_WMF (): - selectedItems = self.Tabla_Prop_WMF.currentRow () self.Tabla_Prop_WMF.removeRow (selectedItems) + def handleClickEventButton_Eliminar_Desde_NC (): - selectedItems = self.Tabla_Prop_NC.currentRow () self.Tabla_Prop_NC.removeRow (selectedItems) def handleClickEventButton_Actualizar_WMF_Desde_NC (): - -# selectedItems = self.Tabla_Prop_NC.currentRow () - rows = sorted (set (index.row () for index in self.Tabla_Prop_NC.selectedIndexes ())) for row in rows: print('Row %d is selected' % row) - + + def handleClickEventButton_Ver_Desde_NC(): + '''Visualiza una de las variables de la cuenca en Qgis''' + #Variables de entrada + selectedItems = self.Tabla_Prop_NC.currentRow () + VarName = self.Tabla_Prop_NC.item(selectedItems,0).text() + PathNC = self.lineEditRutaCuenca.text() + #Ejecucion de la transformacion de la variable cuenca a raster + pathMapa = self.HSutils.Basin_LoadBasicVariable(PathNC, VarName) + #Visualiza + flagCargaMapa = self.HSutils.cargar_mapa_raster(pathMapa) + if flagCargaMapa: + self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'Se cargó la variable de forma exitosa') + else: + self.iface.messageBar().pushError (u'Hydro-SIG:', u'No fue posible cargar la variable') + + print self.HSutils.DicBasinNc print self.HSutils.NumDicBasinNcVariables - - listaHeaderTabla_NC = ["Nombre", "Tipo", "Shape"] - listaHeaderTabla_WMF = ["Nombre", "Tipo", "Shape"] + + listaHeaderTabla_NC = ["Nombre", "Tipo", "Forma", "Categoria"] + listaHeaderTabla_WMF = ["Nombre", "Tipo", "Forma", "Categoria"] self.Tabla_Prop_NC.setRowCount (self.HSutils.NumDicBasinNcVariables) self.Tabla_Prop_NC.setColumnCount (len (listaHeaderTabla_NC)) @@ -473,12 +471,26 @@ def handleClickEventButton_Actualizar_WMF_Desde_NC (): idxFila_NC = 0 idxFila_WMF = 0 - + + #Botones de borrado de variables + self.Tabla_Prop_WMF.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) + self.Tabla_Prop_WMF.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) + self.Button_Eliminar_Desde_WMF.clicked.connect(handleClickEventButton_Eliminar_Desde_WMF) + self.Tabla_Prop_NC.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) + self.Tabla_Prop_NC.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) + self.Button_Eliminar_Desde_NC.clicked.connect(handleClickEventButton_Eliminar_Desde_NC) + #Botones de visualizacion de variables + self.Tabla_Prop_NC.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) + self.Tabla_Prop_NC.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) + self.Button_Visualizar_Desde_NC.clicked.connect(handleClickEventButton_Ver_Desde_NC) + + #Carga las variables a la tabla for keyParam in self.HSutils.DicBasinNc: self.Tabla_Prop_NC.setItem (idxFila_NC, 0, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["nombre"])) self.Tabla_Prop_NC.setItem (idxFila_NC, 1, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["tipo"])) self.Tabla_Prop_NC.setItem (idxFila_NC, 2, QTableWidgetItem (str (self.HSutils.DicBasinNc[keyParam]["shape"]))) + self.Tabla_Prop_NC.setItem (idxFila_NC, 3, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["categoria"])) idxFila_NC = idxFila_NC + 1 @@ -487,8 +499,8 @@ def handleClickEventButton_Actualizar_WMF_Desde_NC (): self.Tabla_Prop_WMF.setItem (idxFila_WMF, 0, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["nombre"])) self.Tabla_Prop_WMF.setItem (idxFila_WMF, 1, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["tipo"])) self.Tabla_Prop_WMF.setItem (idxFila_WMF, 2, QTableWidgetItem (str (self.HSutils.DicBasinNc[keyParam]["shape"]))) + self.Tabla_Prop_WMF.setItem (idxFila_WMF, 3, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["categoria"])) idxFila_WMF = idxFila_WMF + 1 - - + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 76f1d51..b373a0d 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -308,7 +308,7 @@ 0 0 443 - 768 + 918 @@ -329,7 +329,7 @@ 300 - 750 + 900 @@ -344,13 +344,56 @@ 0 0 425 - 711 + 820 QLayout::SetMinimumSize + + + + + + Valor en metros del tamano de una celda en el mapa + (establecer antes de cargar MDE). + + + Valor en metros del tamano de una celda en el mapa. + + + Qt::LeftToRight + + + Valor Dxp [m] + + + + + + + + 100 + 0 + + + + + 150 + 16777215 + + + + 10000.000000000000000 + + + 12.699999999999999 + + + + + @@ -564,48 +607,6 @@ - - - - - - Valor en metros del tamano de una celda en el mapa. - - - Valor en metros del tamano de una celda en el mapa. - - - Qt::LeftToRight - - - Valor Dxp [m] - - - - - - - - 100 - 0 - - - - - 150 - 16777215 - - - - 10000.000000000000000 - - - 12.699999999999999 - - - - - @@ -659,6 +660,33 @@ + + + + Qt::Vertical + + + + 20 + 80 + + + + + + + + + 14 + 75 + true + + + + Variables de la cuenca. + + + @@ -736,7 +764,17 @@ - + + + + 0 + 200 + + + + true + + @@ -815,7 +853,14 @@ - + + + + 0 + 200 + + + From d252466085a1c5817e262881a53a4198bf785b50 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 18 Jun 2018 15:15:57 -0500 Subject: [PATCH 051/142] Carga variables desde la tabla de NC, esqueleto de funciones geomorfologicas, bugs: cuando el proyecto se carga de cero no agarra el dxp y tampoco el noData, corregir que la tabla de nc se refresque cuando se carga un proyecto nuevo. --- qgisplugin/HydroSEDPluginUtils.py | 38 +- qgisplugin/HydroSEDPlugin_dockwidget.py | 162 ++++--- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 462 ++++++++++++++++++- 3 files changed, 565 insertions(+), 97 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 61d264c..09fe91d 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -19,6 +19,7 @@ def __init__(self): self.BasinsCount = 0 self.StreamsCount = 0 self.DicBasinNc = {} + self.DicBasinWMF = {} def cargar_mapa_raster (self,pathMapaRaster): @@ -130,6 +131,15 @@ def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed, PathETROUT Rain = self.cuenca.Transform_Map2Basin(Rain, prop) #Realiza el balance self.cuenca.GetQ_Balance(Rain, Tipo_ETR = PathETR) + #Actualiza el diccionario de WMF + self.DicBasinWMF.update({'Caudal': + {'nombre':'Caudal', + 'tipo':'float32', + 'shape':self.cuenca.CellQmed.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Hidro', + 'var': self.cuenca.CellQmed}}) # Guarda el resultado if len(PathQmed)>2: self.cuenca.Save_Net2Map(PathQmed, dxp, umbral, qmed = self.cuenca.CellQmed) @@ -172,7 +182,7 @@ def Basin_LoadBasin(self, PathNC): #Cargar la cuenca y sus variables base a WMF self.cuenca = wmf.SimuBasin(rute = PathNC) #Area de la cuenca y codigo EPSG - return self.cuenca.ncells*wmf.cu.dxp**2/1e6, self.cuenca.epsg, wmf.models.dxp + return self.cuenca.ncells*wmf.cu.dxp**2./1e6, self.cuenca.epsg, wmf.models.dxp def Basin_LoadBasinDivisory(self, PathDivisory): # Guarda los shapes de divisoria y de red hidrica. @@ -195,3 +205,29 @@ def Basin_LoadBasicVariable(self,PathNC, VarName): EPSG = self.cuenca.epsg) return rutaSalida + def Basin_GeoGetHAND(self, umbral): + self.cuenca.GetGeo_HAND(umbral) + self.DicBasinWMF.update({'HAND': + {'nombre':'HAND', + 'tipo':'float32', + 'shape':self.cuenca.CellHAND.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geo', + 'var': self.cuenca.CellHAND}}) + self.DicBasinWMF.update({'HDND': + {'nombre':'HDND', + 'tipo':'float32', + 'shape':self.cuenca.CellHDND.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geo', + 'var': self.cuenca.CellHDND}}) + self.DicBasinWMF.update({'HAND_class': + {'nombre':'HAND_class', + 'tipo':'float32', + 'shape':self.cuenca.CellHAND_class.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geo', + 'var': self.cuenca.CellHAND_class}}) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 6ffa088..ae0ddd1 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -58,7 +58,9 @@ def __init__(self, iface = None, parent=None): self.setupHidro_Balance() self.setupBasinManager() #self.setupUIButtonEvents () - + + self.TablaFila_WMF = 0 + if not (iface is None): self.iface = iface self.HSutils = HSutils.controlHS() @@ -68,6 +70,15 @@ def __init__(self, iface = None, parent=None): self.spinBoxLongitudTrazadorCuencas) #self.iface.mapCanvas().setMapTool(GetCoords) + def UpdateTablePropWMF(self): + '''Actualiza la lista de las variables en la tabla de WMF''' + for keyParam in self.HSutils.DicBasinWMF: + self.Tabla_Prop_WMF.setItem (self.TablaFila_WMF, 0, QTableWidgetItem (self.HSutils.DicBasinWMF[keyParam]["nombre"])) + self.Tabla_Prop_WMF.setItem (self.TablaFila_WMF, 1, QTableWidgetItem (self.HSutils.DicBasinWMF[keyParam]["tipo"])) + self.Tabla_Prop_WMF.setItem (self.TablaFila_WMF, 2, QTableWidgetItem (str (self.HSutils.DicBasinWMF[keyParam]["shape"]))) + self.Tabla_Prop_WMF.setItem (self.TablaFila_WMF, 3, QTableWidgetItem (self.HSutils.DicBasinWMF[keyParam]["categoria"])) + self.TablaFila_WMF = self.TablaFila_WMF + 1 + def closeEvent(self, event): self.closingPlugin.emit() @@ -193,7 +204,17 @@ def clickEventBasinLoadNetwork(): self.Boton_verDivisoria.clicked.connect(clickEventBasinLoadDivisory) self.Boton_verRedHidrica.clicked.connect(clickEventBasinLoadNetwork) + def setupGeomorfologia(self): + def clickEventGeoHAND(): + self.HSutils.Basin_GeoGetHAND(1000) + #Actualiza la tabla de variables temporales + self.UpdateTablePropWMF() + + #Botones de ejecucion + self.BotonGeoHAND.clicked.connect(clickEventGeoHAND) + + def setupHidro_Balance(self): def setupLineEditButtonOpenRasterFileDialog (lineEditHolder, fileDialogHolder): @@ -270,7 +291,9 @@ def hadleClickEventEjecutarBalance(): self.Button_HidroViewRunoff.setEnabled(True) if len(self.PathOutHydro_ETR.text()) > 2: self.Button_HidroViewETR.setEnabled(True) - + #Actualiza la tabla de variables temporales + self.UpdateTablePropWMF() + #Botones para variables de entrada self.Boton_HidroLoadRain.clicked.connect(clickEventSelectorRaster) #Botones para variables de salida @@ -285,8 +308,65 @@ def hadleClickEventEjecutarBalance(): #Botones para ejecutar self.Butto_Ejec_HidroBalance.clicked.connect(hadleClickEventEjecutarBalance) + def setupTableEdicionAlmacenamientoParametrosWMFNC (self): + + print self.HSutils.DicBasinNc + print self.HSutils.NumDicBasinNcVariables + + listaHeaderTabla_NC = ["Nombre", "Tipo", "Forma", "Categoria"] + listaHeaderTabla_WMF = ["Nombre", "Tipo", "Forma", "Categoria"] + + self.Tabla_Prop_NC.setRowCount (self.HSutils.NumDicBasinNcVariables) + self.Tabla_Prop_NC.setColumnCount (len (listaHeaderTabla_NC)) + self.Tabla_Prop_NC.setHorizontalHeaderLabels (listaHeaderTabla_NC) + + self.Tabla_Prop_WMF.setRowCount (self.HSutils.NumDicBasinNcVariablesBasicas) + self.Tabla_Prop_WMF.setColumnCount (len (listaHeaderTabla_WMF)) + self.Tabla_Prop_WMF.setHorizontalHeaderLabels (listaHeaderTabla_WMF) + + idxFila_NC = 0 + idxFila_WMF = 0 + + #Carga las variables a la tabla + for keyParam in self.HSutils.DicBasinNc: + self.Tabla_Prop_NC.setItem (idxFila_NC, 0, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["nombre"])) + self.Tabla_Prop_NC.setItem (idxFila_NC, 1, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["tipo"])) + self.Tabla_Prop_NC.setItem (idxFila_NC, 2, QTableWidgetItem (str (self.HSutils.DicBasinNc[keyParam]["shape"]))) + self.Tabla_Prop_NC.setItem (idxFila_NC, 3, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["categoria"])) + idxFila_NC = idxFila_NC + 1 + def setupUIInputsOutputs (self): + + def handleClickEventButton_Eliminar_Desde_WMF (): + selectedItems = self.Tabla_Prop_WMF.currentRow () + self.Tabla_Prop_WMF.removeRow (selectedItems) + + + def handleClickEventButton_Eliminar_Desde_NC (): + selectedItems = self.Tabla_Prop_NC.currentRow () + self.Tabla_Prop_NC.removeRow (selectedItems) + def handleClickEventButton_Actualizar_WMF_Desde_NC (): + rows = sorted (set (index.row () for index in self.Tabla_Prop_NC.selectedIndexes ())) + for row in rows: + print('Row %d is selected' % row) + + def handleClickEventButton_Ver_Desde_NC(): + '''Visualiza una de las variables de la cuenca en Qgis''' + #Variables de entrada + selectedItems = self.Tabla_Prop_NC.currentRow () + VarName = self.Tabla_Prop_NC.item(selectedItems,0).text() + PathNC = self.lineEditRutaCuenca.text() + #Ejecucion de la transformacion de la variable cuenca a raster + pathMapa = self.HSutils.Basin_LoadBasicVariable(PathNC, VarName) + print pathMapa + #Visualiza + flagCargaMapa = self.HSutils.cargar_mapa_raster(pathMapa) + if flagCargaMapa: + self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'Se cargó la variable de forma exitosa') + else: + self.iface.messageBar().pushError (u'Hydro-SIG:', u'No fue posible cargar la variable') + def setupLineEditButtonOpenShapeFileDialog (lineEditHolder, fileDialogHolder): '''Hace que cuando se busquen shapes solo se encuetren formatos vectoriales''' lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Shapefiles (*.shp);;")) @@ -422,56 +502,6 @@ def set_dxplano(): print self.spinBox_dxPlano.value() self.spinBox_dxPlano.valueChanged.connect(set_dxplano) - - def setupTableEdicionAlmacenamientoParametrosWMFNC (self): - - def handleClickEventButton_Eliminar_Desde_WMF (): - selectedItems = self.Tabla_Prop_WMF.currentRow () - self.Tabla_Prop_WMF.removeRow (selectedItems) - - - def handleClickEventButton_Eliminar_Desde_NC (): - selectedItems = self.Tabla_Prop_NC.currentRow () - self.Tabla_Prop_NC.removeRow (selectedItems) - - def handleClickEventButton_Actualizar_WMF_Desde_NC (): - rows = sorted (set (index.row () for index in self.Tabla_Prop_NC.selectedIndexes ())) - for row in rows: - print('Row %d is selected' % row) - - def handleClickEventButton_Ver_Desde_NC(): - '''Visualiza una de las variables de la cuenca en Qgis''' - #Variables de entrada - selectedItems = self.Tabla_Prop_NC.currentRow () - VarName = self.Tabla_Prop_NC.item(selectedItems,0).text() - PathNC = self.lineEditRutaCuenca.text() - #Ejecucion de la transformacion de la variable cuenca a raster - pathMapa = self.HSutils.Basin_LoadBasicVariable(PathNC, VarName) - #Visualiza - flagCargaMapa = self.HSutils.cargar_mapa_raster(pathMapa) - if flagCargaMapa: - self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'Se cargó la variable de forma exitosa') - else: - self.iface.messageBar().pushError (u'Hydro-SIG:', u'No fue posible cargar la variable') - - - print self.HSutils.DicBasinNc - print self.HSutils.NumDicBasinNcVariables - - listaHeaderTabla_NC = ["Nombre", "Tipo", "Forma", "Categoria"] - listaHeaderTabla_WMF = ["Nombre", "Tipo", "Forma", "Categoria"] - - self.Tabla_Prop_NC.setRowCount (self.HSutils.NumDicBasinNcVariables) - self.Tabla_Prop_NC.setColumnCount (len (listaHeaderTabla_NC)) - self.Tabla_Prop_NC.setHorizontalHeaderLabels (listaHeaderTabla_NC) - - self.Tabla_Prop_WMF.setRowCount (self.HSutils.NumDicBasinNcVariablesBasicas) - self.Tabla_Prop_WMF.setColumnCount (len (listaHeaderTabla_WMF)) - self.Tabla_Prop_WMF.setHorizontalHeaderLabels (listaHeaderTabla_WMF) - - idxFila_NC = 0 - idxFila_WMF = 0 - #Botones de borrado de variables self.Tabla_Prop_WMF.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) self.Tabla_Prop_WMF.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) @@ -483,24 +513,14 @@ def handleClickEventButton_Ver_Desde_NC(): self.Tabla_Prop_NC.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) self.Tabla_Prop_NC.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self.Button_Visualizar_Desde_NC.clicked.connect(handleClickEventButton_Ver_Desde_NC) - - #Carga las variables a la tabla - for keyParam in self.HSutils.DicBasinNc: - - self.Tabla_Prop_NC.setItem (idxFila_NC, 0, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["nombre"])) - self.Tabla_Prop_NC.setItem (idxFila_NC, 1, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["tipo"])) - self.Tabla_Prop_NC.setItem (idxFila_NC, 2, QTableWidgetItem (str (self.HSutils.DicBasinNc[keyParam]["shape"]))) - self.Tabla_Prop_NC.setItem (idxFila_NC, 3, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["categoria"])) - - idxFila_NC = idxFila_NC + 1 - - if self.HSutils.DicBasinNc[keyParam]["basica"]: - - self.Tabla_Prop_WMF.setItem (idxFila_WMF, 0, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["nombre"])) - self.Tabla_Prop_WMF.setItem (idxFila_WMF, 1, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["tipo"])) - self.Tabla_Prop_WMF.setItem (idxFila_WMF, 2, QTableWidgetItem (str (self.HSutils.DicBasinNc[keyParam]["shape"]))) - self.Tabla_Prop_WMF.setItem (idxFila_WMF, 3, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["categoria"])) - - idxFila_WMF = idxFila_WMF + 1 + + + + #for keyParam in self.HSutils.DicBasinWMF: + #self.Tabla_Prop_WMF.setItem (idxFila_WMF, 0, QTableWidgetItem (self.HSutils.DicBasinWMF[keyParam]["nombre"])) + #self.Tabla_Prop_WMF.setItem (idxFila_WMF, 1, QTableWidgetItem (self.HSutils.DicBasinWMF[keyParam]["tipo"])) + #self.Tabla_Prop_WMF.setItem (idxFila_WMF, 2, QTableWidgetItem (str (self.HSutils.DicBasinWMF[keyParam]["shape"]))) + #self.Tabla_Prop_WMF.setItem (idxFila_WMF, 3, QTableWidgetItem (self.HSutils.DicBasinWMF[keyParam]["categoria"])) + #idxFila_WMF = idxFila_WMF + 1 diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index b373a0d..a444df7 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -860,6 +860,9 @@ 200 + + true + @@ -2923,7 +2926,7 @@ 0 0 - 430 + 461 730 @@ -2953,7 +2956,7 @@ 0 0 - 412 + 443 1918 @@ -2989,14 +2992,14 @@ 0 0 - 395 - 200 + 431 + 100 0 - 200 + 100 @@ -3005,6 +3008,9 @@ 16777215 + + Obtiene celda a celda: pendiente, acumulado, long de celdas y elevacion. + Parametros basicos geomorfologicos @@ -3014,53 +3020,304 @@ + + + + + 0 + 10 + + + + + 75 + true + + + + Datos de entrada: + + + - Lluvia + Umbral - + false - + + + Ejecuta el balance de largo plazo con los parametros dados. + + + Ejecuta el balance de largo plazo con los parametros dados. + - + Ejecutar - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + + 0 + 100 + 431 + 100 + + + + + 0 + 100 + + + + + 16777215 + 16777215 + + + + Obtiene la elevación relativa al canal mas cercano HAND y la distancia horizontal HDND + + + Elevación relativa al canal más cercano (HAND) + + + false + + + + + + + + + 0 + 10 + + + + + 75 + true + + + + Datos de entrada: + + + + + + + + + Umbral + + + + + + + false + + + + + + + Ejecuta el balance de largo plazo con los parametros dados. + + + Ejecuta el balance de largo plazo con los parametros dados. + + + Ejecutar + + + + + + + + 0 + 200 + 431 + 100 + + + + + 0 + 100 + + + + + 16777215 + 16777215 + + + + Obtiene el orden de orton de cada una de las laderas de la cuenca. + + + Orden de laderas y canales. + + + false + + + + + + + + + 0 + 10 + + + + + 75 + true + + + + Datos de entrada: + + + - + + + Umbral + + + + + + + false + + + + + + + Ejecuta el balance de largo plazo con los parametros dados. + + + Ejecuta el balance de largo plazo con los parametros dados. + + + Ejecutar + + + + + + + + + + + + + 0 + 500 + 431 + 100 + + + + + 0 + 100 + + + + + 16777215 + 16777215 + + + + Acumula una variable ingresada como un mapa raster. + + + Acumular variable en la cuenca. + + + false + + + + + + + + + 0 + 10 + + + + + 75 + true + + + + Datos de entrada: + + + + + + + - ETR + Variable - + false - + @@ -3070,35 +3327,190 @@ + + + + Ejecuta el balance de largo plazo con los parametros dados. + + + Ejecuta el balance de largo plazo con los parametros dados. + + + Ejecutar + + + + + + + + + + + 0 + 300 + 431 + 100 + + + + + 0 + 100 + + + + + 16777215 + 16777215 + + + + Obtiene la distancia a la salida de cada una de las celdas de la cuenca. + + + Distancia a la salida [km] + + + false + + + + - + + + + 0 + 10 + + + + + 75 + true + + + + Datos de entrada: + + + + + - + - Choudry + Umbral - + + + false + + + + + + + Ejecuta el balance de largo plazo con los parametros dados. + + + Ejecuta el balance de largo plazo con los parametros dados. + - Cenicafe + Ejecutar + + + + + + + + + + 0 + 400 + 431 + 100 + + + + + 0 + 100 + + + + + 16777215 + 16777215 + + + + Obtiene el índice topográfico de cada celda (Beven, 1979). + + + Índice topográfico (IT). + + + false + + + + + + + + + 0 + 10 + + + + + 75 + true + + + + Datos de entrada: + + + + + - + - Turc + Umbral + + + + + + + false - + + + Ejecuta el balance de largo plazo con los parametros dados. + + + Ejecuta el balance de largo plazo con los parametros dados. + - Map + Ejecutar From 8b0fdf0114c88335e6b1cbd226e59c8377c9d94e Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 19 Jun 2018 11:24:38 -0500 Subject: [PATCH 052/142] se corrigen los bugs por los cuales el noData era diferente cuando se cargaba la cuenca o un mapa DEM, y el bug del dxp que se carga desde la cuenca, el cual iniciaba en cero. --- qgisplugin/HydroSEDPluginUtils.py | 4 +- qgisplugin/HydroSEDPlugin_dockwidget.py | 10 +- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 48 +- wmf/wmf.py | 5788 +++++++++--------- 4 files changed, 2939 insertions(+), 2911 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 09fe91d..5d1d95e 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -89,7 +89,7 @@ def cargar_mapa_dem_wmf (self,pathMapaDEM, dxp): retornoCargaLayerMapaRaster = True except: retornoCargaLayerMapaRaster = False - return retornoCargaLayerMapaRaster, EPSG_code + return retornoCargaLayerMapaRaster, EPSG_code, wmf.cu.nodata def cargar_mapa_dir_wmf (self,pathMapaDIR, dxp): retornoCargaLayerMapaRaster = False @@ -182,7 +182,7 @@ def Basin_LoadBasin(self, PathNC): #Cargar la cuenca y sus variables base a WMF self.cuenca = wmf.SimuBasin(rute = PathNC) #Area de la cuenca y codigo EPSG - return self.cuenca.ncells*wmf.cu.dxp**2./1e6, self.cuenca.epsg, wmf.models.dxp + return self.cuenca.ncells*wmf.cu.dxp**2./1e6, self.cuenca.epsg, wmf.models.dxp, wmf.cu.nodata def Basin_LoadBasinDivisory(self, PathDivisory): # Guarda los shapes de divisoria y de red hidrica. diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index ae0ddd1..aeeb0ad 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -169,14 +169,16 @@ def clickEventBasin2WMF(): self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip()) self.setupTableEdicionAlmacenamientoParametrosWMFNC () - Area, EPSG_code, dxp = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip()) + Area, self.EPSG, dxp, self.noData = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip()) #Habilita los botones de visualizacion de red hidrica y divisoria self.Boton_verDivisoria.setEnabled(True) self.Boton_verRedHidrica.setEnabled(True) #Pone el area de la cuenca texto = '%.1f'%Area self.LabelBasinArea.setText(texto) - self.LineEditEPSG.setText(EPSG_code) + self.LineEditEPSG.setText(self.EPSG) + texto = '%.1f' % self.noData + self.LineEditNoData.setText(texto) self.spinBox_dxPlano.setValue(dxp) print dxp @@ -415,13 +417,15 @@ def clickEventCargarWMFMapaDEM (): '''Carga el mapa dDM base para WMF''' pathMapaDEM = self.lineEditMapaDEM.text ().strip () dxpMapaDEM = self.spinBox_dxPlano.value() - flagCargaMapaDEM_WMF, self.EPSG = self.HSutils.cargar_mapa_dem_wmf (pathMapaDEM, dxpMapaDEM) + flagCargaMapaDEM_WMF, self.EPSG, self.noData = self.HSutils.cargar_mapa_dem_wmf (pathMapaDEM, dxpMapaDEM) if flagCargaMapaDEM_WMF: self.iface.messageBar().pushInfo (u'Hydro-SED', u'Se cargó el mapa MDE al WMF de forma exitosa') else: self.iface.messageBar().pushError (u'Hydro-SED', u'No fue posible cargar el mapa MDE al WMF. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.') #Pone el nombre del codigo EPSG en el dialogo. self.LineEditEPSG.setText(self.EPSG) + t = '%.1f' % self.noData + self.LineEditNoData.setText(t) def clickEventCargarWMFMapaDIR(): '''Carga el mapa DIR base para WMF''' diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index a444df7..868cebe 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -344,7 +344,7 @@ 0 0 425 - 820 + 855 @@ -653,6 +653,52 @@ + + + + + + Código EPSG de los mapas DEM y DIR cargados para el proyecto. + + + Valor en metros del tamano de una celda en el mapa. + + + Qt::LeftToRight + + + Valor datos nulos + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 290 + 16777215 + + + + true + + + + + diff --git a/wmf/wmf.py b/wmf/wmf.py index 9aaf5ab..42df034 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -30,27 +30,27 @@ from multiprocessing import Pool import matplotlib.path as mplPath try: - import netcdf as netcdf + import netcdf as netcdf except: - try: - import netCDF4 as netcdf - except: - print 'No netcdf en esta maquina, se desabilita la funcion SimuBasin.save_SimuBasin' - pass + try: + import netCDF4 as netcdf + except: + print 'No netcdf en esta maquina, se desabilita la funcion SimuBasin.save_SimuBasin' + pass try: - from mpl_toolkits.basemap import Basemap, addcyclic, shiftgrid, cm - from matplotlib.patches import Polygon - from matplotlib.collections import PatchCollection + from mpl_toolkits.basemap import Basemap, addcyclic, shiftgrid, cm + from matplotlib.patches import Polygon + from matplotlib.collections import PatchCollection except: - print 'No se logra importar basemap, por lo tanto no funciona Plot_basin' - pass + print 'No se logra importar basemap, por lo tanto no funciona Plot_basin' + pass try: - from deap import base, creator - from deap import tools - FlagCalib_NSGAII = True + from deap import base, creator + from deap import tools + FlagCalib_NSGAII = True except: - print 'No se logra importar deap tools, por lo tanto se deshabilita SimuBasin.Calib_NSGAII' - FlagCalib_NSGAII = False + print 'No se logra importar deap tools, por lo tanto se deshabilita SimuBasin.Calib_NSGAII' + FlagCalib_NSGAII = False try: import rasterio.features as __fea__ FlagBasinPolygon = True @@ -66,991 +66,992 @@ #Ploteo de variables #----------------------------------------------------------------------- def plot_sim_single(Qs,Qo=None,mrain=None,Dates=None,ruta=None, - figsize=(8,4.5),ids=None,legend=True,ax1 = None,**kwargs): - '''ENTRADAS: - Qs = Caudal simulado, variable tipo lista - Qo = Caudal observado, variable tipo lista - mrain = Lluvia media observada,variable tipo lista - Dates = Indice de tiempo (Datetime), variable tipo lista - ids = Identificador de puntos de control - ax1 = axis o entorno para graficar - **kwargs = Argumentos por defecto, se pueden cambiar. - Estos argumentos son: + figsize=(8,4.5),ids=None,legend=True,ax1 = None,**kwargs): + '''ENTRADAS: + Qs = Caudal simulado, variable tipo lista + Qo = Caudal observado, variable tipo lista + mrain = Lluvia media observada,variable tipo lista + Dates = Indice de tiempo (Datetime), variable tipo lista + ids = Identificador de puntos de control + ax1 = axis o entorno para graficar + **kwargs = Argumentos por defecto, se pueden cambiar. + Estos argumentos son: - ARGUMENTOS POR DEFECTO - rain_alpha': 0.4, Transparencia de la lluvia - rain_color': blue, Color de la lluvia - rain_lw : 0, Ancho de linea de lluvia - rain_ylabel: Precipitation [$mm$], Etiqueta del eje y de la lluvia - label_size: 14, Tamano de fuente - rain_ylim : Se ajusta, Limite del eje y - ColorSim : ['r','g','k','c','y'], Colores para simulacion de caudal - Qs_lw : 1.5, Ancho de linea de caudal simulado - Qo_lw : 2.0, Ancho de linea de caudal observado - Qs_color : red, Color de linea de caudal simulado - Qo_color : blue, Color de linea de caudal observado - Qo_label : Observed, Leyenda de caudal observado - Qs_label : Simulated, Leyenda de caudal simulado - xlabel : Time [$min$], Etiqueta del eje x - ylabel : Streamflow $[m^3/seg], Etiqueta del eje y - legend_loc : upper center, Ubicacion de la leyenda - bbox_to_anchor : (0.5,-0.12), Ajuste de la caja de la leyenda - legend_ncol : 4, Numero de columnas para la leyenda - ''' - show = kwargs.get('show',True) - if ax1 == None: - fig=pl.figure(facecolor='w',edgecolor='w',figsize=figsize) - ax1=fig.add_subplot(111) - else: - show = False - #Fechas - if Dates==None: - if len(Qs.shape)>1: - ejeX=range(len(Qs[0])) - else: - ejeX = range(len(Qs)) - else: - ejeX=Dates - #Grafica la lluvia - if mrain is not None: - ax1AX=pl.gca() - ax2=ax1.twinx() - ax2AX=pl.gca() - alpha = kwargs.get('rain_alpha',0.4) - color = kwargs.get('rain_color','blue') - lw = kwargs.get('rain_lw',0) - ax2.fill_between(ejeX,0,mrain,alpha=alpha,color=color,lw=lw) - ylabel = kwargs.get('rain_ylabel','Precipitation [$mm$]') - label_size = kwargs.get('label_size',14) - ax2.set_ylabel(ylabel,size=label_size) - ylim = kwargs.get('rain_ylim',ax2AX.get_ylim() [::-1]) - ax2AX.set_ylim(ylim) - else: - ax2 = None - #grafica las hidrografas - ColorSim=kwargs.get('ColorSim',['r','g','k','c','y']) - Qs_lw = kwargs.get('Qs_lw',1.5) - Qo_lw = kwargs.get('Qo_lw',2.0) - Qs_color = kwargs.get('Qs_color','r') - Qo_color = kwargs.get('Qo_color','b') - Qo_label = kwargs.get('Qo_label','Observed') - Qs_label = kwargs.get('Qs_label','Simulated') - if len(Qs.shape)>1: - if ids is None: - ids = np.arange(1,Qs.shape[0]+1) - for i,c,d in zip(Qs,ColorSim,ids): - ax1.plot(ejeX,i,c,lw=Qs_lw,label=str(d)) - else: - ax1.plot(ejeX,Qs,Qs_color,lw=Qs_lw,label=Qs_label) - if Qo is not None: ax1.plot(ejeX,Qo,Qo_color,lw=Qo_lw,label=Qo_label) - #Pone elementos en la figura - xlabel = kwargs.get('xlabel','Time [$min$]') - ylabel = kwargs.get('ylabel','Streamflow $[m^3/seg]$') - label_size = kwargs.get('label_size', 16) - ax1.set_xlabel(xlabel,size=label_size) - ax1.set_ylabel(ylabel,size=label_size) - ax1.grid(True) - loc = kwargs.get('legend_loc','upper center') - bbox_to_anchor = kwargs.get('bbox_to_anchor',(0.5,-0.12)) - ncol = kwargs.get('legend_ncol',4) - if legend == True: - lgn1=ax1.legend(loc=loc, bbox_to_anchor=bbox_to_anchor, - fancybox=True, shadow=True, ncol=ncol) - if ruta is not None: - pl.savefig(ruta, bbox_inches='tight') - if show == True: - pl.show() - return ax1, ax2 + ARGUMENTOS POR DEFECTO + rain_alpha': 0.4, Transparencia de la lluvia + rain_color': blue, Color de la lluvia + rain_lw : 0, Ancho de linea de lluvia + rain_ylabel: Precipitation [$mm$], Etiqueta del eje y de la lluvia + label_size: 14, Tamano de fuente + rain_ylim : Se ajusta, Limite del eje y + ColorSim : ['r','g','k','c','y'], Colores para simulacion de caudal + Qs_lw : 1.5, Ancho de linea de caudal simulado + Qo_lw : 2.0, Ancho de linea de caudal observado + Qs_color : red, Color de linea de caudal simulado + Qo_color : blue, Color de linea de caudal observado + Qo_label : Observed, Leyenda de caudal observado + Qs_label : Simulated, Leyenda de caudal simulado + xlabel : Time [$min$], Etiqueta del eje x + ylabel : Streamflow $[m^3/seg], Etiqueta del eje y + legend_loc : upper center, Ubicacion de la leyenda + bbox_to_anchor : (0.5,-0.12), Ajuste de la caja de la leyenda + legend_ncol : 4, Numero de columnas para la leyenda + ''' + #Argumentos kw + show = kwargs.get('show',True) + if ax1 == None: + fig=pl.figure(facecolor='w',edgecolor='w',figsize=figsize) + ax1=fig.add_subplot(111) + else: + show = False + #Fechas + if Dates==None: + if len(Qs.shape)>1: + ejeX=range(len(Qs[0])) + else: + ejeX = range(len(Qs)) + else: + ejeX=Dates + #Grafica la lluvia + if mrain is not None: + ax1AX=pl.gca() + ax2=ax1.twinx() + ax2AX=pl.gca() + alpha = kwargs.get('rain_alpha',0.4) + color = kwargs.get('rain_color','blue') + lw = kwargs.get('rain_lw',0) + ax2.fill_between(ejeX,0,mrain,alpha=alpha,color=color,lw=lw) + ylabel = kwargs.get('rain_ylabel','Precipitation [$mm$]') + label_size = kwargs.get('label_size',14) + ax2.set_ylabel(ylabel,size=label_size) + ylim = kwargs.get('rain_ylim',ax2AX.get_ylim() [::-1]) + ax2AX.set_ylim(ylim) + else: + ax2 = None + #grafica las hidrografas + ColorSim=kwargs.get('ColorSim',['r','g','k','c','y']) + Qs_lw = kwargs.get('Qs_lw',1.5) + Qo_lw = kwargs.get('Qo_lw',2.0) + Qs_color = kwargs.get('Qs_color','r') + Qo_color = kwargs.get('Qo_color','b') + Qo_label = kwargs.get('Qo_label','Observed') + Qs_label = kwargs.get('Qs_label','Simulated') + if len(Qs.shape)>1: + if ids is None: + ids = np.arange(1,Qs.shape[0]+1) + for i,c,d in zip(Qs,ColorSim,ids): + ax1.plot(ejeX,i,c,lw=Qs_lw,label=str(d)) + else: + ax1.plot(ejeX,Qs,Qs_color,lw=Qs_lw,label=Qs_label) + if Qo is not None: ax1.plot(ejeX,Qo,Qo_color,lw=Qo_lw,label=Qo_label) + #Pone elementos en la figura + xlabel = kwargs.get('xlabel','Time [$min$]') + ylabel = kwargs.get('ylabel','Streamflow $[m^3/seg]$') + label_size = kwargs.get('label_size', 16) + ax1.set_xlabel(xlabel,size=label_size) + ax1.set_ylabel(ylabel,size=label_size) + ax1.grid(True) + loc = kwargs.get('legend_loc','upper center') + bbox_to_anchor = kwargs.get('bbox_to_anchor',(0.5,-0.12)) + ncol = kwargs.get('legend_ncol',4) + if legend == True: + lgn1=ax1.legend(loc=loc, bbox_to_anchor=bbox_to_anchor, + fancybox=True, shadow=True, ncol=ncol) + if ruta is not None: + pl.savefig(ruta, bbox_inches='tight') + if show == True: + pl.show() + return ax1, ax2 def plot_mean_storage(Mean_Storage, Dates = None, mrain = None, - rute = None, **kwargs): - 'Funcion: plot_mean_storage\n'\ - 'Descripcion: Plotea como se encuentran los almacenamientos medios en la cuenca.\n'\ - 'Parametros Obligatorios:.\n'\ - ' -Mean_Storage: almacenamiento medio en cada uno de los tanques (5,Npasos).\n'\ - ' Esta es la variables obtenida por wmf.SimuBasin.run_shia como Mean_Storage.\n'\ - 'Parametros Opcionales:.\n'\ - ' -Dates: Fechas para el plot\n'\ - ' -marin: Lluvia promedio sobre la cuenca\n'\ - ' -rute: Ruta donde se va a guardar\n'\ - ' -kwargs: algunos argumentos de set del plot\n'\ - ' - figsize: tamano de la figura.\n'\ - ' - color: Color de los plot.\n'\ - ' - lw: ancho de la linea del plot.\n'\ - ' - labelsize: tamano de los label.\n'\ - ' - ysize: tamano de la fuente en el eje Y.\n'\ - 'Retorno:.\n'\ - ' Plot de los almacenamientos medios.\n'\ - #Argumentos kw - figsize = kwargs.get('figsize',(13,9)) - color = kwargs.get('color','k') - lw = kwargs.get('lw',4) - labelsize = kwargs.get('labelsize', 14) - ysize = kwargs.get('ysize', 16) - show = kwargs.get('show',True) - alpha = kwargs.get('alpha',0.5) - colorRain = kwargs.get('colorRain','b') - lwRain = kwargs.get('lwRain',0.1) - #Inicio de la funcion - if Dates==None: - ejeX=range(Mean_Storage.shape[1]) - else: - ejeX=Dates - #figura - fig = pl.figure(figsize = figsize) - nombres = ['Hu','Runoff','Hg','Sub','Stream'] - for c,i in enumerate(Mean_Storage): - ax = fig.add_subplot(5,1,c+1) - ax.plot(ejeX, i, color, lw = lw) - ax.grid() - # Deja el eje X solo en el ultimo plot - if c<4: - ax.set_xticklabels([]) - ax.tick_params(labelsize = labelsize) - #Pinta la lluvia en el primer plot - if c == 0 and mrain is not None: - ax2=ax.twinx() - ax2AX=pl.gca() - ax2.fill_between(ejeX,0,mrain,alpha=alpha,color=colorRain,lw=lwRain) - ylim = ax2AX.get_ylim()[::-1]; ylim = list(ylim); ylim[1] = 0 - ax2AX.set_ylim(ylim) - #Nombre de cada tanque - ax.set_ylabel(nombres[c], size = ysize) - if rute is not None: - pl.savefig(rute, bbox_inches='tight') - if show == True: - pl.show() - if c == 0 and mrain is not None: - return ax, ax2 - else: - return ax + rute = None, **kwargs): + 'Funcion: plot_mean_storage\n'\ + 'Descripcion: Plotea como se encuentran los almacenamientos medios en la cuenca.\n'\ + 'Parametros Obligatorios:.\n'\ + ' -Mean_Storage: almacenamiento medio en cada uno de los tanques (5,Npasos).\n'\ + ' Esta es la variables obtenida por wmf.SimuBasin.run_shia como Mean_Storage.\n'\ + 'Parametros Opcionales:.\n'\ + ' -Dates: Fechas para el plot\n'\ + ' -marin: Lluvia promedio sobre la cuenca\n'\ + ' -rute: Ruta donde se va a guardar\n'\ + ' -kwargs: algunos argumentos de set del plot\n'\ + ' - figsize: tamano de la figura.\n'\ + ' - color: Color de los plot.\n'\ + ' - lw: ancho de la linea del plot.\n'\ + ' - labelsize: tamano de los label.\n'\ + ' - ysize: tamano de la fuente en el eje Y.\n'\ + 'Retorno:.\n'\ + ' Plot de los almacenamientos medios.\n'\ + #Argumentos kw + figsize = kwargs.get('figsize',(13,9)) + color = kwargs.get('color','k') + lw = kwargs.get('lw',4) + labelsize = kwargs.get('labelsize', 14) + ysize = kwargs.get('ysize', 16) + show = kwargs.get('show',True) + alpha = kwargs.get('alpha',0.5) + colorRain = kwargs.get('colorRain','b') + lwRain = kwargs.get('lwRain',0.1) + #Inicio de la funcion + if Dates==None: + ejeX=range(Mean_Storage.shape[1]) + else: + ejeX=Dates + #figura + fig = pl.figure(figsize = figsize) + nombres = ['Hu','Runoff','Hg','Sub','Stream'] + for c,i in enumerate(Mean_Storage): + ax = fig.add_subplot(5,1,c+1) + ax.plot(ejeX, i, color, lw = lw) + ax.grid() + # Deja el eje X solo en el ultimo plot + if c<4: + ax.set_xticklabels([]) + ax.tick_params(labelsize = labelsize) + #Pinta la lluvia en el primer plot + if c == 0 and mrain is not None: + ax2=ax.twinx() + ax2AX=pl.gca() + ax2.fill_between(ejeX,0,mrain,alpha=alpha,color=colorRain,lw=lwRain) + ylim = ax2AX.get_ylim()[::-1]; ylim = list(ylim); ylim[1] = 0 + ax2AX.set_ylim(ylim) + #Nombre de cada tanque + ax.set_ylabel(nombres[c], size = ysize) + if rute is not None: + pl.savefig(rute, bbox_inches='tight') + if show == True: + pl.show() + if c == 0 and mrain is not None: + return ax, ax2 + else: + return ax #----------------------------------------------------------------------- #Lectura de informacion y mapas #----------------------------------------------------------------------- def read_map_raster(ruta_map,isDEMorDIR=False,dxp=None, noDataP = None,isDIR = False,DIRformat = 'r.watershed'): - 'Funcion: read_map\n'\ - 'Descripcion: Lee un mapa raster soportado por GDAL.\n'\ - 'Parametros Obligatorios:.\n'\ - ' -ruta_map: Ruta donde se encuentra el mapa.\n'\ - 'Parametros Opcionales:.\n'\ - ' -isDEMorDIR: Pasa las propiedades de los mapas al modulo cuencas \n'\ - ' escrito en fortran \n'\ - ' -dxp: tamano plano del mapa\n'\ - ' -noDataP: Valor para datos nulos en el mapa (-9999)\n'\ - ' -DIRformat: donde se ha conseguido el mapa dir (r.watershed) \n'\ - ' - r.watershed: mapa de direcciones obtenido por la funcion de GRASS\n'\ - ' - opentopo: mapa de direcciones de http://www.opentopography.org/\n'\ - ' -isDIR: (FALSE) es este un mapa de direcciones\n'\ - 'Retorno:.\n'\ - ' Si no es DEM o DIR retorna todas las propieades del elemento en un vector.\n'\ - ' En el siguiente orden: ncols,nrows,xll,yll,dx,nodata.\n'\ - ' Si es DEM o DIR le pasa las propieades a cuencas para el posterior trazado.\n'\ - ' de cuencas y tramos.\n' \ + 'Funcion: read_map\n'\ + 'Descripcion: Lee un mapa raster soportado por GDAL.\n'\ + 'Parametros Obligatorios:.\n'\ + ' -ruta_map: Ruta donde se encuentra el mapa.\n'\ + 'Parametros Opcionales:.\n'\ + ' -isDEMorDIR: Pasa las propiedades de los mapas al modulo cuencas \n'\ + ' escrito en fortran \n'\ + ' -dxp: tamano plano del mapa\n'\ + ' -noDataP: Valor para datos nulos en el mapa (-9999)\n'\ + ' -DIRformat: donde se ha conseguido el mapa dir (r.watershed) \n'\ + ' - r.watershed: mapa de direcciones obtenido por la funcion de GRASS\n'\ + ' - opentopo: mapa de direcciones de http://www.opentopography.org/\n'\ + ' -isDIR: (FALSE) es este un mapa de direcciones\n'\ + 'Retorno:.\n'\ + ' Si no es DEM o DIR retorna todas las propieades del elemento en un vector.\n'\ + ' En el siguiente orden: ncols,nrows,xll,yll,dx,nodata.\n'\ + ' Si es DEM o DIR le pasa las propieades a cuencas para el posterior trazado.\n'\ + ' de cuencas y tramos.\n' \ #Abre el mapa - direction=gdal.Open(ruta_map) - #Proyecction - proj = osgeo.osr.SpatialReference(wkt=direction.GetProjection()) - EPSG_code = proj.GetAttrValue('AUTHORITY',1) - #lee la informacion del mapa - ncols=direction.RasterXSize - nrows=direction.RasterYSize - banda=direction.GetRasterBand(1) - noData=banda.GetNoDataValue() - geoT=direction.GetGeoTransform() - dx=geoT[1] - dy = np.abs(geoT[-1]) - xll=geoT[0]; yll=geoT[3]-nrows*dy - #lee el mapa - Mapa=direction.ReadAsArray() - direction.FlushCache() - del direction - if isDEMorDIR==True: - cu.ncols=ncols - cu.nrows=nrows - if noDataP is not None: - cu.nodata = noDataP - Mapa[Mapa<0] = cu.nodata - else: - cu.nodata=noData - cu.dx=dx - cu.dy = dy - cu.xll=xll - cu.yll=yll - if dxp==None: - cu.dxp=30.0 - else: - cu.dxp=dxp - #Guarda la variable para el proyecto - global Global_EPSG - Global_EPSG = EPSG_code - # si es un dir se fija si es de r.watershed - if isDIR: - if DIRformat == 'r.watershed': - Mapa[Mapa<=0] = cu.nodata.astype(int) - Mapa = cu.dir_reclass_rwatershed(Mapa.T,cu.ncols,cu.nrows) - return Mapa, EPSG_code - if DIRformat == 'opentopo': - Mapa[Mapa<=0] = cu.nodata.astype(int) - Mapa = cu.dir_reclass_opentopo(Mapa.T,cu.ncols,cu.nrows) - return Mapa, EPSG_code - #retorna el mapa - return Mapa.T,EPSG_code - else: - return Mapa.T,[ncols,nrows,xll,yll,dx,dy,noData],EPSG_code + direction=gdal.Open(ruta_map) + #Proyecction + proj = osgeo.osr.SpatialReference(wkt=direction.GetProjection()) + EPSG_code = proj.GetAttrValue('AUTHORITY',1) + #lee la informacion del mapa + ncols=direction.RasterXSize + nrows=direction.RasterYSize + banda=direction.GetRasterBand(1) + noData=banda.GetNoDataValue() + geoT=direction.GetGeoTransform() + dx=geoT[1] + dy = np.abs(geoT[-1]) + xll=geoT[0]; yll=geoT[3]-nrows*dy + #lee el mapa + Mapa=direction.ReadAsArray() + direction.FlushCache() + del direction + if isDEMorDIR==True: + cu.ncols=ncols + cu.nrows=nrows + if noDataP is not None: + cu.nodata = noDataP + Mapa[Mapa<0] = cu.nodata + else: + cu.nodata=noData + cu.dx=dx + cu.dy = dy + cu.xll=xll + cu.yll=yll + if dxp==None: + cu.dxp=30.0 + else: + cu.dxp=dxp + #Guarda la variable para el proyecto + global Global_EPSG + Global_EPSG = EPSG_code + # si es un dir se fija si es de r.watershed + if isDIR: + if DIRformat == 'r.watershed': + Mapa[Mapa<=0] = cu.nodata.astype(int) + Mapa = cu.dir_reclass_rwatershed(Mapa.T,cu.ncols,cu.nrows) + return Mapa, EPSG_code + if DIRformat == 'opentopo': + Mapa[Mapa<=0] = cu.nodata.astype(int) + Mapa = cu.dir_reclass_opentopo(Mapa.T,cu.ncols,cu.nrows) + return Mapa, EPSG_code + #retorna el mapa + return Mapa.T,EPSG_code + else: + return Mapa.T,[ncols,nrows,xll,yll,dx,dy,noData],EPSG_code def read_map_points(ruta_map, ListAtr = None): - 'Funcion: read_map_points\n'\ - 'Descripcion: Lee un mapa vectorial de puntos soportado por GDAL.\n'\ - 'Parametros Obligatorios:.\n'\ - ' -ruta_map: Ruta donde se encuentra el mapa.\n'\ - 'Parametros Opcionales:.\n'\ - ' -ListAtr: Lista con los nombres de los atributos de las columnas\n'\ - ' que se quieren leer dentro de la variable Dict\n'\ - 'Retorno:.\n'\ - ' Si ListAtr == None: Retorna unicamente las coordenadas.\n'\ - ' Si ListAtr == [Nombre1, Nombre2, ...]: Retorna: Coord y diccionario con variables.\n'\ - #Obtiene el acceso - dr = osgeo.ogr.Open(ruta_map) - l = dr.GetLayer() - #Lee las coordenadas - Cord = [] - for i in range(l.GetFeatureCount()): - f = l.GetFeature(i) - g = f.GetGeometryRef() - pt = [g.GetX(),g.GetY()] - Cord.append(pt) - Cord = np.array(Cord).T - #Si hay atributos para buscar los lee y los m - if ListAtr is not None: - Dict = {} - for j in ListAtr: - #Busca si el atributo esta - pos = f.GetFieldIndex(j) - #Si esta lee la info del atributo - if pos is not -1: - vals = [] - for i in range(l.GetFeatureCount()): - f = l.GetFeature(i) - vals.append(f.GetField(pos)) - Dict.update({j:np.array(vals)}) - #Cierra el mapa - dr.Destroy() - return Cord, Dict - else: - #Cierra el mapa - dr.Destroy() - return Cord + 'Funcion: read_map_points\n'\ + 'Descripcion: Lee un mapa vectorial de puntos soportado por GDAL.\n'\ + 'Parametros Obligatorios:.\n'\ + ' -ruta_map: Ruta donde se encuentra el mapa.\n'\ + 'Parametros Opcionales:.\n'\ + ' -ListAtr: Lista con los nombres de los atributos de las columnas\n'\ + ' que se quieren leer dentro de la variable Dict\n'\ + 'Retorno:.\n'\ + ' Si ListAtr == None: Retorna unicamente las coordenadas.\n'\ + ' Si ListAtr == [Nombre1, Nombre2, ...]: Retorna: Coord y diccionario con variables.\n'\ + #Obtiene el acceso + dr = osgeo.ogr.Open(ruta_map) + l = dr.GetLayer() + #Lee las coordenadas + Cord = [] + for i in range(l.GetFeatureCount()): + f = l.GetFeature(i) + g = f.GetGeometryRef() + pt = [g.GetX(),g.GetY()] + Cord.append(pt) + Cord = np.array(Cord).T + #Si hay atributos para buscar los lee y los m + if ListAtr is not None: + Dict = {} + for j in ListAtr: + #Busca si el atributo esta + pos = f.GetFieldIndex(j) + #Si esta lee la info del atributo + if pos is not -1: + vals = [] + for i in range(l.GetFeatureCount()): + f = l.GetFeature(i) + vals.append(f.GetField(pos)) + Dict.update({j:np.array(vals)}) + #Cierra el mapa + dr.Destroy() + return Cord, Dict + else: + #Cierra el mapa + dr.Destroy() + return Cord def Save_Array2Raster(Array, ArrayProp, ruta, EPSG = 4326, Format = 'GTiff'): - dst_filename = ruta - #Formato de condiciones del mapa - x_pixels = Array.shape[0] # number of pixels in x - y_pixels = Array.shape[1] # number of pixels in y - PIXEL_SIZE = ArrayProp[4] # size of the pixel... - x_min = ArrayProp[2] - y_max = ArrayProp[3] + ArrayProp[4] * ArrayProp[1] # x_min & y_max are like the "top left" corner. - driver = gdal.GetDriverByName(Format) - #Para encontrar el formato de GDAL - NP2GDAL_CONVERSION = { - "uint8": 1, - "int8": 1, - "uint16": 2, - "int16": 3, - "uint32": 4, - "int32": 5, - "float32": 6, - "float64": 7, - "complex64": 10, - "complex128": 11, - } - gdaltype = NP2GDAL_CONVERSION[Array.dtype.name] - # Crea el driver - dataset = driver.Create( - dst_filename, - x_pixels, - y_pixels, - 1, - gdaltype,) - #coloca la referencia espacial - dataset.SetGeoTransform(( - x_min, # 0 - PIXEL_SIZE, # 1 - 0, # 2 - y_max, # 3 - 0, # 4 - -PIXEL_SIZE)) - #coloca la proyeccion a partir de un EPSG - proj = osgeo.osr.SpatialReference() - texto = 'EPSG:' + str(EPSG) - proj.SetWellKnownGeogCS( texto ) - dataset.SetProjection(proj.ExportToWkt()) - #Coloca el nodata - band = dataset.GetRasterBand(1) - if ArrayProp[-1] == None: - band.SetNoDataValue(wmf.cu.nodata.astype(int).max()) - else: - band.SetNoDataValue(-9999) - #Guarda el mapa - dataset.GetRasterBand(1).WriteArray(Array.T) - dataset.FlushCache() + dst_filename = ruta + #Formato de condiciones del mapa + x_pixels = Array.shape[0] # number of pixels in x + y_pixels = Array.shape[1] # number of pixels in y + PIXEL_SIZE = ArrayProp[4] # size of the pixel... + x_min = ArrayProp[2] + y_max = ArrayProp[3] + ArrayProp[4] * ArrayProp[1] # x_min & y_max are like the "top left" corner. + driver = gdal.GetDriverByName(Format) + #Para encontrar el formato de GDAL + NP2GDAL_CONVERSION = { + "uint8": 1, + "int8": 1, + "uint16": 2, + "int16": 3, + "uint32": 4, + "int32": 5, + "float32": 6, + "float64": 7, + "complex64": 10, + "complex128": 11, + } + gdaltype = NP2GDAL_CONVERSION[Array.dtype.name] + # Crea el driver + dataset = driver.Create( + dst_filename, + x_pixels, + y_pixels, + 1, + gdaltype,) + #coloca la referencia espacial + dataset.SetGeoTransform(( + x_min, # 0 + PIXEL_SIZE, # 1 + 0, # 2 + y_max, # 3 + 0, # 4 + -PIXEL_SIZE)) + #coloca la proyeccion a partir de un EPSG + proj = osgeo.osr.SpatialReference() + texto = 'EPSG:' + str(EPSG) + proj.SetWellKnownGeogCS( texto ) + dataset.SetProjection(proj.ExportToWkt()) + #Coloca el nodata + band = dataset.GetRasterBand(1) + if ArrayProp[-1] == None: + band.SetNoDataValue(wmf.cu.nodata.astype(int).max()) + else: + band.SetNoDataValue(-9999) + #Guarda el mapa + dataset.GetRasterBand(1).WriteArray(Array.T) + dataset.FlushCache() def Save_Points2Map(XY,ids,ruta,EPSG = 4326, Dict = None, - DriverFormat='ESRI Shapefile'): - 'Funcion: Save_Points2Map\n'\ - 'Descripcion: Guarda coordenadas X,Y en un mapa tipo puntos.\n'\ - 'Parametros Opcionales:.\n'\ - 'XY: Coordenadas de los puntos X,Y.\n'\ - 'ids: Numero que representa a cada punto.\n'\ - 'ruta: Ruta de escritura de los puntos.\n'\ - 'Opcionales:.\n'\ - 'EPSG : Codigo del tipo de proyeccion usada, defecto 4326 de WGS84.\n'\ - 'Dict : Diccionario con prop de los puntos, Defecto: None.\n'\ - 'DriverFormat : Formato del archivo vectorial, Defecto: ESRI Shapefile.\n'\ - 'Retorno:.\n'\ - ' Escribe el mapa en la ruta especificada.\n'\ - #Genera el shapefile - spatialReference = osgeo.osr.SpatialReference() - spatialReference.ImportFromEPSG(EPSG) - driver = osgeo.ogr.GetDriverByName(DriverFormat) - if os.path.exists(ruta): - driver.DeleteDataSource(ruta) - shapeData = driver.CreateDataSource(ruta) - layer = shapeData.CreateLayer('layer1', spatialReference, osgeo.ogr.wkbPoint) - layerDefinition = layer.GetLayerDefn() - new_field=osgeo.ogr.FieldDefn('Estacion',osgeo.ogr.OFTReal) - layer.CreateField(new_field) - if Dict is not None: - for p in Dict.keys(): - tipo = type(Dict[p][0]) - if tipo is np.float64: - new_field=osgeo.ogr.FieldDefn(p[:10],osgeo.ogr.OFTReal) - elif tipo is np.int64: - new_field=osgeo.ogr.FieldDefn(p[:10],osgeo.ogr.OFTInteger) - elif tipo is str: - new_field=osgeo.ogr.FieldDefn(p[:10],osgeo.ogr.OFTString) - layer.CreateField(new_field) - #Mete todos los puntos - featureIndex=0 - contador=0 + DriverFormat='ESRI Shapefile'): + 'Funcion: Save_Points2Map\n'\ + 'Descripcion: Guarda coordenadas X,Y en un mapa tipo puntos.\n'\ + 'Parametros Opcionales:.\n'\ + 'XY: Coordenadas de los puntos X,Y.\n'\ + 'ids: Numero que representa a cada punto.\n'\ + 'ruta: Ruta de escritura de los puntos.\n'\ + 'Opcionales:.\n'\ + 'EPSG : Codigo del tipo de proyeccion usada, defecto 4326 de WGS84.\n'\ + 'Dict : Diccionario con prop de los puntos, Defecto: None.\n'\ + 'DriverFormat : Formato del archivo vectorial, Defecto: ESRI Shapefile.\n'\ + 'Retorno:.\n'\ + ' Escribe el mapa en la ruta especificada.\n'\ + #Genera el shapefile + spatialReference = osgeo.osr.SpatialReference() + spatialReference.ImportFromEPSG(EPSG) + driver = osgeo.ogr.GetDriverByName(DriverFormat) + if os.path.exists(ruta): + driver.DeleteDataSource(ruta) + shapeData = driver.CreateDataSource(ruta) + layer = shapeData.CreateLayer('layer1', spatialReference, osgeo.ogr.wkbPoint) + layerDefinition = layer.GetLayerDefn() + new_field=osgeo.ogr.FieldDefn('Estacion',osgeo.ogr.OFTReal) + layer.CreateField(new_field) + if Dict is not None: + for p in Dict.keys(): + tipo = type(Dict[p][0]) + if tipo is np.float64: + new_field=osgeo.ogr.FieldDefn(p[:10],osgeo.ogr.OFTReal) + elif tipo is np.int64: + new_field=osgeo.ogr.FieldDefn(p[:10],osgeo.ogr.OFTInteger) + elif tipo is str: + new_field=osgeo.ogr.FieldDefn(p[:10],osgeo.ogr.OFTString) + layer.CreateField(new_field) + #Mete todos los puntos + featureIndex=0 + contador=0 #Calcula el tamano de la muestra - N=np.size(XY,axis=1) - if N>1: - for i in XY.T: - if i[0]<>-9999.0 and i[1]<>-9999.0: - #inserta el punto - point = osgeo.ogr.Geometry(osgeo.ogr.wkbPoint) - point.SetPoint(0, float(i[0]), float(i[1])) - feature = osgeo.ogr.Feature(layerDefinition) - feature.SetGeometry(point) - feature.SetFID(featureIndex) - feature.SetField('Estacion',ids[contador]) - #Le coloca lo del diccionario - if Dict is not None: - for p in Dict.keys(): - tipo = type(Dict[p][0]) - if tipo is np.float64: - feature.SetField(p[:10],float("%.2f" % Dict[p][contador])) - elif tipo is np.int64: - feature.SetField(p[:10],int("%d" % Dict[p][contador])) - elif tipo is str: - feature.SetField(p[:10],Dict[p][contador]) - #Actualiza contadores - contador+=1 - layer.CreateFeature(feature) - point.Destroy() - feature.Destroy() - else: - point = osgeo.ogr.Geometry(osgeo.ogr.wkbPoint) - point.SetPoint(0, float(XY[0,0]), float(XY[1,0])) - feature = osgeo.ogr.Feature(layerDefinition) - feature.SetGeometry(point) - feature.SetFID(featureIndex) - feature.SetField('Estacion',ids) - for p in Dict.keys(): - feature.SetField(p[:p.index('[')].strip()[:10],float("%.2f" % Param[p])) - contador+=1 - layer.CreateFeature(feature) - point.Destroy() - feature.Destroy() - shapeData.Destroy() + N=np.size(XY,axis=1) + if N>1: + for i in XY.T: + if i[0]<>-9999.0 and i[1]<>-9999.0: + #inserta el punto + point = osgeo.ogr.Geometry(osgeo.ogr.wkbPoint) + point.SetPoint(0, float(i[0]), float(i[1])) + feature = osgeo.ogr.Feature(layerDefinition) + feature.SetGeometry(point) + feature.SetFID(featureIndex) + feature.SetField('Estacion',ids[contador]) + #Le coloca lo del diccionario + if Dict is not None: + for p in Dict.keys(): + tipo = type(Dict[p][0]) + if tipo is np.float64: + feature.SetField(p[:10],float("%.2f" % Dict[p][contador])) + elif tipo is np.int64: + feature.SetField(p[:10],int("%d" % Dict[p][contador])) + elif tipo is str: + feature.SetField(p[:10],Dict[p][contador]) + #Actualiza contadores + contador+=1 + layer.CreateFeature(feature) + point.Destroy() + feature.Destroy() + else: + point = osgeo.ogr.Geometry(osgeo.ogr.wkbPoint) + point.SetPoint(0, float(XY[0,0]), float(XY[1,0])) + feature = osgeo.ogr.Feature(layerDefinition) + feature.SetGeometry(point) + feature.SetFID(featureIndex) + feature.SetField('Estacion',ids) + for p in Dict.keys(): + feature.SetField(p[:p.index('[')].strip()[:10],float("%.2f" % Param[p])) + contador+=1 + layer.CreateFeature(feature) + point.Destroy() + feature.Destroy() + shapeData.Destroy() def __ListaRadarNames__(ruta,FechaI,FechaF,fmt,exten,string,dt): - 'Funcion: OCG_param\n'\ - 'Descripcion: Obtiene una lista con los nombres para leer datos de radar.\n'\ - 'Parametros:.\n'\ - ' -FechaI, FechaF: Fechas inicial y final en formato datetime.\n'\ - ' -fmt : Formato en el que se pasa FechaI a texto, debe couincidir con.\n'\ - ' el del texto que se tenga en los archivos.\n'\ - ' -exten : Extension de los archivos .asc, .nc, .bin ...\n'\ - ' -string : texto antes de la fecha.\n'\ - ' -dt : Intervalos de tiempo entre los eventos.\n'\ - 'Retorno:.\n'\ - ' Lista : la lista de python con los nombres de los binarios.\n'\ - #Crea lista de fechas y mira que archivos estan en esas fechas - Dates=[FechaI]; date=FechaI - while datei: - Flag = True - c2 = c - c3 = 0 - while Flag: - if i= Y.size: Flag = False - else: - Flag=False - Pos.append(c2) - c+=1 - # Obtiene la segunda derivada de la corriente corregida - Y = pd.rolling_mean(Y,window) - l = Y[np.isnan(Y)].shape[0] - Y[:l]=Y[l+1] - slope = np.diff(Y,1) - slope = np.hstack([slope,slope[-1]]) - return Y,np.abs(slope) + # Obtiene la corriente quitando los puntos en donde se eleva + Pos = [] + Y = np.copy(X) + c = 1 + for i,j in zip(X[:-1],X[1:]): + if j>i: + Flag = True + c2 = c + c3 = 0 + while Flag: + if i= Y.size: Flag = False + else: + Flag=False + Pos.append(c2) + c+=1 + # Obtiene la segunda derivada de la corriente corregida + Y = pd.rolling_mean(Y,window) + l = Y[np.isnan(Y)].shape[0] + Y[:l]=Y[l+1] + slope = np.diff(Y,1) + slope = np.hstack([slope,slope[-1]]) + return Y,np.abs(slope) #----------------------------------------------------------------------- #Clase de cuencas #----------------------------------------------------------------------- class Basin: - - #------------------------------------------------------ - # Subrutinas de trazado de cuenca y obtencion de parametros - #------------------------------------------------------ - #Inicia la cuenca - def __init__(self,lat=0,lon=0,DEM=None,DIR=None,name='NaN',stream=None, - umbral=1000, ruta = None, useCauceMap = None): - 'Descripcion: Inicia la variable de la cuenca, y la traza \n'\ - ' obtiene las propiedades basicas de la cuenca. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'lat : Coordenada en X de la salida de la cuenca.\n'\ - 'lon : Coordenada en Y de la salida de la cuenca.\n'\ - 'name : Nombre con el que se va a conocer la cuenca.\n'\ - 'stream : Opcional, si se coloca, las coordenadas no tienen.\n'\ - ' que ser exactas, estas se van a corregir para ubicarse.\n'\ - ' en el punto mas cercano dentro de la corriente, este.\n'\ - ' debe ser un objeto del tipo stream.\n'\ - 'umbral : umbral minimo para la creacion de cauce (defecto =1000).\n'\ - 'ruta : Ruta donde se encuentra un archivo binario de la cuenca.\n'\ - 'useCauceMap : Si se asigna un mapa binario donde 1 es cauce y 0 es ladera.\n'\ - ' el trazador corregira las coordenadas para que estas lleguen a una celda.\n'\ - ' tipo cauce y se trace la cuenca de forma correcta (esta opcion deshabilita \n'\ - ' a stream)\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con las variables iniciadas.\n'\ - #Relaciona con el DEM y el DIR - self.DEM=DEM - self.DIR=DIR - #Si se da la opcion de que use el useCauceMap deshabilita stream - if useCauceMap is not None: - stream = None - #Si se entrega cauce corrige coordenadas - if ruta == None: - # Si se da el stream corrige por corriente - if stream is not None: - error=[] - for i in stream.structure.T: - error.append( np.sqrt((lat-i[0])**2+(lon-i[1])**2) ) - loc=np.argmin(error) - lat=stream.structure[0,loc] - lon=stream.structure[1,loc] - if useCauceMap is not None and useCauceMap.shape == DEM.shape: - lat,lon = cu.stream_find_to_corr(lat,lon,DEM,DIR,useCauceMap, - cu.ncols,cu.nrows) - #copia la direccion de los mapas de DEM y DIR, para no llamarlos mas - self.name=name - #Traza la cuenca - self.ncells = cu.basin_find(lat,lon,DIR, - cu.ncols,cu.nrows) - self.structure = cu.basin_cut(self.ncells) - self.umbral = umbral - else: - self.__Load_BasinNc(ruta) - #Genera el poligono de la cuenca - self.__GetBasinPolygon__() - #Cargador de cuenca - def __Load_BasinNc(self,ruta,Var2Search=None): - 'Descripcion: Lee una cuenca posteriormente guardada\n'\ - ' La cuenca debio ser guardada con Basin.Save_Basin2nc\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'ruta : ruta donde se encuentra ubicada la cuenca guardada\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : La cuenca con sus parametros ya cargada.\n'\ - #Abre el archivo binario de la cuenca - self.rutaNC = ruta - gr = netcdf.Dataset(ruta,'a') - #obtiene las prop de la cuenca - self.name = gr.nombre - self.ncells = gr.ncells - self.umbral = gr.umbral - #Obtiene las prop de los mapas - cu.ncols=gr.ncols - cu.nrows=gr.nrows - cu.nodata=gr.noData - cu.dx=gr.dx - cu.xll=gr.xll - cu.yll=gr.yll - cu.dxp=gr.dxp - #Obtiene las variables vectoriales - self.structure = gr.variables['structure'][:] - #Cierra el archivo - gr.close() + + #------------------------------------------------------ + # Subrutinas de trazado de cuenca y obtencion de parametros + #------------------------------------------------------ + #Inicia la cuenca + def __init__(self,lat=0,lon=0,DEM=None,DIR=None,name='NaN',stream=None, + umbral=1000, ruta = None, useCauceMap = None): + 'Descripcion: Inicia la variable de la cuenca, y la traza \n'\ + ' obtiene las propiedades basicas de la cuenca. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'lat : Coordenada en X de la salida de la cuenca.\n'\ + 'lon : Coordenada en Y de la salida de la cuenca.\n'\ + 'name : Nombre con el que se va a conocer la cuenca.\n'\ + 'stream : Opcional, si se coloca, las coordenadas no tienen.\n'\ + ' que ser exactas, estas se van a corregir para ubicarse.\n'\ + ' en el punto mas cercano dentro de la corriente, este.\n'\ + ' debe ser un objeto del tipo stream.\n'\ + 'umbral : umbral minimo para la creacion de cauce (defecto =1000).\n'\ + 'ruta : Ruta donde se encuentra un archivo binario de la cuenca.\n'\ + 'useCauceMap : Si se asigna un mapa binario donde 1 es cauce y 0 es ladera.\n'\ + ' el trazador corregira las coordenadas para que estas lleguen a una celda.\n'\ + ' tipo cauce y se trace la cuenca de forma correcta (esta opcion deshabilita \n'\ + ' a stream)\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas.\n'\ + #Relaciona con el DEM y el DIR + self.DEM=DEM + self.DIR=DIR + #Si se da la opcion de que use el useCauceMap deshabilita stream + if useCauceMap is not None: + stream = None + #Si se entrega cauce corrige coordenadas + if ruta == None: + # Si se da el stream corrige por corriente + if stream is not None: + error=[] + for i in stream.structure.T: + error.append( np.sqrt((lat-i[0])**2+(lon-i[1])**2) ) + loc=np.argmin(error) + lat=stream.structure[0,loc] + lon=stream.structure[1,loc] + if useCauceMap is not None and useCauceMap.shape == DEM.shape: + lat,lon = cu.stream_find_to_corr(lat,lon,DEM,DIR,useCauceMap, + cu.ncols,cu.nrows) + #copia la direccion de los mapas de DEM y DIR, para no llamarlos mas + self.name=name + #Traza la cuenca + self.ncells = cu.basin_find(lat,lon,DIR, + cu.ncols,cu.nrows) + self.structure = cu.basin_cut(self.ncells) + self.umbral = umbral + else: + self.__Load_BasinNc(ruta) + #Genera el poligono de la cuenca + self.__GetBasinPolygon__() + #Cargador de cuenca + def __Load_BasinNc(self,ruta,Var2Search=None): + 'Descripcion: Lee una cuenca posteriormente guardada\n'\ + ' La cuenca debio ser guardada con Basin.Save_Basin2nc\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'ruta : ruta donde se encuentra ubicada la cuenca guardada\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : La cuenca con sus parametros ya cargada.\n'\ + #Abre el archivo binario de la cuenca + self.rutaNC = ruta + gr = netcdf.Dataset(ruta,'a') + #obtiene las prop de la cuenca + self.name = gr.nombre + self.ncells = gr.ncells + self.umbral = gr.umbral + #Obtiene las prop de los mapas + cu.ncols=gr.ncols + cu.nrows=gr.nrows + cu.nodata=gr.noData + cu.dx=gr.dx + cu.xll=gr.xll + cu.yll=gr.yll + cu.dxp=gr.dxp + #Obtiene las variables vectoriales + self.structure = gr.variables['structure'][:] + #Cierra el archivo + gr.close() - def Load_BasinVar(self, varName): - 'Descripcion: Lee una variable especifica del netCDf de la cuenca\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'varName: nombre de la variable guardada\n'\ - 'Retornos\n'\ - '----------\n'\ - 'var : Retorna la variable como un numpy array.\n'\ - #Lectura del netCDf y lectura de variable - gr = netcdf.Dataset(self.rutaNC,'a') - Var = gr.variables[varName][:] - gr.close() - return Var - - #Guardado de de la cuenca en nc - def Save_Basin2nc(self,ruta,qmed=None,q233=None,q5=None, - ExtraVar=None): - 'Descripcion: guarda una cuenca previamente ejecutada\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'ruta : Ruta donde la cuenca sera guardada.\n'\ - 'qmed : Matriz con caudal medio estimado.\n'\ - 'q233 : Matriz con caudal minimo de 2.33.\n'\ - 'q5 : Matriz con caudal minimo de 5.\n'\ - 'ExtraVar: Diccionario con variables extras que se quieran guardar,.\n'\ - ' se guardan como flotantes.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con las variables iniciadas.\n'\ - #Diccionario con las propiedades - Dict = {'nombre':self.name, - 'noData':cu.nodata, - 'ncells':self.ncells, - 'umbral':self.umbral, - 'dxp':cu.dxp, - 'dx':cu.dx, - 'xll':cu.xll, - 'yll':cu.yll, - 'ncols':cu.ncols, - 'nrows':cu.nrows} - #abre el archivo - gr = netcdf.Dataset(ruta,'w',format='NETCDF4') - #Establece tamano de las variables - DimNcell = gr.createDimension('ncell',self.ncells) - DimCol3 = gr.createDimension('col3',3) - #Crea variables - VarStruc = gr.createVariable('structure','i4',('col3','ncell'),zlib=True) - VarQmed = gr.createVariable('q_med','f4',('ncell',),zlib=True) - VarQ233 = gr.createVariable('q_233','f4',('ncell',),zlib=True) - VarQ5 = gr.createVariable('q_5','f4',('ncell',),zlib=True) - #Variables opcionales - if type(ExtraVar) is dict: - for k in ExtraVar.keys(): - Var = gr.createVariable(k,'f4',('ncell',),zlib=True) - Var[:] = ExtraVar[k] - #Asigna valores a las variables - VarStruc[:] = self.structure - if qmed is not None: - VarQmed[:] = qmed - if q233 is not None: - VarQ233[:] = q233 - if q5 is not None: - VarQ5[:] = q5 - #asignlas prop a la cuenca - gr.setncatts(Dict) - #Cierra el archivo - gr.close() - #Sale del programa - return - #Parametros Geomorfologicos - def GetGeo_Parameters(self,rutaParamASC=None,plotTc=False, - rutaTcPlot = None, figsize=(8,5), GetPerim=True): - 'Descripcion: Obtiene los parametros geomorfologicos de la cuenca \n'\ - ' y los tiempos de concentracion calculados por diferentes metodologias. \n'\ - '\n'\ - 'Parametros\n'\ - ' rutaParamASC: ruta del ascii donde se escriben los param.\n'\ - ' plotTc: Plotea o no los tiempos de concentracion.\n'\ - ' rutaTcPlot: Si se da se guarda la figura de tiempos de concentracion.\n'\ - '----------\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'GeoParameters : Parametros de la cuenca calculados.\n'\ - 'Tc : Tiempo de concentracion calculado para la cuenca.\n'\ - #Calcula lo que se necesita para sacar los parametros - acum,longCeld,S0,Elev=cu.basin_basics(self.structure, - self.DEM,self.DIR,cu.ncols,cu.nrows,self.ncells) - slope=cu.basin_arc_slope(self.structure,self.DEM,self.ncells, - cu.ncols,cu.nrows) - Lpma,puntto=cu.basin_findlong(self.structure,self.ncells) - cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod(self.structure, - acum,self.umbral,self.ncells) - ppal_nceldas,punto = cu.basin_ppalstream_find(self.structure, - nodos,longCeld,Elev,self.ncells) - ppal = cu.basin_ppalstream_cut(ppal_nceldas,self.ncells) - self.hipso_main,self.hipso_basin=cu.basin_ppal_hipsometric( - self.structure,Elev,punto,30,ppal_nceldas,self.ncells) - self.main_stream=ppal - #Obtiene los parametros - Perim = self.Polygon.shape[1]*cu.dxp/1000. - Area=(self.ncells*cu.dxp**2)/1e6 - TotalCauces = self.CellCauce*self.CellLong - TotalCauces = TotalCauces.sum() / 1000. #[km] - Densidad = TotalCauces / Area #[km/km2] - Lcau=ppal[1,-1]/1000.0 - Scau=np.polyfit(ppal[1,::-1],ppal[0],1)[0]*100 - Scue=slope.mean()*100 - Hmin=Elev[-1]; Hmax=Elev[puntto]; Hmean=Elev.mean() - HCmax=Elev[punto] - x,y = cu.basin_coordxy(self.structure,self.ncells) - CentXY = [np.median(x),np.median(y)] - #Genera un diccionario con las propiedades de la cuenca - self.GeoParameters={'Area[km2]': Area, - 'Pend_Cauce [%]':Scau, - 'Long_Cau [km]': Lcau, - 'Pend_Cuenca [%]': Scue, - 'Long_Cuenca [km]': Lpma, - 'Hmax_[m]':Hmax, - 'Hmin_[m]':Hmin, - 'Hmean_[m]':Hmean, - 'H Cauce_Max [m]':HCmax, - 'Centro_[X]': CentXY[0], - 'Centro_[Y]': CentXY[1], + def Load_BasinVar(self, varName): + 'Descripcion: Lee una variable especifica del netCDf de la cuenca\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'varName: nombre de la variable guardada\n'\ + 'Retornos\n'\ + '----------\n'\ + 'var : Retorna la variable como un numpy array.\n'\ + #Lectura del netCDf y lectura de variable + gr = netcdf.Dataset(self.rutaNC,'a') + Var = gr.variables[varName][:] + gr.close() + return Var + + #Guardado de de la cuenca en nc + def Save_Basin2nc(self,ruta,qmed=None,q233=None,q5=None, + ExtraVar=None): + 'Descripcion: guarda una cuenca previamente ejecutada\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'ruta : Ruta donde la cuenca sera guardada.\n'\ + 'qmed : Matriz con caudal medio estimado.\n'\ + 'q233 : Matriz con caudal minimo de 2.33.\n'\ + 'q5 : Matriz con caudal minimo de 5.\n'\ + 'ExtraVar: Diccionario con variables extras que se quieran guardar,.\n'\ + ' se guardan como flotantes.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas.\n'\ + #Diccionario con las propiedades + Dict = {'nombre':self.name, + 'noData':cu.nodata, + 'ncells':self.ncells, + 'umbral':self.umbral, + 'dxp':cu.dxp, + 'dx':cu.dx, + 'xll':cu.xll, + 'yll':cu.yll, + 'ncols':cu.ncols, + 'nrows':cu.nrows} + #abre el archivo + gr = netcdf.Dataset(ruta,'w',format='NETCDF4') + #Establece tamano de las variables + DimNcell = gr.createDimension('ncell',self.ncells) + DimCol3 = gr.createDimension('col3',3) + #Crea variables + VarStruc = gr.createVariable('structure','i4',('col3','ncell'),zlib=True) + VarQmed = gr.createVariable('q_med','f4',('ncell',),zlib=True) + VarQ233 = gr.createVariable('q_233','f4',('ncell',),zlib=True) + VarQ5 = gr.createVariable('q_5','f4',('ncell',),zlib=True) + #Variables opcionales + if type(ExtraVar) is dict: + for k in ExtraVar.keys(): + Var = gr.createVariable(k,'f4',('ncell',),zlib=True) + Var[:] = ExtraVar[k] + #Asigna valores a las variables + VarStruc[:] = self.structure + if qmed is not None: + VarQmed[:] = qmed + if q233 is not None: + VarQ233[:] = q233 + if q5 is not None: + VarQ5[:] = q5 + #asignlas prop a la cuenca + gr.setncatts(Dict) + #Cierra el archivo + gr.close() + #Sale del programa + return + #Parametros Geomorfologicos + def GetGeo_Parameters(self,rutaParamASC=None,plotTc=False, + rutaTcPlot = None, figsize=(8,5), GetPerim=True): + 'Descripcion: Obtiene los parametros geomorfologicos de la cuenca \n'\ + ' y los tiempos de concentracion calculados por diferentes metodologias. \n'\ + '\n'\ + 'Parametros\n'\ + ' rutaParamASC: ruta del ascii donde se escriben los param.\n'\ + ' plotTc: Plotea o no los tiempos de concentracion.\n'\ + ' rutaTcPlot: Si se da se guarda la figura de tiempos de concentracion.\n'\ + '----------\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'GeoParameters : Parametros de la cuenca calculados.\n'\ + 'Tc : Tiempo de concentracion calculado para la cuenca.\n'\ + #Calcula lo que se necesita para sacar los parametros + acum,longCeld,S0,Elev=cu.basin_basics(self.structure, + self.DEM,self.DIR,cu.ncols,cu.nrows,self.ncells) + slope=cu.basin_arc_slope(self.structure,self.DEM,self.ncells, + cu.ncols,cu.nrows) + Lpma,puntto=cu.basin_findlong(self.structure,self.ncells) + cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod(self.structure, + acum,self.umbral,self.ncells) + ppal_nceldas,punto = cu.basin_ppalstream_find(self.structure, + nodos,longCeld,Elev,self.ncells) + ppal = cu.basin_ppalstream_cut(ppal_nceldas,self.ncells) + self.hipso_main,self.hipso_basin=cu.basin_ppal_hipsometric( + self.structure,Elev,punto,30,ppal_nceldas,self.ncells) + self.main_stream=ppal + #Obtiene los parametros + Perim = self.Polygon.shape[1]*cu.dxp/1000. + Area=(self.ncells*cu.dxp**2)/1e6 + TotalCauces = self.CellCauce*self.CellLong + TotalCauces = TotalCauces.sum() / 1000. #[km] + Densidad = TotalCauces / Area #[km/km2] + Lcau=ppal[1,-1]/1000.0 + Scau=np.polyfit(ppal[1,::-1],ppal[0],1)[0]*100 + Scue=slope.mean()*100 + Hmin=Elev[-1]; Hmax=Elev[puntto]; Hmean=Elev.mean() + HCmax=Elev[punto] + x,y = cu.basin_coordxy(self.structure,self.ncells) + CentXY = [np.median(x),np.median(y)] + #Genera un diccionario con las propiedades de la cuenca + self.GeoParameters={'Area[km2]': Area, + 'Pend_Cauce [%]':Scau, + 'Long_Cau [km]': Lcau, + 'Pend_Cuenca [%]': Scue, + 'Long_Cuenca [km]': Lpma, + 'Hmax_[m]':Hmax, + 'Hmin_[m]':Hmin, + 'Hmean_[m]':Hmean, + 'H Cauce_Max [m]':HCmax, + 'Centro_[X]': CentXY[0], + 'Centro_[Y]': CentXY[1], 'Long_tot_cauces[km]': TotalCauces, 'Densidad_drenaje[km/km2]': Densidad} - if GetPerim: - self.GeoParameters.update({'Perimetro[km]':Perim}) - #Calcula los tiempos de concentracion - Tiempos={} - Tc=0.3*(Lcau/(Scue**0.25))**0.75 - Tiempos.update({'US Army': Tc}) - Tc=0.3*(Lcau/((Hmax-Hmin)/Lcau)**0.25)**0.75 - Tiempos.update({'Direccion Carreteras Espana': Tc}) - Tc=(0.02*(Lpma*1000.0)**0.77)/((Scau/100.0)**0.385)/60.0 - Tiempos.update({'Kiprich': Tc}) - Tc=8.157*((Area**0.316)/(((Scau*100)**0.17)*Scue**0.565)) - Tiempos.update({'Campo y Munera': Tc}) - Tc=(4*np.sqrt(Area)+1.5*Lcau)/(0.8*np.sqrt(Hmean)) - Tiempos.update({'Giandotti':Tc}) - Tc=0.4623*(Lcau**0.5)*((Scue/100.0)**(-0.25)) - Tiempos.update({'John Stone': Tc}) - Tc=(Lcau/Area)*(np.sqrt(Area)/Scau) - Tiempos.update({'Ventura': Tc}) - Tc=0.3*(Lcau/(((HCmax-Hmin)/Lcau)*100)**0.25)**0.75 - Tiempos.update({'Temez': Tc}) - self.Tc=Tiempos - #Si se habilita la funcion para guardar el ascii de param lo hace - if rutaParamASC is not None: - self.__WriteGeoParam__(rutaParamASC) - # Grafica Tc si se habilita - if plotTc is True: - self.Plot_Tc(ruta = rutaTcPlot, figsize=figsize) - #Funcion para escribir los parametros de la cuenca en un ascii - def __WriteGeoParam__(self,ruta): - f=open(ruta,'w') - f.write('------------------------------------------------------------ \n') - f.write('Parametros Cuenca \n') - f.write('------------------------------------------------------------ \n') - k=self.GeoParameters.keys() - for i in k: - v=self.GeoParameters[i] - if type(v) is not list: - f.write('%s : %.4f \n' % (i,v)) - f.write('------------------------------------------------------------ \n') - f.write('Tiempos de concentracion \n') - f.write('------------------------------------------------------------ \n') - k=self.Tc.keys() - for i in k: - v=self.Tc[i] - f.write('%s : %.4f \n' % (i,v)) - f.close() + if GetPerim: + self.GeoParameters.update({'Perimetro[km]':Perim}) + #Calcula los tiempos de concentracion + Tiempos={} + Tc=0.3*(Lcau/(Scue**0.25))**0.75 + Tiempos.update({'US Army': Tc}) + Tc=0.3*(Lcau/((Hmax-Hmin)/Lcau)**0.25)**0.75 + Tiempos.update({'Direccion Carreteras Espana': Tc}) + Tc=(0.02*(Lpma*1000.0)**0.77)/((Scau/100.0)**0.385)/60.0 + Tiempos.update({'Kiprich': Tc}) + Tc=8.157*((Area**0.316)/(((Scau*100)**0.17)*Scue**0.565)) + Tiempos.update({'Campo y Munera': Tc}) + Tc=(4*np.sqrt(Area)+1.5*Lcau)/(0.8*np.sqrt(Hmean)) + Tiempos.update({'Giandotti':Tc}) + Tc=0.4623*(Lcau**0.5)*((Scue/100.0)**(-0.25)) + Tiempos.update({'John Stone': Tc}) + Tc=(Lcau/Area)*(np.sqrt(Area)/Scau) + Tiempos.update({'Ventura': Tc}) + Tc=0.3*(Lcau/(((HCmax-Hmin)/Lcau)*100)**0.25)**0.75 + Tiempos.update({'Temez': Tc}) + self.Tc=Tiempos + #Si se habilita la funcion para guardar el ascii de param lo hace + if rutaParamASC is not None: + self.__WriteGeoParam__(rutaParamASC) + # Grafica Tc si se habilita + if plotTc is True: + self.Plot_Tc(ruta = rutaTcPlot, figsize=figsize) + #Funcion para escribir los parametros de la cuenca en un ascii + def __WriteGeoParam__(self,ruta): + f=open(ruta,'w') + f.write('------------------------------------------------------------ \n') + f.write('Parametros Cuenca \n') + f.write('------------------------------------------------------------ \n') + k=self.GeoParameters.keys() + for i in k: + v=self.GeoParameters[i] + if type(v) is not list: + f.write('%s : %.4f \n' % (i,v)) + f.write('------------------------------------------------------------ \n') + f.write('Tiempos de concentracion \n') + f.write('------------------------------------------------------------ \n') + k=self.Tc.keys() + for i in k: + v=self.Tc[i] + f.write('%s : %.4f \n' % (i,v)) + f.close() - #Obtiene la envolvente de la cuenca - def __GetBasinPolygon__(self): + #Obtiene la envolvente de la cuenca + def __GetBasinPolygon__(self): 'Descripcion: obtiene la envolvente de la cuenca, en coordenadas \n'\ ' x,y, esta informacion luego sirve para plot y para escribir el\n'\ ' shpfile de la cuenca\n'\ @@ -1090,43 +1091,43 @@ def __GetBasinPolygon__(self): else: return 1 - #Parametros por mapas (distribuidos) - def GetGeo_Cell_Basics(self): - 'Descripcion: Obtiene: area acumulada, long de celdas, Pendiente \n'\ - ' y Elevacion en cada elemento de la cuenca. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : no necesita nada es autocontenido.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'CellAcum : Cantidad de celdas acumuladas.\n'\ - 'CellLong : Longitud de cada una de las celdas [mts].\n'\ - 'CellSlope : Pendiente de cada una de las celdas [y/x].\n'\ - 'CellHeight : Elevacion de cada una de las celdas [m.s.n.m].\n'\ - #obtiene los parametros basicos por celdas - acum,longCeld,S0,Elev=cu.basin_basics(self.structure, - self.DEMvec,self.DIRvec,self.ncells) - self.CellAcum=acum; self.CellLong=longCeld - self.CellSlope=S0; self.CellHeight=Elev - #Obtiene el canal en la cuenca - self.CellCauce = np.zeros(self.ncells) - self.CellCauce[self.CellAcum>self.umbral]=1 - def GetGeo_StreamOrder(self, MajorBasins = False, umbral = 100, verbose = False, FirtsOrder = 1): + #Parametros por mapas (distribuidos) + def GetGeo_Cell_Basics(self): + 'Descripcion: Obtiene: area acumulada, long de celdas, Pendiente \n'\ + ' y Elevacion en cada elemento de la cuenca. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'CellAcum : Cantidad de celdas acumuladas.\n'\ + 'CellLong : Longitud de cada una de las celdas [mts].\n'\ + 'CellSlope : Pendiente de cada una de las celdas [y/x].\n'\ + 'CellHeight : Elevacion de cada una de las celdas [m.s.n.m].\n'\ + #obtiene los parametros basicos por celdas + acum,longCeld,S0,Elev=cu.basin_basics(self.structure, + self.DEMvec,self.DIRvec,self.ncells) + self.CellAcum=acum; self.CellLong=longCeld + self.CellSlope=S0; self.CellHeight=Elev + #Obtiene el canal en la cuenca + self.CellCauce = np.zeros(self.ncells) + self.CellCauce[self.CellAcum>self.umbral]=1 + def GetGeo_StreamOrder(self, MajorBasins = False, umbral = 100, verbose = False, FirtsOrder = 1): 'Descripcion: Obtiene el orden de horton para cada celda de \n'\ - ' cada ladera y para las celdas de cada cauce.\n'\ + ' cada ladera y para las celdas de cada cauce.\n'\ '\n'\ 'Parametros\n'\ '----------\n'\ 'self : no necesita nada es autocontenido.\n'\ - 'MajorBasins : Obtiene binarios con las sub-cuencas drenando.\n'\ - ' unicamente a cuencas de orden mayor (ej: todas las orden 2 que \n'\ - ' drenan a orden 3 o major).\n'\ - 'umbral: Cantidad minima de celdas para considerar canal (aplica cuando\n'\ - ' se obtienen las sub-cuencas mayores.\n'\ - 'verbose: Muestra el paso de calculo de cuencas mayores.\n'\ - 'FirtsOrder: Primer orden a partir dle cual se analizan ordenes mayores.\n'\ + 'MajorBasins : Obtiene binarios con las sub-cuencas drenando.\n'\ + ' unicamente a cuencas de orden mayor (ej: todas las orden 2 que \n'\ + ' drenan a orden 3 o major).\n'\ + 'umbral: Cantidad minima de celdas para considerar canal (aplica cuando\n'\ + ' se obtienen las sub-cuencas mayores.\n'\ + 'verbose: Muestra el paso de calculo de cuencas mayores.\n'\ + 'FirtsOrder: Primer orden a partir dle cual se analizan ordenes mayores.\n'\ '\n'\ 'Retornos\n'\ '----------\n'\ @@ -1137,467 +1138,467 @@ def GetGeo_StreamOrder(self, MajorBasins = False, umbral = 100, verbose = False, sub_pert,sub_basin = cu.basin_subbasin_find(self.structure,nodos_fin,n_nodos,self.ncells) sub_basins = cu.basin_subbasin_cut(n_nodos) sub_horton,nod_horton = cu.basin_subbasin_horton(sub_basins,self.ncells,n_nodos) - self.CellHorton_Hill,sub_basin = cu.basin_subbasin_find(self.structure,nod_horton,n_nodos,self.ncells) - #Obtiene el canal en la cuenca + self.CellHorton_Hill,sub_basin = cu.basin_subbasin_find(self.structure,nod_horton,n_nodos,self.ncells) + #Obtiene el canal en la cuenca self.CellHorton_Stream = self.CellCauce * self.CellHorton_Hill - #Obtiene las cuencas mayores - if MajorBasins: - pos = np.where(models.control>0)[1] - X,Y = cu.basin_coordxy(self.structure, self.ncells) - DictBasins = {} - for Orden in range(FirtsOrder,self.CellHorton_Hill[-1]): - #Encuentra cuencas de un orden que drenen a un orden mayor - pos2 = np.where(self.CellHorton_Stream[pos] == Orden)[0] - drena = self.ncells - self.structure[0] - pos3 = np.where(self.CellHorton_Stream[drena[pos[pos2]]] > Orden)[0] - #Las ubica en un mapa dentro d ela cuenca - SubCuencas = np.zeros(self.ncells) - cont = 1 - for x,y in zip(X[pos[pos2[pos3]]], Y[pos[pos2[pos3]]]): - #Traza la cuenca - cuTemp = SimuBasin(x,y, self.DEM, self.DIR, umbral=umbral) - #La pega en una mascara con las cub-cuencas - Map, prop = cuTemp.Transform_Basin2Map(np.ones(cuTemp.ncells),) - Map[Map == -9999] = 0 - Var = self.Transform_Map2Basin(Map, prop) - Var[Var == 0] = -9999 - Var[Var == 1] = cont - ptemp = np.where(Var == cont)[0] - #Lo pega en la mascara de sub-uencas - SubCuencas[ptemp] = SubCuencas[ptemp] + Var[ptemp] - cont+=1 - #Agrega al diccionario - DictBasins.update({str(Orden):SubCuencas}) - #Si es verbose muestra en que paso va - if verbose: - print 'Sub-cuencas orden '+str(Orden)+' calculadas' - #Traza la cuenca original para no danar la estructura de guardado - cuTemp = SimuBasin(X[-1], Y[-1], self.DEM, self.DIR, umbral = umbral) - #Retorna el diccionario con las sub-cuencas mayore - return DictBasins - def GetGeo_IsoChrones(self,Tc,Niter=4): - 'Descripcion: Obtiene el tiempo de viaje aproximado de cada \n'\ - ' celda a la salida de la cuenca, para eso usa el tiempo de . \n'\ - ' concentracion obtenido por la funcion GetGeo_Parameters . \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - ' self : no necesita nada es autocontenido.\n'\ - ' Tc : Valor escalar de tiempo de concentracion.\n'\ - ' Niter: Cantidad de iteraciones para aproximar vel, defecto 4.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'isochrones : Mapa de viaje de cada celda a la salida [hrs].\n'\ - #Calcula la velocidad adecuada para que el tiempo coincida - acum,longCeld,S0,Elev=cu.basin_basics(self.structure, - self.DEM,self.DIR,cu.ncols,cu.nrows,self.ncells) - rangos=[50,25,1] - for i in range(Niter): - times=[] - for r in rangos: - speed = r*S0**(0.5) - time = cu.basin_time_to_out(self.structure, - longCeld,speed,self.ncells)/3600.0 - times.append(time[np.isfinite(time)].mean()) - for j in range(2): - if Tc>times[j] and Tc=i) & (time0], bins = binsN) - #Variables del elemento - self.width_hits = hn - self.width_distances = bn[:-1]/1000. - #Estandariza en terminos de probabilidad - hc = hc.astype(float); hc = hc / hc.sum() - hn = hn.astype(float); hn = hn / hn.sum() - #Grafica - fig = pl.figure(figsize=figsize) - ax = fig.add_subplot(111) - ax.plot(bc[:-1]/1000.0, hc, ccolor, lw = 3, label = 'Basin Width') - ax.plot(bn[:-1]/1000.0, hn, ncolor,lw = 3, label = 'Network Width') - ax.grid(True) - ax.set_xlabel('Distance to Outlet [$km$]', size = 16) - ax.set_ylabel('PDF', size = 16) - ax.fill_between(bc[:-1]/1000.0, hc, color = ccolor, alpha = 0.3) - ax.fill_between(bn[:-1]/1000.0, hn, color = ncolor, alpha = 0.3) - ax.set_ylim(0, np.max([hc.max(), hn.max()])+0.01) - ax.tick_params(labelsize = 15) - ax.legend(loc = 0) - ax2 = ax.twinx() - ax2.plot(bc[:-1]/1000.0, hc.cumsum(), ccolor, lw = 3, ls = '--', label = 'Basin Width') - ax2.plot(bn[:-1]/1000.0, hn.cumsum(), ncolor, lw = 3, ls = '--',label = 'Network Width') - ax2.tick_params(labelsize = 15) - ax2.set_ylabel('CDF', size = 16) - #Guarda la figura - if ruta is not None: - pl.savefig(ruta, bbox_inches='tight',pad_inches = 0.25) - if show: - pl.show() - #Retorna ejes de manipulacion - return ax,ax2 - - def GetGeo_Ppal_Hipsometric(self,umbral=1000, - intervals = 30): - 'Descripcion: Calcula y grafica la curva hipsometrica de\n'\ - ' la cuenca.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'umbral : cantidad minima de celdas para el trazado.\n'\ - 'intervals: Cantidad de intervalos en los cuales se haran .\n'\ - ' los muestreos de la curva hipsometrica.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Hipso : Curva hipsometrica en formato vectorial, contiene.\n'\ - ' - Curva sobre cauce ppal.\n'\ - ' - Curva como histograma de la cuenca.\n'\ - 'Figura: Figura de ambas curvas.\n'\ - # Obtiene los nodos de la red hidrica - cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( - self.structure, - self.CellAcum, - umbral, - self.ncells) - # Obtiene el cauce ppal - ppal_nceldas,punto = cu.basin_ppalstream_find( - self.structure, - nodos, - self.CellLong, - self.CellHeight, - self.ncells) - self.ppal_stream = cu.basin_ppalstream_cut(ppal_nceldas, - self.ncells) - #Corrige el perfil del cauce ppal - self.ppal_stream[0],self.ppal_slope = __ModifyElevErode__(self.ppal_stream[0]) - # Obtiene la curva hipsometrica - self.hipso_ppal, self.hipso_basin = cu.basin_ppal_hipsometric( - self.structure, - self.CellHeight, - punto, - intervals, - ppal_nceldas) - self.hipso_ppal[1],self.hipso_ppal_slope = __ModifyElevErode__(self.hipso_ppal[1]) - def GetGeo_IT(self): - 'Descripcion: Calcula el indice topografico para cada celda (Beven)\n'\ - ' Internamente calcula el area para cada elemento y la pendiente en radianes.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : no necesita nada es autocontenido.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'IT : Indice topografico adimensional, a mayor valor se supone un suelo mas humedo.\n'\ - #Obtiene el area - acum = cu.basin_acum(self.structure, self.ncells) - #Obtiene la pendiente en radianes - slope = cu.basin_arc_slope(self.structure,self.DEM, - self.ncells,cu.ncols,cu.nrows) - slope = np.arctan(slope) - slope[slope == 0] = 0.0001 - return np.log((acum*cu.dxp) / np.tan(slope)) - - def GetGeo_HAND(self,umbral=1000): - 'Descripcion: Calcula Height Above the Nearest Drainage (HAND) \n'\ - ' y Horizontal Distance to the Nearest Drainage (HDND) (Renno, 2008). \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : no necesita nada es autocontenido.\n'\ - 'umbral : cantidad minima de celdas para el trazado.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'HAND : Elevacion sobre la red de drenaje cercana [mts].\n'\ - 'HDND : Distancia horizontal a la red de drenaje cercana [mts].\n'\ - #obtiene los parametros basicos por celdas - acum,longCeld,S0,Elev=cu.basin_basics(self.structure, - self.DEM,self.DIR,cu.ncols,cu.nrows,self.ncells) - cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( - self.structure,acum,umbral,self.ncells) - hand,hdnd,hand_destiny = cu.geo_hand(self.structure,Elev,longCeld,cauce,self.ncells) - handC=np.zeros(self.ncells) - handC[hand<5.3]=1 - handC[(hand>=5.3) & (hand<=15.0)]=2 - handC[(hand>15.0) & (S0<0.076)]=4 - handC[(hand>15.0) & (S0>=0.076)]=3 - self.CellHAND=hand - self.CellHAND_class=handC - self.CellHDND=hdnd - self.CellHAND_drainCell=hand_destiny - - def GetGeo_Sections(self, NumCeldas = 6): - 'Descripcion: Obtiene secciones transversales a traves de todos.\n'\ - ' los elementos de la red de drenaje, las secciones se obtienen\n'\ - ' en la direccion perpendicular al flujo, es decir si el mapa de\n'\ - ' direcciones indica en una celda la direccion norte, las secciones\n'\ - ' se obtienen en lsa direcciones oriente, occidente, con NumCeldas\n'\ - ' a cada lado de la celda tipo cauce.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'NumCeldas: Cantidad de celdas para elaborar secciones a ambos lados.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self.Sections : Secciones a traves de los elementos del cauce.\n'\ - ' su tamano es [NumCeldas*2 + 1, self.ncells]\n'\ - #Obtiene mapa de cauces - self.GetGeo_Cell_Basics() - #Obtiene vector de direcciones - directions = self.Transform_Map2Basin(self.DIR, - [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy ,0.0]) - #Obtiene las secciones - self.Sections, self.Sections_Cells = cu.basin_stream_sections(self.structure, - self.CellCauce, directions, self.DEM, NumCeldas, - self.ncells, cu.ncols, cu.nrows) - - #------------------------------------------------------ - # Subrutinas para el calculo de extremos mediante hidrografa unitaria sintetica - #------------------------------------------------------ - def GetHU_Snyder(self,Area,Tc,Cp=0.8,Fc=2.9,pequena='si'): - 'Descripcion: Obtiene HU segun Snyder.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'Area: area de la cuenca en km2.\n'\ - 'Tc: Tiempo de concentracion en Horas.\n'\ - 'Cp : Factor de escalamiento [0.8].\n'\ - 'Fc : Factor de escalamiento [2.9].\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Tiempo : Tiempo total de duracion [M].\n'\ - 'Q : Caudal unitario.\n'\ - 'HU : Reglas del hidrograma unitario.\n'\ - #Calcula parametros para la hidrografa - Tr=0.6*Tc # [h] - T=0.1*Tc # [h] - Ts=Tr/5.5 # [h] - up=Cp*640/(Tr+(T-Ts)/4) #pie3/s/mi2/Pulg - Up=up*0.386*Area - Up=Up*(0.3048)**3.0/25.4 - Tp=T/2+Tr # horas - Tb=3+3*Tr/24 # dias - W50=770/up**1.08 - W75=440/up**1.08 - # Factor de multiplicacion - tb=Tp*Fc #horas - #obtiene las coordenadas del hidrograma - HU=[[0,0]] - At=(Tp-W50/3)*60; Aq=0.5*Up; HU.append([At,Aq]) - Bt=(Tp-W75/3)*60; Bq=0.75*Up; HU.append([Bt,Bq]) - Tpt=Tp*60; Tpq=Up; HU.append([Tpt,Tpq]) - Dt=(Tp+2*W75/3)*60; Dq=0.75*Up; HU.append([Dt,Dq]) - Et=(Tp+2*W50/3)*60; Eq=0.5*Up; HU.append([Et,Eq]) - if pequena=='si': - Tbt=tb*60 - else: - Tbt=Tb*60 - HU.append([Tbt,0]) - HU=np.array(HU).T - #Obtiene los intervalod de tiempo - Dt=Tc*0.1*60 #min - Tiempo=np.arange(0,Tbt+Dt,Dt) - #Obtiene la HU para los intervalos de tiempo necesarios - Q=np.zeros(Tiempo.size) - for cont,t in enumerate(Tiempo): - for h1,h2 in zip(HU.T[:-1],HU.T[1:]): - if t>h1[0] and tt1: - Q[cont]=HU[1,2]*np.exp((t1-t[1])/(3*k)) - if t[1]to: - Q[cont]=HU[1,1]*np.exp((to-t[1])/k) - return Tiempo*60,Q,HU - def GetHU_SCS(self,AreaCuenca,Tc,N=25): - 'Descripcion: Obtiene HU segun SCS.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'AreaCuenca: area de la cuenca en km2.\n'\ - 'Tc: Tiempo de concentracion en Horas.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Tiempo : Tiempo total de duracion [M].\n'\ - 'Q : Caudal unitario.\n'\ - 'HU : Reglas del hidrograma unitario.\n'\ - #Parametros fijos - ttp=np.array([0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1, - 1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0,2.2,2.4,2.6,2.8,3.0,3.2, - 3.4,3.6,3.8,4.0,4.5,5.0]) - UUp=np.array([0.0,0.03,0.1,0.19,0.31,0.47,0.66,0.82,0.93,0.99,1.0,0.99,0.93,0.86, - 0.78,0.68,0.56,0.46,0.39,0.33,0.28,0.21,0.15,0.11,0.08,0.06,0.04,0.03,0.02,0.02,0.01, - 0.01,0.0]) - #Parametros de la hidrografa - Trezago=(3.0/5.0)*float(Tc) - Tlluvia=0.133*Tc - Tpico=Tlluvia/2.0+Trezago - Upa=484.0*AreaCuenca*0.386/Tpico - Upm=Upa*0.3048**3/25.4 - #Obtiene el HU - HU=[] - for t,u in zip(ttp,UUp): - uTemp=u*Upa - HU.append([t*Tpico,uTemp*0.3048**3/25.4]) - HU=np.array(HU) - #Obtiene los intervalod de tiempo - Dt=Tc*0.1*60 #min - #Obtiene la HU para los intervalos de tiempo necesarios - Q=[]; flag=True - Tiempo=[];t=0.0 - for i in range(N): - for h1,h2 in zip(HU[:-1],HU[1:]): - if t>=h1[0] and t0: - L.append(((i-Ia)**2)/(i-Ia+S)) - else: - L.append(0) - lluviaTrTemp.append(L) - lluviaTrTemp=np.array(lluviaTrTemp) - lluviaTrEfect=lluviaTrTemp[:,1:]-lluviaTrTemp[:,:-1] - lluviaTrEfect[lluviaTrEfect<0]=0 - lluviaTrEfect=np.insert(lluviaTrEfect,0,lluviaTrTemp[:,0],axis=1) - if plot=='si': - #if Tr==None or len(Tr)<>IntTr.size(): - # Lista=[2.33,5,10,25,50,100,500,1000] - # Tr=[l for l in Lista[:IntTr.size]] + #Obtiene las cuencas mayores + if MajorBasins: + pos = np.where(models.control>0)[1] + X,Y = cu.basin_coordxy(self.structure, self.ncells) + DictBasins = {} + for Orden in range(FirtsOrder,self.CellHorton_Hill[-1]): + #Encuentra cuencas de un orden que drenen a un orden mayor + pos2 = np.where(self.CellHorton_Stream[pos] == Orden)[0] + drena = self.ncells - self.structure[0] + pos3 = np.where(self.CellHorton_Stream[drena[pos[pos2]]] > Orden)[0] + #Las ubica en un mapa dentro d ela cuenca + SubCuencas = np.zeros(self.ncells) + cont = 1 + for x,y in zip(X[pos[pos2[pos3]]], Y[pos[pos2[pos3]]]): + #Traza la cuenca + cuTemp = SimuBasin(x,y, self.DEM, self.DIR, umbral=umbral) + #La pega en una mascara con las cub-cuencas + Map, prop = cuTemp.Transform_Basin2Map(np.ones(cuTemp.ncells),) + Map[Map == -9999] = 0 + Var = self.Transform_Map2Basin(Map, prop) + Var[Var == 0] = -9999 + Var[Var == 1] = cont + ptemp = np.where(Var == cont)[0] + #Lo pega en la mascara de sub-uencas + SubCuencas[ptemp] = SubCuencas[ptemp] + Var[ptemp] + cont+=1 + #Agrega al diccionario + DictBasins.update({str(Orden):SubCuencas}) + #Si es verbose muestra en que paso va + if verbose: + print 'Sub-cuencas orden '+str(Orden)+' calculadas' + #Traza la cuenca original para no danar la estructura de guardado + cuTemp = SimuBasin(X[-1], Y[-1], self.DEM, self.DIR, umbral = umbral) + #Retorna el diccionario con las sub-cuencas mayore + return DictBasins + def GetGeo_IsoChrones(self,Tc,Niter=4): + 'Descripcion: Obtiene el tiempo de viaje aproximado de cada \n'\ + ' celda a la salida de la cuenca, para eso usa el tiempo de . \n'\ + ' concentracion obtenido por la funcion GetGeo_Parameters . \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + ' self : no necesita nada es autocontenido.\n'\ + ' Tc : Valor escalar de tiempo de concentracion.\n'\ + ' Niter: Cantidad de iteraciones para aproximar vel, defecto 4.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'isochrones : Mapa de viaje de cada celda a la salida [hrs].\n'\ + #Calcula la velocidad adecuada para que el tiempo coincida + acum,longCeld,S0,Elev=cu.basin_basics(self.structure, + self.DEM,self.DIR,cu.ncols,cu.nrows,self.ncells) + rangos=[50,25,1] + for i in range(Niter): + times=[] + for r in rangos: + speed = r*S0**(0.5) + time = cu.basin_time_to_out(self.structure, + longCeld,speed,self.ncells)/3600.0 + times.append(time[np.isfinite(time)].mean()) + for j in range(2): + if Tc>times[j] and Tc=i) & (time0], bins = binsN) + #Variables del elemento + self.width_hits = hn + self.width_distances = bn[:-1]/1000. + #Estandariza en terminos de probabilidad + hc = hc.astype(float); hc = hc / hc.sum() + hn = hn.astype(float); hn = hn / hn.sum() + #Grafica + fig = pl.figure(figsize=figsize) + ax = fig.add_subplot(111) + ax.plot(bc[:-1]/1000.0, hc, ccolor, lw = 3, label = 'Basin Width') + ax.plot(bn[:-1]/1000.0, hn, ncolor,lw = 3, label = 'Network Width') + ax.grid(True) + ax.set_xlabel('Distance to Outlet [$km$]', size = 16) + ax.set_ylabel('PDF', size = 16) + ax.fill_between(bc[:-1]/1000.0, hc, color = ccolor, alpha = 0.3) + ax.fill_between(bn[:-1]/1000.0, hn, color = ncolor, alpha = 0.3) + ax.set_ylim(0, np.max([hc.max(), hn.max()])+0.01) + ax.tick_params(labelsize = 15) + ax.legend(loc = 0) + ax2 = ax.twinx() + ax2.plot(bc[:-1]/1000.0, hc.cumsum(), ccolor, lw = 3, ls = '--', label = 'Basin Width') + ax2.plot(bn[:-1]/1000.0, hn.cumsum(), ncolor, lw = 3, ls = '--',label = 'Network Width') + ax2.tick_params(labelsize = 15) + ax2.set_ylabel('CDF', size = 16) + #Guarda la figura + if ruta is not None: + pl.savefig(ruta, bbox_inches='tight',pad_inches = 0.25) + if show: + pl.show() + #Retorna ejes de manipulacion + return ax,ax2 + + def GetGeo_Ppal_Hipsometric(self,umbral=1000, + intervals = 30): + 'Descripcion: Calcula y grafica la curva hipsometrica de\n'\ + ' la cuenca.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'umbral : cantidad minima de celdas para el trazado.\n'\ + 'intervals: Cantidad de intervalos en los cuales se haran .\n'\ + ' los muestreos de la curva hipsometrica.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Hipso : Curva hipsometrica en formato vectorial, contiene.\n'\ + ' - Curva sobre cauce ppal.\n'\ + ' - Curva como histograma de la cuenca.\n'\ + 'Figura: Figura de ambas curvas.\n'\ + # Obtiene los nodos de la red hidrica + cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( + self.structure, + self.CellAcum, + umbral, + self.ncells) + # Obtiene el cauce ppal + ppal_nceldas,punto = cu.basin_ppalstream_find( + self.structure, + nodos, + self.CellLong, + self.CellHeight, + self.ncells) + self.ppal_stream = cu.basin_ppalstream_cut(ppal_nceldas, + self.ncells) + #Corrige el perfil del cauce ppal + self.ppal_stream[0],self.ppal_slope = __ModifyElevErode__(self.ppal_stream[0]) + # Obtiene la curva hipsometrica + self.hipso_ppal, self.hipso_basin = cu.basin_ppal_hipsometric( + self.structure, + self.CellHeight, + punto, + intervals, + ppal_nceldas) + self.hipso_ppal[1],self.hipso_ppal_slope = __ModifyElevErode__(self.hipso_ppal[1]) + def GetGeo_IT(self): + 'Descripcion: Calcula el indice topografico para cada celda (Beven)\n'\ + ' Internamente calcula el area para cada elemento y la pendiente en radianes.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'IT : Indice topografico adimensional, a mayor valor se supone un suelo mas humedo.\n'\ + #Obtiene el area + acum = cu.basin_acum(self.structure, self.ncells) + #Obtiene la pendiente en radianes + slope = cu.basin_arc_slope(self.structure,self.DEM, + self.ncells,cu.ncols,cu.nrows) + slope = np.arctan(slope) + slope[slope == 0] = 0.0001 + return np.log((acum*cu.dxp) / np.tan(slope)) + + def GetGeo_HAND(self,umbral=1000): + 'Descripcion: Calcula Height Above the Nearest Drainage (HAND) \n'\ + ' y Horizontal Distance to the Nearest Drainage (HDND) (Renno, 2008). \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + 'umbral : cantidad minima de celdas para el trazado.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'HAND : Elevacion sobre la red de drenaje cercana [mts].\n'\ + 'HDND : Distancia horizontal a la red de drenaje cercana [mts].\n'\ + #obtiene los parametros basicos por celdas + acum,longCeld,S0,Elev=cu.basin_basics(self.structure, + self.DEM,self.DIR,cu.ncols,cu.nrows,self.ncells) + cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( + self.structure,acum,umbral,self.ncells) + hand,hdnd,hand_destiny = cu.geo_hand(self.structure,Elev,longCeld,cauce,self.ncells) + handC=np.zeros(self.ncells) + handC[hand<5.3]=1 + handC[(hand>=5.3) & (hand<=15.0)]=2 + handC[(hand>15.0) & (S0<0.076)]=4 + handC[(hand>15.0) & (S0>=0.076)]=3 + self.CellHAND=hand + self.CellHAND_class=handC + self.CellHDND=hdnd + self.CellHAND_drainCell=hand_destiny + + def GetGeo_Sections(self, NumCeldas = 6): + 'Descripcion: Obtiene secciones transversales a traves de todos.\n'\ + ' los elementos de la red de drenaje, las secciones se obtienen\n'\ + ' en la direccion perpendicular al flujo, es decir si el mapa de\n'\ + ' direcciones indica en una celda la direccion norte, las secciones\n'\ + ' se obtienen en lsa direcciones oriente, occidente, con NumCeldas\n'\ + ' a cada lado de la celda tipo cauce.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'NumCeldas: Cantidad de celdas para elaborar secciones a ambos lados.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self.Sections : Secciones a traves de los elementos del cauce.\n'\ + ' su tamano es [NumCeldas*2 + 1, self.ncells]\n'\ + #Obtiene mapa de cauces + self.GetGeo_Cell_Basics() + #Obtiene vector de direcciones + directions = self.Transform_Map2Basin(self.DIR, + [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy ,0.0]) + #Obtiene las secciones + self.Sections, self.Sections_Cells = cu.basin_stream_sections(self.structure, + self.CellCauce, directions, self.DEM, NumCeldas, + self.ncells, cu.ncols, cu.nrows) + + #------------------------------------------------------ + # Subrutinas para el calculo de extremos mediante hidrografa unitaria sintetica + #------------------------------------------------------ + def GetHU_Snyder(self,Area,Tc,Cp=0.8,Fc=2.9,pequena='si'): + 'Descripcion: Obtiene HU segun Snyder.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'Area: area de la cuenca en km2.\n'\ + 'Tc: Tiempo de concentracion en Horas.\n'\ + 'Cp : Factor de escalamiento [0.8].\n'\ + 'Fc : Factor de escalamiento [2.9].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Tiempo : Tiempo total de duracion [M].\n'\ + 'Q : Caudal unitario.\n'\ + 'HU : Reglas del hidrograma unitario.\n'\ + #Calcula parametros para la hidrografa + Tr=0.6*Tc # [h] + T=0.1*Tc # [h] + Ts=Tr/5.5 # [h] + up=Cp*640/(Tr+(T-Ts)/4) #pie3/s/mi2/Pulg + Up=up*0.386*Area + Up=Up*(0.3048)**3.0/25.4 + Tp=T/2+Tr # horas + Tb=3+3*Tr/24 # dias + W50=770/up**1.08 + W75=440/up**1.08 + # Factor de multiplicacion + tb=Tp*Fc #horas + #obtiene las coordenadas del hidrograma + HU=[[0,0]] + At=(Tp-W50/3)*60; Aq=0.5*Up; HU.append([At,Aq]) + Bt=(Tp-W75/3)*60; Bq=0.75*Up; HU.append([Bt,Bq]) + Tpt=Tp*60; Tpq=Up; HU.append([Tpt,Tpq]) + Dt=(Tp+2*W75/3)*60; Dq=0.75*Up; HU.append([Dt,Dq]) + Et=(Tp+2*W50/3)*60; Eq=0.5*Up; HU.append([Et,Eq]) + if pequena=='si': + Tbt=tb*60 + else: + Tbt=Tb*60 + HU.append([Tbt,0]) + HU=np.array(HU).T + #Obtiene los intervalod de tiempo + Dt=Tc*0.1*60 #min + Tiempo=np.arange(0,Tbt+Dt,Dt) + #Obtiene la HU para los intervalos de tiempo necesarios + Q=np.zeros(Tiempo.size) + for cont,t in enumerate(Tiempo): + for h1,h2 in zip(HU.T[:-1],HU.T[1:]): + if t>h1[0] and tt1: + Q[cont]=HU[1,2]*np.exp((t1-t[1])/(3*k)) + if t[1]to: + Q[cont]=HU[1,1]*np.exp((to-t[1])/k) + return Tiempo*60,Q,HU + def GetHU_SCS(self,AreaCuenca,Tc,N=25): + 'Descripcion: Obtiene HU segun SCS.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'AreaCuenca: area de la cuenca en km2.\n'\ + 'Tc: Tiempo de concentracion en Horas.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Tiempo : Tiempo total de duracion [M].\n'\ + 'Q : Caudal unitario.\n'\ + 'HU : Reglas del hidrograma unitario.\n'\ + #Parametros fijos + ttp=np.array([0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1, + 1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0,2.2,2.4,2.6,2.8,3.0,3.2, + 3.4,3.6,3.8,4.0,4.5,5.0]) + UUp=np.array([0.0,0.03,0.1,0.19,0.31,0.47,0.66,0.82,0.93,0.99,1.0,0.99,0.93,0.86, + 0.78,0.68,0.56,0.46,0.39,0.33,0.28,0.21,0.15,0.11,0.08,0.06,0.04,0.03,0.02,0.02,0.01, + 0.01,0.0]) + #Parametros de la hidrografa + Trezago=(3.0/5.0)*float(Tc) + Tlluvia=0.133*Tc + Tpico=Tlluvia/2.0+Trezago + Upa=484.0*AreaCuenca*0.386/Tpico + Upm=Upa*0.3048**3/25.4 + #Obtiene el HU + HU=[] + for t,u in zip(ttp,UUp): + uTemp=u*Upa + HU.append([t*Tpico,uTemp*0.3048**3/25.4]) + HU=np.array(HU) + #Obtiene los intervalod de tiempo + Dt=Tc*0.1*60 #min + #Obtiene la HU para los intervalos de tiempo necesarios + Q=[]; flag=True + Tiempo=[];t=0.0 + for i in range(N): + for h1,h2 in zip(HU[:-1],HU[1:]): + if t>=h1[0] and t0: + L.append(((i-Ia)**2)/(i-Ia+S)) + else: + L.append(0) + lluviaTrTemp.append(L) + lluviaTrTemp=np.array(lluviaTrTemp) + lluviaTrEfect=lluviaTrTemp[:,1:]-lluviaTrTemp[:,:-1] + lluviaTrEfect[lluviaTrEfect<0]=0 + lluviaTrEfect=np.insert(lluviaTrEfect,0,lluviaTrTemp[:,0],axis=1) + if plot=='si': + #if Tr==None or len(Tr)<>IntTr.size(): + # Lista=[2.33,5,10,25,50,100,500,1000] + # Tr=[l for l in Lista[:IntTr.size]] fig=pl.figure(edgecolor='w',facecolor='w') ax=fig.add_subplot(111) X=np.linspace(0,Dur,lluviaTrEfect.shape[1]) @@ -1605,170 +1606,170 @@ def GetHU_DesingStorm(self,IntTr,Dur,CN=70,plot='no',ruta=None,Tr=None, for l,le,t,g in zip(lluviaTr,lluviaTrEfect,Tr,Grosor): ax.plot(X,l,c='b',lw=g,label=str(t)) if CN is not None: - for l,le,t,g in zip(lluviaTr,lluviaTrEfect,Tr,Grosor): - ax.plot(X,le,c='r',lw=g,label=str(t)) + for l,le,t,g in zip(lluviaTr,lluviaTrEfect,Tr,Grosor): + ax.plot(X,le,c='r',lw=g,label=str(t)) ax.set_xlabel('Tiempo $[h]$',size=16) ax.set_ylabel('Precipitacion $[mm]$',size=16) ax.grid(True) - ax.tick_params(labelsize=15) + ax.tick_params(labelsize=15) pl.legend(loc=0,ncol=2) if ruta is not None: pl.savefig(ruta,bbox_inches='tight') pl.show() - if CN is not None: - return lluviaTr,np.array(lluviaTrEfect),S - else: - return lluviaTr - #Convolucion de la tormenta de diseno - def GetHU_Convolution(self,Tiempo,Qhu,lluvEfect): - 'Descripcion: Realia la convolucion de los hidrogramas unitarios \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'Tiempo : Vector de la duracion de la hidrografa unitaria [Nt].\n'\ - 'Qhu : Valores del caudal unitario de la hidrografa unitaria [Nt].\n'\ - 'lluvEfect : Lluvia efectiva en un evento de tormenta cualquiera [Nt, Tr].\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Qtr : Hidrografa para cada periodo de retorno [M, Tr].\n'\ - 'QmaxTr : Caudal maximo para cada periodo de retorno [Tr].\n'\ - 'Tiempo : Tiempo total de duracion [M].\n'\ - #Calcula el caudal convulucionado - Qtr=[]; QmaxTr=[] - for le in lluvEfect: - Qi=np.array([i*Qhu for i in le]) - Qconv=np.zeros(Qhu.size+lluvEfect.shape[1]-1) - for cont,q in enumerate(Qi): - Qconv[cont:cont+Qhu.size]=Qconv[cont:cont+Qhu.size]+q - Qtr.append(Qconv) - QmaxTr.append(Qconv.max()) - #Calcula el tiempo para toda la hidrografa - Dt=Tiempo[1]-Tiempo[0]; Tlast=Tiempo[-1] - T=list(Tiempo) - for i in range(1,lluvEfect.shape[1]): - T.append(Tlast+i*Dt) - return np.array(Qtr), np.array(QmaxTr),np.array(T) - #Grafica los hidrogramas sinteticos - def PlotHU_Synthetic(self,DictHU,ruta = None): - fig=pl.figure(edgecolor='w',facecolor='w') - ax=fig.add_subplot(111) - colors = ['b','r','k','g','m'] - for co,k in enumerate(DictHU.keys()): - ax.plot(DictHU[k]['time'], - DictHU[k]['HU'], - c=colors[co],lw=1.5,label=k) - ax.grid(True) - ax.set_xlabel('Tiempo $[min]$',size=14) - ax.set_ylabel('HU $[m^3/seg/mm]$',size=14) - ax.legend(loc=0) - if ruta is not None: - pl.savefig(ruta,bbox_inches='tight') - pl.show() - - #------------------------------------------------------ - # Trabajo con mapas externos y variables fisicas - #------------------------------------------------------ - def Transform_Map2Basin(self,Map,MapProp): - 'Descripcion: A partir de un mapa leido obtiene un vector \n'\ - ' con la forma de la cuenca, el cual luego puede ser agregado a esta. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'Map : Matriz con la informacion del mapa.\n'\ - 'MapProp : Propiedades del mapa.\n'\ - ' 1. Ncols Mapa.\n'\ - ' 2. Nrows Mapa.\n'\ - ' 3. Xll Mapa.\n'\ - ' 4. Yll Mapa.\n'\ - ' 5. dx Mapa.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'vecMap : Vector conla informacion del mapa al interio de la cuenca.\n'\ - #Comienza le codifgo - vec = cu.basin_map2basin(self.structure, - Map,MapProp[2],MapProp[3],MapProp[4],MapProp[5], - cu.nodata, - self.ncells, - MapProp[0],MapProp[1]) - return vec - def Transform_Basin2Map(self, BasinVar, ruta = None, DriverFormat='GTiff', - EPSG=4326): - 'Descripcion: A partir de un vector con propiedades de la cuenca en celdas\n'\ - ' obtiene un mapa (matriz) con las propiedades del DEM, este puede ser escrito \n'\ - ' en algun formato legible por GDAL. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : la cuenca misma.\n'\ - 'BasinVar : Vector con la variable de la cuenca a escribir [ncells].\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Map : Matriz con la variable de la cuenca, donde no hay cuenca es wmf.cu.nodata .\n'\ - ' el tamano de la matriz es igual a DEM.shape.\n'\ - # Convierte la variable a mapa - map_ncols,map_nrows = cu.basin_2map_find(self.structure,self.ncells) - M,mxll,myll = cu.basin_2map(self.structure, BasinVar, - map_ncols, map_nrows, self.ncells) - # Si exporta el mapa lo guarda si no simplemente devuelve la matriz - if ruta is not None: - Save_Array2Raster(M, [map_ncols,map_nrows,mxll,myll,cu.dx,cu.nodata], - ruta = ruta, EPSG = EPSG, Format = DriverFormat) - return M, [map_ncols,map_nrows,mxll,myll,cu.dx,cu.dy,cu.nodata] + if CN is not None: + return lluviaTr,np.array(lluviaTrEfect),S + else: + return lluviaTr + #Convolucion de la tormenta de diseno + def GetHU_Convolution(self,Tiempo,Qhu,lluvEfect): + 'Descripcion: Realia la convolucion de los hidrogramas unitarios \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'Tiempo : Vector de la duracion de la hidrografa unitaria [Nt].\n'\ + 'Qhu : Valores del caudal unitario de la hidrografa unitaria [Nt].\n'\ + 'lluvEfect : Lluvia efectiva en un evento de tormenta cualquiera [Nt, Tr].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Qtr : Hidrografa para cada periodo de retorno [M, Tr].\n'\ + 'QmaxTr : Caudal maximo para cada periodo de retorno [Tr].\n'\ + 'Tiempo : Tiempo total de duracion [M].\n'\ + #Calcula el caudal convulucionado + Qtr=[]; QmaxTr=[] + for le in lluvEfect: + Qi=np.array([i*Qhu for i in le]) + Qconv=np.zeros(Qhu.size+lluvEfect.shape[1]-1) + for cont,q in enumerate(Qi): + Qconv[cont:cont+Qhu.size]=Qconv[cont:cont+Qhu.size]+q + Qtr.append(Qconv) + QmaxTr.append(Qconv.max()) + #Calcula el tiempo para toda la hidrografa + Dt=Tiempo[1]-Tiempo[0]; Tlast=Tiempo[-1] + T=list(Tiempo) + for i in range(1,lluvEfect.shape[1]): + T.append(Tlast+i*Dt) + return np.array(Qtr), np.array(QmaxTr),np.array(T) + #Grafica los hidrogramas sinteticos + def PlotHU_Synthetic(self,DictHU,ruta = None): + fig=pl.figure(edgecolor='w',facecolor='w') + ax=fig.add_subplot(111) + colors = ['b','r','k','g','m'] + for co,k in enumerate(DictHU.keys()): + ax.plot(DictHU[k]['time'], + DictHU[k]['HU'], + c=colors[co],lw=1.5,label=k) + ax.grid(True) + ax.set_xlabel('Tiempo $[min]$',size=14) + ax.set_ylabel('HU $[m^3/seg/mm]$',size=14) + ax.legend(loc=0) + if ruta is not None: + pl.savefig(ruta,bbox_inches='tight') + pl.show() + + #------------------------------------------------------ + # Trabajo con mapas externos y variables fisicas + #------------------------------------------------------ + def Transform_Map2Basin(self,Map,MapProp): + 'Descripcion: A partir de un mapa leido obtiene un vector \n'\ + ' con la forma de la cuenca, el cual luego puede ser agregado a esta. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'Map : Matriz con la informacion del mapa.\n'\ + 'MapProp : Propiedades del mapa.\n'\ + ' 1. Ncols Mapa.\n'\ + ' 2. Nrows Mapa.\n'\ + ' 3. Xll Mapa.\n'\ + ' 4. Yll Mapa.\n'\ + ' 5. dx Mapa.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'vecMap : Vector conla informacion del mapa al interio de la cuenca.\n'\ + #Comienza le codifgo + vec = cu.basin_map2basin(self.structure, + Map,MapProp[2],MapProp[3],MapProp[4],MapProp[5], + cu.nodata, + self.ncells, + MapProp[0],MapProp[1]) + return vec + def Transform_Basin2Map(self, BasinVar, ruta = None, DriverFormat='GTiff', + EPSG=4326): + 'Descripcion: A partir de un vector con propiedades de la cuenca en celdas\n'\ + ' obtiene un mapa (matriz) con las propiedades del DEM, este puede ser escrito \n'\ + ' en algun formato legible por GDAL. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : la cuenca misma.\n'\ + 'BasinVar : Vector con la variable de la cuenca a escribir [ncells].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Map : Matriz con la variable de la cuenca, donde no hay cuenca es wmf.cu.nodata .\n'\ + ' el tamano de la matriz es igual a DEM.shape.\n'\ + # Convierte la variable a mapa + map_ncols,map_nrows = cu.basin_2map_find(self.structure,self.ncells) + M,mxll,myll = cu.basin_2map(self.structure, BasinVar, + map_ncols, map_nrows, self.ncells) + # Si exporta el mapa lo guarda si no simplemente devuelve la matriz + if ruta is not None: + Save_Array2Raster(M, [map_ncols,map_nrows,mxll,myll,cu.dx,cu.nodata], + ruta = ruta, EPSG = EPSG, Format = DriverFormat) + return M, [map_ncols,map_nrows,mxll,myll,cu.dx,cu.dy,cu.nodata] - def Transform_Hills2Basin(self,HillsMap): - 'Descripcion: A partir de un vector con propiedades de las laderas\n'\ - ' obtiene un vector con las propiedades por celda, ojo estas \n'\ - ' quedan con las formas de las laderas y la variable queda agregada. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : la cuenca misma.\n'\ - 'MapHills : Vector con las variables por laderas [nhills].\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'CellMap : Vector con la variable agregada por laderas, pero .\n'\ - ' pasada a celdas.\n'\ - #Genera el mapa de basin vacio - CellMap = np.ones(self.ncells) - #itera por la cantidad de elementos y les va asignando - for i,k in enumerate(HillsMap[::-1]): - CellMap[self.hills_own==i+1] = k - return CellMap - def Transform_Basin2Hills(self,CellMap,mask=None,SumMeanMax=0): - 'Descripcion: A partir de un vector tipo Basin obtiene un\n'\ - ' vector del tipo laderas, en donde las propiedades se \n'\ - ' agregan para cada ladera. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : la cuenca misma.\n'\ - 'CellMap : Vector con las propiedades por celdas [ncells].\n'\ - 'mask : Celdas sobre las cuales se agrega la variable (1), y\n'\ - ' sobre las que no (0).\n'\ - 'SumMeanMax : si la variable sera agregada como un promedio (0)\n'\ - ' o como una suma (1), o como el maximo valor (2).\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'HillsMap : Vector con las prop agregadas a laderas .\n'\ - #Si hay mascara la tiene en cuenta - if mask is not None: - Ma = np.zeros(self.ncells) - if type(mask) is float or type(mask) is int: - Ma[CellMap==mask] = 1 - elif type(mask) is np.ndarray: - Ma = np.copy(mask) - else: - Ma = np.ones(self.ncells) - #Pasa el mapa de celdas a mapa de laderas - HillsMap = cu.basin_subbasin_map2subbasin(self.hills_own, - CellMap, self.nhills, Ma, SumMeanMax, self.ncells) - return HillsMap + def Transform_Hills2Basin(self,HillsMap): + 'Descripcion: A partir de un vector con propiedades de las laderas\n'\ + ' obtiene un vector con las propiedades por celda, ojo estas \n'\ + ' quedan con las formas de las laderas y la variable queda agregada. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : la cuenca misma.\n'\ + 'MapHills : Vector con las variables por laderas [nhills].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'CellMap : Vector con la variable agregada por laderas, pero .\n'\ + ' pasada a celdas.\n'\ + #Genera el mapa de basin vacio + CellMap = np.ones(self.ncells) + #itera por la cantidad de elementos y les va asignando + for i,k in enumerate(HillsMap[::-1]): + CellMap[self.hills_own==i+1] = k + return CellMap + def Transform_Basin2Hills(self,CellMap,mask=None,SumMeanMax=0): + 'Descripcion: A partir de un vector tipo Basin obtiene un\n'\ + ' vector del tipo laderas, en donde las propiedades se \n'\ + ' agregan para cada ladera. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : la cuenca misma.\n'\ + 'CellMap : Vector con las propiedades por celdas [ncells].\n'\ + 'mask : Celdas sobre las cuales se agrega la variable (1), y\n'\ + ' sobre las que no (0).\n'\ + 'SumMeanMax : si la variable sera agregada como un promedio (0)\n'\ + ' o como una suma (1), o como el maximo valor (2).\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'HillsMap : Vector con las prop agregadas a laderas .\n'\ + #Si hay mascara la tiene en cuenta + if mask is not None: + Ma = np.zeros(self.ncells) + if type(mask) is float or type(mask) is int: + Ma[CellMap==mask] = 1 + elif type(mask) is np.ndarray: + Ma = np.copy(mask) + else: + Ma = np.ones(self.ncells) + #Pasa el mapa de celdas a mapa de laderas + HillsMap = cu.basin_subbasin_map2subbasin(self.hills_own, + CellMap, self.nhills, Ma, SumMeanMax, self.ncells) + return HillsMap def Transform_Basin2Polygon(self, Vector,): 'Descripcion: convierte una variable de topologia de la cuenca en varios poligonos\n'\ @@ -1797,419 +1798,419 @@ def Transform_Basin2Polygon(self, Vector,): DicPoly[str(Value)].update({str(cont):np.array(co).T}) return DicPoly - #------------------------------------------------------ - # Trabajo con datos puntuales puntos - #------------------------------------------------------ - def Points_Points2Stream(self,coordXY,ids): - 'Descripcion: toma las coordenadas de puntos XY y las mueve\n'\ - ' hacia los cauces de la cuenca\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'coordXY : coordenadas de los puntos [2,Ncoord].\n'\ - 'ids : Identificacion de los puntos que se van a mover.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'coordXYNew : Coordenadas transportadas a los cauces.\n'\ - 'basin_pts : Vector con la forma de la cuenca con los puntos.\n'\ - ' donde quedaron localizadas las coordenadas.\n'\ - 'idsOrdered : El orden en que quedaron los Ids ingresados.\n'\ - 'Ver Tambien\n'\ - '----------\n'\ - 'Points_Point2Basin\n'\ - #Obtiene el cauce - self.GetGeo_Cell_Basics() - #modifica los puntos - res_coord,basin_pts,xy_new = cu.basin_stream_point2stream( - self.structure, - self.CellCauce, - ids, - coordXY, - coordXY.shape[1], - self.ncells) - return xy_new, basin_pts, basin_pts[basin_pts<>0] - def Points_Points2Basin(self,coordXY,ids): - 'Descripcion: toma las coordenadas de puntos XY y las pone\n'\ - ' en la cuenca, no las mueve hacia los cuaces\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'coordXY : coordenadas de los puntos [2,Ncoord].\n'\ - 'ids : Identificacion de los puntos que se van a mover.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'basin_pts : Vector con la forma de la cuenca con los puntos.\n'\ - ' donde quedaron localizadas las coordenadas.\n'\ - 'idsOrdered : El orden en que quedaron los Ids ingresados.\n'\ - 'Ver Tambien\n'\ - '----------\n'\ - 'Points_Point2Stream\n'\ - #Obtiene el cauce - self.GetGeo_Cell_Basics() - #modifica los puntos - res_coord,basin_pts = cu.basin_point2var( - self.structure, - ids, - coordXY, - coordXY.shape[1], - self.ncells) - return basin_pts,basin_pts[basin_pts<>0] - #------------------------------------------------------ - # Caudales de largo plazo y regionalizacion - #------------------------------------------------------ - #Caudal de largo plazo - def GetQ_Balance(self,Precipitation, Tipo_ETR = 1, mu_choud = 1.37): - 'Descripcion: Calcula el caudal medio por balance de largo plazo\n'\ - ' para ello requiere conocer la precipitacion y el metodo de\n'\ - ' estimacion de la evaporacion.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : no necesita nada es autocontenido.\n'\ - 'Precipitation : Cantidad anual de lluvia, escalar o vector.\n'\ - 'Elevacion : Elevacion en cada punto de la cuenca.\n'\ - 'Tipo_ETR : Tipo de ecuacion para calcular la evaporacion.\n'\ - ' -1. Turc.\n'\ - ' -2. Cenicafe Budyko.\n'\ - ' -3. Choundry.\n'\ - ' Defecto: 1.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self.CellQmed : Caudal medio calculado para toda la cuenca.\n'\ - 'self.CellETR : ETR calculada para toda la cuenca.\n'\ - #Calcula las propiedades de la cuenca - self.GetGeo_Cell_Basics() - #Determina si la precipitacion es un vector o un escalar - if type(Precipitation) is int or type(Precipitation) is float: - precip = np.ones(self.ncells)*Precipitation - elif type(Precipitation) is np.ndarray: - precip = Precipitation - #Calcula el qmed - self.CellQmed,self.CellETR = cu.basin_qmed( - self.structure, - self.CellHeight, + #------------------------------------------------------ + # Trabajo con datos puntuales puntos + #------------------------------------------------------ + def Points_Points2Stream(self,coordXY,ids): + 'Descripcion: toma las coordenadas de puntos XY y las mueve\n'\ + ' hacia los cauces de la cuenca\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'coordXY : coordenadas de los puntos [2,Ncoord].\n'\ + 'ids : Identificacion de los puntos que se van a mover.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'coordXYNew : Coordenadas transportadas a los cauces.\n'\ + 'basin_pts : Vector con la forma de la cuenca con los puntos.\n'\ + ' donde quedaron localizadas las coordenadas.\n'\ + 'idsOrdered : El orden en que quedaron los Ids ingresados.\n'\ + 'Ver Tambien\n'\ + '----------\n'\ + 'Points_Point2Basin\n'\ + #Obtiene el cauce + self.GetGeo_Cell_Basics() + #modifica los puntos + res_coord,basin_pts,xy_new = cu.basin_stream_point2stream( + self.structure, + self.CellCauce, + ids, + coordXY, + coordXY.shape[1], + self.ncells) + return xy_new, basin_pts, basin_pts[basin_pts<>0] + def Points_Points2Basin(self,coordXY,ids): + 'Descripcion: toma las coordenadas de puntos XY y las pone\n'\ + ' en la cuenca, no las mueve hacia los cuaces\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'coordXY : coordenadas de los puntos [2,Ncoord].\n'\ + 'ids : Identificacion de los puntos que se van a mover.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'basin_pts : Vector con la forma de la cuenca con los puntos.\n'\ + ' donde quedaron localizadas las coordenadas.\n'\ + 'idsOrdered : El orden en que quedaron los Ids ingresados.\n'\ + 'Ver Tambien\n'\ + '----------\n'\ + 'Points_Point2Stream\n'\ + #Obtiene el cauce + self.GetGeo_Cell_Basics() + #modifica los puntos + res_coord,basin_pts = cu.basin_point2var( + self.structure, + ids, + coordXY, + coordXY.shape[1], + self.ncells) + return basin_pts,basin_pts[basin_pts<>0] + #------------------------------------------------------ + # Caudales de largo plazo y regionalizacion + #------------------------------------------------------ + #Caudal de largo plazo + def GetQ_Balance(self,Precipitation, Tipo_ETR = 1, mu_choud = 1.37): + 'Descripcion: Calcula el caudal medio por balance de largo plazo\n'\ + ' para ello requiere conocer la precipitacion y el metodo de\n'\ + ' estimacion de la evaporacion.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + 'Precipitation : Cantidad anual de lluvia, escalar o vector.\n'\ + 'Elevacion : Elevacion en cada punto de la cuenca.\n'\ + 'Tipo_ETR : Tipo de ecuacion para calcular la evaporacion.\n'\ + ' -1. Turc.\n'\ + ' -2. Cenicafe Budyko.\n'\ + ' -3. Choundry.\n'\ + ' Defecto: 1.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self.CellQmed : Caudal medio calculado para toda la cuenca.\n'\ + 'self.CellETR : ETR calculada para toda la cuenca.\n'\ + #Calcula las propiedades de la cuenca + self.GetGeo_Cell_Basics() + #Determina si la precipitacion es un vector o un escalar + if type(Precipitation) is int or type(Precipitation) is float: + precip = np.ones(self.ncells)*Precipitation + elif type(Precipitation) is np.ndarray: + precip = Precipitation + #Calcula el qmed + self.CellQmed,self.CellETR = cu.basin_qmed( + self.structure, + self.CellHeight, precip, - Tipo_ETR, - mu_choud, - self.ncells,) + Tipo_ETR, + mu_choud, + self.ncells,) - #Caudales extremos - def GetQ_Max(self,Qmed,Coef=[6.71, 3.29], Expo= [0.82, 0.64], Cv = 0.5, - Tr = [2.33, 5, 10, 25, 50, 100], Dist = 'gumbel', metodo = 'poveda', - Expo2 = [0.7745, 0.4608]): - 'Descripcion: Calcula el caudal maximo para diferentes\n'\ - ' periodos de retorno. Recibe como entrada el caudal medio \n'\ - ' calculado con GetQ_Balance.\n'\ - ' el calculo se hace a partir de la ecuacion:.\n'\ - ' MedMax = Coef[0] * Qmed ** Exp[0] .\n'\ - ' DesMax = Coef[1] * Qmed ** Exp[1] .\n'\ - ' Qmax = MedMax + K(Tr) * DesMax.\n'\ - ' Donde K es un coeficiente que depende de Tr y f(x).\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'Qmed : Caudal medio calculado con GetQ_Balance.\n'\ - 'Coef : Coeficientes para media y desviacion [6.71, 3.29].\n'\ - 'Expo : Exponentes para media y desviacion [0.82, 0.64].\n'\ - 'Cv : Coeficiente de escalamiento [0.5].\n'\ - 'Tr : Periodo de retorno [2.33, 5, 10, 25, 50, 100].\n'\ - 'Dist : Distrbucion [gumbel/lognorm].\n'\ - 'metodo: Poveda (u = cQA^a) o atlas (u = C(P-E)^a A^b), en este segundo caso Qmed = P-E.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'CellQmax : Caudal maximo para los diferentes periodos.\n'\ - # Calcula la media y desviacion - if metodo == 'poveda': - MedMax = Coef[0] * Qmed ** Expo[0] - DesMax = Coef[1] * Qmed ** Expo[1] - elif metodo == 'atlas': - Acum = cu.basin_acum(self.structure, self.ncells) - Acum = Acum * (cu.dxp**2)/1e6 - MedMax = Coef[0] * (Qmed ** Expo[0]) * (Acum**Expo2[0]) - DesMax = Coef[1] * (Qmed ** Expo[1]) * (Acum**Expo2[1]) - #Itera para todos los periodos de retorno - Qmax=[] - for t in Tr: - #Calcula k - if Dist is 'gumbel': - k=-1*(0.45+0.78*np.log(-1*np.log(1-1/float(t)))) - elif Dist is 'lognorm': - Ztr=norm.ppf(1-1/float(t)) - k=(np.exp(Ztr*np.sqrt(np.log(1+Cv**2))-0.5*np.log(1-Cv**2))-1)/Cv - #Calcula el caudal maximo - Qmax.append(list(MedMax+k*DesMax)) - return np.array(Qmax) - - def GetQ_Min(self,Qmed,Coef=[0.4168, 0.2], Expo= [1.058, 0.98], Cv = 0.5, - Tr = [2.33, 5, 10, 25, 50, 100], Dist = 'gumbel'): - 'Descripcion: Calcula el caudal minimo para diferentes\n'\ - ' periodos de retorno. Recibe como entrada el caudal medio \n'\ - ' calculado con GetQ_Balance.\n'\ - ' el calculo se hace a partir de la ecuacion:.\n'\ - ' MedMin = Coef[0] * Qmed ** Exp[0] .\n'\ - ' DesMin = Coef[1] * Qmed ** Exp[1] .\n'\ - ' Qmin = MedMin + K(Tr) * DesMin.\n'\ - ' Donde K es un coeficiente que depende de Tr y f(x).\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'Qmed : Caudal medio calculado con GetQ_Balance.\n'\ - 'Coef : Coeficientes para media y desviacion [6.71, 3.29].\n'\ - 'Expo : Exponentes para media y desviacion [0.82, 0.64].\n'\ - 'Cv : Coeficiente de escalamiento [0.5].\n'\ - 'Tr : Periodo de retorno [2.33, 5, 10, 25, 50, 100].\n'\ - 'Dist : Distrbucion [gumbel/lognorm].\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'CellQmax : Caudal maximo para los diferentes periodos.\n'\ - # Calcula la media y desviacion - MedMin = Coef[0] * Qmed ** Expo[0] - DesMin = Coef[1] * Qmed ** Expo[1] - #Itera para todos los periodos de retorno - Qmin=[] - for t in Tr: - #Calcula k - if Dist is 'gumbel': - k = (-1*np.sqrt(6)/np.pi)*(0.5772+np.log(-1*np.log(1/float(t)))) - elif Dist is 'lognorm': - Ztr=norm.ppf(1/float(t)) - k = 1*(np.exp(Ztr*np.sqrt(np.log(1+Cv**2))-0.5*np.log(1-Cv**2))-1)/Cv - #Calcula el caudal maximo - Qmin.append(list(MedMin+k*DesMin)) - return np.array(Qmin) - - #------------------------------------------------------ - # Guardado shp de cuencas y redes hidricas - #------------------------------------------------------ - def Save_Net2Map(self,ruta,dx=cu.dxp,umbral=None, - qmed=None,Dict=None,DriverFormat='ESRI Shapefile', - EPSG=4326, NumTramo = True, formato = '%.2f'): - 'Descripcion: Guarda la red hidrica simulada de la cuenca en .shp \n'\ - ' Puede contener un diccionario con propiedades de la red hidrica. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : no necesita nada es autocontenido.\n'\ - 'ruta : Lugar y nombre donde se va a guardar la red hidrica.\n'\ - 'dx : Longitud de las celdas planas (Valor de Dx plano asignado a wmf.cu.dxp).\n'\ - 'umbral : cantidad de celdas necesarias para corriente (Valor del umbral asignado a self.umbral).\n'\ - 'qmed : caudal medio calculado por alguna metodologia.\n'\ - 'Dict : Diccionario con parametros de la red hidrica que se quieren imprimir.\n'\ - 'DriverFormat : nombre del tipo de archivo vectorial de salida (ver OsGeo).\n'\ - 'EPSG : Codigo de proyeccion utilizada para los datos, defecto WGS84.\n'\ - 'NumTramo: Poner o no el numero de tramo en cada elemento de la red.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Escribe un archivo vectorial con la estructura de la red hidrica y sus propiedades.\n'\ - #varia el umbral en funcion de self - if umbral == None: - umbral = self.umbral - #division de la cuenca - acum=cu.basin_acum(self.structure,self.ncells) - cauce,nod_f,n_nodos=cu.basin_subbasin_nod(self.structure,acum,umbral,self.ncells) - sub_pert,sub_basin=cu.basin_subbasin_find(self.structure,nod_f,n_nodos,self.ncells) - sub_basins=cu.basin_subbasin_cut(n_nodos) - sub_horton,nod_hort=cu.basin_subbasin_horton(sub_basins,self.ncells,n_nodos) - sub_hort=cu.basin_subbasin_find(self.structure,nod_hort,n_nodos,self.ncells)[0] - cauceHorton=sub_hort*cauce - #Obtiene la red en manera vectorial - nodos = cu.basin_stream_nod(self.structure,acum,umbral,self.ncells)[1] - netsize = cu.basin_netxy_find(self.structure,nodos,cauceHorton,self.ncells) - net=cu.basin_netxy_cut(netsize,self.ncells) - #Para net con caudal medio - if qmed is not None: - netsize = cu.basin_netxy_find(self.structure,nodos,cauce*qmed,self.ncells) - netQmed=cu.basin_netxy_cut(netsize,self.ncells) - #Para net con tramos - if NumTramo: - netsize2 = cu.basin_netxy_find(self.structure,nodos,sub_pert*cauce,self.ncells) - netTramo = cu.basin_netxy_cut(netsize2,self.ncells) - #Cortes - cortes=np.where(net[0,:]==-999) - cortes=cortes[0].tolist() - cortes.insert(0,0) - #Escribe el shp de la red hidrica - spatialReference = osgeo.osr.SpatialReference() - spatialReference.ImportFromEPSG(EPSG) - driver = osgeo.ogr.GetDriverByName(DriverFormat) - if os.path.exists(ruta): - driver.DeleteDataSource(ruta) - shapeData = driver.CreateDataSource(ruta) - layer = shapeData.CreateLayer('layer1', spatialReference, osgeo.ogr.wkbLineString) - layerDefinition = layer.GetLayerDefn() - new_field=osgeo.ogr.FieldDefn('Long[km]',osgeo.ogr.OFTReal) - layer.CreateField(new_field) - new_field=osgeo.ogr.FieldDefn('Horton',osgeo.ogr.OFTInteger) - layer.CreateField(new_field) - #coloca los nodos - if NumTramo: - new_field=osgeo.ogr.FieldDefn('Tramo',osgeo.ogr.OFTInteger) - layer.CreateField(new_field) - if qmed is not None: - new_field=osgeo.ogr.FieldDefn('Qmed[m3s]',osgeo.ogr.OFTReal) - layer.CreateField(new_field) - if Dict is not None: - if type(Dict==dict): - netDict=[] - for k in Dict.keys(): - new_field=osgeo.ogr.FieldDefn(k[:10],osgeo.ogr.OFTReal) - layer.CreateField(new_field) - netsizeT = cu.basin_netxy_find(self.structure,nodos,cauce*Dict[k],self.ncells) - netDict.append(cu.basin_netxy_cut(netsize,self.ncells)) - #Para cada tramo - featureFID=0 - for i,j in zip(cortes[:-1],cortes[1:]): - line = osgeo.ogr.Geometry(osgeo.ogr.wkbLineString) - for x,y in zip(net[1,i+1:j],net[2,i+1:j]): - line.AddPoint_2D(float(x),float(y)) - feature = osgeo.ogr.Feature(layerDefinition) - feature.SetGeometry(line) - feature.SetFID(0) - feature.SetField('Long[km]',(net[1,i+1:j].size*dx)/1000.0) - feature.SetField('Horton',int(net[0,i+1])) - if qmed is not None: - feature.SetField('Qmed[m3s]',float(netQmed[0,i+1])) - if NumTramo: - feature.SetField('Tramo',int(netTramo[0,i+1])) - if Dict is not None: - if type(Dict==dict): - for n,k in zip(netDict,Dict.keys()): - feature.SetField(k[:10],float(formato % n[0,i+1])) - #featureFID+=1 - layer.CreateFeature(feature) - line.Destroy() - feature.Destroy() - shapeData.Destroy() - def Save_Basin2Map(self,ruta,dx=30.0,Param={}, - DriverFormat='ESRI Shapefile',EPSG=4326, GeoParam = False): - 'Descripcion: Guarda un archivo vectorial de la cuenca en .shp \n'\ - ' Puede contener un diccionario con propiedades. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : no necesita nada es autocontenido.\n'\ - 'ruta : Lugar y nombre donde se va a guardar la cuenca.\n'\ - 'dx : Longitud de las celdas planas.\n'\ - 'DriverFormat : nombre del tipo de archivo vectorial de salida (ver OsGeo).\n'\ - 'EPSG : Codigo de proyeccion utilizada para los datos, defecto WGS84.\n'\ - 'GeoParam: (False) determina si calcular de una los parametros geomorfo o no.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Escribe un archivo vectorial de la cuenca.\n'\ - #Obtiene el perimetro de la cuenca - #nperim = cu.basin_perim_find(self.structure,self.ncells) - #basinPerim=cu.basin_perim_cut(nperim) + #Caudales extremos + def GetQ_Max(self,Qmed,Coef=[6.71, 3.29], Expo= [0.82, 0.64], Cv = 0.5, + Tr = [2.33, 5, 10, 25, 50, 100], Dist = 'gumbel', metodo = 'poveda', + Expo2 = [0.7745, 0.4608]): + 'Descripcion: Calcula el caudal maximo para diferentes\n'\ + ' periodos de retorno. Recibe como entrada el caudal medio \n'\ + ' calculado con GetQ_Balance.\n'\ + ' el calculo se hace a partir de la ecuacion:.\n'\ + ' MedMax = Coef[0] * Qmed ** Exp[0] .\n'\ + ' DesMax = Coef[1] * Qmed ** Exp[1] .\n'\ + ' Qmax = MedMax + K(Tr) * DesMax.\n'\ + ' Donde K es un coeficiente que depende de Tr y f(x).\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'Qmed : Caudal medio calculado con GetQ_Balance.\n'\ + 'Coef : Coeficientes para media y desviacion [6.71, 3.29].\n'\ + 'Expo : Exponentes para media y desviacion [0.82, 0.64].\n'\ + 'Cv : Coeficiente de escalamiento [0.5].\n'\ + 'Tr : Periodo de retorno [2.33, 5, 10, 25, 50, 100].\n'\ + 'Dist : Distrbucion [gumbel/lognorm].\n'\ + 'metodo: Poveda (u = cQA^a) o atlas (u = C(P-E)^a A^b), en este segundo caso Qmed = P-E.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'CellQmax : Caudal maximo para los diferentes periodos.\n'\ + # Calcula la media y desviacion + if metodo == 'poveda': + MedMax = Coef[0] * Qmed ** Expo[0] + DesMax = Coef[1] * Qmed ** Expo[1] + elif metodo == 'atlas': + Acum = cu.basin_acum(self.structure, self.ncells) + Acum = Acum * (cu.dxp**2)/1e6 + MedMax = Coef[0] * (Qmed ** Expo[0]) * (Acum**Expo2[0]) + DesMax = Coef[1] * (Qmed ** Expo[1]) * (Acum**Expo2[1]) + #Itera para todos los periodos de retorno + Qmax=[] + for t in Tr: + #Calcula k + if Dist is 'gumbel': + k=-1*(0.45+0.78*np.log(-1*np.log(1-1/float(t)))) + elif Dist is 'lognorm': + Ztr=norm.ppf(1-1/float(t)) + k=(np.exp(Ztr*np.sqrt(np.log(1+Cv**2))-0.5*np.log(1-Cv**2))-1)/Cv + #Calcula el caudal maximo + Qmax.append(list(MedMax+k*DesMax)) + return np.array(Qmax) + + def GetQ_Min(self,Qmed,Coef=[0.4168, 0.2], Expo= [1.058, 0.98], Cv = 0.5, + Tr = [2.33, 5, 10, 25, 50, 100], Dist = 'gumbel'): + 'Descripcion: Calcula el caudal minimo para diferentes\n'\ + ' periodos de retorno. Recibe como entrada el caudal medio \n'\ + ' calculado con GetQ_Balance.\n'\ + ' el calculo se hace a partir de la ecuacion:.\n'\ + ' MedMin = Coef[0] * Qmed ** Exp[0] .\n'\ + ' DesMin = Coef[1] * Qmed ** Exp[1] .\n'\ + ' Qmin = MedMin + K(Tr) * DesMin.\n'\ + ' Donde K es un coeficiente que depende de Tr y f(x).\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'Qmed : Caudal medio calculado con GetQ_Balance.\n'\ + 'Coef : Coeficientes para media y desviacion [6.71, 3.29].\n'\ + 'Expo : Exponentes para media y desviacion [0.82, 0.64].\n'\ + 'Cv : Coeficiente de escalamiento [0.5].\n'\ + 'Tr : Periodo de retorno [2.33, 5, 10, 25, 50, 100].\n'\ + 'Dist : Distrbucion [gumbel/lognorm].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'CellQmax : Caudal maximo para los diferentes periodos.\n'\ + # Calcula la media y desviacion + MedMin = Coef[0] * Qmed ** Expo[0] + DesMin = Coef[1] * Qmed ** Expo[1] + #Itera para todos los periodos de retorno + Qmin=[] + for t in Tr: + #Calcula k + if Dist is 'gumbel': + k = (-1*np.sqrt(6)/np.pi)*(0.5772+np.log(-1*np.log(1/float(t)))) + elif Dist is 'lognorm': + Ztr=norm.ppf(1/float(t)) + k = 1*(np.exp(Ztr*np.sqrt(np.log(1+Cv**2))-0.5*np.log(1-Cv**2))-1)/Cv + #Calcula el caudal maximo + Qmin.append(list(MedMin+k*DesMin)) + return np.array(Qmin) + + #------------------------------------------------------ + # Guardado shp de cuencas y redes hidricas + #------------------------------------------------------ + def Save_Net2Map(self,ruta,dx=cu.dxp,umbral=None, + qmed=None,Dict=None,DriverFormat='ESRI Shapefile', + EPSG=4326, NumTramo = True, formato = '%.2f'): + 'Descripcion: Guarda la red hidrica simulada de la cuenca en .shp \n'\ + ' Puede contener un diccionario con propiedades de la red hidrica. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + 'ruta : Lugar y nombre donde se va a guardar la red hidrica.\n'\ + 'dx : Longitud de las celdas planas (Valor de Dx plano asignado a wmf.cu.dxp).\n'\ + 'umbral : cantidad de celdas necesarias para corriente (Valor del umbral asignado a self.umbral).\n'\ + 'qmed : caudal medio calculado por alguna metodologia.\n'\ + 'Dict : Diccionario con parametros de la red hidrica que se quieren imprimir.\n'\ + 'DriverFormat : nombre del tipo de archivo vectorial de salida (ver OsGeo).\n'\ + 'EPSG : Codigo de proyeccion utilizada para los datos, defecto WGS84.\n'\ + 'NumTramo: Poner o no el numero de tramo en cada elemento de la red.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Escribe un archivo vectorial con la estructura de la red hidrica y sus propiedades.\n'\ + #varia el umbral en funcion de self + if umbral == None: + umbral = self.umbral + #division de la cuenca + acum=cu.basin_acum(self.structure,self.ncells) + cauce,nod_f,n_nodos=cu.basin_subbasin_nod(self.structure,acum,umbral,self.ncells) + sub_pert,sub_basin=cu.basin_subbasin_find(self.structure,nod_f,n_nodos,self.ncells) + sub_basins=cu.basin_subbasin_cut(n_nodos) + sub_horton,nod_hort=cu.basin_subbasin_horton(sub_basins,self.ncells,n_nodos) + sub_hort=cu.basin_subbasin_find(self.structure,nod_hort,n_nodos,self.ncells)[0] + cauceHorton=sub_hort*cauce + #Obtiene la red en manera vectorial + nodos = cu.basin_stream_nod(self.structure,acum,umbral,self.ncells)[1] + netsize = cu.basin_netxy_find(self.structure,nodos,cauceHorton,self.ncells) + net=cu.basin_netxy_cut(netsize,self.ncells) + #Para net con caudal medio + if qmed is not None: + netsize = cu.basin_netxy_find(self.structure,nodos,cauce*qmed,self.ncells) + netQmed=cu.basin_netxy_cut(netsize,self.ncells) + #Para net con tramos + if NumTramo: + netsize2 = cu.basin_netxy_find(self.structure,nodos,sub_pert*cauce,self.ncells) + netTramo = cu.basin_netxy_cut(netsize2,self.ncells) + #Cortes + cortes=np.where(net[0,:]==-999) + cortes=cortes[0].tolist() + cortes.insert(0,0) + #Escribe el shp de la red hidrica + spatialReference = osgeo.osr.SpatialReference() + spatialReference.ImportFromEPSG(EPSG) + driver = osgeo.ogr.GetDriverByName(DriverFormat) + if os.path.exists(ruta): + driver.DeleteDataSource(ruta) + shapeData = driver.CreateDataSource(ruta) + layer = shapeData.CreateLayer('layer1', spatialReference, osgeo.ogr.wkbLineString) + layerDefinition = layer.GetLayerDefn() + new_field=osgeo.ogr.FieldDefn('Long[km]',osgeo.ogr.OFTReal) + layer.CreateField(new_field) + new_field=osgeo.ogr.FieldDefn('Horton',osgeo.ogr.OFTInteger) + layer.CreateField(new_field) + #coloca los nodos + if NumTramo: + new_field=osgeo.ogr.FieldDefn('Tramo',osgeo.ogr.OFTInteger) + layer.CreateField(new_field) + if qmed is not None: + new_field=osgeo.ogr.FieldDefn('Qmed[m3s]',osgeo.ogr.OFTReal) + layer.CreateField(new_field) + if Dict is not None: + if type(Dict==dict): + netDict=[] + for k in Dict.keys(): + new_field=osgeo.ogr.FieldDefn(k[:10],osgeo.ogr.OFTReal) + layer.CreateField(new_field) + netsizeT = cu.basin_netxy_find(self.structure,nodos,cauce*Dict[k],self.ncells) + netDict.append(cu.basin_netxy_cut(netsize,self.ncells)) + #Para cada tramo + featureFID=0 + for i,j in zip(cortes[:-1],cortes[1:]): + line = osgeo.ogr.Geometry(osgeo.ogr.wkbLineString) + for x,y in zip(net[1,i+1:j],net[2,i+1:j]): + line.AddPoint_2D(float(x),float(y)) + feature = osgeo.ogr.Feature(layerDefinition) + feature.SetGeometry(line) + feature.SetFID(0) + feature.SetField('Long[km]',(net[1,i+1:j].size*dx)/1000.0) + feature.SetField('Horton',int(net[0,i+1])) + if qmed is not None: + feature.SetField('Qmed[m3s]',float(netQmed[0,i+1])) + if NumTramo: + feature.SetField('Tramo',int(netTramo[0,i+1])) + if Dict is not None: + if type(Dict==dict): + for n,k in zip(netDict,Dict.keys()): + feature.SetField(k[:10],float(formato % n[0,i+1])) + #featureFID+=1 + layer.CreateFeature(feature) + line.Destroy() + feature.Destroy() + shapeData.Destroy() + def Save_Basin2Map(self,ruta,dx=30.0,Param={}, + DriverFormat='ESRI Shapefile',EPSG=4326, GeoParam = False): + 'Descripcion: Guarda un archivo vectorial de la cuenca en .shp \n'\ + ' Puede contener un diccionario con propiedades. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + 'ruta : Lugar y nombre donde se va a guardar la cuenca.\n'\ + 'dx : Longitud de las celdas planas.\n'\ + 'DriverFormat : nombre del tipo de archivo vectorial de salida (ver OsGeo).\n'\ + 'EPSG : Codigo de proyeccion utilizada para los datos, defecto WGS84.\n'\ + 'GeoParam: (False) determina si calcular de una los parametros geomorfo o no.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Escribe un archivo vectorial de la cuenca.\n'\ + #Obtiene el perimetro de la cuenca + #nperim = cu.basin_perim_find(self.structure,self.ncells) + #basinPerim=cu.basin_perim_cut(nperim) - #Parametros geomorfo - if GeoParam: - self.GetGeo_Parameters() - DictParam = {} - for k in self.GeoParameters.keys(): - DictParam.update({k[:8]: self.GeoParameters[k]}) - #Genera el shapefile - spatialReference = osgeo.osr.SpatialReference() - spatialReference.ImportFromEPSG(EPSG) - driver = osgeo.ogr.GetDriverByName(DriverFormat) - if os.path.exists(ruta): - driver.DeleteDataSource(ruta) - shapeData = driver.CreateDataSource(ruta) - layer = shapeData.CreateLayer('layer1', spatialReference, osgeo.ogr.wkbPolygon) - layerDefinition = layer.GetLayerDefn() - for p in Param.keys(): - #new_field=osgeo.ogr.FieldDefn(p[:p.index('[')].strip()[:10],osgeo.ogr.OFTReal) - new_field=osgeo.ogr.FieldDefn(p,osgeo.ogr.OFTReal) - layer.CreateField(new_field) - if GeoParam: - for p in DictParam.keys(): - new_field=osgeo.ogr.FieldDefn(p,osgeo.ogr.OFTReal) - layer.CreateField(new_field) - #Calcula el tamano de la muestra - ring = osgeo.ogr.Geometry(osgeo.ogr.wkbLinearRing) - for i in self.Polygon.T: - ring.AddPoint(x=float(i[0]),y=float(i[1])) - poly=osgeo.ogr.Geometry(osgeo.ogr.wkbPolygon) - poly.AddGeometry(ring) - feature = osgeo.ogr.Feature(layerDefinition) - feature.SetGeometry(poly) - feature.SetFID(0) - for p in Param.keys(): - #feature.SetField(p[:p.index('[')].strip()[:10],float("%.2f" % Param[p])) - feature.SetField(p,float("%.2f" % Param[p])) - #Si calcula parametros geomorfo - if GeoParam: - for p in DictParam.keys(): - feature.SetField(p,float("%.2f" % DictParam[p])) - layer.CreateFeature(feature) - poly.Destroy() - ring.Destroy() - feature.Destroy() - shapeData.Destroy() + #Parametros geomorfo + if GeoParam: + self.GetGeo_Parameters() + DictParam = {} + for k in self.GeoParameters.keys(): + DictParam.update({k[:8]: self.GeoParameters[k]}) + #Genera el shapefile + spatialReference = osgeo.osr.SpatialReference() + spatialReference.ImportFromEPSG(EPSG) + driver = osgeo.ogr.GetDriverByName(DriverFormat) + if os.path.exists(ruta): + driver.DeleteDataSource(ruta) + shapeData = driver.CreateDataSource(ruta) + layer = shapeData.CreateLayer('layer1', spatialReference, osgeo.ogr.wkbPolygon) + layerDefinition = layer.GetLayerDefn() + for p in Param.keys(): + #new_field=osgeo.ogr.FieldDefn(p[:p.index('[')].strip()[:10],osgeo.ogr.OFTReal) + new_field=osgeo.ogr.FieldDefn(p,osgeo.ogr.OFTReal) + layer.CreateField(new_field) + if GeoParam: + for p in DictParam.keys(): + new_field=osgeo.ogr.FieldDefn(p,osgeo.ogr.OFTReal) + layer.CreateField(new_field) + #Calcula el tamano de la muestra + ring = osgeo.ogr.Geometry(osgeo.ogr.wkbLinearRing) + for i in self.Polygon.T: + ring.AddPoint(x=float(i[0]),y=float(i[1])) + poly=osgeo.ogr.Geometry(osgeo.ogr.wkbPolygon) + poly.AddGeometry(ring) + feature = osgeo.ogr.Feature(layerDefinition) + feature.SetGeometry(poly) + feature.SetFID(0) + for p in Param.keys(): + #feature.SetField(p[:p.index('[')].strip()[:10],float("%.2f" % Param[p])) + feature.SetField(p,float("%.2f" % Param[p])) + #Si calcula parametros geomorfo + if GeoParam: + for p in DictParam.keys(): + feature.SetField(p,float("%.2f" % DictParam[p])) + layer.CreateFeature(feature) + poly.Destroy() + ring.Destroy() + feature.Destroy() + shapeData.Destroy() - #------------------------------------------------------ - # Graficas de la cuenca - #------------------------------------------------------ - def Plot_basin(self,vec=None,Min=None, - Max=None,ruta=None,figsize=(10,7), - ZeroAsNaN ='no',extra_lat=0.0,extra_long=0.0,lines_spaces='Default', - xy=None,xycolor='b',colorTable=None,alpha=1.0,vmin=None,vmax=None, - colorbar=True, colorbarLabel = None,axis=None,rutaShp=None,shpWidth = 0.7, - shpColor = 'r',axloc = 111, fig = None, EPSG = 4326,backMap = False, - **kwargs): + #------------------------------------------------------ + # Graficas de la cuenca + #------------------------------------------------------ + def Plot_basin(self,vec=None,Min=None, + Max=None,ruta=None,figsize=(10,7), + ZeroAsNaN ='no',extra_lat=0.0,extra_long=0.0,lines_spaces='Default', + xy=None,xycolor='b',colorTable=None,alpha=1.0,vmin=None,vmax=None, + colorbar=True, colorbarLabel = None,axis=None,rutaShp=None,shpWidth = 0.7, + shpColor = 'r',axloc = 111, fig = None, EPSG = 4326,backMap = False, + **kwargs): #Plotea en la terminal como mapa un vector de la cuenca 'Funcion: Plot_basin\n'\ 'Descripcion: Genera un plot del mapa entregado.\n'\ 'del mismo en forma de mapa \n'\ 'Parametros Obligatorios:.\n'\ - ' -basin: Vector con la forma de la cuenca.\n'\ - ' -vec: Vector con los valores a plotear.\n'\ + ' -basin: Vector con la forma de la cuenca.\n'\ + ' -vec: Vector con los valores a plotear.\n'\ 'Parametros Opcionales:.\n'\ - ' -Min: Valor minimo del plot, determina el rango de colores.\n'\ - ' -Max: Valor maximo del plot, determina el rango de colores.\n'\ - ' -ruta: Ruta en la cual se guarda la grafica.\n'\ - ' -colorbar: Muestra o no la barra de colores, defecto: True.\n'\ - ' -figsize: tamano de la ventana donde se muestra la cuenca.\n'\ - ' -ZeroAsNaN: Convierte los valores de cero en NaN.\n'\ - ' -rutaShp: Ruta a un vectorial que se quiera mostrar en el mapa.\n'\ - ' -shpWidth: Ancho de las lineas del shp cargado.\n'\ - ' -shpColor: Color de las lineas del shp cargado.\n'\ - ' -backMap: Pone de fondo un mapa tipo arcGIS.\n'\ + ' -Min: Valor minimo del plot, determina el rango de colores.\n'\ + ' -Max: Valor maximo del plot, determina el rango de colores.\n'\ + ' -ruta: Ruta en la cual se guarda la grafica.\n'\ + ' -colorbar: Muestra o no la barra de colores, defecto: True.\n'\ + ' -figsize: tamano de la ventana donde se muestra la cuenca.\n'\ + ' -ZeroAsNaN: Convierte los valores de cero en NaN.\n'\ + ' -rutaShp: Ruta a un vectorial que se quiera mostrar en el mapa.\n'\ + ' -shpWidth: Ancho de las lineas del shp cargado.\n'\ + ' -shpColor: Color de las lineas del shp cargado.\n'\ + ' -backMap: Pone de fondo un mapa tipo arcGIS.\n'\ 'Otros argumentos:.\n'\ - ' -axis = Entorno de grafica que contiene elementos de las figuras.\n'\ - ' -parallels = Grafica Paralelos, list-like.\n'\ - ' -parallels_labels = Etiquetas de los paralelos, list-like.\n'\ - ' labels = [left,right,top,bottom].\n'\ - ' Ejemplo:\n'\ - ' m.drawparallels(parallels,labels=[False,True,True,False]).\n'\ - ' -parallels_offset: desplazamiento de las coordenadas en X.\n'\ - ' -meridians = Grafica Meridianos, list-like.\n'\ - ' -meridians_labels = Etiquetas de los meridianos, list-like.\n'\ - ' -meridians_offset: desplazamiento de las coordeandas en Y.\n'\ - ' -per_color = Color del perimetro.\n'\ - ' -per_lw = Ancho de linea del perimetro.\n'\ - ' -colorbarLabel = Titulo del colorbar.\n'\ - ' -xy_edgecolor = Color de la linea exterior del scatter .\n'\ - ' -xy_lw = Ancho de linea del Scatter .\n'\ - ' -xy_s = Tamano del scatter.\n'\ - ' -xy_colorbar: Coloca o no barra de colores del scatter enviado (False).\n'\ - ' -show = boolean, si es True muestra la grafica.\n'\ - ' -cbar_ticks: (None) ubicacion de los ticks del cbar.\n'\ - ' -cbar_ticklabels: (None) Labels a poner sobre los ticks.\n'\ - ' -cbar_ticksize: (14) Tamano de los ticks.\n'\ - ' -ShpIsPolygon: Indica si ese shp cargado es poligono (True) o no (False).\n'\ - ' -shpAlpha: transparencia del shp (0.5).\n'\ + ' -axis = Entorno de grafica que contiene elementos de las figuras.\n'\ + ' -parallels = Grafica Paralelos, list-like.\n'\ + ' -parallels_labels = Etiquetas de los paralelos, list-like.\n'\ + ' labels = [left,right,top,bottom].\n'\ + ' Ejemplo:\n'\ + ' m.drawparallels(parallels,labels=[False,True,True,False]).\n'\ + ' -parallels_offset: desplazamiento de las coordenadas en X.\n'\ + ' -meridians = Grafica Meridianos, list-like.\n'\ + ' -meridians_labels = Etiquetas de los meridianos, list-like.\n'\ + ' -meridians_offset: desplazamiento de las coordeandas en Y.\n'\ + ' -per_color = Color del perimetro.\n'\ + ' -per_lw = Ancho de linea del perimetro.\n'\ + ' -colorbarLabel = Titulo del colorbar.\n'\ + ' -xy_edgecolor = Color de la linea exterior del scatter .\n'\ + ' -xy_lw = Ancho de linea del Scatter .\n'\ + ' -xy_s = Tamano del scatter.\n'\ + ' -xy_colorbar: Coloca o no barra de colores del scatter enviado (False).\n'\ + ' -show = boolean, si es True muestra la grafica.\n'\ + ' -cbar_ticks: (None) ubicacion de los ticks del cbar.\n'\ + ' -cbar_ticklabels: (None) Labels a poner sobre los ticks.\n'\ + ' -cbar_ticksize: (14) Tamano de los ticks.\n'\ + ' -ShpIsPolygon: Indica si ese shp cargado es poligono (True) o no (False).\n'\ + ' -shpAlpha: transparencia del shp (0.5).\n'\ 'Retorno:.\n'\ - ' -Actualizacion del binario .int\n'\ - ' -m = Para continuar graficando encima del entorno creado en Basemap\n'\ - ' Ejemplo:.\n'\ - ' m = Plot_basin(**args).\n'\ - ' m.scatter(coordenada_x,coordenada_y).\n' + ' -Actualizacion del binario .int\n'\ + ' -m = Para continuar graficando encima del entorno creado en Basemap\n'\ + ' Ejemplo:.\n'\ + ' m = Plot_basin(**args).\n'\ + ' m.scatter(coordenada_x,coordenada_y).\n' #Prop de la barra de colores cbar_ticklabels = kwargs.get('cbar_ticklabels', None) cbar_ticks = kwargs.get('cbar_ticks', None) @@ -2218,8 +2219,8 @@ def Plot_basin(self,vec=None,Min=None, ShpIsPolygon = kwargs.get('ShpIsPolygon',None) shpAlpha = kwargs.get('shpAlpha',0.5) xy_colorbar = kwargs.get('xy_colorbar', False) - if lines_spaces == 'Default': - lines_spaces = cu.dx*cu.ncols*0.05 + if lines_spaces == 'Default': + lines_spaces = cu.dx*cu.ncols*0.05 #El mapa Mcols,Mrows=cu.basin_2map_find(self.structure,self.ncells) Map,mxll,myll=cu.basin_2map(self.structure,self.structure[0] @@ -2260,12 +2261,11 @@ def Plot_basin(self,vec=None,Min=None, fmt="%.2f", yoffset=meridians_offset) Xm,Ym=m(X,Y) - #plotea el mapa de fondo de arcGIS + #plotea el mapa de fondo de arcGIS if backMap: - #if backMap == 'arcGIS': m.arcgisimage(server='http://server.arcgisonline.com/ArcGIS', service='World_Topo_Map', xpixels = 1500, verbose = True) - #Plotea el contorno de la cuenca y la red - xp,yp = m(self.Polygon[0], self.Polygon[1]) + #Plotea el contorno de la cuenca y la red + xp,yp = m(self.Polygon[0], self.Polygon[1]) per_color = kwargs.get('per_color','r') per_lw = kwargs.get('per_lw',2) m.plot(xp, yp, color=per_color,lw=per_lw) @@ -2330,244 +2330,244 @@ def Plot_basin(self,vec=None,Min=None, return m,ax else: return m, ax, sx - #Grafica de plot para montar en paginas web o presentaciones - def Plot_basinClean(self, vec, ruta = None, umbral = 0.0, - vmin = 0.0, vmax = None, show_cbar = False, **kwargs): - 'Funcion: Plot_basinClean\n'\ - 'Descripcion: Genera un plot del mapa entregado en un lienzo limpio.\n'\ - 'Parametros Obligatorios:.\n'\ - ' -vec: Vector con los valores a plotear.\n'\ - 'Parametros Opcionales:.\n'\ - ' -ruta: ruta donde se guarda el png.\n'\ - ' -umbral: Umbral a partir del cual se plotea variable.\n'\ - ' -vmin: Valor minimo de la variable.\n'\ - ' -vmax: valor maximo de la variable.\n'\ - ' -show_cbar: muestra o no el Cbar del plot.\n'\ - 'Otros argumentos:.\n'\ - ' -cmap: Esquema de colores.\n'\ - ' -figsize = Tamano de la figura.\n'\ - ' -cbar_aspect: (20) relacion largo ancho del cbar.\n'\ - ' -cbar_ticks: (None) ubicacion de los ticks del cbar.\n'\ - ' -cbar_ticklabels: (None) Labels a poner sobre los ticks.\n'\ - ' -cbar_ticksize: (14) Tamano de los ticks.\n'\ - ' -show: SE muestra por defecto la figura (True).\n'\ - ' -interpolation: Tipo de interpolacion utilizada por la funcion imshow (ver opciones en matplotlib).\n'\ - 'Retorno:.\n'\ - ' -Figura se muestra y se guarda.\n'\ - ' -Coordenadas de los bordes del mapa.\n'\ - #Argumentos kw - cmap = kwargs.get('cmap','Spectral') - figsize = kwargs.get('figsize', (10,8)) - cbar_aspect = kwargs.get('cbar_aspect', 20) - cbar_ticklabels = kwargs.get('cbar_ticklabels', None) - cbar_ticks = kwargs.get('cbar_ticks', None) - cbar_ticksize = kwargs.get('cbar_ticksize', 14) - interpolation = kwargs.get('None') - show = kwargs.get('show', True) - #Obtiene la matriz - M,p = self.Transform_Basin2Map(vec) - M[(M == -9999) | (Mumbral)[0] - elif type(umbral) == np.ndarray and umbral.shape[0] == self.ncells: - pos = np.where(umbral == 1)[0] - x,y = cu.basin_coordxy(self.structure, self.ncells) - #Vector para pintar si no tiene el vec_c usa vec - if vec_c is None: - vec_c = np.copy(vec) - #Compara o no - if q_compare is not None: - vec = vec/q_compare.astype(float) - #Figura - fig = pl.figure(figsize=figsize) - ax = fig.add_subplot(111) - sca = pl.scatter(x[pos],y[pos], - s = vec[pos]*escala, - c = vec_c[pos], - lw = 0, - vmin = vmin, - vmax = vmax, - cmap = cmap, - norm = norm) - ax.patch.set_facecolor('w') - ax.patch.set_alpha(0.0) - if grid: - pl.grid(True) - #colorca colorbar - if show_cbar: - cbar = pl.colorbar(sca, aspect = cbar_aspect, ) - if cbar_ticks is not None: - cbar.set_ticks(cbar_ticks) - if cbar_ticklabels is not None: - cbar.ax.set_yticklabels(cbar_ticklabels, size = cbar_ticksize,) - - ax.set_xlim(x[pos].min(),x[pos].max()) - ax.set_ylim(y[pos].min(),y[pos].max()) - #Quita ejes - if clean: - ax.set_xticklabels([]) - ax.set_yticklabels([]) - ax.axis('off') - if clean == False: - ax.set_xlabel('Latitud', size = size) - ax.set_ylabel('Longitud', size = size) - ax.tick_params(labelsize = ticksize) - #Guarda transparente y ajustando bordes - if ruta is not None: - pl.savefig(ruta, - bbox_inches = 'tight', - pad_inches = 0, - transparent = transparent, - edgecolor = 'none', - facecolor = 'none') - if show: - pl.show() - pl.close(fig) - #Retorna las 4 coordenadas de las esquinas - return [x[pos].min(), x[pos].max(), y[pos].min(), y[pos].max()] - - - # Grafica barras de tiempos de concentracion - def Plot_Tc(self,ruta=None,figsize=(8,6),**kwargs): - keys=self.Tc.keys() - keys[2]=u'Carr Espana' - Media=np.array(self.Tc.values()).mean() - Desv=np.array(self.Tc.values()).std() - Mediana=np.percentile(self.Tc.values(),50) - rango=[Media-Desv,Media+Desv] - color1 = kwargs.get('color1','b') - color2 = kwargs.get('color2','r') - colores=[] - for t in self.Tc.values(): - if t>rango[0] and tumbral)[0] + elif type(umbral) == np.ndarray and umbral.shape[0] == self.ncells: + pos = np.where(umbral == 1)[0] + x,y = cu.basin_coordxy(self.structure, self.ncells) + #Vector para pintar si no tiene el vec_c usa vec + if vec_c is None: + vec_c = np.copy(vec) + #Compara o no + if q_compare is not None: + vec = vec/q_compare.astype(float) + #Figura + fig = pl.figure(figsize=figsize) + ax = fig.add_subplot(111) + sca = pl.scatter(x[pos],y[pos], + s = vec[pos]*escala, + c = vec_c[pos], + lw = 0, + vmin = vmin, + vmax = vmax, + cmap = cmap, + norm = norm) + ax.patch.set_facecolor('w') + ax.patch.set_alpha(0.0) + if grid: + pl.grid(True) + #colorca colorbar + if show_cbar: + cbar = pl.colorbar(sca, aspect = cbar_aspect, ) + if cbar_ticks is not None: + cbar.set_ticks(cbar_ticks) + if cbar_ticklabels is not None: + cbar.ax.set_yticklabels(cbar_ticklabels, size = cbar_ticksize,) + + ax.set_xlim(x[pos].min(),x[pos].max()) + ax.set_ylim(y[pos].min(),y[pos].max()) + #Quita ejes + if clean: + ax.set_xticklabels([]) + ax.set_yticklabels([]) + ax.axis('off') + if clean == False: + ax.set_xlabel('Latitud', size = size) + ax.set_ylabel('Longitud', size = size) + ax.tick_params(labelsize = ticksize) + #Guarda transparente y ajustando bordes + if ruta is not None: + pl.savefig(ruta, + bbox_inches = 'tight', + pad_inches = 0, + transparent = transparent, + edgecolor = 'none', + facecolor = 'none') + if show: + pl.show() + pl.close(fig) + #Retorna las 4 coordenadas de las esquinas + return [x[pos].min(), x[pos].max(), y[pos].min(), y[pos].max()] + + + # Grafica barras de tiempos de concentracion + def Plot_Tc(self,ruta=None,figsize=(8,6),**kwargs): + keys=self.Tc.keys() + keys[2]=u'Carr Espana' + Media=np.array(self.Tc.values()).mean() + Desv=np.array(self.Tc.values()).std() + Mediana=np.percentile(self.Tc.values(),50) + rango=[Media-Desv,Media+Desv] + color1 = kwargs.get('color1','b') + color2 = kwargs.get('color2','r') + colores=[] + for t in self.Tc.values(): + if t>rango[0] and tself.ncells: + pendientes en la cuenca. + Requiere: + - ruta: ruta de guaradado de la imagen, + - bins: rango inferior, superior y paso para intervalos. + - Nsize: Cantidad de datos a usar para realizar el histograma. + Retorna: + - Plot. + - Eje del plot si se quiere continuar editando + **kwargs: + - lw: ancho de la linea. + - axissize: tamano de los ejes + - labelsize: tamano de los nombres''' + lw = kwargs.get('lw',3) + labelsize = kwargs.get('labelsize',16) + axissize = kwargs.get('axissize',15) + if Nsize>self.ncells: Nsize = self.ncells pos = np.random.choice(self.ncells,Nsize) h,b=np.histogram(self.CellSlope[pos],bins=np.arange(bins[0],bins[1],bins[2])) b=(b[:-1]+b[1:])/2.0 h=h.astype(float)/h.astype(float).sum() - if fig is None: - fig=pl.figure(figsize = figsize, edgecolor='w',facecolor='w') - ax=fig.add_subplot(111) + if fig is None: + fig=pl.figure(figsize = figsize, edgecolor='w',facecolor='w') + ax=fig.add_subplot(111) ax.plot(b,h,lw=lw) ax.grid(True) - ax.tick_params(labelsize = axissize) + ax.tick_params(labelsize = axissize) ax.set_xlabel('Pendiente',size=labelsize) ax.set_ylabel('$pdf [\%]$',size=labelsize) if ruta is not None: pl.savefig(ruta,bbox_inches='tight') - if show: - pl.show() - return ax - - #Plot de histograma de tiempos de viajes en la cuenca - def Plot_Travell_Hist(self,ruta=None,Nint=10.0): - #comparacion histogramas de tiempos de respuestas - bins=np.arange(0,np.ceil(self.CellTravelTime.max()), - np.ceil(self.CellTravelTime.max())/Nint) - h_lib,b_lib=np.histogram(self.CellTravelTime,bins=bins) - h_lib=h_lib.astype(float)/h_lib.sum() - b_lib=(b_lib[:-1]+b_lib[1:])/2.0 - hc_lib=np.cumsum(h_lib) - fig=pl.figure(facecolor='w',edgecolor='w') - ax=fig.add_subplot(111) - ax.plot(b_lib,h_lib,'b',lw=2,label='Tiempos') - ax2=ax.twinx() - ax2.plot(b_lib,hc_lib,'r',lw=2) - ax2.set_ylim(0,1.1) - ax.set_xlim(0,np.ceil(self.CellTravelTime.max())) - ax.grid(True) - ax.set_xlabel('Tiempo $t [hrs]$',size=14) - ax.set_ylabel('$pdf[\%]$',size=14) - ax2.set_ylabel('$cdf[\%]$',size=14) - ax.set_xticks(b_lib) - ax.legend(loc=4) - if ruta is not None: - pl.savefig(ruta,bbox_inches='tight') - pl.show() - #Plot de curva hipsometrica - def Plot_Hipsometric(self,ruta=None,ventana=10,normed=False, - figsize = (8,6)): - #Suaviza la elevacion en el cuace ppal - elevPpal=pd.Series(self.hipso_ppal[1]) - elevBasin=self.hipso_basin[1] - if normed==True: - elevPpal=elevPpal-elevPpal.min() - elevPpal=(elevPpal/elevPpal.max())*100.0 - elevBasin=elevBasin-elevBasin.min() - elevBasin=(elevBasin/elevBasin.max())*100.0 - elevPpal=pd.rolling_mean(elevPpal,ventana) - ppal_acum=(self.hipso_ppal[0]/self.hipso_ppal[0,-1])*100 - basin_acum=(self.hipso_basin[0]/self.hipso_basin[0,0])*100 - #Genera el plot - fig=pl.figure(edgecolor='w',facecolor='w',figsize = figsize) - ax=fig.add_subplot(111) - #box = ax.get_position() - #ax.set_position([box.x0, box.y0 + box.height * 0.1, - # box.width, box.height * 0.9]) - ax.plot(ppal_acum,elevPpal,c='b',lw=3,label='Cacuce Principal') - ax.plot(basin_acum,elevBasin,c='r',lw=3,label='Cuenca') - ax.tick_params(labelsize = 14) - ax.grid() - ax.set_xlabel('Porcentaje Area Acumulada $[\%]$',size=16) - if normed==False: - ax.set_ylabel('Elevacion $[m.s.n.m]$',size=16) - elif normed==True: - ax.set_ylabel('Elevacion $[\%]$',size=16) - lgn1=ax.legend(loc=0) - if ruta is not None: - pl.savefig(ruta, bbox_inches='tight') - pl.close('all') - else: + if show: pl.show() -class SimuBasin(Basin): + return ax + #Plot de histograma de tiempos de viajes en la cuenca + def Plot_Travell_Hist(self,ruta=None,Nint=10.0): + #comparacion histogramas de tiempos de respuestas + bins=np.arange(0,np.ceil(self.CellTravelTime.max()), + np.ceil(self.CellTravelTime.max())/Nint) + h_lib,b_lib=np.histogram(self.CellTravelTime,bins=bins) + h_lib=h_lib.astype(float)/h_lib.sum() + b_lib=(b_lib[:-1]+b_lib[1:])/2.0 + hc_lib=np.cumsum(h_lib) + fig=pl.figure(facecolor='w',edgecolor='w') + ax=fig.add_subplot(111) + ax.plot(b_lib,h_lib,'b',lw=2,label='Tiempos') + ax2=ax.twinx() + ax2.plot(b_lib,hc_lib,'r',lw=2) + ax2.set_ylim(0,1.1) + ax.set_xlim(0,np.ceil(self.CellTravelTime.max())) + ax.grid(True) + ax.set_xlabel('Tiempo $t [hrs]$',size=14) + ax.set_ylabel('$pdf[\%]$',size=14) + ax2.set_ylabel('$cdf[\%]$',size=14) + ax.set_xticks(b_lib) + ax.legend(loc=4) + if ruta is not None: + pl.savefig(ruta,bbox_inches='tight') + pl.show() + #Plot de curva hipsometrica + def Plot_Hipsometric(self,ruta=None,ventana=10,normed=False, + figsize = (8,6)): + #Suaviza la elevacion en el cuace ppal + elevPpal=pd.Series(self.hipso_ppal[1]) + elevBasin=self.hipso_basin[1] + if normed==True: + elevPpal=elevPpal-elevPpal.min() + elevPpal=(elevPpal/elevPpal.max())*100.0 + elevBasin=elevBasin-elevBasin.min() + elevBasin=(elevBasin/elevBasin.max())*100.0 + elevPpal=pd.rolling_mean(elevPpal,ventana) + ppal_acum=(self.hipso_ppal[0]/self.hipso_ppal[0,-1])*100 + basin_acum=(self.hipso_basin[0]/self.hipso_basin[0,0])*100 + #Genera el plot + fig=pl.figure(edgecolor='w',facecolor='w',figsize = figsize) + ax=fig.add_subplot(111) + #box = ax.get_position() + #ax.set_position([box.x0, box.y0 + box.height * 0.1, + # box.width, box.height * 0.9]) + ax.plot(ppal_acum,elevPpal,c='b',lw=3,label='Cacuce Principal') + ax.plot(basin_acum,elevBasin,c='r',lw=3,label='Cuenca') + ax.tick_params(labelsize = 14) + ax.grid() + ax.set_xlabel('Porcentaje Area Acumulada $[\%]$',size=16) + if normed==False: + ax.set_ylabel('Elevacion $[m.s.n.m]$',size=16) + elif normed==True: + ax.set_ylabel('Elevacion $[\%]$',size=16) + lgn1=ax.legend(loc=0) + if ruta is not None: + pl.savefig(ruta, bbox_inches='tight') + pl.close('all') + else: + pl.show() +class SimuBasin(Basin): + def __init__(self,lat=None,lon=None,DEM=None,DIR=None,rute = None, name='NaN',stream=None, - umbral=500,useCauceMap = None, - noData=-999,modelType='cells',SimSed=False,SimSlides=False,dt=60, - SaveStorage='no',SaveSpeed='no',retorno = 0, - SeparateFluxes = 'no',SeparateRain='no',ShowStorage='no', SimFloods = 'no', - controlNodos = True, storageConstant = 0.001): + umbral=500,useCauceMap = None, + noData=-999,modelType='cells',SimSed=False,SimSlides=False,dt=60, + SaveStorage='no',SaveSpeed='no',retorno = 0, + SeparateFluxes = 'no',SeparateRain='no',ShowStorage='no', SimFloods = 'no', + controlNodos = True, storageConstant = 0.001): 'Descripcion: Inicia un objeto para simulacion \n'\ - ' el objeto tiene las propieades de una cuenca con. \n'\ - ' la diferencia de que inicia las variables requeridas. \n'\ - ' para simular. \n'\ + ' el objeto tiene las propieades de una cuenca con. \n'\ + ' la diferencia de que inicia las variables requeridas. \n'\ + ' para simular. \n'\ '\n'\ 'Parametros\n'\ '----------\n'\ @@ -2723,30 +2723,30 @@ def __init__(self,lat=None,lon=None,DEM=None,DIR=None,rute = None, name='NaN',st 'lat : Coordenada en X de la salida de la cuenca.\n'\ 'lon : Coordenada en Y de la salida de la cuenca.\n'\ 'name : Nombre con el que se va a conocer la cuenca.\n'\ - ' (defecto = NaN).\n'\ + ' (defecto = NaN).\n'\ 'stream : Opcional, si se coloca, las coordenadas no tienen.\n'\ - ' que ser exactas, estas se van a corregir para ubicarse.\n'\ - ' en el punto mas cercano dentro de la corriente, este.\n'\ - ' debe ser un objeto del tipo stream.\n'\ + ' que ser exactas, estas se van a corregir para ubicarse.\n'\ + ' en el punto mas cercano dentro de la corriente, este.\n'\ + ' debe ser un objeto del tipo stream.\n'\ 'useCauceMap: Utiliza un mapa de 1 y 0 representando las celdas que.\n'\ - ' son canal, con este mapa corrige el punto de trazado de la cuenca.\n'\ + ' son canal, con este mapa corrige el punto de trazado de la cuenca.\n'\ 'umbral : Cantidad minima de celdas para la creacion de cauces.\n'\ - ' (defecto = 500 ).\n'\ + ' (defecto = 500 ).\n'\ 'noData : Valor correspondiente a valores sin dato (defecto = -999).\n'\ 'modelType : Tipo de modelo, por celdas o por laderas (defecto = cells).\n'\ - ' opciones: .\n'\ - ' cells => modela por celdas.\n'\ - ' hills => modela por laderas.\n'\ + ' opciones: .\n'\ + ' cells => modela por celdas.\n'\ + ' hills => modela por laderas.\n'\ 'SimSed : Simula si, o no simula sedimentos no.\n'\ 'SimSlides : Simula si, o no simula deslizamientos no.\n'\ 'dt : Tamano del intervlao de tiempo en que trabaj el modelo (defecto=60seg) [secs].\n'\ 'SaveStorage : Guarda o no el almacenamiento.\n'\ 'SaveSpeed : Guarda o no mapas de velocidad.\n'\ 'rute : por defecto es None, si se coloca la ruta, el programa no.\n'\ - ' hace una cuenca, si no que trata de leer una en el lugar especificado.\n'\ - ' Ojo: la cuenca debio ser guardada con la funcion: Save_SimuBasin().\n'\ + ' hace una cuenca, si no que trata de leer una en el lugar especificado.\n'\ + ' Ojo: la cuenca debio ser guardada con la funcion: Save_SimuBasin().\n'\ 'retorno : (defecto = 0), si es cero no se considera alm maximo en .\n'\ - ' el tanque 3, si es 1, si se considera.\n'\ + ' el tanque 3, si es 1, si se considera.\n'\ 'SeparateFluxes : Separa el flujo en base, sub-superficial y escorrentia.\n'\ 'SeparateRain : Separa el flujo proveniente de convectivas y de estratiformes.\n'\ 'ShowStorage : Muestra en la salida del modelo el alm promedio en cada uno de los tanques.\n'\ @@ -2786,19 +2786,10 @@ def __init__(self,lat=None,lon=None,DEM=None,DIR=None,rute = None, name='NaN',st cu.ncols,cu.nrows) self.structure = cu.basin_cut(self.ncells) #Obtiene las propiedades para el tamano de la cuenca. - self.DEMvec = self.Transform_Map2Basin(DEM, - [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy]) - self.DIRvec = self.Transform_Map2Basin(DIR, - [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy]) - # self.DEM,prop =self.Transform_Basin2Map(self.DEMvec) - # self.DIR,prop =self.Transform_Basin2Map(self.DIRvec) - # cu.ncols = prop[0] - # cu.nrows = prop[1] - # cu.xll = prop[2] - # cu.yll = prop[3] - #cu.dx = prop[4] - #cu.dy = prop[5] - #traza las sub-cuencas + self.DEMvec = self.Transform_Map2Basin(DEM, + [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy]) + self.DIRvec = self.Transform_Map2Basin(DIR, + [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy]) acum=cu.basin_acum(self.structure,self.ncells) cauce,nodos,self.nhills = cu.basin_subbasin_nod(self.structure ,acum,umbral,self.ncells) @@ -2823,7 +2814,7 @@ def __init__(self,lat=None,lon=None,DEM=None,DIR=None,rute = None, name='NaN',st models.calc_niter = 5 models.retorno = 0 models.verbose = 0 - #Define los puntos de control + #Define los puntos de control models.control = np.zeros((1,N)) #Si se da la opcion de puntos de control en toda la red lo hace if controlNodos: @@ -2871,12 +2862,12 @@ def __init__(self,lat=None,lon=None,DEM=None,DIR=None,rute = None, name='NaN',st # si hay tura lee todo lo de la cuenca elif rute is not None: self.__Load_SimuBasin(rute, SimSlides) - # Obtiene la envolvente de la cuenca - self.__GetBasinPolygon__() + # Obtiene la envolvente de la cuenca + self.__GetBasinPolygon__() def __Load_SimuBasin(self,ruta, sim_slides = False): 'Descripcion: Lee una cuenca posteriormente guardada\n'\ - ' La cuenca debio ser guardada con SimuBasin.save_SimuBasin\n'\ + ' La cuenca debio ser guardada con SimuBasin.save_SimuBasin\n'\ '\n'\ 'Parametros\n'\ '----------\n'\ @@ -2914,26 +2905,14 @@ def __Load_SimuBasin(self,ruta, sim_slides = False): models.gullienogullie = gr.sl_gullie models.sl_gammaw = gr.sl_gammaw #Nueva metodologia de geoespacial de la cuenca - cu.ncols = gr.ncols - cu.nrows = gr.nrows - cu.xll = gr.xll - cu.yll = gr.yll - cu.dx = gr.dx - cu.dy = gr.dy - #Asigna dem y DIr a partir de la ruta -# try: -# DEM = read_map_raster(gr.DEM,True,gr.dxp) -# DIR = read_map_raster(gr.DIR,True,gr.dxp) -# cu.nodata = -9999.0 -# DIR[DIR<=0]=cu.nodata.astype(int) -# DIR=cu.dir_reclass_rwatershed(DIR,cu.ncols,cu.nrows) -# self.DEM = DEM -# self.DIR = DIR -# except: -# print 'No se encuentran el DEM y el DIR en la ruta:' -# print gr.DEM -# print gr.DIR -# pass + cu.ncols = gr.ncols + cu.nrows = gr.nrows + cu.xll = gr.xll + cu.yll = gr.yll + cu.dx = gr.dx + cu.dy = gr.dy + cu.dxp = gr.dxp + cu.nodata = gr.noData #de acuerdo al tipo de modeloe stablece numero de elem if self.modelType[0] is 'c': N = self.ncells @@ -2943,10 +2922,10 @@ def __Load_SimuBasin(self,ruta, sim_slides = False): self.structure = gr.variables['structure'][:] self.hills = gr.variables['hills'][:] self.hills_own = gr.variables['hills_own'][:] - self.DEMvec = gr.variables['DEM'][:] - self.DIRvec = gr.variables['DIR'][:] - self.DEM = self.Transform_Basin2Map(self.DEMvec) - self.DIR = self.Transform_Basin2Map(self.DIRvec) + self.DEMvec = gr.variables['DEM'][:] + self.DIRvec = gr.variables['DIR'][:] + self.DEM = self.Transform_Basin2Map(self.DEMvec) + self.DIR = self.Transform_Basin2Map(self.DIRvec) #obtiene las propieades del modelo models.h_coef = np.ones((4,N)) * gr.variables['h_coef'][:] models.v_coef = np.ones((4,N)) * gr.variables['v_coef'][:] @@ -2980,70 +2959,69 @@ def __Load_SimuBasin(self,ruta, sim_slides = False): models.sl_frictionangle = np.ones((1,N)) * gr.variables['friction_angle'][:] models.sl_radslope = np.ones((1,N)) * gr.variables['rad_slope'][:] models.sl_zs = np.ones((1,N)) * gr.variables['z_soil'][:] - #Cierra el archivo gr.close() #Determina que por defecto debe estar set la geomorfologia self.isSetGeo = True - + #------------------------------------------------------ # Subrutinas de lluvia, interpolacion, lectura, escritura, agrega funcion para variar evp en - # el tiempo - #------------------------------------------------------ - def __GetEVP_Serie__(self, index): - 'Descripcion: Genera una serie que pondera la evp ' - rng=index - rad=np.zeros(rng.size) - for pos,time in enumerate(rng): - Hora=time - # Dia del Ano - dn = Hora.timetuple().tm_yday - Theta_d = (2 * np.pi * (dn-1))/ 365. - # (d/d)2 - an = [1.000110, 0.034221, 0.000719] - bn = [0, 0.001280, 0.000077] - # - d = 0 - tmp = 0 - for i in range(3): - tmp = (an[i] * np.cos(i*Theta_d)) + (bn[i] * np.sin(i*Theta_d)) - d = d + tmp - # Delta - a_n = [0.006918, -0.399912, -0.006758, -0.002697] - b_n = [0, 0.070257, 0.000907, 0.001480] - # - Delta = 0 - tmp = 0 - for i in range(4): - tmp = (a_n[i] * np.cos(i*Theta_d)) + (b_n[i] * np.sin(i*Theta_d)) - Delta = Delta + tmp - #Angulo horario (cada minuto) - Minutos = (Hora.hour * 60) + Hora.minute - Horario = 180 - (0.25 * Minutos) - Horario = (Horario * np.pi)/180. - # Coseno de Theta - Latitud = (6.2593 * np.pi)/180. - Cos_Theta = (np.sin(Latitud)*np.sin(Delta)) + (np.cos(Latitud)*np.cos(Delta)*np.cos(Horario)) - # Radiacion Teorica - So = 1367 #w/m2 - Q = So * d * Cos_Theta - # Escala entre 0 y 1 - rad_max=1369.8721876806876 - Q=1*Q/rad_max - #Guarda - rad[pos]=Q - #Se vuelven cero los valores negativos. - rad[rad<0]=0 - #Serie - rad=pd.Series(rad,index=rng) - models.evpserie = np.copy(rad.values) - return rad + # el tiempo + #------------------------------------------------------ + def __GetEVP_Serie__(self, index): + '''Descripcion: Genera una serie que pondera la evp ''' + rng=index + rad=np.zeros(rng.size) + for pos,time in enumerate(rng): + Hora=time + # Dia del Ano + dn = Hora.timetuple().tm_yday + Theta_d = (2 * np.pi * (dn-1))/ 365. + # (d/d)2 + an = [1.000110, 0.034221, 0.000719] + bn = [0, 0.001280, 0.000077] + # + d = 0 + tmp = 0 + for i in range(3): + tmp = (an[i] * np.cos(i*Theta_d)) + (bn[i] * np.sin(i*Theta_d)) + d = d + tmp + # Delta + a_n = [0.006918, -0.399912, -0.006758, -0.002697] + b_n = [0, 0.070257, 0.000907, 0.001480] + # + Delta = 0 + tmp = 0 + for i in range(4): + tmp = (a_n[i] * np.cos(i*Theta_d)) + (b_n[i] * np.sin(i*Theta_d)) + Delta = Delta + tmp + #Angulo horario (cada minuto) + Minutos = (Hora.hour * 60) + Hora.minute + Horario = 180 - (0.25 * Minutos) + Horario = (Horario * np.pi)/180. + # Coseno de Theta + Latitud = (6.2593 * np.pi)/180. + Cos_Theta = (np.sin(Latitud)*np.sin(Delta)) + (np.cos(Latitud)*np.cos(Delta)*np.cos(Horario)) + # Radiacion Teorica + So = 1367 #w/m2 + Q = So * d * Cos_Theta + # Escala entre 0 y 1 + rad_max=1369.8721876806876 + Q=1*Q/rad_max + #Guarda + rad[pos]=Q + #Se vuelven cero los valores negativos. + rad[rad<0]=0 + #Serie + rad=pd.Series(rad,index=rng) + models.evpserie = np.copy(rad.values) + return rad def rain_interpolate_mit(self,coord,registers,ruta, umbral = 0.01): 'Descripcion: Interpola la lluvia mediante una malla\n'\ - ' irregular de triangulos, genera campos que son. \n'\ - ' guardados en un binario para luego ser leido por el. \n'\ - ' modelo en el momento de simular. \n'\ + ' irregular de triangulos, genera campos que son. \n'\ + ' guardados en un binario para luego ser leido por el. \n'\ + ' modelo en el momento de simular. \n'\ '\n'\ 'Parametros\n'\ '----------\n'\ @@ -3051,7 +3029,7 @@ def rain_interpolate_mit(self,coord,registers,ruta, umbral = 0.01): 'coord : Array (2,Ncoord) con las coordenadas de estaciones.\n'\ 'registers : Array (Nest,Nregisters) con los registros de lluvia.\n'\ 'ruta : Ruta con nombre en donde se guardara el binario con.\n'\ - ' la informacion de lluvia.\n'\ + ' la informacion de lluvia.\n'\ 'umbral: Umbral a partir del cual se considera que un campo contiene lluvia\n'\ '\n'\ 'Retornos\n'\ @@ -3077,19 +3055,19 @@ def rain_interpolate_mit(self,coord,registers,ruta, umbral = 0.01): y=cu.yll+cu.nrows*cu.dx*j d=np.sqrt((coord[0,:]-x)**2+(coord[1,:]-y)**2) pos=np.argmin(d) - #Actualiza las coordenadas - coord=np.vstack((coord.T,np.array([x,y]))).T + #Actualiza las coordenadas + coord=np.vstack((coord.T,np.array([x,y]))).T #pone lluvia en ese registro reg=np.vstack((reg,reg[pos])) #Obtiene las coordenadas de cada celda de la cuenca x,y = cu.basin_coordxy(self.structure,self.ncells) - xy_basin=np.vstack((x,y)) + xy_basin=np.vstack((x,y)) #Obtiene la malla irregular TIN_mesh=Delaunay(coord.T) TIN_mesh=TIN_mesh.vertices.T+1 #Obtiene las pertenencias en la cuenca a la malla #TIN_perte = models.rain_pre_mit(xy_basin,TIN_mesh,coord,self.ncells, - # TIN_mesh.shape[1],coord.shape[1]) + # TIN_mesh.shape[1],coord.shape[1]) c = 1 TIN_perte = np.zeros((1,self.ncells)) for t in TIN_mesh.T: @@ -3101,12 +3079,12 @@ def rain_interpolate_mit(self,coord,registers,ruta, umbral = 0.01): TIN_perte[0][Contiene == True] = c c+=1 #Revisa si todas las celdas quedaron asignadas - if len(TIN_perte[TIN_perte == 0]) == 0: + if len(TIN_perte[TIN_perte == 0]) == 0: #Selecciona si es por laderas o por celdas - if self.modelType[0] is 'h': + if self.modelType[0] is 'h': maskVector = np.copy(self.hills_own) elif self.modelType[0] is 'c': - maskVector = np.ones(self.ncells) + maskVector = np.ones(self.ncells) #Interpola con tin meanRain,posIds = models.rain_mit(xy_basin, coord, @@ -3120,7 +3098,7 @@ def rain_interpolate_mit(self,coord,registers,ruta, umbral = 0.01): self.ncells, coord.shape[1], TIN_mesh.shape[1], - reg.shape[1]) + reg.shape[1]) #Guarda un archivo con informacion de la lluvia f=open(ruta[:-3]+'hdr','w') f.write('Numero de celdas: %d \n' % self.ncells) @@ -3132,7 +3110,7 @@ def rain_interpolate_mit(self,coord,registers,ruta, umbral = 0.01): if isPandas: dates=registers.index.to_pydatetime() c = 1 - for d,pos,m in zip(dates,posIds,meanRain): + for d,pos,m in zip(dates,posIds,meanRain): f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) c+=1 f.close() @@ -3141,10 +3119,10 @@ def rain_interpolate_mit(self,coord,registers,ruta, umbral = 0.01): print 'Error: Existen celdas de la cuenca sin asignacion de triangulos, se retornan las coordenadas no asignadas' pos = np.where(TIN_perte == 0)[1] return xy_basin[0,pos], xy_basin[1,pos] - + def rain_interpolate_idw(self,coord,registers,ruta,p=1,umbral=0.0): 'Descripcion: Interpola la lluvia mediante la metodologia\n'\ - ' del inverso de la distancia ponderado. \n'\ + ' del inverso de la distancia ponderado. \n'\ '\n'\ 'Parametros\n'\ '----------\n'\ @@ -3153,11 +3131,11 @@ def rain_interpolate_idw(self,coord,registers,ruta,p=1,umbral=0.0): 'registers : DataFrame de pandas (Nest,Nregisters) con los registros de lluvia.\n'\ 'p : exponente para la interpolacion de lluvia.\n'\ 'ruta : Ruta con nombre en donde se guardara el binario con.\n'\ - ' la informacion de lluvia.\n'\ + ' la informacion de lluvia.\n'\ 'umbral : Umbral de suma total de lluvia bajo el cual se considera\n'\ - ' que un intervalo tiene suficiente agua como para generar reaccion\n'\ - ' (umbral = 0.0) a medida que incremente se generaran archivos mas\n'\ - ' livianos, igualmente existe la posibilidad de borrar informacion.\n'\ + ' que un intervalo tiene suficiente agua como para generar reaccion\n'\ + ' (umbral = 0.0) a medida que incremente se generaran archivos mas\n'\ + ' livianos, igualmente existe la posibilidad de borrar informacion.\n'\ '\n'\ 'Retornos\n'\ '----------\n'\ @@ -3178,9 +3156,9 @@ def rain_interpolate_idw(self,coord,registers,ruta,p=1,umbral=0.0): reg=registers #Obtiene las coordenadas de cada celda de la cuenca x,y = cu.basin_coordxy(self.structure,self.ncells) - xy_basin=np.vstack((x,y)) - #Interpola con idw - if self.modelType[0] is 'h': + xy_basin=np.vstack((x,y)) + #Interpola con idw + if self.modelType[0] is 'h': meanRain,posIds = models.rain_idw(xy_basin, coord, reg, p, self.nhills, ruta, umbral, self.hills_own, self.ncells, coord.shape[1],reg.shape[1]) elif self.modelType[0] is 'c': @@ -3202,7 +3180,7 @@ def rain_interpolate_idw(self,coord,registers,ruta,p=1,umbral=0.0): c+=1 f.close() return meanRain,posIds - + def rain_radar2basin_from_asc(self,ruta_in,ruta_out,fechaI,fechaF,dt, pre_string,post_string,fmt = '%Y%m%d%H%M',conv_factor=1.0/12.0, umbral = 0.0): @@ -3238,7 +3216,7 @@ def rain_radar2basin_from_asc(self,ruta_in,ruta_out,fechaI,fechaF,dt, N = self.ncells elif self.modelType[0] is 'h': N = self.nhills - #Guarda la primera entrada como un mapa de ceros + #Guarda la primera entrada como un mapa de ceros models.write_int_basin(ruta_bin,np.zeros((1,N)),1,N,1) #Genera la lista de las fechas. ListDates,dates = __ListaRadarNames__(ruta_in, @@ -3280,6 +3258,7 @@ def rain_radar2basin_from_asc(self,ruta_in,ruta_out,fechaI,fechaF,dt, c+=1 f.close() return np.array(meanRain),np.array(posIds) + def rain_radar2basin_from_array(self,vec=None,ruta_out=None,fecha=None,dt=None, status='update',umbral = 0.01, doit = False): 'Descripcion: Genera campos de lluvia a partir de archivos array\n'\ @@ -3292,10 +3271,10 @@ def rain_radar2basin_from_array(self,vec=None,ruta_out=None,fecha=None,dt=None, 'fecha: Fecha del registro actual.\n'\ 'dt: Intervalo de tiempo entre registros.\n'\ 'status: Estado en el cual se encuentra el binario que se va a pasar a campo.\n'\ - ' update: (Defecto) Con este estado se genera un binario y se agregan nuevos campos.\n'\ - ' old: Estado para abrir y tomar las propiedades de self.radar.. para la generacion de un binario.\n'\ - ' close: Cierra un binario que se ha generado mediante update.\n'\ - ' reset: Reinicia las condiciones de self.radar... para la creacion de un campo nuevo.\n'\ + ' update: (Defecto) Con este estado se genera un binario y se agregan nuevos campos.\n'\ + ' old: Estado para abrir y tomar las propiedades de self.radar.. para la generacion de un binario.\n'\ + ' close: Cierra un binario que se ha generado mediante update.\n'\ + ' reset: Reinicia las condiciones de self.radar... para la creacion de un campo nuevo.\n'\ 'doit: Independiente del umbral escribe el binario en la siguiente entrada.\n'\ 'Retornos\n'\ '----------\n'\ @@ -3321,7 +3300,7 @@ def rain_radar2basin_from_array(self,vec=None,ruta_out=None,fecha=None,dt=None, N = self.nhills try: if vec.shape[0] == self.ncells: - vec = self.Transform_Basin2Hills(vec,sumORmean=1) + vec = self.Transform_Basin2Hills(vec,sumORmean=1) except: pass # De acerudo al estado actualiza las variables o guarda el @@ -3388,7 +3367,7 @@ def rain_radar2basin_from_array(self,vec=None,ruta_out=None,fecha=None,dt=None, for i in a[3]: d = datetime.datetime.strptime(i,'%Y-%m-%d-%H:%M') self.radarDates.append(d) - else: + else: self.radarPos = [int(a[1].split(',')[0])] self.radarMeanRain = [float(a[2].split(',')[0])] self.radarDates = [datetime.datetime.strptime(a[-1], '%Y-%m-%d-%H:%M')] @@ -3396,41 +3375,41 @@ def rain_radar2basin_from_array(self,vec=None,ruta_out=None,fecha=None,dt=None, #------------------------------------------------------ # Subrutinas para preparar modelo - #------------------------------------------------------ + #------------------------------------------------------ def set_Geomorphology(self,umbrales=[30,500],stream_width=None): 'Descripcion: calcula las propiedades geomorfologicas necesarias \n'\ - ' para la simulacion. \n'\ + ' para la simulacion. \n'\ '\n'\ 'Parametros\n'\ '----------\n'\ 'self : Inicia las variables vacias.\n'\ 'umbrales : Lista con la cantidad de celdas necesarias .\n'\ - ' para que una celda sea: ladera, carcava o cauce .\n'\ + ' para que una celda sea: ladera, carcava o cauce .\n'\ 'stream_width = Ancho del canal en cada tramo (opcional).\n'\ '\n'\ 'Retornos\n'\ '----------\n'\ 'self : Con las variables geomorfologicas de simulacion iniciadas.\n'\ - ' models.drena : Numero de celda o ladera destino. \n'\ - ' models.nceldas : Numero de celdas o laderas. \n'\ - ' models.unit_type : tipo de celda, en el caso de ladera no aplica.\n'\ - ' 1: Celda tipo ladera.\n'\ - ' 2: Celda tipo transitorio.\n'\ - ' 3: Celda tipo cauce.\n'\ - ' models.hill_long : Longitud promedio de la ladera (o celda). \n'\ - ' - Celdas: Longitud de cada elemento (cu.dxp) para ortogonal y 1.43*cu.dxp para diagonal. \n'\ - ' - Laderas: Promedio de las longitudes recorridas entre una celda y la corriente de la ladera. \n'\ - ' models.hill_slope : Pendiente de cada ladera (promedio) o celda.\n'\ - ' models.stream_long : Longitud de cada tramo de cuace. \n'\ - ' - Celdas: Es cu.dxp: ortogonal, 1.42*cu.dxp: Diagonal. \n'\ - ' - Laderas: Es la Longitud de los elementos del cauce que componen la ladera. \n'\ - ' models.stream_slope : Pendiente de cada tramo de cauce. \n'\ - ' - Celdas: Es la pendiente estimada por self.GetGeo_Cell_Basics(). \n'\ - ' - Laderas: Pendiente promedio de las laderas. \n'\ - ' models.stream_width : Ancho de cada tramo de cauce. \n'\ - ' - Celdas: No aplica y se hacen todos iguales a la unidad. \n'\ - ' - Laderas: Es el ancho del canal calculado a partir de geomrofologia o entregado. \n'\ - ' models.elem_area : Area de cada celda (cu.dxp**2) o ladera (nceldasLadera * cu.dxp**2). \n'\ + ' models.drena : Numero de celda o ladera destino. \n'\ + ' models.nceldas : Numero de celdas o laderas. \n'\ + ' models.unit_type : tipo de celda, en el caso de ladera no aplica.\n'\ + ' 1: Celda tipo ladera.\n'\ + ' 2: Celda tipo transitorio.\n'\ + ' 3: Celda tipo cauce.\n'\ + ' models.hill_long : Longitud promedio de la ladera (o celda). \n'\ + ' - Celdas: Longitud de cada elemento (cu.dxp) para ortogonal y 1.43*cu.dxp para diagonal. \n'\ + ' - Laderas: Promedio de las longitudes recorridas entre una celda y la corriente de la ladera. \n'\ + ' models.hill_slope : Pendiente de cada ladera (promedio) o celda.\n'\ + ' models.stream_long : Longitud de cada tramo de cuace. \n'\ + ' - Celdas: Es cu.dxp: ortogonal, 1.42*cu.dxp: Diagonal. \n'\ + ' - Laderas: Es la Longitud de los elementos del cauce que componen la ladera. \n'\ + ' models.stream_slope : Pendiente de cada tramo de cauce. \n'\ + ' - Celdas: Es la pendiente estimada por self.GetGeo_Cell_Basics(). \n'\ + ' - Laderas: Pendiente promedio de las laderas. \n'\ + ' models.stream_width : Ancho de cada tramo de cauce. \n'\ + ' - Celdas: No aplica y se hacen todos iguales a la unidad. \n'\ + ' - Laderas: Es el ancho del canal calculado a partir de geomrofologia o entregado. \n'\ + ' models.elem_area : Area de cada celda (cu.dxp**2) o ladera (nceldasLadera * cu.dxp**2). \n'\ #Obtiene lo basico para luego pasar argumentos acum,hill_long,pend,elev = cu.basin_basics(self.structure, self.DEMvec,self.DIRvec,self.ncells) @@ -3439,7 +3418,7 @@ def set_Geomorphology(self,umbrales=[30,500],stream_width=None): self.structure,acum,umbrales[1],self.ncells) stream_s,stream_l = cu.basin_stream_slope( self.structure,elev,hill_long,nodos,n_cauce,self.ncells) - stream_s[np.isnan(stream_s)]=self.nodata + stream_s[np.isnan(stream_s)]=self.nodata #Obtiene para metros por subn cuencas sub_horton,nod_horton = cu.basin_subbasin_horton(self.hills,self.ncells, self.hills.shape[1]) @@ -3484,27 +3463,28 @@ def set_Geomorphology(self,umbrales=[30,500],stream_width=None): models.elem_area = np.ones((1,N))*np.array([self.hills_own[self.hills_own==i].shape[0] for i in range(1,self.hills.shape[1]+1)])*cu.dxp**2.0 #Ajusta variable de que la geomorfologia esta calculada self.isSetGeo = True + def set_Speed_type(self,types=np.ones(3)): 'Descripcion: Especifica el tipo de velocidad a usar en cada \n'\ - ' nivel del modelo. \n'\ + ' nivel del modelo. \n'\ '\n'\ 'Parametros\n'\ '----------\n'\ 'self : Inicia las variables vacias.\n'\ 'types : tipos de velocidad .\n'\ - ' 1. Velocidad tipo embalse lineal, no se especifica h_exp.\n'\ - ' 2. Velocidad onda cinematica, se debe especificar h_exp.\n'\ + ' 1. Velocidad tipo embalse lineal, no se especifica h_exp.\n'\ + ' 2. Velocidad onda cinematica, se debe especificar h_exp.\n'\ '\n'\ 'Retornos\n'\ '----------\n'\ 'self : Con la variable models.speed_type especificada.\n'\ - #Especifica la ecuacion de velocidad a usar en cada nivel del modelo + #Especifica la ecuacion de velocidad a usar en cada nivel del modelo for c,i in enumerate(types): if i==1 or i==2: models.speed_type[c]=i else: - models.speed_type[c]=1 - + models.speed_type[c]=1 + def set_Floods(self,var,VarName, umbral = 1000, NumCeldas = 6, Default = False): 'Descripcion: Aloja las variables del sub modelo de inundaciones\n'\ '\n'\ @@ -3513,28 +3493,28 @@ def set_Floods(self,var,VarName, umbral = 1000, NumCeldas = 6, Default = False): '----------\n'\ 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ 'varName: Nombre de la variable a ingresar en el modelo.\n'\ - ' GammaWater : Densidad del agua (Defecto: 1000).\n'\ - ' GammaSoil : Densidad del sedimento (Defecto: 2600).\n'\ - ' VelArea: Factor conversion Velocidad - Area (Defecto: 1/200).\n'\ - ' Cmax: Maxima concentracion de sedimentos (Defecto 0.75).\n'\ - ' MaxIter: Cantidad maxima de iteraciones para obtener la mancha de inunudacion.\n'\ - ' VelUmbral: Velocidad minima para que se de el flujo de escombros ( Defecto: 3 m/s).\n'\ - ' Stream_W: Ancho del canal en cada celda (ncells).\n'\ - ' Stream_D50: Tamano de particula percentil 50 (ncells).\n'\ - ' HAND: Modelo de elevacion relativa de celda ladera a celda cauce (ncells), no se ponde nada.\n'\ - ' umbral: Umbral para determinar corriente segun HAND debe coincidir con el umbral del modelo.\n'\ - ' Slope: Pendiente del canal, (no se ponde variable)\n'\ - ' Default: Poner o no parametros por defecto (False)\n'\ + ' GammaWater : Densidad del agua (Defecto: 1000).\n'\ + ' GammaSoil : Densidad del sedimento (Defecto: 2600).\n'\ + ' VelArea: Factor conversion Velocidad - Area (Defecto: 1/200).\n'\ + ' Cmax: Maxima concentracion de sedimentos (Defecto 0.75).\n'\ + ' MaxIter: Cantidad maxima de iteraciones para obtener la mancha de inunudacion.\n'\ + ' VelUmbral: Velocidad minima para que se de el flujo de escombros ( Defecto: 3 m/s).\n'\ + ' Stream_W: Ancho del canal en cada celda (ncells).\n'\ + ' Stream_D50: Tamano de particula percentil 50 (ncells).\n'\ + ' HAND: Modelo de elevacion relativa de celda ladera a celda cauce (ncells), no se ponde nada.\n'\ + ' umbral: Umbral para determinar corriente segun HAND debe coincidir con el umbral del modelo.\n'\ + ' Slope: Pendiente del canal, (no se ponde variable)\n'\ + ' Default: Poner o no parametros por defecto (False)\n'\ 'Retornos\n'\ '----------\n'\ 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ - ' wmf.models.flood_dw.\n'\ - ' wmf.models.flood_dsed.\n'\ - ' wmf.models.flood_av.\n'\ - ' wmf.models.flood_cmax.\n'\ - ' wmf.models.flood_d50.\n'\ - ' wmf.models.flood_hand.\n'\ - ' wmf.models.flood_aquien.\n'\ + ' wmf.models.flood_dw.\n'\ + ' wmf.models.flood_dsed.\n'\ + ' wmf.models.flood_av.\n'\ + ' wmf.models.flood_cmax.\n'\ + ' wmf.models.flood_d50.\n'\ + ' wmf.models.flood_hand.\n'\ + ' wmf.models.flood_aquien.\n'\ #Si el modelo es tipo ladera agrega la variable if self.modelType[0] == 'h': return 'El modelo por laderas no simula inundaciones.' @@ -3558,7 +3538,7 @@ def set_Floods(self,var,VarName, umbral = 1000, NumCeldas = 6, Default = False): elif type(var) is int or float: Vec = np.ones((1,self.ncells))*var isVec=True - elif type(var) is np.ndarray and var.shape[0] == self.ncells: + elif type(var) is np.ndarray and var.shape[0] == self.ncells: Vec = var isVec=True #finalmente mete la variable en el modelo @@ -3568,7 +3548,7 @@ def set_Floods(self,var,VarName, umbral = 1000, NumCeldas = 6, Default = False): elif VarName is 'Stream_D50': models.flood_d50 = np.ones((1,N))*Vec elif VarName is 'HAND': - self.GetGeo_HAND(umbral = umbral) + self.GetGeo_HAND(umbral = umbral) models.flood_hand = np.ones((1,N))*np.copy(self.CellHAND) models.flood_aquien = np.ones((1,N))*np.copy(self.CellHAND_drainCell) elif VarName is 'Slope': @@ -3590,41 +3570,41 @@ def set_Floods(self,var,VarName, umbral = 1000, NumCeldas = 6, Default = False): models.flood_umbral = var elif VarName == 'MaxIter': models.flood_max_iter = var - + def set_PhysicVariables(self,modelVarName,var,pos,mask=None): 'Descripcion: Coloca las variables fisicas en el modelo \n'\ - ' Se debe assignarel nombre del tipo de variable, la variable\n'\ - ' y la posicion en que esta va a ser insertada\n'\ + ' Se debe assignarel nombre del tipo de variable, la variable\n'\ + ' y la posicion en que esta va a ser insertada\n'\ '\n'\ 'Parametros\n'\ '----------\n'\ 'self : Objeto de la cuenca 2que luego se va a simular.\n'\ 'modelVarName : Nombre de la variable del modelo que se va a incertar.\n'\ - ' - h_coef: coeficientes horizontales\n'\ - ' [0]: Flujo de Escorrentia.\n'\ - ' [1]: Flujo Sub-superficial.\n'\ - ' [2]: Flujo subterraneo.\n'\ - ' [3]: Flujo en cauces.\n'\ - ' - h_exp: exponentes del tipo v = h_coef*(A**h_exp)\n'\ - ' [0]: Escorrentia.\n'\ - ' [1]: sub-superficial.\n'\ - ' [2]: subterraneo.\n'\ - ' [3]: cauce.\n'\ - ' - v_coef.\n'\ - ' [0]: Tasa evaporacion.\n'\ - ' [1]: Infiltracion.\n'\ - ' [2]: Percolacion.\n'\ - ' [3]: Perdidas (0).\n'\ - ' - v_exp: procesos verticales no lineales\n'\ - ' (no implementado dentro del modelo)\n' - ' - capilar.\n'\ - ' - gravit.\n'\ + ' - h_coef: coeficientes horizontales\n'\ + ' [0]: Flujo de Escorrentia.\n'\ + ' [1]: Flujo Sub-superficial.\n'\ + ' [2]: Flujo subterraneo.\n'\ + ' [3]: Flujo en cauces.\n'\ + ' - h_exp: exponentes del tipo v = h_coef*(A**h_exp)\n'\ + ' [0]: Escorrentia.\n'\ + ' [1]: sub-superficial.\n'\ + ' [2]: subterraneo.\n'\ + ' [3]: cauce.\n'\ + ' - v_coef.\n'\ + ' [0]: Tasa evaporacion.\n'\ + ' [1]: Infiltracion.\n'\ + ' [2]: Percolacion.\n'\ + ' [3]: Perdidas (0).\n'\ + ' - v_exp: procesos verticales no lineales\n'\ + ' (no implementado dentro del modelo)\n' + ' - capilar.\n'\ + ' - gravit.\n'\ 'var : variable que ingresa en el modelo, esta puede ser:.\n'\ - ' - Ruta: una ruta del tipo string.\n'\ - ' - Escalar : Un valor escalar que se asignara a toda la cuenca.\n'\ - ' - Vector : Un vector con la informacion leida (1,ncells).\n'\ + ' - Ruta: una ruta del tipo string.\n'\ + ' - Escalar : Un valor escalar que se asignara a toda la cuenca.\n'\ + ' - Vector : Un vector con la informacion leida (1,ncells).\n'\ 'pos : Posicion de insercion, aplica para : h_coef, v_coef,.\n'\ - ' h_exp, v_exp.\n'\ + ' h_exp, v_exp.\n'\ '\n'\ 'Retornos\n'\ '----------\n'\ @@ -3635,7 +3615,7 @@ def set_PhysicVariables(self,modelVarName,var,pos,mask=None): 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ 'rain_read_bin: Lee binario de registros para ver que tiene.\n'\ 'rain_ncf2bin: Convierte ncf a binario en formato del modelo (para imagenes de radar).\n'\ - + #Obtiene el vector que va a alojar en el modelo isVec=False if type(var) is str: @@ -3646,7 +3626,7 @@ def set_PhysicVariables(self,modelVarName,var,pos,mask=None): elif type(var) is int or float: Vec = np.ones((1,self.ncells))*var isVec=True - elif type(var) is np.ndarray and var.shape[0] == self.ncells: + elif type(var) is np.ndarray and var.shape[0] == self.ncells: Vec = var isVec=True #Si el modelo es tipo ladera agrega la variable @@ -3665,26 +3645,27 @@ def set_PhysicVariables(self,modelVarName,var,pos,mask=None): models.max_capilar[0] = Vec elif modelVarName is 'gravit': models.max_gravita[0] = Vec + def set_Storage(self,var,pos,hour_scale=False): 'Descripcion: \n'\ - ' Establece el almacenamiento inicial del modelo\n'\ - ' la variable puede ser un valor, una ruta o un vector.\n'\ + ' Establece el almacenamiento inicial del modelo\n'\ + ' la variable puede ser un valor, una ruta o un vector.\n'\ '\n'\ 'Parametros\n'\ '----------\n'\ 'var : Variable con la cual se va a iniciar el almancenamiento.\n'\ - ' - ruta : es una ruta a un archivo binario de almacenamiento.\n'\ - ' - escalar : valor de almacenamiento constate para toda la cuenca.\n'\ - ' - vector : Vector con valores para cadda unidad de la cuenca.\n'\ + ' - ruta : es una ruta a un archivo binario de almacenamiento.\n'\ + ' - escalar : valor de almacenamiento constate para toda la cuenca.\n'\ + ' - vector : Vector con valores para cadda unidad de la cuenca.\n'\ 'pos : Posicion de insercion,.\n'\ - ' - 0 : alm cpailar.\n'\ - ' - 1 : alm superficial.\n'\ - ' - 2 : alm sub-superficial.\n'\ - ' - 3 : alm subterraneo.\n'\ - ' - 4 : alm cauce.\n'\ - ' - fecha: en caso de que var sea la ruta a StOhdr:\n'\ - ' - valor: puede ser un entero con la posicion.\n'\ - ' - str fecha: puede ser un srint con la fecha: YYYY-MM-DD-HH:MM :\n'\ + ' - 0 : alm cpailar.\n'\ + ' - 1 : alm superficial.\n'\ + ' - 2 : alm sub-superficial.\n'\ + ' - 3 : alm subterraneo.\n'\ + ' - 4 : alm cauce.\n'\ + ' - fecha: en caso de que var sea la ruta a StOhdr:\n'\ + ' - valor: puede ser un entero con la posicion.\n'\ + ' - str fecha: puede ser un srint con la fecha: YYYY-MM-DD-HH:MM :\n'\ 'hour_scale: Buscar fechas a escala horaria o minutos?.\n'\ '\n'\ 'Retornos\n'\ @@ -3723,22 +3704,20 @@ def set_Storage(self,var,pos,hour_scale=False): Vec,res = models.read_float_basin_ncol(var_bin,posFecha+1,N,5) isVec=True for p in range(5): - models.storage[p] = Vec[p] + models.storage[p] = Vec[p] elif type(var) is int or float: Vec = np.ones((1,N))*var isVec=True models.storage[pos] = Vec - elif type(var) is np.ndarray and var.shape[0] == N: + elif type(var) is np.ndarray and var.shape[0] == N: Vec = var isVec=True models.storage[pos] = Vec - - def set_Control(self,coordXY,ids,tipo = 'Q'): 'Descripcion: \n'\ - ' Establece los puntos deonde se va a realizar control del caudal\n'\ - ' y de la humedad simulada.\n'\ + ' Establece los puntos deonde se va a realizar control del caudal\n'\ + ' y de la humedad simulada.\n'\ '\n'\ 'Parametros\n'\ '----------\n'\ @@ -3749,8 +3728,8 @@ def set_Control(self,coordXY,ids,tipo = 'Q'): 'Retornos\n'\ '----------\n'\ 'Define los puntos de control en las variables:\n'\ - ' - models.control : control de caudal y sedimentos.\n'\ - ' - models.control_h : control de la humedad del suelo.\n'\ + ' - models.control : control de caudal y sedimentos.\n'\ + ' - models.control_h : control de la humedad del suelo.\n'\ 'IdsControl : El orden en que quedaron los puntos de control al interior.\n'\ '\n'\ 'Mirar Tambien\n'\ @@ -3767,7 +3746,7 @@ def set_Control(self,coordXY,ids,tipo = 'Q'): pos = self.hills_own * self.CellCauce * unitario posGrande = self.hills_own * self.CellCauce * basinPts IdsConvert = posGrande[posGrande<>0] / pos[pos<>0] - models.control[0][pos[pos<>0].astype(int).tolist()] = IdsConvert + models.control[0][pos[pos<>0].astype(int).tolist()] = IdsConvert elif tipo is 'H': xyNew = coordXY basinPts, order = self.Points_Points2Basin(coordXY,ids) @@ -3781,39 +3760,39 @@ def set_Control(self,coordXY,ids,tipo = 'Q'): IdsConvert = posGrande[posGrande<>0] / pos[pos<>0] models.control_h[0][pos[pos<>0].astype(int).tolist()] = IdsConvert return IdsConvert,xyNew - - + + def set_sediments(self,var,VarName, wi = [0.036, 2.2e-4, 8.6e-7], diametro = [0.35, 0.016, 0.001], G = 9.8): 'Descripcion: Alojas las variables requeridas para la ejecucion\n'\ - ' del modelo de sedimentos.\n'\ + ' del modelo de sedimentos.\n'\ '\n'\ 'Parametros\n'\ '----------\n'\ 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ 'varName: Nombre de la variable a ingresar en el modelo.\n'\ - ' Krus : Erosividad del suelo (RUSLE).\n'\ - ' Crus : Cobertura del suelo (RUSLE).\n'\ - ' Prus : Practicas proteccion (RUSLE).\n'\ - ' PArLiAc : Porcentaje Arenas, Limos y Arcillas.\n'\ - ' wi : velocidad de caida de cada particula de sed [m/s].\n'\ - ' diametro : diametro de cada tipo de sedimento [mm].\n'\ + ' Krus : Erosividad del suelo (RUSLE).\n'\ + ' Crus : Cobertura del suelo (RUSLE).\n'\ + ' Prus : Practicas proteccion (RUSLE).\n'\ + ' PArLiAc : Porcentaje Arenas, Limos y Arcillas.\n'\ + ' wi : velocidad de caida de cada particula de sed [m/s].\n'\ + ' diametro : diametro de cada tipo de sedimento [mm].\n'\ '\n'\ 'Retornos\n'\ '----------\n'\ 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ - ' wmf.models.krus.\n'\ - ' wmf.models.crus.\n'\ - ' wmf.models.prus.\n'\ - ' wmf.models.parliac.\n'\ - ' wmf.models.wi.\n'\ - ' wmf.models.diametro.\n'\ - #Determina el tipo de unidades del modelo + ' wmf.models.krus.\n'\ + ' wmf.models.crus.\n'\ + ' wmf.models.prus.\n'\ + ' wmf.models.parliac.\n'\ + ' wmf.models.wi.\n'\ + ' wmf.models.diametro.\n'\ + #Determina el tipo de unidades del modelo if self.modelType[0] is 'c': N = self.ncells elif self.modelType[0] is 'h': N = self.nhills - #Se fija que tipo de variable es + #Se fija que tipo de variable es isVec=False if type(var) is str: #Si es un string lee el mapa alojado en esa ruta @@ -3829,44 +3808,44 @@ def set_sediments(self,var,VarName, wi = [0.036, 2.2e-4, 8.6e-7], #Si el modelo es tipo ladera agrega la variable if self.modelType[0] is 'h': Vec = self.Transform_Basin2Hills(Vec,mask=mask) - #Inicia las variables + #Inicia las variables if VarName == 'Krus': - models.krus = np.ones((1,N))*Vec - if VarName == 'Prus': - models.prus = np.ones((1,N))*Vec - if VarName == 'Crus': - models.crus = np.ones((1,N))*Vec - if VarName == 'PArLiAc': - models.parliac = np.ones((3,N))*Vec - #Variables de diametro y velocidad de caida - models.wi = wi - models.diametro = diametro - models.g = G - + models.krus = np.ones((1,N))*Vec + if VarName == 'Prus': + models.prus = np.ones((1,N))*Vec + if VarName == 'Crus': + models.crus = np.ones((1,N))*Vec + if VarName == 'PArLiAc': + models.parliac = np.ones((3,N))*Vec + #Variables de diametro y velocidad de caida + models.wi = wi + models.diametro = diametro + models.g = G + def set_Slides(self,var,VarName): 'Descripcion: Alojas las variables requeridas para la ejecucion\n'\ - ' del modelo de deslizamientos.\n'\ + ' del modelo de deslizamientos.\n'\ '\n'\ 'Parametros\n'\ '----------\n'\ 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ 'varName: Nombre de la variable a ingresar en el modelo.\n'\ - ' Zs : Profundidad del suelo.\n'\ - ' GammaSoil: Densidad del suelo.\n'\ - ' Cohesion: Cohesion del suelo.\n'\ - ' FrictionAngle : Angulo de friccion del suelo.\n'\ - ' FS: Factor de Seguridad, en este caso se envia una constante.\n'\ - ' RadSlope : .\n'\ + ' Zs : Profundidad del suelo.\n'\ + ' GammaSoil: Densidad del suelo.\n'\ + ' Cohesion: Cohesion del suelo.\n'\ + ' FrictionAngle : Angulo de friccion del suelo.\n'\ + ' FS: Factor de Seguridad, en este caso se envia una constante.\n'\ + ' RadSlope : .\n'\ '\n'\ 'Retornos\n'\ '----------\n'\ 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ - ' wmf.models.sl_zs.\n'\ - ' wmf.models.sl_gammas.\n'\ - ' wmf.models.sl_cohesion.\n'\ - ' wmf.models.sl_frictionangle.\n'\ - ' wmf.models.sl_radslope.\n'\ - ' wmf.models.sl_fs.\n'\ + ' wmf.models.sl_zs.\n'\ + ' wmf.models.sl_gammas.\n'\ + ' wmf.models.sl_cohesion.\n'\ + ' wmf.models.sl_frictionangle.\n'\ + ' wmf.models.sl_radslope.\n'\ + ' wmf.models.sl_fs.\n'\ #Pone el gamma del agua por defecto models.sl_gammaw = 9.8 #Obtiene el vector que va a alojar en el modelo @@ -3880,7 +3859,7 @@ def set_Slides(self,var,VarName): elif type(var) is int or float: Vec = np.ones((1,self.ncells))*var isVec=True - elif type(var) is np.ndarray and var.shape[0] == self.ncells: + elif type(var) is np.ndarray and var.shape[0] == self.ncells: Vec = var isVec=True #Si el modelo es tipo ladera agrega la variable @@ -3903,7 +3882,7 @@ def set_Slides(self,var,VarName): models.sl_radslope[models.sl_radslope == 0] = 0.01 #------------------------------------------------------ # Guardado y Cargado de modelos de cuencas preparados - #------------------------------------------------------ + #------------------------------------------------------ def Save_SimuBasin(self,ruta,SimSlides = False, ExtraVar = None): 'Descripcion: guarda una cuenca previamente ejecutada\n'\ @@ -3914,10 +3893,10 @@ def Save_SimuBasin(self,ruta,SimSlides = False, 'ruta_dem : direccion donde se aloja el DEM (se recomienda absoluta).\n'\ 'ruta_dir : direccion donde se aloja el DIR (se recomienda absoluta).\n'\ 'SimSlides: indica a la funcion si va a guardar o no informacion para la simulacion.\n'\ - ' de deslizamientos.\n'\ + ' de deslizamientos.\n'\ 'ExtraVar: Variables extras de simulacion deben ir en un diccionario.\n'\ - ' Forma del diccionario Dict = {"varName": {"Data": vector[ncells], "type": "tipo"}}.\n'\ - ' Los tipos de variables son: flotante: "f4", entero "i4".\n'\ + ' Forma del diccionario Dict = {"varName": {"Data": vector[ncells], "type": "tipo"}}.\n'\ + ' Los tipos de variables son: flotante: "f4", entero "i4".\n'\ '\n'\ 'Retornos\n'\ '----------\n'\ @@ -3932,24 +3911,24 @@ def Save_SimuBasin(self,ruta,SimSlides = False, elif self.modelType[0] is 'h': N = self.nhills Dict = {'nombre':self.name, - 'modelType':self.modelType,'noData':self.nodata,'umbral':self.umbral, - 'ncells':self.ncells,'nhills':self.nhills, - 'dt':models.dt,'Nelem':N,'dxp':cu.dxp,'retorno':models.retorno, - 'storageConst' :models.storage_constant, - 'ncols':cu.ncols, - 'nrows':cu.nrows, - 'xll':cu.xll, - 'yll':cu.yll, - 'dx':cu.dx, - 'dy':cu.dy, - 'epsg': self.epsg} + 'modelType':self.modelType,'noData':cu.nodata,'umbral':self.umbral, + 'ncells':self.ncells,'nhills':self.nhills, + 'dt':models.dt,'Nelem':N,'dxp':cu.dxp,'retorno':models.retorno, + 'storageConst' :models.storage_constant, + 'ncols':cu.ncols, + 'nrows':cu.nrows, + 'xll':cu.xll, + 'yll':cu.yll, + 'dx':cu.dx, + 'dy':cu.dy, + 'epsg': self.epsg} if SimSlides: Dict.update({'sl_fs':models.sl_fs, 'sl_gullie':models.sl_gullienogullie, 'sl_gammaw':models.sl_gammaw}) #abre el archivo gr = netcdf.Dataset(ruta,'w',format='NETCDF4') #Variables del DEM y del DIR - #DEMdim = gr.createDimension('ncols',DEM - #Establece tamano de las variables + #DEMdim = gr.createDimension('ncols',DEM + #Establece tamano de las variables DimNcell = gr.createDimension('ncell',self.ncells) DimNhill = gr.createDimension('nhills',self.nhills) DimNelem = gr.createDimension('Nelem',N) @@ -4035,64 +4014,63 @@ def Save_SimuBasin(self,ruta,SimSlides = False, gr.close() #Sale del programa return - - #------------------------------------------------------ - # Ejecucion del modelo - #------------------------------------------------------ + + #------------------------------------------------------ + # Ejecucion del modelo + #------------------------------------------------------ def run_shia(self,Calibracion, rain_rute, N_intervals, start_point = 1, StorageLoc = None, HspeedLoc = None,ruta_storage = None, ruta_speed = None, - ruta_conv = None, ruta_stra = None, ruta_retorno = None,kinematicN = 5, - QsimDataFrame = True, EvpVariable = False): + ruta_conv = None, ruta_stra = None, ruta_retorno = None,kinematicN = 5, QsimDataFrame = True, EvpVariable = False): 'Descripcion: Ejecuta el modelo una ves este es preparado\n'\ - ' Antes de su ejecucion se deben tener listas todas las . \n'\ - ' variables requeridas . \n'\ + ' Antes de su ejecucion se deben tener listas todas las . \n'\ + ' variables requeridas . \n'\ '\n'\ 'Parametros\n'\ '----------\n'\ 'self : Cuenca a ejecutar con todo listo para ser ejecutada.\n'\ 'Calibracion : Parametros de calibracion del modelo, orden:.\n'\ - ' - Evaporacion.\n'\ - ' - Infiltracion.\n'\ - ' - Percolacion.\n'\ - ' - Perdidas.\n'\ - ' - Vel Superficial .\n'\ - ' - Vel Sub-superficial.\n'\ - ' - Vel Subterranea.\n'\ - ' - Vel Cauce.\n'\ - ' - Max Capilar.\n'\ - ' - Max Gravitacional.\n'\ + ' - Evaporacion.\n'\ + ' - Infiltracion.\n'\ + ' - Percolacion.\n'\ + ' - Perdidas.\n'\ + ' - Vel Superficial .\n'\ + ' - Vel Sub-superficial.\n'\ + ' - Vel Subterranea.\n'\ + ' - Vel Cauce.\n'\ + ' - Max Capilar.\n'\ + ' - Max Gravitacional.\n'\ 'rain_rute : Ruta donde se encuentra el archivo binario de lluvia:.\n'\ - ' generado por rain_interpolate_* o por rain_radar2basin.\n'\ + ' generado por rain_interpolate_* o por rain_radar2basin.\n'\ 'N_intervals : Numero de intervalos de tiempo.\n'\ 'start_point : Punto donde comienza a usar registros de lluvia.\n'\ - ' los binarios generados por rain_* generan un archivo de texto.\n'\ - ' que contiene fechas par aayudar a ubicar el punto de inicio deseado.\n'\ + ' los binarios generados por rain_* generan un archivo de texto.\n'\ + ' que contiene fechas par aayudar a ubicar el punto de inicio deseado.\n'\ 'StorageLoc: Variable local de almacenamiento, esto es en el caso de que no se.\n'\ - ' desee usar la configuracion global de almacenamiento del modelo (5, N).\n'\ + ' desee usar la configuracion global de almacenamiento del modelo (5, N).\n'\ 'HspeedLoc: Variable local para setear la velocidad horizontal inicial de ejecucion.\n'\ 'ruta_storage : Ruta donde se guardan los estados del modelo en cada intervalo.\n'\ - ' de tiempo, esta es opcional, solo se guardan si esta variable es asignada.\n'\ + ' de tiempo, esta es opcional, solo se guardan si esta variable es asignada.\n'\ 'ruta_conv : Ruta al binario y hdr indicando las nubes que son convectivas.\n'\ 'ruta_stra : Ruta al binario y hdr indicando las nubes que son estratiformes.\n'\ 'ruta_retorno : Ruta al binario y hdr en donde escribe la serie con los milimetros retornados al tanque runoff.\n'\ 'kinematicN: Cantidad de iteraciones para la solucion de la onda cinematica.\n'\ - ' De forma continua: 5 iteraciones, recomendado para cuando el modelo se\n'\ - ' ejecuta en forma continua Ej: cu.run_shia(Calib, rain_rute, 100)\n'\ - ' Por intervalos: 10 iteraciones, recomendado cuando el modelo se ejecuta\n'\ - ' por intervalos de un paso ej:\n'\ - ' for i in range(1,N)\n'\ - ' Results = cu.run_shia(Calib, ruta_rain, 1, i)\n'\ - ' for c,j in enumerate(Results[''Storage'']):\n'\ - ' cu.set_Storage(j,c)\n'\ + ' De forma continua: 5 iteraciones, recomendado para cuando el modelo se\n'\ + ' ejecuta en forma continua Ej: cu.run_shia(Calib, rain_rute, 100)\n'\ + ' Por intervalos: 10 iteraciones, recomendado cuando el modelo se ejecuta\n'\ + ' por intervalos de un paso ej:\n'\ + ' for i in range(1,N)\n'\ + ' Results = cu.run_shia(Calib, ruta_rain, 1, i)\n'\ + ' for c,j in enumerate(Results[''Storage'']):\n'\ + ' cu.set_Storage(j,c)\n'\ 'QsimDataFrame: Retorna un data frame con los caudales simulados indicando su id de acuerdo con el\n'\ - ' que guarda la funcion Save_Net2Map con la opcion NumTramo = True. \n'\ - 'EvpVariable: (False) Asume que la evp del modelo cambia en funcion o no de la radiacion\n'\ + ' que guarda la funcion Save_Net2Map con la opcion NumTramo = True. \n'\ + 'EvpVariable: (False) Asume que la evp del modelo cambia en funcion o no de la radiacion\n'\ '\n'\ 'Retornos\n'\ '----------\n'\ 'Qsim : Caudal simulado en los puntos de control.\n'\ 'Hsim : Humedad simulada en los puntos de control.\n'\ - #genera las rutas + #genera las rutas rain_ruteBin,rain_ruteHdr = __Add_hdr_bin_2route__(rain_rute) #Obtiene las fechas Rain = read_mean_rain(rain_ruteHdr, N_intervals, start_point) @@ -4165,11 +4143,11 @@ def run_shia(self,Calibracion, else: HspeedLoc = np.zeros((4,N))*-9999.0 #Implementa o no la EVP variable en funcion de la radiacion - if EvpVariable: - Rad = self.__GetEVP_Serie__(Rain.index) - else: - models.evpserie = np.ones(N_intervals) - # Ejecuta el modelo + if EvpVariable: + Rad = self.__GetEVP_Serie__(Rain.index) + else: + models.evpserie = np.ones(N_intervals) + # Ejecuta el modelo Qsim,Qsed,Qseparated,Humedad,St1,St3,Balance,Speed,Area,Alm,Qsep_byrain = models.shia_v1( rain_ruteBin, rain_ruteHdr, @@ -4243,7 +4221,7 @@ def run_shia(self,Calibracion, #Campo de lluvia acumulado para el evento Retornos.update({'Rain_Acum': models.acum_rain}) - Retornos.update({'Rain_hietogram': models.mean_rain}) + Retornos.update({'Rain_hietogram': models.mean_rain}) #Retornos en caso de simular deslizamientos if models.sim_slides == 1: Retornos.update({'Slides_Map': np.copy(models.sl_slideocurrence)}) @@ -4269,8 +4247,8 @@ def run_shia(self,Calibracion, index = pd.MultiIndex.from_tuples(tupla, names=['reach','flux']) Qsep = np.array(Qsep) QsepDict = pd.DataFrame(Qsep.T, index=Rain.index, columns=index) - #Si simula sedimentos, hace el dataframe - if models.sim_sediments == 1: + #Si simula sedimentos, hace el dataframe + if models.sim_sediments == 1: Qsedi = [] tupla = [] for z,i,j in zip(Retornos['Qsim'][1:], Retornos['Sediments'][1:], ids): @@ -4281,18 +4259,18 @@ def run_shia(self,Calibracion, index = pd.MultiIndex.from_tuples(tupla, names=['reach','Sediments']) Qsedi = np.array(Qsedi) QsediDict = pd.DataFrame(Qsedi.T, index=Rain.index, columns=index) - if models.separate_fluxes == 1 and models.sim_sediments == 0: - return Retornos, Qdict, QsepDict - if models.separate_fluxes == 1 and models.sim_sediments == 1: - return Retornos, Qdict, QsepDict, QsediDict - if models.separate_fluxes == 0 and models.sim_sediments == 1: - return Retornos, Qdict, QsediDict - return Retornos, Qdict + if models.separate_fluxes == 1 and models.sim_sediments == 0: + return Retornos, Qdict, QsepDict + if models.separate_fluxes == 1 and models.sim_sediments == 1: + return Retornos, Qdict, QsepDict, QsediDict + if models.separate_fluxes == 0 and models.sim_sediments == 1: + return Retornos, Qdict, QsediDict + return Retornos, Qdict return Retornos - + def efficiencia(self, Qobs, Qsim): 'Descripcion: Calcula diferentes indices de desempeno del modelo\n'\ - ' nash, qpico, rmse, rmseLog, t_pico\n'\ + ' nash, qpico, rmse, rmseLog, t_pico\n'\ '\n'\ 'Parametros\n'\ '----------\n'\ @@ -4308,28 +4286,28 @@ def efficiencia(self, Qobs, Qsim): DictEff.update({'RmseLog': __eval_rmse_log__(Qobs, Qsim)}) DictEff.update({'Rmse': __eval_rmse__(Qobs, Qsim)}) return DictEff - + def Calib_NSGAII(self, nsga_el, nodo_eval, pop_size = 40, process = 4, NGEN = 6, MUTPB = 0.5, CXPB = 0.5): 'Descripcion: Algoritmo para calibrar de forma automatica el modelo\n'\ - ' hidrologico utilizando DEAP y su funcion de seleccion NSGAII.\n'\ + ' hidrologico utilizando DEAP y su funcion de seleccion NSGAII.\n'\ '\n'\ 'Parametros\n'\ '----------\n'\ - ' - nsga_el : un objeto de la clase nsgaii_element, el cual determinara las reglas.\n'\ - ' para la generacion de calibraciones.\n'\ - ' - nodo_eval: nodo donde se evalua el modelo.\n'\ - ' - pop_size: tamano de la poblacion (cantidad de calibraciones a evaluar, multiplo de 4).\n'\ - ' - process: Cantidad de procesadores que se utilizaran en la generacion.\n'\ - ' - NGEN: Cantidad de generaciones para obtener la poblacion final.\n'\ - ' - MUTPB: Probabilidad generica de que un gen mute.\n'\ - ' - CXPB: Probabilidad generica de que dos genes se crucen.\n'\ + ' - nsga_el : un objeto de la clase nsgaii_element, el cual determinara las reglas.\n'\ + ' para la generacion de calibraciones.\n'\ + ' - nodo_eval: nodo donde se evalua el modelo.\n'\ + ' - pop_size: tamano de la poblacion (cantidad de calibraciones a evaluar, multiplo de 4).\n'\ + ' - process: Cantidad de procesadores que se utilizaran en la generacion.\n'\ + ' - NGEN: Cantidad de generaciones para obtener la poblacion final.\n'\ + ' - MUTPB: Probabilidad generica de que un gen mute.\n'\ + ' - CXPB: Probabilidad generica de que dos genes se crucen.\n'\ '\n'\ 'Retornos\n'\ '----------\n'\ - ' - pop: poblacion final.\n'\ - ' - Qsim: Caudales simulados en el punto evaluado.\n'\ - ' - fitness: desempeno de la poblacion obtenida.\n'\ + ' - pop: poblacion final.\n'\ + ' - Qsim: Caudales simulados en el punto evaluado.\n'\ + ' - fitness: desempeno de la poblacion obtenida.\n'\ #Check de que la poblacion sea multiplo de 4 Flag = True while Flag: @@ -4381,233 +4359,233 @@ def Calib_NSGAII(self, nsga_el, nodo_eval, pop_size = 40, process = 4, pop = nsga_el.toolbox.select(pop + offspring, pop_size) #Retorno return pop, QsimPar, np.array(fitnesses).T - - + + class nsgaii_element: - def __init__(self, rutaLluvia, Qobs, npasos, inicio, SimuBasinElem ,evp =[0,1], infil = [1,200], perco = [1, 40], - losses = [0,1],velRun = [0.1, 1], velSub = [0.1, 1], velSup =[0.1, 1], - velStream = [0.1, 1], Hu = [0.1, 1], Hg = [0.1, 1], - probCruce = np.ones(10)*0.5, probMutacion = np.ones(10)*0.5, - rangosMutacion = [[0,1], [1,200], [1,40], [0,1], [0.1,1], [0.1, 1], [0.1,1], [0.1,1], [0.1, 1], [0.1,1]], - MaxMinOptima = (1.0, -1.0), CrowDist = 0.5): - 'Descripcion: Inicia el objeto de calibracion genetica tipo NSGAII\n'\ - ' este objeto contiene las reglas principales para la implementacion\n'\ - ' de todo el algoritmo de calibracion genetico.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - ' -rutaLluvia : Ruta donde se encuentra el archivo de lluvia binario.\n'\ - ' -Qobs: Array numpy con el caudal observado [npasos].\n'\ - ' -npasos: Cantidad de pasos en simulacion.\n'\ - ' -inicio: Punto de inicio en la simulacion.\n'\ - ' -SimuBasinElem: Objeto de simulacion.\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con las variables iniciadas.\n'\ - #Rangos parametros - self.evp_range = evp - self.infil_range = infil - self.perco_range = perco - self.losses_range = losses - self.velRun_range = velRun - self.velSub_range = velSub - self.velSup_range = velSup - self.velStream_range = velStream - self.hu_range = Hu - self.hg_range = Hg - #Establece propiedades para ejecucion - self.npasos = npasos - self.inicio = inicio - self.ruta_lluvia = rutaLluvia - self.Qobs = Qobs - self.simelem = SimuBasinElem - #Propiedades de cruce y mutacion - self.prob_cruce = probCruce - self.prob_mutacion = probMutacion - self.rangos_mutacion = rangosMutacion - self.optimiza = MaxMinOptima - self.crowdist = CrowDist - - def __crea_calibracion__(self): - #Evp - if self.evp_range[0] <> self.evp_range[1]: - evp = np.random.uniform(self.evp_range[0], self.evp_range[1],1)[0] - else: - evp = self.evp_range[0] - #Infiltracion - if self.infil_range[0] <> self.infil_range[1]: - infil = np.random.uniform(self.infil_range[0], self.infil_range[1],1)[0] - else: - infil = self.infil_range[0] - #Percolacion - if self.perco_range[0] <> self.perco_range[1]: - perco = np.random.uniform(self.perco_range[0], self.perco_range[1],1)[0] - else: - perco = self.perco_range[0] - #Perdidas - if self.losses_range[0] <> self.losses_range[1]: - losses = np.random.uniform(self.losses_range[0], self.losses_range[1],1)[0] - else: - losses = self.losses_range[0] - #runoff - if self.velRun_range[0] <> self.velRun_range[1]: - velRun = np.random.uniform(self.velRun_range[0], self.velRun_range[1],1)[0] - else: - velRun = self.velRun_range[0] - #Vel subsuperficial - if self.velSub_range[0] <> self.velSub_range[1]: - velSub = np.random.uniform(self.velSub_range[0], self.velSub_range[1],1)[0] - else: - velSub = self.velSub_range[0] - #Vel acuifero - if self.velSup_range[0] <> self.velSup_range[1]: - velSup = np.random.uniform(self.velSup_range[0], self.velSup_range[1],1)[0] - else: - velSup = self.velSup_range[0] - #Vel cauce - if self.velStream_range[0] <> self.velStream_range[1]: - velStream = np.random.uniform(self.velStream_range[0], self.velStream_range[1],1)[0] - else: - velStream = self.velStream_range[0] - #almacenamiento hu - if self.hu_range[0] <> self.hu_range[1]: - hu = np.random.uniform(self.hu_range[0], self.hu_range[1],1)[0] - else: - hu = self.hu_range[0] - #almacenamiento hg - if self.hg_range[0] <> self.hg_range[1]: - hg = np.random.uniform(self.hg_range[0], self.hg_range[1],1)[0] - else: - hg = self.hg_range[0] - #Retorna una calibracion aleatoria - return [evp, infil, perco, losses, velRun, velSub, velSup, velStream, hu, hg] - - def __crea_ejec__(self, calibracion): - return [calibracion, self.ruta_lluvia, self.npasos, self.inicio, self.simelem] + def __init__(self, rutaLluvia, Qobs, npasos, inicio, SimuBasinElem ,evp =[0,1], infil = [1,200], perco = [1, 40], + losses = [0,1],velRun = [0.1, 1], velSub = [0.1, 1], velSup =[0.1, 1], + velStream = [0.1, 1], Hu = [0.1, 1], Hg = [0.1, 1], + probCruce = np.ones(10)*0.5, probMutacion = np.ones(10)*0.5, + rangosMutacion = [[0,1], [1,200], [1,40], [0,1], [0.1,1], [0.1, 1], [0.1,1], [0.1,1], [0.1, 1], [0.1,1]], + MaxMinOptima = (1.0, -1.0), CrowDist = 0.5): + 'Descripcion: Inicia el objeto de calibracion genetica tipo NSGAII\n'\ + ' este objeto contiene las reglas principales para la implementacion\n'\ + ' de todo el algoritmo de calibracion genetico.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + ' -rutaLluvia : Ruta donde se encuentra el archivo de lluvia binario.\n'\ + ' -Qobs: Array numpy con el caudal observado [npasos].\n'\ + ' -npasos: Cantidad de pasos en simulacion.\n'\ + ' -inicio: Punto de inicio en la simulacion.\n'\ + ' -SimuBasinElem: Objeto de simulacion.\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas.\n'\ + #Rangos parametros + self.evp_range = evp + self.infil_range = infil + self.perco_range = perco + self.losses_range = losses + self.velRun_range = velRun + self.velSub_range = velSub + self.velSup_range = velSup + self.velStream_range = velStream + self.hu_range = Hu + self.hg_range = Hg + #Establece propiedades para ejecucion + self.npasos = npasos + self.inicio = inicio + self.ruta_lluvia = rutaLluvia + self.Qobs = Qobs + self.simelem = SimuBasinElem + #Propiedades de cruce y mutacion + self.prob_cruce = probCruce + self.prob_mutacion = probMutacion + self.rangos_mutacion = rangosMutacion + self.optimiza = MaxMinOptima + self.crowdist = CrowDist + + def __crea_calibracion__(self): + #Evp + if self.evp_range[0] <> self.evp_range[1]: + evp = np.random.uniform(self.evp_range[0], self.evp_range[1],1)[0] + else: + evp = self.evp_range[0] + #Infiltracion + if self.infil_range[0] <> self.infil_range[1]: + infil = np.random.uniform(self.infil_range[0], self.infil_range[1],1)[0] + else: + infil = self.infil_range[0] + #Percolacion + if self.perco_range[0] <> self.perco_range[1]: + perco = np.random.uniform(self.perco_range[0], self.perco_range[1],1)[0] + else: + perco = self.perco_range[0] + #Perdidas + if self.losses_range[0] <> self.losses_range[1]: + losses = np.random.uniform(self.losses_range[0], self.losses_range[1],1)[0] + else: + losses = self.losses_range[0] + #runoff + if self.velRun_range[0] <> self.velRun_range[1]: + velRun = np.random.uniform(self.velRun_range[0], self.velRun_range[1],1)[0] + else: + velRun = self.velRun_range[0] + #Vel subsuperficial + if self.velSub_range[0] <> self.velSub_range[1]: + velSub = np.random.uniform(self.velSub_range[0], self.velSub_range[1],1)[0] + else: + velSub = self.velSub_range[0] + #Vel acuifero + if self.velSup_range[0] <> self.velSup_range[1]: + velSup = np.random.uniform(self.velSup_range[0], self.velSup_range[1],1)[0] + else: + velSup = self.velSup_range[0] + #Vel cauce + if self.velStream_range[0] <> self.velStream_range[1]: + velStream = np.random.uniform(self.velStream_range[0], self.velStream_range[1],1)[0] + else: + velStream = self.velStream_range[0] + #almacenamiento hu + if self.hu_range[0] <> self.hu_range[1]: + hu = np.random.uniform(self.hu_range[0], self.hu_range[1],1)[0] + else: + hu = self.hu_range[0] + #almacenamiento hg + if self.hg_range[0] <> self.hg_range[1]: + hg = np.random.uniform(self.hg_range[0], self.hg_range[1],1)[0] + else: + hg = self.hg_range[0] + #Retorna una calibracion aleatoria + return [evp, infil, perco, losses, velRun, velSub, velSup, velStream, hu, hg] + + def __crea_ejec__(self, calibracion): + return [calibracion, self.ruta_lluvia, self.npasos, self.inicio, self.simelem] - def __evalfunc__(self, Qsim, f1 = __eval_nash__, f2 = __eval_q_pico__): - E1 = f1(self.Qobs, Qsim) - E2 = f2(self.Qobs, Qsim) - return E1, E2 - - def __cruce__(self, indi1, indi2): - for i,u in zip(range(10), self.prob_cruce): - p = np.random.uniform(0,1,1) - if p>u: - a = indi1[i]; b = indi2[i] - indi1[i] = b - indi2[i] = a - return indi1, indi2 - - def __mutacion__(self, indi): - c = 0 - for i,u in zip(range(10), self.prob_mutacion): - p = np.random.uniform(0,1,1) - if p>u: - indi[i] = np.random.uniform(self.rangos_mutacion[c][0],self.rangos_mutacion[c][0],1)[0] - c+=1 - return indi - - def set_nsgaII(self): - self.toolbox = base.Toolbox() - creator.create("FitnessMin", base.Fitness, - weights = self.optimiza, - crowding_dist = self.crowdist) - creator.create("Individual", list, fitness=creator.FitnessMin) - self.toolbox.register("attr1", self.__crea_calibracion__) - self.toolbox.register("individual", tools.initRepeat, creator.Individual, - self.toolbox.attr1, n=1) - self.toolbox.register("population", tools.initRepeat, list, self.toolbox.individual) - self.toolbox.register("evaluate", self.__evalfunc__) - self.toolbox.register("mate", self.__cruce__) - self.toolbox.register("mutate", self.__mutacion__) - self.toolbox.register("select", tools.selNSGA2) - + def __evalfunc__(self, Qsim, f1 = __eval_nash__, f2 = __eval_q_pico__): + E1 = f1(self.Qobs, Qsim) + E2 = f2(self.Qobs, Qsim) + return E1, E2 + + def __cruce__(self, indi1, indi2): + for i,u in zip(range(10), self.prob_cruce): + p = np.random.uniform(0,1,1) + if p>u: + a = indi1[i]; b = indi2[i] + indi1[i] = b + indi2[i] = a + return indi1, indi2 + + def __mutacion__(self, indi): + c = 0 + for i,u in zip(range(10), self.prob_mutacion): + p = np.random.uniform(0,1,1) + if p>u: + indi[i] = np.random.uniform(self.rangos_mutacion[c][0],self.rangos_mutacion[c][0],1)[0] + c+=1 + return indi + + def set_nsgaII(self): + self.toolbox = base.Toolbox() + creator.create("FitnessMin", base.Fitness, + weights = self.optimiza, + crowding_dist = self.crowdist) + creator.create("Individual", list, fitness=creator.FitnessMin) + self.toolbox.register("attr1", self.__crea_calibracion__) + self.toolbox.register("individual", tools.initRepeat, creator.Individual, + self.toolbox.attr1, n=1) + self.toolbox.register("population", tools.initRepeat, list, self.toolbox.individual) + self.toolbox.register("evaluate", self.__evalfunc__) + self.toolbox.register("mate", self.__cruce__) + self.toolbox.register("mutate", self.__mutacion__) + self.toolbox.register("select", tools.selNSGA2) + class Stream: - #------------------------------------------------------ - # Subrutinas de trazado de corriente y obtencion de parametros - #------------------------------------------------------ - #Inicia la cuenca - def __init__(self,lat,lon,DEM,DIR,name='NaN'): - 'Descripcion: Traza un cauce e inicia la variable de este \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'lat : Coordenada en X del punto mas alto del cauce.\n'\ - 'lon : Coordenada en Y del punto mas alto del cauce.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con las variables iniciadas y estructura del cauce.\n'\ - #Realiza copia de los mapas y obtiene el cauce - self.DEM = DEM - self.DIR = DIR - self.ncells = cu.stream_find(lat,lon,self.DEM, - self.DIR,cu.ncols,cu.nrows) - self.structure = cu.stream_cut(self.ncells) - #------------------------------------------------------ - # Guardado shp de cauce - #------------------------------------------------------ - def Save_Stream2Map(self,ruta,DriverFormat='ESRI Shapefile', - EPSG=4326): - 'Descripcion: Guarda el cauce trazado en un mapa \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'ruta : Nombre del lugar donde se va a guardar el cauce.\n'\ - 'DriverFormat : Tipo de mapa vectorial.\n'\ - 'EPSG : Codigo de tipo de proyeccion usada (defecto 4326).\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Guarda el cauce en el formato especificado.\n'\ - #Escribe el shp del cauce - if ruta.endswith('.shp')==False: - ruta=ruta+'.shp' - spatialReference = osgeo.osr.SpatialReference() - spatialReference.ImportFromEPSG(EPSG) - driver = osgeo.ogr.GetDriverByName(DriverFormat) - if os.path.exists(ruta): - driver.DeleteDataSource(ruta) - shapeData = driver.CreateDataSource(ruta) - layer = shapeData.CreateLayer('layer1', - spatialReference, osgeo.ogr.wkbLineString) - layerDefinition = layer.GetLayerDefn() - line = osgeo.ogr.Geometry(osgeo.ogr.wkbLineString) - for x,y in zip(self.structure[0],self.structure[1]): - line.AddPoint_2D(float(x),float(y)) - feature = osgeo.ogr.Feature(layerDefinition) - feature.SetGeometry(line) - feature.SetFID(0) - layer.CreateFeature(feature) - line.Destroy() - feature.Destroy() - shapeData.Destroy() - #------------------------------------------------------ - # Plot de variables - #------------------------------------------------------ - def Plot_Profile(self,ruta=None): - 'Descripcion: Grafica el perfil del cauce trazado \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'ruta : Nombre de la imagen si se va a guardar la imagen del cauce.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Guarda el cauce en el formato especificado.\n'\ - #Escribe el shp del cauce - fig=pl.figure(facecolor='w',edgecolor='w') - ax=fig.add_subplot(111) - ax.plot(self.structure[3],self.structure[2],lw=2) - ax.set_xlabel('Distancia $[mts]$',size=14) - ax.set_ylabel('Elevacion $[m.s.n.m]$',size=14) - ax.grid(True) - if ruta is not None: - pl.savefig(ruta,bbox_inches='tight') - pl.show() - #def Plot_Map(self,ruta=None + #------------------------------------------------------ + # Subrutinas de trazado de corriente y obtencion de parametros + #------------------------------------------------------ + #Inicia la cuenca + def __init__(self,lat,lon,DEM,DIR,name='NaN'): + 'Descripcion: Traza un cauce e inicia la variable de este \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'lat : Coordenada en X del punto mas alto del cauce.\n'\ + 'lon : Coordenada en Y del punto mas alto del cauce.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas y estructura del cauce.\n'\ + #Realiza copia de los mapas y obtiene el cauce + self.DEM = DEM + self.DIR = DIR + self.ncells = cu.stream_find(lat,lon,self.DEM, + self.DIR,cu.ncols,cu.nrows) + self.structure = cu.stream_cut(self.ncells) + #------------------------------------------------------ + # Guardado shp de cauce + #------------------------------------------------------ + def Save_Stream2Map(self,ruta,DriverFormat='ESRI Shapefile', + EPSG=4326): + 'Descripcion: Guarda el cauce trazado en un mapa \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'ruta : Nombre del lugar donde se va a guardar el cauce.\n'\ + 'DriverFormat : Tipo de mapa vectorial.\n'\ + 'EPSG : Codigo de tipo de proyeccion usada (defecto 4326).\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el cauce en el formato especificado.\n'\ + #Escribe el shp del cauce + if ruta.endswith('.shp')==False: + ruta=ruta+'.shp' + spatialReference = osgeo.osr.SpatialReference() + spatialReference.ImportFromEPSG(EPSG) + driver = osgeo.ogr.GetDriverByName(DriverFormat) + if os.path.exists(ruta): + driver.DeleteDataSource(ruta) + shapeData = driver.CreateDataSource(ruta) + layer = shapeData.CreateLayer('layer1', + spatialReference, osgeo.ogr.wkbLineString) + layerDefinition = layer.GetLayerDefn() + line = osgeo.ogr.Geometry(osgeo.ogr.wkbLineString) + for x,y in zip(self.structure[0],self.structure[1]): + line.AddPoint_2D(float(x),float(y)) + feature = osgeo.ogr.Feature(layerDefinition) + feature.SetGeometry(line) + feature.SetFID(0) + layer.CreateFeature(feature) + line.Destroy() + feature.Destroy() + shapeData.Destroy() + #------------------------------------------------------ + # Plot de variables + #------------------------------------------------------ + def Plot_Profile(self,ruta=None): + 'Descripcion: Grafica el perfil del cauce trazado \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'ruta : Nombre de la imagen si se va a guardar la imagen del cauce.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el cauce en el formato especificado.\n'\ + #Escribe el shp del cauce + fig=pl.figure(facecolor='w',edgecolor='w') + ax=fig.add_subplot(111) + ax.plot(self.structure[3],self.structure[2],lw=2) + ax.set_xlabel('Distancia $[mts]$',size=14) + ax.set_ylabel('Elevacion $[m.s.n.m]$',size=14) + ax.grid(True) + if ruta is not None: + pl.savefig(ruta,bbox_inches='tight') + pl.show() + #def Plot_Map(self,ruta=None From 1a6a8a02f39b74121554734ddc6e16d846f20b64 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 19 Jun 2018 11:40:15 -0500 Subject: [PATCH 053/142] =?UTF-8?q?se=20cambia=20el=20comportamiento=20de?= =?UTF-8?q?=20la=20funci=C3=B3n=20de=20balance=20para=20Qgis,=20en=20esta?= =?UTF-8?q?=20ya=20los=20resultados=20se=20cargan=20a=20la=20tabla=20de=20?= =?UTF-8?q?variables=20WMF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPluginUtils.py | 25 ++- qgisplugin/HydroSEDPlugin_dockwidget.py | 26 +-- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 169 +------------------ 3 files changed, 24 insertions(+), 196 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 5d1d95e..1a27bb5 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -122,7 +122,7 @@ def trazador_cuenca(self,x,y, dxp,umbral,PathDiv, PathRed, PathNC,PathDEM, PathD if len(PathNC)>2: self.cuenca.Save_SimuBasin(PathNC) - def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed, PathETROUT, PathRunoff): + def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed): #Se fija si la lluvia es un path o un valor try: Rain = float(PathRain) @@ -140,15 +140,26 @@ def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed, PathETROUT 'basica': False, 'categoria': 'Hidro', 'var': self.cuenca.CellQmed}}) + self.DicBasinWMF.update({'ETR': + {'nombre':'ETR', + 'tipo':'float32', + 'shape':self.cuenca.CellETR.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Hidro', + 'var': self.cuenca.CellETR}}) + Runoff = Rain - self.cuenca.CellETR + self.DicBasinWMF.update({'Runoff': + {'nombre':'Runoff', + 'tipo':'float32', + 'shape':self.cuenca.CellETR.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Hidro', + 'var': Runoff}}) # Guarda el resultado if len(PathQmed)>2: self.cuenca.Save_Net2Map(PathQmed, dxp, umbral, qmed = self.cuenca.CellQmed) - if len(PathETROUT)>2: - self.cuenca.Transform_Basin2Map(self.cuenca.CellETR, PathETROUT) - if len(PathRunoff)>2: - Runoff = Rain - self.cuenca.CellETR - self.cuenca.Transform_Basin2Map(Runoff, PathRunoff) - #Retorna el resultado a la salida return self.cuenca.CellQmed[-1] diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index aeeb0ad..1852404 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -240,12 +240,6 @@ def clickEventSelectorRaster(): def clickEventViewRainfall(): pathMapaRain = self.PathInHydro_Rain.text().strip() flagCargaMapaRain = self.HSutils.cargar_mapa_raster(pathMapaRain) - def clickEventViewETR(): - pathMapaETR = self.PathOutHydro_ETR.text().strip() - flagCargaMapaRain = self.HSutils.cargar_mapa_raster(pathMapaETR) - def clickEventViewRunoff(): - pathMapaRain = self.PathOutHydro_Runoff.text().strip() - flagCargaMapaRain = self.HSutils.cargar_mapa_raster(pathMapaRain) def clickEventViewQmedNetwork(): OutPathRed = self.PathOutHydro_Qmed.text().strip() ret, layer = self.HSutils.cargar_mapa_vector(OutPathRed, self.HSutils.TIPO_STYLE_POLILINEA, width = 0.4) @@ -256,12 +250,6 @@ def clickEventViewQmedNetwork(): def clickEventOutQmed(): '''Habilita la ruta para decir donde se va a guardar la variable de caudal medio''' setupLineEditButtonSaveFileDialog(self.PathOutHydro_Qmed, QFileDialog) - def clickEventOutRunoff(): - '''Habilita la ruta para decir donde se va a guardar la variable de caudal medio''' - setupLineEditButtonSaveFileDialog(self.PathOutHydro_Runoff, QFileDialog) - def clickEventOutETR(): - '''Habilita la ruta para decir donde se va a guardar la variable de caudal medio''' - setupLineEditButtonSaveFileDialog(self.PathOutHydro_ETR, QFileDialog) #Funciones para el calculo de balance def hadleClickEventEjecutarBalance(): @@ -278,21 +266,15 @@ def hadleClickEventEjecutarBalance(): self.spinBoxUmbralRed.value(), self.PathInHydro_Rain.text(), TipoETR, - self.PathOutHydro_Qmed.text(), - self.PathOutHydro_ETR.text(), - self.PathOutHydro_Runoff.text()) + self.PathOutHydro_Qmed.text()) #Pone el valor de cadual medio en el cuadro textoCaudal = '%.3f' % QSalida self.ShowResultQmed.setText(textoCaudal) #Mensaje de exito - self.iface.messageBar().pushInfo(u'HidroSIG:',u'Se ha realizado el balance de caudal con exito.') + self.iface.messageBar().pushInfo(u'HidroSIG:',u'Balance realizado: variables Caudal, ETR y Runoff cargadas a Tabla de propiedades WMF.') #Habilita botones de visualizacion de variables if len(self.PathOutHydro_Qmed.text()) > 2: self.Button_HidroViewQmed.setEnabled(True) - if len(self.PathOutHydro_Runoff.text()) > 2: - self.Button_HidroViewRunoff.setEnabled(True) - if len(self.PathOutHydro_ETR.text()) > 2: - self.Button_HidroViewETR.setEnabled(True) #Actualiza la tabla de variables temporales self.UpdateTablePropWMF() @@ -300,13 +282,9 @@ def hadleClickEventEjecutarBalance(): self.Boton_HidroLoadRain.clicked.connect(clickEventSelectorRaster) #Botones para variables de salida self.Button_HidroSaveQmed.clicked.connect(clickEventOutQmed) - self.Button_HidroSaveRunoff.clicked.connect(clickEventOutRunoff) - self.Button_HidroSaveETR.clicked.connect(clickEventOutETR) #Botones para visualizar variables self.Button_HidroViewRain.clicked.connect(clickEventViewRainfall) self.Button_HidroViewQmed.clicked.connect(clickEventViewQmedNetwork) - self.Button_HidroViewETR.clicked.connect(clickEventViewETR) - self.Button_HidroViewRunoff.clicked.connect(clickEventViewRunoff) #Botones para ejecutar self.Butto_Ejec_HidroBalance.clicked.connect(hadleClickEventEjecutarBalance) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 868cebe..da804af 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -262,7 +262,7 @@ - 0 + 2 @@ -1815,13 +1815,13 @@ 0 0 431 - 290 + 231 0 - 290 + 200 @@ -2112,167 +2112,6 @@ - - - - - - - 11 - 50 - false - false - - - - El valor de la escorrentía como un mapa Raster [mm/año] - - - El valor de la escorrentía como un mapa Raster - - - Escorrentía - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - Ruta de guardado - - - false - - - - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - false - - - - 40 - 16777215 - - - - Visualizar raster con la escorrentia calculada. - - - Visualizar raster con la escorrentia calculada. - - - Ver - - - - - - - - - - - El valor de la evaporacion estimada como un Raster [mm/año] - - - El valor de la evaporacion estimada como un Raster - - - ETR - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - Ruta de guardado - - - false - - - - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - false - - - - 40 - 16777215 - - - - Visualizar raster con la ETR calculada. - - - Visualizar raster con la ETR calculada. - - - Ver - - - - - - - - - Qt::Horizontal - - - @@ -2337,7 +2176,7 @@ 0 - 290 + 230 431 351 From c1316c38ca88167a7bc72a714958b532c3e49490 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 20 Jun 2018 11:07:18 -0500 Subject: [PATCH 054/142] comienzan trabajos para hacer que las tablas se comporten como clases, y funciona mejor que de la otra manera --- qgisplugin/HydroSEDPluginUtils.py | 1 + qgisplugin/HydroSEDPlugin_dockwidget.py | 111 +++++++++++++++++------- 2 files changed, 81 insertions(+), 31 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 1a27bb5..b1e164f 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -192,6 +192,7 @@ def Basin_LoadBasin(self, PathNC): g.close() #Cargar la cuenca y sus variables base a WMF self.cuenca = wmf.SimuBasin(rute = PathNC) + self.NumDicBasinWMFVariables = 50 #Area de la cuenca y codigo EPSG return self.cuenca.ncells*wmf.cu.dxp**2./1e6, self.cuenca.epsg, wmf.models.dxp, wmf.cu.nodata diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 1852404..7d4b22a 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -60,6 +60,7 @@ def __init__(self, iface = None, parent=None): #self.setupUIButtonEvents () self.TablaFila_WMF = 0 + self.TablaFila_NC = 0 if not (iface is None): self.iface = iface @@ -166,9 +167,10 @@ def clickEventSelectorBasin(): self.ButtonLoadBasinProyect.setEnabled(True) def clickEventBasin2WMF(): '''Agrega el proyecto de cuenca a WMF''' - self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip()) - self.setupTableEdicionAlmacenamientoParametrosWMFNC () + self.TableStart() + for k in self.HSutils.DicBasinNc.keys(): + self.TabNC.NewEntry(self.HSutils.DicBasinNc[k],k, self.Tabla_Prop_NC) Area, self.EPSG, dxp, self.noData = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip()) #Habilita los botones de visualizacion de red hidrica y divisoria self.Boton_verDivisoria.setEnabled(True) @@ -276,7 +278,8 @@ def hadleClickEventEjecutarBalance(): if len(self.PathOutHydro_Qmed.text()) > 2: self.Button_HidroViewQmed.setEnabled(True) #Actualiza la tabla de variables temporales - self.UpdateTablePropWMF() + for k in ['Caudal','ETR','Runoff']: + self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[k],k, self.Tabla_Prop_WMF) #Botones para variables de entrada self.Boton_HidroLoadRain.clicked.connect(clickEventSelectorRaster) @@ -288,43 +291,54 @@ def hadleClickEventEjecutarBalance(): #Botones para ejecutar self.Butto_Ejec_HidroBalance.clicked.connect(hadleClickEventEjecutarBalance) - def setupTableEdicionAlmacenamientoParametrosWMFNC (self): - - print self.HSutils.DicBasinNc - print self.HSutils.NumDicBasinNcVariables + def TableStart (self): + '''Arranca las tablas de NC y WMF''' + self.TabNC = Tabla(self.HSutils.NumDicBasinNcVariables,self.Tabla_Prop_NC) + self.TabWMF = Tabla(self.HSutils.NumDicBasinWMFVariables, self.Tabla_Prop_WMF) + + #def TableUpdate(self): + # '''Actualiza entrada en la tabla''' + - listaHeaderTabla_NC = ["Nombre", "Tipo", "Forma", "Categoria"] - listaHeaderTabla_WMF = ["Nombre", "Tipo", "Forma", "Categoria"] + #print self.HSutils.DicBasinNc + #print self.HSutils.NumDicBasinNcVariables + + #listaHeaderTabla_NC = ["Nombre", "Tipo", "Forma", "Categoria"] + #listaHeaderTabla_WMF = ["Nombre", "Tipo", "Forma", "Categoria"] - self.Tabla_Prop_NC.setRowCount (self.HSutils.NumDicBasinNcVariables) - self.Tabla_Prop_NC.setColumnCount (len (listaHeaderTabla_NC)) - self.Tabla_Prop_NC.setHorizontalHeaderLabels (listaHeaderTabla_NC) + #self.Tabla_Prop_NC.setRowCount (self.HSutils.NumDicBasinNcVariables) + #self.Tabla_Prop_NC.setColumnCount (len (listaHeaderTabla_NC)) + #self.Tabla_Prop_NC.setHorizontalHeaderLabels (listaHeaderTabla_NC) - self.Tabla_Prop_WMF.setRowCount (self.HSutils.NumDicBasinNcVariablesBasicas) - self.Tabla_Prop_WMF.setColumnCount (len (listaHeaderTabla_WMF)) - self.Tabla_Prop_WMF.setHorizontalHeaderLabels (listaHeaderTabla_WMF) + #self.Tabla_Prop_WMF.setRowCount (self.HSutils.NumDicBasinNcVariablesBasicas) + #self.Tabla_Prop_WMF.setColumnCount (len (listaHeaderTabla_WMF)) + #self.Tabla_Prop_WMF.setHorizontalHeaderLabels (listaHeaderTabla_WMF) - idxFila_NC = 0 - idxFila_WMF = 0 + #idxFila_NC = 0 + #idxFila_WMF = 0 + + #Crea los objetos de tabla para WMF y NC - #Carga las variables a la tabla - for keyParam in self.HSutils.DicBasinNc: - self.Tabla_Prop_NC.setItem (idxFila_NC, 0, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["nombre"])) - self.Tabla_Prop_NC.setItem (idxFila_NC, 1, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["tipo"])) - self.Tabla_Prop_NC.setItem (idxFila_NC, 2, QTableWidgetItem (str (self.HSutils.DicBasinNc[keyParam]["shape"]))) - self.Tabla_Prop_NC.setItem (idxFila_NC, 3, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["categoria"])) - idxFila_NC = idxFila_NC + 1 + ##Carga las variables a la tabla + #for keyParam in self.HSutils.DicBasinNc: + #self.Tabla_Prop_NC.setItem (self.TablaFila_NC, 0, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["nombre"])) + #self.Tabla_Prop_NC.setItem (self.TablaFila_NC, 1, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["tipo"])) + #self.Tabla_Prop_NC.setItem (self.TablaFila_NC, 2, QTableWidgetItem (str (self.HSutils.DicBasinNc[keyParam]["shape"]))) + #self.Tabla_Prop_NC.setItem (self.TablaFila_NC, 3, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["categoria"])) + #self.TablaFila_NC += 1 def setupUIInputsOutputs (self): def handleClickEventButton_Eliminar_Desde_WMF (): selectedItems = self.Tabla_Prop_WMF.currentRow () self.Tabla_Prop_WMF.removeRow (selectedItems) + self.TablaFila_WMF -= 1 def handleClickEventButton_Eliminar_Desde_NC (): selectedItems = self.Tabla_Prop_NC.currentRow () self.Tabla_Prop_NC.removeRow (selectedItems) + self.TablaFila_NC -= 1 def handleClickEventButton_Actualizar_WMF_Desde_NC (): rows = sorted (set (index.row () for index in self.Tabla_Prop_NC.selectedIndexes ())) @@ -497,12 +511,47 @@ def set_dxplano(): self.Button_Visualizar_Desde_NC.clicked.connect(handleClickEventButton_Ver_Desde_NC) - - #for keyParam in self.HSutils.DicBasinWMF: - #self.Tabla_Prop_WMF.setItem (idxFila_WMF, 0, QTableWidgetItem (self.HSutils.DicBasinWMF[keyParam]["nombre"])) - #self.Tabla_Prop_WMF.setItem (idxFila_WMF, 1, QTableWidgetItem (self.HSutils.DicBasinWMF[keyParam]["tipo"])) - #self.Tabla_Prop_WMF.setItem (idxFila_WMF, 2, QTableWidgetItem (str (self.HSutils.DicBasinWMF[keyParam]["shape"]))) - #self.Tabla_Prop_WMF.setItem (idxFila_WMF, 3, QTableWidgetItem (self.HSutils.DicBasinWMF[keyParam]["categoria"])) - #idxFila_WMF = idxFila_WMF + 1 +class Tabla(): + + def __init__(self, NumRows, TabElement): + self.NumRows = 0 + self.TabPositions = [] + self.TabNames = [] + Header = ["Nombre", "Tipo", "Forma", "Categoria"] + TabElement.setRowCount(NumRows) + TabElement.setColumnCount(len(Header)) + TabElement.setHorizontalHeaderLabels(Header) + + def New_Row_in_Dic(self,DicElement): + '''Coloca una nueva entrada en el diccionario de datos''' + self.Dic.update(DicElement) + self.NumRows += 1 + + def Del_Row_in_Dic(self, KeyToDel): + '''Borra una entrada en el diccionario de datos''' + self.Dic.pop[KeyToDel] + self.NumRows -= 1 + + def NewEntry(self, Dic, DicKey,TabElement): + '''Actualiza la lista de las variables en una tabla''' + #Busca si ese nombre ya se encuentra en la tabla + try: + #Si esta, remplaza esa posicion + pos = self.TabNames.index(DicKey) + suma = 0 + except: + #Si no esta, lo pone al final. + pos = self.NumRows + self.TabNames.append(DicKey) + suma = 1 + #for keyParam in Dic: + TabElement.setItem (pos, 0, QTableWidgetItem (Dic["nombre"])) + TabElement.setItem (pos, 1, QTableWidgetItem (Dic["tipo"])) + TabElement.setItem (pos, 2, QTableWidgetItem (str (Dic["shape"]))) + TabElement.setItem (pos, 3, QTableWidgetItem (Dic["categoria"])) + self.NumRows += suma + + + From 3b1067dc168cdc9fbdd00151c7c351733817bf36 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 20 Jun 2018 16:07:56 -0500 Subject: [PATCH 055/142] Se crea la clase Tabla con la que se manejan las tablas en Qgis, ademas se hace un cambio de fondo en WMF/Save_SimuBasin y __LoadSimuBasin ambas funciones ya cargan y guardan las variables por grupos --- qgisplugin/HydroSEDPluginUtils.py | 11 +- qgisplugin/HydroSEDPlugin_dockwidget.py | 115 +++++---- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 8 +- wmf/wmf.py | 242 ++++++++++++++++++- 4 files changed, 317 insertions(+), 59 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index b1e164f..fba0668 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -216,7 +216,16 @@ def Basin_LoadBasicVariable(self,PathNC, VarName): ruta = rutaSalida, EPSG = self.cuenca.epsg) return rutaSalida - + + def Basin_LoadVariableFromDicWMF(self,VarName): + '''Toma una variable del diccionario de variables basicas y la carga a Qgis''' + #Transforma a un raster + rutaSalida = '/tmp/HydroSED/Raster_'+VarName+'.tiff' + self.cuenca.Transform_Basin2Map(self.DicBasinWMF[VarName]['var'], + ruta = rutaSalida, + EPSG = self.cuenca.epsg) + return rutaSalida + def Basin_GeoGetHAND(self, umbral): self.cuenca.GetGeo_HAND(umbral) self.DicBasinWMF.update({'HAND': diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 7d4b22a..9489289 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -71,15 +71,6 @@ def __init__(self, iface = None, parent=None): self.spinBoxLongitudTrazadorCuencas) #self.iface.mapCanvas().setMapTool(GetCoords) - def UpdateTablePropWMF(self): - '''Actualiza la lista de las variables en la tabla de WMF''' - for keyParam in self.HSutils.DicBasinWMF: - self.Tabla_Prop_WMF.setItem (self.TablaFila_WMF, 0, QTableWidgetItem (self.HSutils.DicBasinWMF[keyParam]["nombre"])) - self.Tabla_Prop_WMF.setItem (self.TablaFila_WMF, 1, QTableWidgetItem (self.HSutils.DicBasinWMF[keyParam]["tipo"])) - self.Tabla_Prop_WMF.setItem (self.TablaFila_WMF, 2, QTableWidgetItem (str (self.HSutils.DicBasinWMF[keyParam]["shape"]))) - self.Tabla_Prop_WMF.setItem (self.TablaFila_WMF, 3, QTableWidgetItem (self.HSutils.DicBasinWMF[keyParam]["categoria"])) - self.TablaFila_WMF = self.TablaFila_WMF + 1 - def closeEvent(self, event): self.closingPlugin.emit() @@ -296,49 +287,25 @@ def TableStart (self): self.TabNC = Tabla(self.HSutils.NumDicBasinNcVariables,self.Tabla_Prop_NC) self.TabWMF = Tabla(self.HSutils.NumDicBasinWMFVariables, self.Tabla_Prop_WMF) - #def TableUpdate(self): - # '''Actualiza entrada en la tabla''' - - - #print self.HSutils.DicBasinNc - #print self.HSutils.NumDicBasinNcVariables - - #listaHeaderTabla_NC = ["Nombre", "Tipo", "Forma", "Categoria"] - #listaHeaderTabla_WMF = ["Nombre", "Tipo", "Forma", "Categoria"] - - #self.Tabla_Prop_NC.setRowCount (self.HSutils.NumDicBasinNcVariables) - #self.Tabla_Prop_NC.setColumnCount (len (listaHeaderTabla_NC)) - #self.Tabla_Prop_NC.setHorizontalHeaderLabels (listaHeaderTabla_NC) - - #self.Tabla_Prop_WMF.setRowCount (self.HSutils.NumDicBasinNcVariablesBasicas) - #self.Tabla_Prop_WMF.setColumnCount (len (listaHeaderTabla_WMF)) - #self.Tabla_Prop_WMF.setHorizontalHeaderLabels (listaHeaderTabla_WMF) - - #idxFila_NC = 0 - #idxFila_WMF = 0 - - #Crea los objetos de tabla para WMF y NC - - ##Carga las variables a la tabla - #for keyParam in self.HSutils.DicBasinNc: - #self.Tabla_Prop_NC.setItem (self.TablaFila_NC, 0, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["nombre"])) - #self.Tabla_Prop_NC.setItem (self.TablaFila_NC, 1, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["tipo"])) - #self.Tabla_Prop_NC.setItem (self.TablaFila_NC, 2, QTableWidgetItem (str (self.HSutils.DicBasinNc[keyParam]["shape"]))) - #self.Tabla_Prop_NC.setItem (self.TablaFila_NC, 3, QTableWidgetItem (self.HSutils.DicBasinNc[keyParam]["categoria"])) - #self.TablaFila_NC += 1 - def setupUIInputsOutputs (self): def handleClickEventButton_Eliminar_Desde_WMF (): + #Selecciona el item y su nombre selectedItems = self.Tabla_Prop_WMF.currentRow () + ItemName = self.Tabla_Prop_WMF.item(selectedItems,0).text() + #Remueve de la tabla visible y de los demas elementos. self.Tabla_Prop_WMF.removeRow (selectedItems) - self.TablaFila_WMF -= 1 + self.TabWMF.DelEntry(ItemName) + self.HSutils.DicBasinWMF.pop(ItemName) - def handleClickEventButton_Eliminar_Desde_NC (): + #Selecciona el item y su nombre selectedItems = self.Tabla_Prop_NC.currentRow () + ItemName = str(self.Tabla_Prop_NC.item(selectedItems,0).text()) + #Remueve de la tabla visible y de los demas elementos. self.Tabla_Prop_NC.removeRow (selectedItems) - self.TablaFila_NC -= 1 + self.TabNC.DelEntry(ItemName) + self.HSutils.DicBasinNc.pop(ItemName) def handleClickEventButton_Actualizar_WMF_Desde_NC (): rows = sorted (set (index.row () for index in self.Tabla_Prop_NC.selectedIndexes ())) @@ -360,6 +327,46 @@ def handleClickEventButton_Ver_Desde_NC(): self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'Se cargó la variable de forma exitosa') else: self.iface.messageBar().pushError (u'Hydro-SIG:', u'No fue posible cargar la variable') + + def handleClickEventButton_Ver_Desde_WMF(): + '''Visualiza una de las variables de la cuenca en Qgis''' + #Ejecucion de la transformacion de la variable cuenca a raster + selectedItems = self.Tabla_Prop_WMF.currentRow () + VarName = self.Tabla_Prop_WMF.item(selectedItems,0).text() + pathMapa = self.HSutils.Basin_LoadVariableFromDicWMF(VarName) + print pathMapa + #Visualiza + flagCargaMapa = self.HSutils.cargar_mapa_raster(pathMapa) + if flagCargaMapa: + self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'Se cargó la variable de forma exitosa') + else: + self.iface.messageBar().pushError (u'Hydro-SIG:', u'No fue posible cargar la variable') + + def handleClickEventButton_NC2WMF(): + '''Mueve variables de NC a WMF en la tabla.''' + # Elemento seleccionado + selectedItems = self.Tabla_Prop_NC.currentRow () + VarName = self.Tabla_Prop_NC.item(selectedItems,0).text() + # Copia la entrada a WMF y la saca de NC + self.HSutils.DicBasinWMF.update({VarName:self.HSutils.DicBasinNc[VarName]}) + # Mete la entrada en la tabla de WMF y la saca de la tabla de NC + self.TabWMF.NewEntry(self.HSutils.DicBasinNc[VarName], VarName, self.Tabla_Prop_WMF) + self.Tabla_Prop_NC.removeRow (selectedItems) + self.TabNC.DelEntry(VarName) + self.HSutils.DicBasinNc.pop(VarName) + + def handleClickEventButton_WMF2NC(): + '''Mueve variables de NC a WMF en la tabla.''' + # Elemento seleccionado + selectedItems = self.Tabla_Prop_WMF.currentRow () + VarName = self.Tabla_Prop_WMF.item(selectedItems,0).text() + # Copia la entrada a WMF y la saca de NC + self.HSutils.DicBasinNc.update({VarName:self.HSutils.DicBasinWMF[VarName]}) + # Mete la entrada en la tabla de WMF y la saca de la tabla de NC + self.TabNC.NewEntry(self.HSutils.DicBasinWMF[VarName], VarName, self.Tabla_Prop_NC) + self.Tabla_Prop_WMF.removeRow (selectedItems) + self.TabWMF.DelEntry(VarName) + self.HSutils.DicBasinWMF.pop(VarName) def setupLineEditButtonOpenShapeFileDialog (lineEditHolder, fileDialogHolder): '''Hace que cuando se busquen shapes solo se encuetren formatos vectoriales''' @@ -498,38 +505,40 @@ def set_dxplano(): print self.spinBox_dxPlano.value() self.spinBox_dxPlano.valueChanged.connect(set_dxplano) - #Botones de borrado de variables + #Botones de borrado de variables de NC y WMF self.Tabla_Prop_WMF.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) self.Tabla_Prop_WMF.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self.Button_Eliminar_Desde_WMF.clicked.connect(handleClickEventButton_Eliminar_Desde_WMF) self.Tabla_Prop_NC.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) self.Tabla_Prop_NC.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self.Button_Eliminar_Desde_NC.clicked.connect(handleClickEventButton_Eliminar_Desde_NC) - #Botones de visualizacion de variables + #Botones de visualizacion de variables de NC self.Tabla_Prop_NC.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) self.Tabla_Prop_NC.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self.Button_Visualizar_Desde_NC.clicked.connect(handleClickEventButton_Ver_Desde_NC) + #Botones de visualizacion de variables de WMF + self.Tabla_Prop_WMF.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) + self.Tabla_Prop_WMF.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) + self.Button_Visualizar_Desde_WMF.clicked.connect(handleClickEventButton_Ver_Desde_WMF) + #Botones movimiento variables NC a WMF y de WMF a NC + self.Button_NC2WMF.clicked.connect(handleClickEventButton_NC2WMF) + self.Button_WMF2NC.clicked.connect(handleClickEventButton_WMF2NC) class Tabla(): def __init__(self, NumRows, TabElement): self.NumRows = 0 - self.TabPositions = [] self.TabNames = [] Header = ["Nombre", "Tipo", "Forma", "Categoria"] TabElement.setRowCount(NumRows) TabElement.setColumnCount(len(Header)) TabElement.setHorizontalHeaderLabels(Header) - def New_Row_in_Dic(self,DicElement): - '''Coloca una nueva entrada en el diccionario de datos''' - self.Dic.update(DicElement) - self.NumRows += 1 - - def Del_Row_in_Dic(self, KeyToDel): + def DelEntry(self, KeyToDel): '''Borra una entrada en el diccionario de datos''' - self.Dic.pop[KeyToDel] + pos = self.TabNames.index(KeyToDel) + self.TabNames.pop(pos) self.NumRows -= 1 def NewEntry(self, Dic, DicKey,TabElement): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index da804af..e3678e1 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -262,7 +262,7 @@ - 2 + 0 @@ -306,7 +306,7 @@ 0 - 0 + -190 443 918 @@ -851,7 +851,7 @@ - + 50 @@ -874,7 +874,7 @@ - + 50 diff --git a/wmf/wmf.py b/wmf/wmf.py index 42df034..4587e64 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -2861,10 +2861,113 @@ def __init__(self,lat=None,lon=None,DEM=None,DIR=None,rute = None, name='NaN',st self.isSetGeo = False # si hay tura lee todo lo de la cuenca elif rute is not None: - self.__Load_SimuBasin(rute, SimSlides) + self.__Load_SimuBasin2(rute, SimSlides) # Obtiene la envolvente de la cuenca self.__GetBasinPolygon__() + def __Load_SimuBasin2(self,ruta, sim_slides = False): + 'Descripcion: Lee una cuenca posteriormente guardada\n'\ + ' La cuenca debio ser guardada con SimuBasin.save_SimuBasin\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'ruta : ruta donde se encuentra ubicada la cuenca guardada\n'\ + 'Opcionales\n'\ + '----------\n'\ + 'sim_slides : (False, True) Carga variables de modelos de deslizamientos previmaente guardadas.\n'\ + 'sim_sed : (False, True) Carga variables de modelo de sedimentos previamente guardadas\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : La cuenca con sus parametros ya cargada.\n'\ + #Abre el archivo binario de la cuenca + self.rutaNC = ruta + gr = netcdf.Dataset(ruta,'a') + #obtiene las prop de la cuenca + self.name = gr.nombre + self.modelType = gr.modelType.encode() + self.nodata = gr.noData + self.umbral = gr.umbral + self.ncells = gr.ncells + self.nhills = gr.nhills + self.epsg = gr.epsg + models.dt = gr.dt + models.dxp = gr.dxp + models.retorno = gr.retorno + try: + models.storage_constant = gr.storageConst + except: + models.storage_constant = 0.0 + #Si carga deslizamientos + if sim_slides: + models.sim_slides = 1 + models.sl_fs = gr.sl_fs + models.gullienogullie = gr.sl_gullie + models.sl_gammaw = gr.sl_gammaw + #Nueva metodologia de geoespacial de la cuenca + cu.ncols = gr.ncols + cu.nrows = gr.nrows + cu.xll = gr.xll + cu.yll = gr.yll + cu.dx = gr.dx + cu.dy = gr.dy + cu.dxp = gr.dxp + cu.nodata = gr.noData + #de acuerdo al tipo de modeloe stablece numero de elem + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + #Obtiene las variables base + GrupoBase = gr.groups['base'] + self.structure = GrupoBase.variables['structure'][:] + self.hills = GrupoBase.variables['hills'][:] + self.hills_own = GrupoBase.variables['hills_own'][:] + #Obtiene las geomorfologicas + GrupoGeo = gr.groups['Geomorfo'] + self.DEMvec = GrupoGeo.variables['DEM'][:] + self.DIRvec = GrupoGeo.variables['DIR'][:] + self.DEM = self.Transform_Basin2Map(self.DEMvec) + self.DIR = self.Transform_Basin2Map(self.DIRvec) + #obtiene las propieades del modelo + GrupoSimHid = gr.groups['SimHidro'] + models.h_coef = np.ones((4,N)) * GrupoSimHid.variables['h_coef'][:] + models.v_coef = np.ones((4,N)) * GrupoSimHid.variables['v_coef'][:] + models.h_exp = np.ones((4,N)) * GrupoSimHid.variables['h_exp'][:] + models.v_exp = np.ones((4,N)) * GrupoSimHid.variables['v_exp'][:] + models.max_capilar = np.ones((1,N)) * GrupoSimHid.variables['h1_max'][:] + models.max_gravita = np.ones((1,N)) * GrupoSimHid.variables['h3_max'][:] + #Variable de drena de acuerdo al tipo de modelo + if self.modelType[0] is 'c': + models.drena = np.ones((3,N)) *GrupoSimHid.variables['drena'][:] + elif self.modelType[0] is 'h': + models.drena = np.ones((1,N)) * GrupoSimHid.variables['drena'][:] + models.unit_type = np.ones((1,N)) * GrupoSimHid.variables['unit_type'][:] + models.hill_long = np.ones((1,N)) * GrupoSimHid.variables['hill_long'][:] + models.hill_slope = np.ones((1,N)) * GrupoSimHid.variables['hill_slope'][:] + models.stream_long = np.ones((1,N)) * GrupoSimHid.variables['stream_long'][:] + models.stream_slope = np.ones((1,N)) * GrupoSimHid.variables['stream_slope'][:] + models.stream_width = np.ones((1,N)) * GrupoSimHid.variables['stream_width'][:] + models.elem_area = np.ones((1,N)) * GrupoSimHid.variables['elem_area'][:] + models.speed_type = np.ones((3)) * GrupoSimHid.variables['speed_type'][:] + models.storage = np.ones((5,N)) * GrupoSimHid.variables['storage'][:] + models.control = np.ones((1,N)) * GrupoSimHid.variables['control'][:] + models.control_h = np.ones((1,N)) * GrupoSimHid.variables['control_h'][:] + + #Propiedades de deslizamientos + if sim_slides: + GrupoSlides = gr.groups['SimSlides'] + models.sl_gammas = np.ones((1,N)) * GrupoSlides.variables['gamma_soil'][:] + models.sl_cohesion = np.ones((1,N)) * GrupoSlides.variables['cohesion'][:] + models.sl_frictionangle = np.ones((1,N)) * GrupoSlides.variables['friction_angle'][:] + models.sl_radslope = np.ones((1,N)) * GrupoSlides.variables['rad_slope'][:] + models.sl_zs = np.ones((1,N)) * GrupoSlides.variables['z_soil'][:] + #Cierra el archivo + gr.close() + #Determina que por defecto debe estar set la geomorfologia + self.isSetGeo = True + + def __Load_SimuBasin(self,ruta, sim_slides = False): 'Descripcion: Lee una cuenca posteriormente guardada\n'\ ' La cuenca debio ser guardada con SimuBasin.save_SimuBasin\n'\ @@ -3883,6 +3986,143 @@ def set_Slides(self,var,VarName): #------------------------------------------------------ # Guardado y Cargado de modelos de cuencas preparados #------------------------------------------------------ + def Save_SimuBasin2(self,ruta,SimSlides = False, + ExtraVar = None): + 'Descripcion: guarda una cuenca previamente ejecutada\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'ruta : Ruta donde la cuenca sera guardada.\n'\ + 'ruta_dem : direccion donde se aloja el DEM (se recomienda absoluta).\n'\ + 'ruta_dir : direccion donde se aloja el DIR (se recomienda absoluta).\n'\ + 'SimSlides: indica a la funcion si va a guardar o no informacion para la simulacion.\n'\ + ' de deslizamientos.\n'\ + 'ExtraVar: Variables extras de simulacion deben ir en un diccionario.\n'\ + ' Forma del diccionario Dict = {"varName": {"Data": vector[ncells], "type": "tipo"}}.\n'\ + ' Los tipos de variables son: flotante: "f4", entero "i4".\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas.\n'\ + #Si esta o no set el Geomorphology, de acuerdo a eso lo estima por defecto + if self.isSetGeo is False: + self.set_Geomorphology() + print 'Aviso: SE ha estimado la geomorfologia con los umbrales por defecto umbral = [30, 500]' + #Guarda la cuenca + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + Dict = {'nombre':self.name, + 'modelType':self.modelType,'noData':cu.nodata,'umbral':self.umbral, + 'ncells':self.ncells,'nhills':self.nhills, + 'dt':models.dt,'Nelem':N,'dxp':cu.dxp,'retorno':models.retorno, + 'storageConst' :models.storage_constant, + 'ncols':cu.ncols, + 'nrows':cu.nrows, + 'xll':cu.xll, + 'yll':cu.yll, + 'dx':cu.dx, + 'dy':cu.dy, + 'epsg': self.epsg} + if SimSlides: + Dict.update({'sl_fs':models.sl_fs, 'sl_gullie':models.sl_gullienogullie, 'sl_gammaw':models.sl_gammaw}) + #abre el archivo + gr = netcdf.Dataset(ruta,'w',format='NETCDF4') + #Grupo base + GrupoBase = gr.createGroup('base') + GrupoSimHid = gr.createGroup('SimHidro') + GrupoSimSed = gr.createGroup('SimSediments') + GrupoSimSli = gr.createGroup('SimSlides') + GrupoHidro = gr.createGroup('Hidro') + GrupoGeo = gr.createGroup('Geomorfo') + #Variables grupo base + DimNcell = GrupoBase.createDimension('ncell',self.ncells) + DimNhill = GrupoBase.createDimension('nhills',self.nhills) + DimCol3 = GrupoBase.createDimension('col3',3) + DimCol2 = GrupoBase.createDimension('col2',2) + VarStruc = GrupoBase.createVariable('structure','i4',('col3','ncell'),zlib=True) + VarHills = GrupoBase.createVariable('hills','i4',('col2','nhills'),zlib=True) + VarHills_own = GrupoBase.createVariable('hills_own','i4',('ncell',),zlib=True) + VarStruc[:] = self.structure + VarHills[:] = self.hills + VarHills_own[:] = self.hills_own + #Variables de Simulacion hidrologica + DimNelem = GrupoSimHid.createDimension('Nelem',N) + DimCol3 = GrupoSimHid.createDimension('col3',3) + DimCol2 = GrupoSimHid.createDimension('col2',2) + DimCol4 = GrupoSimHid.createDimension('col4',4) + DimCol5 = GrupoSimHid.createDimension('col5',5) + VarH_coef = GrupoSimHid.createVariable('h_coef','f4',('col4','Nelem'),zlib=True) + VarV_coef = GrupoSimHid.createVariable('v_coef','f4',('col4','Nelem'),zlib=True) + VarH_exp = GrupoSimHid.createVariable('h_exp','f4',('col4','Nelem'),zlib=True) + VarV_exp = GrupoSimHid.createVariable('v_exp','f4',('col4','Nelem'),zlib=True) + Var_H1max = GrupoSimHid.createVariable('h1_max','f4',('Nelem',),zlib = True) + Var_H3max = GrupoSimHid.createVariable('h3_max','f4',('Nelem',),zlib = True) + Control = GrupoSimHid.createVariable('control','i4',('Nelem',),zlib = True) + ControlH = GrupoSimHid.createVariable('control_h','i4',('Nelem',),zlib = True) + if self.modelType[0] is 'c': + drena = GrupoSimHid.createVariable('drena','i4',('col3','Nelem'),zlib = True) + elif self.modelType[0] is 'h': + drena = GrupoSimHid.createVariable('drena','i4',('Nelem'),zlib = True) + unitType = GrupoSimHid.createVariable('unit_type','i4',('Nelem',),zlib = True) + hill_long = GrupoSimHid.createVariable('hill_long','f4',('Nelem',),zlib = True) + hill_slope = GrupoSimHid.createVariable('hill_slope','f4',('Nelem',),zlib = True) + stream_long = GrupoSimHid.createVariable('stream_long','f4',('Nelem',),zlib = True) + stream_slope = GrupoSimHid.createVariable('stream_slope','f4',('Nelem',),zlib = True) + stream_width = GrupoSimHid.createVariable('stream_width','f4',('Nelem',),zlib = True) + elem_area = GrupoSimHid.createVariable('elem_area','f4',('Nelem',),zlib = True) + speed_type = GrupoSimHid.createVariable('speed_type','i4',('col3',),zlib = True) + storage = GrupoSimHid.createVariable('storage','i4',('col5','Nelem'),zlib = True) + VarH_coef[:] = models.h_coef + VarV_coef[:] = models.v_coef + VarH_exp[:] = models.h_exp + VarV_exp[:] = models.v_exp + Var_H1max[:] = models.max_capilar + Var_H3max[:] = models.max_gravita + Control[:] = models.control + ControlH[:] = models.control_h + drena[:] = models.drena + unitType[:] = models.unit_type + hill_long[:] = models.hill_long + hill_slope[:] = models.hill_slope + stream_long[:] = models.stream_long + stream_slope[:] = models.stream_slope + stream_width[:] = models.stream_width + elem_area[:] = models.elem_area + speed_type[:] = models.speed_type + storage[:] = models.storage + #Variables grupo GEomorfologia + DimNcell = GrupoGeo.createDimension('ncell',self.ncells) + VarDEM = GrupoGeo.createVariable('DEM','f4',('ncell',),zlib = True) + VarDIR = GrupoGeo.createVariable('DIR','i4',('ncell',),zlib = True) + VarDEM[:] = self.DEMvec + VarDIR[:] = self.DIRvec + #Variables de deslizamientos + if SimSlides: + DimNelem = GrupoSimSli.createDimension('Nelem',N) + frictionAngle = GrupoSimSli.createVariable('friction_angle','f4',('Nelem',),zlib = True) + Cohesion = GrupoSimSli.createVariable('cohesion','f4',('Nelem',),zlib = True) + GammaSoil = GrupoSimSli.createVariable('gamma_soil','f4',('Nelem',),zlib = True) + ZSoil = GrupoSimSli.createVariable('z_soil','f4',('Nelem',),zlib = True) + RadSlope = GrupoSimSli.createVariable('rad_slope','f4',('Nelem',),zlib = True) + frictionAngle[:] = models.sl_frictionangle + Cohesion[:] = models.sl_cohesion + GammaSoil[:] = models.sl_gammas + ZSoil[:] = models.sl_zs + RadSlope[:] = models.sl_radslope + #Introduce variables extras en caso de que el usuario las incluyera + if type(ExtraVar) is dict: + for k in ExtraVar.keys(): + Var = gr.createVariable(k,ExtraVar[k]['type'],('ncell',),zlib=True) + Var[:] = ExtraVar[k]['Data'] + #asigna las prop a la cuenca + gr.setncatts(Dict) + #Cierra el archivo + gr.close() + #Sale del programa + return + def Save_SimuBasin(self,ruta,SimSlides = False, ExtraVar = None): 'Descripcion: guarda una cuenca previamente ejecutada\n'\ From 504ba6111cdaa2d12a6a26995f76ac8c3ed3d27f Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 20 Jun 2018 16:29:25 -0500 Subject: [PATCH 056/142] Cambio del todo en la forma de escribir los netCDF de la cuenca, eso nos da mas versatilidad ya que existen grupos, falta cambiar la manera en que se despliegan los NC en Qgis, ya que la version anterior no es compatible con esta nueva. --- qgisplugin/HydroSEDPluginUtils.py | 36 ++--- wmf/wmf.py | 238 +----------------------------- 2 files changed, 22 insertions(+), 252 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index fba0668..6a00051 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -172,23 +172,25 @@ def Basin_LoadBasin(self, PathNC): self.cuenca = wmf.SimuBasin(rute = PathNC) #Cargar las variables de la cuenca a un diccionario. g = netCDF4.Dataset(PathNC) - for k in g.variables.keys(): - #Evalua si tiene la misma cantidad de celdas y puede ser un mapa - shape = g.variables[k].shape - MapaRaster = False - for s in shape: - if s == self.cuenca.ncells: - MapaRaster = True - #Actualiza el diccionario - self.DicBasinNc.update({k: - {'nombre':k, - 'tipo':g.variables[k].dtype.name, - 'shape':g.variables[k].shape, - 'raster':MapaRaster, - 'basica': True, - 'categoria': 'Base'}}) - self.NumDicBasinNcVariables = self.NumDicBasinNcVariables + 1 - self.NumDicBasinNcVariablesBasicas = self.NumDicBasinNcVariablesBasicas + 1 + for grupoKey in ['base','Geomorfo']: + for k in g.groups[grupoKey].variables.keys(): + #Evalua si tiene la misma cantidad de celdas y puede ser un mapa + shape = g.groups[grupoKey].variables[k].shape + MapaRaster = False + for s in shape: + if s == self.cuenca.ncells: + MapaRaster = True + #Actualiza el diccionario + self.DicBasinNc.update({k: + {'nombre':k, + 'tipo':g.groups[grupoKey].variables[k].dtype.name, + 'shape':g.groups[grupoKey].variables[k].shape, + 'raster':MapaRaster, + 'basica': True, + 'categoria': grupoKey, + 'var': g.groups[grupoKey].variables[k][:]}}) + self.NumDicBasinNcVariables = self.NumDicBasinNcVariables + 1 + self.NumDicBasinNcVariablesBasicas = self.NumDicBasinNcVariablesBasicas + 1 g.close() #Cargar la cuenca y sus variables base a WMF self.cuenca = wmf.SimuBasin(rute = PathNC) diff --git a/wmf/wmf.py b/wmf/wmf.py index 4587e64..d8a0561 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -2861,11 +2861,11 @@ def __init__(self,lat=None,lon=None,DEM=None,DIR=None,rute = None, name='NaN',st self.isSetGeo = False # si hay tura lee todo lo de la cuenca elif rute is not None: - self.__Load_SimuBasin2(rute, SimSlides) + self.__Load_SimuBasin(rute, SimSlides) # Obtiene la envolvente de la cuenca self.__GetBasinPolygon__() - def __Load_SimuBasin2(self,ruta, sim_slides = False): + def __Load_SimuBasin(self,ruta, sim_slides = False): 'Descripcion: Lee una cuenca posteriormente guardada\n'\ ' La cuenca debio ser guardada con SimuBasin.save_SimuBasin\n'\ '\n'\ @@ -2967,106 +2967,6 @@ def __Load_SimuBasin2(self,ruta, sim_slides = False): #Determina que por defecto debe estar set la geomorfologia self.isSetGeo = True - - def __Load_SimuBasin(self,ruta, sim_slides = False): - 'Descripcion: Lee una cuenca posteriormente guardada\n'\ - ' La cuenca debio ser guardada con SimuBasin.save_SimuBasin\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'ruta : ruta donde se encuentra ubicada la cuenca guardada\n'\ - 'Opcionales\n'\ - '----------\n'\ - 'sim_slides : (False, True) Carga variables de modelos de deslizamientos previmaente guardadas.\n'\ - 'sim_sed : (False, True) Carga variables de modelo de sedimentos previamente guardadas\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : La cuenca con sus parametros ya cargada.\n'\ - #Abre el archivo binario de la cuenca - self.rutaNC = ruta - gr = netcdf.Dataset(ruta,'a') - #obtiene las prop de la cuenca - self.name = gr.nombre - self.modelType = gr.modelType.encode() - self.nodata = gr.noData - self.umbral = gr.umbral - self.ncells = gr.ncells - self.nhills = gr.nhills - self.epsg = gr.epsg - models.dt = gr.dt - models.dxp = gr.dxp - models.retorno = gr.retorno - try: - models.storage_constant = gr.storageConst - except: - models.storage_constant = 0.0 - #Si carga deslizamientos - if sim_slides: - models.sim_slides = 1 - models.sl_fs = gr.sl_fs - models.gullienogullie = gr.sl_gullie - models.sl_gammaw = gr.sl_gammaw - #Nueva metodologia de geoespacial de la cuenca - cu.ncols = gr.ncols - cu.nrows = gr.nrows - cu.xll = gr.xll - cu.yll = gr.yll - cu.dx = gr.dx - cu.dy = gr.dy - cu.dxp = gr.dxp - cu.nodata = gr.noData - #de acuerdo al tipo de modeloe stablece numero de elem - if self.modelType[0] is 'c': - N = self.ncells - elif self.modelType[0] is 'h': - N = self.nhills - #Obtiene las variables vectoriales - self.structure = gr.variables['structure'][:] - self.hills = gr.variables['hills'][:] - self.hills_own = gr.variables['hills_own'][:] - self.DEMvec = gr.variables['DEM'][:] - self.DIRvec = gr.variables['DIR'][:] - self.DEM = self.Transform_Basin2Map(self.DEMvec) - self.DIR = self.Transform_Basin2Map(self.DIRvec) - #obtiene las propieades del modelo - models.h_coef = np.ones((4,N)) * gr.variables['h_coef'][:] - models.v_coef = np.ones((4,N)) * gr.variables['v_coef'][:] - models.h_exp = np.ones((4,N)) * gr.variables['h_exp'][:] - models.v_exp = np.ones((4,N)) * gr.variables['v_exp'][:] - models.max_capilar = np.ones((1,N)) * gr.variables['h1_max'][:] - models.max_gravita = np.ones((1,N)) * gr.variables['h3_max'][:] - #Variable de drena de acuerdo al tipo de modelo - if self.modelType[0] is 'c': - models.drena = np.ones((3,N)) *gr.variables['drena'][:] - elif self.modelType[0] is 'h': - models.drena = np.ones((1,N)) * gr.variables['drena'][:] - models.unit_type = np.ones((1,N)) * gr.variables['unit_type'][:] - models.hill_long = np.ones((1,N)) * gr.variables['hill_long'][:] - models.hill_slope = np.ones((1,N)) * gr.variables['hill_slope'][:] - models.stream_long = np.ones((1,N)) * gr.variables['stream_long'][:] - models.stream_slope = np.ones((1,N)) * gr.variables['stream_slope'][:] - models.stream_width = np.ones((1,N)) * gr.variables['stream_width'][:] - models.elem_area = np.ones((1,N)) * gr.variables['elem_area'][:] - models.speed_type = np.ones((3)) * gr.variables['speed_type'][:] - models.storage = np.ones((5,N)) * gr.variables['storage'][:] - - #propiedades de puntos de control - models.control = np.ones((1,N)) * gr.variables['control'][:] - models.control_h = np.ones((1,N)) * gr.variables['control_h'][:] - - #Propiedades de deslizamientos - if sim_slides: - models.sl_gammas = np.ones((1,N)) * gr.variables['gamma_soil'][:] - models.sl_cohesion = np.ones((1,N)) * gr.variables['cohesion'][:] - models.sl_frictionangle = np.ones((1,N)) * gr.variables['friction_angle'][:] - models.sl_radslope = np.ones((1,N)) * gr.variables['rad_slope'][:] - models.sl_zs = np.ones((1,N)) * gr.variables['z_soil'][:] - #Cierra el archivo - gr.close() - #Determina que por defecto debe estar set la geomorfologia - self.isSetGeo = True - #------------------------------------------------------ # Subrutinas de lluvia, interpolacion, lectura, escritura, agrega funcion para variar evp en # el tiempo @@ -3986,7 +3886,7 @@ def set_Slides(self,var,VarName): #------------------------------------------------------ # Guardado y Cargado de modelos de cuencas preparados #------------------------------------------------------ - def Save_SimuBasin2(self,ruta,SimSlides = False, + def Save_SimuBasin(self,ruta,SimSlides = False, ExtraVar = None): 'Descripcion: guarda una cuenca previamente ejecutada\n'\ '\n'\ @@ -4123,138 +4023,6 @@ def Save_SimuBasin2(self,ruta,SimSlides = False, #Sale del programa return - def Save_SimuBasin(self,ruta,SimSlides = False, - ExtraVar = None): - 'Descripcion: guarda una cuenca previamente ejecutada\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'ruta : Ruta donde la cuenca sera guardada.\n'\ - 'ruta_dem : direccion donde se aloja el DEM (se recomienda absoluta).\n'\ - 'ruta_dir : direccion donde se aloja el DIR (se recomienda absoluta).\n'\ - 'SimSlides: indica a la funcion si va a guardar o no informacion para la simulacion.\n'\ - ' de deslizamientos.\n'\ - 'ExtraVar: Variables extras de simulacion deben ir en un diccionario.\n'\ - ' Forma del diccionario Dict = {"varName": {"Data": vector[ncells], "type": "tipo"}}.\n'\ - ' Los tipos de variables son: flotante: "f4", entero "i4".\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con las variables iniciadas.\n'\ - #Si esta o no set el Geomorphology, de acuerdo a eso lo estima por defecto - if self.isSetGeo is False: - self.set_Geomorphology() - print 'Aviso: SE ha estimado la geomorfologia con los umbrales por defecto umbral = [30, 500]' - #Guarda la cuenca - if self.modelType[0] is 'c': - N = self.ncells - elif self.modelType[0] is 'h': - N = self.nhills - Dict = {'nombre':self.name, - 'modelType':self.modelType,'noData':cu.nodata,'umbral':self.umbral, - 'ncells':self.ncells,'nhills':self.nhills, - 'dt':models.dt,'Nelem':N,'dxp':cu.dxp,'retorno':models.retorno, - 'storageConst' :models.storage_constant, - 'ncols':cu.ncols, - 'nrows':cu.nrows, - 'xll':cu.xll, - 'yll':cu.yll, - 'dx':cu.dx, - 'dy':cu.dy, - 'epsg': self.epsg} - if SimSlides: - Dict.update({'sl_fs':models.sl_fs, 'sl_gullie':models.sl_gullienogullie, 'sl_gammaw':models.sl_gammaw}) - #abre el archivo - gr = netcdf.Dataset(ruta,'w',format='NETCDF4') - #Variables del DEM y del DIR - #DEMdim = gr.createDimension('ncols',DEM - #Establece tamano de las variables - DimNcell = gr.createDimension('ncell',self.ncells) - DimNhill = gr.createDimension('nhills',self.nhills) - DimNelem = gr.createDimension('Nelem',N) - DimCol3 = gr.createDimension('col3',3) - DimCol2 = gr.createDimension('col2',2) - DimCol4 = gr.createDimension('col4',4) - DimCol5 = gr.createDimension('col5',5) - #Crea variables - VarDEM = gr.createVariable('DEM','f4',('ncell',),zlib = True) - VarDIR = gr.createVariable('DIR','i4',('ncell',),zlib = True) - VarStruc = gr.createVariable('structure','i4',('col3','ncell'),zlib=True) - VarHills = gr.createVariable('hills','i4',('col2','nhills'),zlib=True) - VarHills_own = gr.createVariable('hills_own','i4',('ncell',),zlib=True) - VarH_coef = gr.createVariable('h_coef','f4',('col4','Nelem'),zlib=True) - VarV_coef = gr.createVariable('v_coef','f4',('col4','Nelem'),zlib=True) - VarH_exp = gr.createVariable('h_exp','f4',('col4','Nelem'),zlib=True) - VarV_exp = gr.createVariable('v_exp','f4',('col4','Nelem'),zlib=True) - Var_H1max = gr.createVariable('h1_max','f4',('Nelem',),zlib = True) - Var_H3max = gr.createVariable('h3_max','f4',('Nelem',),zlib = True) - Control = gr.createVariable('control','i4',('Nelem',),zlib = True) - ControlH = gr.createVariable('control_h','i4',('Nelem',),zlib = True) - if self.modelType[0] is 'c': - drena = gr.createVariable('drena','i4',('col3','Nelem'),zlib = True) - elif self.modelType[0] is 'h': - drena = gr.createVariable('drena','i4',('Nelem'),zlib = True) - unitType = gr.createVariable('unit_type','i4',('Nelem',),zlib = True) - hill_long = gr.createVariable('hill_long','f4',('Nelem',),zlib = True) - hill_slope = gr.createVariable('hill_slope','f4',('Nelem',),zlib = True) - stream_long = gr.createVariable('stream_long','f4',('Nelem',),zlib = True) - stream_slope = gr.createVariable('stream_slope','f4',('Nelem',),zlib = True) - stream_width = gr.createVariable('stream_width','f4',('Nelem',),zlib = True) - elem_area = gr.createVariable('elem_area','f4',('Nelem',),zlib = True) - speed_type = gr.createVariable('speed_type','i4',('col3',),zlib = True) - storage = gr.createVariable('storage','i4',('col5','Nelem'),zlib = True) - #Variables de deslizamientos - if SimSlides: - frictionAngle = gr.createVariable('friction_angle','f4',('Nelem',),zlib = True) - Cohesion = gr.createVariable('cohesion','f4',('Nelem',),zlib = True) - GammaSoil = gr.createVariable('gamma_soil','f4',('Nelem',),zlib = True) - ZSoil = gr.createVariable('z_soil','f4',('Nelem',),zlib = True) - RadSlope = gr.createVariable('rad_slope','f4',('Nelem',),zlib = True) - #Asigna valores a las variables - VarDEM[:] = self.DEMvec - VarDIR[:] = self.DIRvec - VarStruc[:] = self.structure - VarHills[:] = self.hills - VarHills_own[:] = self.hills_own - VarH_coef[:] = models.h_coef - VarV_coef[:] = models.v_coef - VarH_exp[:] = models.h_exp - VarV_exp[:] = models.v_exp - Var_H1max[:] = models.max_capilar - Var_H3max[:] = models.max_gravita - Control[:] = models.control - ControlH[:] = models.control_h - drena[:] = models.drena - unitType[:] = models.unit_type - hill_long[:] = models.hill_long - hill_slope[:] = models.hill_slope - stream_long[:] = models.stream_long - stream_slope[:] = models.stream_slope - stream_width[:] = models.stream_width - elem_area[:] = models.elem_area - speed_type[:] = models.speed_type - storage[:] = models.storage - - #Asigna valores de deslizamientos - if SimSlides: - frictionAngle[:] = models.sl_frictionangle - Cohesion[:] = models.sl_cohesion - GammaSoil[:] = models.sl_gammas - ZSoil[:] = models.sl_zs - RadSlope[:] = models.sl_radslope - - #Introduce variables extras en caso de que el usuario las incluyera - if type(ExtraVar) is dict: - for k in ExtraVar.keys(): - Var = gr.createVariable(k,ExtraVar[k]['type'],('ncell',),zlib=True) - Var[:] = ExtraVar[k]['Data'] - #asigna las prop a la cuenca - gr.setncatts(Dict) - #Cierra el archivo - gr.close() - #Sale del programa - return - #------------------------------------------------------ # Ejecucion del modelo #------------------------------------------------------ From 6aae855b4d1db2ac1fa5c3996d63af01397a3003 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 21 Jun 2018 11:29:23 -0500 Subject: [PATCH 057/142] se incluye la herramienta para importar mapas raster en el WMF que luego pueden ser importados a la cuenca como tal. --- qgisplugin/HydroSEDPluginUtils.py | 71 +++++--- qgisplugin/HydroSEDPlugin_dockwidget.py | 53 +++++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 173 ++++++++++++++++++- 3 files changed, 258 insertions(+), 39 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 6a00051..6446658 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -172,25 +172,25 @@ def Basin_LoadBasin(self, PathNC): self.cuenca = wmf.SimuBasin(rute = PathNC) #Cargar las variables de la cuenca a un diccionario. g = netCDF4.Dataset(PathNC) - for grupoKey in ['base','Geomorfo']: - for k in g.groups[grupoKey].variables.keys(): - #Evalua si tiene la misma cantidad de celdas y puede ser un mapa - shape = g.groups[grupoKey].variables[k].shape - MapaRaster = False - for s in shape: - if s == self.cuenca.ncells: - MapaRaster = True - #Actualiza el diccionario - self.DicBasinNc.update({k: - {'nombre':k, - 'tipo':g.groups[grupoKey].variables[k].dtype.name, - 'shape':g.groups[grupoKey].variables[k].shape, - 'raster':MapaRaster, - 'basica': True, - 'categoria': grupoKey, - 'var': g.groups[grupoKey].variables[k][:]}}) - self.NumDicBasinNcVariables = self.NumDicBasinNcVariables + 1 - self.NumDicBasinNcVariablesBasicas = self.NumDicBasinNcVariablesBasicas + 1 + for grupoKey in ['base','Geomorfo']: + for k in g.groups[grupoKey].variables.keys(): + #Evalua si tiene la misma cantidad de celdas y puede ser un mapa + shape = g.groups[grupoKey].variables[k].shape + MapaRaster = False + for s in shape: + if s == self.cuenca.ncells: + MapaRaster = True + #Actualiza el diccionario + self.DicBasinNc.update({k: + {'nombre':k, + 'tipo':g.groups[grupoKey].variables[k].dtype.name, + 'shape':g.groups[grupoKey].variables[k].shape, + 'raster':MapaRaster, + 'basica': True, + 'categoria': grupoKey, + 'var': g.groups[grupoKey].variables[k][:]}}) + self.NumDicBasinNcVariables = self.NumDicBasinNcVariables + 1 + self.NumDicBasinNcVariablesBasicas = self.NumDicBasinNcVariablesBasicas + 1 g.close() #Cargar la cuenca y sus variables base a WMF self.cuenca = wmf.SimuBasin(rute = PathNC) @@ -206,15 +206,11 @@ def Basin_LoadBasinNetwork(self, PathNetwork): # Guarda los shapes de divisoria y de red hidrica. self.cuenca.Save_Net2Map(PathNetwork, wmf.cu.dxp, self.cuenca.umbral) - def Basin_LoadBasicVariable(self,PathNC, VarName): + def Basin_LoadVariableFromDicNC(self, VarName): '''Toma una variable del diccionario de variables basicas y la carga a Qgis''' - #Lee los datos del nc de la cuenca de la variable indicada - g = netCDF4.Dataset(PathNC) - Data = g.variables[VarName][:] - g.close() #Transforma a un raster - rutaSalida = '/tmp/HydroSED/Raster_'+VarName+'.tiff' - self.cuenca.Transform_Basin2Map(Data, + rutaSalida = '/tmp/HydroSED/'+VarName+'.tiff' + self.cuenca.Transform_Basin2Map(self.DicBasinNc[VarName]['var'], ruta = rutaSalida, EPSG = self.cuenca.epsg) return rutaSalida @@ -222,12 +218,33 @@ def Basin_LoadBasicVariable(self,PathNC, VarName): def Basin_LoadVariableFromDicWMF(self,VarName): '''Toma una variable del diccionario de variables basicas y la carga a Qgis''' #Transforma a un raster - rutaSalida = '/tmp/HydroSED/Raster_'+VarName+'.tiff' + rutaSalida = '/tmp/HydroSED/'+VarName+'.tiff' self.cuenca.Transform_Basin2Map(self.DicBasinWMF[VarName]['var'], ruta = rutaSalida, EPSG = self.cuenca.epsg) return rutaSalida + def Basin_Raster2WMF(self, VarName, VarPath, VarGroup): + '''toma una ruta y convierte un mapa raster a cuenca para luego ponerlo + en el diccionario de WMF''' + #Lee la variable + Var, prop, epsg = wmf.read_map_raster(VarPath) + if epsg == self.cuenca.epsg: + #Convierte a cuenca + Var = self.cuenca.Transform_Map2Basin(Var, prop) + #Actualiza el diccionario de WMF + self.DicBasinWMF.update({VarName: + {'nombre':VarName, + 'tipo':Var.dtype.name, + 'shape':Var.shape, + 'raster':True, + 'basica': False, + 'categoria': VarGroup, + 'var': Var}}) + return 0 + else: + return 1 + def Basin_GeoGetHAND(self, umbral): self.cuenca.GetGeo_HAND(umbral) self.DicBasinWMF.update({'HAND': diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 9489289..e07599b 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -62,6 +62,11 @@ def __init__(self, iface = None, parent=None): self.TablaFila_WMF = 0 self.TablaFila_NC = 0 + #Inicia el comboBox de la seleccion de categoria para transformar raster a WMF + for k in ['base','Geomorfo','SimHidro','Hidro']: + self.ComboBoxRaster2WMF.addItem(k) + self.setupRaster2WMF() + if not (iface is None): self.iface = iface self.HSutils = HSutils.controlHS() @@ -143,8 +148,6 @@ def setupBasinManager(self): def setupLineEditButtonOpenBasinFileDialog (lineEditHolder, fileDialogHolder): '''Busca un proyecto de cuenca ya guardado anteriormente''' - #lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), 'Open File',"", - # QtGui.QFileDialog.DontUseNativeDialog)) lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "Cargador de cuencas", "*","Cuenca en NetCDF4(*.nc);;", QtGui.QFileDialog.DontUseNativeDialog)) @@ -286,7 +289,47 @@ def TableStart (self): '''Arranca las tablas de NC y WMF''' self.TabNC = Tabla(self.HSutils.NumDicBasinNcVariables,self.Tabla_Prop_NC) self.TabWMF = Tabla(self.HSutils.NumDicBasinWMFVariables, self.Tabla_Prop_WMF) + + def setupRaster2WMF(self): + + def setupLineEditButtonOpenRasterFileDialog (lineEditHolder, fileDialogHolder): + '''Hace que solo0 se busquen formatos aceptados por GDAL''' + lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), 'Open File',"", GdalTools_utils.FileFilter.allRastersFilter (), + QtGui.QFileDialog.DontUseNativeDialog)) + def clickEventSelectorMapaRaster(): + '''Evento de click: selecciona mapa Raster''' + setupLineEditButtonOpenRasterFileDialog (self.PathRaster2WMF, QFileDialog) + + #Funciones para Cargar variables + def clickEventSelectorRaster(): + '''click para seleccionar un proyecto de cuenca''' + #Pone el texto de la ruta + setupLineEditButtonOpenRasterFileDialog(self.PathRaster2WMF, QFileDialog) + + #Funcion para pasar variable raster a WMF + def handleClickConnectRaster2WMF(): + #Chequeos de variables + #if len(self.NameRaster2WMF.text())<2: + # self.iface.messageBar().pushError (u'Hydro-SIG:', u'Debe ingresar un nombre para el mapa raster a convertir.') + # return 1 + #if len(self.PathRaster2WMF.text())<2: + # self.iface.messageBar().pushError (u'Hydro-SIG:', u'Debe seleccionar un mapa raster para ser convertido a la cuenca.') + # return 1 + #Parametros para la conversion + Nombre = self.NameRaster2WMF.text() + PathRaster = self.PathRaster2WMF.text() + Grupo = self.ComboBoxRaster2WMF.currentText() + #Conversion, convierte la variable y actualiza el diccionario. + Retorno = self.HSutils.Basin_Raster2WMF(Nombre, PathRaster, Grupo) + self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[Nombre],Nombre, self.Tabla_Prop_WMF) + if Retorno == 0: + self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'El mapa raster ha ingresado a WMF.') + #Habilita botones. + self.ButtonPathRaster2WMF.clicked.connect(clickEventSelectorMapaRaster) + self.Button_Raster2WMF.clicked.connect(handleClickConnectRaster2WMF) + + def setupUIInputsOutputs (self): def handleClickEventButton_Eliminar_Desde_WMF (): @@ -314,12 +357,10 @@ def handleClickEventButton_Actualizar_WMF_Desde_NC (): def handleClickEventButton_Ver_Desde_NC(): '''Visualiza una de las variables de la cuenca en Qgis''' - #Variables de entrada + #Ejecucion de la transformacion de la variable cuenca a raster selectedItems = self.Tabla_Prop_NC.currentRow () VarName = self.Tabla_Prop_NC.item(selectedItems,0).text() - PathNC = self.lineEditRutaCuenca.text() - #Ejecucion de la transformacion de la variable cuenca a raster - pathMapa = self.HSutils.Basin_LoadBasicVariable(PathNC, VarName) + pathMapa = self.HSutils.Basin_LoadVariableFromDicNC(VarName) print pathMapa #Visualiza flagCargaMapa = self.HSutils.cargar_mapa_raster(pathMapa) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index e3678e1..6bb13aa 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -6,7 +6,7 @@ 0 0 - 493 + 489 936 @@ -306,9 +306,9 @@ 0 - -190 + -206 443 - 918 + 2018 @@ -329,7 +329,7 @@ 300 - 900 + 2000 @@ -344,7 +344,7 @@ 0 0 425 - 855 + 1081 @@ -711,10 +711,13 @@ Qt::Vertical + + QSizePolicy::Minimum + 20 - 80 + 20 @@ -733,6 +736,161 @@ + + + + Qt::Horizontal + + + + + + + + 0 + 100 + + + + Convertir raster a cuenca. + + + + + 10 + 20 + 401 + 71 + + + + + + + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + Ruta mapa raster + + + + + + + + 290 + 16777215 + + + + true + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + Nombre: + + + + + + + + 290 + 16777215 + + + + false + + + + + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + Categoría: + + + + + + + + + + Ejecutar la función de trazado de corriente. + + + Ejecutar la función de trazado de corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + + + + Qt::Horizontal + + + @@ -852,6 +1010,9 @@ + + false + 50 From ebac3ac3e244fff939a291a362555dc4ab430174 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 4 Jul 2018 15:26:23 -0500 Subject: [PATCH 058/142] ya comienza a funcionar el modulo que calcula la geomorfologia de raster, falta configurar algunas variables. --- qgisplugin/HydroSEDPluginUtils.py | 44 +- qgisplugin/HydroSEDPlugin_dockwidget.py | 34 +- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 1080 +++++++++--------- qgisplugin/icons/RedHidrica.ico | Bin 0 -> 32988 bytes qgisplugin/icons/toexcel.png | Bin 0 -> 27543 bytes qgisplugin/resources.qrc | 2 + 6 files changed, 626 insertions(+), 534 deletions(-) create mode 100644 qgisplugin/icons/RedHidrica.ico create mode 100644 qgisplugin/icons/toexcel.png diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 6446658..082df43 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -112,9 +112,9 @@ def trazador_corriente(self,x,y, path = None): def trazador_cuenca(self,x,y, dxp,umbral,PathDiv, PathRed, PathNC,PathDEM, PathDIR,TopoNodes = False, LastStream = True): # Traza la cuenca con y sin la ultima corriente. if LastStream: - self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR, stream=self.stream) + self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR, stream=self.stream, umbral = umbral) else: - self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR) + self.cuenca = wmf.SimuBasin(x, y, self.DEM, self.DIR, umbral = umbral) # Guarda los shapes de divisoria y de red hidrica. self.cuenca.Save_Basin2Map(PathDiv, dxp) self.cuenca.Save_Net2Map(PathRed, dxp, umbral) @@ -196,7 +196,7 @@ def Basin_LoadBasin(self, PathNC): self.cuenca = wmf.SimuBasin(rute = PathNC) self.NumDicBasinWMFVariables = 50 #Area de la cuenca y codigo EPSG - return self.cuenca.ncells*wmf.cu.dxp**2./1e6, self.cuenca.epsg, wmf.models.dxp, wmf.cu.nodata + return self.cuenca.ncells*wmf.cu.dxp**2./1e6, self.cuenca.epsg, wmf.models.dxp, wmf.cu.nodata, self.cuenca.umbral def Basin_LoadBasinDivisory(self, PathDivisory): # Guarda los shapes de divisoria y de red hidrica. @@ -245,6 +245,44 @@ def Basin_Raster2WMF(self, VarName, VarPath, VarGroup): else: return 1 + def Basin_GeoGetAcumSlope(self): + self.cuenca.GetGeo_Cell_Basics() + self.DicBasinWMF.update({'Area': + {'nombre':'Area', + 'tipo':'float32', + 'shape':self.cuenca.CellAcum.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geo', + 'var': self.cuenca.CellAcum}}) + self.DicBasinWMF.update({'Pendiente': + {'nombre':'Pendiente', + 'tipo':'float32', + 'shape':self.cuenca.CellSlope.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geo', + 'var': self.cuenca.CellSlope}}) + + def Basin_GeoGetOrder(self): + self.cuenca.GetGeo_StreamOrder(umbral = self.cuenca.umbral) + self.DicBasinWMF.update({'Order_hills': + {'nombre':'Order_hills', + 'tipo':self.cuenca.CellHorton_Hill.dtype.name, + 'shape':self.cuenca.CellHorton_Hill.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geo', + 'var': self.cuenca.CellHorton_Hill}}) + self.DicBasinWMF.update({'Order_channels': + {'nombre':'Order_channels', + 'tipo':self.cuenca.CellHorton_Stream.dtype.name, + 'shape':self.cuenca.CellHorton_Stream.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geo', + 'var': self.cuenca.CellHorton_Stream}}) + def Basin_GeoGetHAND(self, umbral): self.cuenca.GetGeo_HAND(umbral) self.DicBasinWMF.update({'HAND': diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index e07599b..61cbf8c 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -57,6 +57,7 @@ def __init__(self, iface = None, parent=None): self.setupUIInputsOutputs () self.setupHidro_Balance() self.setupBasinManager() + self.setupGeomorfologia() #self.setupUIButtonEvents () self.TablaFila_WMF = 0 @@ -165,7 +166,8 @@ def clickEventBasin2WMF(): self.TableStart() for k in self.HSutils.DicBasinNc.keys(): self.TabNC.NewEntry(self.HSutils.DicBasinNc[k],k, self.Tabla_Prop_NC) - Area, self.EPSG, dxp, self.noData = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip()) + Area, self.EPSG, dxp, self.noData, self.umbral = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip()) + #print self.umbral #Habilita los botones de visualizacion de red hidrica y divisoria self.Boton_verDivisoria.setEnabled(True) self.Boton_verRedHidrica.setEnabled(True) @@ -176,7 +178,7 @@ def clickEventBasin2WMF(): texto = '%.1f' % self.noData self.LineEditNoData.setText(texto) self.spinBox_dxPlano.setValue(dxp) - print dxp + self.SpinGeoUmbralCanal.setValue(self.umbral) def clickEventBasinLoadDivisory(): '''Carga la divisoria de la cuenca cargada a WMF''' @@ -203,14 +205,29 @@ def clickEventBasinLoadNetwork(): self.Boton_verRedHidrica.clicked.connect(clickEventBasinLoadNetwork) def setupGeomorfologia(self): - - def clickEventGeoHAND(): - self.HSutils.Basin_GeoGetHAND(1000) + '''Conjunto de herramientas para manejar parametros geomorfologicos de la cuenca analizada''' + + def clickEventGeoRasterProp(): + '''calcula los parametros geomorfologicos de la cuenca por raster''' + #Lista de variables a calcular + ListaVar = [] + #Revisa cada checkbox + if self.checkBoxArea.isChecked(): + self.HSutils.Basin_GeoGetAcumSlope() + ListaVar.extend(['Area','Pendiente']) + if self.checkBoxOrder.isChecked(): + self.HSutils.Basin_GeoGetOrder() + ListaVar.extend(['Order_hills','Order_channels']) + + + #mensaje de caso de exito + self.iface.messageBar().pushInfo(u'HidroSIG:',u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.') #Actualiza la tabla de variables temporales - self.UpdateTablePropWMF() + for k in ListaVar: + self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[k],k, self.Tabla_Prop_WMF) #Botones de ejecucion - self.BotonGeoHAND.clicked.connect(clickEventGeoHAND) + self.ButtonGeomorfoRasterVars.clicked.connect(clickEventGeoRasterProp) def setupHidro_Balance(self): @@ -361,7 +378,6 @@ def handleClickEventButton_Ver_Desde_NC(): selectedItems = self.Tabla_Prop_NC.currentRow () VarName = self.Tabla_Prop_NC.item(selectedItems,0).text() pathMapa = self.HSutils.Basin_LoadVariableFromDicNC(VarName) - print pathMapa #Visualiza flagCargaMapa = self.HSutils.cargar_mapa_raster(pathMapa) if flagCargaMapa: @@ -375,7 +391,6 @@ def handleClickEventButton_Ver_Desde_WMF(): selectedItems = self.Tabla_Prop_WMF.currentRow () VarName = self.Tabla_Prop_WMF.item(selectedItems,0).text() pathMapa = self.HSutils.Basin_LoadVariableFromDicWMF(VarName) - print pathMapa #Visualiza flagCargaMapa = self.HSutils.cargar_mapa_raster(pathMapa) if flagCargaMapa: @@ -543,7 +558,6 @@ def clickEventSelectorOutputCuencaNCTrazadorCuencas (): def set_dxplano(): #self.spinBox_dxPlano.valueFromText() self.spinBox_dxPlano.value() - print self.spinBox_dxPlano.value() self.spinBox_dxPlano.valueChanged.connect(set_dxplano) #Botones de borrado de variables de NC y WMF diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 6bb13aa..bd904ef 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -96,19 +96,6 @@ - - - - Coordenada en X del punto de inicio. - - - Coordenada en X del punto de inicio. - - - Cuenca: - - - @@ -122,13 +109,6 @@ - - - - Qt::Vertical - - - @@ -235,6 +215,9 @@ Cuenca: + verticalLayoutWidget_3 + labelLongitudTrazadorCorrientes_17 + tabPanelDockOpciones @@ -262,7 +245,7 @@ - 0 + 3 @@ -306,7 +289,7 @@ 0 - -206 + 0 443 2018 @@ -344,7 +327,7 @@ 0 0 425 - 1081 + 1147 @@ -902,7 +885,7 @@ <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Propiedades mapas WMF + Variables WMF @@ -919,6 +902,47 @@ + + + + false + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Qt::DefaultContextMenu + + + Convertir variable a red hídrica (promedia celdas del tramo). + + + Convertir variable a red hídrica (promedia celdas del tramo). + + + + + + + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico + + + + 16 + 16 + + + + @@ -933,6 +957,12 @@ 16777215 + + Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + + + Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + @@ -991,7 +1021,7 @@ <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Propiedades mapas NC + Variables NC @@ -1087,6 +1117,47 @@ + + + + false + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Qt::DefaultContextMenu + + + Convertir variable a red hídrica (promedia celdas del tramo). + + + Convertir variable a red hídrica (promedia celdas del tramo). + + + + + + + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico + + + + 16 + 16 + + + + @@ -1144,10 +1215,6 @@ - - - :/plugins/HydroSEDPlugin/icons/cuenca.ico:/plugins/HydroSEDPlugin/icons/cuenca.ico - Trazadores @@ -1897,10 +1964,6 @@ - - - :/plugins/HydroSEDPlugin/icons/cuenca.ico:/plugins/HydroSEDPlugin/icons/cuenca.ico - Hidrología @@ -2323,7 +2386,11 @@ Ejecuta el balance de largo plazo con los parametros dados. - Ejecutar + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3033,536 +3100,507 @@ 50000 - + 0 - 0 - 431 - 100 + 320 + 421 + 271 - - - 0 - 100 - - - - - 16777215 - 16777215 - - - Obtiene celda a celda: pendiente, acumulado, long de celdas y elevacion. + Calcúla características geomorfológicas ráster de la cuenca. - - Parametros basicos geomorfologicos + + Calcúla características geomorfológicas ráster de la cuenca. - - false + + Geomorfología Raster - - - - - - - - 0 - 10 - - - - - 75 - true - - - - Datos de entrada: - - - - - - - - - Umbral - - - - - - - false - - - - - - - Ejecuta el balance de largo plazo con los parametros dados. - - - Ejecuta el balance de largo plazo con los parametros dados. - - - Ejecutar - - - - - - - - + + + + 10 + 30 + 401 + 236 + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Calcular mapas raster de área acumulada y pendiente (Area, Pendiente). + + + Calcular mapas raster de área acumulada y pendiente (Area, Pendiente). + + + Área, Pendiente. + + + + + + + Calcular mapas raster con el orden de strahler. (Order_hills, Order_channels) + + + Calcular mapas raster con el orden de strahler. (Order_hills, Order_channels) + + + Orden de canales y laderas + + + + + + + Calcula mapas raster de la elevación relativa al canal (Rennó, 2008) (HAND, HDND, HAND_class) + + + Calcula mapas raster de la elevación relativa al canal (Rennó, 2008) (HAND, HDND, HAND_class) + + + HAND + + + + + + + Cálcula mapa raster del IT (índice topográfico) (Beven, 1974) (IT) + + + Cálcula mapa raster del IT (índice topográfico) (Beven, 1974) (IT) + + + Índice Topográfico. + + + + + + + Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + + + Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + + + Distancia a la salida. + + + + + + + Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + + + Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + + + Canales + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Calcular parámetros seleccionados (enviados a Variables WMF) + + + Calcular parámetros seleccionados (enviados a Variables WMF) + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + GrupoGeoParametros + verticalLayoutWidget_4 - + 0 - 100 - 431 - 100 + 630 + 421 + 181 - - - 0 - 100 - - - - - 16777215 - 16777215 - - - - Obtiene la elevación relativa al canal mas cercano HAND y la distancia horizontal HDND - - Elevación relativa al canal más cercano (HAND) + Acumular Variable: - + false - - - - - - - - 0 - 10 - - - - - 75 - true - - - - Datos de entrada: - - - - - - - - - Umbral - - - - - - - false - - - - - - - Ejecuta el balance de largo plazo con los parametros dados. - - - Ejecuta el balance de largo plazo con los parametros dados. - - - Ejecutar - - - - - - - - + + + + 10 + 30 + 401 + 141 + + + + + + + + 0 + 10 + + + + + 75 + true + + + + Datos de entrada: + + + + + + + + + Variable de WMf utilizada como máscara para acumular variables. + + + Variable de WMf utilizada como máscara para acumular variables. + + + Mascara + + + + + + + + 250 + 0 + + + + + + + + + + + + Variables a acumular cargada en WMF + + + Variables a acumular cargada en WMF + + + Variable + + + + + + + + 250 + 0 + + + + + + + + + + + + Nombre de la variable acumulada. + + + Nombre de la variable acumulada. + + + Nombre variable acumulada: + + + + + + + + 290 + 16777215 + + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Acumular variable (cargada a Variables WMF). + + + Acumular variable (cargada a Variables WMF). + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + - + 0 - 200 - 431 - 100 + 40 + 421 + 271 - - - 0 - 100 - - - - - 16777215 - 16777215 - - - Obtiene el orden de orton de cada una de las laderas de la cuenca. + Calcúla los parámetros básicos de la cuenca. - - Orden de laderas y canales. + + Calcúla los parámetros básicos de la cuenca. - - false + + Parámetros geomorfológicos - - - - - - - - 0 - 10 - - - - - 75 - true - - - - Datos de entrada: - - - - - - - - - Umbral - - - - - - - false - - - - - - - Ejecuta el balance de largo plazo con los parametros dados. - - - Ejecuta el balance de largo plazo con los parametros dados. - - - Ejecutar - - - - - - - - + + + + 0 + 330 + 411 + 21 + + + + Qt::Horizontal + + + + + + 10 + 30 + 401 + 211 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Exportar parámetros geomorfológicos a excel. + + + Exportar parámetros geomorfológicos a excel. + + + + + + + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png + + + + + + + Calcula parámetros geomorfológicos básicos de la cuenca. + + + Calcula parámetros geomorfológicos básicos de la cuenca. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + + 200 + 270 + 411 + 21 + + + + Qt::Horizontal + + + + + + 0 + 260 + 411 + 21 + + + + Qt::Horizontal + + - + - 0 - 500 - 431 - 100 + 10 + 600 + 411 + 21 - - - 0 - 100 - - - - - 16777215 - 16777215 - - - - Acumula una variable ingresada como un mapa raster. - - - Acumular variable en la cuenca. - - - false + + Qt::Horizontal - - - - - - - - 0 - 10 - - - - - 75 - true - - - - Datos de entrada: - - - - - - - - - Variable - - - - - - - false - - - - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - Ejecuta el balance de largo plazo con los parametros dados. - - - Ejecuta el balance de largo plazo con los parametros dados. - - - Ejecutar - - - - - - - - - + - 0 - 300 - 431 - 100 + 10 + 0 + 399 + 41 - - - 0 - 100 - - - - - 16777215 - 16777215 - - - - Obtiene la distancia a la salida de cada una de las celdas de la cuenca. - - - Distancia a la salida [km] - - - false - - + - - - - - - 0 - 10 - - - - - 75 - true - - - - Datos de entrada: - - - - - - - - - Umbral - - - - - - - false - - - - - - - Ejecuta el balance de largo plazo con los parametros dados. - - - Ejecuta el balance de largo plazo con los parametros dados. - - - Ejecutar - - - - - - + + + Umbral a partir del cual se consideran corrientes (defecto el de la cuenca) + + + Umbral a partir del cual se consideran corrientes (defecto el de la cuenca) + + + Umbral para estimar canales: + + - - - - - - 0 - 400 - 431 - 100 - - - - - 0 - 100 - - - - - 16777215 - 16777215 - - - - Obtiene el índice topográfico de cada celda (Beven, 1979). - - - Índice topográfico (IT). - - - false - - - - - - - - 0 - 10 - - - - - 75 - true - - - - Datos de entrada: - - - - - - - - - Umbral - - - - - - - false - - - - - - - Ejecuta el balance de largo plazo con los parametros dados. - - - Ejecuta el balance de largo plazo con los parametros dados. - - - Ejecutar - - - - - - + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 0 + + + 0.000000000000000 + + + 100000.000000000000000 + + + 0.000000000000000 + + diff --git a/qgisplugin/icons/RedHidrica.ico b/qgisplugin/icons/RedHidrica.ico new file mode 100644 index 0000000000000000000000000000000000000000..86287c27bb78b9b18080f3ad160f0a845ead3c2b GIT binary patch literal 32988 zcmeI4X{c3I6vvOH*`TF1s7<^E#Y!TBh)U=+S)o>b=tCIw!4DCcpKKt_Y_cdLunD0e zN{JvGDp51cLV^e>gCL@!!pcfZvw5(7f4PemyL0b3=k0snyYIRe{MgglYp=ETKKq>e zKD;a&kPXbbyEDqJY#imJEX%sOYVBcJHjBPdqiXE~vh49IvTPXrd-Mlp+4`%pY#eh? z%jSdnlcWr!45SRC45SRC45SRC45SQ{%)meB86~H5l$ynEWk&^9A{dL?$`VsLPQ_xk zvf~0Q2*~2LvOvA#hAnPic3hAJ0r}Wf-`iwwk6-)kbFjDVe;9vy2I5bEKTk#V_|@Vq zggzEo4E1B$MQioecuWj2b9*bkqIF_oC^NTc{k|SA6GNy|&*xCj+V%9?q2GM;WsG0m zj<3hqZ1r64r|Pj1+Ou}7-B!&v|9ly{mbc~Wv36TE-}`9w*tN`#FJo=CYQFc;*JIc7 zwp4Ft34OJ8JNw*B-z?s|vYG3&qpiG{!@hR(yBR)(aTc|kv1Ys2$cxqcmN%}xPLVLa zytqOg-_FzTPkm)$@p``ApJL7PwMr~rH>~H`?!>+@?ywybb2Dwl_|a%?=wn{H(R@Fa zH`n)h-FB&a{~Fcn`P*ntI9AU_U-o++%@5z_>qX;UH?MB<+ocSB^nQh7RodQ8yVmpK z$@4W&uU=o?{C4cC>VG|b>u<*x>-l6phh;r|-yhDgw%2L*y7?TIW&IB4S-b4~zSJ{c z^U5lI<;_=LJ4-#Et-p%zHYcyFVy8ECLtnLaUSAoX!g;=3W`1w$c>k;}AFOU=S-(ub zURl;oZ|LRuXzMl_Go7#u=V(0aQ@dRx^eyzOXuOPmXv5m!+`ed=FII*=Sidhr9pCnP zs+)xUe#~@wy9|A*w|-eY&G)*YJwK*;UrQB#ylx}Ei}Z@d8`*C5SgU-I-Tol0ioZX^ zE+13;|K*^+>{;?NWgulBWnfPR^nU`npc~Tv2_Okc%4A>wN{5zFY?01z?Cye9EwW!^ zmjAkuy$SmMIloA`MdPz->%T!Me|lR+vfy^u4F~r2;B17vqufzc_9n-6QKH|xwEhOI3iA6|yRP*3E; zH?R$2_uj9eJ=OZ=!+w4+s2@VR8E0Q+mH*3N2WV}bag{pn7elLs|9X`DQDZ8l;#vvv z;ZK+ctrV@V*!8TNDEG@jJ_wEJt}GIrhpNw`@~@b~{T@P}?q>7hTk3iSz33d+J++?t z&oIX;MAWtZFQDh_MUWqVgYJZL;eL=$=AZWJC%6q_MbDp|0kfxbp!K!h?pmoe*Mh&N z_NN^yw)cu(`8BzSitb2@`C%JqVmZy(|1QVwAo^CJIcm9fm85zGb$9&R}1NVpJT8uOnp~QH_GrApM=7DO;>NViGj-JJ36(-v--Y zf$wZ$eP3)n1A5Plg;q#6M)kYq%2pW1roP?ZgD1eAUESsSO@ARwhxzaTJOVSJiVQ?q zw)I|k9X7!G@Hu=0>es#b6)XXLr&JaBBpdqeq4(ZwkpD-+B+y!0LEq!rv#O$Vv>7(S zF*%dZpii+Vh9h#u%XH00Nilo?CqXE>ex^WAezTp$ybnP!du$mz`nlmpzMAON-_#1=(2*`+!96=37ADJu6`dR2A7) zUiF(nXGwR)@nAB6%GaQ^bsh#m712GUJ$(_*0ohpu7Q-CsJ767XOwW0h98E`mC!7Zo z*}wre zRKuVP`oVY7Xxy9uJ$WXWw&(q+yWnaydMNXl_oSPv--9FJL^vIef<~hIPj~wQ&~NG` zum-+_6)+VV$#4eWhLtc4&ICOtI?sBij({S$2?gDg7dS=TbvHxNd_5;xdl_s3J?r)y zQ7sg`lXW*qw7&lCupGvMWCF~E8=&Z3(l>%~_Z)15=V1eAf3AZ@^T#m09TtMb?i{^0 ziexYfTJsao9cb@)`LGMLFO6g}gVG%jFTh0Tf~BClP4}7Bs3*#w@-ESD$e|z~boK^- z-tCR{MEW|nNm2$<22uu622uu622uu622uu622uu622uu622uu622uu622uu622uu6 f22uu622uu622uu622uu622uu622ut(I0OFzS2|Xx literal 0 HcmV?d00001 diff --git a/qgisplugin/icons/toexcel.png b/qgisplugin/icons/toexcel.png new file mode 100644 index 0000000000000000000000000000000000000000..76af3d8bbe14ecb7115c0966dddd914770905d07 GIT binary patch literal 27543 zcmeEvcTiNxw?8l>13_6q@+hvjA|T9=B#RP6z(|s$D9nhGb4Cg+kI|N^X!VI3d4Sm{S*`w3~H(u zu2E3XDnS3yqX31q&GQZTAEn(jmGczoO)M$pGFf*et3!^Y=pfDprykQuM zFf)p}ZZY#k!28w z>;r1Sx3Dm?um-a*5@aqw0U8^^%o-ZZ8c4u;01EJ$k;2SK4Q3=@9`FZ%33>x}0Q&(5 zU?D&agaOb1C13?OfMOsUhz7DqkmsOg@E!bX2n!=Yjs*4rwcuMrLs$a|_!XE7P=LlT zQbQOC_z`#-H~`=R?7-2$THs3H4*(PN2JQfufWg2*fEow`pg~Un3*Z2Xfovd}1ceCV z2F>6*_(uW}1C9jt0kz;;1BnC$5Dq_t0*)vYPdG>rDA?~%cwtvU7-8=~(S{9%Aj395 z!G~c%7QmW-XpjydO2B!*CZH-qTZ0P>fK&F@G_PZehSfD|0rv%KHR0CFrQVspm@XCXs+Kv>8}D-<=YCD z$8Fi{_ef0KRXXag1^cBxev&BaT%L|(rwh4q8?WOuGbB%;S=#TlF+4v!a*1>>^MV2e zC*7c?(86mbsX~t*Wz@6G%;goyDFGO* z6L?M-5K|~lg8omVKx3tZhhRC1lG1E#dS*?L23JjY;Pw-5ieJc3kRk3+>FSpfpoDU`OIJ#Uu(lc^g;gvQA zccu_%n;zP^TZ&TCU-Z7Ei$<5nuu29e99pP+L_Q-(>Op{w!&jfl=HQt;PeReq$)V$k@LNE74`3do_l9 zLIIB)hahKWT39;SD?r*zq_|Yu7~o!i%PcYWm%?xw0(-gbVC&BEGM)%S+NHQ6?a<#+ zVFvpepA+gZLre3t$U=)DJuE^fJ%-Wc+kHhCC5H|A8wboi2GDfCURE7ec;x`2>1LyQ zbrhD6SyU@v>GTfy%wp-ZVsCF3M|yJ+f;S|a%nKqAlN~UcF{pEsBoP4lRxuEzR_K~v z;`-zJVdmEg3cpS=o|vAVUs^6;UE|-4I0O5`>zr)qu%n8EioaH}ez(p_MmCIP#}B3E zdah`5!?tKtV@pgAhHAv+KI*8V!jz{Ilk=H!_bVcySSc^Ls6NE1X!i8(5=^?=t|`xB zi&m3x^4IFp?_QrS`vyDo%X1*KuxxWKf z)XdUY@5;Aw*=hB=uq$p=fMM3}u}KW^acg7y4oegt+QBTe%uVi1jLzqMH{H4q169R? zXmvFEGP|{eHo$zJMigG93u$>u(`V6n^uvl1Vu}2~i|w9}fip1(^Y=;t)GX7{BIWIdi5MpJh-zrVHP zMYBgZ!S5v;=7ZiKpoQB@Em*k}(CZX-OtK=iqDvrB!+J-BzU{-?ggWF@1|GqrP$wGr4( zBwB{RLtT|=!w}4J1m=Bbe@mS~rt?3(Gb&a#!S-}oH_p9?e(_cgxSJpg`%LdB-79;C zFW-U3a8yXgJ3JY{!gf)}LNmm|Gd=)Uf0_pX7OoBh6U}Z90yz^mG=?aQxJ-qi;&fWu+=Ammby*~4U(M6of z{E;l}n7nBYqbLHy#n@bev!H+Rq~LjkjRmk-{DN}x5|Y;oV6dl`%CA2Qm=EjZgY0pW z0$JnHAq5N+yae}Jf`)ENH{`r~aM*+8L6nWn*=lcN4`1zK%;LqM zY$&JoT72d-<#=-kUB#1g4fZ=d@KyEPi+)@IBXqv$H3 zoN(y-CA!DG+)*~ncjWckAb~f%cnsuiisF;`fZodoB7ojlBLy%MWN$~9TE1CN?q~$) zubhUY&VpGsyY(>S(GQ22fgb{Wnaz_NpiH|m4I)|Pfy*m&DM1uUCFyNsw^*UD z9Q_*|q{9yeKEE7$zNiN;2T@;rPDI%hRlY2hf}BxIW$W4?ZC`Y*XxP#J9}j;>b~p9d z)^u=as_RIB*1*a`D0U{ykg>DdbBva6irOUvAee=e!`y|yk0WPSxS?q$Qy*~}C*ygp zXQdAz>7DctDqt>M!h#_btb3>>XAtkw{C<(s9w;bUXINoF6rY;5=ZQdK4^v9**7=+; z9qvsRF72}`FN@2zlYdTYc{1-~T(#c}Eo^T7LFPP${A$yU&e?_1*? z37!|mPN6Z)llj6l5?g){TOBDA%-c;MD%V#Gq0j~IgYvLO@o8_ol?T*M76n#O15HBU z@vgSD2leTeh4Q%<1lQ8(!CRq6P_{|$QiFkL?k>t)_!s2tViw4=gkEmv_rznsenqa} z4A7~kr&=UW8eMn_=HU+Z<=-12wb7r?P{hJ^BB9?c2&CwnH>*_ODQJs#~dd{w@~ zXkK*B(K>A~?i}O!$43l9%a1coZZ0}y`rJZ;T=2BFp*kSt+LqYWUO^~z)!=$ef4%U$ z&v@U=2yrrYCggz>{h?0#C@S^BmhrCoikGF<$JQkPlT)Ft&%LNAs@c)lPPJly6>VQl zbwGM%v#r6WbZP?*>uAfp183#~(kmEGQ-hiBXpoSR2@S8q5phl#w2HrbAxf$3$idY2 zUB>5Y80hn)&x#t>l%IaF#YH1|R{?muvOV`;YC?Uzt}o5lwp|RM&`dq2?X>-%o>eVL zIgGw=Bd(r9w=prjnpTN=Y;WS-t?^U$`XYipj9%6;jox-}2b0td`?v#Kx~(Nbwb)Vb zUw!;PZW5{K17|e5OyAy9m@jpoaHKoEoutmKt1~*N*hdAP8JRTxg#$isa{K8-_S454 ztTLMlr_=6QF*+0EZOwdKd^|k!?;edQO{a0BaJPhtH zQz+Xz%*TtNV^$p~W@oi~>CV2|zz=W)n|g3lNEfxOQASQJ^?|M9+vGWvWDh9=O--#k z5Vpo-a+lQnh?&{MB_`L4g5S-{FUXrhpk`@94TZ$)SS)k+IHTDh;ArIZ;1k?F#yhb$V`v43p9;Q(oo7C;-1{=E7;u)2it0u(1NIbE zo45C6Pzini@8^I0@P9T3Uau~i+zh`EUfLjzXD|Z`u9+O4&!yA#6kf;SkpcE&hu{GL zs#MI#VEJD{B9!8-Yk0(d*m4LD=o#F9pp6B4Ik23=ug11+7PhLUxU}u0;vN|NA*;n> zl3r@Z_vme=X1TNufj#DN>V%#rev`!Wd}-qsvh8dWvcg)Y5PH<8`eFt?HWz29oh~Mh z;Q&<$#mC+`(w!Ub{r3~z^x-TuOK}e@vBj{?>7mQ0l|&!br4M0xt=+RYXV`~r6(4D* zh!^)M^bz z-v1AIB-?LF9VIwokZo)GA&b3@9@Iks^dLS$Yi9_per1W-_yr}qghQaZae-cy_l4I9 z&v8wZ;P9mo+YtjC1E`h&o#zUEpdadG3`8F!l}@_R?S|F7gCicL>nSwsl$8A7uKSPI zksAYwUP&T|AmKcY#54g0d-w2QmIam|u{s1~lFdKn=DWx1<+uiylHP~4p%FBk+k9D{ zcDP#XBWH7&-X>o~WXR8}+=;?R`eJ0{20iYHH6S8t7o7<@mzg*RwTL&d{uvw*0t^@g zq^->D9VaG^$(Do7+}U1cnKfZBNLhUBm()RvLe9#viA^u%>nKoZd&(Rf9gV%FL$kO4 zj`Q<7oATYvkoh`5V?miNDcwS&s*YkoqeT_LC$P?!We`(Ph^cfc^k{1d#3vvz3f+FG z8^kdgTZ-pU7Q$l9IY2!XM0%y;Tx|ine9j#PSMFzT(DiHgvUNA{-Mfph`ue|R=AYO)Fw-PaOuOX=FTWi9;`pU?I@r$swx`SLXJ-ZRj922?+joG;-u7`10A-(ARMt4BFZ5HyRXUN#-a5+4O*d!v^6W3Gkc6zm{OyZCYq-MeXW#JcXTjmxtr? z$CuhmbY-S5gvCA|!qve(6lJPp(jb||>KIooq_?U1KgW~lEDI{?gf$)Jvg?2Oy9z|q zM8Yn_h`8HUTg{7ozlt?V+9j+yNiv*+qd#$HK%eAh&}<9)GvOW0(ZS9m!e0(}em&1#k@J=Ki;g*3FkSGL3lXG@me&zHky`rw8T7YGpg+W8sUBKjxs(GYozOeXSW zF^Z{LI3}NZv36{40lR`o30-}u%O`WSdH%2J>kJQ0aDZ|=NVpr(-PU4IPaUYdKHzM)kR~a}NHRZJYx z;P6BMHE*h>vJhHd_4{mabXj9}5cDyFx4Ft%k8%HKGu7xUN)@{Y~aJmVW9Wq9aK$|0)HkNF$RTa5<4{#_6iCpp8t zVjivt>pb&yL-kBo*&_oBcX4d`Av`U@PCv<)bvd+SuEYXm>_JTp7IyV#`?;F(N zhzhWQOyPp3?z`-1b}{X5YH-za7t2JVOOLdW>BsoPA0MklMfb^-T6xWm$>R?rl3&-n ziEc0O!&N=VbswB9W@$VQXXD$EwYWX29iu@f>5DeA>OtNnLezIfYEVfv7A1Z> z+D4(Xt}!Yy?DAtQ8XJnJecP*&$}f~G8x|F(JK~=_fe1ga?2+@DHeWRR`d=jjgOQ2f z5R<;T2URU?VHvS# zyg)X6HMB#E0V|!M8_y9lfrt^v^vL;PG}yGqBX*GG;yg%!$B4sdlEZ_e-jMc>IJDH4 zDBtupLsmByXWfRX?{@qxPW;qw=edlHN9=!McGtXPJ`PYT!J5=ijPZk}hk zBb6adV$>`gH}{2uLNyqosgl&;lj% z4TQaFwjix667L>hQG8fhz#h2ZBzXM|Tp%E_-B5WqkvGaH`IL4c2wpa#HuoL(_Da2P zP2SmzGH=|Kn>cMGOF1%l!$PhTtgiBJHOkI9=rJj@BON;O0nYDA8!K*Zx^r?Z2G|V5 zsvzP^U1PCQ8W(PxvhRZx6A3P$hz)Ymwe-G`2B!ZY!O@2JH^5R{PL(%LKjaPnNm|{19xF$4-+p`MhvR#zF<8K&1gM{IX^kdP0`FXyFsZU&63g(e`Or!i6ANEY;3L<_2TNXGP|9qf)`X^0dJW=c?1<66ZZGp-Wkbn z)y=^MfhUo*6m9Cjx2^h@$`X7jIt!L!A0A=Bc>%CGu(8fycMT)G^=_a1RS#kR2Yy~Z zMP-aqdxh_2ptakDpe0!nB8Ig%`ol_lpS)z`KzZ@^kfG2xDTJR+qqV+)&dt5u%Jls_ zlw_u`P0pEH3TwiX9Q`tp^E+pp*19;b-(bBWts8`QwW(e-Qk_;KCO%G)X=>RBewJvk zF1v4UXMJg+*sDW7$_!a&38nHJ+-ncadmCkxBj5ocBGYAps=^oc4R0}=!KvQEL$5~< zQQa9m-=4E{(U;gX{a5u*ro;n^X5)6*Ju zh!A0w@RX2w-jK7d+2xn5L^1K-5Erwh@HKh0b-UWQ7Jc@+5qT249t4Bcj4P;W#yzHB zF`PK9rgT~}yYbUbrg9Ewh?G0F7*Nw$tKxALwa#(PA$&eo-|G5w{eyO2*4skVRfP6q zSLGdceG6NS6((fT2A(BJBbA3QhnSOjGv)j7IN8W43y$s@D4q+k^r|Q-(H>O=pztSg zd&g?)IU_c13p=QID43S|?&p`@k{%87$)3D)Y4E zm&lzo6{4}Gd>&wJy&|GUz_DP*$q1snC3&88j23uwZRyjl722vKOEEq7#-h<73^Y~K z#ro4W%{`O5_c);`ErjPUO1y%?NzVOGJNUK}c9WLhl)m!G;Aj)awUJ?~Q;GoCyVq7+ zZd>~K-<4`lrMsxW!5sYUE!Bwg32kD`PY=zjvo6?rdh8q-!AI{LPjfTtk1y|SHsEgQ z9H#6!3tZOuMWXQbFR%s^teyO;`e8p9WiDi3gx!MH1=Unx4!swpPkp{HGpa8C26mv1 zU!%7!-tVo=`;4s8TLhdmc9E$>Kp{SfDC&M_;XV|&S&o1gy1*MV#uH5KAZ=i4pw`Cmhp(a z(bZKKp-vojlMK7sd&Av*o1fu080EW?drN7s@J!<=o?5YLhCFU z-$~RRrxV&ELXR}4uV<7UiJc}x(4eiF78#MBU6m!xXYW;ZaN`vs;y1~S4{59BRZ~ky z`{PKK9%qX+3CR7`W_n(rFudz0a{dUrqcmNnkj=9Mc)F!#-& zAcISx%#uEAkuggDu<5S>Xf>$sL+;Vx-Oc^XA;V^F zOn#BNXp;?vXdf+-K4z#pD`yG3j$R+~HMW0(Lwb^F739>mRG3{WZ*u!N@z+Iyc|;B^ z89^mw*5;Y$Sy#QEk#X-Ny%U)QzmhvxE4aVldwrci!tryH02W#IZ1CTct?f^jXh&)7$z1h_UAtqH_+P zl*8*<-QTrz`rJ;(lhUq#5S|uTsO~tP=p-nwo(x*%B}r8^w%qyMuryfk_UmKi)ubAM zlprUo6)RtDQv^0Mb3ENn$wqD7;3!vhNqTc(4hI7Iv3EXjYEZMYSF5nz5vLZf7TZ74 z8i=Z?8?3pW6@_~)p3B^jC0n9_lc|sUcaqkMdAJp5(We zH7n06vMN9qLg!tw1A=3?21ZxfZ}HN!mg%=kn>Sho{FgSFrhS{k1g2X@W!#kK4J9 zcPF>l1V$LQ1oYp)4_o$-N;<)@jIPX1ufz0CEynGikp+A#N0|-x?rOX1ZnDuL%YvAo zI&1widP?@!tuJ-Giv1iuc@^^jHz*R3T|>NR{&hjGKI{Azc_SvL7E-JOvVy;=7pb!` z64aHc?PW7}0ac-;{|-^xx#iVHn(i>)r$Y+-9uY$r6i>ShuWAC->pz$3WZX{k4E$C= z`^Y#)6kc733Ptc`8I|}YdVL93C!kmaHDK<84HK%VgPNM8B(EF}0;;UF4S`?Y=~bD! zG+XlkN)kDS8F4B0CVjq&Ir~8CpiEyPL}Mv1Jzn zke!B-oz!7smxJ|3ugq7%9JEHQGl=-^PI;%9>WoUI6;fB+)giGoO$7VHRSDT=e%VX$ z3HiQz;?Pkyu;4w|G^To{-%ZyEyDm@bBain$md(~d`jKz?ca9SF1}{x`x=&{2$RQ95 zZ>2RAdb%I==wCPCE)AsgYNtZhyuUcgoIKgR!qvqXhq=$;VsAyunpUv z3Fw>2fqPx20emKXWS{g=;Xux(2nW*1gg524a+G0=*D6A^aT-o3JPo;BPx7Vo6X2l! zQ!%WX>R)5=u{x}i(yHw=j9PVHN-61ExlS5tAmJv0i$hyZ+2h_hRT@gc>#&D@nAo1^ zJm(o1|0uZg9~jE>Uy_F{xDAdjw46hv93c#T^8s5)S^W>Nu8()-l3!*_j&rH(__BhN zl>q*C0N;X!EnNP*{znAQXv$l>DKJG&@Ft=sYevs6W%!eG%v+?({?>C3_dB&X#pWW& z&dc3@|K+jtlyr+eqW14~{f~3`9Sw`Z`rz~tSkr$T(-+8P?^7InrVUQH0j-yMe!kSz z376PYOF?#ci8(@xCZ+OExfj}P5g~#WazF4cLE&P18ubWIHP%zf|10+jH@*Z;hJ<$v z+|R1HR}AqL$oFu%G;NO^gWfl+X9AumKlZ+{td??fAn|0N6TTYZh)m;p<`BC%VyK^m z08^>I+4syWU>*MrVTjfM3<=-v(CKF*-oPDDxwEMBkO_S6q(Y>e>0&1*HIR zWD2Zyk8t0wo@u*~#UiK=d+T+=5dmWM#Iq<|2O=?{S^slfzHce7AhMJDVV@wDGOeFo zWtsB;NsD%gG(9zAtlF$95s`WErrcrm>s9GFmI%X-c-FL7evLy#ZC?@J++@?wwVfAJ zoV_d%3Zu9u=4tWJhR(xEzW{+v)UDTUc%S6okDo?hq+`-<35Ij6#U>)#%)(1xC){JCfBk?q{6ijtJ~c>`Z@*(b(_SwuPX6nE0Y<>yz4TE&VbCGD z2$`S>2vTh=t>**CN|!DQNHGso_4;&*!oK@*w<>RGN#v`e{&zSQJ+E%1jj2l3B|uuC z5h{MSq4}`w>pPgVy9lbfcgbPDuCAErBirSk7yN0XIA;MX0YNf@GI1%xpYEr4+d0H? zGZ`Fvtz8m3T8)To)od*lRe zA34ah?yr6r=Lbb6|BVEVVI!4>t2fuo_fMXcs-z7LIZNIS*G4jHhI9R3NSB<2Tz4od zIoCKh0R?+(R-K59xN-dI{`?<-nfz(sz%)>MLt>5nWX5918I}6b>d$=V6`pS=RSWni z9kKg89t=h$x*O8Wp8Od>UpUhYj|7FYt^FQzZJN3E_hfK){tUWH(rs-W6&HhJbIF5J zGspIcHLt9q1p?y95vj_t+yfenMeS|K7`tt*pRZqf-?2MPTL_Nh%+?17fr-oQl}$NF z!RT7(+qB3Mp>s0rxHw2bm0#EYkF@YK5P4jJt`jgwFt$@FXw|wvwm8TY`Fe#@MT~=YLO} z9v#n*IHrI6Gu3|lFabQsh5yv;(|HEQzJDu~Mqn=ccP;#5S{#>QkFFE0}K%S z*R~mnKLa^6xJYr;$TRVhxQ*X83u7^d9p6s!Q`6p`j&jkh@7he5kuaa)D2qZiW4^%uXY{SEpzBE4y5sFTl%x73eC_D zKe8)XYrUHHXt%s_-(W(=pY4vYK+Nr>DCIa(o+yvz#>up%-^jgO+rFnxT~opr2fMno zS^tt2{7+Nc*VO4riRvMlYBml=&*a=c(wG=yNS#->ny$N705!4yX%O>|>1p?0Ut!Yj z+8RwdF4*{6O@>sTjKEOaD^5 zrg+ae{|NqdKIQigu}&*U|K*$A#gA5@?U$n)OCHk3-~0n0nJ%sF`(D1@L)(Py00F|j zLHyO<@?Hk%2j}7?%cgjxhlU@Qwa5K-!g2ke+}+h3`H-@sCHXDyeqFZsql(EmhsR>u z!n7!|ZhIt!mWJx{ZR)${6^z{5ZByq6I?qVVOzc=_ zNqXbYoa4Vub$5#I(Cz1p$+dRnW%WO;nS=h_A|u^#Cw0Ct^y$ii%#K5dSN4BtvU9O) z?;T`_DB~%S?D!zAMHKm+j$WiFoM2}%Wr>+RPbY>)^OSzj?;3+a(^(hC4~KRuMuTf( zlIZ3wBi{a}USMuXEzG3n@z>++skn~c+xx2VgCSmAN7|ef9oA}Xf^H@LX}NIVHrjop zCdAX{StqZY7)}K7=(h<_HHqckcF57IdDL z+!($3*z4EUnL26Te(FE<7e|E$z|!>u`_ScyC;lvlgXfN;Lp12dv;&5QN-#<8a`PJ_ z+Lb?r1b-K7Y!&423|z%-Iu#RDCN85xn-5#hA&C$oNLMw@v>Jm=de`BbI5Bu(Er*ee zppw#N%iYO3aAYBJuXLsV%R=;_UM+WY>gvoWaU+h zWnRK+fT00SmoxF^@467f(+-toY?6~?34XRHgQH6ve~8@24Ar)wF*B20v%<4$%eLTd zpD6jKu6AD`((=@-yTowz9*WJ)@M8y#f!s?OWt%>It9#cimQ?QNm#e1#h#Z7g@1s$- zKR1txHN0>b9Ph8a_ov_|j=JL@?Hc2|FKWKey=%)3XY!|l_|4nBV@z%d~nmML!H(8-mR1T1 zzFJ+~`{#K^7&mcmIG`q1Dx5^l1rr4xtiu7fvY>BsK-VNkcPDO(>~J^A#X_bu#kmTA z!eiix!SkdT2bZi*owWs1;B`R={JJ3QIiya#!(*m29PeNi0@Fo#) z1@PPdr)iuTy_H6T(}Pp;d0F55S?6+7upj{qkA9}Vz|w5mOR;z8VaWjP^K*Nd|#bnP+= zd=PJ{OcxP z?|uzwc+JEW#(n<7)x-jBVrjwlRJbE-`_aO-#~LRzuevwR>#pyn_b%c)VPo!mSd3_k zQ0^!P8q;JWuY|zIJecK;%-^jzzXrd#n%|b^vcQGg!&15nI_)*=UD{Isy)meO^Z5jF zM#b?3){ws@7 zFo;HsSxnf}+OvH{ru}&<*5?}~VOxr2@aaODV(E@skCeYG+g)Wrn1#bX1-$UOln0!u zwB9N<3`ZbqDfVOG)aI|m8uf>?{2Y2N;mC0wNgL_SVq#XVV{M_=#;*_WZzfN}+moj( z8bAE}I-UVrczLj&XRzQ$!=O?jGP33}H*x(h<7Mg2-O4w9+L30+TP?XJF)dCG9SI=E zY8)gLatvwXtaN1p$vk%#3eNlY9ZBRjV+?uia%LOt1%p}hhJ)s2>f{$`Y{p{hoR~9t zfZXdW`F;X#+cbCm=a#3jDM;qM9T3kNp1iAE$K+6+maOzFzIoiQH>p?zGR235MSNLqUL z2mNS*;_IBc?QcOyJJpD696O!fZ*I1fn~i|DuYzIo7KZ)#Tp1s24EA%_Q6Ay|X-HKd z9N9IdHqA4QWqXPDF6ge0fMC|bQP7JRq~kL)Hm@}8pWGe_Ks6$pYi%H#HDTB{^Lw_XJtA)2G)f#)G^5B&jEj5`K^@x zm9nrmn=h>NBFJx}QZBl`|9 zvGl!zme|id>^wxHb-BU`WIrY#TKp#UrJzFD`!@#&X&f3zX{6J1!=;dB@YxvTsSFN- zKkwZqRhLEMUJ8C)SS@-oP+2U~h-}%k?c(t4VVi$dcX0(d3@$w4@jHo#w-DLEu6>nw z$p9>M{SY^SREsP`WL`NA(>MaBOn?a~5Aoo)kdycB`hY~X0}gnvH6pA|K40(#r>V(G zk{SkJme>uwlMo?9=a$I8)L)DzYEAn?J@_j`u}J+(@5wOxNsD5~QRh^*YA~PZ!YPq@ z9%H+7QR&v}(X4r5YE>#0six`qjy5+sFk-r_=En_u1(cSNZOxHLi}RYS(ia!SfN*&( zy!Abt5#n8{O3Y<#w_)S5lF()jgCpU{ZtBd!`DGj1xGce@MetbQWyBU9$EF}w_33ET zKCk&g#ZX>*-S zaL6oc=DR)*v2-jxcOqE|-s9GNJ=lC!Z+nBk9w2mYn>yX{8s4_v)qCsJXSC^S_qMh$ z)K&6*5>gAUZ@ZBSvLq!7_`Js0*{dZG;l65&JtB}IPg%L7yM75|Gx^NSt5NoojOKKZ z&dzBeObhwojT#|EHpl_Y%GJxjPGhm+VLVdI{*120T$b63eCU$u76qJ+RK(BJE+=|2 zSl;6Z3@Z_`G7U$n=Vxk{mKjr`;x@v^v*z!C>6d(#=#ETtRL78Z^6)#UA5(u$7+vEL zJ0L7B+~z#tu$w38^qzc9>Dn22LGu+oIznB;_vB*xI5PRXjFzB;{XXO21mGlv*`5#Zm(g>%J8;ssG zwq8a&btqc6`5kx1unQOxd<<45;cAGSVP(v(JL@BXK#WjK?t|E8h!`rF=Cd}EAcNW+ zmTrCU!1Eyaqi-+$19 z*U%2p=YpTI3~Y81EioV4$O?SgSEmz#8H})90i=%;i2_o7=9yf&2t3nQ#TzfelmVQBJ0wlCjfS^C)2BD00Mc)4e0V zzk85TT(;Ar4+z;obnekX-W{4jFx@qvN-VTtnPmzU)|q-H(r8Nd(d zA+NTb>n#ZU^-Qu0@<=BIT|D`mqyZ21zJyY7Xx+*(CLXL?hLF13$@CaA$+nFKe2$}# zSZNmS7owAe(9?ttm;$)p$zK**gU5B4KhffBWgl&)^W4EDiTo}snf!#veiC}dOlN2dngCGDTJux0v*bWN5W0glCpQM;ULwf344Tg_LUe#p<@qly4j05L#Xjpl-~>D#w01w17Fo(gd9<3$1v=CE&t=W;X*sxG^hJ)_mbzQ* zyjY)pV*UjLNV0?8KUM@bQ`MM2l!{U0O-gRvX1^~hHUT?vdPZ4k6*Dzj{16}UR_p~bCD(0ukpl24yi3H#3-}Jh*gCSX9QqsVj#Wtlp z;;=@Lk8UTmABwrX7&1qPp>s9Op+(kyyWP>nA_LQ2WfsL3%&`qUXUV6i?MJs&##^Bk z=bG-i&5PPDYd9$qI0KAqc8$uky9a7x)pQdAx-vr|zQrE=#s2i9O+!$J4 zDoC-I<;a;4MMED0{ zx_=x+eDY*jD~AJG@3{l{c7)cKen^d8FwlyqEp>76$f#+5+JYn=smr$wT|i~u7z1mV z$iZc^o%fssq>jGCBPOIiAM;SXZT8HjT;vrLVyVoe1WgAJA_j!W8{7~4{VNYOJGsb@ zZ2%+Q^X-E{iL^zeA|0+gu4bBAyE*IL3&t$+zUkHK#rV%RW`IVll6tz=Li;ax0zL6< z(|~X+x;^UN?)PDE=sZvvSxc!A4oGB_lnTa6wVmJ&^V~9yM^<)`oP=-Ja-nsTTxb8B zTole44(BV|v|}!(oj{PAVo2-mi&uOR_P-`$Zqq;sx3$(zpv7M_MaTz+P)c82s99mRqh9>8v81G8rcGU^GA7&m2CyxkGir`R^q3Pq%QSX{^g1b4BFi)nkIzYpoldd)+}hBFI27z@ z`YTc5SKtYNq67cGio_k2HghApt}V1DNlEal0X<|%OKiGWz!^}uc5OKhPT@l){jLR5 z-NpU;84a!t_}35Mc;^2NKiu<>((8yfdzlD+-fKr{If49!5x&&{+<5r!^$q`CWC1@U z{=L%U-=XmDQ24(x6bg$e29nfI1b9=dfjfyX)YO^D4Ak$AK{xoI%Nva3+yAHQfUX<9 zmp+EvHG~N&JnsZu$P2D9`kyZta+YeRDda>h82V)!f52XXe2>w+jOIg!nN5y>3x+~1 z3}cJP5`_!poGu^&wO`nK%s(YxjASsi)pzL6%}8qZ5Gf`XLnqV8w;_G=6>2sFS1mzT z7KQA}(EwNu0G1}W+X-B^3*D|1IJ>={m6B5XJp=X8p6y8~MBLHV>H=^XEOgP*udK;r z`WUi|Ae3Qb5g%eFr+=aNdJ9Kze8lK=kAEnN&UMgIJ&>6h=~J>$FzVx$n{#?9lW9}? zQ`$Q~7;v`!jTQzMx;3qP?PKUpV0p+{Ud?Y9u|35W%*$h$AzDfCW&AuR?b(-`2UOR+ zizSOB_daDX4KYak6!6|>7`7b-y1!tQw{_!o?qz$(QeJ5e5ru)wQg^wo1?r(tr8(yE zuO&havW;9oq-OeID`wQp2oHVgi9wYjRRtq!Q|gUz?OrPD;EjXB0pnClBU2N6F-Ivk zxacEK7?cR`AT1*{mTPdhqrOWoD@d?_FsU4xq?U@Dd;tfyJ3-L6cS~?g~KWxrrpuhoe|67cAFB~gO_vz@%C8=_sLBA1~Zo)h?)Q=p!sT&4zTO0%u!ECWpx3SE7U*t=}b6j4#SRQLoQ4G=Ogv2oHVr0?bKo3_vf*pK?9>zUx$ z3aQ;r9SPTK}em-yYqCkX7t5Dfz zJko(QTUqg})Lzehp818n3zfRdyJ5QF3JH(J5s)E(jj!;m&%M5;rI!W1f`)Z{M|~I! zL&~WvCtQzA43)WBRc=YhInmPO0zo( z&@Fb2dMkYbb%TVyrf$=rm&SjsE!PtNZrUfaVP%(bdv|#0G5^imE`>XvomKg{Watuh zI9;5|35U*H)&W1^gKp-#A*GeY4nitb2wm2|X;& zW4v1xZ9fePvXUFJXcG6#$OT$pBU9mhNPO}BIxn5Vb1xmdmS1WGn$Q)(7wHx=)_IXU zT34UZ_8qM#vQL9MW6-21TmFO)aEmO+wF^3+3hm=tMzs{lyvN$cB%%CE+z<`+%!~u{ zb=g7gXG{2jVq^Pc9m)ol4In72tDL{3!;$fWYf1{EDHd-}QnVo=}F>E|f+ zfcAAM=$gz7q$gLM?%UEzNO2+USoNp`qvCV`C*P6j2>AX_F9lB^-W)ImmS#Xq6Z`89 z0G8SL19@F3EqPeT-c(AL#p#*1oP35hXj7UkGf;<<)ScpQt;k~mtTTZq_S&Qc@QX|z z-;1PE^~X*{_1mFGGgkybImkM5$Kn{cb+kC4gGK8T$E#8|NQt(qNR-l*bK9P1J_%*z zI4k(#$(vqN*5};KWj@~L+IkBL7LvLot+ZsWM{R5|(p-;9Z$TX|8?6m7zixWLxY_q! z!Xq9^5XlnDJ?H9UrvSEi5sx5CRts8%v7XW zdIa!G7fDXo`CGKEqaiP;f(Z)PzL@aI0k;VS^UE|mnoCA zs-?eVtin~-?cWKmA1PPd1e3h%1jr~r(o_ef#vv0<#2Q&^v?&TYuj}K>Kr=?;A8TJj zczFUkChOyyMl+>BD^!> zV?Pc$;m?)XQ#J~FV$nnY6XXf%F*YEJI6Lutb8TBENyzuTlWDE z#R82sl=U37--w?MDPttc{JK?nE7@3cka3m(2v%^_w21I!prpi zvL7#DKxGf8nW#N>%A;eW@BK;WDq3&vGf&!wi#YZal%e-!z&yPl(~Atk_*Kl3PhdFt z7Hb)R)}jH$F17(X`mP|9mH2#4J`N|?&7V(0=74M2&&C{W4Tf@;Ie68E{*sPw-_cg6 zd=GB(X8}GmzTR)A%#5ODq_noPa2; z!|kqsV;Lo&P5O9$Vs|9IT)HFOZ_E)d0}17oaYSf1j}&!c zGCSklA38|%PlIHR-U4wIMq>ZEcKVm$>bc;n#^4+Ply$U_i-*@fttu#cz|TnPyGoGZ z*%70DoP1ly;k>Gw02gi3Uy@hp0i*>))x(jJQdtlAV4K0H1QIkK17VpemVqldgM>r7 zD&&5kmzK2G{FO4q4;4;byjB2nW9#sCjPws-XyAjtDR4kS+0}JYL3tM$anu=5kVE+^ zLO!h^+L()E#49r|+*q?%)=pu7E3o4IFr zp<#$dcUQoJY6=YTk9+2@6CXv{&_8E_J8W;dx>ve+bg4iIi}vB5^>@*@2A7T!_%$2Jfk)(V4s5m7#vHG72l zwF}&=TfW+U?8x+UnBkfxh!Zc&5db*kU{Pllh9Wun2=M3BCrVe4KbE0;WMQ@O7=$ZR zj#06P6G{XsHh=~E%@1I-cDfYxJ$`8L)9+ZDjv2zAE_=vRUz8VI1Xt?;mQG3P@rMWp zfNc!RKL{Qap0M2}Acc>^tu=OAIh#sXkoNn%3#)%aTF-uN8W=)G(Ja0J9Stq?M0LX@S^#j{X)9`KGH=pvbh)KYaT%bGJSd zy98hu{n*}|U)H{0PDaLoUBHeY_iE<=Ia3Xg%#E8bKlUE>j^dZ%+hD}R^d|kUbAW}X zAn-z%35EYEw@NG5bP4DIIc2*}DQaB*b+>UVaGdk(rS=6eufDT}xjQuQ$*mW&W^vuG zyupr%sbupJMU6R0O!6!&FS74B2k?E}&Ax(4Zx0P zWvspIw^b(ue~X6gP-tW=0ftRnJdXkJx|pRVa!rT+^6vnuU&MEAvbkH{S5^jTU~l%| zz4irn3L7~808ic3t=@Bey1U0gV23wsE3myI{%dOkFa=2b02a;e@?WzVfSu@q!oS}Y zHPYwXzl>+9@2L=XBk{KWF*Z*hE`eB{8 TKkFJV0}yz+`njxgN@xNAd~?mC literal 0 HcmV?d00001 diff --git a/qgisplugin/resources.qrc b/qgisplugin/resources.qrc index f379941..370a019 100644 --- a/qgisplugin/resources.qrc +++ b/qgisplugin/resources.qrc @@ -1,5 +1,7 @@ + icons/toexcel.png + icons/RedHidrica.ico icons/play.png icons/coordCapture.png icons/config.png From 0e9d723a4864c520349f51fcdde2d60f1bfdffa4 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 5 Jul 2018 08:45:05 -0500 Subject: [PATCH 059/142] funcionan los que obtienen parametros geomorfo por raster menos HAND e IT --- qgisplugin/HydroSEDPluginUtils.py | 46 +++++++++++++++++++++---- qgisplugin/HydroSEDPlugin_dockwidget.py | 15 ++++++-- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 082df43..e768aa8 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -195,6 +195,7 @@ def Basin_LoadBasin(self, PathNC): #Cargar la cuenca y sus variables base a WMF self.cuenca = wmf.SimuBasin(rute = PathNC) self.NumDicBasinWMFVariables = 50 + self.cuenca.GetGeo_Cell_Basics() #Area de la cuenca y codigo EPSG return self.cuenca.ncells*wmf.cu.dxp**2./1e6, self.cuenca.epsg, wmf.models.dxp, wmf.cu.nodata, self.cuenca.umbral @@ -246,7 +247,7 @@ def Basin_Raster2WMF(self, VarName, VarPath, VarGroup): return 1 def Basin_GeoGetAcumSlope(self): - self.cuenca.GetGeo_Cell_Basics() + #self.cuenca.GetGeo_Cell_Basics() self.DicBasinWMF.update({'Area': {'nombre':'Area', 'tipo':'float32', @@ -283,11 +284,44 @@ def Basin_GeoGetOrder(self): 'categoria': 'Geo', 'var': self.cuenca.CellHorton_Stream}}) - def Basin_GeoGetHAND(self, umbral): - self.cuenca.GetGeo_HAND(umbral) + def Basin_GeoGetIT(self): + IT = self.cuenca.GetGeo_IT() + self.DicBasinWMF.update({'Topo_index': + {'nombre':'Topo_index', + 'tipo':IT.dtype.name, + 'shape':IT.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geo', + 'var': IT}}) + + def Basin_GeoGetChannels(self): + #self.cuenca.GetGeo_Cell_Basics() + self.DicBasinWMF.update({'Channels': + {'nombre':'Channels', + 'tipo':self.cuenca.CellCauce.dtype.name, + 'shape':self.cuenca.CellCauce.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geo', + 'var': self.cuenca.CellCauce}}) + + def Basin_GeoGetDist2Out(self): + self.cuenca.GetGeo_WidthFunction(show = False) + self.DicBasinWMF.update({'Dist2Out': + {'nombre':'Dist2Out', + 'tipo':self.cuenca.CellDist2Out.dtype.name, + 'shape':self.cuenca.CellDist2Out.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geo', + 'var': self.cuenca.CellDist2Out}}) + + def Basin_GeoGetHAND(self): + self.cuenca.GetGeo_HAND(umbral = self.cuenca.umbral) self.DicBasinWMF.update({'HAND': {'nombre':'HAND', - 'tipo':'float32', + 'tipo':self.cuenca.CellHAND.dtype.name, 'shape':self.cuenca.CellHAND.shape, 'raster':True, 'basica': False, @@ -295,7 +329,7 @@ def Basin_GeoGetHAND(self, umbral): 'var': self.cuenca.CellHAND}}) self.DicBasinWMF.update({'HDND': {'nombre':'HDND', - 'tipo':'float32', + 'tipo':self.cuenca.CellHDND.dtype.name, 'shape':self.cuenca.CellHDND.shape, 'raster':True, 'basica': False, @@ -303,7 +337,7 @@ def Basin_GeoGetHAND(self, umbral): 'var': self.cuenca.CellHDND}}) self.DicBasinWMF.update({'HAND_class': {'nombre':'HAND_class', - 'tipo':'float32', + 'tipo':self.cuenca.CellHAND_class.dtype.name, 'shape':self.cuenca.CellHAND_class.shape, 'raster':True, 'basica': False, diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 61cbf8c..1bbb792 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -218,14 +218,23 @@ def clickEventGeoRasterProp(): if self.checkBoxOrder.isChecked(): self.HSutils.Basin_GeoGetOrder() ListaVar.extend(['Order_hills','Order_channels']) - - + if self.checkBoxHAND.isChecked(): + self.HSutils.Basin_GeoGetHAND() + ListaVar.extend(['HAND','HDND','HAND_class']) + if self.checkBoxIT.isChecked(): + self.HSutils.Basin_GeoGetIT() + ListaVar.extend(['Topo_index']) + if self.checkBoxDist2Out.isChecked(): + self.HSutils.Basin_GeoGetDist2Out() + ListaVar.extend(['Dist2Out']) + if self.checkBoxChannels.isChecked(): + self.HSutils.Basin_GeoGetChannels() + ListaVar.extend(['Channels']) #mensaje de caso de exito self.iface.messageBar().pushInfo(u'HidroSIG:',u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.') #Actualiza la tabla de variables temporales for k in ListaVar: self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[k],k, self.Tabla_Prop_WMF) - #Botones de ejecucion self.ButtonGeomorfoRasterVars.clicked.connect(clickEventGeoRasterProp) From cdea15e6fae94d84e6cb7bbb058e2305a25f4171 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 5 Jul 2018 08:59:15 -0500 Subject: [PATCH 060/142] corrige errores de cambios en wmf para permitir usar HAND e IT, incluye boton para seleccionar todos los param geomorfo de raster --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 88 ++++++++++++-------- wmf/wmf.py | 6 +- 2 files changed, 54 insertions(+), 40 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index bd904ef..525845c 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -3068,7 +3068,7 @@ 0 - 0 + -308 443 1918 @@ -3124,7 +3124,7 @@ 10 30 401 - 236 + 181 @@ -3146,6 +3146,19 @@ + + + + calcula todos los parámetros geomorfológicos distribuidos. + + + calcula todos los parámetros geomorfológicos distribuidos. + + + Seleccionar todos + + + @@ -3211,39 +3224,39 @@ - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Calcular parámetros seleccionados (enviados a Variables WMF) - - - Calcular parámetros seleccionados (enviados a Variables WMF) - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Calcular parámetros seleccionados (enviados a Variables WMF) + + + Calcular parámetros seleccionados (enviados a Variables WMF) + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + @@ -3256,7 +3269,7 @@ 0 - 630 + 580 421 181 @@ -3541,7 +3554,7 @@ 10 - 600 + 550 411 21 @@ -3836,6 +3849,7 @@ + diff --git a/wmf/wmf.py b/wmf/wmf.py index d8a0561..ac02c44 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -1344,8 +1344,8 @@ def GetGeo_IT(self): #Obtiene el area acum = cu.basin_acum(self.structure, self.ncells) #Obtiene la pendiente en radianes - slope = cu.basin_arc_slope(self.structure,self.DEM, - self.ncells,cu.ncols,cu.nrows) + acum,longCeld,slope,Elev=cu.basin_basics(self.structure, + self.DEMvec,self.DIRvec,self.ncells) slope = np.arctan(slope) slope[slope == 0] = 0.0001 return np.log((acum*cu.dxp) / np.tan(slope)) @@ -1365,7 +1365,7 @@ def GetGeo_HAND(self,umbral=1000): 'HDND : Distancia horizontal a la red de drenaje cercana [mts].\n'\ #obtiene los parametros basicos por celdas acum,longCeld,S0,Elev=cu.basin_basics(self.structure, - self.DEM,self.DIR,cu.ncols,cu.nrows,self.ncells) + self.DEMvec,self.DIRvec,self.ncells) cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( self.structure,acum,umbral,self.ncells) hand,hdnd,hand_destiny = cu.geo_hand(self.structure,Elev,longCeld,cauce,self.ncells) From 1ba00a1baf224ebdb23e64b07fb36f56cf84ece2 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 5 Jul 2018 09:07:04 -0500 Subject: [PATCH 061/142] ya funcionan todos los checks de calculo geomorfo de raster, y se incluye boton chebre que checkea a todos de una. --- qgisplugin/HydroSEDPlugin_dockwidget.py | 21 +++++++++++++++++++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 1 - 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 1bbb792..b6ddb2f 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -207,6 +207,25 @@ def clickEventBasinLoadNetwork(): def setupGeomorfologia(self): '''Conjunto de herramientas para manejar parametros geomorfologicos de la cuenca analizada''' + def clickEventActivateGeoCheckBoxes(): + '''Selecciona y des-selecciona todas las opciones de calculo de una ves''' + #Si esta checked todas se seleccionan + if self.checkBoxTodos.isChecked(): + self.checkBoxArea.setChecked(True) + self.checkBoxOrder.setChecked(True) + self.checkBoxChannels.setChecked(True) + self.checkBoxDist2Out.setChecked(True) + self.checkBoxHAND.setChecked(True) + self.checkBoxIT.setChecked(True) + #Si no, des-selecciona a todas + else: + self.checkBoxArea.setChecked(False) + self.checkBoxOrder.setChecked(False) + self.checkBoxChannels.setChecked(False) + self.checkBoxDist2Out.setChecked(False) + self.checkBoxHAND.setChecked(False) + self.checkBoxIT.setChecked(False) + def clickEventGeoRasterProp(): '''calcula los parametros geomorfologicos de la cuenca por raster''' #Lista de variables a calcular @@ -237,7 +256,7 @@ def clickEventGeoRasterProp(): self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[k],k, self.Tabla_Prop_WMF) #Botones de ejecucion self.ButtonGeomorfoRasterVars.clicked.connect(clickEventGeoRasterProp) - + self.checkBoxTodos.clicked.connect(clickEventActivateGeoCheckBoxes) def setupHidro_Balance(self): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 525845c..60212c5 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -3849,7 +3849,6 @@ - From f2f133c4c4f6035746e441c73ae74cba0966421a Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 5 Jul 2018 10:18:27 -0500 Subject: [PATCH 062/142] =?UTF-8?q?geomorfologia,=20el=20reporte=20resumen?= =?UTF-8?q?=20ya=20se=20genera=20en=20la=20tabla,=20correciones=20menores?= =?UTF-8?q?=20a=20nombres=20de=20categor=C3=ADas=20de=20los=20mapas=20rast?= =?UTF-8?q?er=20de=20geomorfologia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPluginUtils.py | 24 ++++++----- qgisplugin/HydroSEDPlugin_dockwidget.py | 44 ++++++++++++++++++++ qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 14 ++++++- wmf/wmf.py | 34 +++++++-------- 4 files changed, 86 insertions(+), 30 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index e768aa8..d653780 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -254,7 +254,7 @@ def Basin_GeoGetAcumSlope(self): 'shape':self.cuenca.CellAcum.shape, 'raster':True, 'basica': False, - 'categoria': 'Geo', + 'categoria': 'Geomorfo', 'var': self.cuenca.CellAcum}}) self.DicBasinWMF.update({'Pendiente': {'nombre':'Pendiente', @@ -262,7 +262,7 @@ def Basin_GeoGetAcumSlope(self): 'shape':self.cuenca.CellSlope.shape, 'raster':True, 'basica': False, - 'categoria': 'Geo', + 'categoria': 'Geomorfo', 'var': self.cuenca.CellSlope}}) def Basin_GeoGetOrder(self): @@ -273,7 +273,7 @@ def Basin_GeoGetOrder(self): 'shape':self.cuenca.CellHorton_Hill.shape, 'raster':True, 'basica': False, - 'categoria': 'Geo', + 'categoria': 'Geomorfo', 'var': self.cuenca.CellHorton_Hill}}) self.DicBasinWMF.update({'Order_channels': {'nombre':'Order_channels', @@ -281,7 +281,7 @@ def Basin_GeoGetOrder(self): 'shape':self.cuenca.CellHorton_Stream.shape, 'raster':True, 'basica': False, - 'categoria': 'Geo', + 'categoria': 'Geomorfo', 'var': self.cuenca.CellHorton_Stream}}) def Basin_GeoGetIT(self): @@ -292,7 +292,7 @@ def Basin_GeoGetIT(self): 'shape':IT.shape, 'raster':True, 'basica': False, - 'categoria': 'Geo', + 'categoria': 'Geomorfo', 'var': IT}}) def Basin_GeoGetChannels(self): @@ -303,7 +303,7 @@ def Basin_GeoGetChannels(self): 'shape':self.cuenca.CellCauce.shape, 'raster':True, 'basica': False, - 'categoria': 'Geo', + 'categoria': 'Geomorfo', 'var': self.cuenca.CellCauce}}) def Basin_GeoGetDist2Out(self): @@ -314,7 +314,7 @@ def Basin_GeoGetDist2Out(self): 'shape':self.cuenca.CellDist2Out.shape, 'raster':True, 'basica': False, - 'categoria': 'Geo', + 'categoria': 'Geomorfo', 'var': self.cuenca.CellDist2Out}}) def Basin_GeoGetHAND(self): @@ -325,7 +325,7 @@ def Basin_GeoGetHAND(self): 'shape':self.cuenca.CellHAND.shape, 'raster':True, 'basica': False, - 'categoria': 'Geo', + 'categoria': 'Geomorfo', 'var': self.cuenca.CellHAND}}) self.DicBasinWMF.update({'HDND': {'nombre':'HDND', @@ -333,7 +333,7 @@ def Basin_GeoGetHAND(self): 'shape':self.cuenca.CellHDND.shape, 'raster':True, 'basica': False, - 'categoria': 'Geo', + 'categoria': 'Geomorfo', 'var': self.cuenca.CellHDND}}) self.DicBasinWMF.update({'HAND_class': {'nombre':'HAND_class', @@ -341,5 +341,9 @@ def Basin_GeoGetHAND(self): 'shape':self.cuenca.CellHAND_class.shape, 'raster':True, 'basica': False, - 'categoria': 'Geo', + 'categoria': 'Geomorfo', 'var': self.cuenca.CellHAND_class}}) + + def Basin_GeoGetParameters(self): + self.cuenca.GetGeo_Parameters() + return self.cuenca.GeoParameters, self.cuenca.Tc diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index b6ddb2f..b92a804 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -226,6 +226,48 @@ def clickEventActivateGeoCheckBoxes(): self.checkBoxHAND.setChecked(False) self.checkBoxIT.setChecked(False) + def GeoTableStart(): + '''Inicia la tabla donde monta los parametros geomorfologicos de la cuenca''' + self.GeoTableNumRows = 23 + self.GeoTableNumItems = 0 + self.GeoTableHeader = ["Parametro", "Valor", "Unidades"] + self.TableGeoParameters.setRowCount(self.GeoTableNumRows) + self.TableGeoParameters.setColumnCount(len(self.GeoTableHeader)) + self.TableGeoParameters.setHorizontalHeaderLabels(self.GeoTableHeader) + + def clickEventGeoProperties(): + '''Calcula los parametros geomorfologicos de la cuenca.''' + #Reinicia la talba para que no se llene de cosas + self.GeoTableNumItems = 0 + self.TableGeoParameters.clear() + self.TableGeoParameters.clearContents() + #Calcula los parametros. + Param,Tc = self.HSutils.Basin_GeoGetParameters() + print Param + #Inicia la tabla + GeoTableStart() + #le pone los parametros + for d in Param.keys(): + #Obtiene nombre y unidad + cadena = d.split('_') + unidad = cadena[-1].split('[')[-1].split(']')[0] + nombre = ' '.join(cadena[:-1]) + valor = '%.3f' % Param[d] + #Actualiza la tabla + self.TableGeoParameters.setItem (self.GeoTableNumItems, 0, QTableWidgetItem(nombre)) + self.TableGeoParameters.setItem (self.GeoTableNumItems, 1, QTableWidgetItem(valor)) + self.TableGeoParameters.setItem (self.GeoTableNumItems, 2, QTableWidgetItem(unidad)) + self.GeoTableNumItems += 1 + for d in Tc.keys(): + nombre = d + valor = '%.3f' % Tc[d] + unidad = 'Hrs' + #Actualiza la tabla + self.TableGeoParameters.setItem (self.GeoTableNumItems, 0, QTableWidgetItem(nombre)) + self.TableGeoParameters.setItem (self.GeoTableNumItems, 1, QTableWidgetItem(valor)) + self.TableGeoParameters.setItem (self.GeoTableNumItems, 2, QTableWidgetItem(unidad)) + self.GeoTableNumItems += 1 + def clickEventGeoRasterProp(): '''calcula los parametros geomorfologicos de la cuenca por raster''' #Lista de variables a calcular @@ -254,9 +296,11 @@ def clickEventGeoRasterProp(): #Actualiza la tabla de variables temporales for k in ListaVar: self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[k],k, self.Tabla_Prop_WMF) + #Botones de ejecucion self.ButtonGeomorfoRasterVars.clicked.connect(clickEventGeoRasterProp) self.checkBoxTodos.clicked.connect(clickEventActivateGeoCheckBoxes) + self.ButtonGeoParameters.clicked.connect(clickEventGeoProperties) def setupHidro_Balance(self): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 60212c5..cea2015 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -3068,7 +3068,7 @@ 0 - -308 + 0 443 1918 @@ -3468,7 +3468,17 @@ - + + + true + + + true + + + true + + diff --git a/wmf/wmf.py b/wmf/wmf.py index ac02c44..5496609 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -963,10 +963,8 @@ def GetGeo_Parameters(self,rutaParamASC=None,plotTc=False, 'GeoParameters : Parametros de la cuenca calculados.\n'\ 'Tc : Tiempo de concentracion calculado para la cuenca.\n'\ #Calcula lo que se necesita para sacar los parametros - acum,longCeld,S0,Elev=cu.basin_basics(self.structure, - self.DEM,self.DIR,cu.ncols,cu.nrows,self.ncells) - slope=cu.basin_arc_slope(self.structure,self.DEM,self.ncells, - cu.ncols,cu.nrows) + acum,longCeld,slope,Elev=cu.basin_basics(self.structure, + self.DEMvec,self.DIRvec,self.ncells) Lpma,puntto=cu.basin_findlong(self.structure,self.ncells) cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod(self.structure, acum,self.umbral,self.ncells) @@ -990,21 +988,21 @@ def GetGeo_Parameters(self,rutaParamASC=None,plotTc=False, x,y = cu.basin_coordxy(self.structure,self.ncells) CentXY = [np.median(x),np.median(y)] #Genera un diccionario con las propiedades de la cuenca - self.GeoParameters={'Area[km2]': Area, - 'Pend_Cauce [%]':Scau, - 'Long_Cau [km]': Lcau, - 'Pend_Cuenca [%]': Scue, - 'Long_Cuenca [km]': Lpma, - 'Hmax_[m]':Hmax, - 'Hmin_[m]':Hmin, - 'Hmean_[m]':Hmean, - 'H Cauce_Max [m]':HCmax, - 'Centro_[X]': CentXY[0], - 'Centro_[Y]': CentXY[1], - 'Long_tot_cauces[km]': TotalCauces, - 'Densidad_drenaje[km/km2]': Densidad} + self.GeoParameters={'Area_[km2]': Area, + 'Pend_Cauce_[%]':Scau, + 'Long_Cauce_[km]': Lcau, + 'Pend_Cuenca_[%]': Scue, + 'Long_Cuenca_[km]': Lpma, + 'Hmax_[m]':Hmax, + 'Hmin_[m]':Hmin, + 'Hmean_[m]':Hmean, + 'H_Cauce_Max_[m]':HCmax, + 'Centro_[X]': CentXY[0], + 'Centro_[Y]': CentXY[1], + 'Long_tot_cauces_[km]': TotalCauces, + 'Densidad_drenaje_[km/km2]': Densidad} if GetPerim: - self.GeoParameters.update({'Perimetro[km]':Perim}) + self.GeoParameters.update({'Perimetro_[km]':Perim}) #Calcula los tiempos de concentracion Tiempos={} Tc=0.3*(Lcau/(Scue**0.25))**0.75 From 8c187b734368dc5db8e7642d6e70ade91a883075 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 5 Jul 2018 17:37:12 -0500 Subject: [PATCH 063/142] =?UTF-8?q?se=20comienza=20a=20elaborar=20el=20esq?= =?UTF-8?q?ueleto=20de=20lo=20que=20ser=C3=A1=20el=20tab=20de=20simulaci?= =?UTF-8?q?=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPlugin_dockwidget.py | 15 +- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 492 +++++++++++++------ 2 files changed, 351 insertions(+), 156 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index b92a804..0315d94 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -179,6 +179,10 @@ def clickEventBasin2WMF(): self.LineEditNoData.setText(texto) self.spinBox_dxPlano.setValue(dxp) self.SpinGeoUmbralCanal.setValue(self.umbral) + #Actualiza comboBox de goemorfo + for k in self.HSutils.DicBasinWMF.keys(): + self.ComboGeoMaskVar.addItem(k) + def clickEventBasinLoadDivisory(): '''Carga la divisoria de la cuenca cargada a WMF''' @@ -206,6 +210,8 @@ def clickEventBasinLoadNetwork(): def setupGeomorfologia(self): '''Conjunto de herramientas para manejar parametros geomorfologicos de la cuenca analizada''' + + def clickEventActivateGeoCheckBoxes(): '''Selecciona y des-selecciona todas las opciones de calculo de una ves''' @@ -267,7 +273,7 @@ def clickEventGeoProperties(): self.TableGeoParameters.setItem (self.GeoTableNumItems, 1, QTableWidgetItem(valor)) self.TableGeoParameters.setItem (self.GeoTableNumItems, 2, QTableWidgetItem(unidad)) self.GeoTableNumItems += 1 - + def clickEventGeoRasterProp(): '''calcula los parametros geomorfologicos de la cuenca por raster''' #Lista de variables a calcular @@ -296,11 +302,14 @@ def clickEventGeoRasterProp(): #Actualiza la tabla de variables temporales for k in ListaVar: self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[k],k, self.Tabla_Prop_WMF) + self.ComboGeoMaskVar.addItem(k) + self.ComboGeoVar2Acum.addItem(k) #Botones de ejecucion self.ButtonGeomorfoRasterVars.clicked.connect(clickEventGeoRasterProp) self.checkBoxTodos.clicked.connect(clickEventActivateGeoCheckBoxes) self.ButtonGeoParameters.clicked.connect(clickEventGeoProperties) + #self.ComboGeoMaskVar.activated.connect(clickEventUpdateComboBoxMask) def setupHidro_Balance(self): @@ -360,10 +369,10 @@ def hadleClickEventEjecutarBalance(): #Habilita botones de visualizacion de variables if len(self.PathOutHydro_Qmed.text()) > 2: self.Button_HidroViewQmed.setEnabled(True) - #Actualiza la tabla de variables temporales + #Actualiza la tabla de variables temporales y actualiza comboBox de gomorfo for k in ['Caudal','ETR','Runoff']: self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[k],k, self.Tabla_Prop_WMF) - + #Botones para variables de entrada self.Boton_HidroLoadRain.clicked.connect(clickEventSelectorRaster) #Botones para variables de salida diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index cea2015..f875f2d 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -245,7 +245,7 @@ - 3 + 4 @@ -3478,6 +3478,12 @@ true + + 50 + + + true + @@ -3497,6 +3503,9 @@ + + false + Exportar parámetros geomorfológicos a excel. @@ -3642,20 +3651,20 @@ 10 10 - 341 - 400 + 451 + 721 - 0 - 200 + 430 + 400 16777215 - 400 + 750 @@ -3669,8 +3678,8 @@ 0 0 - 323 - 930 + 433 + 1918 @@ -3687,156 +3696,333 @@ - - - - 0 - 100 - - - - - 16777215 - 16777215 - - - - Grupo 1 - - - - - - TextLabel - - - - - - - - - - - + 0 - 300 - - - - - 16777215 - 16777215 - - - - Grupo 2 - - - - - - TextLabel - - - - - - - - - - TextLabel - - - - - - - - - - TextLabel - - - - - - - - - - TextLabel - - - - - - - - - - - - - - 0 - 500 - - - - - 16777215 - 16777215 + 1900 - - Grupo 3 - - - - - - TextLabel - - - - - - - - - - TextLabel - - - - - - - - - - TextLabel - - - - - - - - - - TextLabel - - - - - - - + + + + 0 + 0 + 411 + 71 + + + + Serie de Caudal Observado + + + + + 0 + 20 + 401 + 51 + + + + + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Seleccionar la ruta donde se va a guardar la corriente. + + + Seleccionar la ruta donde se va a guardar la corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + 0 + 80 + 411 + 481 + + + + Variables Físicas + + + + + 0 + 60 + 401 + 351 + + + + + + + 4 + + + + + Variable + + + + + + + + + + Coef + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Vh2 [m/s] + + + + + + + + + + Expo + + + + + + + + + + Vh3 [m/s] + + + + + + + Vh1 [m/s] + + + + + + + + + + + + + + + + Vv1 [mm/s] + + + + + + + + + + Vv2 [mm/s] + + + + + + + + + + Vh4 [m/s] + + + + + + + + + + + + + + + + + + + Vv3 [mm/s] + + + + + + + + + + + + + Hg [mm] + + + + + + + Hu [mm] + + + + + + + Nombre variable + + + + + + + + + + + 0 + 410 + 401 + 51 + + + + + + + + + Nombre calibración + + + + + + + false + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg + + + + + + + Establecer + + + + + + + + + + + 0 + 20 + 401 + 41 + + + + + + + Seleccionar calibración anterior + + + + + + + + + From 8b2d3ba4012d7176e75559c880fb7ddc64e3d21f Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 12 Jul 2018 11:28:57 -0500 Subject: [PATCH 064/142] sigue avanzando el desarrollo de la interfaz del modelo en el gui, cambia la forma de interpolar la lluvia --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 4167 ++++++++++-------- qgisplugin/resources.qrc | 2 + 2 files changed, 2400 insertions(+), 1769 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index f875f2d..061dfb0 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -220,22 +220,6 @@ tabPanelDockOpciones - - - - QFrame::Raised - - - 4 - - - 2 - - - Qt::Horizontal - - - @@ -245,7 +229,7 @@ - 4 + 3 @@ -1253,8 +1237,8 @@ 0 0 - 446 - 728 + 443 + 918 @@ -1270,248 +1254,12 @@ - - - - - 299 - 180 - - - - - 50000 - 50000 - - - - - - 0 - 30 - 421 - 168 - - - - - - - - - Punto de inicio de trazado de la corriente - - - Punto de inicio de trazado de la corriente - - - Ubicación - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Obtener coordenadas dando click sobre el mapa - - - Obtener coordenadas dando click sobre el mapa - - - - - - - :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png - - - - - - - - - - - Coordenada en Y del punto de inicio. - - - Coordenada en Y del punto de inicio. - - - Latitud: - - - - - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 - - - - - - - - - - - Coordenada en X del punto de inicio. - - - Coordenada en X del punto de inicio. - - - Longitud - - - - - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 - - - - - - - - - Qt::Horizontal - - - - - - - Ruta corriente trazada (*.shp): - - - - - - - - - false - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - Seleccionar la ruta donde se va a guardar la corriente. - - - Seleccionar la ruta donde se va a guardar la corriente. - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - Ejecutar la función de trazado de corriente. - - - Ejecutar la función de trazado de corriente. - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - - - - - - - - - - 0 - 10 - 171 - 16 - - - - - 13 - 75 - true - - - - Corrientes - - - Qt::PlainText - - - - - - - - Qt::Horizontal - - - 250 - 500 + 900 @@ -1524,9 +1272,9 @@ 0 - 30 + 280 421 - 402 + 436 @@ -1934,70 +1682,302 @@ - + 0 - 10 - 171 - 16 + 0 + 421 + 231 - - - 13 - 75 - true - - - - Cuencas - - - Qt::PlainText + + Corriente - - - - - - - - - - Hidrología - - - - - 0 - 0 - 461 - 730 - - - - - 430 - 400 - - - - - 50000 - 50000 - - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAsNeeded - - - true - - + + + + 0 + 20 + 421 + 211 + + + + + + + + + Punto de inicio de trazado de la corriente + + + Punto de inicio de trazado de la corriente + + + Ubicación + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Obtener coordenadas dando click sobre el mapa + + + Obtener coordenadas dando click sobre el mapa + + + + + + + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png + + + + + + + + + + + Coordenada en Y del punto de inicio. + + + Coordenada en Y del punto de inicio. + + + Latitud: + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + + + + + Coordenada en X del punto de inicio. + + + Coordenada en X del punto de inicio. + + + Longitud + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + + + Qt::Horizontal + + + + + + + Ruta corriente trazada (*.shp): + + + + + + + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Seleccionar la ruta donde se va a guardar la corriente. + + + Seleccionar la ruta donde se va a guardar la corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + Ejecutar la función de trazado de corriente. + + + Ejecutar la función de trazado de corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + + 0 + 0 + 421 + 1900 + + + + + 0 + 1900 + + + + + + + + 0 + 260 + 421 + 650 + + + + + 0 + 650 + + + + Cuenca + + + + + + 0 + 240 + 421 + 16 + + + + Qt::Horizontal + + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/geomorfologia.ico:/plugins/HydroSEDPlugin/icons/geomorfologia.ico + + + Geomorfología + + + + + 0 + 0 + 461 + 730 + + + + + 430 + 400 + + + + + 50000 + 50000 + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + true + + 0 @@ -2018,9 +1998,9 @@ 16777215 - + - + 300 @@ -2033,1265 +2013,1455 @@ 50000 - + 0 - 0 - 431 - 231 + 320 + 421 + 271 - - - 0 - 200 - + + Calcúla características geomorfológicas ráster de la cuenca. - - - 16777215 - 16777215 - + + Calcúla características geomorfológicas ráster de la cuenca. - Balance Largo Plazo, Q = A(P-E) - - - false + Geomorfología Raster - - - - - - - Qt::Horizontal - - - - - - - - 0 - 10 - - - - - 75 - true - - - - Datos de entrada: - - - - - - - - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - - - Lluvia* [mm/año] - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - false - - - - - - - Establecer ruta donde se aloja el mapa de precipitación. - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - false - - - - 40 - 16777215 - - - - Visualizar shp con el caudal calculado por tramos. - - - Visualizar shp con el caudal calculado por tramos. - - - Ver - - - - - - - - - - - Estimación de la evaporación anual (mm/año), seleccionar metodología o cargar mapa. - - - Estimación de la evaporación anual (mm/año), seleccionar metodología o cargar mapa. - - - ETR [mm/año] - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - Metodología de cálculo Turc. - - - Metodología de cálculo Turc. - - - Turc - - - true - - - - - - - Metodología de cálculo Cenicafe. - - - Metodología de cálculo Cenicafe. - - - Cenicafe - - - false - - - - - - - Metodología de cálculo Choudry. - - - Metodología de cálculo Choudry. - - - Choudry - - - - - - - - - - - - Qt::Horizontal - - - - - - - - 75 - true - - - - Datos de salida: - - - Qt::AutoText - - - - - - - - - El valor del caudal calculado en cada tramo hidrológico. - - - El valor del caudal calculado en cada tramo hidrológico. - - - Qmed*[m3/s] - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - Ruta de guardado - - - false - - - - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - false - - - - 40 - 16777215 - - - - Visualizar shp con el caudal calculado por tramos. - - - Visualizar shp con el caudal calculado por tramos. - - - Ver - - - - - - - - - - - - 75 - true - - - - El valor del caudal calculado solo a la salida de la cuenca. - - - El valor del caudal calculado solo a la salida de la cuenca. - - - Q salida [m3/s]: - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - true - - - - - - - Ejecuta el balance de largo plazo con los parametros dados. - - - Ejecuta el balance de largo plazo con los parametros dados. - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - - - - - - - + + + + 10 + 30 + 401 + 181 + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Calcular mapas raster de área acumulada y pendiente (Area, Pendiente). + + + Calcular mapas raster de área acumulada y pendiente (Area, Pendiente). + + + Área, Pendiente. + + + + + + + calcula todos los parámetros geomorfológicos distribuidos. + + + calcula todos los parámetros geomorfológicos distribuidos. + + + Seleccionar todos + + + + + + + Calcular mapas raster con el orden de strahler. (Order_hills, Order_channels) + + + Calcular mapas raster con el orden de strahler. (Order_hills, Order_channels) + + + Orden de canales y laderas + + + + + + + Calcula mapas raster de la elevación relativa al canal (Rennó, 2008) (HAND, HDND, HAND_class) + + + Calcula mapas raster de la elevación relativa al canal (Rennó, 2008) (HAND, HDND, HAND_class) + + + HAND + + + + + + + Cálcula mapa raster del IT (índice topográfico) (Beven, 1974) (IT) + + + Cálcula mapa raster del IT (índice topográfico) (Beven, 1974) (IT) + + + Índice Topográfico. + + + + + + + Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + + + Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + + + Distancia a la salida. + + + + + + + Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + + + Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + + + Canales + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Calcular parámetros seleccionados (enviados a Variables WMF) + + + Calcular parámetros seleccionados (enviados a Variables WMF) + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + GrupoGeoParametros + verticalLayoutWidget_4 - + 0 - 230 - 431 - 351 + 580 + 421 + 181 - - - 0 - 350 - - - - - 16777215 - 16777215 - - - Interpolación Campo de lluvia + Acumular Variable: - + false - - - - - - - Qt::Horizontal - - - - - - - - 0 - 10 - - - - - 75 - true - - - - Datos de entrada: - - - - - - - - - Vectorial con los puntos de los pluviometros a interpolar. - - - Vectorial con los puntos de los pluviometros a interpolar. - - - Pluviómetros - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - false - - - - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - false - - - - 40 - 16777215 - - - - Visualizar puntos de pluviómetros. - - - Ver - - - - - - - - - - - Campo de atributos a partir del cual se realiza la interpolación. - - - Campo de atributos a partir del cual se realiza la interpolación. - - - Campo - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - false - - - - - - - false - - - - 0 - 0 - - - - - 30 - 0 - - - - - 100 - 16777215 - - - - Seleccionar el campo a interpolar. - - - Seleccionar el campo a interpolar. - - - Campo - - - - - - - - - - - - - - - - - - Archivo de excel con las series de tiempo de los puntos a interpolar. - - - Archivo de excel con las series de tiempo de los puntos a interpolar. - - - Archivo excel - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - false - - - - - - - false - - - - 100 - 16777215 - - - - Establecer archivo de excel a utilizar. - - - Establecer archivo de excel a utilizar. - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - - - - - - - - - - - Metodología utilizada para la interpolación: IDW (inverse distance weighted), TIN (Triangular irregular network) - - - Metodología utilizada para la interpolación: IDW (inverse distance weighted), TIN (Triangular irregular network) - - - Metodología - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - Metodología de interpolación IDW. - - - Metodología de interpolación IDW. - - - IDW - - - true - - - - - - - Metodología de interpolación TIN. - - - Metodología de interpolación TIN. - - - TIN - - - false - - - - - - - - - - - Exponente para ponderar la distancia en la metodología IDW. - - - Exponente para ponderar la distancia en la metodología IDW. - - - Exponente distancia IDW - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - - 50 - 0 - - - - 2 - - - 1.000000000000000 - - - 20.000000000000000 - - - 1.000000000000000 - - - - - - - - - Qt::Horizontal - - - - - - - - 75 - true - - - - Datos de salida: - - - Qt::AutoText - - - - - - - - - Ruta de guardado del campo de lluvia.tif (en el caso de que sea solo un intervalo). - - - Ruta de guardado del campo de lluvia.tif (en el caso de que sea solo un intervalo). - - - Campo de lluvia - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - Ruta de guardado - - - false - - - - - - - Establecer ruta del raster de lluvia interpolado. - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - false - - - - 40 - 16777215 - - - - Visualiza el raster del campo de lluvia interpolado. - - - Ver - - - - - - - - - - - Ruta de guardado del binario de fortran con la serie de precipitación interpolada. - - - Ruta de guardado del binario de fortran con la serie de precipitación interpolada. - - - Binario de lluvia - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - Ruta de guardado - - - false - - - - - - - Establecer ruta de guardado del binario de lluvia. - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - 50 - 0 - - - - Entrada del binario de lluvia a visualizar. - - - 0 - - - 0.000000000000000 - - - 10000000.000000000000000 - - - 1.000000000000000 - - - - - - - false - - - - 40 - 16777215 - - - - Visualiza una entrada del binario de lluvia interpolado. - - - Ver - - - - - - - - - Qt::Horizontal - - - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - Ejecuta la interpolación para la cuenca con los parámetros dados. - - - Ejecuta la interpolación para la cuenca con los parámetros dados. - - - Ejecutar - - - - - - + + + + 10 + 30 + 401 + 141 + + + + + + + + 0 + 10 + + + + + 75 + true + + + + Datos de entrada: + + + + + + + + + Variable de WMf utilizada como máscara para acumular variables. + + + Variable de WMf utilizada como máscara para acumular variables. + + + Mascara + + + + + + + + 250 + 0 + + + + + + + + + + + + Variables a acumular cargada en WMF + + + Variables a acumular cargada en WMF + + + Variable + + + + + + + + 250 + 0 + + + + + + + + + + + + Nombre de la variable acumulada. + + + Nombre de la variable acumulada. + + + Nombre variable acumulada: + + + + + + + + 290 + 16777215 + + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Acumular variable (cargada a Variables WMF). + + + Acumular variable (cargada a Variables WMF). + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + + + 0 + 40 + 421 + 271 + + + + Calcúla los parámetros básicos de la cuenca. + + + Calcúla los parámetros básicos de la cuenca. + + + Parámetros geomorfológicos + + + + + 0 + 330 + 411 + 21 + + + + Qt::Horizontal + + + + + + 10 + 30 + 401 + 211 + + + + + + + true + + + true + + + true + + + 50 + + + true + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Exportar parámetros geomorfológicos a excel. + + + Exportar parámetros geomorfológicos a excel. + + + + + + + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png + + + + + + + Calcula parámetros geomorfológicos básicos de la cuenca. + + + Calcula parámetros geomorfológicos básicos de la cuenca. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + + 200 + 270 + 411 + 21 + + + + Qt::Horizontal + + + + + + 0 + 260 + 411 + 21 + + + + Qt::Horizontal + + + + + + + 10 + 550 + 411 + 21 + + + + Qt::Horizontal + + + + + + 10 + 0 + 399 + 41 + + + + + + + Umbral a partir del cual se consideran corrientes (defecto el de la cuenca) + + + Umbral a partir del cual se consideran corrientes (defecto el de la cuenca) + + + Umbral para estimar canales: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 0 + + + 0.000000000000000 + + + 100000.000000000000000 + + + 0.000000000000000 + + - - - - - - - - - - :/plugins/HydroSEDPlugin/icons/geomorfologia.ico:/plugins/HydroSEDPlugin/icons/geomorfologia.ico - - - Geomorfología - - - - - 0 - 0 - 461 - 730 - - - - - 430 - 400 - - - - - 50000 - 50000 - - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAsNeeded - - - true - - - - - 0 - 0 - 443 - 1918 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - - - - 300 - 1900 - - - - - 50000 - 50000 - - - + + + + + + + + + Hidrología + + + + + 0 + 0 + 461 + 730 + + + + + 430 + 400 + + + + + 50000 + 50000 + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + true + + + + + 0 + 0 + 443 + 1918 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + 300 + 1900 + + + + + 50000 + 50000 + + + + + + 0 + 350 + 421 + 241 + + + + Balance hidrológico + + + + + 0 + 30 + 411 + 203 + + + + + + + Qt::Horizontal + + + + + + + + 0 + 10 + + + + + 75 + true + + + + Datos de entrada: + + + + + + + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Lluvia* [mm/año] + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + false + + + + + + + Establecer ruta donde se aloja el mapa de precipitación. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + false + + + + 40 + 16777215 + + + + Visualizar shp con el caudal calculado por tramos. + + + Visualizar shp con el caudal calculado por tramos. + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + + + + + Estimación de la evaporación anual (mm/año), seleccionar metodología o cargar mapa. + + + Estimación de la evaporación anual (mm/año), seleccionar metodología o cargar mapa. + + + ETR [mm/año] + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + Metodología de cálculo Turc. + + + Metodología de cálculo Turc. + + + Turc + + + true + + + + + + + Metodología de cálculo Cenicafe. + + + Metodología de cálculo Cenicafe. + + + Cenicafe + + + false + + + + + + + Metodología de cálculo Choudry. + + + Metodología de cálculo Choudry. + + + Choudry + + + + + + + + + + + + Qt::Horizontal + + + + + + + + 75 + true + + + + Datos de salida: + + + Qt::AutoText + + + + + + + + + El valor del caudal calculado en cada tramo hidrológico. + + + El valor del caudal calculado en cada tramo hidrológico. + + + Qmed*[m3/s] + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + Ruta de guardado + + + false + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + false + + + + 40 + 16777215 + + + + Visualizar shp con el caudal calculado por tramos. + + + Visualizar shp con el caudal calculado por tramos. + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + + + + + + 75 + true + + + + El valor del caudal calculado solo a la salida de la cuenca. + + + El valor del caudal calculado solo a la salida de la cuenca. + + + Q salida [m3/s]: + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + true + + + + + + + Ejecuta el balance de largo plazo con los parametros dados. + + + Ejecuta el balance de largo plazo con los parametros dados. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + 0 - 320 - 421 - 271 + 0 + 411 + 331 - - Calcúla características geomorfológicas ráster de la cuenca. - - - Calcúla características geomorfológicas ráster de la cuenca. - - Geomorfología Raster + Generador campos de lluvia - + - 10 - 30 - 401 - 181 + 0 + 20 + 411 + 307 - + + + + + Qt::Horizontal + + + + + + + + 0 + 10 + + + + + 75 + true + + + + Datos de entrada: + + + + + + + + + Vectorial con los puntos de los pluviometros a interpolar. + + + Vectorial con los puntos de los pluviometros a interpolar. + + + Pluviómetros + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + false + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + - - - QFormLayout::AllNonFixedFieldsGrow - - - + + + - Calcular mapas raster de área acumulada y pendiente (Area, Pendiente). + Archivo de excel con las series de tiempo de los puntos a interpolar. - Calcular mapas raster de área acumulada y pendiente (Area, Pendiente). + Archivo de excel con las series de tiempo de los puntos a interpolar. - Área, Pendiente. + Archivo excel - - + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + false + + + + + + + true + + + + 100 + 16777215 + + - calcula todos los parámetros geomorfológicos distribuidos. + Establecer archivo de excel a utilizar. - calcula todos los parámetros geomorfológicos distribuidos. + Establecer archivo de excel a utilizar. - Seleccionar todos + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - + + + + + + - Calcular mapas raster con el orden de strahler. (Order_hills, Order_channels) + Exponente para ponderar la distancia en la metodología IDW. - Calcular mapas raster con el orden de strahler. (Order_hills, Order_channels) + Exponente para ponderar la distancia en la metodología IDW. - Orden de canales y laderas + Exponente distancia IDW - - + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + + 50 + 0 + + + + 2 + + + 1.000000000000000 + + + 20.000000000000000 + + + 1.000000000000000 + + + + + + + + + + + Fecha inicio interpolación + + + + + + + + 2015 + 1 + 1 + + + + + + + + + + + + Fecha fin interpolación + + + + + + + + 2015 + 1 + 1 + + + + + + + + + + Qt::Horizontal + + + + + + + + 75 + true + + + + Datos de salida: + + + Qt::AutoText + + + + + + + - Calcula mapas raster de la elevación relativa al canal (Rennó, 2008) (HAND, HDND, HAND_class) + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. - Calcula mapas raster de la elevación relativa al canal (Rennó, 2008) (HAND, HDND, HAND_class) + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. - HAND + Binario de lluvia - - - - Cálcula mapa raster del IT (índice topográfico) (Beven, 1974) (IT) + + + + Qt::Horizontal + + + + 10 + 20 + + + + + - Cálcula mapa raster del IT (índice topográfico) (Beven, 1974) (IT) + Ruta de guardado + + + false + + + + + + + Establecer ruta de guardado del binario de lluvia. - Índice Topográfico. + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + + + + + 50 + 0 + - Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + Entrada del binario de lluvia a visualizar. + + + 0 + + + 0.000000000000000 + + + 10000000.000000000000000 + + + 1.000000000000000 + + + + + + + false + + + + 40 + 16777215 + + + + Visualiza una entrada del binario de lluvia interpolado. - Distancia a la salida. + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - - + + + + + + Qt::Horizontal + + + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + - Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + Ejecuta la interpolación para la cuenca con los parámetros dados. - Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + Ejecuta la interpolación para la cuenca con los parámetros dados. - Canales + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Calcular parámetros seleccionados (enviados a Variables WMF) - - - Calcular parámetros seleccionados (enviados a Variables WMF) - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - - - - - GrupoGeoParametros - verticalLayoutWidget_4 - + + + + -3 + 330 + 411 + 20 + + + + Qt::Horizontal + + + 0 - 580 + 620 421 - 181 + 271 - Acumular Variable: - - - false + Máximos regionalización - + - 10 + 0 30 - 401 - 141 + 411 + 236 - + - + + + Qt::Horizontal + + + + + 0 @@ -3310,224 +3480,291 @@ - + - + - Variable de WMf utilizada como máscara para acumular variables. + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - Variable de WMf utilizada como máscara para acumular variables. + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - Mascara + Caudal medio - - + + + Qt::Horizontal + + - 250 - 0 + 10 + 20 + + + + + + false + - + - + + + + + + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Cmed + + + + + + + + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Cdes + + + + + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Emed + + + + + + + + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Edes + + + + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + + + + + 75 + true + + + + Datos de salida: + + + Qt::AutoText + + + + + + + - Variables a acumular cargada en WMF + El valor del caudal calculado en cada tramo hidrológico. - Variables a acumular cargada en WMF + El valor del caudal calculado en cada tramo hidrológico. - Variable + Qmax*[m3/s] - - + + + Qt::Horizontal + + - 250 - 0 + 10 + 20 - + - - - - - - - Nombre de la variable acumulada. - + - Nombre de la variable acumulada. + Ruta de guardado - - Nombre variable acumulada: + + false - - - - 290 - 16777215 - + + + - - false + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - Qt::Horizontal + + + false - + 40 - 20 + 16777215 - - - - - Acumular variable (cargada a Variables WMF). + Visualizar shp con el caudal calculado por tramos. - Acumular variable (cargada a Variables WMF). + Visualizar shp con el caudal calculado por tramos. - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - - - - - - - 0 - 40 - 421 - 271 - - - - Calcúla los parámetros básicos de la cuenca. - - - Calcúla los parámetros básicos de la cuenca. - - - Parámetros geomorfológicos - - - - - 0 - 330 - 411 - 21 - - - - Qt::Horizontal - - - - - - 10 - 30 - 401 - 211 - - - - - - - true - - - true - - - true - - - 50 - - - true - - - - + - + + + + 75 + true + + + + El valor del caudal calculado solo a la salida de la cuenca. + + + El valor del caudal calculado solo a la salida de la cuenca. + + + Qmax salida [m3/s]: + + + + + Qt::Horizontal - 40 + 10 20 - - - false - - - Exportar parámetros geomorfológicos a excel. - - - Exportar parámetros geomorfológicos a excel. - - - - - - - :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png + + + true - + - Calcula parámetros geomorfológicos básicos de la cuenca. + Ejecuta el balance de largo plazo con los parametros dados. - Calcula parámetros geomorfológicos básicos de la cuenca. + Ejecuta el balance de largo plazo con los parametros dados. @@ -3542,100 +3779,20 @@ - - - - 200 - 270 - 411 - 21 - - - - Qt::Horizontal - - - - - - 0 - 260 - 411 - 21 - - - - Qt::Horizontal - - - + - 10 - 550 + 0 + 590 411 - 21 + 20 Qt::Horizontal - - - - 10 - 0 - 399 - 41 - - - - - - - Umbral a partir del cual se consideran corrientes (defecto el de la cuenca) - - - Umbral a partir del cual se consideran corrientes (defecto el de la cuenca) - - - Umbral para estimar canales: - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 0 - - - 0.000000000000000 - - - 100000.000000000000000 - - - 0.000000000000000 - - - - - @@ -3709,68 +3866,131 @@ 0 0 411 - 71 + 101 Serie de Caudal Observado - + 0 20 401 - 51 + 81 - + - - - false - - + + + + + Ruta a la serie de caudales obsevada + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Seleccionar la ruta donde se va a guardar la corriente. + + + Seleccionar la ruta donde se va a guardar la corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + - - - - 30 - 0 - - - - - 30 - 16777215 - - - - Seleccionar la ruta donde se va a guardar la corriente. - - - Seleccionar la ruta donde se va a guardar la corriente. - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - + + + + + Selección estación + + + + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + + + Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + + -3 + 530 + 411 + 20 + + + + Qt::Horizontal + + 0 - 80 + 330 411 - 481 + 641 @@ -3780,9 +4000,9 @@ 0 - 60 + 70 401 - 351 + 531 @@ -3791,6 +4011,15 @@ 4 + + + + + + + + + @@ -3808,6 +4037,13 @@ + + + + Krusle + + + @@ -3815,7 +4051,14 @@ - + + + Exponente regional en caso de usar aproximación no lineal v = C A^e + + + Exponente aproximación no lineal al flujo superficial + + @@ -3827,7 +4070,14 @@ - + + + Exponente regional en caso de usar aproximación no lineal v = C A^e + + + Exponente aproximación no lineal al flujo sub-superficial + + @@ -3903,51 +4153,127 @@ - + + + Exponente regional en caso de usar aproximación no lineal v = C A^e + + + Exponente aproximación no lineal al flujo subterráneo + + - + + + Exponente regional en caso de usar aproximación no lineal v = C A^e + + + Exponente aproximación no lineal al flujo en canales + + - - + + + + Vv3 [mm/s] + + + + + + + + + + + + + Hg [mm] + + + + + + + Hu [mm] + + + + + + + Nombre variable + + + + + + + Crusle + + + + + + + + + + + - Vv3 [mm/s] + Prusle - - - - - + + - - + + - Hg [mm] + Limos - - + + + + + + + + - Hu [mm] + Arcillas - - + + - Nombre variable + Arenas + + + + + + + + + + + + @@ -3956,9 +4282,9 @@ 0 - 410 + 600 401 - 51 + 41 @@ -4000,28 +4326,322 @@ - + 0 - 20 + 30 401 41 - + - - - Seleccionar calibración anterior - - + + + + + Seleccionar calibración anterior + + + + + + + + + + + + + + + 0 + 120 + 411 + 191 + + + + Serie de precipitación + + + + + 0 + 20 + 401 + 171 + + + + + + + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Seleccionar la ruta donde se va a guardar la corriente. + + + Seleccionar la ruta donde se va a guardar la corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + Fecha inicio simulación + + + + + + + + 2015 + 1 + 1 + + + + + + + + + + + + Fecha fin simulación + + + + + + + + 2015 + 12 + 31 + + + + + + + + + + + + Paso de tiempo (dt) + + + + + + + Paso del intervalo de tiempo en los campos cargados. + + + 0 + + + 0.000000000000000 + + + 100000.000000000000000 + + + 0.000000000000000 + + + + - + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Visualizar serie de precipitación entre las fechas seleccionadas. + + + Visualizar serie de precipitación. + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Visualizar acumulado de precipitación entre fecha inicial y final + + + Visualizar acumulado de precipitación entre fecha inicial y final + + + + + + + :/plugins/HydroSEDPlugin/icons/toRaster.ico:/plugins/HydroSEDPlugin/icons/toRaster.ico + + + + + + + + 130 + 280 + 115 + 50 + + + + Nombre variable + + + + + + + 0 + 310 + 411 + 20 + + + + Qt::Horizontal + + + + + + 0 + 970 + 411 + 20 + + + + Qt::Horizontal + + + + + + 0 + 990 + 401 + 271 + + + + Ejecución + + + + + 0 + 30 + 401 + 221 + + + + + + + + + 0 + 100 + 411 + 20 + + + + Qt::Horizontal + @@ -4031,20 +4651,29 @@ + + + + QFrame::Raised + + + 4 + + + 2 + + + Qt::Horizontal + + + - - - QgsCollapsibleGroupBox - QGroupBox -
qgscollapsiblegroupbox.h
- 1 -
-
+ diff --git a/qgisplugin/resources.qrc b/qgisplugin/resources.qrc index 370a019..5ebb4aa 100644 --- a/qgisplugin/resources.qrc +++ b/qgisplugin/resources.qrc @@ -1,5 +1,7 @@ + icons/toRaster.ico + icons/save.svg icons/toexcel.png icons/RedHidrica.ico icons/play.png From 22068f59a278cbf38b4029b5cc28cd2af22d63ac Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 17 Jul 2018 16:34:15 -0500 Subject: [PATCH 065/142] se ha introducido la funcion de actualizar el nc de la cuenca con la cual se este trabajando --- qgisplugin/HydroSEDPluginUtils.py | 33 + qgisplugin/HydroSEDPlugin_dockwidget.py | 20 +- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 8094 +++++++++--------- 3 files changed, 4093 insertions(+), 4054 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index d653780..778a2d4 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -4,6 +4,7 @@ from PyQt4 import QtGui, uic import netCDF4 from wmf import wmf +import numpy as np class controlHS: @@ -20,6 +21,7 @@ def __init__(self): self.StreamsCount = 0 self.DicBasinNc = {} self.DicBasinWMF = {} + self.Nc2Save = [] def cargar_mapa_raster (self,pathMapaRaster): @@ -163,6 +165,37 @@ def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed): #Retorna el resultado a la salida return self.cuenca.CellQmed[-1] + def Basin_Update(self, PathNC): + '''Actualiza el archivo nc de la cuenca con las variables agregadas o borradas de la misma''' + #Lectura del archivo + g = netCDF4.Dataset(PathNC,'a') + #Inclusion de nuevas variables + for l in self.Nc2Save: + #Selecciona el grupo del nc en donde va a meter la variable + Grupo = self.DicBasinNc[l]['categoria'] + Group = g.groups[Grupo] + #Obtiene el nombre, tipo y variable a actualizar + nombre = l + tipo = self.DicBasinNc[l]['tipo'] + if tipo == 'float32': + tipo = 'f4' + elif tipo == 'int64': + tipo = 'i4' + Var = np.copy(self.DicBasinNc[l]['var']) + #Trata de meter la variable como algo no existente + try: + print 'variable nueva' + VarName = Group.createVariable(nombre,tipo,('ncell',),zlib=True) + #si ya existe la variable la sobre escribe + except: + print 'variable vieja' + VarName = Grupo['variables'][nombre] + #guarda la variable + VarName[:] = Var + self.Nc2Save = [] + #Cerrado del archivo nc + g.close() + def Basin_LoadBasin(self, PathNC): # Numero Total de Variables self.NumDicBasinNcVariables = 0 diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 0315d94..94c2de2 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -182,7 +182,6 @@ def clickEventBasin2WMF(): #Actualiza comboBox de goemorfo for k in self.HSutils.DicBasinWMF.keys(): self.ComboGeoMaskVar.addItem(k) - def clickEventBasinLoadDivisory(): '''Carga la divisoria de la cuenca cargada a WMF''' @@ -210,8 +209,8 @@ def clickEventBasinLoadNetwork(): def setupGeomorfologia(self): '''Conjunto de herramientas para manejar parametros geomorfologicos de la cuenca analizada''' - - + + def clickEventActivateGeoCheckBoxes(): '''Selecciona y des-selecciona todas las opciones de calculo de una ves''' @@ -447,6 +446,7 @@ def handleClickEventButton_Eliminar_Desde_NC (): self.Tabla_Prop_NC.removeRow (selectedItems) self.TabNC.DelEntry(ItemName) self.HSutils.DicBasinNc.pop(ItemName) + self.HSutils.Nc2Erase.append(ItemName) def handleClickEventButton_Actualizar_WMF_Desde_NC (): rows = sorted (set (index.row () for index in self.Tabla_Prop_NC.selectedIndexes ())) @@ -503,8 +503,14 @@ def handleClickEventButton_WMF2NC(): self.TabNC.NewEntry(self.HSutils.DicBasinWMF[VarName], VarName, self.Tabla_Prop_NC) self.Tabla_Prop_WMF.removeRow (selectedItems) self.TabWMF.DelEntry(VarName) - self.HSutils.DicBasinWMF.pop(VarName) - + self.HSutils.DicBasinWMF.pop(VarName) + self.HSutils.Nc2Save.append(VarName) + + def clickEventBasinUpdateNC(): + '''Actualiza el archivo .nc de la cuenca con las variables cargadas en la TablaNC''' + RutaNC = self.lineEditRutaCuenca.text().strip() + self.HSutils.Basin_Update(RutaNC) + def setupLineEditButtonOpenShapeFileDialog (lineEditHolder, fileDialogHolder): '''Hace que cuando se busquen shapes solo se encuetren formatos vectoriales''' lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Shapefiles (*.shp);;")) @@ -647,7 +653,6 @@ def set_dxplano(): self.Button_Eliminar_Desde_WMF.clicked.connect(handleClickEventButton_Eliminar_Desde_WMF) self.Tabla_Prop_NC.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) self.Tabla_Prop_NC.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) - self.Button_Eliminar_Desde_NC.clicked.connect(handleClickEventButton_Eliminar_Desde_NC) #Botones de visualizacion de variables de NC self.Tabla_Prop_NC.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) self.Tabla_Prop_NC.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) @@ -659,7 +664,8 @@ def set_dxplano(): #Botones movimiento variables NC a WMF y de WMF a NC self.Button_NC2WMF.clicked.connect(handleClickEventButton_NC2WMF) self.Button_WMF2NC.clicked.connect(handleClickEventButton_WMF2NC) - + #Boton para actualizar los archivos que se encuentran guardados en un netCDF + self.Button_Update_NC.clicked.connect(clickEventBasinUpdateNC) class Tabla(): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 061dfb0..feb46a2 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -27,23 +27,17 @@ - - - - 16777215 - 100 - - + - Proyecto de Cuenca + Proyecto de cuenca - 10 + 0 20 - 455 - 81 + 461 + 101 @@ -94,6 +88,50 @@ + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Simulación + + + + + + + false + + + Sedimentos + + + + + + + false + + + Deslizamientos + + + + + @@ -196,2701 +234,304 @@ - + - 130 - 90 - 57 - 34 + 0 + 150 + 469 + 776 - - Coordenada en X del punto de inicio. - - - Coordenada en X del punto de inicio. + + + 0 + 0 + - - Cuenca: + + 1 - - verticalLayoutWidget_3 - labelLongitudTrazadorCorrientes_17 - tabPanelDockOpciones - - - - - - - 0 - 0 - - - - 3 - - - - - :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png - - - - - - - - 0 - 0 - 461 - 730 - - - - - 430 - 400 - - - - - 50000 - 50000 - - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAsNeeded - - - true - - + + + + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png + + + + + 0 0 - 443 - 2018 + 461 + 730 - 0 - 0 + 430 + 400 - 16777215 - 16777215 + 50000 + 50000 - - - - - - 300 - 2000 - - - - - 50000 - 50000 - - - - - - 0 - 0 - 425 - 1147 - + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + true + + + + + 0 + 0 + 443 + 2018 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + 300 + 2000 + - - - QLayout::SetMinimumSize + + + 50000 + 50000 + + + + + + 0 + 0 + 425 + 1147 + - - - - - - Valor en metros del tamano de una celda en el mapa + + + QLayout::SetMinimumSize + + + + + + + Valor en metros del tamano de una celda en el mapa (establecer antes de cargar MDE). - - - Valor en metros del tamano de una celda en el mapa. - - - Qt::LeftToRight - - - Valor Dxp [m] - - - - - - - - 100 - 0 - - - - - 150 - 16777215 - - - - 10000.000000000000000 - - - 12.699999999999999 - - - - - - - - - <html><head/><body><p>Dirección al MDE (modelo digital de elevación), este se usa como base para un proyecto.</p></body></html> - - - <html><head/><body><p>Dirección al MDE (modelo digital de elevación), este se usa como base para un proyecto.</p></body></html> - - - Mapa MDE: - - - - - - - - - - 100 - 20 - - - - - 290 - 16777215 - - - - true - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - 100 - 16777215 - - - - <html><head/><body><p>Establece el MDE y sus propiedades como el mapa base para WMF.</p></body></html> - - - Cargar - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 100 - 16777215 - - - - <html><head/><body><p>Carga el MDE en el layout de mapas de Qgis.</p></body></html> - - - Visualizar - - - - - - - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - Mapa DIR: - - - - - - - - - - 290 - 16777215 - - - - true - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - 100 - 16777215 - - - - <html><head/><body><p>Establece el DIR y sus propiedades como el mapa base para WMF.</p></body></html> - - - Cargar - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 100 - 16777215 - - - - <html><head/><body><p>Carga el DIR en el layout de mapas de Qgis.</p></body></html> - - - Visualizar - - - - - - - - - - - - - - Código EPSG de los mapas DEM y DIR cargados para el proyecto. - - - Valor en metros del tamano de una celda en el mapa. - - - Qt::LeftToRight - - - Proyección EPSG - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 290 - 16777215 - - - - true - - - - - - - - - - - Código EPSG de los mapas DEM y DIR cargados para el proyecto. - - - Valor en metros del tamano de una celda en el mapa. - - - Qt::LeftToRight - - - Valor datos nulos - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 290 - 16777215 - - - - true - - - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - QSizePolicy::Minimum - - - - 20 - 20 - - - - - - - - - 14 - 75 - true - - - - Variables de la cuenca. - - - - - - - Qt::Horizontal - - - - - - - - 0 - 100 - - - - Convertir raster a cuenca. - - - - - 10 - 20 - 401 - 71 - + + + Valor en metros del tamano de una celda en el mapa. + + + Qt::LeftToRight + + + Valor Dxp [m] + + + + + + + + 100 + 0 + + + + + 150 + 16777215 + + + + 10000.000000000000000 + + + 12.699999999999999 + + + + + + + + + <html><head/><body><p>Dirección al MDE (modelo digital de elevación), este se usa como base para un proyecto.</p></body></html> + + + <html><head/><body><p>Dirección al MDE (modelo digital de elevación), este se usa como base para un proyecto.</p></body></html> + + + Mapa MDE: - - - - - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - Ruta mapa raster - - - - - - - - 290 - 16777215 - - - - true - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - Nombre: - - - - - - - - 290 - 16777215 - - - - false - - - - - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - Categoría: - - - - - - - - - - Ejecutar la función de trazado de corriente. - - - Ejecutar la función de trazado de corriente. - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - - - - - - - - - - - - Qt::Horizontal - - - - - - - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - Variables WMF - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Qt::DefaultContextMenu - - - Convertir variable a red hídrica (promedia celdas del tramo). - - - Convertir variable a red hídrica (promedia celdas del tramo). - - - - - - - :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico - - - - 16 - 16 - - - - - - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) - - - Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - - - - - - - - 50 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png - - - - - - - - - - 0 - 200 - - - - true - - - - - - - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - Variables NC - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - - 50 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png:/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png - - - - - - - - 50 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png:/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png - - - - - - - - - - 0 - 200 - - - - true - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Qt::DefaultContextMenu - - - Convertir variable a red hídrica (promedia celdas del tramo). - - - Convertir variable a red hídrica (promedia celdas del tramo). - - - - - - - :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico - - - - 16 - 16 - - - - - - - - - 50 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - - - - - - - - 50 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png - - - - - - - - - - - - - - - - Trazadores - - - - - 0 - 0 - 461 - 730 - - - - - 430 - 400 - - - - - 50000 - 50000 - - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAsNeeded - - - true - - - - - 0 - 0 - 443 - 918 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - - - - 250 - 900 - - - - - 50000 - 50000 - - - - - - 0 - 280 - 421 - 436 - - - - - QLayout::SetMinimumSize - - - - - - - Ubicación - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png - - - - - - - - - - - Coordenada en X del punto de inicio. - - - Coordenada en X del punto de inicio. - - - Latitud: - - - - - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 - - - - - - - - - - - Coordenada en Y del punto de inicio. - - - Coordenada en Y del punto de inicio. - - - Longitud - - - - - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 - - - - - - - - - - - Umbral mínimo para determinar red de drenaje en la cuenca - - - Umbral mínimo para determinar red de drenaje en la cuenca - - - Umbral - - - - - - - 0 - - - 10.000000000000000 - - - 100000.000000000000000 - - - 100.000000000000000 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca - - - Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca - - - Ultima corriente - - - - - - - Si usar o no usar ultima corriente - - - Si usar o no usar ultima corriente - - - - - - true - - - - - - - - - Qt::Horizontal - - - - - - - Ruta divisoria de aguas (*.shp): - - - - - - - - - false - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - - Qt::Horizontal - - - - - - - Ruta red hidrica (*.shp): - - - - - - - - - Obtiene automaticamente los nodos topograficos. - - - Obtiene automaticamente los nodos topograficos. - - - Topo Nodes - - - - - - - Obtiene parametros geomorfologicos de la cuenca. - - - GetGeo - - - - - - - Obtiene el ancho del canal en cada tramo. - - - Ancho canal - - - - - - - - - - - false - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - - Qt::Horizontal - - - - - - - Path Salida (*.nc): - - - - - - - - - false - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - - - - Nombre interno que identifica a la cuenca trazada (Cuenca) - - - Nombre: - - - - - - - Cuenca - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - - - - - - - - - - 0 - 0 - 421 - 231 - - - - Corriente - - - - - 0 - 20 - 421 - 211 - - - - - - - - - Punto de inicio de trazado de la corriente - - - Punto de inicio de trazado de la corriente - - - Ubicación - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Obtener coordenadas dando click sobre el mapa - - - Obtener coordenadas dando click sobre el mapa - - - - - - - :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png - - - - - - - - - - - Coordenada en Y del punto de inicio. - - - Coordenada en Y del punto de inicio. - - - Latitud: - - - - - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 - - - - - - - - - - - Coordenada en X del punto de inicio. - - - Coordenada en X del punto de inicio. - - - Longitud - - - - - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 - - - - - - - - - Qt::Horizontal - - - - - - - Ruta corriente trazada (*.shp): - - - - - - - - - false - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - Seleccionar la ruta donde se va a guardar la corriente. - - - Seleccionar la ruta donde se va a guardar la corriente. - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - Ejecutar la función de trazado de corriente. - - - Ejecutar la función de trazado de corriente. - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - - - - - - - - - - 0 - 0 - 421 - 1900 - - - - - 0 - 1900 - - - - - - - - 0 - 260 - 421 - 650 - - - - - 0 - 650 - - - - Cuenca - - - - - - 0 - 240 - 421 - 16 - - - - Qt::Horizontal - - - - - - - - - - - - :/plugins/HydroSEDPlugin/icons/geomorfologia.ico:/plugins/HydroSEDPlugin/icons/geomorfologia.ico - - - Geomorfología - - - - - 0 - 0 - 461 - 730 - - - - - 430 - 400 - - - - - 50000 - 50000 - - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAsNeeded - - - true - - - - - 0 - 0 - 443 - 1918 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - - - - 300 - 1900 - - - - - 50000 - 50000 - - - - - - 0 - 320 - 421 - 271 - - - - Calcúla características geomorfológicas ráster de la cuenca. - - - Calcúla características geomorfológicas ráster de la cuenca. - - - Geomorfología Raster - - - - - 10 - 30 - 401 - 181 - - - - - - - QFormLayout::AllNonFixedFieldsGrow - - - - - Calcular mapas raster de área acumulada y pendiente (Area, Pendiente). - - - Calcular mapas raster de área acumulada y pendiente (Area, Pendiente). - - - Área, Pendiente. - - - - - - - calcula todos los parámetros geomorfológicos distribuidos. - - - calcula todos los parámetros geomorfológicos distribuidos. - - - Seleccionar todos - - - - - - - Calcular mapas raster con el orden de strahler. (Order_hills, Order_channels) - - - Calcular mapas raster con el orden de strahler. (Order_hills, Order_channels) - - - Orden de canales y laderas - - - - - - - Calcula mapas raster de la elevación relativa al canal (Rennó, 2008) (HAND, HDND, HAND_class) - - - Calcula mapas raster de la elevación relativa al canal (Rennó, 2008) (HAND, HDND, HAND_class) - - - HAND - - - - - - - Cálcula mapa raster del IT (índice topográfico) (Beven, 1974) (IT) - - - Cálcula mapa raster del IT (índice topográfico) (Beven, 1974) (IT) - - - Índice Topográfico. - - - - - - - Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) - - - Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) - - - Distancia a la salida. - - - - - - - Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) - - - Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) - - - Canales - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Calcular parámetros seleccionados (enviados a Variables WMF) - - - Calcular parámetros seleccionados (enviados a Variables WMF) - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - - - - - - - - - GrupoGeoParametros - verticalLayoutWidget_4 - - - - - 0 - 580 - 421 - 181 - - - - Acumular Variable: - - - false - - - - - 10 - 30 - 401 - 141 - - - - - - - - 0 - 10 - - - - - 75 - true - - - - Datos de entrada: - - - - - - - - - Variable de WMf utilizada como máscara para acumular variables. - - - Variable de WMf utilizada como máscara para acumular variables. - - - Mascara - - - - - - - - 250 - 0 - - - - - - - - - - - - Variables a acumular cargada en WMF - - - Variables a acumular cargada en WMF - - - Variable - - - - - - - - 250 - 0 - - - - - - - - - - - - Nombre de la variable acumulada. - - - Nombre de la variable acumulada. - - - Nombre variable acumulada: - - - - - - - - 290 - 16777215 - - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Acumular variable (cargada a Variables WMF). - - - Acumular variable (cargada a Variables WMF). - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - - - - - - - - - - - 0 - 40 - 421 - 271 - - - - Calcúla los parámetros básicos de la cuenca. - - - Calcúla los parámetros básicos de la cuenca. - - - Parámetros geomorfológicos - - - - - 0 - 330 - 411 - 21 - - - - Qt::Horizontal - - - - - - 10 - 30 - 401 - 211 - - - - - - - true - - - true - - - true - - - 50 - - - true - - + - - - Qt::Horizontal - - + + - 40 + 100 20 - - - - - - false - - - Exportar parámetros geomorfológicos a excel. - - - Exportar parámetros geomorfológicos a excel. - - - - - - - :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png - - - - - - - Calcula parámetros geomorfológicos básicos de la cuenca. - - - Calcula parámetros geomorfológicos básicos de la cuenca. - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - - - - - - - - - - 200 - 270 - 411 - 21 - - - - Qt::Horizontal - - - - - - 0 - 260 - 411 - 21 - - - - Qt::Horizontal - - - - - - - 10 - 550 - 411 - 21 - - - - Qt::Horizontal - - - - - - 10 - 0 - 399 - 41 - - - - - - - Umbral a partir del cual se consideran corrientes (defecto el de la cuenca) - - - Umbral a partir del cual se consideran corrientes (defecto el de la cuenca) - - - Umbral para estimar canales: - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 0 - - - 0.000000000000000 - - - 100000.000000000000000 - - - 0.000000000000000 - - - - - - - - - - - - - - Hidrología - - - - - 0 - 0 - 461 - 730 - - - - - 430 - 400 - - - - - 50000 - 50000 - - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAsNeeded - - - true - - - - - 0 - 0 - 443 - 1918 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - - - - 300 - 1900 - - - - - 50000 - 50000 - - - - - - 0 - 350 - 421 - 241 - - - - Balance hidrológico - - - - - 0 - 30 - 411 - 203 - - - - - - - Qt::Horizontal - - - - - - - - 0 - 10 - - - - - 75 - true - - - - Datos de entrada: - - - - - - - - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - - - Lluvia* [mm/año] - - - - - - - Qt::Horizontal - - + - 10 - 20 + 290 + 16777215 - - - - - false - - - - - - - Establecer ruta donde se aloja el mapa de precipitación. - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + true - - - false + + + + 30 + 0 + - 40 + 30 16777215 - - Visualizar shp con el caudal calculado por tramos. - - - Visualizar shp con el caudal calculado por tramos. - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - + - - - Estimación de la evaporación anual (mm/año), seleccionar metodología o cargar mapa. + + + + 100 + 16777215 + - - Estimación de la evaporación anual (mm/año), seleccionar metodología o cargar mapa. + + <html><head/><body><p>Establece el MDE y sus propiedades como el mapa base para WMF.</p></body></html> - ETR [mm/año] + Cargar + + + + - + Qt::Horizontal - 10 + 40 20 - - - Metodología de cálculo Turc. - - - Metodología de cálculo Turc. - - - Turc - - - true - - - - - - - Metodología de cálculo Cenicafe. - - - Metodología de cálculo Cenicafe. - - - Cenicafe - - - false + + + + 100 + 16777215 + - - - - - Metodología de cálculo Choudry. - - - Metodología de cálculo Choudry. + <html><head/><body><p>Carga el MDE en el layout de mapas de Qgis.</p></body></html> - Choudry + Visualizar - - - - - - Qt::Horizontal + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - - - - - 75 - true - + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Datos de salida: - - - Qt::AutoText + Mapa DIR: - + - - - El valor del caudal calculado en cada tramo hidrológico. - - - El valor del caudal calculado en cada tramo hidrológico. + + + + 290 + 16777215 + - - Qmed*[m3/s] + + true - - - Qt::Horizontal - - + + - 10 - 20 + 30 + 0 - - - - - - Ruta de guardado - - - false + + + 30 + 16777215 + - - - - @@ -2901,515 +542,673 @@ - - - false - + - 40 + 100 16777215 - Visualizar shp con el caudal calculado por tramos. - - - Visualizar shp con el caudal calculado por tramos. + <html><head/><body><p>Establece el DIR y sus propiedades como el mapa base para WMF.</p></body></html> - - - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + Cargar - - - - - - 75 - true - - - - El valor del caudal calculado solo a la salida de la cuenca. - - - El valor del caudal calculado solo a la salida de la cuenca. - - - Q salida [m3/s]: - - - + - + Qt::Horizontal - 10 + 40 20 - - - true + + + + 100 + 16777215 + - - - - - Ejecuta el balance de largo plazo con los parametros dados. - - - Ejecuta el balance de largo plazo con los parametros dados. + <html><head/><body><p>Carga el DIR en el layout de mapas de Qgis.</p></body></html> - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + Visualizar - - - - - - - 0 - 0 - 411 - 331 - - - - Generador campos de lluvia - - - - - 0 - 20 - 411 - 307 - - - - - - - Qt::Horizontal - - - - - - - 0 - 10 - - - - - 75 - true - - - - Datos de entrada: - - + - + - + - Vectorial con los puntos de los pluviometros a interpolar. + Código EPSG de los mapas DEM y DIR cargados para el proyecto. - Vectorial con los puntos de los pluviometros a interpolar. + Valor en metros del tamano de una celda en el mapa. + + + Qt::LeftToRight - Pluviómetros + Proyección EPSG - + Qt::Horizontal - 10 + 40 20 - - - false - - - - - - - + + + + 290 + 16777215 + - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + true - - - - + - + - Archivo de excel con las series de tiempo de los puntos a interpolar. + Código EPSG de los mapas DEM y DIR cargados para el proyecto. - Archivo de excel con las series de tiempo de los puntos a interpolar. + Valor en metros del tamano de una celda en el mapa. + + + Qt::LeftToRight - Archivo excel + Valor datos nulos - + Qt::Horizontal - 10 + 40 20 - - - false - - - - - - - true - + - 100 + 290 16777215 - - Establecer archivo de excel a utilizar. - - - Establecer archivo de excel a utilizar. - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + true - + + + Qt::Horizontal + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 20 + 20 + + + + + + + + + 14 + 75 + true + + + + Variables de la cuenca. + + + + + + + Qt::Horizontal + + + + + + + + 0 + 100 + + + + Convertir raster a cuenca. + + + + + 10 + 20 + 401 + 71 + + + + + + + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + Ruta mapa raster + + + + + + + + 290 + 16777215 + + + + true + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + Nombre: + + + + + + + + 290 + 16777215 + + + + false + + + + + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + Categoría: + + + + + + + + + + Ejecutar la función de trazado de corriente. + + + Ejecutar la función de trazado de corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + + + + Qt::Horizontal + + + + + - + - Exponente para ponderar la distancia en la metodología IDW. + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Exponente para ponderar la distancia en la metodología IDW. + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Exponente distancia IDW + Variables WMF - + Qt::Horizontal - 10 + 40 20 - + + + false + 50 0 - - 2 + + + 30 + 16777215 + - - 1.000000000000000 + + Qt::DefaultContextMenu - - 20.000000000000000 + + Convertir variable a red hídrica (promedia celdas del tramo). - - 1.000000000000000 + + Convertir variable a red hídrica (promedia celdas del tramo). - - - - - - - - - Fecha inicio interpolación + - - - - - - - 2015 - 1 - 1 - + + + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico + + + + 16 + 16 + - - - - - + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + + + Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + - Fecha fin interpolación + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - - - - 2015 - 1 - 1 - + + + + 50 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png - - - Qt::Horizontal - - - - - - - - 75 - true - - - - Datos de salida: + + + + 0 + 200 + - - Qt::AutoText + + true - + - + - Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Binario de lluvia + Variables NC - + Qt::Horizontal - 10 + 40 20 - - - Ruta de guardado - - + + false - - - - - - Establecer ruta de guardado del binario de lluvia. + + + 50 + 0 + + + + + 30 + 16777215 + - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + :/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png:/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png - + 50 0 - - Entrada del binario de lluvia a visualizar. - - - 0 - - - 0.000000000000000 - - - 10000000.000000000000000 - - - 1.000000000000000 - - - - - - - false - - 40 + 30 16777215 - - Visualiza una entrada del binario de lluvia interpolado. - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + :/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png:/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png - - - Qt::Horizontal + + + + 0 + 200 + + + + true - + - + Qt::Horizontal - 10 + 40 20 - + + + false + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Qt::DefaultContextMenu + - Ejecuta la interpolación para la cuenca con los parámetros dados. + Convertir variable a red hídrica (promedia celdas del tramo). + + + Convertir variable a red hídrica (promedia celdas del tramo). + + + + + + + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico + + + + 16 + 16 + + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + - Ejecuta la interpolación para la cuenca con los parámetros dados. + Actualiza el archivo .nc del proyecto cuenca. + + + + + + + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3417,1235 +1216,3437 @@ - - - - - -3 - 330 - 411 - 20 - - - - Qt::Horizontal - - - - - - 0 - 620 - 421 - 271 - - - - Máximos regionalización - - + + + + + + + + + Trazadores + + + + + 0 + 0 + 461 + 730 + + + + + 430 + 400 + + + + + 50000 + 50000 + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + true + + + + + 0 + -190 + 443 + 918 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + 250 + 900 + + + + + 50000 + 50000 + + + + + + 0 + 0 + 421 + 231 + + + + Corriente + + + + + 0 + 20 + 421 + 211 + + + + + + + + + Punto de inicio de trazado de la corriente + + + Punto de inicio de trazado de la corriente + + + Ubicación + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Obtener coordenadas dando click sobre el mapa + + + Obtener coordenadas dando click sobre el mapa + + + + + + + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png + + + + + + + + + + + Coordenada en Y del punto de inicio. + + + Coordenada en Y del punto de inicio. + + + Latitud: + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + + + + + Coordenada en X del punto de inicio. + + + Coordenada en X del punto de inicio. + + + Longitud + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + + + Qt::Horizontal + + + + + + + Ruta corriente trazada (*.shp): + + + + + + + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Seleccionar la ruta donde se va a guardar la corriente. + + + Seleccionar la ruta donde se va a guardar la corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + Ejecutar la función de trazado de corriente. + + + Ejecutar la función de trazado de corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + + + 0 + 240 + 421 + 16 + + + + Qt::Horizontal + + + + + + 0 + 250 + 421 + 461 + + + + Cuencas + + + + + 0 + 20 + 421 + 436 + + + + + QLayout::SetMinimumSize + + + + + + + Ubicación + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png + + + + + + + + + + + Coordenada en X del punto de inicio. + + + Coordenada en X del punto de inicio. + + + Latitud: + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + + + + + Coordenada en Y del punto de inicio. + + + Coordenada en Y del punto de inicio. + + + Longitud + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + + + + + Umbral mínimo para determinar red de drenaje en la cuenca + + + Umbral mínimo para determinar red de drenaje en la cuenca + + + Umbral + + + + + + + 0 + + + 10.000000000000000 + + + 100000.000000000000000 + + + 100.000000000000000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca + + + Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca + + + Ultima corriente + + + + + + + Si usar o no usar ultima corriente + + + Si usar o no usar ultima corriente + + + + + + true + + + + + + + + + Qt::Horizontal + + + + + + + Ruta divisoria de aguas (*.shp): + + + + + + + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + Qt::Horizontal + + + + + + + Ruta red hidrica (*.shp): + + + + + + + + + Obtiene automaticamente los nodos topograficos. + + + Obtiene automaticamente los nodos topograficos. + + + Topo Nodes + + + + + + + Obtiene parametros geomorfologicos de la cuenca. + + + GetGeo + + + + + + + Obtiene el ancho del canal en cada tramo. + + + Ancho canal + + + + + + + + + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + Qt::Horizontal + + + + + + + Path Salida (*.nc): + + + + + + + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + Nombre interno que identifica a la cuenca trazada (Cuenca) + + + Nombre: + + + + + + + Cuenca + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/geomorfologia.ico:/plugins/HydroSEDPlugin/icons/geomorfologia.ico + + + Geomorfología + + + + + 0 + 0 + 461 + 730 + + + + + 430 + 400 + + + + + 50000 + 50000 + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + true + + + + + 0 + 0 + 443 + 1918 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + 300 + 1900 + + + + + 50000 + 50000 + + + + + + 0 + 320 + 421 + 271 + + + + Calcúla características geomorfológicas ráster de la cuenca. + + + Calcúla características geomorfológicas ráster de la cuenca. + + + Geomorfología Raster + + + + + 10 + 30 + 401 + 181 + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Calcular mapas raster de área acumulada y pendiente (Area, Pendiente). + + + Calcular mapas raster de área acumulada y pendiente (Area, Pendiente). + + + Área, Pendiente. + + + + + + + calcula todos los parámetros geomorfológicos distribuidos. + + + calcula todos los parámetros geomorfológicos distribuidos. + + + Seleccionar todos + + + + + + + Calcular mapas raster con el orden de strahler. (Order_hills, Order_channels) + + + Calcular mapas raster con el orden de strahler. (Order_hills, Order_channels) + + + Orden de canales y laderas + + + + + + + Calcula mapas raster de la elevación relativa al canal (Rennó, 2008) (HAND, HDND, HAND_class) + + + Calcula mapas raster de la elevación relativa al canal (Rennó, 2008) (HAND, HDND, HAND_class) + + + HAND + + + + + + + Cálcula mapa raster del IT (índice topográfico) (Beven, 1974) (IT) + + + Cálcula mapa raster del IT (índice topográfico) (Beven, 1974) (IT) + + + Índice Topográfico. + + + + + + + Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + + + Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + + + Distancia a la salida. + + + + + + + Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + + + Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + + + Canales + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Calcular parámetros seleccionados (enviados a Variables WMF) + + + Calcular parámetros seleccionados (enviados a Variables WMF) + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + + + + + 0 + 580 + 421 + 181 + + + + Acumular Variable: + + + false + + + + + 10 + 30 + 401 + 141 + + + + + + + + 0 + 10 + + + + + 75 + true + + + + Datos de entrada: + + + + + + + + + Variable de WMf utilizada como máscara para acumular variables. + + + Variable de WMf utilizada como máscara para acumular variables. + + + Mascara + + + + + + + + 250 + 0 + + + + + + + + + + + + Variables a acumular cargada en WMF + + + Variables a acumular cargada en WMF + + + Variable + + + + + + + + 250 + 0 + + + + + + + + + + + + Nombre de la variable acumulada. + + + Nombre de la variable acumulada. + + + Nombre variable acumulada: + + + + + + + + 290 + 16777215 + + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Acumular variable (cargada a Variables WMF). + + + Acumular variable (cargada a Variables WMF). + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + 0 - 30 + 40 + 421 + 271 + + + + Calcúla los parámetros básicos de la cuenca. + + + Calcúla los parámetros básicos de la cuenca. + + + Parámetros geomorfológicos + + + + + 0 + 330 + 411 + 21 + + + + Qt::Horizontal + + + + + + 10 + 30 + 401 + 211 + + + + + + + true + + + true + + + true + + + 50 + + + true + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Exportar parámetros geomorfológicos a excel. + + + Exportar parámetros geomorfológicos a excel. + + + + + + + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png + + + + + + + Calcula parámetros geomorfológicos básicos de la cuenca. + + + Calcula parámetros geomorfológicos básicos de la cuenca. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + + 200 + 270 + 411 + 21 + + + + Qt::Horizontal + + + + + + 0 + 260 + 411 + 21 + + + + Qt::Horizontal + + + + + + + 10 + 550 411 - 236 + 21 - - - - - Qt::Horizontal - - - - - - - - 0 - 10 - - - - - 75 - true - - - - Datos de entrada: - - - - - - - - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - - - Caudal medio - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - false - - - - - - - - - - - - - - - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - - - Cmed - - - - - - - - - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - - - Cdes - - - - - - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - - - Emed - - - - - - - - - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - - - Edes - - - - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] - - - - - - - - - - - - - - - - - Qt::Horizontal - - - - - - - - 75 - true - - - - Datos de salida: - - - Qt::AutoText - - - - - - - - - El valor del caudal calculado en cada tramo hidrológico. - - - El valor del caudal calculado en cada tramo hidrológico. - - - Qmax*[m3/s] - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - Ruta de guardado - - - false - - - - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - false - - - - 40 - 16777215 - - - - Visualizar shp con el caudal calculado por tramos. - - - Visualizar shp con el caudal calculado por tramos. - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - - - - - - - - - - - - 75 - true - - - - El valor del caudal calculado solo a la salida de la cuenca. - - - El valor del caudal calculado solo a la salida de la cuenca. - - - Qmax salida [m3/s]: - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - true - - - - - - - Ejecuta el balance de largo plazo con los parametros dados. - - - Ejecuta el balance de largo plazo con los parametros dados. - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - - - + + Qt::Horizontal + + + + + + 10 + 0 + 399 + 41 + + + + + + + Umbral a partir del cual se consideran corrientes (defecto el de la cuenca) + + + Umbral a partir del cual se consideran corrientes (defecto el de la cuenca) + + + Umbral para estimar canales: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 0 + + + 0.000000000000000 + + + 100000.000000000000000 + + + 0.000000000000000 + + - - - - 0 - 590 - 411 - 20 - - - - Qt::Horizontal - - - - - + + + + + + + + Hidrología + + + + + 0 + 0 + 461 + 730 + + + + + 430 + 400 + + + + + 50000 + 50000 + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + true + + + + + 0 + 0 + 443 + 1918 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + 300 + 1900 + + + + + 50000 + 50000 + + + + + + 0 + 350 + 421 + 241 + + + + Balance hidrológico + + + + + 0 + 30 + 411 + 203 + + + + + + + Qt::Horizontal + + + + + + + + 0 + 10 + + + + + 75 + true + + + + Datos de entrada: + + + + + + + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Lluvia* [mm/año] + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + false + + + + + + + Establecer ruta donde se aloja el mapa de precipitación. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + false + + + + 40 + 16777215 + + + + Visualizar shp con el caudal calculado por tramos. + + + Visualizar shp con el caudal calculado por tramos. + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + + + + + Estimación de la evaporación anual (mm/año), seleccionar metodología o cargar mapa. + + + Estimación de la evaporación anual (mm/año), seleccionar metodología o cargar mapa. + + + ETR [mm/año] + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + Metodología de cálculo Turc. + + + Metodología de cálculo Turc. + + + Turc + + + true + + + + + + + Metodología de cálculo Cenicafe. + + + Metodología de cálculo Cenicafe. + + + Cenicafe + + + false + + + + + + + Metodología de cálculo Choudry. + + + Metodología de cálculo Choudry. + + + Choudry + + + + + + + + + + + + Qt::Horizontal + + + + + + + + 75 + true + + + + Datos de salida: + + + Qt::AutoText + + + + + + + + + El valor del caudal calculado en cada tramo hidrológico. + + + El valor del caudal calculado en cada tramo hidrológico. + + + Qmed*[m3/s] + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + Ruta de guardado + + + false + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + false + + + + 40 + 16777215 + + + + Visualizar shp con el caudal calculado por tramos. + + + Visualizar shp con el caudal calculado por tramos. + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + + + + + + 75 + true + + + + El valor del caudal calculado solo a la salida de la cuenca. + + + El valor del caudal calculado solo a la salida de la cuenca. + + + Q salida [m3/s]: + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + true + + + + + + + Ejecuta el balance de largo plazo con los parametros dados. + + + Ejecuta el balance de largo plazo con los parametros dados. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + + + 0 + 0 + 411 + 331 + + + + Generador campos de lluvia + + + + + 0 + 20 + 411 + 307 + + + + + + + Qt::Horizontal + + + + + + + + 0 + 10 + + + + + 75 + true + + + + Datos de entrada: + + + + + + + + + Vectorial con los puntos de los pluviometros a interpolar. + + + Vectorial con los puntos de los pluviometros a interpolar. + + + Pluviómetros + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + false + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + + + + Archivo de excel con las series de tiempo de los puntos a interpolar. + + + Archivo de excel con las series de tiempo de los puntos a interpolar. + + + Archivo excel + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + false + + + + + + + true + + + + 100 + 16777215 + + + + Establecer archivo de excel a utilizar. + + + Establecer archivo de excel a utilizar. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + Exponente para ponderar la distancia en la metodología IDW. + + + Exponente para ponderar la distancia en la metodología IDW. + + + Exponente distancia IDW + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + + 50 + 0 + + + + 2 + + + 1.000000000000000 + + + 20.000000000000000 + + + 1.000000000000000 + + + + + + + + + + + Fecha inicio interpolación + + + + + + + + 2015 + 1 + 1 + + + + + + + + + + + + Fecha fin interpolación + + + + + + + + 2015 + 1 + 1 + + + + + + + + + + Qt::Horizontal + + + + + + + + 75 + true + + + + Datos de salida: + + + Qt::AutoText + + + + + + + + + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + + + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + + + Binario de lluvia + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + Ruta de guardado + + + false + + + + + + + Establecer ruta de guardado del binario de lluvia. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + 50 + 0 + + + + Entrada del binario de lluvia a visualizar. + + + 0 + + + 0.000000000000000 + + + 10000000.000000000000000 + + + 1.000000000000000 + + + + + + + false + + + + 40 + 16777215 + + + + Visualiza una entrada del binario de lluvia interpolado. + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + + + Qt::Horizontal + + + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + + + -3 + 330 + 411 + 20 + + + + Qt::Horizontal + + + + + + 0 + 620 + 421 + 271 + + + + Máximos regionalización + + + + + 0 + 30 + 411 + 236 + + + + + + + Qt::Horizontal + + + + + + + + 0 + 10 + + + + + 75 + true + + + + Datos de entrada: + + + + + + + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Caudal medio + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + false + + + + + + + + + + + + + + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Cmed + + + + + + + + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Cdes + + + + + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Emed + + + + + + + + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Edes + + + + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + + + + + 75 + true + + + + Datos de salida: + + + Qt::AutoText + + + + + + + + + El valor del caudal calculado en cada tramo hidrológico. + + + El valor del caudal calculado en cada tramo hidrológico. + + + Qmax*[m3/s] + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + Ruta de guardado + + + false + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + false + + + + 40 + 16777215 + + + + Visualizar shp con el caudal calculado por tramos. + + + Visualizar shp con el caudal calculado por tramos. + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + + + + + + 75 + true + + + + El valor del caudal calculado solo a la salida de la cuenca. + + + El valor del caudal calculado solo a la salida de la cuenca. + + + Qmax salida [m3/s]: + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + true + + + + + + + Ejecuta el balance de largo plazo con los parametros dados. + + + Ejecuta el balance de largo plazo con los parametros dados. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + + + 0 + 590 + 411 + 20 + + + + Qt::Horizontal + + + + + + - - - - Simulación - - - - - 10 - 10 - 451 - 721 - - - - - 430 - 400 - - - - - 16777215 - 750 - - - - Qt::ScrollBarAlwaysOn - - - true - - + + + Simulación + + - 0 - 0 - 433 - 1918 + 10 + 10 + 451 + 721 - 0 - 0 + 430 + 400 16777215 - 16777215 + 750 - - - - - - 0 - 1900 - - - - - - 0 - 0 - 411 - 101 - - - - Serie de Caudal Observado + + Qt::ScrollBarAlwaysOn + + + true + + + + + 0 + 0 + 433 + 1918 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + 0 + 1900 + - + - - 0 - 20 - 401 - 81 - - - - - - - - - Ruta a la serie de caudales obsevada - - - false - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - Seleccionar la ruta donde se va a guardar la corriente. - - - Seleccionar la ruta donde se va a guardar la corriente. - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - - - - Selección estación - - - - - - - - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) - - - Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - - - - - - + + 0 + 0 + 411 + 101 + + + + Serie de Caudal Observado + + + + + 0 + 20 + 401 + 81 + + + + + + + + + Ruta a la serie de caudales obsevada + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Seleccionar la ruta donde se va a guardar la corriente. + + + Seleccionar la ruta donde se va a guardar la corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + Selección estación + + + + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + + + Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + + + + + -3 + 530 + 411 + 20 + + + + Qt::Horizontal + + - + - -3 - 530 + 0 + 330 411 - 20 + 641 - - Qt::Horizontal + + Variables Físicas + + + + 0 + 70 + 401 + 531 + + + + + + + 4 + + + + + + + + + + + + + + Variable + + + + + + + + + + Coef + + + + + + + Krusle + + + + + + + + + + + + + Exponente regional en caso de usar aproximación no lineal v = C A^e + + + Exponente aproximación no lineal al flujo superficial + + + + + + + + + + + + + + + + Exponente regional en caso de usar aproximación no lineal v = C A^e + + + Exponente aproximación no lineal al flujo sub-superficial + + + + + + + + + + Vh2 [m/s] + + + + + + + + + + Expo + + + + + + + + + + Vh3 [m/s] + + + + + + + Vh1 [m/s] + + + + + + + + + + + + + + + + Vv1 [mm/s] + + + + + + + + + + Vv2 [mm/s] + + + + + + + + + + Vh4 [m/s] + + + + + + + Exponente regional en caso de usar aproximación no lineal v = C A^e + + + Exponente aproximación no lineal al flujo subterráneo + + + + + + + + + + Exponente regional en caso de usar aproximación no lineal v = C A^e + + + Exponente aproximación no lineal al flujo en canales + + + + + + + + + + Vv3 [mm/s] + + + + + + + + + + + + + Hg [mm] + + + + + + + Hu [mm] + + + + + + + Nombre variable + + + + + + + Crusle + + + + + + + + + + + + + Prusle + + + + + + + + + + Limos + + + + + + + + + + + + + Arcillas + + + + + + + Arenas + + + + + + + + + + + + + + + + + + + + + + + 0 + 600 + 401 + 41 + + + + + + + + + Nombre calibración + + + + + + + false + + + + + + + + + + + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg + + + + + + + Establecer + + + + + + + + + + + 0 + 30 + 401 + 41 + + + + + + + + + Seleccionar calibración anterior + + + + + + + + + + - - - - - 0 - 330 - 411 - 641 - - - - Variables Físicas - - + 0 - 70 - 401 - 531 + 120 + 411 + 191 - - - - - 4 - - - - - - - - - - - - - - Variable - - - - - - - - - - Coef - - - - - - - Krusle - - - - - - - - - - - - - Exponente regional en caso de usar aproximación no lineal v = C A^e - - - Exponente aproximación no lineal al flujo superficial - - - - - - - - - - - - - - - - Exponente regional en caso de usar aproximación no lineal v = C A^e - - - Exponente aproximación no lineal al flujo sub-superficial - - - - - - - - - - Vh2 [m/s] - - - - - - - - - - Expo - - - - - - - - - - Vh3 [m/s] - - - - - - - Vh1 [m/s] - - - - - - - - - - - - - - - - Vv1 [mm/s] - - - - - - - - - - Vv2 [mm/s] - - - - - - - - - - Vh4 [m/s] - - - - - - - Exponente regional en caso de usar aproximación no lineal v = C A^e - - - Exponente aproximación no lineal al flujo subterráneo - - - - - - - - - - Exponente regional en caso de usar aproximación no lineal v = C A^e - - - Exponente aproximación no lineal al flujo en canales - - - - - - - - - - Vv3 [mm/s] - - - - - - - - - - - - - Hg [mm] - - - - - - - Hu [mm] - - - - - - - Nombre variable - - - - - - - Crusle - - - - - - - - - - - - - Prusle - - - - - - - - - - Limos - - - - - - - - - - - - - Arcillas - - - - - - - Arenas - - - - - - - - - - - - - - - - - - + + Serie de precipitación + + + + + 0 + 20 + 401 + 171 + + + + + + + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Seleccionar la ruta donde se va a guardar la corriente. + + + Seleccionar la ruta donde se va a guardar la corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + Fecha inicio simulación + + + + + + + + 2015 + 1 + 1 + + + + + + + + + + + + Fecha fin simulación + + + + + + + + 2015 + 12 + 31 + + + + + + + + + + + + Paso de tiempo (dt) + + + + + + + Paso del intervalo de tiempo en los campos cargados. + + + 0 + + + 0.000000000000000 + + + 100000.000000000000000 + + + 0.000000000000000 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Visualizar serie de precipitación entre las fechas seleccionadas. + + + Visualizar serie de precipitación. + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Visualizar acumulado de precipitación entre fecha inicial y final + + + Visualizar acumulado de precipitación entre fecha inicial y final + + + + + + + :/plugins/HydroSEDPlugin/icons/toRaster.ico:/plugins/HydroSEDPlugin/icons/toRaster.ico + + + + + + + + + + + 130 + 280 + 115 + 50 + + + + Nombre variable + + - + 0 - 600 - 401 - 41 + 310 + 411 + 20 - - - - - - - Nombre calibración - - - - - - - false - - - - - - - - - - - :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg - - - - - - - Establecer - - - - - - + + Qt::Horizontal + - + 0 - 30 - 401 - 41 + 970 + 411 + 20 - - - - - - - Seleccionar calibración anterior - - - - - - - - - + + Qt::Horizontal + - - - - - 0 - 120 - 411 - 191 - - - - Serie de precipitación - - + 0 - 20 + 990 401 - 171 - - - - - - - - - false - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - Seleccionar la ruta donde se va a guardar la corriente. - - - Seleccionar la ruta donde se va a guardar la corriente. - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - - - - Fecha inicio simulación - - - - - - - - 2015 - 1 - 1 - - - - - - - - - - - - Fecha fin simulación - - - - - - - - 2015 - 12 - 31 - - - - - - - - - - - - Paso de tiempo (dt) - - - - - - - Paso del intervalo de tiempo en los campos cargados. - - - 0 - - - 0.000000000000000 - - - 100000.000000000000000 - - - 0.000000000000000 - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Visualizar serie de precipitación entre las fechas seleccionadas. - - - Visualizar serie de precipitación. - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - - - - - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Visualizar acumulado de precipitación entre fecha inicial y final - - - Visualizar acumulado de precipitación entre fecha inicial y final - - - - - - - :/plugins/HydroSEDPlugin/icons/toRaster.ico:/plugins/HydroSEDPlugin/icons/toRaster.ico - - - - - - - - - - - 130 - 280 - 115 - 50 + 271 - - Nombre variable + + Ejecución + + + + 0 + 30 + 401 + 221 + + + + - - - - - 0 - 310 - 411 - 20 - - - - Qt::Horizontal - - - - - - 0 - 970 - 411 - 20 - - - - Qt::Horizontal - - - - - - 0 - 990 - 401 - 271 - - - - Ejecución - - + 0 - 30 - 401 - 221 + 100 + 411 + 20 - + + Qt::Horizontal + - - - - 0 - 100 - 411 - 20 - - - - Qt::Horizontal - - - - - + + + @@ -4673,7 +4674,6 @@ - From 4e8c5ddbe4c54d1f4fdd11092f96ae29fb169c28 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 18 Jul 2018 09:30:17 -0500 Subject: [PATCH 066/142] correcciones en el actualizador de NC ya deja guardar variables que no se tenian en cuenta --- qgisplugin/HydroSEDPluginUtils.py | 48 ++++++++++++++++++------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 778a2d4..e9a6e8d 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -174,6 +174,11 @@ def Basin_Update(self, PathNC): #Selecciona el grupo del nc en donde va a meter la variable Grupo = self.DicBasinNc[l]['categoria'] Group = g.groups[Grupo] + #mira si el grupo tiene la dimension ncells en caso de que no, la crea + try: + pos = Group.dimensions.keys().index('ncell') + except: + DimNcell = Group.createDimension('ncell',self.cuenca.ncells) #Obtiene el nombre, tipo y variable a actualizar nombre = l tipo = self.DicBasinNc[l]['tipo'] @@ -189,7 +194,7 @@ def Basin_Update(self, PathNC): #si ya existe la variable la sobre escribe except: print 'variable vieja' - VarName = Grupo['variables'][nombre] + VarName = Group.variables[nombre] #guarda la variable VarName[:] = Var self.Nc2Save = [] @@ -205,25 +210,28 @@ def Basin_LoadBasin(self, PathNC): self.cuenca = wmf.SimuBasin(rute = PathNC) #Cargar las variables de la cuenca a un diccionario. g = netCDF4.Dataset(PathNC) - for grupoKey in ['base','Geomorfo']: - for k in g.groups[grupoKey].variables.keys(): - #Evalua si tiene la misma cantidad de celdas y puede ser un mapa - shape = g.groups[grupoKey].variables[k].shape - MapaRaster = False - for s in shape: - if s == self.cuenca.ncells: - MapaRaster = True - #Actualiza el diccionario - self.DicBasinNc.update({k: - {'nombre':k, - 'tipo':g.groups[grupoKey].variables[k].dtype.name, - 'shape':g.groups[grupoKey].variables[k].shape, - 'raster':MapaRaster, - 'basica': True, - 'categoria': grupoKey, - 'var': g.groups[grupoKey].variables[k][:]}}) - self.NumDicBasinNcVariables = self.NumDicBasinNcVariables + 1 - self.NumDicBasinNcVariablesBasicas = self.NumDicBasinNcVariablesBasicas + 1 + for grupoKey in ['base','Geomorfo','Hidro']: + #Carga los grupos de variables en donde si se tengan variables + if len(g.groups[grupoKey].variables.keys())>0: + #itera + for k in g.groups[grupoKey].variables.keys(): + #Evalua si tiene la misma cantidad de celdas y puede ser un mapa + shape = g.groups[grupoKey].variables[k].shape + MapaRaster = False + for s in shape: + if s == self.cuenca.ncells: + MapaRaster = True + #Actualiza el diccionario + self.DicBasinNc.update({k: + {'nombre':k, + 'tipo':g.groups[grupoKey].variables[k].dtype.name, + 'shape':g.groups[grupoKey].variables[k].shape, + 'raster':MapaRaster, + 'basica': True, + 'categoria': grupoKey, + 'var': g.groups[grupoKey].variables[k][:]}}) + self.NumDicBasinNcVariables = self.NumDicBasinNcVariables + 1 + self.NumDicBasinNcVariablesBasicas = self.NumDicBasinNcVariablesBasicas + 1 g.close() #Cargar la cuenca y sus variables base a WMF self.cuenca = wmf.SimuBasin(rute = PathNC) From 37b32299f79442538767b3fe623c037a1f21af66 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 19 Jul 2018 14:25:06 -0500 Subject: [PATCH 067/142] ya funciona el conversor de variable a red de drenaje, sin embargo, funciona solo cuando la variable ha sido cargada desde el proyecto -nc y no cuando solo se ha pasado al mismo --- qgisplugin/HydroSEDPlugin.py | 1 + qgisplugin/HydroSEDPluginUtils.py | 13 ++++ qgisplugin/HydroSEDPlugin_dockwidget.py | 42 +++++++++++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 68 ++++++++------------ 4 files changed, 82 insertions(+), 42 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin.py b/qgisplugin/HydroSEDPlugin.py index 1d5a21a..7884d82 100644 --- a/qgisplugin/HydroSEDPlugin.py +++ b/qgisplugin/HydroSEDPlugin.py @@ -24,6 +24,7 @@ from PyQt4.QtGui import QAction, QIcon # Initialize Qt resources from file resources.py import resources +import resources_rc import os # Import the code for the DockWidget from HydroSEDPlugin_dockwidget import HydroSEDPluginDockWidget diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index e9a6e8d..a46e2ae 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -123,6 +123,19 @@ def trazador_cuenca(self,x,y, dxp,umbral,PathDiv, PathRed, PathNC,PathDEM, PathD # Guarda el nc de la cuenca if len(PathNC)>2: self.cuenca.Save_SimuBasin(PathNC) + + def BasinNc2Network(self,pathNetwork, names): + '''Guarda una red hidrica con las variables seleccionadas del diccionario NC''' + # genera el diccionario de las variables a guardar + DicVar = {} + for n in names: + DicVar.update({n.encode():self.DicBasinNc[n]['var'].data}) + print DicVar + #Guarda la red hidrica + self.cuenca.Save_Net2Map(pathNetwork, wmf.cu.dxp, + umbral = self.cuenca.umbral, + EPSG = int(self.cuenca.epsg), + Dict = DicVar) def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed): #Se fija si la lluvia es un path o un valor diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 94c2de2..7416e0a 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -27,7 +27,7 @@ from PyQt4.QtCore import pyqtSignal from qgis.gui import QgsMessageBar -from PyQt4.QtGui import QFileDialog, QTableWidgetItem +from PyQt4.QtGui import QFileDialog, QTableWidgetItem, QAbstractItemView import os.path @@ -62,6 +62,7 @@ def __init__(self, iface = None, parent=None): self.TablaFila_WMF = 0 self.TablaFila_NC = 0 + self.botonClicked = False #Inicia el comboBox de la seleccion de categoria para transformar raster a WMF for k in ['base','Geomorfo','SimHidro','Hidro']: @@ -152,6 +153,18 @@ def setupLineEditButtonOpenBasinFileDialog (lineEditHolder, fileDialogHolder): lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "Cargador de cuencas", "*","Cuenca en NetCDF4(*.nc);;", QtGui.QFileDialog.DontUseNativeDialog)) + def clickEventSelectShape2SaveNc(): + self.ruta2network = SelectNetworkshapeDialog (QFileDialog) + self.Tabla_Prop_NC.setSelectionMode(QAbstractItemView.SingleSelection) + self.ruta2network + + def SelectNetworkshapeDialog (fileDialogHolder): + '''Hace que cuando se busquen shapes solo se encuetren formatos vectoriales''' + lineEditHolder = fileDialogHolder.getOpenFileName (QtGui.QDialog (), "Guardar en capa vectorial...", "*", "Shapefiles (*.shp);;") + return lineEditHolder + #if ((os.path.exists (lineEditHolder.text ().strip ())) and (not (self.iface is None))): + # self.iface.addVectorLayer (lineEditHolder.text ().strip (), os.path.basename (lineEditHolder.text ()).strip (), "ogr") + #Funciones para Cargar variables def clickEventSelectorBasin(): '''click para seleccionar un proyecto de cuenca''' @@ -200,12 +213,37 @@ def clickEventBasinLoadNetwork(): self.iface.mapCanvas().refresh() self.iface.legendInterface().refreshLayerSymbology(layer) + def clickEventBasinVarNC2Network(): + '''Convierte un conjunto de variables a una red hidrica de la cuenca''' + if self.botonClicked is False: + #Hace que la seleccion sea multiple en la columna de NC + self.Tabla_Prop_NC.setSelectionMode(QAbstractItemView.MultiSelection) + self.ruta2Network = '' + #imprime las variables seleccionadas + self.Vars2Network = [] + self.botonClicked = True + self.ButtonVar2Net_NC.setText('Variables') + return + elif self.botonClicked is True: + for i in self.Tabla_Prop_NC.selectedItems()[::4]: + self.Vars2Network.append(i.text()) + #En el segundo click selecciona el archivo y ejecuta + self.ruta2Network = SelectNetworkshapeDialog(QFileDialog) + self.Tabla_Prop_NC.setSelectionMode(QAbstractItemView.SingleSelection) + self.botonClicked = False + #Guardado de las variables en formato red hidrica + self.HSutils.BasinNc2Network(self.ruta2Network,self.Vars2Network) + self.ButtonVar2Net_NC.setText('Var2Net') + #Botones para variables de entrada self.botonSelectorProyectBasin.clicked.connect(clickEventSelectorBasin) self.ButtonLoadBasinProyect.clicked.connect(clickEventBasin2WMF) #Botones para visualizar polilineas y poligonos self.Boton_verDivisoria.clicked.connect(clickEventBasinLoadDivisory) self.Boton_verRedHidrica.clicked.connect(clickEventBasinLoadNetwork) + #boton para convertir variables a red hidrica + self.ButtonVar2Net_NC.clicked.connect(clickEventBasinVarNC2Network) + def setupGeomorfologia(self): '''Conjunto de herramientas para manejar parametros geomorfologicos de la cuenca analizada''' @@ -662,7 +700,7 @@ def set_dxplano(): self.Tabla_Prop_WMF.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self.Button_Visualizar_Desde_WMF.clicked.connect(handleClickEventButton_Ver_Desde_WMF) #Botones movimiento variables NC a WMF y de WMF a NC - self.Button_NC2WMF.clicked.connect(handleClickEventButton_NC2WMF) + #self.Button_NC2WMF.clicked.connect(handleClickEventButton_NC2WMF) self.Button_WMF2NC.clicked.connect(handleClickEventButton_WMF2NC) #Boton para actualizar los archivos que se encuentran guardados en un netCDF self.Button_Update_NC.clicked.connect(clickEventBasinUpdateNC) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index feb46a2..18dd859 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -250,7 +250,7 @@ - 1 + 0 @@ -294,7 +294,7 @@ 0 - 0 + -455 443 2018 @@ -609,7 +609,7 @@ Qt::LeftToRight - Proyección EPSG + Proyección EPSG @@ -630,7 +630,7 @@ - 290 + 85 16777215 @@ -676,7 +676,7 @@ - 290 + 85 16777215 @@ -763,7 +763,7 @@ <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Ruta mapa raster + Mapa raster @@ -824,7 +824,7 @@ - 290 + 100 16777215 @@ -1010,6 +1010,12 @@ 200 + + QAbstractItemView::MultiSelection + + + QAbstractItemView::SelectRows + true @@ -1043,32 +1049,6 @@ - - - - false - - - - 50 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png:/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png - - - @@ -1102,6 +1082,18 @@ 200 + + Qt::TargetMoveAction + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + true @@ -1125,11 +1117,11 @@ - false + true - 50 + 75 0 @@ -1149,11 +1141,7 @@ Convertir variable a red hídrica (promedia celdas del tramo). - - - - - :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico + Var2Net From 8c5328331d70993b90c8237a6d1c14c734dd49be Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 23 Jul 2018 11:37:57 -0500 Subject: [PATCH 068/142] =?UTF-8?q?Funcionan=20el=2080%=20de=20los=20boton?= =?UTF-8?q?es=20de=20la=20herramienta=20de=20interpolaci=C3=B3n=20de=20cam?= =?UTF-8?q?pos=20de=20precipitaci=C3=B3n=20en=20IDW.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPluginUtils.py | 30 ++++++++- qgisplugin/HydroSEDPlugin_dockwidget.py | 47 +++++++++++++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 65 +++++++++++++++----- 3 files changed, 124 insertions(+), 18 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index a46e2ae..236a21b 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -5,6 +5,8 @@ import netCDF4 from wmf import wmf import numpy as np +import pandas as pd +import osgeo.ogr as ogr class controlHS: @@ -22,7 +24,7 @@ def __init__(self): self.DicBasinNc = {} self.DicBasinWMF = {} self.Nc2Save = [] - + self.Interpol_Columnas = [] def cargar_mapa_raster (self,pathMapaRaster): @@ -401,3 +403,29 @@ def Basin_GeoGetHAND(self): def Basin_GeoGetParameters(self): self.cuenca.GetGeo_Parameters() return self.cuenca.GeoParameters, self.cuenca.Tc + + def Interpol_GetFields(self, Path2Points): + '''Entrega una lista con los nombres de los atributos de un shp de puntos''' + #Lectura del archivo + Driver = ogr.Open(Path2Points) + layer = Driver.GetLayer(0) + #Obtiene los nombres de las columnas + self.Interpol_Columnas = [] + ldefn = layer.GetLayerDefn() + for n in range(ldefn.GetFieldCount()): + fdefn = ldefn.GetFieldDefn(n) + self.Interpol_Columnas.append(fdefn.name) + #Cierra el archivos + Driver.Destroy() + + def Interpol_GetDateTimeParams(self, Path2Excel): + '''Encuentra las fechas y el paso de tiempo del archivo de excel que contiene los registros de lluvia''' + #Abre el archivo y encuentra fechas + Data = pd.read_excel(Path2Excel) + self.Interpol_fi = Data.index[0].to_pydatetime() + self.Interpol_ff = Data.index[-1].to_pydatetime() + self.Interpol_fd = Data.index[1] - Data.index[0] + + + + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 7416e0a..5570166 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -23,7 +23,7 @@ import os -from PyQt4 import QtGui, uic +from PyQt4 import QtGui, uic, QtCore from PyQt4.QtCore import pyqtSignal from qgis.gui import QgsMessageBar @@ -59,6 +59,7 @@ def __init__(self, iface = None, parent=None): self.setupBasinManager() self.setupGeomorfologia() #self.setupUIButtonEvents () + self.setupRainfallInterpolation() self.TablaFila_WMF = 0 self.TablaFila_NC = 0 @@ -465,6 +466,49 @@ def handleClickConnectRaster2WMF(): self.Button_Raster2WMF.clicked.connect(handleClickConnectRaster2WMF) + def setupRainfallInterpolation(self): + '''Conjunto de herramientas dispuestas para interpolar campos de precipitacion''' + + def setupLineEditButtonOpenShapeFileDialog (lineEditHolder, fileDialogHolder): + '''Hace que cuando se busquen shapes solo se encuetren formatos vectoriales''' + lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Shapefiles (*.shp);;")) + if ((os.path.exists (lineEditHolder.text ().strip ())) and (not (self.iface is None))): + self.iface.addVectorLayer (lineEditHolder.text ().strip (), os.path.basename (lineEditHolder.text ()).strip (), "ogr") + + def setupLineEditButtonOpenExcelFileDialog (lineEditHolder, fileDialogHolder): + '''Hace que cuando se busquen shapes solo se encuetren formatos vectoriales''' + lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Excel (*.xlsx);;")) + + def clickEventSelectorMapaPuntosPluvio(): + '''Evento de click: selecciona el shp con las estaciones''' + #Reinicia el vector con los nombres de las variables y abre el archivo de puntos + self.HSutils.Interpol_Columnas = [] + setupLineEditButtonOpenShapeFileDialog (self.PathInHydro_Interpol_Pluvios, QFileDialog) + #Esculca los nombres de las columnas del mismo. + Path2Vect = self.PathInHydro_Interpol_Pluvios.text().strip() + self.HSutils.Interpol_GetFields(Path2Vect) + #Llena las opciones del ComboBox de Ids para elegir + for l in self.HSutils.Interpol_Columnas: + self.comboBox_Interpol.addItem(l) + + def clickEventSelectorArchivoExcel(): + '''Evento de click: selecciona el archivo de excel con los datos de pracipitacion a interpolar''' + #Busca el archivo + setupLineEditButtonOpenExcelFileDialog (self.PathInHydro_Interpol_Serie, QFileDialog) + #Encuentra la fecha inicio, fin y paso de tiempo, sugiere esos datos al usuario + Path2Excel = self.PathInHydro_Interpol_Serie.text().strip() + self.HSutils.Interpol_GetDateTimeParams(Path2Excel) + #Pone las fechas + Date = QtCore.QDateTime(self.HSutils.Interpol_fi) + self.Interpol_DateTimeStart.setDateTime(Date) + Date = QtCore.QDateTime(self.HSutils.Interpol_ff) + self.Interpol_DateTimeEnd.setDateTime(Date) + #Pone el intervalo de tiempo de interpolacion + self.Interpol_SpinBox_delta.setValue(self.HSutils.Interpol_fd.total_seconds()) + + self.Boton_HidroLoad_Pluvios.clicked.connect(clickEventSelectorMapaPuntosPluvio) + self.Boton_HidroLoad_Serie.clicked.connect(clickEventSelectorArchivoExcel) + def setupUIInputsOutputs (self): def handleClickEventButton_Eliminar_Desde_WMF (): @@ -537,6 +581,7 @@ def handleClickEventButton_WMF2NC(): VarName = self.Tabla_Prop_WMF.item(selectedItems,0).text() # Copia la entrada a WMF y la saca de NC self.HSutils.DicBasinNc.update({VarName:self.HSutils.DicBasinWMF[VarName]}) + self.HSutils.DicBasinNc[VarName]['var'] = np.copy(self.HSutils.DicBasinWMF[VarName]['var']) # Mete la entrada en la tabla de WMF y la saca de la tabla de NC self.TabNC.NewEntry(self.HSutils.DicBasinWMF[VarName], VarName, self.Tabla_Prop_NC) self.Tabla_Prop_WMF.removeRow (selectedItems) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 18dd859..c9181e6 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -250,7 +250,7 @@ - 0 + 3 @@ -294,7 +294,7 @@ 0 - -455 + -20 443 2018 @@ -2617,7 +2617,7 @@ 0 - 350 + 440 421 241 @@ -2985,7 +2985,7 @@ 0 0 411 - 331 + 421 @@ -2995,9 +2995,9 @@ 0 - 20 + 30 411 - 307 + 365 @@ -3074,7 +3074,7 @@ - + @@ -3107,14 +3107,14 @@ - + false - + true @@ -3203,7 +3203,7 @@ - + 2015 @@ -3211,6 +3211,12 @@ 1 + + dd/MMM/yyyy HH:mm + + + true + @@ -3225,7 +3231,7 @@ - + 2015 @@ -3233,6 +3239,33 @@ 1 + + dd/MMM/yyyy HH:mm + + + true + + + + + + + + + + + Intervalo de tiempo [seg] + + + + + + + 5.000000000000000 + + + 999999999.000000000000000 + @@ -3410,7 +3443,7 @@ -3 - 330 + 420 411 20 @@ -3423,7 +3456,7 @@ 0 - 620 + 710 421 271 @@ -3772,7 +3805,7 @@ 0 - 590 + 680 411 20 @@ -4413,7 +4446,7 @@ - + 2015 @@ -4435,7 +4468,7 @@ - + 2015 From 58673b09a2d1219fc6ceb409e5dba75c0423469e Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 23 Jul 2018 14:43:33 -0500 Subject: [PATCH 069/142] Ya el interpolador parece estar funcionando bien, falta comprobar si es correcto el resultado, todo indica que si --- qgisplugin/HydroSEDPluginUtils.py | 28 ++++++++++++++++++++ qgisplugin/HydroSEDPlugin_dockwidget.py | 26 +++++++++++++++++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 8 +++--- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 236a21b..c93979b 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -422,9 +422,37 @@ def Interpol_GetDateTimeParams(self, Path2Excel): '''Encuentra las fechas y el paso de tiempo del archivo de excel que contiene los registros de lluvia''' #Abre el archivo y encuentra fechas Data = pd.read_excel(Path2Excel) + self.InterpolData = Data.copy() self.Interpol_fi = Data.index[0].to_pydatetime() self.Interpol_ff = Data.index[-1].to_pydatetime() self.Interpol_fd = Data.index[1] - Data.index[0] + + def Interpol_GetInterpolation(self, Path2Shp,Campo2Read,fi,ff,fd,expo, PathOutput): + '''Interpola los campos de precipitacion para el periodo seleccionado con las estaciones disponibles''' + #Fechas en letras + fi = fi.strftime('%Y-%m-%d-%H:%M') + ff = ff.strftime('%Y-%m-%d-%H:%M') + tr = '%dS'%fd + #Obtiene los ids de excel + idExcel = self.InterpolData.columns.values.tolist() + idExcel = [i.encode() for i in idExcel] + #Lee el shp con los puntos y los ids + xy,idShape = wmf.read_map_points(Path2Shp,[Campo2Read.encode()]) + idShape = idShape[Campo2Read].astype(int).astype(str).tolist() + #Organiza los datos para interpolar + xyNew = [] + ColGood = [] + for i in idShape: + try: + pos = idExcel.index(i) + xyNew.append(xy.T[pos].tolist()) + ColGood.append(i) + except: + pass + xyNew = np.array(xyNew) + Data = self.InterpolData[ColGood][fi:ff].resample(tr).sum() + #Interpola + self.cuenca.rain_interpolate_idw(xyNew.T, Data, PathOutput,p = expo) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 5570166..459a610 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -475,6 +475,10 @@ def setupLineEditButtonOpenShapeFileDialog (lineEditHolder, fileDialogHolder): if ((os.path.exists (lineEditHolder.text ().strip ())) and (not (self.iface is None))): self.iface.addVectorLayer (lineEditHolder.text ().strip (), os.path.basename (lineEditHolder.text ()).strip (), "ogr") + def setupLineEditButtonSaveFileDialog (lineEditHolder, fileDialogHolder): + '''Pone la ruta elegida en el dialogo de texto para guardado''' + lineEditHolder.setText (fileDialogHolder.getSaveFileName (QtGui.QDialog (), "Guardar (cargar) binario de lluvia", "*", "RainBin (*.bin);;")) + def setupLineEditButtonOpenExcelFileDialog (lineEditHolder, fileDialogHolder): '''Hace que cuando se busquen shapes solo se encuetren formatos vectoriales''' lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Excel (*.xlsx);;")) @@ -505,9 +509,29 @@ def clickEventSelectorArchivoExcel(): self.Interpol_DateTimeEnd.setDateTime(Date) #Pone el intervalo de tiempo de interpolacion self.Interpol_SpinBox_delta.setValue(self.HSutils.Interpol_fd.total_seconds()) - + + def clickEventSelectorArchivoBinarioLluvia(): + '''Selecciona la ruta en donde se guardara el binario de salida.''' + setupLineEditButtonSaveFileDialog(self.PathOutHydro_Interpol,QFileDialog) + + def clickEventEjecutarInterpolacion(): + '''Interpola los campos de precipitacion con los parametros ingresados.''' + #Toma los parametros para la interpolacion + Path2Shp = self.PathInHydro_Interpol_Pluvios.text().strip() + Campo2Read = self.comboBox_Interpol.currentText() + fi = self.Interpol_DateTimeStart.dateTime().toPyDateTime() + ff = self.Interpol_DateTimeEnd.dateTime().toPyDateTime() + fd = self.Interpol_SpinBox_delta.value() + expo = self.Interpol_SpinBox_expIDW.value() + PathOut = self.PathOutHydro_Interpol.text().strip() + #Interpola para la cuenca seleccionada + self.HSutils.Interpol_GetInterpolation(Path2Shp,Campo2Read,fi,ff,fd,expo, PathOut) + self.iface.messageBar().pushInfo(u'HidroSIG:',u'Interpolacion de campos de precipitacion realizada con exito') + self.Boton_HidroLoad_Pluvios.clicked.connect(clickEventSelectorMapaPuntosPluvio) self.Boton_HidroLoad_Serie.clicked.connect(clickEventSelectorArchivoExcel) + self.Button_HidroSaveInterpol.clicked.connect(clickEventSelectorArchivoBinarioLluvia) + self.Butto_Ejec_HidroInterpol.clicked.connect(clickEventEjecutarInterpolacion) def setupUIInputsOutputs (self): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index c9181e6..9a6d004 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -1248,7 +1248,7 @@ 0 - -190 + 0 443 918 @@ -3170,7 +3170,7 @@ - + 50 @@ -3322,7 +3322,7 @@ - + Ruta de guardado @@ -3332,7 +3332,7 @@ - + Establecer ruta de guardado del binario de lluvia. From 8d8d68aea465a2e2686f643c89ab4b217cf79cf0 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 24 Jul 2018 10:37:19 -0500 Subject: [PATCH 070/142] =?UTF-8?q?el=20interpolador=20funciona,=20grafica?= =?UTF-8?q?=20la=20serie,=20histograma=20y=20climatologia,=20adem=C3=A1s?= =?UTF-8?q?=20obtiene=20el=20campo=20de=20precipitacion=20del=20periodo=20?= =?UTF-8?q?seleccionado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPlots.py | 213 +++++++++++++++++++ qgisplugin/HydroSEDPluginUtils.py | 21 ++ qgisplugin/HydroSEDPlugin_dockwidget.py | 89 +++++++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 208 +++++++++++++----- 4 files changed, 470 insertions(+), 61 deletions(-) create mode 100644 qgisplugin/HydroSEDPlots.py diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py new file mode 100644 index 0000000..1db1cb5 --- /dev/null +++ b/qgisplugin/HydroSEDPlots.py @@ -0,0 +1,213 @@ +from wmf import wmf +import numpy as np +import plotly.graph_objs as go +from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot + +class PlotRainfall(): + + def __init__(self, pathRain): + self.path_rainBin, self.path_rainHdr = wmf.__Add_hdr_bin_2route__(pathRain) + self.rainData = wmf.read_rain_struct(self.path_rainHdr) + + def Plot_Rainfall(self, pathFigure): + '''Hace el plot de la serie de tiempo de lluvia e incluye en esta toda la info necesaria''' + #obtiene los records + Rs = self.rainData.copy() + Records = ['Record: %d'%i for i in Rs[' Record'].values] + #Datos de lluvia + trace1 = go.Scatter( + x = Rs.index.to_pydatetime(), + y = Rs[' Lluvia'].values, + text = Records, + name = 'Lluvia [mm]', + line = {'width':3}, + fill='tozeroy' + ) + #Datos de lluvia acumulada + trace2 = go.Scatter( + x = Rs.index.to_pydatetime(), + y = Rs[' Lluvia'].values.cumsum(), + name = 'Acumulado [mm]', + line = {'width':3}, + yaxis = 'y2' + ) + #Datos y formato de la figura + data = [trace1, trace2] + layout = dict( + width=1020, + height=400, + showlegend = False, + margin=dict( + l=50, + r=50, + b=50, + t=50, + pad=4 + ), + yaxis=dict( + title='Precipitacion', + titlefont=dict( + color='rgb(0, 102, 153)', + size = 15 + ), + tickangle=-90, + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16, + ), + ), + + xaxis = dict( + tickfont = dict( + size = 16 + ), + ), + + yaxis2=dict( + title='Acumulada', + titlefont=dict( + color='rgb(255, 153, 51)', + size = 15 + ), + tickangle=90, + tickfont=dict( + color='rgb(255, 153, 51)', + size = 16, + ), + overlaying='y', + side='right', + range = [0,Rs[' Lluvia'].values.sum()] + )) + #Figura + fig = dict(data=data, layout=layout) + #Guarda el html + plot(fig,filename=pathFigure, auto_open = False) + + def Plot_Histogram(self, pathFigure): + '''Hace un plot del histograma de la distribucion de la lluvia en la cuenca.''' + #Hace una cipia de la informacion + Data = self.rainData.copy() + Data = Data[' Lluvia'].values + Data = Data[Data>0] + step = (np.percentile(Data,95) - np.percentile(Data,5))/7. + #Genera los datos de la figura + trace1 = go.Histogram( + x = Data, + name = 'Lluvia [mm]', + xbins = dict( + start = np.percentile(Data,5), + end = np.percentile(Data,95), + size = step) + ) + #Establece la configuracion de la misma + layout = dict( + width=400, + height=400, + showlegend = False, + margin=dict( + l=50, + r=50, + b=70, + t=50, + pad=4 + ), + yaxis=dict( + title='PDF', + titlefont=dict( + color='rgb(0, 102, 153)', + size = 15 + ), + tickangle=45, + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16, + ),), + xaxis = dict( + title = 'Lluvia [mm]', + titlefont =dict( + color='rgb(0, 102, 153)', + size = 15 + ), + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16, + ) + ) + ) + #Monta la figura + data = [trace1] + fig = dict(data = data, layout = layout) + plot(fig,filename=pathFigure, auto_open = False) + + def Plot_MediaMensual(self, pathFigure): + '''Hace el plot de la media mensual multi-anual de la serie de lluvia de la cuenca''' + Rs = self.rainData.copy() + Rain = Rs[' Lluvia'].resample('M').sum() + #Obtiene media y desviqacion + Mean = [] + Desv = [] + for i in range(1,13): + Mean.append(Rain[Rain.index.month == i].mean()) + Desv.append(np.std(Rain[Rain.index.month == i])) + Mean = np.array(Mean) + Desv = np.array(Desv) + #Hace la figura + trace1 = go.Scatter( + x = np.arange(1,13,1), + y = Mean, + name = 'Media', + line = {'width':5, + 'color':('rgb(0, 51, 102)')}, + ) + + trace2 = go.Scatter( + x = np.arange(1,13,1), + y = Mean + Desv, + name = 'm + s', + line = dict(color = ('rgb(255, 153, 51)'), + width = 3), + ) + + trace3 = go.Scatter( + x = np.arange(1,13,1), + y = Mean - Desv, + name = 'm - s', + fill='tonexty', + line = dict( width=3, + color = ('rgb(255, 153, 51)')), + ) + data = [trace2, trace3, trace1] + layout = dict( + width=800, + height=400, + showlegend = False, + margin=dict( + l=50, + r=50, + b=50, + t=50, + pad=4 + ), + xaxis=dict( + dtick=1, + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16), + ticktext = ['Ene','Feb','Mar','Abr','May','Jun','Jul','Ago','Sep','Oct','Nov','Dic'], + tickvals = range(1,13) + ), + yaxis=dict( + title='Precipitacion', + titlefont=dict( + color='rgb(0, 102, 153)', + size = 15 + ), + tickangle=-90, + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16, + ), + ), + ) + fig = dict(data=data, layout=layout) + plot(fig,filename=pathFigure, auto_open = False) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index c93979b..6c90592 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -7,6 +7,7 @@ import numpy as np import pandas as pd import osgeo.ogr as ogr +import HydroSEDPlots as HSplots class controlHS: @@ -454,6 +455,26 @@ def Interpol_GetInterpolation(self, Path2Shp,Campo2Read,fi,ff,fd,expo, PathOutpu #Interpola self.cuenca.rain_interpolate_idw(xyNew.T, Data, PathOutput,p = expo) + def Interpol_GetRainfallAcum(self, path2bin, inicio, fin): + '''Obtiene un campo acumulado de precipitacion para el periodo especifico''' + #Lee el binario y los datos en el intervalo + Vsum = np.zeros(self.cuenca.ncells) + for i in range(inicio, fin+1): + vect,res = wmf.models.read_int_basin(path2bin,i,self.cuenca.ncells) + if res == 0: + vect = vect.astype(float)/1000. + Vsum+=vect + #Pasa el acumulado al diccionario de WMF + self.DicBasinWMF.update({'Lluvia': + {'nombre':'Lluvia', + 'tipo':Vsum.dtype.name, + 'shape':Vsum.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Hidro', + 'var': Vsum}}) + + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 459a610..49318b3 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -24,7 +24,8 @@ import os from PyQt4 import QtGui, uic, QtCore -from PyQt4.QtCore import pyqtSignal +from PyQt4.QtCore import pyqtSignal, QUrl +from PyQt4.QtWebKit import QWebView from qgis.gui import QgsMessageBar from PyQt4.QtGui import QFileDialog, QTableWidgetItem, QAbstractItemView @@ -33,6 +34,7 @@ import HydroSEDPluginUtils as HSutils import HydroGetCoordinates as HSCoord +import HydroSEDPlots as HSplots import GdalTools_utils as GdalTools_utils @@ -72,7 +74,7 @@ def __init__(self, iface = None, parent=None): if not (iface is None): self.iface = iface - self.HSutils = HSutils.controlHS() + self.HSutils = HSutils.controlHS() self.GetCoordsCorriente = HSCoord.PointTool(self.iface.mapCanvas(), self.spinBoxLatitudTrazadorCorrientes, self.spinBoxLongitudTrazadorCorrientes) self.GetCoordsCuenca = HSCoord.PointTool(self.iface.mapCanvas(), self.spinBoxLatitudTrazadorCuencas, @@ -512,7 +514,14 @@ def clickEventSelectorArchivoExcel(): def clickEventSelectorArchivoBinarioLluvia(): '''Selecciona la ruta en donde se guardara el binario de salida.''' + #pone el camino del archivo con la lluvia de la cuenca setupLineEditButtonSaveFileDialog(self.PathOutHydro_Interpol,QFileDialog) + #Trata de leer datos de lluvia en caso de que ya existan + try: + PathData = self.PathOutHydro_Interpol.text().strip() + self.HSplots = HSplots.PlotRainfall(PathData) + except: + pass def clickEventEjecutarInterpolacion(): '''Interpola los campos de precipitacion con los parametros ingresados.''' @@ -526,12 +535,86 @@ def clickEventEjecutarInterpolacion(): PathOut = self.PathOutHydro_Interpol.text().strip() #Interpola para la cuenca seleccionada self.HSutils.Interpol_GetInterpolation(Path2Shp,Campo2Read,fi,ff,fd,expo, PathOut) + #Trata de leer datos de lluvia en caso de que ya existan + try: + PathData = self.PathOutHydro_Interpol.text().strip() + self.HSplots = HSplots.PlotRainfall(PathData) + except: + pass + #Aviso de existo self.iface.messageBar().pushInfo(u'HidroSIG:',u'Interpolacion de campos de precipitacion realizada con exito') + def clickEventViewSerieRainfall(): + '''Genera y visualiza la grafica de lluvia interpolada para la cuenca''' + #Hace la figura + PathFigure = '/tmp/HydroSED/RainfallPlot.html' + self.HSplots.Plot_Rainfall(PathFigure) + #Set de la ventana que contiene la figura. + self.VistaRainWeb = QWebView(None) + self.VistaRainWeb.load(QUrl.fromLocalFile(PathFigure)) + self.VistaRainWeb.setWindowTitle('Precipitacion media en la cuenca') + self.VistaRainWeb.setMinimumWidth(1100) + self.VistaRainWeb.setMaximumWidth(3000) + self.VistaRainWeb.setMinimumHeight(100) + self.VistaRainWeb.setMaximumHeight(400) + self.VistaRainWeb.show() + + def clickEventViewHistogramRainfall(): + '''Genera y visualiza la grafica de lluvia interpolada para la cuenca''' + #Hace la figura + PathFigure = '/tmp/HydroSED/RainfallHistogram.html' + self.HSplots.Plot_Histogram(PathFigure) + #Set de la ventana que contiene la figura. + self.VistaRainWeb = QWebView(None) + self.VistaRainWeb.load(QUrl.fromLocalFile(PathFigure)) + self.VistaRainWeb.setWindowTitle('Histograma precipitacion') + self.VistaRainWeb.setMinimumWidth(200) + self.VistaRainWeb.setMaximumWidth(400) + self.VistaRainWeb.setMinimumHeight(400) + self.VistaRainWeb.setMaximumHeight(400) + self.VistaRainWeb.show() + + def clickEventViewMediaMensualRainfall(): + '''Genera y visualiza la grafica de la lluvia media mensual en la cuenca''' + #Hace la figura + PathFigure = '/tmp/HydroSED/RainfallMediaMensual.html' + self.HSplots.Plot_MediaMensual(PathFigure) + #Set de la ventana que contiene la figura. + self.VistaRainWeb = QWebView(None) + self.VistaRainWeb.load(QUrl.fromLocalFile(PathFigure)) + self.VistaRainWeb.setWindowTitle('Media mensual multi-anual de precipitacion') + self.VistaRainWeb.setMinimumWidth(200) + self.VistaRainWeb.setMaximumWidth(800) + self.VistaRainWeb.setMinimumHeight(100) + self.VistaRainWeb.setMaximumHeight(400) + self.VistaRainWeb.show() + + def clickEventGetAcumRainfall(): + '''Obtiene el acumulado de lluvia en el periodo especifico''' + #Punto inicial y final + Path = self.PathOutHydro_Interpol.text().strip() + inicio = int(self.spinBoxCampoInicio.value()) + fin = int(self.spinBoxCampoFin.value()) + #Obtiene el campo acumulado para el periodo seleccionado + self.HSutils.Interpol_GetRainfallAcum(Path, inicio, fin) + #Actualiza la tabla WMF + k = 'Lluvia' + self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[k],k, self.Tabla_Prop_WMF) + #Aviso de existo + self.iface.messageBar().pushInfo(u'HidroSIG:',u'Los campos de han acumulado en la variable Lluvia de la tabla WMF') + + #Botones de set de interpolacion self.Boton_HidroLoad_Pluvios.clicked.connect(clickEventSelectorMapaPuntosPluvio) self.Boton_HidroLoad_Serie.clicked.connect(clickEventSelectorArchivoExcel) self.Button_HidroSaveInterpol.clicked.connect(clickEventSelectorArchivoBinarioLluvia) - self.Butto_Ejec_HidroInterpol.clicked.connect(clickEventEjecutarInterpolacion) + #Botones de ejecucion + self.Button_Ejec_HidroInterpol.clicked.connect(clickEventEjecutarInterpolacion) + self.Button_InterpolViewField.clicked.connect(clickEventGetAcumRainfall) + #Botones de visualizacion + self.Button_InterpolSerieView.clicked.connect(clickEventViewSerieRainfall) + self.Button_InterpolHistogram.clicked.connect(clickEventViewHistogramRainfall) + self.Button_InterpolCiclo.clicked.connect(clickEventViewMediaMensualRainfall) + def setupUIInputsOutputs (self): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 9a6d004..0778179 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -294,7 +294,7 @@ 0 - -20 + 0 443 2018 @@ -2581,7 +2581,7 @@ 0 - 0 + -38 443 1918 @@ -2985,7 +2985,7 @@ 0 0 411 - 421 + 411 @@ -2997,7 +2997,7 @@ 0 30 411 - 365 + 381 @@ -3308,19 +3308,6 @@ - - - - Qt::Horizontal - - - - 10 - 20 - - - - @@ -3346,91 +3333,196 @@ - + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + Qt::Horizontal + + + + + + + + + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + + + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + + + Gráficas tiempo + + + + + - 50 + 20 0 + + Ejecuta la interpolación para la cuenca con los parámetros dados. + - Entrada del binario de lluvia a visualizar. + Ejecuta la interpolación para la cuenca con los parámetros dados. - - 0 + + Ciclo Anual - - 0.000000000000000 + + + + + + + 10 + 0 + - - 10000000.000000000000000 + + Ejecuta la interpolación para la cuenca con los parámetros dados. - - 1.000000000000000 + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Histograma - - - false + + + + 20 + 0 + - 40 + 100 16777215 + + Ejecuta la interpolación para la cuenca con los parámetros dados. + - Visualiza una entrada del binario de lluvia interpolado. + Ejecuta la interpolación para la cuenca con los parámetros dados. - - - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + Serie - - - Qt::Horizontal - - - - - + - - - Qt::Horizontal + + + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. - + + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + + + Gráficas espacio + + + + + + - 10 - 20 + 20 + 0 - + + Entrada del binario de lluvia a visualizar. + + + 0 + + + 0.000000000000000 + + + 10000000.000000000000000 + + + 1.000000000000000 + + - - - Ejecuta la interpolación para la cuenca con los parámetros dados. + + + + 50 + 0 + - Ejecuta la interpolación para la cuenca con los parámetros dados. + Entrada del binario de lluvia a visualizar. + + + 0 + + + 0.000000000000000 + + + 10000000.000000000000000 + + + 1.000000000000000 + + + + + + + true + + + + 40 + 16777215 + + + + Visualiza una entrada del binario de lluvia interpolado. - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png From d9e6e37282860e480e8ea3f911bb4a76c26ea8ee Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 6 Aug 2018 15:57:24 -0500 Subject: [PATCH 071/142] cambios en la interfaz para poner a simular el modelo --- qgisplugin/HydroSEDPluginUtils.py | 42 +- qgisplugin/HydroSEDPlugin_dockwidget.py | 48 +- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 565 +++++++++++++++---- wmf/wmf.py | 1 + 4 files changed, 541 insertions(+), 115 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 6c90592..29b2f45 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -217,7 +217,10 @@ def Basin_Update(self, PathNC): #Cerrado del archivo nc g.close() - def Basin_LoadBasin(self, PathNC): + def Basin_LoadBasin(self, PathNC, LoadSim = False, LoadSed = False): + '''Carga un proyecto cuenca de nc en la memoria de Qgis: + LoadSim: Carga las variables de simulacion + LoadSed: Carga variables de simulacion de sedimentos''' # Numero Total de Variables self.NumDicBasinNcVariables = 0 # Numero Total de Variables Basicas @@ -226,7 +229,12 @@ def Basin_LoadBasin(self, PathNC): self.cuenca = wmf.SimuBasin(rute = PathNC) #Cargar las variables de la cuenca a un diccionario. g = netCDF4.Dataset(PathNC) - for grupoKey in ['base','Geomorfo','Hidro']: + ListGrupos = ['base','Geomorfo','Hidro'] + if LoadSim: + ListGrupos.append('SimHidro') + if LoadSed: + ListGrupos.append('SimSediments') + for grupoKey in ListGrupos: #Carga los grupos de variables en donde si se tengan variables if len(g.groups[grupoKey].variables.keys())>0: #itera @@ -474,7 +482,33 @@ def Interpol_GetRainfallAcum(self, path2bin, inicio, fin): 'categoria': 'Hidro', 'var': Vsum}}) - - + def Sim_SaveParameters(self, PathNC, ParamName, scalarParam): + '''Actualiza el nc con un conjunto de parametros escalares nuevo''' + #Abre el archivo nc y apunta al grupo de parametros + g = netCDF4.Dataset(PathNC,'a') + GrupoParam = g.groups['Parametros'] + Ejecuto = 1 + if len(ParamName)>0: + #mira si el grupo ya tiene parametros adentro, si no crea la dimension + try: + pos = GrupoParam.dimensions.keys().index('nparam') + except: + DimNparam = GrupoParam.createDimension('nparam',15) + #Crea el sub-grupo con el nombre de los parametros dentro del nc + SubGroup = g.groups['Parametros'].createGroup('NombreParam') + nnames = SubGroup.createDimension('nnames',15) + nombres = SubGroup.createVariable('nombres', str, ('nnames',)) + nombres[:] = np.array(['Hu','Hg','Evp','Inf','Per','Loss','vRun','vSub','vSup','vChannel', + 'SedParam','Exp1','Exp2','Exp3','Exp4'], dtype = object) + #Crea la variable en el grupo o la sobre-escribe + try: + Var = GrupoParam.createVariable(ParamName,'f4',('nparam',),zlib=True) + except: + Var = GrupoParam.variables[ParamName] + Var[:] = scalarParam + Ejecuto = 0 + #cierra el archivo + g.close() + return Ejecuto diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 49318b3..e580b2b 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -62,6 +62,7 @@ def __init__(self, iface = None, parent=None): self.setupGeomorfologia() #self.setupUIButtonEvents () self.setupRainfallInterpolation() + self.setupSimulation() self.TablaFila_WMF = 0 self.TablaFila_NC = 0 @@ -178,7 +179,11 @@ def clickEventSelectorBasin(): self.ButtonLoadBasinProyect.setEnabled(True) def clickEventBasin2WMF(): '''Agrega el proyecto de cuenca a WMF''' - self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip()) + #Checks para simulacion de sedimentos e hidrologica + Simhidro = self.checkBox_simBasin.isChecked() + SimSed = self.checkBox_simSed.isChecked() + #Cargado de la cuenca + self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), Simhidro, SimSed) self.TableStart() for k in self.HSutils.DicBasinNc.keys(): self.TabNC.NewEntry(self.HSutils.DicBasinNc[k],k, self.Tabla_Prop_NC) @@ -615,6 +620,47 @@ def clickEventGetAcumRainfall(): self.Button_InterpolHistogram.clicked.connect(clickEventViewHistogramRainfall) self.Button_InterpolCiclo.clicked.connect(clickEventViewMediaMensualRainfall) + + def setupSimulation(self): + '''Herramientas para gestionar la simulacion hidrologica con la cuenca cargada''' + + def clickEventUpdateParamMapValues(): + '''Muestra en los campos de simulacion el valor medio de los mapas de simulacion''' + VarNames = ['h1_max','h3_max', 'v_coef','v_coef','v_coef','v_coef','h_coef', + 'h_coef','h_coef','h_coef', 'Krusle','Crusle','Prusle', + 'Arenas','Limos','Arcillas'] + Ejes = [0,0,0,1,2,3,0,1,2,3,0,0,0,0,0,0] + for name, i, eje in zip(VarNames, range(1,17), Ejes): + Campo = getattr(self, 'ParamVal'+str(i)) + Campo.setMinimum(-99999) + Campo.setValue(0) + try: + Value = self.HSutils.DicBasinNc[name]['var'].mean(axis = 1)[eje] + except: + try: + Value = self.HSutils.DicBasinNc[name]['var'].mean() + except: + Value = -9999 + Campo.setValue(Value) + + def clickEventAddNewParamSet(): + '''Agrega un nuevo conjunto de parametros en el proyecto de cuenca''' + #Obtiene los parametros + PathNC = self.lineEditRutaCuenca.text().strip() + ParamName = self.ParamName.text().strip() + #Itera para los parametros escalares y de sedimentos + ListaParam = [] + for i in range(1,12): + ListaParam.append(getattr(self, 'Param'+str(i)).value()) + #Itera en los exponentes + for i in range(1,5): + ListaParam.append(getattr(self, 'ParamExp'+str(i)).value()) + #Mete el set nuevo de calibracion + self.HSutils.Sim_SaveParameters(PathNC, ParamName, ListaParam) + + + self.ButtonSimCalib2Nc.clicked.connect(clickEventAddNewParamSet) + self.tabPanelDockOpciones.currentChanged.connect(clickEventUpdateParamMapValues) def setupUIInputsOutputs (self): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 0778179..43a7d4a 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -113,7 +113,7 @@ - false + true Sedimentos @@ -250,7 +250,7 @@ - 3 + 4 @@ -2581,7 +2581,7 @@ 0 - -38 + 0 443 1918 @@ -3947,7 +3947,7 @@ 0 - 0 + -328 433 1918 @@ -4103,7 +4103,7 @@ 0 330 411 - 641 + 711 @@ -4115,7 +4115,7 @@ 0 70 401 - 531 + 551 @@ -4124,27 +4124,21 @@ 4 - - - - - - - - - + + Valor medio de la variable + Variable - - - + + Parametro calibrador + Coef @@ -4152,71 +4146,68 @@ + + Parámetro K de RUSLE + Krusle - - - - - - - + Exponente regional en caso de usar aproximación no lineal v = C A^e Exponente aproximación no lineal al flujo superficial + + 99999.000000000000000 + + + 1.000000000000000 + - - - - - - - - - - + Exponente regional en caso de usar aproximación no lineal v = C A^e Exponente aproximación no lineal al flujo sub-superficial + + 1.000000000000000 + - - - + + Velocidad horizontal sub-superficial (h_coef[1]) + Vh2 [m/s] - - - + + Exponente aproximacion potencial (dejar en 1 para ecuaciones lineales) + Expo - - - + + Velocidad horizontal subterranea (h_coef[2]) + Vh3 [m/s] @@ -4224,97 +4215,84 @@ + + Velocidad horizontal escorrentia (h_coef[0]) + Vh1 [m/s] - - - - - - - - - + + Velocidad vertical infiltracion (v_coef[1]) + Vv1 [mm/s] - - - + + Velocidad vertical percolacion (v_coef[2]) + Vv2 [mm/s] - - - + + Velocidad horizontal canales (h_coef[3]) + Vh4 [m/s] - + Exponente regional en caso de usar aproximación no lineal v = C A^e Exponente aproximación no lineal al flujo subterráneo - - - - - - - - - Exponente regional en caso de usar aproximación no lineal v = C A^e - - - Exponente aproximación no lineal al flujo en canales + + 1.000000000000000 - - - + + Velocidad vertical pérdidas (v_coef[3]) + Vv3 [mm/s] - - - - - - + + Velocidad vertical evaporacion (v_coef[0]) + - Hg [mm] + Vv0 [mm] + + Almacenamiento máximo capilar [h3_max] + - Hu [mm] + Hg [mm] @@ -4327,42 +4305,39 @@ + + Parámetro C de RUSLE + Crusle - - - - - - + + Parámetro P de RUSLE + Prusle - - - + + Porcentaje de limos (0-100) + Limos - - - - - - + + Porcentaje de arcillas (0-100) + Arcillas @@ -4370,22 +4345,391 @@ + + Porcentaje de arenas (0-100) + Arenas - - + + + + Sed Param + + - - + + + + 1.000000000000000 + + + + + + + Almacenamiento máximo capilar [h1_max] + + + Hu [mm] + + + + + + + 1.000000000000000 + + + + + + + 1.000000000000000 + + + + + + + 1.000000000000000 + + + + + + + 1.000000000000000 + + + + + + + 1.000000000000000 + + + + + + + 1.000000000000000 + + + + + + + 1.000000000000000 + + + + + + + 1.000000000000000 + + - - + + + + 1.000000000000000 + + - - + + + + 1.000000000000000 + + + + + + + Exponente regional en caso de usar aproximación no lineal v = C A^e + + + Exponente aproximación no lineal al flujo en canales + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 99999.000000000000000 + + + 0.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 99999.000000000000000 + + + 0.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + -1.000000000000000 + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + -99999.000000000000000 + + + 99999.000000000000000 + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 1.000000000000000 + + @@ -4395,7 +4739,7 @@ 0 - 600 + 620 401 41 @@ -4411,7 +4755,7 @@ - + false @@ -4710,7 +5054,7 @@ 0 - 970 + 1050 411 20 @@ -4723,7 +5067,7 @@ 0 - 990 + 1070 401 271 @@ -4787,6 +5131,7 @@ + diff --git a/wmf/wmf.py b/wmf/wmf.py index 5496609..838f4fc 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -3934,6 +3934,7 @@ def Save_SimuBasin(self,ruta,SimSlides = False, GrupoSimSli = gr.createGroup('SimSlides') GrupoHidro = gr.createGroup('Hidro') GrupoGeo = gr.createGroup('Geomorfo') + GrupoCalib = gr.createGroup('Parametros') #Variables grupo base DimNcell = GrupoBase.createDimension('ncell',self.ncells) DimNhill = GrupoBase.createDimension('nhills',self.nhills) From 2df3a7976a89fc4fe61ba12a12c53785051bfff8 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 8 Aug 2018 16:31:53 -0500 Subject: [PATCH 072/142] =?UTF-8?q?se=20ponene=20tres=20nu8evas=20opciones?= =?UTF-8?q?=20en=20el=20calculo=20de=20parma=20geomorfologicos,=20todas=20?= =?UTF-8?q?relacionadas=20con=20coeficientes=20y=20exponentes=20no=20linea?= =?UTF-8?q?les=20del=20modelo,=20adem=C3=A1s=20se=20comienza=20a=20esbozar?= =?UTF-8?q?=20el=20esquema=20de=20gesti=C3=B3n=20de=20variables=20en=20el?= =?UTF-8?q?=20NC=20y=20el=20establecimiento=20de=20variables=20propias=20d?= =?UTF-8?q?e=20modelaci=C3=B3n=20en=20el=20mismo,=20nada=20de=20esto=20est?= =?UTF-8?q?a=20probado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPluginUtils.py | 77 ++- qgisplugin/HydroSEDPlugin_dockwidget.py | 16 + qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 499 +++++++++++++------ wmf/wmf.py | 1 + 4 files changed, 433 insertions(+), 160 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 29b2f45..2743809 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -408,7 +408,82 @@ def Basin_GeoGetHAND(self): 'basica': False, 'categoria': 'Geomorfo', 'var': self.cuenca.CellHAND_class}}) - + + def Basin_GeoGetOCG(self): + '''Obtiene el coeficiente y el exponente de OCG (velez, 2001) para la cuenca''' + #Obtiene param basicos de la cuenca + self.cuenca.GetGeo_Cell_Basics() + Area = self.cuenca.CellAcum*wmf.cu.dxp**2/1e6 + #Obtiene el coeficiente + Coef, Expo = wmf.OCG_param(pend=self.cuenca.CellSlope, area=Area) + #Agrea los resultados al diccionario + self.DicBasinWMF.update({'OCG_coef': + {'nombre':'OCG_coef', + 'tipo':Coef.dtype.name, + 'shape':Coef.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geomorfo', + 'var': np.copy(Coef)}}) + self.DicBasinWMF.update({'OCG_exp': + {'nombre':'OCG_exp', + 'tipo':Coef.dtype.name, + 'shape':Coef.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geomorfo', + 'var': np.copy(Expo)}}) + + def Basin_GeoGetKubota(self): + '''Obtiene el coeficiente de kubota y sivapalan para el flujo de agua en el suelo + para el correcto calculo el susuario debe tener definidas las variables: + - Hu: almacenamiento capilar maximo [mm] DicBasinNc['h1_max'] + - ks: conductividad saturada del suelo [mm/s] DicBasinNc['v_coef'][1]''' + #Copia parametros de la cuenca que deben estar definidos + Hu = np.copy(self.DicBasinNc['h1_max']['var']) + ks = np.copy(self.DicBasinNc['v_coef']['var'][0]) + self.cuenca.GetGeo_Cell_Basics() + So = np.copy(self.cuenca.CellSlope) + Factor = (wmf.cu.dxp**2.)/1000. #[m3/mm] + #Calculo del coeficiente de kubota + Coef = (ks*So*(wmf.cu.dxp**2.))/(3*(Hu*Factor)**2.) + #Actualiza el diccionario + self.DicBasinWMF.update({'Kubota_coef': + {'nombre':'Kubota_coef', + 'tipo':Coef.dtype.name, + 'shape':Coef.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geomorfo', + 'var': np.copy(Coef)}}) + + def Basin_GeoGetRunoff(self, e1, Epsilon): + '''Obtiene el coeficiente de escorrentia para carcavas''' + #Obtiene pendiente y param requeridos + self.cuenca.GetGeo_Cell_Basics() + So = np.copy(self.cuenca.CellSlope) + Man = np.copy(self.DicBasinWMF['Manning']['var']) + #Calcula + Coef = (Epsilon/Man)*(So**2.) + Expo = (2./3.)*e1 + #Pone en los diccionarios + self.DicBasinWMF.update({'Runoff_coef': + {'nombre':'Runoff_coef', + 'tipo':Coef.dtype.name, + 'shape':Coef.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geomorfo', + 'var': np.copy(Coef)}}) + self.DicBasinWMF.update({'Runoff_exp': + {'nombre':'Runoff_exp', + 'tipo':Expo.dtype.name, + 'shape':Expo.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geomorfo', + 'var': np.copy(Expo)}}) + def Basin_GeoGetParameters(self): self.cuenca.GetGeo_Parameters() return self.cuenca.GeoParameters, self.cuenca.Tc diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index e580b2b..8ea551c 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -268,6 +268,9 @@ def clickEventActivateGeoCheckBoxes(): self.checkBoxDist2Out.setChecked(True) self.checkBoxHAND.setChecked(True) self.checkBoxIT.setChecked(True) + self.checkBoxOCG.setChecked(True) + self.checkBoxKubota.setChecked(True) + self.checkBoxRunoff.setChecked(True) #Si no, des-selecciona a todas else: self.checkBoxArea.setChecked(False) @@ -276,6 +279,9 @@ def clickEventActivateGeoCheckBoxes(): self.checkBoxDist2Out.setChecked(False) self.checkBoxHAND.setChecked(False) self.checkBoxIT.setChecked(False) + self.checkBoxOCG.setChecked(False) + self.checkBoxKubota.setChecked(False) + self.checkBoxRunoff.setChecked(False) def GeoTableStart(): '''Inicia la tabla donde monta los parametros geomorfologicos de la cuenca''' @@ -342,6 +348,16 @@ def clickEventGeoRasterProp(): if self.checkBoxChannels.isChecked(): self.HSutils.Basin_GeoGetChannels() ListaVar.extend(['Channels']) + if self.checkBoxOCG.isChecked(): + self.HSutils.Basin_GeoGetOCG() + ListaVar.extend(['OCG_coef']) + if self.checkBoxKubota.isChecked(): + self.HSutils.Basin_GeoGetKubota() + ListaVar.extend(['kubota_coef']) + if self.checkBoxRunoff.isChecked(): + self.HSutils.Basin_GeoGetRunoff() + ListaVar.extend(['Runoff_coef']) + #mensaje de caso de exito self.iface.messageBar().pushInfo(u'HidroSIG:',u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.') #Actualiza la tabla de variables temporales diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 43a7d4a..1dfd586 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -6,7 +6,7 @@ 0 0 - 489 + 487 936 @@ -238,7 +238,7 @@ 0 - 150 + 120 469 776 @@ -250,7 +250,7 @@ - 4 + 0 @@ -294,7 +294,7 @@ 0 - 0 + -981 443 2018 @@ -332,7 +332,7 @@ 0 0 425 - 1147 + 1151 @@ -687,43 +687,6 @@ - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - QSizePolicy::Minimum - - - - 20 - 20 - - - - - - - - - 14 - 75 - true - - - - Variables de la cuenca. - - - @@ -1099,111 +1062,257 @@ - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - true - - - - 75 - 0 - - - - - 30 - 16777215 - - - - Qt::DefaultContextMenu - - - Convertir variable a red hídrica (promedia celdas del tramo). - - - Convertir variable a red hídrica (promedia celdas del tramo). - - - Var2Net - - - - 16 - 16 - - - - - - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Actualiza el archivo .nc del proyecto cuenca. - - - - - - - :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg - - - - - - - - 50 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - - - - - + + + + 0 + 1160 + 421 + 151 + + + + Gestión de variables Nc + + + + + 0 + 20 + 421 + 121 + + + + + + + + + + + + + + + + + 50 + 16777215 + + + + Ejecutar la función de trazado de corriente. + + + Ejecutar la función de trazado de corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + 50 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + Actualizar + + + + + + + Capa a ver de la variable, aplica solo para variables 2D + + + + + + + Tipo conversión + + + + + + + Método + + + + + + + + + + 230 + 1350 + 99 + 27 + + + + PushButton + + + + + + 120 + 1420 + 61 + 27 + + + + + + + 0 + 1420 + 117 + 22 + + + + Canales + + + + + + 0 + 1440 + 117 + 22 + + + + Laderas + + + + + + 0 + 1400 + 117 + 21 + + + + Tipo conversión + + + + + + 120 + 1400 + 61 + 16 + + + + Método + + + + + + 220 + 1420 + 101 + 27 + + + + + + + 220 + 1400 + 61 + 16 + + + + Objetivo + + + + + + 220 + 1450 + 101 + 27 + + + + + + + 330 + 1420 + 41 + 27 + + + + Capa a ver de la variable, aplica solo para variables 2D + + + + + + 200 + 1420 + 21 + 22 + + + + + + + + + + 200 + 1450 + 21 + 22 + + + + + + @@ -2049,19 +2158,6 @@ - - - - calcula todos los parámetros geomorfológicos distribuidos. - - - calcula todos los parámetros geomorfológicos distribuidos. - - - Seleccionar todos - - - @@ -2161,6 +2257,91 @@ + + + + calcula todos los parámetros geomorfológicos distribuidos. + + + calcula todos los parámetros geomorfológicos distribuidos. + + + Seleccionar todos + + + + + + + Calcula el mapa con el coeficiente de la OCG (Velez, 2001) + + + Calcula el mapa con el coeficiente de la OCG (Velez, 2001) + + + Coeficiente OCG + + + + + + + + + + Calcular mapa de coeficiente de flujo sub-superficial (kubota, 1995), requiere: h1_max y v_coef[1] definidos en la tabla de Nc + + + Coeficiente kubota + + + + + + + + + + Calcular coeficiente y exp de escorrentía, requiere mapa Manning en WMF + + + Coeficiente runoff + + + + + + + + + Exponente e1 para calculo de coef de escorrentia (0.64, 0.53, 0.315) + + + 3 + + + 1.000000000000000 + + + 0.530000000000000 + + + + + + + Coeficiente Epsilon cálculo runoff (0.5, 0.44, 0.38) + + + 3 + + + 0.440000000000000 + + + + + @@ -3947,7 +4128,7 @@ 0 - -328 + -361 433 1918 diff --git a/wmf/wmf.py b/wmf/wmf.py index 838f4fc..e71890a 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -744,6 +744,7 @@ def __ejec_parallel__(ListEjecs, nproc, nodo): Res = P.map(__multiprocess_Warper__, ListEjecs) Lista = [i['Qsim'][nodo][0] for i in Res] P.close() + P.join() return Lista #----------------------------------------------------------------------- From 2134d74043bd8907567ad760a2c0c1eb04973b0a Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 9 Aug 2018 15:17:37 -0500 Subject: [PATCH 073/142] =?UTF-8?q?cambios=20en=20el=20comportamiento=20de?= =?UTF-8?q?=20las=20tablas=20con=20las=20variables=20no=20guardadas=20de?= =?UTF-8?q?=20Nc=20aparecen=20con=20un=20asterisco,=20adem=C3=A1s=20se=20c?= =?UTF-8?q?onfigura=20el=20formato=20que=20se=20manejar=C3=A1=20para=20ges?= =?UTF-8?q?tionar=20las=20vaqriables=20de=20la=20tabla,=20falta=20el=20cod?= =?UTF-8?q?igo=20base=20que=20lo=20sustente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPluginUtils.py | 66 ++- qgisplugin/HydroSEDPlugin_dockwidget.py | 42 +- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 482 +++++++++++-------- 3 files changed, 344 insertions(+), 246 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 2743809..1c66742 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -157,7 +157,8 @@ def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed): 'raster':True, 'basica': False, 'categoria': 'Hidro', - 'var': self.cuenca.CellQmed}}) + 'var': self.cuenca.CellQmed, + 'saved':False}}) self.DicBasinWMF.update({'ETR': {'nombre':'ETR', 'tipo':'float32', @@ -165,7 +166,8 @@ def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed): 'raster':True, 'basica': False, 'categoria': 'Hidro', - 'var': self.cuenca.CellETR}}) + 'var': self.cuenca.CellETR, + 'saved':False}}) Runoff = Rain - self.cuenca.CellETR self.DicBasinWMF.update({'Runoff': {'nombre':'Runoff', @@ -174,7 +176,8 @@ def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed): 'raster':True, 'basica': False, 'categoria': 'Hidro', - 'var': Runoff}}) + 'var': Runoff, + 'saved':False}}) # Guarda el resultado if len(PathQmed)>2: self.cuenca.Save_Net2Map(PathQmed, dxp, umbral, qmed = self.cuenca.CellQmed) @@ -211,8 +214,9 @@ def Basin_Update(self, PathNC): except: print 'variable vieja' VarName = Group.variables[nombre] - #guarda la variable + #guarda la variable y la actualiza en estado a guardada VarName[:] = Var + self.DicBasinNc[l]['saved'] = True self.Nc2Save = [] #Cerrado del archivo nc g.close() @@ -253,7 +257,8 @@ def Basin_LoadBasin(self, PathNC, LoadSim = False, LoadSed = False): 'raster':MapaRaster, 'basica': True, 'categoria': grupoKey, - 'var': g.groups[grupoKey].variables[k][:]}}) + 'var': g.groups[grupoKey].variables[k][:], + 'saved':True}}) self.NumDicBasinNcVariables = self.NumDicBasinNcVariables + 1 self.NumDicBasinNcVariablesBasicas = self.NumDicBasinNcVariablesBasicas + 1 g.close() @@ -306,7 +311,8 @@ def Basin_Raster2WMF(self, VarName, VarPath, VarGroup): 'raster':True, 'basica': False, 'categoria': VarGroup, - 'var': Var}}) + 'var': Var, + 'saved':False}}) return 0 else: return 1 @@ -320,7 +326,8 @@ def Basin_GeoGetAcumSlope(self): 'raster':True, 'basica': False, 'categoria': 'Geomorfo', - 'var': self.cuenca.CellAcum}}) + 'var': self.cuenca.CellAcum, + 'saved':False}}) self.DicBasinWMF.update({'Pendiente': {'nombre':'Pendiente', 'tipo':'float32', @@ -328,7 +335,8 @@ def Basin_GeoGetAcumSlope(self): 'raster':True, 'basica': False, 'categoria': 'Geomorfo', - 'var': self.cuenca.CellSlope}}) + 'var': self.cuenca.CellSlope, + 'saved':False}}) def Basin_GeoGetOrder(self): self.cuenca.GetGeo_StreamOrder(umbral = self.cuenca.umbral) @@ -339,7 +347,8 @@ def Basin_GeoGetOrder(self): 'raster':True, 'basica': False, 'categoria': 'Geomorfo', - 'var': self.cuenca.CellHorton_Hill}}) + 'var': self.cuenca.CellHorton_Hill, + 'saved':False}}) self.DicBasinWMF.update({'Order_channels': {'nombre':'Order_channels', 'tipo':self.cuenca.CellHorton_Stream.dtype.name, @@ -347,7 +356,8 @@ def Basin_GeoGetOrder(self): 'raster':True, 'basica': False, 'categoria': 'Geomorfo', - 'var': self.cuenca.CellHorton_Stream}}) + 'var': self.cuenca.CellHorton_Stream, + 'saved':False}}) def Basin_GeoGetIT(self): IT = self.cuenca.GetGeo_IT() @@ -358,7 +368,8 @@ def Basin_GeoGetIT(self): 'raster':True, 'basica': False, 'categoria': 'Geomorfo', - 'var': IT}}) + 'var': IT, + 'saved':False}}) def Basin_GeoGetChannels(self): #self.cuenca.GetGeo_Cell_Basics() @@ -369,7 +380,8 @@ def Basin_GeoGetChannels(self): 'raster':True, 'basica': False, 'categoria': 'Geomorfo', - 'var': self.cuenca.CellCauce}}) + 'var': self.cuenca.CellCauce, + 'saved':False}}) def Basin_GeoGetDist2Out(self): self.cuenca.GetGeo_WidthFunction(show = False) @@ -380,7 +392,8 @@ def Basin_GeoGetDist2Out(self): 'raster':True, 'basica': False, 'categoria': 'Geomorfo', - 'var': self.cuenca.CellDist2Out}}) + 'var': self.cuenca.CellDist2Out, + 'saved':False}}) def Basin_GeoGetHAND(self): self.cuenca.GetGeo_HAND(umbral = self.cuenca.umbral) @@ -391,7 +404,8 @@ def Basin_GeoGetHAND(self): 'raster':True, 'basica': False, 'categoria': 'Geomorfo', - 'var': self.cuenca.CellHAND}}) + 'var': self.cuenca.CellHAND, + 'saved':False}}) self.DicBasinWMF.update({'HDND': {'nombre':'HDND', 'tipo':self.cuenca.CellHDND.dtype.name, @@ -399,7 +413,8 @@ def Basin_GeoGetHAND(self): 'raster':True, 'basica': False, 'categoria': 'Geomorfo', - 'var': self.cuenca.CellHDND}}) + 'var': self.cuenca.CellHDND, + 'saved':False}}) self.DicBasinWMF.update({'HAND_class': {'nombre':'HAND_class', 'tipo':self.cuenca.CellHAND_class.dtype.name, @@ -407,7 +422,8 @@ def Basin_GeoGetHAND(self): 'raster':True, 'basica': False, 'categoria': 'Geomorfo', - 'var': self.cuenca.CellHAND_class}}) + 'var': self.cuenca.CellHAND_class, + 'saved':False}}) def Basin_GeoGetOCG(self): '''Obtiene el coeficiente y el exponente de OCG (velez, 2001) para la cuenca''' @@ -424,7 +440,8 @@ def Basin_GeoGetOCG(self): 'raster':True, 'basica': False, 'categoria': 'Geomorfo', - 'var': np.copy(Coef)}}) + 'var': np.copy(Coef), + 'saved':False}}) self.DicBasinWMF.update({'OCG_exp': {'nombre':'OCG_exp', 'tipo':Coef.dtype.name, @@ -432,7 +449,8 @@ def Basin_GeoGetOCG(self): 'raster':True, 'basica': False, 'categoria': 'Geomorfo', - 'var': np.copy(Expo)}}) + 'var': np.copy(Expo), + 'saved':False}}) def Basin_GeoGetKubota(self): '''Obtiene el coeficiente de kubota y sivapalan para el flujo de agua en el suelo @@ -455,7 +473,8 @@ def Basin_GeoGetKubota(self): 'raster':True, 'basica': False, 'categoria': 'Geomorfo', - 'var': np.copy(Coef)}}) + 'var': np.copy(Coef), + 'saved': False}}) def Basin_GeoGetRunoff(self, e1, Epsilon): '''Obtiene el coeficiente de escorrentia para carcavas''' @@ -474,7 +493,8 @@ def Basin_GeoGetRunoff(self, e1, Epsilon): 'raster':True, 'basica': False, 'categoria': 'Geomorfo', - 'var': np.copy(Coef)}}) + 'var': np.copy(Coef), + 'saved':False}}) self.DicBasinWMF.update({'Runoff_exp': {'nombre':'Runoff_exp', 'tipo':Expo.dtype.name, @@ -482,7 +502,8 @@ def Basin_GeoGetRunoff(self, e1, Epsilon): 'raster':True, 'basica': False, 'categoria': 'Geomorfo', - 'var': np.copy(Expo)}}) + 'var': np.copy(Expo), + 'saved':False}}) def Basin_GeoGetParameters(self): self.cuenca.GetGeo_Parameters() @@ -555,7 +576,8 @@ def Interpol_GetRainfallAcum(self, path2bin, inicio, fin): 'raster':True, 'basica': False, 'categoria': 'Hidro', - 'var': Vsum}}) + 'var': Vsum, + 'saved':False}}) def Sim_SaveParameters(self, PathNC, ParamName, scalarParam): '''Actualiza el nc con un conjunto de parametros escalares nuevo''' diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 8ea551c..e68a26e 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -22,6 +22,7 @@ """ import os +import numpy as np from PyQt4 import QtGui, uic, QtCore from PyQt4.QtCore import pyqtSignal, QUrl @@ -349,15 +350,15 @@ def clickEventGeoRasterProp(): self.HSutils.Basin_GeoGetChannels() ListaVar.extend(['Channels']) if self.checkBoxOCG.isChecked(): - self.HSutils.Basin_GeoGetOCG() - ListaVar.extend(['OCG_coef']) - if self.checkBoxKubota.isChecked(): - self.HSutils.Basin_GeoGetKubota() - ListaVar.extend(['kubota_coef']) - if self.checkBoxRunoff.isChecked(): - self.HSutils.Basin_GeoGetRunoff() - ListaVar.extend(['Runoff_coef']) - + self.HSutils.Basin_GeoGetOCG() + ListaVar.extend(['OCG_coef']) + if self.checkBoxKubota.isChecked(): + self.HSutils.Basin_GeoGetKubota() + ListaVar.extend(['kubota_coef']) + if self.checkBoxRunoff.isChecked(): + self.HSutils.Basin_GeoGetRunoff() + ListaVar.extend(['Runoff_coef']) + #mensaje de caso de exito self.iface.messageBar().pushInfo(u'HidroSIG:',u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.') #Actualiza la tabla de variables temporales @@ -709,7 +710,10 @@ def handleClickEventButton_Ver_Desde_NC(): #Ejecucion de la transformacion de la variable cuenca a raster selectedItems = self.Tabla_Prop_NC.currentRow () VarName = self.Tabla_Prop_NC.item(selectedItems,0).text() - pathMapa = self.HSutils.Basin_LoadVariableFromDicNC(VarName) + try: + pathMapa = self.HSutils.Basin_LoadVariableFromDicNC(VarName) + except: + pathMapa = self.HSutils.Basin_LoadVariableFromDicNC(VarName[:-1]) #Visualiza flagCargaMapa = self.HSutils.cargar_mapa_raster(pathMapa) if flagCargaMapa: @@ -752,7 +756,7 @@ def handleClickEventButton_WMF2NC(): self.HSutils.DicBasinNc.update({VarName:self.HSutils.DicBasinWMF[VarName]}) self.HSutils.DicBasinNc[VarName]['var'] = np.copy(self.HSutils.DicBasinWMF[VarName]['var']) # Mete la entrada en la tabla de WMF y la saca de la tabla de NC - self.TabNC.NewEntry(self.HSutils.DicBasinWMF[VarName], VarName, self.Tabla_Prop_NC) + self.TabNC.NewEntry(self.HSutils.DicBasinWMF[VarName], VarName, self.Tabla_Prop_NC, New = True) self.Tabla_Prop_WMF.removeRow (selectedItems) self.TabWMF.DelEntry(VarName) self.HSutils.DicBasinWMF.pop(VarName) @@ -935,7 +939,16 @@ def DelEntry(self, KeyToDel): self.TabNames.pop(pos) self.NumRows -= 1 - def NewEntry(self, Dic, DicKey,TabElement): + def SavedEntry(self, TabElement): + '''Busca los elementos de la tabla que terminen con * y se los quita, solo para + que el usuario sepa que han sido guardados''' + #Busca en cada entrada + for i in range(self.NumRows): + Nombre = TabElement.ItemAt(i,0).text() + if Nombre[-1] == '*': + TabElement.setItem(i,0, QTableWidgetItem(Nombre[:-1])) + + def NewEntry(self, Dic, DicKey,TabElement, New = False): '''Actualiza la lista de las variables en una tabla''' #Busca si ese nombre ya se encuentra en la tabla try: @@ -948,7 +961,10 @@ def NewEntry(self, Dic, DicKey,TabElement): self.TabNames.append(DicKey) suma = 1 #for keyParam in Dic: - TabElement.setItem (pos, 0, QTableWidgetItem (Dic["nombre"])) + if New: + TabElement.setItem (pos, 0, QTableWidgetItem (Dic["nombre"]+'*')) + else: + TabElement.setItem (pos, 0, QTableWidgetItem (Dic["nombre"])) TabElement.setItem (pos, 1, QTableWidgetItem (Dic["tipo"])) TabElement.setItem (pos, 2, QTableWidgetItem (str (Dic["shape"]))) TabElement.setItem (pos, 3, QTableWidgetItem (Dic["categoria"])) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 1dfd586..e453e31 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -294,7 +294,7 @@ 0 - -981 + -829 443 2018 @@ -1070,7 +1070,7 @@ 0 1160 421 - 151 + 161 @@ -1082,237 +1082,298 @@ 0 20 421 - 121 + 138 - + - - - - - - - - - - - - - 50 - 16777215 - - - - Ejecutar la función de trazado de corriente. - - - Ejecutar la función de trazado de corriente. - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - + + + + + Celdas + + + + + + + Agrega la variable por canales + + + Canales + + + + + + + Agrega la variable por laderas + + + Laderas + + + + + + + Tipo de conversión usada para agregar (promedio) + + + + - - + + - 50 - 16777215 + 16777215 + 20 - - - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - - - - - - - Actualizar + Objetivo - - - - Capa a ver de la variable, aplica solo para variables 2D - - + + + + + + + + + 20 + 16777215 + + + + Aplicar la conversión sobre una variable del nc + + + + + + + + + + + 16777215 + 70 + + + + Selección de la variable del Nc sobre la cual se aplicará la conversión. + + + + + + + + + + + + 20 + 16777215 + + + + Aplicar la conversión y escribir una variable nueva + + + + + + + + + + + 16777215 + 70 + + + + Nombre de la variable que contiene la conversión + + + + + + + Categoría de la nueva variable obtenida + + + + + + + + + + + + 50 + 16777215 + + + + Capa a ver (o editar) de la variable Nc + + + + + + + + 50 + 16777215 + + + + Visualizar una variable del Nc + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + false + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Qt::DefaultContextMenu + + + Convertir variable a red hídrica (promedia celdas del tramo). + + + Convertir variable a red hídrica (promedia celdas del tramo). + + + + + + + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico + + + + 16 + 16 + + + + + + + + + 50 + 16777215 + + + + Ejecutar la función de trazado de corriente. + + + Convertir variables. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + 50 + 16777215 + + + + Actualizar variables del Nc. + + + + + + + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png + + + + + + - - Tipo conversión + + + 16777215 + 20 + - - - - - Método + Conversión - - - - 230 - 1350 - 99 - 27 - - - - PushButton - - - - - - 120 - 1420 - 61 - 27 - - - - - - - 0 - 1420 - 117 - 22 - - - - Canales - - - - - - 0 - 1440 - 117 - 22 - - - - Laderas - - - - - - 0 - 1400 - 117 - 21 - - - - Tipo conversión - - - - - - 120 - 1400 - 61 - 16 - - - - Método - - - - - - 220 - 1420 - 101 - 27 - - - - - - - 220 - 1400 - 61 - 16 - - - - Objetivo - - - - - - 220 - 1450 - 101 - 27 - - - - - - - 330 - 1420 - 41 - 27 - - - - Capa a ver de la variable, aplica solo para variables 2D - - - - - - 200 - 1420 - 21 - 22 - - - - - - - - - - 200 - 1450 - 21 - 22 - - - - - - @@ -5312,7 +5373,6 @@ - From 2ac81e0a5e13ef026fc63528bcac2903f5bc6a46 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 13 Aug 2018 10:43:12 -0500 Subject: [PATCH 074/142] corrige la barra del trazador para que baje harto --- qgisplugin/HydroSEDPluginUtils.py | 4 ++-- qgisplugin/HydroSEDPlugin_dockwidget.py | 5 ++++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 6 +++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 1c66742..abca37f 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -208,11 +208,11 @@ def Basin_Update(self, PathNC): Var = np.copy(self.DicBasinNc[l]['var']) #Trata de meter la variable como algo no existente try: - print 'variable nueva' + #print 'variable nueva' VarName = Group.createVariable(nombre,tipo,('ncell',),zlib=True) #si ya existe la variable la sobre escribe except: - print 'variable vieja' + #print 'variable vieja' VarName = Group.variables[nombre] #guarda la variable y la actualiza en estado a guardada VarName[:] = Var diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index e68a26e..365160e 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -766,6 +766,7 @@ def clickEventBasinUpdateNC(): '''Actualiza el archivo .nc de la cuenca con las variables cargadas en la TablaNC''' RutaNC = self.lineEditRutaCuenca.text().strip() self.HSutils.Basin_Update(RutaNC) + self.TabNC.SavedEntry(self.Tabla_Prop_NC) def setupLineEditButtonOpenShapeFileDialog (lineEditHolder, fileDialogHolder): '''Hace que cuando se busquen shapes solo se encuetren formatos vectoriales''' @@ -944,7 +945,9 @@ def SavedEntry(self, TabElement): que el usuario sepa que han sido guardados''' #Busca en cada entrada for i in range(self.NumRows): - Nombre = TabElement.ItemAt(i,0).text() + Nombre = TabElement.itemAt(i,0).text() + print Nombre + print i if Nombre[-1] == '*': TabElement.setItem(i,0, QTableWidgetItem(Nombre[:-1])) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index e453e31..f223424 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -250,7 +250,7 @@ - 0 + 1 @@ -1420,7 +1420,7 @@ 0 0 443 - 918 + 2018 @@ -1441,7 +1441,7 @@ 250 - 900 + 2000 From a41fbd8e3a6ca8bb1ee0bb9d1c6d7c72f3af8d7d Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 13 Aug 2018 17:30:33 -0500 Subject: [PATCH 075/142] cambios menores --- qgisplugin/HydroSEDPlugin_dockwidget.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 365160e..bcc471f 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -24,7 +24,7 @@ import os import numpy as np -from PyQt4 import QtGui, uic, QtCore +from PyQt4 import QtGui, uic, QtCore, Qt from PyQt4.QtCore import pyqtSignal, QUrl from PyQt4.QtWebKit import QWebView @@ -945,11 +945,11 @@ def SavedEntry(self, TabElement): que el usuario sepa que han sido guardados''' #Busca en cada entrada for i in range(self.NumRows): - Nombre = TabElement.itemAt(i,0).text() - print Nombre - print i + Nombre = TabElement.takeItem(i,0).text() if Nombre[-1] == '*': TabElement.setItem(i,0, QTableWidgetItem(Nombre[:-1])) + else: + TabElement.setItem(i,0, QTableWidgetItem(Nombre)) def NewEntry(self, Dic, DicKey,TabElement, New = False): '''Actualiza la lista de las variables en una tabla''' From 8fd4849672b13d7c7f73068853c6b3b7bf1ea906 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 14 Aug 2018 09:48:59 -0500 Subject: [PATCH 076/142] Tabla Nc permite mover variables con WMF y borrar variables, eso si, las uqe tengan el * de que no han sido guardadas en el proyecto --- qgisplugin/HydroSEDPlugin_dockwidget.py | 105 ++++++++++++------- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 42 +++++++- 2 files changed, 107 insertions(+), 40 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index bcc471f..f83bebc 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -469,12 +469,14 @@ def clickEventSelectorRaster(): #Funcion para pasar variable raster a WMF def handleClickConnectRaster2WMF(): #Chequeos de variables - #if len(self.NameRaster2WMF.text())<2: - # self.iface.messageBar().pushError (u'Hydro-SIG:', u'Debe ingresar un nombre para el mapa raster a convertir.') - # return 1 - #if len(self.PathRaster2WMF.text())<2: - # self.iface.messageBar().pushError (u'Hydro-SIG:', u'Debe seleccionar un mapa raster para ser convertido a la cuenca.') - # return 1 + if len(self.NameRaster2WMF.text())<2: + self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'Debe ingresar un nombre para el mapa raster a convertir.', + level=QgsMessageBar.WARNING, duration=5) + return 1 + if len(self.PathRaster2WMF.text())<2: + self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'Debe seleccionar un mapa raster para ser convertido a la cuenca.', + level=QgsMessageBar.WARNING, duration=5) + return 1 #Parametros para la conversion Nombre = self.NameRaster2WMF.text() PathRaster = self.PathRaster2WMF.text() @@ -694,11 +696,20 @@ def handleClickEventButton_Eliminar_Desde_NC (): #Selecciona el item y su nombre selectedItems = self.Tabla_Prop_NC.currentRow () ItemName = str(self.Tabla_Prop_NC.item(selectedItems,0).text()) - #Remueve de la tabla visible y de los demas elementos. - self.Tabla_Prop_NC.removeRow (selectedItems) - self.TabNC.DelEntry(ItemName) - self.HSutils.DicBasinNc.pop(ItemName) - self.HSutils.Nc2Erase.append(ItemName) + #Revisa que todavia no este guardado + if ItemName[-1] == '*' and self.HSutils.DicBasinNc[ItemName[:-1]]['saved'] is False: + ItemName = ItemName[:-1] + #Remueve de la tabla visible y de los demas elementos. + self.Tabla_Prop_NC.removeRow (selectedItems) + self.TabNC.DelEntry(ItemName) + self.HSutils.DicBasinNc.pop(ItemName) + #self.HSutils.Nc2Erase.append(ItemName) + #Mensaje de exito + self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'La variable '+ItemName + ' ha sido borrada') + else: + #Mensaje de no exito + self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'La variable '+ItemName[:-1]+' no puede ser borrada del Nc (ya esta guardada)', + level=QgsMessageBar.WARNING, duration=5) def handleClickEventButton_Actualizar_WMF_Desde_NC (): rows = sorted (set (index.row () for index in self.Tabla_Prop_NC.selectedIndexes ())) @@ -719,7 +730,8 @@ def handleClickEventButton_Ver_Desde_NC(): if flagCargaMapa: self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'Se cargó la variable de forma exitosa') else: - self.iface.messageBar().pushError (u'Hydro-SIG:', u'No fue posible cargar la variable') + self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'No fue posible cargar la variable', + level=QgsMessageBar.WARNING, duration=5) def handleClickEventButton_Ver_Desde_WMF(): '''Visualiza una de las variables de la cuenca en Qgis''' @@ -732,20 +744,32 @@ def handleClickEventButton_Ver_Desde_WMF(): if flagCargaMapa: self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'Se cargó la variable de forma exitosa') else: - self.iface.messageBar().pushError (u'Hydro-SIG:', u'No fue posible cargar la variable') + self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'No fue posible cargar la variable', + level=QgsMessageBar.WARNING, duration=5) def handleClickEventButton_NC2WMF(): '''Mueve variables de NC a WMF en la tabla.''' # Elemento seleccionado selectedItems = self.Tabla_Prop_NC.currentRow () VarName = self.Tabla_Prop_NC.item(selectedItems,0).text() - # Copia la entrada a WMF y la saca de NC - self.HSutils.DicBasinWMF.update({VarName:self.HSutils.DicBasinNc[VarName]}) - # Mete la entrada en la tabla de WMF y la saca de la tabla de NC - self.TabWMF.NewEntry(self.HSutils.DicBasinNc[VarName], VarName, self.Tabla_Prop_WMF) - self.Tabla_Prop_NC.removeRow (selectedItems) - self.TabNC.DelEntry(VarName) - self.HSutils.DicBasinNc.pop(VarName) + #Verifica que la variable ahun no este guardada en el Nc + print VarName.strip() + if VarName[-1] == '*': + # Copia la entrada a WMF y la saca de NC + VarName = VarName[:-1] + self.HSutils.DicBasinWMF.update({VarName:self.HSutils.DicBasinNc[VarName]}) + # Mete la entrada en la tabla de WMF y la saca de la tabla de NC + self.TabWMF.NewEntry(self.HSutils.DicBasinNc[VarName], VarName, self.Tabla_Prop_WMF) + self.Tabla_Prop_NC.removeRow (selectedItems) + self.TabNC.DelEntry(VarName) + self.HSutils.DicBasinNc.pop(VarName) + #Mensaje de exito + self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'La variable '+VarName+' ha sido movida de NC a WMF') + else: + #Mensaje de no exito + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + u'La variable '+VarName+' no ha podido ser movida a WMF, ya se encuentra guardada en NC', + level=QgsMessageBar.WARNING, duration=5) def handleClickEventButton_WMF2NC(): '''Mueve variables de NC a WMF en la tabla.''' @@ -760,7 +784,9 @@ def handleClickEventButton_WMF2NC(): self.Tabla_Prop_WMF.removeRow (selectedItems) self.TabWMF.DelEntry(VarName) self.HSutils.DicBasinWMF.pop(VarName) - self.HSutils.Nc2Save.append(VarName) + self.HSutils.Nc2Save.append(VarName) + # Mensaje de exito + self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'La variable '+VarName+' ha sido movida de WMF a NC') def clickEventBasinUpdateNC(): '''Actualiza el archivo .nc de la cuenca con las variables cargadas en la TablaNC''' @@ -802,7 +828,9 @@ def clickEventVisualizarMapaDEM (): if flagCargaMapaDEM: self.iface.messageBar().pushInfo (u'Hydro-SED', u'Se cargó el mapa MDE de forma exitosa') else: - self.iface.messageBar().pushError (u'Hydro-SED', u'No fue posible cargar el mapa MDE. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.') + self.iface.messageBar().pushMessage (u'Hydro-SED', + u'No fue posible cargar el mapa MDE. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.', + level=QgsMessageBar.WARNING, duration=5) def clickEventVisualizarMapaDIR (): pathMapaDIR = self.lineEditMapaDIR.text ().strip () @@ -810,7 +838,9 @@ def clickEventVisualizarMapaDIR (): if flagCargaMapaDIR: self.iface.messageBar().pushInfo (u'Hydro-SED', u'Se cargó el mapa DIR de forma exitosa') else: - self.iface.messageBar().pushError (u'Hydro-SED', u'No fue posible cargar el mapa DIR. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.') + self.iface.messageBar().pushMessage (u'Hydro-SED', + u'No fue posible cargar el mapa DIR. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.', + level=QgsMessageBar.WARNING, duration=5) def clickEventCargarWMFMapaDEM (): '''Carga el mapa dDM base para WMF''' @@ -820,7 +850,9 @@ def clickEventCargarWMFMapaDEM (): if flagCargaMapaDEM_WMF: self.iface.messageBar().pushInfo (u'Hydro-SED', u'Se cargó el mapa MDE al WMF de forma exitosa') else: - self.iface.messageBar().pushError (u'Hydro-SED', u'No fue posible cargar el mapa MDE al WMF. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.') + self.iface.messageBar().pushMessage (u'Hydro-SED', + u'No fue posible cargar el mapa MDE al WMF. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.', + level=QgsMessageBar.WARNING, duration=5) #Pone el nombre del codigo EPSG en el dialogo. self.LineEditEPSG.setText(self.EPSG) t = '%.1f' % self.noData @@ -834,7 +866,9 @@ def clickEventCargarWMFMapaDIR(): if flagCargaMapaDIR_WMF: self.iface.messageBar().pushInfo (u'Hydro-SED', u'Se cargó el mapa DIR al WMF de forma exitosa') else: - self.iface.messageBar().pushError (u'Hydro-SED', u'No fue posible cargar el mapa DIR al WMF. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.') + self.iface.messageBar().pushMessage (u'Hydro-SED', + u'No fue posible cargar el mapa DIR al WMF. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.', + level=QgsMessageBar.WARNING, duration=5) def clickEventSelectorBinarioNC (): setupLineEditButtonOpenFileDialog (self.lineEditSelectorBinarioNC, QFileDialog) @@ -910,6 +944,7 @@ def set_dxplano(): self.Button_Eliminar_Desde_WMF.clicked.connect(handleClickEventButton_Eliminar_Desde_WMF) self.Tabla_Prop_NC.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) self.Tabla_Prop_NC.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) + self.Button_Eliminar_Desde_NC.clicked.connect(handleClickEventButton_Eliminar_Desde_NC) #Botones de visualizacion de variables de NC self.Tabla_Prop_NC.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) self.Tabla_Prop_NC.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) @@ -919,7 +954,7 @@ def set_dxplano(): self.Tabla_Prop_WMF.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self.Button_Visualizar_Desde_WMF.clicked.connect(handleClickEventButton_Ver_Desde_WMF) #Botones movimiento variables NC a WMF y de WMF a NC - #self.Button_NC2WMF.clicked.connect(handleClickEventButton_NC2WMF) + self.Button_NC2WMF.clicked.connect(handleClickEventButton_NC2WMF) self.Button_WMF2NC.clicked.connect(handleClickEventButton_WMF2NC) #Boton para actualizar los archivos que se encuentran guardados en un netCDF self.Button_Update_NC.clicked.connect(clickEventBasinUpdateNC) @@ -941,15 +976,15 @@ def DelEntry(self, KeyToDel): self.NumRows -= 1 def SavedEntry(self, TabElement): - '''Busca los elementos de la tabla que terminen con * y se los quita, solo para - que el usuario sepa que han sido guardados''' - #Busca en cada entrada - for i in range(self.NumRows): - Nombre = TabElement.takeItem(i,0).text() - if Nombre[-1] == '*': - TabElement.setItem(i,0, QTableWidgetItem(Nombre[:-1])) - else: - TabElement.setItem(i,0, QTableWidgetItem(Nombre)) + '''Busca los elementos de la tabla que terminen con * y se los quita, solo para + que el usuario sepa que han sido guardados''' + #Busca en cada entrada + for i in range(self.NumRows): + Nombre = TabElement.takeItem(i,0).text() + if Nombre[-1] == '*': + TabElement.setItem(i,0, QTableWidgetItem(Nombre[:-1])) + else: + TabElement.setItem(i,0, QTableWidgetItem(Nombre)) def NewEntry(self, Dic, DicKey,TabElement, New = False): '''Actualiza la lista de las variables en una tabla''' diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index f223424..6600ad2 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -250,7 +250,7 @@ - 1 + 0 @@ -294,7 +294,7 @@ 0 - -829 + -747 443 2018 @@ -1012,6 +1012,29 @@ + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png:/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png + + + @@ -1332,7 +1355,7 @@ - + 50 @@ -1418,7 +1441,7 @@ 0 - 0 + -255 443 2018 @@ -1927,6 +1950,9 @@ + + false + Obtiene automaticamente los nodos topograficos. @@ -1940,6 +1966,9 @@ + + false + Obtiene parametros geomorfologicos de la cuenca. @@ -1950,6 +1979,9 @@ + + false + Obtiene el ancho del canal en cada tramo. @@ -4189,7 +4221,7 @@ 0 - -361 + -226 433 1918 From ab9e845a307fc4dc4cf7a851c7e42d01f33a960a Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 14 Aug 2018 10:12:56 -0500 Subject: [PATCH 077/142] Boton de ver de NC ya permite ver capas de variables con 2 dimensiones --- qgisplugin/HydroSEDPluginUtils.py | 17 +++++++++++++---- qgisplugin/HydroSEDPlugin_dockwidget.py | 17 ++++++++++++----- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 7 +++++-- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index abca37f..425beae 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -277,13 +277,22 @@ def Basin_LoadBasinNetwork(self, PathNetwork): # Guarda los shapes de divisoria y de red hidrica. self.cuenca.Save_Net2Map(PathNetwork, wmf.cu.dxp, self.cuenca.umbral) - def Basin_LoadVariableFromDicNC(self, VarName): + def Basin_LoadVariableFromDicNC(self, VarName, capa = None): '''Toma una variable del diccionario de variables basicas y la carga a Qgis''' - #Transforma a un raster - rutaSalida = '/tmp/HydroSED/'+VarName+'.tiff' - self.cuenca.Transform_Basin2Map(self.DicBasinNc[VarName]['var'], + #Variable de acuerdo a si hay capa o no + print capa + if capa is None: + Variable = np.copy(self.DicBasinNc[VarName]['var']) + rutaSalida = '/tmp/HydroSED/'+VarName+'.tiff' + else: + Variable = np.copy(self.DicBasinNc[VarName]['var'][capa]) + rutaSalida = '/tmp/HydroSED/'+VarName+'_'+str(capa+1)+'.tiff' + print Variable + #Conversion + self.cuenca.Transform_Basin2Map(Variable, ruta = rutaSalida, EPSG = self.cuenca.epsg) + #Devuelve la ruta temporal donde esta el mapa raster con al variable return rutaSalida def Basin_LoadVariableFromDicWMF(self,VarName): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index f83bebc..976c30e 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -718,13 +718,18 @@ def handleClickEventButton_Actualizar_WMF_Desde_NC (): def handleClickEventButton_Ver_Desde_NC(): '''Visualiza una de las variables de la cuenca en Qgis''' - #Ejecucion de la transformacion de la variable cuenca a raster + #Nombre de la variable a observar selectedItems = self.Tabla_Prop_NC.currentRow () VarName = self.Tabla_Prop_NC.item(selectedItems,0).text() - try: - pathMapa = self.HSutils.Basin_LoadVariableFromDicNC(VarName) - except: - pathMapa = self.HSutils.Basin_LoadVariableFromDicNC(VarName[:-1]) + if VarName[-1] == '*': VarName = varName[:-1] + #Capa de la variable + if self.SpinBoxLayer2View.value() == 0: + Capa = None + else: + Capa = self.SpinBoxLayer2View.value() - 1 + #Ejecuta la conversion a mapa raster + print Capa + pathMapa = self.HSutils.Basin_LoadVariableFromDicNC(VarName, capa = Capa) #Visualiza flagCargaMapa = self.HSutils.cargar_mapa_raster(pathMapa) if flagCargaMapa: @@ -732,6 +737,8 @@ def handleClickEventButton_Ver_Desde_NC(): else: self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'No fue posible cargar la variable', level=QgsMessageBar.WARNING, duration=5) + #Hace que el spinbox vuelva a lo normal + self.SpinBoxLayer2View.setValue(0) def handleClickEventButton_Ver_Desde_WMF(): '''Visualiza una de las variables de la cuenca en Qgis''' diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 6600ad2..b60c881 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -1238,7 +1238,7 @@ - + 50 @@ -1246,7 +1246,10 @@ - Capa a ver (o editar) de la variable Nc + Capa a ver (o editar) de la variable Nc. + + + 5 From 9b34e5dc6044e4908740ca325aab0cb905cac4f0 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 14 Aug 2018 11:33:38 -0500 Subject: [PATCH 078/142] La herramienta para convertir mapas rasters ahora admite poner un valor constante --- qgisplugin/HydroSEDPluginUtils.py | 24 +++++++++++++------ qgisplugin/HydroSEDPlugin_dockwidget.py | 25 +++++++++++++------- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 4 ++-- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 425beae..0ec10a6 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -304,15 +304,25 @@ def Basin_LoadVariableFromDicWMF(self,VarName): EPSG = self.cuenca.epsg) return rutaSalida - def Basin_Raster2WMF(self, VarName, VarPath, VarGroup): + def Basin_Raster2WMF(self, VarName, VarPath, VarGroup, PathOrValue = 'Path', Value = None): '''toma una ruta y convierte un mapa raster a cuenca para luego ponerlo en el diccionario de WMF''' - #Lee la variable - Var, prop, epsg = wmf.read_map_raster(VarPath) - if epsg == self.cuenca.epsg: - #Convierte a cuenca - Var = self.cuenca.Transform_Map2Basin(Var, prop) - #Actualiza el diccionario de WMF + Convierte = False + #si es un mapa raster + if PathOrValue == 'Path': + Var, prop, epsg = wmf.read_map_raster(VarPath) + if epsg == self.cuenca.epsg: + #Convierte a cuenca + Var = self.cuenca.Transform_Map2Basin(Var, prop) + Convierte = True + else: + return 1 + #Si es una constante + else: + Var = np.ones(self.cuenca.ncells)*Value + Convierte = True + #Actualiza el diccionario de WMF + if Convierte: self.DicBasinWMF.update({VarName: {'nombre':VarName, 'tipo':Var.dtype.name, diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 976c30e..9610e03 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -469,20 +469,30 @@ def clickEventSelectorRaster(): #Funcion para pasar variable raster a WMF def handleClickConnectRaster2WMF(): #Chequeos de variables + Valor = -9 if len(self.NameRaster2WMF.text())<2: self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'Debe ingresar un nombre para el mapa raster a convertir.', level=QgsMessageBar.WARNING, duration=5) - return 1 - if len(self.PathRaster2WMF.text())<2: - self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'Debe seleccionar un mapa raster para ser convertido a la cuenca.', - level=QgsMessageBar.WARNING, duration=5) - return 1 + return 1 + if len(self.PathRaster2WMF.text())<5: + try: + Valor = float(self.PathRaster2WMF.text()) + PathRaster = 'noMapa' + PathOrValue = 'Value' + print Valor + except: + self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'Debe seleccionar un mapa raster para ser convertido a la cuenca.', + level=QgsMessageBar.WARNING, duration=5) + return 1 + else: + PathRaster = self.PathRaster2WMF.text() + PathOrValue = 'Path' #Parametros para la conversion Nombre = self.NameRaster2WMF.text() - PathRaster = self.PathRaster2WMF.text() Grupo = self.ComboBoxRaster2WMF.currentText() #Conversion, convierte la variable y actualiza el diccionario. - Retorno = self.HSutils.Basin_Raster2WMF(Nombre, PathRaster, Grupo) + Retorno = self.HSutils.Basin_Raster2WMF(Nombre, PathRaster, Grupo, PathOrValue, Valor) + print Retorno self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[Nombre],Nombre, self.Tabla_Prop_WMF) if Retorno == 0: self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'El mapa raster ha ingresado a WMF.') @@ -728,7 +738,6 @@ def handleClickEventButton_Ver_Desde_NC(): else: Capa = self.SpinBoxLayer2View.value() - 1 #Ejecuta la conversion a mapa raster - print Capa pathMapa = self.HSutils.Basin_LoadVariableFromDicNC(VarName, capa = Capa) #Visualiza flagCargaMapa = self.HSutils.cargar_mapa_raster(pathMapa) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index b60c881..f0b95d2 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -294,7 +294,7 @@ 0 - -747 + -137 443 2018 @@ -739,7 +739,7 @@ - true + false From 87d8f73e66581269db981be7d29c7345f88b48a5 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 14 Aug 2018 13:07:57 -0500 Subject: [PATCH 079/142] se agregan las listas a los combobox del gestor de variables nc. Falta implementar el montaje de variables de modelacion --- qgisplugin/HydroSEDPlugin_dockwidget.py | 18 +++++ qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 72 +++++++------------- 2 files changed, 44 insertions(+), 46 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 9610e03..5ad7cfe 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -64,6 +64,7 @@ def __init__(self, iface = None, parent=None): #self.setupUIButtonEvents () self.setupRainfallInterpolation() self.setupSimulation() + self.setupNcVariables() self.TablaFila_WMF = 0 self.TablaFila_NC = 0 @@ -186,8 +187,11 @@ def clickEventBasin2WMF(): #Cargado de la cuenca self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), Simhidro, SimSed) self.TableStart() + #Actualiza tabla de Nc y comboBox + self.VarFromNC.clear() for k in self.HSutils.DicBasinNc.keys(): self.TabNC.NewEntry(self.HSutils.DicBasinNc[k],k, self.Tabla_Prop_NC) + self.VarFromNC.addItem(k) Area, self.EPSG, dxp, self.noData, self.umbral = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip()) #print self.umbral #Habilita los botones de visualizacion de red hidrica y divisoria @@ -501,6 +505,20 @@ def handleClickConnectRaster2WMF(): self.ButtonPathRaster2WMF.clicked.connect(clickEventSelectorMapaRaster) self.Button_Raster2WMF.clicked.connect(handleClickConnectRaster2WMF) + def setupNcVariables(self): + '''Conjunto de herramientas para gestionar las variables del NC''' + + #Llena de datos los combobox + ListaMetodos = ['No metodo','media','min','P10','P25','P50','P75','P90','max'] + map(self.ComboMethod4Conversion.addItem,ListaMetodos) + #Lista de grupos posibles para una variable + ListaGrupos = ['base','Geomorfo','SimHidro','Hidro'] + map(self.ComboBoxNewNcVarGroup.addItem, ListaGrupos) + #Lista de unidades de conversion + ListaUnidades = ['Celdas','Laderas','Canales'] + map(self.ComboConversionUnits.addItem, ListaUnidades) + # + def setupRainfallInterpolation(self): '''Conjunto de herramientas dispuestas para interpolar campos de precipitacion''' diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index f0b95d2..c21e1b4 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -294,7 +294,7 @@ 0 - -137 + -887 443 2018 @@ -1112,34 +1112,46 @@ - + + + + 16777215 + 20 + + - Celdas + Unidades - - - Agrega la variable por canales + + + Tipo de conversión usada para agregar (promedio) - - Canales + + Tipo de conversión usada para agregar (promedio) - - - Agrega la variable por laderas + + + + 16777215 + 20 + - Laderas + Método + + Tipo de conversión usada para agregar (promedio) + Tipo de conversión usada para agregar (promedio) @@ -1164,22 +1176,6 @@ - - - - - 20 - 16777215 - - - - Aplicar la conversión sobre una variable del nc - - - - - - @@ -1197,22 +1193,6 @@ - - - - - 20 - 16777215 - - - - Aplicar la conversión y escribir una variable nueva - - - - - - @@ -1227,7 +1207,7 @@ - + Categoría de la nueva variable obtenida @@ -4224,7 +4204,7 @@ 0 - -226 + 0 433 1918 From 96c907e73a6dfeed24a1e46e570b00dcfab2cee7 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 14 Aug 2018 16:08:27 -0500 Subject: [PATCH 080/142] Balance hidrico ya recibe mapas raster para el balance --- qgisplugin/HydroSEDPluginUtils.py | 9 +++++--- qgisplugin/HydroSEDPlugin_dockwidget.py | 29 +++++++++++++++++++++---- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 0ec10a6..8609b06 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -145,8 +145,11 @@ def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed): try: Rain = float(PathRain) except: - Rain, prop = wmf.read_map_raster(PathRain) - Rain = self.cuenca.Transform_Map2Basin(Rain, prop) + Rain, prop, epsg = wmf.read_map_raster(PathRain) + if epsg == self.cuenca.epsg: + Rain = self.cuenca.Transform_Map2Basin(Rain, prop) + else: + return 1, 1 #Realiza el balance self.cuenca.GetQ_Balance(Rain, Tipo_ETR = PathETR) #Actualiza el diccionario de WMF @@ -182,7 +185,7 @@ def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed): if len(PathQmed)>2: self.cuenca.Save_Net2Map(PathQmed, dxp, umbral, qmed = self.cuenca.CellQmed) #Retorna el resultado a la salida - return self.cuenca.CellQmed[-1] + return 0,self.cuenca.CellQmed[-1] def Basin_Update(self, PathNC): '''Actualiza el archivo nc de la cuenca con las variables agregadas o borradas de la misma''' diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 5ad7cfe..f4eb871 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -422,7 +422,7 @@ def hadleClickEventEjecutarBalance(): if self.RadioBalance_ETR_Turc.isChecked(): TipoETR = 1 #Invoca la funcion - QSalida = self.HSutils.hidologia_balance(self.spinBox_dxPlano.value(), + Retorno, QSalida = self.HSutils.hidologia_balance(self.spinBox_dxPlano.value(), self.spinBoxUmbralRed.value(), self.PathInHydro_Rain.text(), TipoETR, @@ -431,7 +431,12 @@ def hadleClickEventEjecutarBalance(): textoCaudal = '%.3f' % QSalida self.ShowResultQmed.setText(textoCaudal) #Mensaje de exito - self.iface.messageBar().pushInfo(u'HidroSIG:',u'Balance realizado: variables Caudal, ETR y Runoff cargadas a Tabla de propiedades WMF.') + if Retorno == 0: + self.iface.messageBar().pushInfo(u'HidroSIG:',u'Balance realizado: variables Caudal, ETR y Runoff cargadas a Tabla de propiedades WMF.') + else: + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + u'No se ha logrado realizar el balance hidrológico en la cuenca', + level=QgsMessageBar.WARNING, duration=5) #Habilita botones de visualizacion de variables if len(self.PathOutHydro_Qmed.text()) > 2: self.Button_HidroViewQmed.setEnabled(True) @@ -496,10 +501,14 @@ def handleClickConnectRaster2WMF(): Grupo = self.ComboBoxRaster2WMF.currentText() #Conversion, convierte la variable y actualiza el diccionario. Retorno = self.HSutils.Basin_Raster2WMF(Nombre, PathRaster, Grupo, PathOrValue, Valor) - print Retorno + print QmedValue self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[Nombre],Nombre, self.Tabla_Prop_WMF) if Retorno == 0: self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'El mapa raster ha ingresado a WMF.') + else: + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + u'El mapa raster no ha ingresado a WMF.', + level=QgsMessageBar.WARNING, duration=5) #Habilita botones. self.ButtonPathRaster2WMF.clicked.connect(clickEventSelectorMapaRaster) @@ -517,8 +526,20 @@ def setupNcVariables(self): #Lista de unidades de conversion ListaUnidades = ['Celdas','Laderas','Canales'] map(self.ComboConversionUnits.addItem, ListaUnidades) - # + + def clickEventConvertVariable2NC(): + '''Convierte una variable clickeada a la tabla de NC con una transformacion''' + selectedItems = self.Tabla_Prop_WMF.currentRow () + VarName1 = self.Tabla_Prop_WMF.item(selectedItems,0).text() + print VarName1 + + selectedItems = self.Tabla_Prop_NC.currentRow () + VarName1 = self.Tabla_Prop_NC.item(selectedItems,0).text() + print VarName1 + + + self.Button_EditNcVariable.clicked.connect(clickEventConvertVariable2NC) def setupRainfallInterpolation(self): '''Conjunto de herramientas dispuestas para interpolar campos de precipitacion''' From 25d38d7aa86c3ee70cbbd86e379666e7ff43a71b Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 14 Aug 2018 16:34:11 -0500 Subject: [PATCH 081/142] Corrige bug en el interpolador que no deja interpolar si el campo de excel no es un string en el nombre de las columnas --- qgisplugin/HydroSEDPluginUtils.py | 3 +-- qgisplugin/HydroSEDPlugin_dockwidget.py | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 8609b06..aaba302 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -562,10 +562,9 @@ def Interpol_GetInterpolation(self, Path2Shp,Campo2Read,fi,ff,fd,expo, PathOutpu tr = '%dS'%fd #Obtiene los ids de excel idExcel = self.InterpolData.columns.values.tolist() - idExcel = [i.encode() for i in idExcel] #Lee el shp con los puntos y los ids xy,idShape = wmf.read_map_points(Path2Shp,[Campo2Read.encode()]) - idShape = idShape[Campo2Read].astype(int).astype(str).tolist() + idShape = idShape[Campo2Read].astype(int).tolist() #Organiza los datos para interpolar xyNew = [] ColGood = [] diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index f4eb871..5268933 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -501,7 +501,6 @@ def handleClickConnectRaster2WMF(): Grupo = self.ComboBoxRaster2WMF.currentText() #Conversion, convierte la variable y actualiza el diccionario. Retorno = self.HSutils.Basin_Raster2WMF(Nombre, PathRaster, Grupo, PathOrValue, Valor) - print QmedValue self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[Nombre],Nombre, self.Tabla_Prop_WMF) if Retorno == 0: self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'El mapa raster ha ingresado a WMF.') From 88c0dccb87a8d8f175b5a8bd4aab21b47aad5473 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 14 Aug 2018 17:26:48 -0500 Subject: [PATCH 082/142] nueva clase plots geomorfologicos, ahora las cosas temporales van por carpetas, falta terminar de arreglar bug que nace de este cambio --- qgisplugin/HydroSEDPlots.py | 419 +++++++++-------- qgisplugin/HydroSEDPlugin.py | 5 + qgisplugin/HydroSEDPluginUtils.py | 7 +- qgisplugin/HydroSEDPlugin_dockwidget.py | 30 +- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 465 +++++++++++++------ 5 files changed, 569 insertions(+), 357 deletions(-) diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py index 1db1cb5..b68ff53 100644 --- a/qgisplugin/HydroSEDPlots.py +++ b/qgisplugin/HydroSEDPlots.py @@ -5,209 +5,216 @@ class PlotRainfall(): - def __init__(self, pathRain): - self.path_rainBin, self.path_rainHdr = wmf.__Add_hdr_bin_2route__(pathRain) - self.rainData = wmf.read_rain_struct(self.path_rainHdr) - - def Plot_Rainfall(self, pathFigure): - '''Hace el plot de la serie de tiempo de lluvia e incluye en esta toda la info necesaria''' - #obtiene los records - Rs = self.rainData.copy() - Records = ['Record: %d'%i for i in Rs[' Record'].values] - #Datos de lluvia - trace1 = go.Scatter( - x = Rs.index.to_pydatetime(), - y = Rs[' Lluvia'].values, - text = Records, - name = 'Lluvia [mm]', - line = {'width':3}, - fill='tozeroy' - ) - #Datos de lluvia acumulada - trace2 = go.Scatter( - x = Rs.index.to_pydatetime(), - y = Rs[' Lluvia'].values.cumsum(), - name = 'Acumulado [mm]', - line = {'width':3}, - yaxis = 'y2' - ) - #Datos y formato de la figura - data = [trace1, trace2] - layout = dict( - width=1020, - height=400, - showlegend = False, - margin=dict( - l=50, - r=50, - b=50, - t=50, - pad=4 - ), - yaxis=dict( - title='Precipitacion', - titlefont=dict( - color='rgb(0, 102, 153)', - size = 15 - ), - tickangle=-90, - tickfont=dict( - color='rgb(0, 102, 153)', - size = 16, - ), - ), - - xaxis = dict( - tickfont = dict( - size = 16 - ), - ), - - yaxis2=dict( - title='Acumulada', - titlefont=dict( - color='rgb(255, 153, 51)', - size = 15 - ), - tickangle=90, - tickfont=dict( - color='rgb(255, 153, 51)', - size = 16, - ), - overlaying='y', - side='right', - range = [0,Rs[' Lluvia'].values.sum()] - )) - #Figura - fig = dict(data=data, layout=layout) - #Guarda el html - plot(fig,filename=pathFigure, auto_open = False) - - def Plot_Histogram(self, pathFigure): - '''Hace un plot del histograma de la distribucion de la lluvia en la cuenca.''' - #Hace una cipia de la informacion - Data = self.rainData.copy() - Data = Data[' Lluvia'].values - Data = Data[Data>0] - step = (np.percentile(Data,95) - np.percentile(Data,5))/7. - #Genera los datos de la figura - trace1 = go.Histogram( - x = Data, - name = 'Lluvia [mm]', - xbins = dict( - start = np.percentile(Data,5), - end = np.percentile(Data,95), - size = step) - ) - #Establece la configuracion de la misma - layout = dict( - width=400, - height=400, - showlegend = False, - margin=dict( - l=50, - r=50, - b=70, - t=50, - pad=4 - ), - yaxis=dict( - title='PDF', - titlefont=dict( - color='rgb(0, 102, 153)', - size = 15 - ), - tickangle=45, - tickfont=dict( - color='rgb(0, 102, 153)', - size = 16, - ),), - xaxis = dict( - title = 'Lluvia [mm]', - titlefont =dict( - color='rgb(0, 102, 153)', - size = 15 - ), - tickfont=dict( - color='rgb(0, 102, 153)', - size = 16, - ) - ) - ) - #Monta la figura - data = [trace1] - fig = dict(data = data, layout = layout) - plot(fig,filename=pathFigure, auto_open = False) - - def Plot_MediaMensual(self, pathFigure): - '''Hace el plot de la media mensual multi-anual de la serie de lluvia de la cuenca''' - Rs = self.rainData.copy() - Rain = Rs[' Lluvia'].resample('M').sum() - #Obtiene media y desviqacion - Mean = [] - Desv = [] - for i in range(1,13): - Mean.append(Rain[Rain.index.month == i].mean()) - Desv.append(np.std(Rain[Rain.index.month == i])) - Mean = np.array(Mean) - Desv = np.array(Desv) - #Hace la figura - trace1 = go.Scatter( - x = np.arange(1,13,1), - y = Mean, - name = 'Media', - line = {'width':5, - 'color':('rgb(0, 51, 102)')}, - ) - - trace2 = go.Scatter( - x = np.arange(1,13,1), - y = Mean + Desv, - name = 'm + s', - line = dict(color = ('rgb(255, 153, 51)'), - width = 3), - ) - - trace3 = go.Scatter( - x = np.arange(1,13,1), - y = Mean - Desv, - name = 'm - s', - fill='tonexty', - line = dict( width=3, - color = ('rgb(255, 153, 51)')), - ) - data = [trace2, trace3, trace1] - layout = dict( - width=800, - height=400, - showlegend = False, - margin=dict( - l=50, - r=50, - b=50, - t=50, - pad=4 - ), - xaxis=dict( - dtick=1, - tickfont=dict( - color='rgb(0, 102, 153)', - size = 16), - ticktext = ['Ene','Feb','Mar','Abr','May','Jun','Jul','Ago','Sep','Oct','Nov','Dic'], - tickvals = range(1,13) - ), - yaxis=dict( - title='Precipitacion', - titlefont=dict( - color='rgb(0, 102, 153)', - size = 15 - ), - tickangle=-90, - tickfont=dict( - color='rgb(0, 102, 153)', - size = 16, - ), - ), - ) - fig = dict(data=data, layout=layout) - plot(fig,filename=pathFigure, auto_open = False) + def __init__(self, pathRain): + self.path_rainBin, self.path_rainHdr = wmf.__Add_hdr_bin_2route__(pathRain) + self.rainData = wmf.read_rain_struct(self.path_rainHdr) + + def Plot_Rainfall(self, pathFigure): + '''Hace el plot de la serie de tiempo de lluvia e incluye en esta toda la info necesaria''' + #obtiene los records + Rs = self.rainData.copy() + Records = ['Record: %d'%i for i in Rs[' Record'].values] + #Datos de lluvia + trace1 = go.Scatter( + x = Rs.index.to_pydatetime(), + y = Rs[' Lluvia'].values, + text = Records, + name = 'Lluvia [mm]', + line = {'width':3}, + fill='tozeroy' + ) + #Datos de lluvia acumulada + trace2 = go.Scatter( + x = Rs.index.to_pydatetime(), + y = Rs[' Lluvia'].values.cumsum(), + name = 'Acumulado [mm]', + line = {'width':3}, + yaxis = 'y2' + ) + #Datos y formato de la figura + data = [trace1, trace2] + layout = dict( + width=1020, + height=400, + showlegend = False, + margin=dict( + l=50, + r=50, + b=50, + t=50, + pad=4 + ), + yaxis=dict( + title='Precipitacion', + titlefont=dict( + color='rgb(0, 102, 153)', + size = 15 + ), + tickangle=-90, + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16, + ), + ), + + xaxis = dict( + tickfont = dict( + size = 16 + ), + ), + + yaxis2=dict( + title='Acumulada', + titlefont=dict( + color='rgb(255, 153, 51)', + size = 15 + ), + tickangle=90, + tickfont=dict( + color='rgb(255, 153, 51)', + size = 16, + ), + overlaying='y', + side='right', + range = [0,Rs[' Lluvia'].values.sum()] + )) + #Figura + fig = dict(data=data, layout=layout) + #Guarda el html + plot(fig,filename=pathFigure, auto_open = False) + + def Plot_Histogram(self, pathFigure): + '''Hace un plot del histograma de la distribucion de la lluvia en la cuenca.''' + #Hace una cipia de la informacion + Data = self.rainData.copy() + Data = Data[' Lluvia'].values + Data = Data[Data>0] + step = (np.percentile(Data,95) - np.percentile(Data,5))/7. + #Genera los datos de la figura + trace1 = go.Histogram( + x = Data, + name = 'Lluvia [mm]', + xbins = dict( + start = np.percentile(Data,5), + end = np.percentile(Data,95), + size = step) + ) + #Establece la configuracion de la misma + layout = dict( + width=400, + height=400, + showlegend = False, + margin=dict( + l=50, + r=50, + b=70, + t=50, + pad=4 + ), + yaxis=dict( + title='PDF', + titlefont=dict( + color='rgb(0, 102, 153)', + size = 15 + ), + tickangle=45, + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16, + ),), + xaxis = dict( + title = 'Lluvia [mm]', + titlefont =dict( + color='rgb(0, 102, 153)', + size = 15 + ), + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16, + ) + ) + ) + #Monta la figura + data = [trace1] + fig = dict(data = data, layout = layout) + plot(fig,filename=pathFigure, auto_open = False) + + def Plot_MediaMensual(self, pathFigure): + '''Hace el plot de la media mensual multi-anual de la serie de lluvia de la cuenca''' + Rs = self.rainData.copy() + Rain = Rs[' Lluvia'].resample('M').sum() + #Obtiene media y desviqacion + Mean = [] + Desv = [] + for i in range(1,13): + Mean.append(Rain[Rain.index.month == i].mean()) + Desv.append(np.std(Rain[Rain.index.month == i])) + Mean = np.array(Mean) + Desv = np.array(Desv) + #Hace la figura + trace1 = go.Scatter( + x = np.arange(1,13,1), + y = Mean, + name = 'Media', + line = {'width':5, + 'color':('rgb(0, 51, 102)')}, + ) + + trace2 = go.Scatter( + x = np.arange(1,13,1), + y = Mean + Desv, + name = 'm + s', + line = dict(color = ('rgb(255, 153, 51)'), + width = 3), + ) + + trace3 = go.Scatter( + x = np.arange(1,13,1), + y = Mean - Desv, + name = 'm - s', + fill='tonexty', + line = dict( width=3, + color = ('rgb(255, 153, 51)')), + ) + data = [trace2, trace3, trace1] + layout = dict( + width=800, + height=400, + showlegend = False, + margin=dict( + l=50, + r=50, + b=50, + t=50, + pad=4 + ), + xaxis=dict( + dtick=1, + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16), + ticktext = ['Ene','Feb','Mar','Abr','May','Jun','Jul','Ago','Sep','Oct','Nov','Dic'], + tickvals = range(1,13) + ), + yaxis=dict( + title='Precipitacion', + titlefont=dict( + color='rgb(0, 102, 153)', + size = 15 + ), + tickangle=-90, + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16, + ), + ), + ) + fig = dict(data=data, layout=layout) + plot(fig,filename=pathFigure, auto_open = False) + + +class PlotGeomorphology(): + + def __init__(self): + self.a = 0 + diff --git a/qgisplugin/HydroSEDPlugin.py b/qgisplugin/HydroSEDPlugin.py index 7884d82..e664a2f 100644 --- a/qgisplugin/HydroSEDPlugin.py +++ b/qgisplugin/HydroSEDPlugin.py @@ -235,6 +235,11 @@ def run(self): #Crea un directorio temporal try: os.makedirs('/tmp/HydroSED') + os.makedirs('/tmp/HydroSED/raster') + os.makedirs('/tmp/HydroSED/vector') + os.makedirs('/tmp/HydroSED/Plots_Rainfall') + os.makedirs('/tmp/HydroSED/Plots_Geomorfo') + os.makedirs('/tmp/HydroSED/Plots_Sim') except: pass diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index aaba302..6266648 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -283,13 +283,12 @@ def Basin_LoadBasinNetwork(self, PathNetwork): def Basin_LoadVariableFromDicNC(self, VarName, capa = None): '''Toma una variable del diccionario de variables basicas y la carga a Qgis''' #Variable de acuerdo a si hay capa o no - print capa if capa is None: Variable = np.copy(self.DicBasinNc[VarName]['var']) - rutaSalida = '/tmp/HydroSED/'+VarName+'.tiff' + rutaSalida = '/tmp/HydroSED/raster/'+VarName+'.tiff' else: Variable = np.copy(self.DicBasinNc[VarName]['var'][capa]) - rutaSalida = '/tmp/HydroSED/'+VarName+'_'+str(capa+1)+'.tiff' + rutaSalida = '/tmp/HydroSED/raster/'+VarName+'_'+str(capa+1)+'.tiff' print Variable #Conversion self.cuenca.Transform_Basin2Map(Variable, @@ -301,7 +300,7 @@ def Basin_LoadVariableFromDicNC(self, VarName, capa = None): def Basin_LoadVariableFromDicWMF(self,VarName): '''Toma una variable del diccionario de variables basicas y la carga a Qgis''' #Transforma a un raster - rutaSalida = '/tmp/HydroSED/'+VarName+'.tiff' + rutaSalida = '/tmp/HydroSED/raster/'+VarName+'.tiff' self.cuenca.Transform_Basin2Map(self.DicBasinWMF[VarName]['var'], ruta = rutaSalida, EPSG = self.cuenca.epsg) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 5268933..7c40d07 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -70,6 +70,8 @@ def __init__(self, iface = None, parent=None): self.TablaFila_NC = 0 self.botonClicked = False + self.GeoPlots = HSplots.PlotGeomorphology() + #Inicia el comboBox de la seleccion de categoria para transformar raster a WMF for k in ['base','Geomorfo','SimHidro','Hidro']: self.ComboBoxRaster2WMF.addItem(k) @@ -102,7 +104,7 @@ def handleClickEventEjecutarTrazadorCorrientes (self): x = self.spinBoxLongitudTrazadorCorrientes.value () #Camino a los temporales if len(self.PathCorriente_out.text()) == 0: - self.PathCorriente_out.setText('/tmp/HydroSED/Corriente.shp') + self.PathCorriente_out.setText('/tmp/HydroSED/vector/Corriente.shp') OutPath = self.PathCorriente_out.text() try: self.HSutils.trazador_corriente(x,y, OutPath) @@ -121,9 +123,9 @@ def handleClickEventEjecutarTrazadorCuencas (self): x = self.spinBoxLongitudTrazadorCuencas.value () #Camino a los temporales if len(self.PathOutputDivisoria.text()) == 0: - self.PathOutputDivisoria.setText('/tmp/HydroSED/Cuenca.shp') + self.PathOutputDivisoria.setText('/tmp/HydroSED/vector/Cuenca.shp') if len(self.PathOutputRed.text()) == 0: - self.PathOutputRed.setText('/tmp/HydroSED/Cuenca_Red.shp') + self.PathOutputRed.setText('/tmp/HydroSED/vector/Cuenca_Red.shp') #Paths para guardar la cuenca OutPathDivisoria = self.PathOutputDivisoria.text() OutPathRed = self.PathOutputRed.text() @@ -211,7 +213,7 @@ def clickEventBasin2WMF(): def clickEventBasinLoadDivisory(): '''Carga la divisoria de la cuenca cargada a WMF''' - OutPathDivisoria = '/tmp/HydroSED/CuencaCargada.shp' + OutPathDivisoria = '/tmp/HydroSED/vector/CuencaCargada.shp' self.HSutils.Basin_LoadBasinDivisory(OutPathDivisoria) #Carga la divisoria ret, layer = self.HSutils.cargar_mapa_vector(OutPathDivisoria, self.HSutils.TIPO_STYLE_POLIGONO, color = (255,0,0), width = 0.6) @@ -219,7 +221,7 @@ def clickEventBasinLoadDivisory(): self.iface.legendInterface().refreshLayerSymbology(layer) def clickEventBasinLoadNetwork(): '''Carga la divisoria de la cuenca cargada a WMF''' - OutPathNetwork = '/tmp/HydroSED/RedCargada.shp' + OutPathNetwork = '/tmp/HydroSED/vector/RedCargada.shp' self.HSutils.Basin_LoadBasinNetwork(OutPathNetwork) #Carga la red ret, layer = self.HSutils.cargar_mapa_vector(OutPathNetwork, self.HSutils.TIPO_STYLE_POLILINEA, width = 0.4) @@ -619,7 +621,7 @@ def clickEventEjecutarInterpolacion(): def clickEventViewSerieRainfall(): '''Genera y visualiza la grafica de lluvia interpolada para la cuenca''' #Hace la figura - PathFigure = '/tmp/HydroSED/RainfallPlot.html' + PathFigure = '/tmp/HydroSED/Plots_Rainfall/RainfallPlot.html' self.HSplots.Plot_Rainfall(PathFigure) #Set de la ventana que contiene la figura. self.VistaRainWeb = QWebView(None) @@ -634,7 +636,7 @@ def clickEventViewSerieRainfall(): def clickEventViewHistogramRainfall(): '''Genera y visualiza la grafica de lluvia interpolada para la cuenca''' #Hace la figura - PathFigure = '/tmp/HydroSED/RainfallHistogram.html' + PathFigure = '/tmp/HydroSED/Plots_Rainfall/RainfallHistogram.html' self.HSplots.Plot_Histogram(PathFigure) #Set de la ventana que contiene la figura. self.VistaRainWeb = QWebView(None) @@ -649,7 +651,7 @@ def clickEventViewHistogramRainfall(): def clickEventViewMediaMensualRainfall(): '''Genera y visualiza la grafica de la lluvia media mensual en la cuenca''' #Hace la figura - PathFigure = '/tmp/HydroSED/RainfallMediaMensual.html' + PathFigure = '/tmp/HydroSED/Plots_Rainfall/RainfallMediaMensual.html' self.HSplots.Plot_MediaMensual(PathFigure) #Set de la ventana que contiene la figura. self.VistaRainWeb = QWebView(None) @@ -731,6 +733,18 @@ def clickEventAddNewParamSet(): def setupUIInputsOutputs (self): + def DrawClickEvent_histogram_WMF(): + '''Hace un histograma de la variable seleccionada''' + #Selecciona el item y su nombre + selectedItems = self.Tabla_Prop_WMF.currentRow () + ItemName = self.Tabla_Prop_WMF.item(selectedItems,0).text() + if ItemName[-1] == '*': ItemName = ItemName[:-1] + #Obtiene la variable e invoca la funciond e grafica + Var = self.HSutils.DicBasinWMF[ItemName]['var'] + PathFigure = '/tmp/HydroSED/Plots_Geomorfo/' + #self.GeoPlots.VarHistogram(Var, PathFigure) + + def handleClickEventButton_Eliminar_Desde_WMF (): #Selecciona el item y su nombre selectedItems = self.Tabla_Prop_WMF.currentRow () diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index c21e1b4..1bd6cfc 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -238,7 +238,7 @@ 0 - 120 + 130 469 776 @@ -294,7 +294,7 @@ 0 - -887 + -629 443 2018 @@ -870,6 +870,47 @@ + + + + true + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Qt::DefaultContextMenu + + + Grafica el histograma de la variable seleccionada + + + Grafica el histograma de la variable seleccionada + + + + + + + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico + + + + 16 + 16 + + + + @@ -1091,7 +1132,7 @@ 0 - 1160 + 1230 421 161 @@ -1217,83 +1258,6 @@ - - - - - 50 - 16777215 - - - - Capa a ver (o editar) de la variable Nc. - - - 5 - - - - - - - - 50 - 16777215 - - - - Visualizar una variable del Nc - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - - - - - - - false - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Qt::DefaultContextMenu - - - Convertir variable a red hídrica (promedia celdas del tramo). - - - Convertir variable a red hídrica (promedia celdas del tramo). - - - - - - - :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico - - - - 16 - 16 - - - - @@ -1317,49 +1281,6 @@ - - - - - 50 - 16777215 - - - - Actualizar variables del Nc. - - - - - - - :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg - - - - - - - - 50 - 0 - - - - - 30 - 16777215 - - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png - - - @@ -1380,6 +1301,192 @@ + + + + 0 + 1150 + 423 + 41 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 50 + 16777215 + + + + Actualizar variables del Nc. + + + + + + + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg + + + + + + + true + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Qt::DefaultContextMenu + + + Grafica el histograma de la variable seleccionada + + + Grafica el histograma de la variable seleccionada + + + + + + + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico + + + + 16 + 16 + + + + + + + + false + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Qt::DefaultContextMenu + + + Convertir variable a red hídrica (promedia celdas del tramo). + + + Convertir variable a red hídrica (promedia celdas del tramo). + + + + + + + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico + + + + 16 + 16 + + + + + + + + + 50 + 16777215 + + + + Capa a ver (o editar) de la variable Nc. + + + 5 + + + + + + + + 50 + 16777215 + + + + Visualizar una variable del Nc + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png + + + + + @@ -2194,7 +2301,7 @@ 0 320 421 - 271 + 211 @@ -2427,7 +2534,7 @@ 0 - 580 + 550 421 181 @@ -2621,7 +2728,7 @@ 10 30 401 - 211 + 221 @@ -2698,6 +2805,86 @@ + + + + + + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + + + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + + + Gráficas: + + + + + + + + 20 + 0 + + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Perfiles + + + + + + + + 10 + 0 + + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Hietograma + + + + + + + + 20 + 0 + + + + + 100 + 16777215 + + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Tc + + + + + @@ -2727,19 +2914,6 @@ - - - - 10 - 550 - 411 - 21 - - - - Qt::Horizontal - - @@ -2794,6 +2968,19 @@ + + + + 0 + 530 + 411 + 21 + + + + Qt::Horizontal + + From abdc7ceb405f4e049f54fdccb9a82324dfc2ab38 Mon Sep 17 00:00:00 2001 From: nicolas998 Date: Tue, 14 Aug 2018 22:33:47 -0500 Subject: [PATCH 083/142] funciona el plot de histogramas de variables de la cuenca --- qgisplugin/HydroSEDPlots.py | 86 +++++++++++++++++++++++++ qgisplugin/HydroSEDPlugin_dockwidget.py | 15 ++++- 2 files changed, 99 insertions(+), 2 deletions(-) diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py index b68ff53..98adaff 100644 --- a/qgisplugin/HydroSEDPlots.py +++ b/qgisplugin/HydroSEDPlots.py @@ -217,4 +217,90 @@ class PlotGeomorphology(): def __init__(self): self.a = 0 + + def VarHistogram(self, var, pathFigure, ncells): + '''Hace el plot de un histograma de una variable seleccionada''' + #Seleccion de datos + if ncells > 10000: + pos = np.random.choice(ncells, 10000) + else: + pos = range(10000) + #Obtiene la pdf y cdf de la variable + var = var[pos] + p1 = np.percentile(var, 0.1) + p99 = np.percentile(var, 99.9) + h,b = np.histogram(var, bins=np.linspace(p1,p99,10)) + pdf = h.astype(float)/h.sum() + cdf = pdf.cumsum() + b = (b[:-1]+b[1:])/2. + #Create a trace + trace1 = go.Scatter( + x = b, + y = pdf, + name = 'PDF', + line = {'width':3}, + fill='tozeroy' + ) + trace2 = go.Scatter( + x = b, + y = cdf, + name = 'CDF', + line = {'width':3}, + yaxis = 'y2' + ) + #Datos del plot + data = [trace1, trace2] + #Configuracion del plot + layout = dict( + width=400, + height=400, + showlegend = False, + margin=dict( + l=50, + r=50, + b=50, + t=50, + pad=4 + ), + xaxis = dict( + title = 'Variable', + titlefont =dict( + color='rgb(0, 102, 153)', + size = 15 + ), + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16, + ) + ), + yaxis=dict( + title='PDF', + titlefont=dict( + color='rgb(0, 102, 153)', + size = 15 + ), + tickangle=-90, + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16, + ), + ), + + yaxis2=dict( + title='CDF', + titlefont=dict( + color='rgb(255, 153, 51)', + size = 15 + ), + tickangle=90, + tickfont=dict( + color='rgb(255, 153, 51)', + size = 16, + ), + overlaying='y', + side='right', + )) + #Figura y guardado + fig = dict(data=data, layout=layout) + plot(fig,filename=pathFigure, auto_open = False) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 7c40d07..e637c74 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -741,8 +741,17 @@ def DrawClickEvent_histogram_WMF(): if ItemName[-1] == '*': ItemName = ItemName[:-1] #Obtiene la variable e invoca la funciond e grafica Var = self.HSutils.DicBasinWMF[ItemName]['var'] - PathFigure = '/tmp/HydroSED/Plots_Geomorfo/' - #self.GeoPlots.VarHistogram(Var, PathFigure) + PathFigure = '/tmp/HydroSED/Plots_Geomorfo/VarHistogram.html' + self.GeoPlots.VarHistogram(Var, PathFigure, self.HSutils.cuenca.ncells) + #Set de la ventana que contiene la figura. + self.VistaRainWeb = QWebView(None) + self.VistaRainWeb.load(QUrl.fromLocalFile(PathFigure)) + self.VistaRainWeb.setWindowTitle('Histograma variable') + self.VistaRainWeb.setMinimumWidth(100) + self.VistaRainWeb.setMaximumWidth(500) + self.VistaRainWeb.setMinimumHeight(100) + self.VistaRainWeb.setMaximumHeight(500) + self.VistaRainWeb.show() def handleClickEventButton_Eliminar_Desde_WMF (): @@ -1026,6 +1035,8 @@ def set_dxplano(): self.Button_WMF2NC.clicked.connect(handleClickEventButton_WMF2NC) #Boton para actualizar los archivos que se encuentran guardados en un netCDF self.Button_Update_NC.clicked.connect(clickEventBasinUpdateNC) + #Botones para graficas de variables de la cuenca + self.ButtonDraw_histogram_WMF.clicked.connect(DrawClickEvent_histogram_WMF) class Tabla(): From 6c79932fe501933a8d753eb59b504886d4e6076a Mon Sep 17 00:00:00 2001 From: nicolas998 Date: Tue, 14 Aug 2018 23:06:55 -0500 Subject: [PATCH 084/142] funciona el plot de los tiempos de concentracion de la cuenca --- qgisplugin/HydroSEDPlots.py | 223 +++++++++++++++--------- qgisplugin/HydroSEDPlugin_dockwidget.py | 18 ++ 2 files changed, 155 insertions(+), 86 deletions(-) diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py index 98adaff..40e3fdb 100644 --- a/qgisplugin/HydroSEDPlots.py +++ b/qgisplugin/HydroSEDPlots.py @@ -215,92 +215,143 @@ def Plot_MediaMensual(self, pathFigure): class PlotGeomorphology(): - def __init__(self): - self.a = 0 - - def VarHistogram(self, var, pathFigure, ncells): - '''Hace el plot de un histograma de una variable seleccionada''' - #Seleccion de datos - if ncells > 10000: - pos = np.random.choice(ncells, 10000) - else: - pos = range(10000) - #Obtiene la pdf y cdf de la variable - var = var[pos] - p1 = np.percentile(var, 0.1) - p99 = np.percentile(var, 99.9) - h,b = np.histogram(var, bins=np.linspace(p1,p99,10)) - pdf = h.astype(float)/h.sum() - cdf = pdf.cumsum() - b = (b[:-1]+b[1:])/2. - #Create a trace - trace1 = go.Scatter( - x = b, - y = pdf, - name = 'PDF', - line = {'width':3}, - fill='tozeroy' - ) - trace2 = go.Scatter( - x = b, - y = cdf, - name = 'CDF', - line = {'width':3}, - yaxis = 'y2' - ) - #Datos del plot - data = [trace1, trace2] - #Configuracion del plot - layout = dict( - width=400, - height=400, - showlegend = False, - margin=dict( - l=50, - r=50, - b=50, - t=50, - pad=4 - ), - xaxis = dict( - title = 'Variable', - titlefont =dict( - color='rgb(0, 102, 153)', - size = 15 - ), - tickfont=dict( - color='rgb(0, 102, 153)', - size = 16, - ) - ), - yaxis=dict( - title='PDF', - titlefont=dict( - color='rgb(0, 102, 153)', - size = 15 - ), - tickangle=-90, - tickfont=dict( - color='rgb(0, 102, 153)', - size = 16, + def __init__(self): + self.a = 0 + + def VarHistogram(self, var, pathFigure, ncells): + '''Hace el plot de un histograma de una variable seleccionada''' + #Seleccion de datos + if ncells > 10000: + pos = np.random.choice(ncells, 10000) + else: + pos = range(10000) + #Obtiene la pdf y cdf de la variable + var = var[pos] + p1 = np.percentile(var, 0.1) + p99 = np.percentile(var, 99.9) + h,b = np.histogram(var, bins=np.linspace(p1,p99,10)) + pdf = h.astype(float)/h.sum() + cdf = pdf.cumsum() + b = (b[:-1]+b[1:])/2. + #Create a trace + trace1 = go.Scatter( + x = b, + y = pdf, + name = 'PDF', + line = {'width':3}, + fill='tozeroy' + ) + trace2 = go.Scatter( + x = b, + y = cdf, + name = 'CDF', + line = {'width':3}, + yaxis = 'y2' + ) + #Datos del plot + data = [trace1, trace2] + #Configuracion del plot + layout = dict( + width=400, + height=400, + showlegend = False, + margin=dict( + l=50, + r=50, + b=50, + t=50, + pad=4 + ), + xaxis = dict( + title = 'Variable', + titlefont =dict( + color='rgb(0, 102, 153)', + size = 15 ), + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16, + ) ), - - yaxis2=dict( - title='CDF', - titlefont=dict( - color='rgb(255, 153, 51)', - size = 15 - ), - tickangle=90, - tickfont=dict( - color='rgb(255, 153, 51)', - size = 16, - ), - overlaying='y', - side='right', - )) - #Figura y guardado - fig = dict(data=data, layout=layout) - plot(fig,filename=pathFigure, auto_open = False) + yaxis=dict( + title='PDF', + titlefont=dict( + color='rgb(0, 102, 153)', + size = 15 + ), + tickangle=-90, + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16, + ), + ), + + yaxis2=dict( + title='CDF', + titlefont=dict( + color='rgb(255, 153, 51)', + size = 15 + ), + tickangle=90, + tickfont=dict( + color='rgb(255, 153, 51)', + size = 16, + ), + overlaying='y', + side='right', + )) + #Figura y guardado + fig = dict(data=data, layout=layout) + plot(fig,filename=pathFigure, auto_open = False) + + def TiempoConcentracion(self, DicTiempos, pathFigure): + '''Plot de los tiempos de concentracion de la cuenca''' + #Los datos + Names = [i[0][:7] for i in DicTiempos.items()] + Texto = [i[0] for i in DicTiempos.items()] + Times = ['%.3f'%i[1] for i in DicTiempos.items()] + #El plot + data = [go.Bar( + x = Names, + y = Times, + text = Texto + )] + #Configuracion del plot + layout = dict( + width=600, + height=400, + showlegend = False, + margin=dict( + l=50, + r=50, + b=50, + t=50, + pad=4 + ), + xaxis = dict( + title = 'Variable', + titlefont =dict( + color='rgb(0, 102, 153)', + size = 15 + ), + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16, + ) + ), + yaxis=dict( + title='Tiempo viaje [hrs]', + titlefont=dict( + color='rgb(0, 102, 153)', + size = 15 + ), + tickangle=0, + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16, + ), + ),) + #Figura y guardado + fig = dict(data=data, layout=layout) + plot(fig,filename=pathFigure, auto_open = False) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index e637c74..1f40805 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -373,11 +373,29 @@ def clickEventGeoRasterProp(): self.ComboGeoMaskVar.addItem(k) self.ComboGeoVar2Acum.addItem(k) + def PlotTiempoConcentracion(): + '''Plot con el tiempo de concentracion estimado por diferentes metodologias''' + #Obtiene la variable e invoca la funciond e grafica + PathFigure = '/tmp/HydroSED/Plots_Geomorfo/TiemposConcentracion.html' + self.GeoPlots.TiempoConcentracion(self.HSutils.cuenca.Tc, PathFigure) + #Set de la ventana que contiene la figura. + self.VistaRainWeb = QWebView(None) + self.VistaRainWeb.load(QUrl.fromLocalFile(PathFigure)) + self.VistaRainWeb.setWindowTitle('Tiempos de concentracion') + self.VistaRainWeb.setMinimumWidth(100) + self.VistaRainWeb.setMaximumWidth(600) + self.VistaRainWeb.setMinimumHeight(100) + self.VistaRainWeb.setMaximumHeight(500) + self.VistaRainWeb.show() + + #Botones de ejecucion self.ButtonGeomorfoRasterVars.clicked.connect(clickEventGeoRasterProp) self.checkBoxTodos.clicked.connect(clickEventActivateGeoCheckBoxes) self.ButtonGeoParameters.clicked.connect(clickEventGeoProperties) #self.ComboGeoMaskVar.activated.connect(clickEventUpdateComboBoxMask) + #Botones de figuras + self.Button_GeomorfoTc.clicked.connect(PlotTiempoConcentracion) def setupHidro_Balance(self): From b0bb2f52ba46a25d0f9eaab22b4b8e33a67ada6a Mon Sep 17 00:00:00 2001 From: nicolas998 Date: Tue, 14 Aug 2018 23:39:47 -0500 Subject: [PATCH 085/142] funciona el plot de la curva hipsometrica y perfil --- qgisplugin/HydroSEDPlots.py | 74 ++++++++++++++++++++ qgisplugin/HydroSEDPlugin_dockwidget.py | 24 ++++++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 35 +++------ 3 files changed, 105 insertions(+), 28 deletions(-) diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py index 40e3fdb..9b43cdb 100644 --- a/qgisplugin/HydroSEDPlots.py +++ b/qgisplugin/HydroSEDPlots.py @@ -355,3 +355,77 @@ def TiempoConcentracion(self, DicTiempos, pathFigure): fig = dict(data=data, layout=layout) plot(fig,filename=pathFigure, auto_open = False) + def StreamProfileHipsometric(self, pathFigure, HipsoData, StreamData): + '''Hace el plot del perfil longitudinal y de la curva hipsometrica''' + #plot# Create a trace + trace1 = go.Scatter( + x = HipsoData[0], + y = HipsoData[1], + name = 'Curva hipso', + line = {'width':3}, + ) + x = StreamData[0] + y = StreamData[1] + trace2 = go.Scatter( + x = x[30:], + y = y[30:], + name = 'Perfil', + line = {'width':3}, + xaxis = 'x2' + ) + + data = [trace1, trace2] + + layout = dict( + width=600, + height=400, + showlegend = False, + margin=dict( + l=50, + r=50, + b=50, + t=50, + pad=4 + ), + + xaxis = dict( + title = 'Porcentaje del area [%]', + titlefont =dict( + color='rgb(0, 102, 153)', + size = 15 + ), + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16, + ) + ), + + yaxis=dict( + title='Elevacion [m.s.n.m]', + titlefont=dict( + color='rgb(0, 102, 153)', + size = 15 + ), + tickangle=-90, + tickfont=dict( + color='rgb(0, 102, 153)', + size = 16, + ), + ), + + xaxis2=dict( + title='Distancia a la salida [km]', + titlefont=dict( + color='rgb(255, 153, 51)', + size = 15 + ), + tickfont=dict( + color='rgb(255, 153, 51)', + size = 16, + ), + overlaying='x', + side='top', + )) + fig = dict(data=data, layout=layout) + plot(fig,filename=pathFigure, auto_open = False) + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 1f40805..36bd15a 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -387,7 +387,28 @@ def PlotTiempoConcentracion(): self.VistaRainWeb.setMinimumHeight(100) self.VistaRainWeb.setMaximumHeight(500) self.VistaRainWeb.show() - + + def PlotCurvaHipsometricaPerfil(): + '''Hace el plot de la curva hipsometrica de la cuenca y del perfil del canal ppal''' + #Obtiene la variable e invoca la funciond e grafica + PathFigure = '/tmp/HydroSED/Plots_Geomorfo/PerfilYCurvaHipso.html' + self.HSutils.cuenca.GetGeo_Ppal_Hipsometric() + #Variables + Hipso = np.copy(self.HSutils.cuenca.hipso_basin) + Stream = np.vstack([self.HSutils.cuenca.ppal_stream[1]/1000., + self.HSutils.cuenca.ppal_stream[0]]) + #Plot + self.GeoPlots.StreamProfileHipsometric(PathFigure, Hipso, Stream) + #Set de la ventana que contiene la figura. + self.VistaRainWeb = QWebView(None) + self.VistaRainWeb.load(QUrl.fromLocalFile(PathFigure)) + self.VistaRainWeb.setWindowTitle('Perfil longitudinal y curva hipsométrica') + self.VistaRainWeb.setMinimumWidth(100) + self.VistaRainWeb.setMaximumWidth(700) + self.VistaRainWeb.setMinimumHeight(100) + self.VistaRainWeb.setMaximumHeight(400) + self.VistaRainWeb.show() + #Botones de ejecucion self.ButtonGeomorfoRasterVars.clicked.connect(clickEventGeoRasterProp) @@ -396,6 +417,7 @@ def PlotTiempoConcentracion(): #self.ComboGeoMaskVar.activated.connect(clickEventUpdateComboBoxMask) #Botones de figuras self.Button_GeomorfoTc.clicked.connect(PlotTiempoConcentracion) + self.Button_GeomorfoPerfil.clicked.connect(PlotCurvaHipsometricaPerfil) def setupHidro_Balance(self): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 1bd6cfc..c5e12a5 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -250,7 +250,7 @@ - 0 + 2 @@ -294,7 +294,7 @@ 0 - -629 + 0 443 2018 @@ -900,7 +900,7 @@ - + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico @@ -1339,7 +1339,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -1374,7 +1374,7 @@ - + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico @@ -1531,7 +1531,7 @@ 0 - -255 + 0 443 2018 @@ -2839,25 +2839,6 @@ - - - - - 10 - 0 - - - - Ejecuta la interpolación para la cuenca con los parámetros dados. - - - Ejecuta la interpolación para la cuenca con los parámetros dados. - - - Hietograma - - - @@ -5211,7 +5192,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -5458,7 +5439,7 @@ - + :/plugins/HydroSEDPlugin/icons/toRaster.ico:/plugins/HydroSEDPlugin/icons/toRaster.ico From 43f579cf2a0a504928124eb2373fdc320a505a66 Mon Sep 17 00:00:00 2001 From: nicolas998 Date: Tue, 14 Aug 2018 23:47:07 -0500 Subject: [PATCH 086/142] =?UTF-8?q?tabla=20param=20geomorfo:=20se=20corrig?= =?UTF-8?q?e=20que=20esta=20tiraba=20tama=C3=B1os=20de=20filas=20muy=20gra?= =?UTF-8?q?ndes=20y=20feos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index c5e12a5..3efca3f 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -2743,12 +2743,24 @@ true + + 120 + + + 10 + - 50 + 20 + + + 10 true + + true + From 796060623ca369f1a1f622280e52dcb85c9d23ca Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 15 Aug 2018 10:12:50 -0500 Subject: [PATCH 087/142] se montan los iconos que no estaban montados en el repo --- qgisplugin/icons/histograma.ico | Bin 0 -> 32988 bytes qgisplugin/icons/save.svg | 55 ++++++++++++++++++++++++++++++++ qgisplugin/icons/toRaster.ico | Bin 0 -> 32988 bytes 3 files changed, 55 insertions(+) create mode 100644 qgisplugin/icons/histograma.ico create mode 100644 qgisplugin/icons/save.svg create mode 100644 qgisplugin/icons/toRaster.ico diff --git a/qgisplugin/icons/histograma.ico b/qgisplugin/icons/histograma.ico new file mode 100644 index 0000000000000000000000000000000000000000..e31f1bccb7ee650954071c604134dd4d34ca03fa GIT binary patch literal 32988 zcmeHPdrVvB6~8=UZ2W#dFxUhVuuTjuF)oe?(1J@?)kQQR!9WOU%KMQ}k&w~GSsP`W zqA98>C8|_Klcr6Pl7IHkv6zeCK-@F2|K|m0V8`hgT=pjMp&7aZcw(UBhup_{?J2sLMF+_HmBW z;B)@{N{)Lt!g0;m2Vdi^A<=VI7y=9dh5$o=A;1t|2rvW~0t^9$07HNwkOl$3XM2s( zm?`)OZr{G0mI#;g=g$igwXa~i5K;R}Ep38C?G}?QEoEz?_6&qgIhVAy6DG(((00Ow z+J$VV=hV*ZXZ{z80g4Y6|2rQ42%jkBc^&_v7>`U!)_&401HB0Li)CXbKBescOnQse z_QKnbKnjkt-CX~P<=_JN?CScj0KLWP%Ix38{f}5qEPxO5f06xj53|4c@n0m@iNcoopZQ-f1~9@3KK~OXN{h!t&~~xTKZ~cjD4d!7Z2Swx07lrJ zAOB=yCMxvz4^c+x?lIZx{?CRivmf)L&={a`BlO!3J*W0;0GD{XpzXQ-{#oMoWmAvY z&*EP&1~7PD`0-B|WT9+htd!dYeV@#KrL4RNx-t8+ z0{F!ZPWLU47G;#Bsv?)mFCRO0EOFw*i9|RYPB@*;L`O#lPadx~vESiH^acWnZhYo% zYfI=f+Jwz)<;iR`C!|toLLpc3ME5dTHGf}SEl-q{l_gMKl0L_K(qUUMnN08BxpN2Z z-@gyHZry_3-d?zP@giKfZ~;cg#-RV`QTX7UcOZ)OrOC6<=-3YdpPwh6yA?EQE!0?R zk?KIL(tycm;p-N&4a&>QQ`ZcJZNjl)Fc_jYZ{CEvckjaW>(?O^3c<|G3`|c?!-x$=BP8 zSn_QaJ17;ZCo*YuLSC(iSIgvaw0~inur!ra{JXlkc4R-vN4a03hk#bQx9_vc%E~Aa##`DL&qJTQ z<;$w7R`cMW?bW>HOC^$P*_h_hzU%UF{QYxvb#*iU_6CE3`H%cBvi+KxnwmcagTXkC z!??%eNre3VC*PZ&Pn&;>AfM((HPU822x2~1$9#}3{}(}iYN*J&Fdyuqd~K@y21oto z{M+8*BmaMpsIx%DwQ|$(7(`Er80@+651RkQYjQs{2X6Tp-fAmKb;fcCkMGUBz8_v3Le>2 z9bCBfzZZ!_KE=If%;)pP0-;c>xw$zOYHyFdhW7^=8e$f`DOPK<#k6W|OfHqj6mmrj z_na|>g09uSLJJ-uJwp0%iZ!9NwY7gec<=zuojV6(xUXDTT!g`a0a(Uy{r#1T(BE|w zJO|zU+~%mM1Eayrud8)hJ=kj;V9=XrZT(-QuaHRA*3x<9%9X$0yLS&JFh`v}eHx~5 z5BXYuKg^-5cNZ7n)gvKrH8w*>+hM4+)q+v~l)p-;0lm(Mdp8a39nK?lBDuCQ$NNqF zCnqQ2)TvW2h5ONPUmwhlj>7uFJiHP-!t?jHwm;>+p}#~T`zfx?dy%@3&%PAC$*K$Y z{y#(fe~D|a$7jx*;q}kN-(;{LJ~oiaJxQ&X_Gv;+g;a9aNL_PXEUtL9wzrM_b}n-3}+FY*nWsIeD9ACuWeZU1T`#MD9-;S}AiYQ?G?(A@+!1WqCjvW?eTR|1)f8X;@o)yb4RoT>1ans zv@aBjI_-5)o5hCfUsV+6`lt%`066d8KuA7D`VJD6Dm*v-jJ_#F=f)$E2)u>!@Z!W7 z{QJ;WXlZiu^Eu76W|I}?TQ$w+e?X!+mrB*j%F4sd{v#tP{XP7Aq|+MyA(tyYl*tq) zu@9Z+CVg5lFfefX`0?W(4G#~;$8oPXiTj25@iFjuy!_gN&WW`e(-+vsjwDnJIKMxh zz;y}rpZli&|1=uS@0AKA*-Y`2wy4$Wdc^S0lQ=HF>E8;6np*yC&}v`DPDy>!_D5_R zQU5Q_VqV(b-}4`<(KwK{)0T%QUyElq%RayV!-+TFjMKh}$N!-FYqP;X@^dYQw%f72ugCKSp3(1UF3v+1dzB%;5MT%}1Q-Gg z0fqoWfFZyTUvFa#I^3;~7!Lx3T$ H3kdull{6B( literal 0 HcmV?d00001 diff --git a/qgisplugin/icons/save.svg b/qgisplugin/icons/save.svg new file mode 100644 index 0000000..77028fc --- /dev/null +++ b/qgisplugin/icons/save.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/qgisplugin/icons/toRaster.ico b/qgisplugin/icons/toRaster.ico new file mode 100644 index 0000000000000000000000000000000000000000..d12897555d2c4dfeb24b97c92e80ebcd79827547 GIT binary patch literal 32988 zcmeHPc}!K=8NVnhxT01;LBzTdzzw&ER#w4Lqqs#Uu84|TRNM+C%^)Ox0FhH3I z1eL*3CyHk5m^$4i)BfFL9B1mF)0ni?wl*_NruFpqJM-?#=bVc^O$*QhwWK5seUuiBK3&tas3^yMh^FnwSXh|jK3LOAGc_#) z?%Y#zHUGZ*peILwntwI_zQ%xx|DNjsU+13mJ-PYA{_fym<@4^)qq}4(`^_HkX)d;J z-!AL|qT9$SEiDyxVWKTBdB4;K40LAe4LTX#Z=>Y7VXJ_h!t=+ou}l!};IKdGp3r zD;j0LqeiIt_u&ku;@|7@>S}*Ut zsdZK~PJOz;2B&N3_yFSu9?>SfrSY3+Nf}=D(qhukn%m{ zKe+lLU#@>kmMoERrRO*Gpf7a!p7Q@ykl&vFJ>{Q2?APOuekM5Ij5+2$YXF~9N6r(G znVBgjO`7Cx-t}=i@yGlSTuZsWa-G!?92_k3--CU+98bNz{(_BVV_vd0ykUVKVeHFM zqecnVN3Kyic+YV@2Z}9d$&Y;X{Rb|+YJW4sePIq)Xn?3-HYnJQ%r+7|3d2IYnfS(-HrUNhGcY=*j zi#fzSyN;8%UJe8RzP4Y30b|vOT8#OF|1AsNlvUv;{>^UqzvUh*s;(G~d+t-%7!!;Q#z}z#pP;wm{{-W|2Yw6u&IKRh`VS6#_lz4iPM-0$ZQCXe9Xcd(b92S+-Mhuekt0QTc=%V@*;)6q zvNzvn&v(J|CuEMsIWzH3Nl6ih4<8nL_wJQF_rLnSi~BO7va(V{MMYtMJf)@S-D@`+ z8m}}rUTuUNa|;^HL#lP6D#s;Vl93l}bk$jC?$8yoxh z?b_=1%5aveuBp5OU0T7@BY*DC>4ROncFCUmcmv5&64bNN=y zmAczk8tQL@zpMVt8I%4A2?=87&YfcO=FPI_*?{~D3JOF?Nr}X%Q>Vn3F=Iq@O!OCJ zm1Vztv*i3;{Qv2@@E7%G%&=MV=RRl1kRf95;K8ydZ=MN8j2I!;d9DFGqsX&({S$p1FDErwq_of${FH zUC++W7T2y_6PGSslKs-9OXa?e`#7H42*%IEi4(1ObIcR}=8YRS%KbU#kTQ4<Kf{F?8rq z*@uLL=--9@gy(#R@3S_Mb~oUz4aNi3L)J-xd)mUulPAkFdRA7J{BFYUC9FSqwi5Ub zpubPr{y;}sK5HKLnfw+&-?45W=E*;$BaGat2cpl`uh@-fc%{4V5H|7bkqrYj2Qz&?rluSvjoM?VUEN7`Y${5inC zL$I#~0s*`2hj>wsQ}(xkj?m{D=-rrX8o;^a^(tU3kPdJy zr;QJR`>3-|d6s02=emS*;D1w7Q@=)SY{lNc6?OS}N=nk76O$G`L40tnpA6grq)gUn zuF3iN`C`L{4YG#v4143o4Y?M9_tU!inmbi*SA7^47fX6h^DkWKd7eFf{J3D93kwSq ztUJxk%{u*)t3SVbqqe^G9&&=YOZj(P>6t4$Bl9~d*AT`v>wH>T8ufXWle6QG*eiUD z_3vZQF;-p&xMt)-|GTqi&lW3Jt`uA+Sc4WUSRnI(bqX>2!U3*Hj1k6}vmws&n4h$l zc5@A6UFLmWUY=fa^!c%(FF1DWn6#JcbwosjIC0{HXlQ7V_H)gHFddA~Hu9lc0cz(r z_+H(Ld21awaNrBBGxP;>96J98G+zSW0Q5iO#&92$j`M)tlm=|P##boP##bo zP##boP##boP##boP##boP##boP##boP##boP##boP##boP##boP##boP##boP##bo MP##boczHeWKenlPV*mgE literal 0 HcmV?d00001 From cee0a6b60b2ba919f76665bb0981ddadb68ee9b2 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 15 Aug 2018 11:08:38 -0500 Subject: [PATCH 088/142] exporta param geomorfologicos a excel --- qgisplugin/HydroSEDPlots.py | 1 - qgisplugin/HydroSEDPluginUtils.py | 29 ++++++++++++++++++++ qgisplugin/HydroSEDPlugin_dockwidget.py | 24 ++++++++++++++++ qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 18 ++++++++---- 4 files changed, 65 insertions(+), 7 deletions(-) diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py index 9b43cdb..9765ce9 100644 --- a/qgisplugin/HydroSEDPlots.py +++ b/qgisplugin/HydroSEDPlots.py @@ -263,7 +263,6 @@ def VarHistogram(self, var, pathFigure, ncells): pad=4 ), xaxis = dict( - title = 'Variable', titlefont =dict( color='rgb(0, 102, 153)', size = 15 diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 6266648..87ec35d 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -338,6 +338,35 @@ def Basin_Raster2WMF(self, VarName, VarPath, VarGroup, PathOrValue = 'Path', Val else: return 1 + def Basin_Geo2Excel(self,ExcelPath): + '''Guarda los parametros geomorfologicos de la cuenca en un archivo de excel''' + #Obtiene param de curvas + self.cuenca.GetGeo_Ppal_Hipsometric() + #PArametros + GeoData = pd.DataFrame.from_dict(self.cuenca.GeoParameters, 'index') + GeoData = pd.DataFrame(GeoData.values, index=GeoData.index,columns=['Parametros']) + TcData = pd.DataFrame.from_dict(self.cuenca.Tc, 'index') + TcData = pd.DataFrame(TcData.values, TcData.index, columns=['T viaje [hrs]']) + #perfil + Perfil = pd.DataFrame(np.vstack([self.cuenca.ppal_stream[1]/1000., self.cuenca.ppal_stream[0][::-1]]).T, + index=range(self.cuenca.ppal_stream.shape[1]), + columns=['Dist2Out[km]','Elevacion[m]']) + #Curva hipsometrica + CurvaHipso = pd.DataFrame(np.vstack([self.cuenca.hipso_basin[0]*wmf.cu.dxp**2/1e6, self.cuenca.hipso_basin[1]]).T, + index = range(self.cuenca.hipso_basin.shape[1]), + columns = ['Area[km2]','Elevacion[m]']) + #Escritor + W = pd.ExcelWriter(ExcelPath) + #Escribe + GeoData.to_excel(W) + TcData.to_excel(W, startcol=3, startrow=0) + Perfil.to_excel(W, startcol=6, startrow=0) + CurvaHipso.to_excel(W, startcol=10, startrow=0) + #Cierra el archivo + W.close() + return 0 + + def Basin_GeoGetAcumSlope(self): #self.cuenca.GetGeo_Cell_Basics() self.DicBasinWMF.update({'Area': diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 36bd15a..7c04807 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -331,6 +331,28 @@ def clickEventGeoProperties(): self.TableGeoParameters.setItem (self.GeoTableNumItems, 1, QTableWidgetItem(valor)) self.TableGeoParameters.setItem (self.GeoTableNumItems, 2, QTableWidgetItem(unidad)) self.GeoTableNumItems += 1 + #Habilita los botones de geomrofologia + self.ButtonGeoParameters2Excel.setEnabled(True) + self.Button_GeomorfoPerfil.setEnabled(True) + self.Button_GeomorfoTc.setEnabled(True) + + def setupLineEditButtonSaveFileDialog (fileDialogHolder): + '''Pone la ruta elegida en el dialogo de texto para guardado''' + return fileDialogHolder.getSaveFileName (QtGui.QDialog (), "Guardar parametros en un archivo de excel", "*", "Excel (*.xlsx);;") + + def clickEventExportParam2Excel(): + '''Exporta los parametros geomorfologicos a excel''' + #Set de la ruta donde se guarda el archivo + PathExcel = setupLineEditButtonSaveFileDialog(QFileDialog) + #Funcion que pone param en excel + Retorno = self.HSutils.Basin_Geo2Excel(PathExcel) + #Mensage de exito o error + if Retorno == 0: + self.iface.messageBar().pushInfo(u'HidroSIG',u'Los parametros geomorfologicos se han exportado correctamente') + else: + self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'No ha sido posible exportar los parametros geomorfologicos de la cuenca', + level=QgsMessageBar.WARNING, duration=5) + def clickEventGeoRasterProp(): '''calcula los parametros geomorfologicos de la cuenca por raster''' @@ -418,6 +440,8 @@ def PlotCurvaHipsometricaPerfil(): #Botones de figuras self.Button_GeomorfoTc.clicked.connect(PlotTiempoConcentracion) self.Button_GeomorfoPerfil.clicked.connect(PlotCurvaHipsometricaPerfil) + #Boton para exporar datos a excel + self.ButtonGeoParameters2Excel.clicked.connect(clickEventExportParam2Excel) def setupHidro_Balance(self): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 3efca3f..9629c96 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -6,7 +6,7 @@ 0 0 - 487 + 493 936 @@ -900,7 +900,7 @@ - + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico @@ -1339,7 +1339,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -1374,7 +1374,7 @@ - + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico @@ -2834,6 +2834,9 @@ + + false + 20 @@ -2853,6 +2856,9 @@ + + false + 20 @@ -5204,7 +5210,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -5451,7 +5457,7 @@ - + :/plugins/HydroSEDPlugin/icons/toRaster.ico:/plugins/HydroSEDPlugin/icons/toRaster.ico From c7aa1e073eaeefab3b17bb0ab576e02b4c48dfd0 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 15 Aug 2018 11:24:52 -0500 Subject: [PATCH 089/142] se agrega la opcion de obtener histogramas de las variables del NC --- qgisplugin/HydroSEDPlugin_dockwidget.py | 32 ++++++++++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 56 ++++++++++---------- 2 files changed, 58 insertions(+), 30 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 7c04807..a7ff0c3 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -817,6 +817,33 @@ def DrawClickEvent_histogram_WMF(): self.VistaRainWeb.setMaximumHeight(500) self.VistaRainWeb.show() + def DrawClickEvent_histogram_NC(): + '''Hace un histograma de la variable seleccionada y su capa seleccionada''' + #Selecciona el item y su nombre + selectedItems = self.Tabla_Prop_NC.currentRow () + ItemName = self.Tabla_Prop_NC.item(selectedItems,0).text() + if ItemName[-1] == '*': ItemName = ItemName[:-1] + #Selecciona la capa + if self.SpinBoxNCLayer.value() == 0: + Var = self.HSutils.DicBasinNc[ItemName]['var'] + else: + Capa = self.SpinBoxNCLayer.value() - 1 + Var = self.HSutils.DicBasinNc[ItemName]['var'][Capa] + #Obtiene la variable e invoca la funciond e grafica + PathFigure = '/tmp/HydroSED/Plots_Geomorfo/VarHistogram.html' + self.GeoPlots.VarHistogram(Var, PathFigure, self.HSutils.cuenca.ncells) + #Set de la ventana que contiene la figura. + self.VistaRainWeb = QWebView(None) + self.VistaRainWeb.load(QUrl.fromLocalFile(PathFigure)) + self.VistaRainWeb.setWindowTitle('Histograma variable') + self.VistaRainWeb.setMinimumWidth(100) + self.VistaRainWeb.setMaximumWidth(500) + self.VistaRainWeb.setMinimumHeight(100) + self.VistaRainWeb.setMaximumHeight(500) + self.VistaRainWeb.show() + #Vuelve el spinBox a su set original + self.SpinBoxNCLayer.setValue(0) + def handleClickEventButton_Eliminar_Desde_WMF (): #Selecciona el item y su nombre @@ -858,10 +885,10 @@ def handleClickEventButton_Ver_Desde_NC(): VarName = self.Tabla_Prop_NC.item(selectedItems,0).text() if VarName[-1] == '*': VarName = varName[:-1] #Capa de la variable - if self.SpinBoxLayer2View.value() == 0: + if self.SpinBoxNCLayer.value() == 0: Capa = None else: - Capa = self.SpinBoxLayer2View.value() - 1 + Capa = self.SpinBoxNCLayer.value() - 1 #Ejecuta la conversion a mapa raster pathMapa = self.HSutils.Basin_LoadVariableFromDicNC(VarName, capa = Capa) #Visualiza @@ -1101,6 +1128,7 @@ def set_dxplano(): self.Button_Update_NC.clicked.connect(clickEventBasinUpdateNC) #Botones para graficas de variables de la cuenca self.ButtonDraw_histogram_WMF.clicked.connect(DrawClickEvent_histogram_WMF) + self.ButtonDraw_histogram_NC.clicked.connect(DrawClickEvent_histogram_NC) class Tabla(): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 9629c96..7b12819 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -250,7 +250,7 @@ - 2 + 0 @@ -294,7 +294,7 @@ 0 - 0 + -887 443 2018 @@ -1345,9 +1345,9 @@ - + - true + false @@ -1365,17 +1365,17 @@ Qt::DefaultContextMenu - Grafica el histograma de la variable seleccionada + Convertir variable a red hídrica (promedia celdas del tramo). - Grafica el histograma de la variable seleccionada + Convertir variable a red hídrica (promedia celdas del tramo). - :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -1386,9 +1386,25 @@ - + + + + 50 + 16777215 + + + + Capa a ver (o editar) de la variable Nc. + + + 5 + + + + + - false + true @@ -1406,17 +1422,17 @@ Qt::DefaultContextMenu - Convertir variable a red hídrica (promedia celdas del tramo). + Grafica el histograma de la variable seleccionada - Convertir variable a red hídrica (promedia celdas del tramo). + Grafica el histograma de la variable seleccionada - :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico @@ -1426,22 +1442,6 @@ - - - - - 50 - 16777215 - - - - Capa a ver (o editar) de la variable Nc. - - - 5 - - - From 4b53b0dcbe5b5f5db7894e4c868042258142441f Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 15 Aug 2018 16:33:45 -0500 Subject: [PATCH 090/142] acumula flujos y no se que mas --- qgisplugin/HydroSEDPluginUtils.py | 38 +++++++++ qgisplugin/HydroSEDPlugin_dockwidget.py | 64 +++++++++++++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 90 +++++++++++++++++--- 3 files changed, 175 insertions(+), 17 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 87ec35d..c442381 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -559,6 +559,44 @@ def Basin_GeoGetParameters(self): self.cuenca.GetGeo_Parameters() return self.cuenca.GeoParameters, self.cuenca.Tc + def Basin_GeoAcumVar(self, VarName, VarAcumName, WhatAcumDic,VarMaskName,WhatMaskDic,umbral): + '''Acumula una variable teniendo en cuenta una mascara y un umbral sobre la misma''' + #Selecciona variable de acumulacion + if WhatAcumDic == 'NC': + Var = np.copy(self.DicBasinNc[VarAcumName]['var']) + elif WhatAcumDic == 'WMF': + Var = np.copy(self.DicBasinWMF[VarAcumName]['var']) + #Selecciona la mascara + Mask = np.ones(self.cuenca.ncells) + if VarMaskName is not None: + #Si hay mascara busca en que diccionario esta y la toma + if WhatMaskDic == 'NC': + MaskTemp = np.copy(self.DicBasinNc[VarMaskName]['var']) + elif WhatMaskDic == 'WMF': + MaskTemp = np.copy(self.DicBasinWMF[VarMaskName]['var']) + #Con el umbral convierte a la mascara en una variable de ceros y unos + Mask[MaskTemp<=umbral] = 0 + #Variable a acumular y acumulacion + Var = Var*Mask + AcumVar = wmf.cu.basin_acum_var(self.cuenca.structure[0], + np.ones((1,self.cuenca.ncells))*Var, + self.cuenca.ncells) + AcumVar = AcumVar[0] + #Mete la variable en el diccionario de WMF + self.DicBasinWMF.update({VarName: + {'nombre':VarName, + 'tipo':AcumVar.dtype.name, + 'shape':AcumVar.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geomorfo', + 'var': np.copy(AcumVar), + 'saved':False}}) + return 0 + + + + def Interpol_GetFields(self, Path2Points): '''Entrega una lista con los nombres de los atributos de un shp de puntos''' #Lectura del archivo diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index a7ff0c3..ff3a5cb 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -353,7 +353,6 @@ def clickEventExportParam2Excel(): self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'No ha sido posible exportar los parametros geomorfologicos de la cuenca', level=QgsMessageBar.WARNING, duration=5) - def clickEventGeoRasterProp(): '''calcula los parametros geomorfologicos de la cuenca por raster''' #Lista de variables a calcular @@ -392,8 +391,8 @@ def clickEventGeoRasterProp(): #Actualiza la tabla de variables temporales for k in ListaVar: self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[k],k, self.Tabla_Prop_WMF) - self.ComboGeoMaskVar.addItem(k) - self.ComboGeoVar2Acum.addItem(k) + #self.ComboGeoMaskVar.addItem(k) + #self.ComboGeoVar2Acum.addItem(k) def PlotTiempoConcentracion(): '''Plot con el tiempo de concentracion estimado por diferentes metodologias''' @@ -431,17 +430,76 @@ def PlotCurvaHipsometricaPerfil(): self.VistaRainWeb.setMaximumHeight(400) self.VistaRainWeb.show() + def clickEventUpdateAcumVarMask(): + '''Actuaqliza la lista de variables existentes en las tablas para usar como mascara''' + self.ComboGeoMaskVar.clear() + for i in self.HSutils.DicBasinWMF.keys(): + self.ComboGeoMaskVar.addItem(i+'-WMF') + for i in self.HSutils.DicBasinNc.keys(): + self.ComboGeoMaskVar.addItem(i+'-NC') + self.ComboGeoMaskVar.addItem('sin mascara') + self.ComboGeoMaskVar.setCurrentIndex(self.ComboGeoMaskVar.findText('sin mascara')) + + def clickEventUpdateAcumVar(): + '''Actuaqliza la lista de variables existentes en las tablas para acumular''' + self.ComboGeoVar2Acum.clear() + for i in self.HSutils.DicBasinWMF.keys(): + self.ComboGeoVar2Acum.addItem(i+'-WMF') + for i in self.HSutils.DicBasinNc.keys(): + self.ComboGeoVar2Acum.addItem(i+'-NC') + + def clickEventAcumVar(): + '''Acumula la variable seleccionada.''' + #Toma el nombre de la variable + Nombre = self.NameGeoAcumVar.text().strip() + umbral = self.UmbralAcum.value() + #Variable mascara + MascaraText = self.ComboGeoMaskVar.currentText() + if MascaraText == 'sin mascara': + VarMaskName = None + WhatMaskDic = None + else: + WhatMaskDic = MascaraText.split('-')[-1] + VarMaskName = MascaraText.split('-')[0] + #Variable a acumular + VarAcumText = self.ComboGeoVar2Acum.currentText() + WhatAcumDic = VarAcumText.split('-')[-1] + VarAcumName = VarAcumText.split('-')[0] + #Invoca funcion para acumular variable + Retorno = self.HSutils.Basin_GeoAcumVar(Nombre, + VarAcumName, + WhatAcumDic, + VarMaskName, + WhatMaskDic, + umbral) + #Actualiza la tabla de WMF + self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[Nombre],Nombre, self.Tabla_Prop_WMF) + #Mensaje de exito o error + if Retorno == 0: + self.iface.messageBar().pushMessage(u'HidroSIG:',u'La variable '+VarAcumName+' se ha acumulado como '+Nombre+' en la tabla WMF.', + level=QgsMessageBar.INFO, + duration = 5) + else: + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + u'No se ha logrado acumular la variable '+ VarAcumName, + level=QgsMessageBar.WARNING, duration=5) + #Botones de ejecucion self.ButtonGeomorfoRasterVars.clicked.connect(clickEventGeoRasterProp) self.checkBoxTodos.clicked.connect(clickEventActivateGeoCheckBoxes) self.ButtonGeoParameters.clicked.connect(clickEventGeoProperties) + self.ButtonUpdateMask.clicked.connect(clickEventUpdateAcumVarMask) + self.ButtonUpdateVarList.clicked.connect(clickEventUpdateAcumVar) + self.ButtonGeomorfoAcumVar.clicked.connect(clickEventAcumVar) #self.ComboGeoMaskVar.activated.connect(clickEventUpdateComboBoxMask) #Botones de figuras self.Button_GeomorfoTc.clicked.connect(PlotTiempoConcentracion) self.Button_GeomorfoPerfil.clicked.connect(PlotCurvaHipsometricaPerfil) #Boton para exporar datos a excel self.ButtonGeoParameters2Excel.clicked.connect(clickEventExportParam2Excel) + + def setupHidro_Balance(self): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 7b12819..444f472 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -250,7 +250,7 @@ - 0 + 2 @@ -294,7 +294,7 @@ 0 - -887 + -300 443 2018 @@ -2263,7 +2263,7 @@ 0 - 0 + -147 443 1918 @@ -2589,6 +2589,29 @@ + + + + + 40 + 16777215 + + + + Refresca lista de variables a usar como máscara + + + Refresca lista de variables a usar como máscara + + + + + + + :/plugins/HydroSEDPlugin/icons/update.png:/plugins/HydroSEDPlugin/icons/update.png + + + @@ -2616,6 +2639,29 @@ + + + + + 40 + 16777215 + + + + Refresca lista de variables para acumular + + + Refresca lista de variables para acumular + + + + + + + :/plugins/HydroSEDPlugin/icons/update.png:/plugins/HydroSEDPlugin/icons/update.png + + + @@ -2639,7 +2685,7 @@ Nombre de la variable acumulada. - Nombre variable acumulada: + Resultado @@ -2657,20 +2703,36 @@ - - - Qt::Horizontal + + + Nombre de la variable acumulada. - - - 40 - 20 - + + Nombre de la variable acumulada. - + + Umbral + + + + + + + -999999.000000000000000 + + + 9999999.000000000000000 + + + 1.000000000000000 + + + 1.000000000000000 + + - + Acumular variable (cargada a Variables WMF). From 8b05e52519dfc5e7554b6c7351bded2d1becd393 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 15 Aug 2018 16:34:27 -0500 Subject: [PATCH 091/142] se monta el icono de actualizacion --- qgisplugin/icons/update.png | Bin 0 -> 22811 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 qgisplugin/icons/update.png diff --git a/qgisplugin/icons/update.png b/qgisplugin/icons/update.png new file mode 100644 index 0000000000000000000000000000000000000000..2eaaa0c3dd9bf0a0a1852f249246cde654b8677f GIT binary patch literal 22811 zcmZr&2{_d0A0H7FLgXwH5^c_0$)IvoDwQol&T=zFX~s38+(%UIMv-KN$`ytocVk2tI}RS-T7O-DZ+Abh0pFA3TW|I^jL*H_cXUjl;N3J=aJbYk`?tuQ`y>^Dc0}%Y zd#7xULvoe7BJZ$Nk)+CD$!`?}xRrz@x2fK5T9W6|AGVHg=&scA1kQ)R8MjtdbagdU zb#=?+=0&#fAm(dW!5;|?(~EHU;5w@~YWOY(_(M9XCwID;L?Xqo>Cim~IR5(QyFD0d zjg6IN2BV)^<8&@d=FjR$;^L&n4Bc7H;4qknO{7UvI2TG8k5x^CDMA z;XhWmlr*8Z&m9TdvVoGGKd876cQE9~l;hl62SuGdU^vC3EgP(U=#8r%;A7t3e{6U4 zJxz#Lfk!y#*<~9Ac2Di!dENh-)ObG$<7S)0;yfX6dFJ~JOD+4KM})h!aQbc;dm=cI z@jh)SS$3`(*VKbbg4uTAAp1%K%yHJ&k7jqo|8*5LQArbGK^Kj+mjhjn%*XDlhyQ&?t$Ft>>V%YF z=y2V?$G{4Go2?3B30nDU@79-5#)u2seoTLl#=GaQorSDO9r^q07mQxlLe~!Nel*VZ z?{oVxQ%%U<n?dF z6Rn%i9ke{2aA(Qp_>b;yMs4QLt?hLwU&1esXM&%0rprhFy#njED1*78R#>t3jze46 zpZ@djqbO+;QUL1%=VI^4BKZh7Q;r0#*Gqf03CHd{F)qqL=vxFwv+~6Af(~qYa zVcK_IBj$0iAICyo_>G12ynETCqBCsAvpd^Q{JlQpM^rV7Y)Pm0Tv90O+_n>pzm7?< z9C!Mqnm-HcgRsAk#(ESzGC0U74Eu2#*YEe_&r5y&>yVRniU^F>UHUSEbI=7ZC11u|uC`h%V7A^Zx(}_ORSD^6|HQ|GmLB2j5pq3W z{5YeARgn*ux!ijl_C@plZg5tH&2mdLYy>(v#9VelA;Zhg7qk?4M z@Li4bxP+XEYL@0QKg07}!a)}{FC#4@qc88Py1L&ee%MHP2$@{?i7?SiP%JfYEa~=> z0R4nGNj*1)V9~`DOBu_1f|0P(n~R>Haee)IncX&?bgsdxDsM^1tr1u7?Wjq5`kq1w z`0(8xQ!HkAPy=@V@~G}idC2(PiLIOc%A#@}rB1zvF*+{z#>KsvjEf|nI7>B5>*PP% z^|{>2a~mDTgFA_O9K<49YPl$+3cLTYl1&2KTat*i2D|O?1)CYZU;~T>AxVr<}9>jaWs5~^qmqi)_UQW+b5X4#ZsIq!4iRiWDcjL!Wz2QSi=Sb6+qshr}d zN}d0ES7ow_uUIDEtSEjk)yH=bYz`9&)g_JG^0(8s^5D9I3hu$dqsF-}ycZ67SC3gR z;~yu5(%nMo@`mJtF@^!_r5+sl`hm5q$nCn&*<6pBP%1o?u%g&l^tif1Fd#dNu;$)P zQr1@~^$-|T6uHb{MlieTf$u6Inz~7*smGj9&qjtkPJDDo3TuGBu;1q6{tZvdDOtags|J{$ z9@Yg?*kRaR+PzIdS_(DGzic+y_2rGh&U}}(ay19*X;)gH(X`@G3!4}6^aWO}{uW&X zU%7k%zU+#3+3{CvO{Ro0QA!jyElrK~(BOGu>v-a`p_=K7jCER|g&1tEReEj;4@s}} zGQx4NkFWRIN$iVL)`cm$`EvAj*2>P??*`;sGsaf^n%ut0)gQIS+E?qn@$YM=RB=04 zD_tn`=qvST4V=`N|1ycL)tbHYe7t*OFez%V3!{0XR0&cQ@+fe-#o0Y#2@}Ezcf=^I zF$S2(#b&Ea%h6T85O$co_7Oy#S4JthDU=)%O1}T)lcih97rl@8Vf4S0z+5d(-co&T z=*E+}>BjVeWReO&*OailY_&&j)xm0k2CnKTAMQygJt>v$Ph@yWdA;lQ#VjHz|DnRi zy-F-RE)Cqq&WHw-<}d9I9mghH%dhEKEw~+txf1U77M(hNppL3r+C1$R8_=J+&?rDT z?uxDsU1PU>-j%u-e?`QIGm&JB-~y1z zcqelou2Cg30zU3g;FnL+5(OzE1J}a~RP{G<4X}BSzLZ!ouY zFuKe2HeB8d_l8XSklDwtOpssouv##^RKhZv>N4olK=mdvF4Qr0S&~1NxaG(blJ1h} z>`yx{lB#S(cjBbBEpRB7Aixt;dv0xOUOnj9K6q@Wx3OpVp};4iuy8j+R3>IRl8!V> z>v8Lj%e~TlH`(kB?YC#$^IN%&iI4JFi=rEajV-B%=en6~*YF$)Jxz~!vO5jKB~Z^$ zg6pUFuU8eN(55W3-wdtG-UC-c!x>jz?y;sG?HBFH zB(Tc7$-c1?X(eQ)^Bx#V3Dn-eZzTpBotG$CYGdi$H`41~{PA!%0ndcolwB>BDuc;? zh|qS1jVE^U*tGXFKISpH#$V5g)0y`X&UE8$kx^?gew-~n5?j7z&pZx{v!VuYWZh{L z?nBeD-sxGL(y^bkiVn-gbobOhj=Rhb8{KMMh>oN$r_x(P>1v_$Hc*9&j>tST_MuSTONq*2Er|Y*i3ci!o7QVVMrC()x_hc;9Q&aZc@^hQWPo=y#`2{ZR(wNi;|mveAEe)!3EtxsOln7LL1peFYmu@oNNI+%b?owW66 zxuYCiK?yiiz+mTwft7|9GHfOax1VhGSMbfa%Kr3;sX3n#?0UEm%6L5Gk2f*W8FlmK zzr`uW9l}?$9Mh?3m7PzFSyad*tdavp}`>T5x(PyD$`5 zaNjl=XB{)(4}bP-xA_PYI5D@2O_@!xro&<`JB6ey*Qbo|Erop@{Y-WHnh$!3jLd%A zuXuLe|2y}w+-$5LUUd)3h!^ODCWOJQ^fzQ4VezVQm&~ZqKa$RYgX6S53@>V*jhqa> zN1FJ@$?Z8vvi30B-Ev=8JYe(+_3^u@Y<|`tMsU)}1tA)!tJN3wv=!0?}Hn$h4k291;0)~O+>Nzom+2q8Eb9MsS0eKjY`I&B{YvRTcI>^ z_KS;0@&-qplr{Dc1wZzO5b#aF&cE_u=tXwekQF_yTDRIft?w5?#~r!iR?r3NHj#PO zf-10PMbvhIjSMY)(NQoGl5g-?8by4{m8M?zmbK2|7|H^pT;O}98MY5UEbXb~K~d~+ zEeSiukO&=?e-CM=w~zhdbq=plsq~JUT~YFfqriJ`7H_!%Y>G%d+N@`!W=Rx$oyfnU;-PgqfD_D&PNio-GgEJXH+2n2`MHt`QCeWqj}R=} ztpd%z^yQi1*ED4Wdqz&O?k=+`RjY}1a6S~8jeKmE#MAWAXCmoSmXHmAHGGsn!%>F|6+*QRwreLFxKHUTUWcfd=jkfIOQNk zE4sNod6{Q)cNIy2^<&$?SKEYx4%e$)#R1RwN`ZQkJ!*ekPRfvw**cvaMu#Df5f`}s z_~U@`9K8Mz+80FB{*_K_4M8lz_usvU(oj>=v@5O_t&@7=m$YGKwbXOti4;(a?D07f z3f@iq0m^gB=5-pPN?m~0_cYg%@lgDZ}Wc5;y4Y+Zzc2J2(N&2HELw_YlF*$-D` zwo^Fh#GwWF_x@UH4Q)%fTO>-YNxSj#>N&2sYc%jcZ+2xI@I69h8GJe~KwA&(!z+HAV(ODzuB@+0WS_@dG@kmfFK>!-Nl9xa?4fT#in73pA)-ay35uV2cYXv7%jl_7gYXhZESR17Brr)D==UWzi z=voyM7XLb4ZkVyxY`tVtqT*?Ct66qB+h~yE!8zC%GtG0Wgt;@+r~<9#0Ijm*Ff@0& z4ZSrkT3L{y4OE68?(5fsUd5{tp+>7fJdsg(%tzVccm0EUc(9Jl#m}G3xBoTVmy(V| z`PCd@agh-hTKBstqy(fAgp`pv2k6UI3L5v&JPRC!TamQIMrF&z$HL;hBfXM^U_2iU z7lHBnl%?kIe9R+r6h z9u?-9Z28qW04(l1YH+sQe2TO=79XuTyJQeft5*C0g3Q#8cnnmak!C3*d(^c>^@A-b z;1csYv%t&DtfD6IsDdCPc{zappE#XoCrNo#N?7~~WkCeIkh=G$h}Enq&UM=ie(; z=s2UIjHv0@uNaeu6)T{zfeV#h2rt+jFG>lpLH`W1G_~ewwcP}+lTvhz%Ki;OGwn4< z9t*X^Z3qNEhr#8?X4FMs>gYbCZILXjN|Clrt!@=DnnqtMl@K+w&`IObKPE!Q5aOVZ z@dCyPc$AH}xkLX7>V0sy+}xJ!MvHK;G|pEnN7M>@K{UG$K79MVso;PczcweWdhXwj z`HV1HOr7xi-h3uc-8S4nn?B}()zYgJ_1@ zX&+mq3{FpjsNH#CY8RK(yr4Pj{QGxPz1UMytgdRUvy0$lTrHSNrWJ!;!Ra@9_Sbp`w)bn>!ny*-n1*)`EwubKs zL1!p!de26!eM*|o_QVf42;c3QGFAD`IrfK>!7VnRcD}(I7=C)HpsBlfFh4)CuQcTH z(bEBY!BTy2p~{NkdDuP?7+J#)arV|$6?hO33ZvJRk*e@Pp32mvtPe+Q#`80i=(9af zG$7}uW;(fNq_X=$cM%eDg9TSV6BHY9a1<85gqb`W{9&8VEgZ2!tVy7CNmzXNc3sga zZD7QGPQqjSgUTiq9t#dkD;3t_;LbmsR?q{XM?KEPGhZ=&FjJ=f66yBXo)DmWs17Y% z5UxO2yDNa%z-4r^*Q|N9RIV28`^*=CZyp1SvD^W6tWe!`Df`MT5UgMmEgD3i*KtGi1JKS?6DFM^FCaj~4I(oFUz9 zG4FGx(=F`8D~?dJMV(5nV_G?{C2e6JwtfGEZcN|=@?{zA^r&K}eM%^{J45xkwWofp zVEh;0h3m>L_1}1s16-B+e>mkA4nimZ@APN%FHk8MCz5^;oXqTZxs5vohcj|T){$q+ zl*`bx&`TlKq}x5{!@vnN$GRRP%}dq%W0yoVt3xm5nt zD<{j`CQ1D8?HiYCsv6%mK7+rRXH+f&6IZ-z!;Z99jt8N5?6uUeh_O!4Nc>ssTe49q z`I0*AOM2O<)0uDwWnDpF8~L#ZDkPIy4#ASds($T)}N)o!+co^#juj}EsI%&I4_yL^__Z* ztT9aj_x1KFVewq@z^hZ%xg~?TZtHyAu&35FmgJhJde7jjjnkJ`_+}c=9}+ei=1+={ zGBac|#~d9U4c~r&+d+%R8O&{Y%|Ilza_i~d(7)k|HY7W%`lVW5PneUvXq2hzrAcI< zIyq6sqw&5hi>#v=rw0iHLbx4MI#rt+LBH!5AiOG-&T_0ONQg=k;_DS!Wmzy8Q~6}t zKGQ-G$uBI>`u^tS#5_A}iNo3nLDQM!sMo!Ob1kWevn%H&Vn0^38hGZ5tr=LBc@By# z;pXEceYb#BZA0}nxe-I2!g)73=ecOT&fm!kAk-~5Jn_l~-*!U#jw9?mX83licS*Ux zI{SjjRug^KNP3{E-zU^mpDA(Gu+w`2nse|XI(2bmvJ6$fiC+7>>}t0$ERqRxdc=%! z>ysf7JqE;<_Ar|cEGfR!ozEOaPp~~5T5YA3F?p&^ofoOKPIn3~ecJo5&f5UvLQHiL zTk5CB)vZQAjmf=3U$mX zEx%ZT86WYBRW-mySh$L%YV+X=3-=-`gvE`=)ZCX*08qR@bH8Y!k6*I-FSL9{o2%x% zB{Q>^BP1tzuFRlq(Rvm{m69Nj0M5psp(BxDqmX178aORdI2qt066ABv&Y%YNh;L@A zpne1a^s``KkjZ6sDE%e?l}+*Bn$d}fz3bil);|ZK!Bx#4Fqy{fGa)S?`0REqxg;#! z4xDsNaj>(vojWQ5)iu(L@CF}fzr>)yRg>@WdLL&(K8zLdXxjQ{h8is*(mIvF>G?L8 z>Nh-v<7-I9NAv?E*zYk=v{53@%tCOYZI9tS;)t%*0`A%Ri%eokZIySnhw z8G1!Lk5)Fi&AX4(S1beI95y9_Qz)INW?L8B{*PtN$Lx{xF!y=d%VEgCyeDux?Om&z zu7^Fv)=nq(xU26p#LK7r?diUB+HlJ1<+x{bOPViVzi1gm6dBR0tc4SZeBFq^Y5qdX z5t7C06g0BIpCdJZ7v+!6zwEaywF-|@02^6mQKhbXljQkBfbednq!_2Xv%$PF_ z+B2?W!-$d7mqR=b(T}F8BuWJg-E)N3l-Wh2)xq9`DYY74wD6yV?XB=kOH0HH{G4uT zQ6bJ)&TVO1YQQ{-yHA@BEOiggu}C?Dc{O202-gv4WZ}6!7f?QVbv=pIiPPz~&!x?7 zAJf;z4^oCeBz}o^x|R%*0br&;s+C8^edcWHPe$_!SLquvyQ&ksVJOq@YWB`xbDqW2 zWc~}J;fC5G1Dg=$Y~;_LY-)q8mSoz;^Z-iy(cSjipK+;gO!T!wgoFyM3z5e+eCmG@ zuZx#M@=pzhQfA;L`~kN;J*TaCr&%y^jZw=ox{3TW5D-43G~6LPY! z;~4;FaiJIin;M7yXoHn{yM0|O^8Y1m_?Ss5MY$;QQZ78cF&aMHjE)@lRdqt5OF!K?XJQhYrTMVQ%?Wl< zhAD>u*~GefWL;>=A9YkMLP+&|U=R>NqYwP?qNzp82(v!qG4BHpb5cy2&uP;xDa23h z4=io2<8D1i2*J{P4%1j5ae7oY`@5=B99j}T^zJ4Frs{MU9VHS}+*Rbr^a5Jrq{c$W zeq5NymeIB8%J}xC{R$SU%T<%Fu zif#zBn)hO2VuygMaoqcR?1bz3RaGaD;-HJ<<~tdGyR6@2KrLmXWhwFa;zC{;U^3GB zN_kd=M)B9MlDGG#7M0;bO?A15Del%EVb5P-k+G{?Z}0nTuSbL@_S_nfYR6x7TjdQd zn*NSYkD|=%C0$;1b8aKk{8=Bo^<~~Q%`b>O8VHgCMGRKj(>u6SweB;G z?Z4%0d@u}*q0EdNw00d)YD6S)?NP$vRgL16wTbm& zb=Y8%F-T8Ica^DC5zl^1uNsMHR!vpei|8peIp?c=h@!vv^|> zDf=HT_PMVfX9IOpbDfB2zEl-$C=NP#OWSf$EW7h}-LX5(EJdw*vjgv=KOPdti>~)2 z{-i5%tMgl^#;T@B)RPMD@FiR5pa{N{R*$|x#n_dus}my09NJ?6d)NCCe$g3}VM27_ zCFd7dP1>BERYyafSb*1wxCa54qFyU;Ge)V0mUDI%`6wX?JO3>m({MsbMM`YhdmK2;inj+wsEhzkaQlRzc|Hs5dp%}$svw~_f=JZ z@S=A`)YCBc;m0%D<_{clv-TByB?CBXy+HSRdq8Ms(ZdHk9$)j5729d<@mCg+LO9R+ zx^&J|vbOV!@a4-+bniSfFYu%(A_@E)=Kx%AA@NJ%bAQ=H8{2CA)(%2WCg!I8jg_sM ziT*-F0p&RIfb)w*>KBn9W)FNLIz`%r{*jPl51N`1CZ1s=n0Dw^L9IXdiJjUekOy>H zvG6fV_{fKiDB^nR_z1YNgK(f#koeRqWMNg)`ohr%IPTF@PoP$w7A`rp45ZRO ztCIDUb$Mvg7K13_6N8NtjJj8jI-EoSc@iI5xL$1lH^6<&h9}X!{M4nc&|-4k&2-j1 z*<}vZ`c05~4AjX`pqdH|la-P=b}&(QV#}Njc)~3-Qfb_XZSGu`+;mOxc%2~aEFno2 zJ=HZi^pWt4z}{qji#zq;3GwzY2#yAc%EBch>UKwk7s~L0Qk(nqU3*PbFaqm+)+<#3 zm=nN{ICtenBG7XNDh5ra`X)i|USv4wV|$ub`&^PuOuThOV^(XE75Q`yNLFlF@4NiN zuSgA+l8knYd{h<^ei=L~l6N%vrtXx9@{pZ=Y}*MPNSi3~Rf(?FWSv}`8y%g?Snl`& zL)j>x%{CtYUiCr$mTc<5qabG{QLiS3=uubvieA6s6#}B|SL8b00AZT+(ZQ$UY-+Io zAR(nk4$Bp%Y){Sg!^%@Hhr6kxZuc?VOfp7xU8R6@qvJt1goGw-E0aRfUYs;sEBk-< zzC&P79Yavn^cD_6!A4WLu}GM2anN*Cep~!WH=Rcp6~GnaF0bidE5;aOv1{!6hQ5g$ zR|XoPLvW8n%f!bs@e4kCiXA&#Hz#(m{uHv>S8(cFi8BCT;s_~BqcWRkv$5(dGf*b!Q`Sj@Z@EM?9j)A+) z15qSz&&+&>I*Q>6{U0<%Wgh?LVLX#H7mXa$chpwi-y(5EpIiSeRG03;)wA+ow zrnE8V7n7(Z-vG{fH7$hR)KQ6C#jED8ZN50@#Ky$wQ zLa2F98*JvLPUWOxp_K2oQK9#+*S^veV^!RXY4Hf)0w~^^Z}j_khHnAHN>J+$uo(%a zA^y6ruf6aBXHy>Flz{85dO}Wz+?P4JxVNp)G1ZPwD8N5xKhrzvl3;qGvvuHhlP1f; zbhL(b-d?c&_P$ewAm#~y+N-qow4Z68FYaE;N_pF0*$hLxJol)&{A&e|9^>dlOq_;{ zvW?^@@OGCt7KTEEtX!fTEq2W*sG5F9Rf+|1^hB;Q>-9U1Gb+Z2M2|ipn)Gkt_$`}l zbIb!{9V3IB+SQz2%q$d3D_Xp^F4ntrmjS?OVwD2=U6=3cC+ z2X~0uL_2;E2LSrrqrD@pYnQ@puDLz(tnt5c)T9WcEHs+$2Cq;qsoZiAu~#A=N=A!hbb# zwXfmlU?39fX0k9q{u#RY5iZPqpBS9sYNWQL3T>z`nr>Sntp!YTa zzhxgh0t7-3U^q>}`^|~{U%o5&_pLI{u#aZ|24Xew z=Fbj*+!ciG`YI}2!L_9Ei|-H|tf%kb{K6SER`P}Kukp>PEQF+N$cb85rTt&x`G#yv z?S<3%hAIYiZtvPg{%j3d3z{@|8nLTse_?U-;>Zn%{~HnUBE&H=wC7d1k!>;{MHM56 z3>RRGP>i#kHqB+rTi9)7iM1(!0{AQ?bEM0C+4-*%46hES?_x2@LuN5gP%CybpZ~ol z7fKfJ9LBjN0(-}x>!82Ah0R;iIFHe0p0cdy1hRZ1@@X;>bf>BhmsW4W4vwhepJl~E(BpY&6CO8$MnONd9=@N zKI4`{kN`(Z$6X-YVH>k7dd13zcVAFP4!+(&lRiAycLBq@v9+x)F|GX!-~7qJyN;2^ z7%3zrIjuW!NaEX_`i!>?X`bpYlx;Fc7u?Q+#@eL50~LbA;#+{YunibEaTTE$X}FDC zwVEU6LaSim$WbHU3DtpIk->V&^_|xhjzo@!Z7!wV!1={D6i@o8+99{yLth(z-wWE4 zWN&W)8V!*~r@zEE+#l*&mI0i)@y_(J+5ESLD)I|B4`U_|u~QT5m!0TkTIv7F<(wL{ z2i2BCkn*`gz12CCIhw(99kyj+yV=F!;i)aEru%VP?PvC;nowlK5-Z=69ejPg_JG*{ z>H@qSQLJO2z!dWM!ZK;iWs}#9%iB0@5nQxpCkB>?{+3*+7>br1d~g6AAVW`1O-%>a z(V#*Yss~ogsCeg6Ss3=;_=1eikuM1wz>y7~Py^(}Q5+?Z_*RmBB8M&vN5)D8_Ku1q z;-RCV*<=~4&;FFh_Ob|eI0<5X0d5l&c$8iB5flB-yz9kzMS{hbA(NO)hY^yRQCd!b zSkpPA@H4#UoEq%#(D%30gTG;Yr9$bF$TV};G|7tWK7Xa6W5BXOfEt(bK8dE6m*@M5B>F)wJ5_D@!WB5hx5NiP_4+A1eQ&vdy9VLYJdh(yWLyU4b$M-* zZEaGtvWCba8$vQ?NsgA|@xGpGB%Iin*=7WoAtQ<6Si8Xe6yxVenJ4#F(|%a}`@`=n zY=B^d=A_`$dkr?vQ^4m|!4SSWx|1cLB3^9#R$TO_!#CQ{s$@s`7eB zaZCk4TRUNH_UjeSyb{)%M0VuzUYN2?Vq=?a#UPEamr0 zXGM)YCyjJKrkc0s7D$O@DcNL_TW$m00o+81RA5}1i^##n8V}!)l_Tk~f#Z7muDm^q zG)B=W&~l{QzB&?E{W5azrXl)J*-<)s!nGlT&Q+I4AeTUG=5AUcKOkMYYrq%<=9YD*ByL<`*I#(s^u-G2GMLXaHBY@O{9Pnwq zDre(DGdYdMlsLdFX9dv-!YCIB-Uv=H0{AD)FP!+YITI*{=fW9l$25af>h)ZY2qDa- z5*Tf3x|UVCeKgg2Ftla+xNOy4n)Jm%;!FJbAG+g{;GVOKH$bSQbt57@ZP-!t)BZyE zBY(*9gGgn(%bjLVND2r1nypJcmw&eXrNg}Kr$J9dH|EUffjuC2yKX?efBZueDj&^T zuU3U{Hxk!2d5Gg%>bXezH*wx{_a29KBrq9N*I2(Z38|+b@xL{E?#eAOXlio42=a{P z={cZ(lAT%}p2tK{BL|)StSe#TI;I&@yHL0a{J`okK)g8RasX`G&W2;wPv@iw6pw-M zelG}vara9}hU-Lm+Bb3`;LiL_hdJwZgDcN0D@Ag`<4#NVU2t4ZzeRo9+vzWx{Q?S( zMKaxho)yGUw7kmu4|fg)yR8_q{y$~*^s?W(Hf84*;L17Rg<37N?N1IWPttkg zUBcaVG-RN~Y0|zRW2f~JuZ?03_zl4XEFv~uPwY(OzzRLD(9Fq^0X|yQ5lM4T2;vYa z_Pu%aPWFKc+3obnde||mhjkr0}ifJX<8e^i75n7NCgPJQ14p&k5U6K6l-x(yUt|*`!o;MUe zVX3)cELhm^L_@rYP>J5YFP zI0=w!1`yNHaJkom+m^zlg0(0I6F32y=6cRJFnxOL;N7!jZ(7W~^gfLNR24*(JAwKT z1=t+|Xv`^|(IGVmlyjT{u{XRgj?o?C9sPFl`|thT{Y04UJL#kxdAb7SI0>bZ1^f%+ zQ5R#Rfyz=W@Z!}p$~-cxDP@j?Jnq)m;(EwVhr3bHk(1j1-bOvC69JTpVuVwlPp!F^ zMrsiN3q9H<4FWZQ3-Y0h!YFPqIatCsnu;2H08+YO3*>{hw}1r!pwf;B(AGPEOy2Zm z!BOf14(>@u$3u1yR@fXSIR+}H7BwOA@w}G; z(>xv8WCKhs#wLEd4TP{AX9vPIfY4F{qgSV`8G88jr2E6N*;cAfbLi4$J7Xe}_$K44 zY=Bwnn1;1CPs0sk1rwEwd+3j2O_7Z_AoNduL>HhRWg1|OII z*Bsw<^&5fne(01u6oLNeJ!r#o)Ok$jB|i4&I-D!c-$SPnAP10B^{o%FV;kj;y}kc? zzVhFU7ia~ZO8vVUy_3a2K9vwMNOjNF30s{u|Bno$>E0QLem^H0AOzMjai^$XU;j|w zc-crN+(qA$Xu%MT^%f4bq@tkgGXSbdw`YLz*}L$Q@;OxNQ(VmpRx<0ELP9>~0kEsO z+_IxeAdb6E-fk4%d{;M_qn!$pzmjhirxaBS$zRKnFzPIpPXMS9Rb!$xz$ZbD0K5B` z*N1QPBa=^K*4}-=X|*nN04B~z;=Tnl*T*2&OnbVFF!167Bm7DQy5jcTBER&vh>0c{ zpC+xSZz}qh41Xxi?DeQ(KMiSY?kW~)=>^d&lQ{woHxXo>GEXf0$}MQVRwPD=YENGu zb4g5lkt0LY5Ac5?MK!K3RAGg^iM`5zgA@rI`*zaW5#+grB7ccuc7#-YE<%8pgevXU zz4?fFXmla~@JNL{Lr8gmP#-x?0&|b8^FYhjfMqB8ep~-^V|Z`vGdT?{mAQPm3L)Zl zYb%81HNiTMVYFW5ki5S3a90PKtQ;fedQ7S{sLtEuaOJ5u>^D=0+Ri26H(UNNvHJX7Tugu$Xg zrwtFJR8m7!05kffT{%CP9D&ebtMgFWtTh0%@0SxgG&%IHslqY@+eB>~%e*TOYQa50 zfAI!a*H``7 zA)KATqL!)*YJEr|erLlCF*%@tzPz3}roEiu#IJUN#Jf=qFxMV1#Pr(Ei02frzmtpz zM~2$*mlI6tBk7^z+IkF!k+Wydssj)*3pA54iBE01A@-n;Y4OmmTx4m_rs7=UT8N98 zaP{T`yRY_)JF^N_yn+VRMqD(~d6IGj-k{6`qF?#O{;30&Y&9TM2P}-d8L@gUP(hkv z2Y^ziG`pqhhQfSf)BmcK^8)!#z;t;WIc^BGA60YvHm1}+`WMe$;h1(4Lp?gXCkrd} zqm(XT$ySWglL=NURCvJ~9ycN=hWtFl%C@xU(46JViRNGAnx|B`@giXv+8qaorA%sW zMBOhVJn-jTLcj{&AJ!FL+LQZV$<3pmL&^Nk=jK--rZT@$|0-r2X|5Bx8U=AzNaJ3u z=SlHD$*o9j+qgTW1nTmhUvo=cK8eJ*0#FSxK-uNI02-hE30mZvsksVEH2yd#FnDoI*Z8F&sO+_x}e!@BY~u5;RW&!18Ne&%{pfy6D}KpF#%t)D%xvix%DY zjlK7a^s$HJ8^jtFh4dIh*{#+5uu;Xgr}zefSH)iMRZ7tf^^J}G|E%V|dOR^$0^_hx zRSS?<|73xPf!Emhy8r&F*pb0l!>np>(14}zH#=`6(EW1Gv)h0O#z9Nr|>sFvkrJ?Zs-#HgWgX1fDIdubj5gYS)FAW(I9NN%B@OGNlPO#cX|s2b+v-Sl)rCwC!POoKT^N=;=}Z>@ZKojQyeCI0XtUtIDdll_-5vD;29x0 z+o#MR5@Ku7V_z@9HRA6v`6;A!xs790&!cj#FeN0p)+e=oHm3r$-_m=E2V@*jK|SlQ z$udsaL(vz|M253N%T`YLOoOWD_nS6$fNsCq&}}};2+Oa9cAy`GL8N_WCcAd#0CjvY zbLg4%Cn)YCfSlULxN7RJmh%|kCgw#6*Llfoaxsr8!%j`b-Jb3i200UD5IOs{a3L!t zEI6RW{z|Hqh8(udZUQvZPoLl&F}c3PNep0xbzbn*qNXXU7*l;FjpTme=Cv;*x?~;# zbjIm>IpML!t{6aRi#{UBqw=clt-%Htod{|`haisaj`i^SKk8*SCeeUc_}F0C9u*{% z2(Wdoiu;Ds)0NsM8KUFtl+fm+v?F0 z2gs#vOYM?PO_xZiWNt9P)djf+b!Z4iI6|cWP&1GQ zIyKYILpu_Y6BaW|acEuCpEUSN4Fq4W*_-}wJGMb_L?1%8z;~y@@1U_;E66V?#J|Ux zaQ&#Ktu&g*P=UW)%exC0&gG>6UhZj^<8iE@l3_nG2k3W7KxVxz`~!@wjlW>uXKjDV zm)gujTv_h(qK&wHfCNr(0yOLUBQ6OVwu3UKe+txtZI?qefTGGw849ywvwmQz(FW0? ziT*o5&6l4zMjmiS>u@H~|6yXKKJ!ugmG9V`y(I!j(3M55je&N6IDV=P+Qm{p17oeB zbhQBoKWW{*Hggy@oBlo$fMrsj+o^v-Gc`(EkP=wpRQCi^{FQ@3}P=6?$`?7Et8ESL!Gq7c|fQ5{J^i*2y6B8{@lylH7D~dH_#-B751n1 zY>niY1gCqN7r5(W`w;Tfe$d6{VKAUA*RWrjup5*KofxWG=05i9@d}UMH(T^Dnk9HI zA1HM#P}-jX7N^Kn$j{1qTU#uFM-o0P|9W!HtFM$Zc{yU_XD-n_+p=+x**#Xr2mnO* z_W)=*1-RFFgeE|z_Tk^K=?0&Icm}$S{#=3@7Y=wj&gPztN?QuELM|m|2$^a3Szva7 zTYXKO%UE)q1(y~3kF0J3Wnf1fS_Z%qxLsZ5>&E)A)z_z(DL`ex;zw<+xQbB%B>%R$ zMvaz^$wT+Rg_c1;GPE2b9lUw)X@SVeBZRd_G)OG{OsoOzCft#E7$}@m0bL(1QB*)9 zz#>jwJ|ZbxyS>Fb;*mXF6Z~pSiT4GiXRpHBjC9^wV;1cQe&M>o{0UCU69TOnK(?ap zm8G#vIsr<*i4%IL-+NzpnSN#KVR`gx`t&?LT|sR4xZ z9+3aeY3hPECKT?2r|@n}8{7l+%RkCc62@&!Koa*n0bUCl+u$lZ+QRdIk~3&FnzC7{ ztZ=--al%SP=BKZCw79-5>E>`Xu8sn_Oc!0k!F5b--7ZFs z%8eJn9-M`sjJgR-H3XPPgdxLTh8QwkCH znDPb8^N9>aYJA%=1FB5l7n(Bm7@-YBqk2Fk*uDl9?RfCBx3}f;TLbGbu((%F#MC($m>RtTa~96}L}D{|GS+7@L3t;AsORsS%FzVSk#mJ_5)+ zWT_NT@figug7(|2C!y5YKK@a>=YZ(jOA|75J5Z^i2rMVsYJJ3cNs26W7ZFu(Gh7uE zvBpA?=B^MGox${*`UQ3KFyw2rzpvH0<0IyFYWzFjavZ3(XH{n7F=A7E@7CSlr1@$C zvTs`k`*frV0s#qHn0}HsZc^6?WYa*k<8g-2NO`H|0PqjMi*Fg${tR0z8scgu8%D}$)2dpz2}oQhWvfd*jC;W<1{m&zIhW^zG>|qSh=fL?V zGRI+=eRFNBxQekoPKN>@U#Mj~7ZaBUmR8c-WV-;k7pe4is8)FwB#hDrj}(*+4MU|e ztT=sIFvplsX>Y8|n~Ms(qCPu08wigzH+& z&80N^a&dY%sLPxKa*h0U!ayQc)hz7M&Wpkbp+jY}7xh z*waTyldv8JT%!N~xQU`p>E=WBx)%LfYt*1^}lY#0dlB`|0I8Z8lIKUjHAY z7sUD6T(OD$bzVGR?=EBIhWLX8f#5?UdOG$a1FynkgHU&SSbs8(JfGl2x2GvpSF=cs zV1@Z0D^s$$DL(q73MnB@u{cQ=9KyC=tYgSx6F_%7OY(@I%5XS4t*I~uoN_C%*$4x; z&V~k4CqbFE_UJF4QF3{}Om6Y@_~IPE4c7N{Vqto7WAOMmK-v6_vhm4cZtKF9LZg30 zr0kTqT&?f%v7Z3ZJ}8OX8U?H*{$Qr%gE(wzWgb_%AT--Agxk(A-4~9Fc+u={Kuswg z0vO2ZyH%p>x)52)7wbq5DQ0CQQT}=M>vIp7*E4DKpxF-aU2}Pb?>#FZXm98b#`%MSJcEIp!uePn{PB^^Gc)ue>W9q1asfFF>dCf9H`M3TLlOSBS{wq(+!p(;_FUcmhDFf@XTEV$%Bv!4ac4Ly zYIq@SR8$<$^~hNcgFb*Sd`{!V6tCF)KIUGAl6U)S|2?BHaTKRmP~c9U>+RajM$Uuh z%+eIks=KD`QwLI3xzcWte>*0y68iQ+vpg@ye9f3flN#cY!LkJ0F4nzU=xnE3-)2)O zhC_F(##N&KqXU{9=G5}bO%Fk}SkgIhymY~coq4GgTpnd{Rms}hNdg*qZL!HYA1HK3 zHOT)4SyCqej)rrizLFO#!7~5_+w{+4MS3b2pG<2lVS85bdJK#y4E&!^=f(%VrH<$_ zzJTof#V24hyGZC`LX z^;IyPN;Xh(3&?0cMCWg4heL7sl~#}gwo$=+fp~qObJWkI`du@`G>uoTpsaAJF)$uH zKJa;g(D8H7QyX{j_S~~>*XJXl(kEZU_@b0?T;BoQ%;9~^t#idg@rjljel`leW*g%* zz3;DZe}7%qf1Y5{PC%;3B?%|u!ACHrcattr`j4z;0ax=RTIbv0{TamuJ6p%S^q^th z|G%xi&gMsgJ49cXLq{J#KbBn0d^1@FG^XTel}ao#*`mZ%^*;TxOR}QIb8LReAm=E| zy73p?u+0ZG*xAXZVKwnG)x&zk)w}w_>eM-n%Xfu?0i-Tsqz%>JKbMAoNr1a0bU+2f zyHO(Jzo?4swbn-=$M}Z6x=Z|oXy%5hzFDZ|jji^{*TpmT8fm-bFQ4{e016QZ8$sq- zsj#N?$geb*Eo_x{aCYDeG3vQFt_fu#iG^Z`eZWNAc74w5D?Ge~c52_vo>SCXTmVYgn2=ZZt!L-Wvj;$S zgWqU9|Eg9#hkRh_I2?q)X@%CabB zZZ0rZt6r@fauUpz${dN0`0p?Pm;_i(b^f8Hi`|Yz<$Gu_#QagpeLp|&$*O(K?Gz&5 z?pORF<9^xXPBA)3o|3k68V||}%1;q1M_=MwS{5uaHU^)BPFfKCvG#%3I@|$J+U6h* zK9`jN90}dvCtQQKigaA`v9`%JZpj;#Z~C{r5qAd`StHi>ibngZ<^MHuu0c&5Q5+96 z2n7ORS`m^!APv%~K*9i`6a{Ul0<~(a7SRUOA?Q$^mN97^BZv`D5n2V}1MCB-LJ@4mty}_7$ z6%?gzbyf%Lx!%2YK+>}^^GwY|o=7Bedd=X$O433O=NxY0N{Pw-EbpWuN0$o0{+Ow( zm

+UAWg(oUaFq|Lc|`;H*S&XZu2&P`TV;vNGthYTu3>@A;_+p|BjvDvk$3-Rv1x zoL)QG@9jD)4(dq&G|DH{-*tY#-%6Qf|F&zcho1U3hz{wD`p9*Ub15mgeXa+5U`diY zPV1Oh(lNqXR;<&y4L?YRVluKI0X{;g`-ziEJZT zLY&-$bcBC{Qzr>jkZ3z2zR7{TsrKluy1ij(Nj7(x2)96%b(?G+J3tq^Wrr4TPx8uq zrKZ1+Sa{S1&}^a8#m(j_AixhY#E@72{pn`?g+?(W$tDEt31^;fBTMWR zh@v1tEG_k?Js^z-L(L0nltni^JyZbbfsygeGR>3&Ffv3Yt@`%{E%TR^{0cx&-T$6k zd`lSaFTex(4zUdrzye7!q80SLLM8E%vK`PS8Is9b@)+p4kZd|)MMfd&su}!x~G?I*C(G*=H*A|iQC9t$ja0|sR;!rvuLjayJ;ZR~e zv_@Oit$v098}i7G|FwuJkrY2tT1P>Ob;(c+G_QZSv$k@DDg1~ zJuu5k)|lR=drJ`On@MmK?#Y)#HRIkN^i|oBj&GEIm5td)4m1hNF}Fth8S6}_u{_Ql zB*eyzIO?XhJ8$!&EC|OFbBg+$l6=&5^%yJ+R@@^ vlx8X;;8TCSvM0uQ-riS1HGY;kb6Sh=z14|i5j_^5$GFId&sjAa Date: Thu, 16 Aug 2018 11:24:25 -0500 Subject: [PATCH 092/142] se corrige bug con la gestion de las tablas --- qgisplugin/HydroSEDPluginUtils.py | 3 +++ qgisplugin/HydroSEDPlugin_dockwidget.py | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index c442381..a7956d6 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -228,6 +228,9 @@ def Basin_LoadBasin(self, PathNC, LoadSim = False, LoadSed = False): '''Carga un proyecto cuenca de nc en la memoria de Qgis: LoadSim: Carga las variables de simulacion LoadSed: Carga variables de simulacion de sedimentos''' + #Inicia de cero el diccionario de la cuenca + self.DicBasinNc = {} + self.DicBasinWMF = {} # Numero Total de Variables self.NumDicBasinNcVariables = 0 # Numero Total de Variables Basicas diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index ff3a5cb..9a430d5 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -69,6 +69,7 @@ def __init__(self, iface = None, parent=None): self.TablaFila_WMF = 0 self.TablaFila_NC = 0 self.botonClicked = False + self.segundaCarga = False self.GeoPlots = HSplots.PlotGeomorphology() @@ -186,6 +187,11 @@ def clickEventBasin2WMF(): #Checks para simulacion de sedimentos e hidrologica Simhidro = self.checkBox_simBasin.isChecked() SimSed = self.checkBox_simSed.isChecked() + #Si hay una tabla vieja le trata de borrar todas sus entradas + if self.segundaCarga: + self.TabNC.EmptyTable(self.Tabla_Prop_NC) + self.TabWMF.EmptyTable(self.Tabla_Prop_WMF) + self.segundaCarga = True #Cargado de la cuenca self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), Simhidro, SimSed) self.TableStart() @@ -580,8 +586,8 @@ def hadleClickEventEjecutarBalance(): def TableStart (self): '''Arranca las tablas de NC y WMF''' - self.TabNC = Tabla(self.HSutils.NumDicBasinNcVariables,self.Tabla_Prop_NC) - self.TabWMF = Tabla(self.HSutils.NumDicBasinWMFVariables, self.Tabla_Prop_WMF) + self.TabNC = Tabla(50,self.Tabla_Prop_NC) + self.TabWMF = Tabla(50, self.Tabla_Prop_WMF) def setupRaster2WMF(self): @@ -957,7 +963,7 @@ def handleClickEventButton_Ver_Desde_NC(): self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'No fue posible cargar la variable', level=QgsMessageBar.WARNING, duration=5) #Hace que el spinbox vuelva a lo normal - self.SpinBoxLayer2View.setValue(0) + self.SpinBoxNCLayer.setValue(0) def handleClickEventButton_Ver_Desde_WMF(): '''Visualiza una de las variables de la cuenca en Qgis''' @@ -1198,6 +1204,12 @@ def __init__(self, NumRows, TabElement): TabElement.setColumnCount(len(Header)) TabElement.setHorizontalHeaderLabels(Header) + def EmptyTable(self, TabElement): + '''Vacia la tabla, quita todos los elementos''' + TabElement.setRowCount(0) + self.TabNames = [] + self.NumRows = 0 + def DelEntry(self, KeyToDel): '''Borra una entrada en el diccionario de datos''' pos = self.TabNames.index(KeyToDel) From a4f73213a70ac446603b62605ca494d153f5c2d7 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 16 Aug 2018 11:37:11 -0500 Subject: [PATCH 093/142] se corrige bug ocasionado por valores constantes de mas de 5 caracteres cuando se va a convertir a WMF --- qgisplugin/HydroSEDPlugin_dockwidget.py | 11 ++++-- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 39 +++++++++++++++++++- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 9a430d5..03005d0 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -189,8 +189,8 @@ def clickEventBasin2WMF(): SimSed = self.checkBox_simSed.isChecked() #Si hay una tabla vieja le trata de borrar todas sus entradas if self.segundaCarga: - self.TabNC.EmptyTable(self.Tabla_Prop_NC) - self.TabWMF.EmptyTable(self.Tabla_Prop_WMF) + self.TabNC.EmptyTable(self.Tabla_Prop_NC) + self.TabWMF.EmptyTable(self.Tabla_Prop_WMF) self.segundaCarga = True #Cargado de la cuenca self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), Simhidro, SimSed) @@ -613,7 +613,12 @@ def handleClickConnectRaster2WMF(): self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'Debe ingresar un nombre para el mapa raster a convertir.', level=QgsMessageBar.WARNING, duration=5) return 1 - if len(self.PathRaster2WMF.text())<5: + try: + Valor = float(self.PathRaster2WMF.text()) + EsNumero = True + except: + EsNumero = False + if EsNumero: try: Valor = float(self.PathRaster2WMF.text()) PathRaster = 'noMapa' diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 444f472..c46c5f1 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -250,7 +250,7 @@ - 2 + 0 @@ -294,7 +294,7 @@ 0 - -300 + -815 443 2018 @@ -1230,6 +1230,25 @@ + + + + + 82 + 16777215 + + + + Capa a ver (o editar) de la variable Nc. + + + Capa a ver (o editar) de la variable Nc. + + + 5 + + + @@ -1249,6 +1268,9 @@ + + Categoría de la nueva variable obtenida + Categoría de la nueva variable obtenida @@ -1258,6 +1280,19 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + From 9c250c5674866c34205f61aab45e74f915722f4f Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 16 Aug 2018 17:55:09 -0500 Subject: [PATCH 094/142] gestor de variables tiene la opcion de evaluar expresiones para obtener variables nuevas --- qgisplugin/HydroSEDPluginUtils.py | 27 ++++++++- qgisplugin/HydroSEDPlugin_dockwidget.py | 11 +++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 63 +++++++++++++++++++- 3 files changed, 96 insertions(+), 5 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index a7956d6..dd8fde5 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -697,5 +697,30 @@ def Sim_SaveParameters(self, PathNC, ParamName, scalarParam): #cierra el archivo g.close() return Ejecuto - + + def ExpressionParser(self, expresion): + '''Toma una expresion enviada en string, extrae las variables del diccionario + y evalua la expresion''' + #Busca en el diccionario de NC las variables de la expresion + Lista = self.DicBasinWMF.keys() + Lista.extend(self.DicBasinNc.keys()) + for k in Lista: + #Tamano y pos de la letra + largo = len(k) + pos = -1 + try: + pos = expresion.index(k) + #Extrae el valor de la var del diccionario y define variables + try: + var = self.DicBasinNc[k]['var'] + except: + var = self.DicBasinWMF[k]['var'] + ejec = expresion[pos:pos+largo]+'=var' + exec(ejec) + except: + pass + #Formula la expresion + AA = eval(expresion) + return AA + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 03005d0..4d54315 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -661,6 +661,15 @@ def setupNcVariables(self): ListaUnidades = ['Celdas','Laderas','Canales'] map(self.ComboConversionUnits.addItem, ListaUnidades) + def clickEventEvalString(): + '''Funcion que eavlua una expresion escrita''' + #toma la expresion y la evalua + exp = self.LineaComando.text().strip() + Var = self.HSutils.ExpressionParser(exp) + #Dependiendo de la opcion la agrega como nueva var a WMF o actualiza una en NC + + + def clickEventConvertVariable2NC(): '''Convierte una variable clickeada a la tabla de NC con una transformacion''' @@ -673,7 +682,7 @@ def clickEventConvertVariable2NC(): print VarName1 - self.Button_EditNcVariable.clicked.connect(clickEventConvertVariable2NC) + self.Button_EditNcVariable.clicked.connect(clickEventEvalString) def setupRainfallInterpolation(self): '''Conjunto de herramientas dispuestas para interpolar campos de precipitacion''' diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index c46c5f1..78268ea 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -294,7 +294,7 @@ 0 - -815 + -875 443 2018 @@ -1134,7 +1134,7 @@ 0 1230 421 - 161 + 311 @@ -1146,7 +1146,7 @@ 0 20 421 - 138 + 161 @@ -1198,6 +1198,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -1217,6 +1230,19 @@ + + + + + 20 + 16777215 + + + + + + + @@ -1253,6 +1279,19 @@ + + + + + 20 + 16777215 + + + + + + + @@ -1278,6 +1317,23 @@ + + + + + + + 16777215 + 70 + + + + Nombre de la variable que contiene la conversión + + + + + @@ -5671,6 +5727,7 @@ + From dd762b659397d62f3fe67069ee4ae827cd2c4f7f Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Fri, 17 Aug 2018 11:50:28 -0500 Subject: [PATCH 095/142] =?UTF-8?q?corrige=20bug=20ene=20l=20cargador=20de?= =?UTF-8?q?=20cuencas=20que=20sobre-escribia,=20adem=C3=A1s,=20tiene=20la?= =?UTF-8?q?=20herramienta=20de=20gestor=20de=20mapas=20NC=20al=2080%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPluginUtils.py | 27 ++++++------- qgisplugin/HydroSEDPlugin_dockwidget.py | 42 ++++++++++++++++++-- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 28 +++++++++---- 3 files changed, 71 insertions(+), 26 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index dd8fde5..7759625 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -253,20 +253,19 @@ def Basin_LoadBasin(self, PathNC, LoadSim = False, LoadSed = False): shape = g.groups[grupoKey].variables[k].shape MapaRaster = False for s in shape: - if s == self.cuenca.ncells: - MapaRaster = True - #Actualiza el diccionario - self.DicBasinNc.update({k: - {'nombre':k, - 'tipo':g.groups[grupoKey].variables[k].dtype.name, - 'shape':g.groups[grupoKey].variables[k].shape, - 'raster':MapaRaster, - 'basica': True, - 'categoria': grupoKey, - 'var': g.groups[grupoKey].variables[k][:], - 'saved':True}}) - self.NumDicBasinNcVariables = self.NumDicBasinNcVariables + 1 - self.NumDicBasinNcVariablesBasicas = self.NumDicBasinNcVariablesBasicas + 1 + if s == self.cuenca.ncells: MapaRaster = True + #Actualiza el diccionario + self.DicBasinNc.update({k: + {'nombre':k, + 'tipo':g.groups[grupoKey].variables[k].dtype.name, + 'shape':g.groups[grupoKey].variables[k].shape, + 'raster':MapaRaster, + 'basica': True, + 'categoria': grupoKey, + 'var': g.groups[grupoKey].variables[k][:], + 'saved':True}}) + self.NumDicBasinNcVariables = self.NumDicBasinNcVariables + 1 + self.NumDicBasinNcVariablesBasicas = self.NumDicBasinNcVariablesBasicas + 1 g.close() #Cargar la cuenca y sus variables base a WMF self.cuenca = wmf.SimuBasin(rute = PathNC) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 4d54315..45a0904 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -193,14 +193,17 @@ def clickEventBasin2WMF(): self.TabWMF.EmptyTable(self.Tabla_Prop_WMF) self.segundaCarga = True #Cargado de la cuenca - self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), Simhidro, SimSed) + Area, self.EPSG, dxp, self.noData, self.umbral = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), + Simhidro, SimSed) + #self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), Simhidro, SimSed) self.TableStart() #Actualiza tabla de Nc y comboBox self.VarFromNC.clear() for k in self.HSutils.DicBasinNc.keys(): self.TabNC.NewEntry(self.HSutils.DicBasinNc[k],k, self.Tabla_Prop_NC) self.VarFromNC.addItem(k) - Area, self.EPSG, dxp, self.noData, self.umbral = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip()) + #Area, self.EPSG, dxp, self.noData, self.umbral = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), + # Simhidro, SimSed) #print self.umbral #Habilita los botones de visualizacion de red hidrica y divisoria self.Boton_verDivisoria.setEnabled(True) @@ -656,7 +659,7 @@ def setupNcVariables(self): map(self.ComboMethod4Conversion.addItem,ListaMetodos) #Lista de grupos posibles para una variable ListaGrupos = ['base','Geomorfo','SimHidro','Hidro'] - map(self.ComboBoxNewNcVarGroup.addItem, ListaGrupos) + map(self.ComboBoxNewWMFVarGroup.addItem, ListaGrupos) #Lista de unidades de conversion ListaUnidades = ['Celdas','Laderas','Canales'] map(self.ComboConversionUnits.addItem, ListaUnidades) @@ -666,7 +669,38 @@ def clickEventEvalString(): #toma la expresion y la evalua exp = self.LineaComando.text().strip() Var = self.HSutils.ExpressionParser(exp) - #Dependiendo de la opcion la agrega como nueva var a WMF o actualiza una en NC + print self.HSutils.DicBasinNc.keys() + EsCuenca = False + if Var.size == self.HSutils.cuenca.ncells: EsCuenca = True + #Si es al nc sobre-escribe una entrada del diccionario + if self.Radio2NcVar.isChecked(): + VarDestinoName = self.VarFromNC.currentText().encode() + Capa = self.ObjectiveLayer.value() + #Solo pasa al NC si el tamano es el de la cuenca + if EsCuenca: + try: + self.HSutils.DicBasinNc[VarDestinoName]['var'][Capa] = np.copy(Var) + except: + self.HSutils.DicBasinNc[VarDestinoName]['var'] = np.copy(Var) + self.HSutils.DicBasinNc[VarDestinoName]['saved'] = False + #si es una variable nueva la tira al WMF + elif self.Radio2WMF.isChecked(): + #Variable al diccionario + VarDestinoName = self.lineEditNewVarName.text().strip() + Grupo = self.ComboBoxNewWMFVarGroup.currentText().strip().encode() + self.HSutils.DicBasinWMF.update({VarDestinoName: + {'nombre':VarDestinoName, + 'tipo':Var.dtype.name, + 'shape':Var.shape, + 'raster':EsCuenca, + 'basica': False, + 'categoria': Grupo, + 'var': np.copy(Var), + 'saved':False}}) + #Actualiza la tabla + self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[VarDestinoName], + VarDestinoName, self.Tabla_Prop_WMF) + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 78268ea..ac52a11 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -1132,7 +1132,7 @@ 0 - 1230 + 1200 421 311 @@ -1146,7 +1146,7 @@ 0 20 421 - 161 + 184 @@ -1231,7 +1231,7 @@ - + 20 @@ -1257,7 +1257,7 @@ - + 82 @@ -1280,7 +1280,7 @@ - + 20 @@ -1306,7 +1306,7 @@ - + Categoría de la nueva variable obtenida @@ -1317,6 +1317,19 @@ + + + + + 16777215 + 20 + + + + Expresión + + + @@ -2354,7 +2367,7 @@ 0 - -147 + 0 443 1918 @@ -5727,7 +5740,6 @@ - From 3382fe2324a00dd13901825a54e0da2f6eaf0b2e Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Sun, 19 Aug 2018 09:14:31 -0500 Subject: [PATCH 096/142] Se cambia en el wmf el rolling_mean por rolling().mean() --- wmf/wmf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wmf/wmf.py b/wmf/wmf.py index e71890a..e6398ee 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -771,7 +771,7 @@ def __ModifyElevErode__(X,slope=0.01,d2 = 0.03, window = 25): Pos.append(c2) c+=1 # Obtiene la segunda derivada de la corriente corregida - Y = pd.rolling_mean(Y,window) + Y = Y.rolling(window).mean() l = Y[np.isnan(Y)].shape[0] Y[:l]=Y[l+1] slope = np.diff(Y,1) From ef55464995eaa8dc7e258574a76b20e4a4a13d83 Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Sun, 19 Aug 2018 09:41:30 -0500 Subject: [PATCH 097/142] Se cambia el pd.rolling_mean() por pd.series.rolling().mean() que es para pandas >0.18 --- wmf/wmf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/wmf/wmf.py b/wmf/wmf.py index e6398ee..113ab48 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -771,6 +771,7 @@ def __ModifyElevErode__(X,slope=0.01,d2 = 0.03, window = 25): Pos.append(c2) c+=1 # Obtiene la segunda derivada de la corriente corregida + Y = pd.Series(Y) Y = Y.rolling(window).mean() l = Y[np.isnan(Y)].shape[0] Y[:l]=Y[l+1] From c02abb9e7bc550b3a81fc36125de79e17dd8d154 Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Sun, 19 Aug 2018 10:12:23 -0500 Subject: [PATCH 098/142] Se corrige para que grafique el histograma de variables que tengan menor len que ncells --- qgisplugin/HydroSEDPlots.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py index 9765ce9..296a136 100644 --- a/qgisplugin/HydroSEDPlots.py +++ b/qgisplugin/HydroSEDPlots.py @@ -222,7 +222,7 @@ def VarHistogram(self, var, pathFigure, ncells): '''Hace el plot de un histograma de una variable seleccionada''' #Seleccion de datos if ncells > 10000: - pos = np.random.choice(ncells, 10000) + pos = np.random.choice(len(var), 10000) else: pos = range(10000) #Obtiene la pdf y cdf de la variable From ac37c38e091683daea2fbbe9d3c56fbec2f6a17b Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Sun, 19 Aug 2018 11:11:32 -0500 Subject: [PATCH 099/142] Se agrega resources.py para que puedan cargar todos los iconos --- qgisplugin/resources.py | 2117 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 2107 insertions(+), 10 deletions(-) diff --git a/qgisplugin/resources.py b/qgisplugin/resources.py index 33b6a0d..15f6aa7 100644 --- a/qgisplugin/resources.py +++ b/qgisplugin/resources.py @@ -76,6 +76,146 @@ \x81\xa3\x32\xb1\xfb\xf4\x0c\x30\xb8\xb1\x82\x9b\xb0\x09\x60\x30\ \xb1\xfb\xf4\xcc\xbf\xa0\xe9\x6e\xae\x5a\xdf\x4b\x81\x00\x00\x00\ \x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x08\x91\ +\x00\ +\x00\x80\xdc\x78\x9c\xed\x5c\x6b\x4c\x54\x47\x14\x1e\x14\x15\x7c\ +\xa2\x54\x40\x41\xc4\x22\x6a\x00\x5f\xf8\x8a\x68\xe5\x29\x58\x35\ +\x8a\xaf\x60\xe3\x13\x51\xf1\x15\x15\x5f\x05\x93\xa6\x0b\x34\x96\ +\xfa\xa8\x5a\x29\x50\xa0\x34\x02\x41\xa5\x58\xaa\x51\x34\x5a\x4d\ +\xed\x3b\x6d\x7f\x37\xa9\x55\xab\xa8\x8d\x49\x5b\x6d\x6b\x53\x69\ +\xda\x3a\x3d\xdf\xdc\x7b\xb7\xeb\xba\x7b\x59\xca\x92\x82\x3d\x5f\ +\xf2\x65\x76\xf7\xde\x39\x67\xbe\xb9\x67\xce\x9c\xb9\x24\x08\xe1\ +\x21\x3c\x45\x6c\xac\xa0\x36\x44\x0c\xa3\x36\x49\x08\x11\x12\xa2\ +\x7f\xf7\x11\x62\x23\xfd\x16\x10\xa0\x7f\xf7\x16\xa2\x30\x45\x08\ +\x1f\x1f\xfd\xbb\xa7\x10\x17\x9f\x13\x62\x18\xf5\xa1\xdb\x84\x45\ +\x68\xbf\x33\x18\x0c\x86\x1b\x21\xdd\xc0\xf6\x0c\xd6\xcf\xfa\x59\ +\x3f\xeb\x67\xfd\xac\x9f\xf5\xb3\x7e\xd6\xcf\xfa\x59\x3f\xeb\x67\ +\xfd\xac\xbf\x2d\xf3\x49\xd2\xc2\xfa\xdb\x80\xfe\x95\x2b\x57\xba\ +\x4c\xfb\xbe\x85\x85\x85\x2e\xf3\xb1\xbe\xc5\x05\x17\x5c\x21\xeb\ +\x67\xfd\xac\x9f\xf5\xb3\x7e\xd6\xcf\xfa\x59\x3f\xeb\x67\xfd\xac\ +\x9f\xf5\xbb\x4b\x7f\x3b\x23\xeb\x67\xfd\xee\x80\xd5\x66\x8b\xd6\ +\x70\x0b\xfa\xb2\x7e\xd6\xcf\xfa\x59\x3f\xeb\x67\xfd\xac\x9f\xf5\ +\xb3\x7e\xd6\xdf\xde\xf4\xff\x07\x74\xbb\xfe\x76\x46\xd6\xcf\xfa\ +\xff\x4b\x58\xc7\xd2\x9c\xf7\x66\x0e\xde\x9d\xb5\x57\xb0\x7e\xd6\ +\xcf\xfa\x59\x3f\xeb\x67\xfd\xff\x6b\xfd\x2d\x64\x7b\x05\xeb\x6f\ +\x43\xfa\xf1\x7f\x02\x42\x84\xf6\xbf\x02\xda\xe9\xff\x09\xf0\x20\ +\xf6\x26\xf6\x31\xa1\x77\x2b\xfa\xf7\x21\x5e\x23\xde\x35\x61\x56\ +\x2b\xfa\x87\xf6\xfb\xc2\x3c\x56\xf2\x5a\xd9\xff\x8f\x4d\xf8\xb7\ +\xb0\xff\x27\xd6\x7f\x37\x17\xfc\x6f\x77\x83\x1f\xac\x61\x47\x6b\ +\xfb\x69\xa1\xad\x31\x33\xff\xef\x0b\x6d\x0e\x9c\x31\x87\x98\x6b\ +\x47\xfc\x96\x25\xfe\xc9\x1d\xcf\x0b\xc7\x6b\xfb\x1e\xf1\xa1\xa7\ +\xa7\xa7\xf4\xf2\xf2\x92\x5d\xba\x74\x79\x84\xc6\x18\xba\x76\xed\ +\x2a\xbb\x75\xeb\xf6\x08\x3b\x75\xea\xa4\xae\xa9\xbe\xde\x5e\xaa\ +\xbf\x22\x7d\xc6\x6f\x7a\x5f\x5f\xdd\x7f\xae\x99\xc6\x91\x23\x47\ +\xca\x55\xab\x56\xc9\x25\x4b\x96\x28\x2e\x5f\xbe\x5c\xa6\xa6\xa6\ +\xca\x8e\x1d\x3b\xaa\x71\xe4\xe6\xe6\xca\x03\x07\x0e\xc8\xbd\x7b\ +\xf7\x2a\x16\x15\x15\xc9\xe4\xe4\x64\xd5\x37\x7a\x52\xf4\xf5\xa2\ +\xe2\x82\x0b\xaf\xec\xcd\xbf\x04\xe2\xf3\xc4\x89\x13\xbf\xa3\x6b\ +\xbf\xea\x73\x0c\xbc\x68\xe6\x7f\xcc\x98\x31\x72\xd3\xa6\x4d\x32\ +\x23\x23\x43\x71\xdd\xba\x75\x72\xd9\xb2\x65\x56\xff\xfb\xf7\xef\ +\x97\xe5\xe5\xe5\xb2\xa4\xa4\x44\xb1\xba\xba\x5a\xce\x9a\x35\x4b\ +\xf5\x8d\x89\x89\xb9\x5a\x5b\x57\x53\x5f\x5a\x5e\x72\x1e\xc4\xe7\ +\xd8\xb8\x67\x6e\x36\xc7\x7f\x54\x54\x94\xdc\xb0\x61\x83\xb5\x56\ +\xc4\x18\x30\x0f\x86\xff\x3d\x7b\xf6\x28\xbf\xc6\x7b\xd8\x8a\x8a\ +\x0a\x39\x73\xe6\x4c\xcd\x7f\x6c\xcc\xb5\xea\x63\x55\x67\x0b\x48\ +\x37\x88\xcf\x53\xa6\x4c\xb9\xc5\xfe\x5d\xf7\x3f\x7e\xfc\x78\xb9\ +\x7d\xfb\x76\x35\x06\x70\xf3\xe6\xcd\x2a\x1e\xe1\x1f\x31\x8d\x78\ +\x3b\x72\xe4\x88\xf2\x0b\xd6\xd5\xd5\xc9\xb9\x73\xe7\xaa\xbe\x89\ +\xc9\x89\xdf\x9c\xbb\x70\xe6\x24\xfc\x82\xf8\x9c\x90\x18\xd7\x60\ +\xe7\xdf\x34\xfe\xfd\xfd\xfd\xe5\xe8\xd1\xa3\xe5\x88\x11\x23\x14\ +\xb1\x1e\xc2\xc3\xc3\xa5\x87\x87\x87\x1a\x43\x5c\x5c\x9c\x9c\x36\ +\x6d\x9a\x4c\x4a\x4a\x52\x84\xf6\xc1\x83\x07\xab\xbe\x81\x41\x81\ +\xf7\x92\x92\x12\xaf\x60\x1e\x40\x7c\x0e\x0e\x0e\xfa\x85\xae\xfd\ +\x6c\xe3\x7f\x87\xd0\xf2\x9c\x3d\x91\x03\x1e\xc2\x4f\x87\x0e\x1d\ +\x1e\xa3\xd9\x98\x5d\xe0\x5d\x1b\xff\x5e\x42\xcb\xf5\xf6\x1c\x84\ +\xfb\xa6\x4e\x9d\xaa\xe6\xd8\x58\xdf\x58\xeb\x79\x79\x79\xea\xd9\ +\x77\xee\xdc\xd9\x74\xfd\xbb\xe8\xdf\x19\x54\xfe\xc7\x7c\x62\x4d\ +\x1b\xeb\x1b\x6b\x1d\xfe\x0c\xff\x66\xeb\xbf\x85\xfe\xd5\xfe\x37\ +\x7d\xfa\x74\x15\x57\x46\x7c\xc3\x07\x74\x1a\xfe\xcd\xe2\xff\x49\ +\xf0\xdf\xd4\xfc\x9b\xad\x3f\x77\xf8\x37\xe2\x0f\x3a\x41\x3c\x6f\ +\xc4\x1c\xd6\x3e\xd6\x1f\xae\x63\x8c\x98\x27\x30\x25\x25\x45\x0e\ +\x19\x32\xc4\x1d\xfe\x71\x5d\xed\xa5\xd8\x53\xb1\xcf\x1a\xf4\xf6\ +\xf6\x56\xeb\xbf\x09\x1f\x4d\xd1\xf7\x31\x8f\x8f\x02\xeb\x12\xb9\ +\xe1\x45\x07\x7c\x99\xf8\x5b\xbf\x7e\xfd\x54\x7e\x44\x8e\x36\x88\ +\xef\xf8\x1d\xd7\x89\xf9\x4e\xfa\xc3\x6e\x4b\xcf\x2e\x3f\xd8\xe7\ +\x66\x10\xdf\xf1\xbb\xd0\x72\x58\x6b\x41\xc5\x86\xfd\xde\x04\xe2\ +\x3b\x7e\x17\xae\x3d\xe3\x16\xf9\x6f\x42\x7f\x6b\xfb\xbf\xdf\xc4\ +\xf3\xb7\xdd\xe3\xdc\x0d\x9c\x4d\xaf\x08\xc7\xfb\x96\xc1\xab\xfa\ +\x38\x4d\x81\xf7\x04\x01\xc4\x51\xa2\x4d\xbe\x27\x58\x2c\xb4\x35\ +\x94\x63\xc3\x5d\xc4\x59\x42\x7b\x3f\xd0\x52\x7c\x28\x1c\xe7\x86\ +\x4a\x37\xd9\x3f\xe3\xc4\x7e\x89\x9b\xec\xd7\x3b\xb1\xff\x86\x9b\ +\xec\x9f\x76\x62\xff\x75\x37\xd8\x06\x4e\x38\xb1\xff\x26\xd1\x9f\ +\xe8\xa7\xb7\x06\x03\xec\xd8\x5f\x68\x75\x0a\x80\x98\x40\x6c\x20\ +\x46\x2c\x3a\xbf\x71\x62\xff\x0e\xf1\x53\xe2\xc7\xc4\x4f\x6c\xf8\ +\x19\xf1\x0b\x9d\x9f\xeb\xed\x3a\xdd\x7e\x85\x23\x5b\xc3\x87\x0f\ +\x97\xb3\x67\xcf\x56\x35\x28\xea\x9e\x41\x83\x06\xa9\x33\xde\x8a\ +\x15\x2b\xe4\x96\x2d\x5b\x64\x66\x66\xa6\x5c\xbb\x76\xad\xf4\xf3\ +\xf3\x93\x81\x81\x81\x0f\xd2\xd3\xd3\x2e\xa7\xa5\x2f\xbd\x8c\x16\ +\xf7\x92\x8d\x57\x75\xfb\x6f\x38\xb2\x1f\x1f\x1f\x2f\xb7\x6e\xdd\ +\x2a\xd7\xaf\x5f\xaf\x5a\xd4\xbf\x46\xdd\x85\xba\x00\x2c\x2d\x2d\ +\x95\x21\x21\x21\x54\x1f\x0f\x6f\xa8\x3b\x79\xfc\x74\x4d\xed\xd1\ +\xfa\xda\x13\xb5\xf5\x51\x51\x23\x1f\x08\x6d\xaf\x02\x8a\x1d\xd9\ +\xa7\xf3\x80\x35\x87\xa3\x8d\x8c\x8c\x54\xf6\x77\xed\xda\x25\xcb\ +\xca\xca\x14\x0f\x1e\x3c\x28\x83\x83\x83\x65\x44\x44\xc4\xad\xb7\ +\x2a\xcb\xcf\x15\xd1\x59\xae\xbc\xa2\xf4\x3c\x8d\xa5\xb1\x29\xfb\ +\xa8\xcf\x31\x07\x6b\xd6\xac\x51\x2d\x6a\x78\xd8\x47\x0d\x55\x59\ +\x59\xa9\x88\xfa\x62\xe0\xc0\x81\x74\x2d\xe2\xe6\xb1\xb7\x8f\x9c\ +\xa9\x38\x5a\x75\xf6\x68\x4d\xf5\x59\xb2\x6f\x3b\xfe\x12\x47\xf6\ +\xa3\xa3\xa3\xe5\xea\xd5\xab\xe5\xd2\xa5\x4b\x55\x8b\xb3\x01\xec\ +\x5b\x2c\x16\x59\x50\x50\xa0\xb8\x7b\xf7\x6e\x39\x60\xc0\x00\x39\ +\x2c\x7c\xd8\xed\xa2\xd2\xa2\xf7\x5e\x2b\x38\x70\xb1\xb0\xb8\xe0\ +\x22\xcd\x57\xa3\x1e\x33\x4e\xed\xa3\xce\xe9\xd5\xab\x97\xec\xd9\ +\xb3\xa7\x6a\x61\x1b\xb5\x47\xdf\xbe\x7d\x55\x9e\x07\x71\x46\xd1\ +\xdf\x13\xfc\xde\xbf\x7f\xff\x9f\x0c\xa2\x56\x11\xda\xf9\x06\x08\ +\x27\x4e\x27\x26\x13\xa7\xea\xfc\x9c\xce\xc8\x72\xe3\xc6\x8d\x6a\ +\xec\x68\x47\x8d\x1a\xa5\xce\x17\x0b\x17\x2e\xb4\x9e\xb9\x71\xe6\ +\x87\x0f\x27\xb1\x9c\x23\x9c\xe3\x44\x7a\x7a\xba\x3c\x7e\xfc\xb8\ +\x3c\x7c\xf8\xb0\x6a\x67\xcc\x98\xa1\xea\x36\xc4\x0f\xea\x46\x10\ +\xf1\x13\x16\x16\xf6\x6f\xec\xd7\x2f\x5e\xbc\x58\xd5\x9d\x78\x86\ +\xf0\x81\x33\x18\xec\xe7\xe7\xe7\xab\x5a\x15\x3c\x74\xe8\x90\x0c\ +\x0d\x0d\xfd\x37\xf6\x4f\xdb\x8e\xbf\xb6\xb6\xd6\x3a\xfe\x7d\xfb\ +\xf6\xc9\xaa\xaa\x2a\x15\x3f\xc5\xc5\xc5\xd6\x33\x9f\x03\x5a\x4c\ +\xec\x7f\x80\xf5\xb5\x6d\xdb\x36\xeb\xfa\x1a\x3b\x76\xac\xea\x87\ +\xbd\x7c\xd2\xa4\x49\x8a\x13\x26\x4c\x90\x3d\x7a\xf4\x70\x66\x7f\ +\xb7\x89\xfd\xd7\x84\x96\x53\x3e\xd2\x79\x89\x78\x03\x71\xd1\xa7\ +\x4f\x1f\xd9\xbb\x77\x6f\xd5\xfa\xf8\xf8\x18\xef\x85\xbe\xd2\xef\ +\xc1\xbd\x1f\xeb\x7d\xd7\x9a\xd8\xef\x29\xb4\x3c\xe8\xa7\x13\x35\ +\x6d\xee\xd0\xa1\x43\xd5\x19\x3d\x2d\x2d\x4d\xad\x6b\xbc\x2f\x40\ +\xfe\xa1\x6b\x73\x88\x4f\xd9\xdc\x8f\xbe\x5d\x4d\xec\x3b\x42\x36\ +\x72\x1e\xea\x2c\xbc\x0b\xc0\xdc\x21\x6f\x50\xbc\xc3\x7e\x7c\x33\ +\x6d\x39\x42\x1e\xf2\xe2\x82\x05\x0b\xd4\x39\x66\xfe\xfc\xf9\x2a\ +\xbf\xfa\xfa\xfa\xc2\xfe\x4c\x37\xd8\xcf\xa4\xb9\xfe\x9e\x9e\xc1\ +\x4d\x3a\x47\x34\x50\xdb\x40\x67\xa9\x5b\xb4\xe6\xf0\x5e\xc4\xe9\ +\xf8\x51\x27\xa1\xe8\x0a\x11\xcd\xaa\x93\x50\x7f\x0d\x21\x86\xea\ +\x6d\xbf\x66\x8e\x75\x2b\xf1\x86\xd0\xfe\x0e\x81\xb6\x9c\xe8\xd9\ +\x8c\xfe\x2f\x89\x47\x63\xf5\x6c\x33\xfb\x67\xdb\xf5\x7f\xdb\x85\ +\x3e\xd0\x18\x46\x1c\x28\xb4\xbd\xcd\xb6\x3f\xf6\x58\xec\xd3\xcf\ +\x0a\xed\x59\xe2\xf3\x5c\xe2\x02\xa1\xfd\x3b\x6c\xec\xe5\xd0\x78\ +\x9d\x78\x99\xf2\xec\x5d\x9c\x25\x91\xe3\xb1\x2f\xd1\x39\xf0\xaf\ +\x84\x84\x84\xdf\x29\x37\x36\x52\x9d\xdd\x48\xf9\xf8\x7e\x7c\x7c\ +\xec\xb7\x31\xb1\x53\xee\x50\x7c\x60\xaf\x1f\x2a\x6c\x6a\x2e\xe4\ +\x69\xec\xc9\xd9\xd9\xd9\x72\xd1\xa2\x45\x2a\x87\xe2\x0c\x7b\xea\ +\xd4\x29\xb5\x17\x91\xed\xbb\x55\xd5\x15\xe7\xcb\xde\x2a\xfb\x2c\ +\x32\x32\x02\xfd\xf1\x98\xdf\xb5\xed\x8f\xf3\xec\xce\x9d\x3b\x25\ +\xf2\x5c\x40\x40\x80\xca\x3b\xf5\xf5\xf5\x46\xff\x3b\xc7\xde\x39\ +\x76\xaa\xb2\xba\xf2\x12\xad\x89\xaf\x74\xff\xe7\x6d\xfb\x63\xad\ +\xe0\x8c\x8c\xf7\xa8\xd8\x43\x10\xd7\xc8\xf3\x89\x89\x89\x18\xcf\ +\xbd\x8c\x8c\x55\x5f\x52\xad\xf0\x35\xed\x7f\x5f\x0b\x2d\x46\x9e\ +\x13\xda\x9e\x91\x4d\xfd\x2f\x8e\x1b\x37\x4e\xce\x99\x33\x07\xef\ +\x52\x55\x0e\x9a\x3c\x79\xb2\x5a\x0f\xc8\x53\x14\xb3\x0f\x75\xc2\ +\x17\x62\x24\xd4\xf6\x41\x50\x9c\x67\x61\x7d\x42\x2f\x74\x63\x0f\ +\x44\x5e\xc6\xf7\xac\xac\x2c\xdb\x77\xd1\xa0\xa3\xfe\x96\x1d\x3b\ +\x76\x28\xbd\xd8\xaf\x83\x82\x82\x64\x4e\x4e\x8e\xac\xa9\xa9\x51\ +\xfa\xed\xfa\xdf\xb0\xef\x4f\xe3\xb2\x50\xee\xfc\x23\x35\x35\xb5\ +\x91\x9e\x5b\x63\xf7\xee\xdd\x1f\x62\x9f\xc1\x5c\x60\x8d\xd3\x98\ +\xff\x14\xda\x39\xf9\x0f\xa1\xd5\x6a\x61\x76\xb1\x84\xf9\x48\xd1\ +\x63\x63\x19\xcd\xff\x6d\xec\x2f\x78\xcf\x80\xfc\x4c\xf6\x51\x93\ +\x25\xe8\x71\x84\xd6\x2c\x97\xf9\xd3\xf3\xba\x8e\x71\xe3\x79\xce\ +\x9b\x37\x0f\x7b\xf9\x0b\x26\xf7\xdb\x63\x00\xcd\xff\x07\xb4\xcf\ +\x34\x90\x9d\x2b\x18\x0b\xf9\xcf\x6c\x46\x7f\x06\x83\xc1\x60\x30\ +\x18\x0c\x06\x83\xc1\x60\x30\x18\x0c\x06\x83\xc1\x60\x30\x18\x0c\ +\x06\x83\xc1\x60\x30\x18\x0c\x06\xa3\x8d\xe2\x6f\xb6\xa9\x79\x63\ +\ \x00\x00\x02\x6f\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -1112,6 +1252,104 @@ \x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\ \x40\xc3\xff\xfe\xef\xff\x01\xe5\xf9\xa3\x47\x4e\x17\x0b\xed\x00\ \x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x05\xfd\ +\x00\ +\x00\x80\xdc\x78\x9c\xed\x5c\x57\x88\x5d\x55\x14\x5d\x63\x12\x63\ +\x4c\x9b\x18\x35\x63\xe5\x59\x89\x05\x89\x82\x88\x05\x1c\x5b\x34\ +\xa4\x68\x3e\xfc\x10\x25\x7e\xf8\x21\xa2\xc9\x57\x2c\x58\x62\xd4\ +\x58\xd0\x88\x10\xa3\x12\x30\x22\x16\x44\x90\xd8\xb1\x44\x62\x41\ +\x04\x11\xb1\x80\x20\xa2\xa2\x62\x2f\xb1\xc4\xd8\x35\xee\xc5\xde\ +\x87\xb9\x79\x79\x33\xb7\x9d\x37\xef\xde\xf7\xf6\x82\xc5\x9b\x7b\ +\xef\xb9\xbb\x9d\x73\xf6\x3e\xfb\x7e\x0c\xd0\x87\xb1\x18\x1c\x84\ +\xfc\x36\x30\x53\x7e\x67\x03\x68\x34\xec\xba\x1f\x58\x22\xf7\x06\ +\x06\xec\x7a\x02\x70\xe7\x19\x40\x7f\xbf\x5d\x8f\x05\x36\x9c\x05\ +\xcc\x94\x77\x64\x18\x96\x43\xef\x3b\x1c\x0e\x87\xc3\xe1\x70\x38\ +\x1c\x19\xb1\x25\xc1\x5e\xc4\x16\xf4\x76\x0c\x7a\xdd\x7f\xa2\xd7\ +\x63\xe0\xfe\x7b\x0c\xdc\xff\xde\xf6\x9f\x70\xff\x7b\x3b\x06\xb1\ +\xfd\x6f\x95\x57\x87\x63\x15\x90\xd7\xa6\x3c\xfe\xd5\xc1\x7f\x22\ +\xa6\x4f\xee\x7f\x75\xfd\x1c\x0e\x31\x7d\xaa\x63\x0c\x62\xdb\xdb\ +\x0d\x31\x88\x2d\xaf\xea\x31\x68\x87\xad\x1e\x83\xfa\xfb\xdf\x8e\ +\x18\x54\x19\x75\x5b\xb3\xb1\x51\xe7\x3a\x5e\x16\xdd\x70\x96\x29\ +\x8a\x6e\x3b\xd3\xe5\x41\x9a\x7f\xdd\x1e\x83\x2c\x7e\x75\xf3\x5a\ +\xc8\xea\x4b\xaf\xfb\xdf\x3c\xb6\xdb\xe2\x90\x15\xed\xcc\x8d\x75\ +\x88\x69\xcc\xfa\x50\xc7\x3a\x53\xb6\x46\xd6\xbd\xce\xb6\xb2\x2f\ +\xcd\xfe\xbc\xe7\x8b\xaa\xfa\x5f\xe4\x9c\x50\x47\x3f\x5b\x21\xab\ +\xdd\xdd\xe6\x37\x11\x7b\x8f\xd7\x09\x65\x7c\xe8\x75\xff\x63\xbc\ +\xdf\x49\xc4\x5a\xc3\x75\x8c\x41\xcc\x3d\x5c\xc7\x5c\xd0\xca\xce\ +\xd8\x7b\xa0\xaa\xfe\x0f\x67\x67\x3b\xfc\xaf\x5a\x0c\x46\xb2\xaf\ +\x88\xed\x59\xe2\x58\xa5\x18\xa4\xd9\xd5\x2e\xff\xab\x12\x83\xbc\ +\xfe\xa7\xd9\x1d\x73\x2d\xb5\x1b\x59\xed\x29\xea\x7f\x19\x39\xa3\ +\x81\x58\x7e\xe5\x19\x57\x55\xff\x63\xcb\xad\x03\xaa\x34\x17\x9d\ +\x80\xfb\xdf\xdb\xfe\x3b\x1c\x8e\x1a\x83\xff\x27\xa0\x01\xfd\x5f\ +\x01\xfe\x7f\x02\x1c\x19\xd1\x27\x9c\xde\x41\xfd\xd3\x84\x9b\x84\ +\x4f\x77\x48\xff\x04\xe1\x2b\xd0\xba\x7f\x62\x87\x6c\x58\x62\xfa\ +\x5f\x36\x7b\x46\x1b\x33\x84\x3f\x08\xff\x13\xee\xd8\x01\xfd\xc4\ +\x4a\x68\x0c\x66\x67\x18\xbb\x53\x13\xb9\x86\xfa\x4a\xea\x5f\x0a\ +\xf5\x7f\x55\x93\xec\x39\xc2\x15\xc2\x1b\x8d\xeb\x85\x1b\x85\x3f\ +\x62\xe8\xbc\xf8\x8b\x8d\x2d\x83\xdd\x84\x3f\x0b\x7f\x17\xfe\x89\ +\x6d\xfb\xd1\x66\xd2\x56\xc6\xec\x1a\xe1\x95\x28\xbf\x6e\x26\x0b\ +\xbf\x36\xd9\x2f\x98\xdc\xeb\x85\xd7\x0a\x4f\x83\xc6\x98\x3c\x5d\ +\xf8\x87\x8d\xbb\xa7\xa4\xce\x24\x38\x7f\x57\x9b\xdc\x75\x29\x63\ +\xe7\x25\x6c\x78\x16\xf1\xd6\xec\xce\xc2\xcf\x4d\xee\x93\xc2\xf1\ +\x29\x36\x7c\x23\xfc\x1e\xe5\xe7\x3e\x89\xb0\x0f\x82\x0d\xdb\x8f\ +\x30\x76\x2a\xe2\xac\x7d\x98\x8c\x05\xc2\x9f\x4c\xf7\x46\xfb\xe5\ +\x7a\x3f\x35\x82\xfc\x34\xf4\x0b\xff\x32\xce\x87\xfa\xf5\xb8\xd9\ +\xf0\xb7\x70\xd9\x28\xe8\xa7\xef\x2b\x12\xf7\x18\xfb\x47\x31\x34\ +\x1f\x7c\x36\x23\x83\x2c\xae\x87\xbc\xfb\x91\xf1\x9f\x86\x6d\xe7\ +\x7b\x12\x34\x37\x07\x1b\xbe\x85\xee\xc1\x24\xb8\x0e\x42\x9e\xda\ +\x20\xdc\x2c\xbc\x22\xa7\xfe\xe1\x40\xfd\xbf\x41\xf7\xd9\x23\x66\ +\xc3\xbf\xd0\x9c\x70\xbc\xf0\x26\xb3\x29\xd8\xc7\xb9\xfa\x55\x78\ +\x79\x04\xdd\xdc\x7f\x61\x0d\x04\x79\xcb\x4c\x7f\xc8\x81\x41\xe7\ +\x73\xd8\x3a\x4f\xed\x10\x41\x7f\x98\x7b\xfa\x3f\x27\x71\xff\x14\ +\x68\x8e\x0c\x3e\xdf\x16\x41\x57\x33\x16\x26\xe4\x7f\xd7\xe2\xf9\ +\x38\xe1\x33\xf6\x9c\x39\x68\x5e\x44\xdd\x53\xa0\x73\xf8\x8f\xf0\ +\x4d\x68\x4d\x1a\x6c\x31\xee\xa2\x84\x8d\xac\x81\x53\x23\xe8\xe6\ +\xfa\x7f\xcc\x64\xae\x11\x2e\xb6\xbf\x5f\x6a\x1a\xc7\xfd\xf5\x3c\ +\xb4\x66\xbe\x63\x63\x9e\x80\xce\x7d\x19\xec\x6e\xb2\x28\x97\xeb\ +\x8f\xeb\x7f\x93\xdd\x5b\x90\x18\x37\xdd\xee\x7d\x02\xcd\x57\x9b\ +\xed\xfa\xaa\x92\xfa\x2f\x83\xae\xeb\xe5\x89\x7b\x94\xcf\x7c\x7c\ +\x5d\xe2\x1e\xf3\x15\xf7\xc1\x4a\xbb\x9e\x6b\x63\xca\xea\xbf\x05\ +\xea\x47\x73\x9e\x63\x5c\x93\x39\x8d\xf9\x6a\xb0\x69\x5c\xf3\x98\ +\x22\xe0\x59\x86\xf9\x6e\x4a\x49\x39\x45\x41\xfb\x63\xd5\xd4\x4a\ +\x82\xdf\x09\x06\x84\xb3\xe0\xdf\x09\x22\x81\x39\x82\x7d\x4b\xcc\ +\x73\x60\x12\xec\x0d\x98\xe3\x6f\x68\x93\xfc\x31\xc2\x7b\xa1\x75\ +\xe6\xc0\x36\xe9\x18\x84\xf6\x35\x67\xb6\x49\x3e\xcf\xee\x6f\x0b\ +\xef\xc2\xd0\xde\x65\x2e\x67\x4f\x7f\xb2\xf0\x6c\x68\x4e\xbd\x59\ +\x78\x3b\xb4\x76\xe5\xc1\x58\x93\xcd\xba\xf0\x22\xb4\x1e\xbd\x2b\ +\xfc\x54\xf8\x81\xdd\x67\xde\xfc\x52\xf8\x00\x8a\x9d\x57\x43\x3d\ +\xe5\xb9\x9f\x75\x6f\xa9\xd9\xbf\x27\x74\x7d\x51\x17\x7b\x34\x9e\ +\xc7\xc7\x14\x90\xcf\x75\xc4\x5a\xf9\xaa\x70\xaf\x16\xcf\x8f\x84\ +\xfa\x42\x1f\x76\x2d\x20\x9f\x58\x0e\xf5\xe1\x3d\xe1\x41\x2d\x9e\ +\x33\xfd\xf0\xac\x52\xa4\x67\x3b\x5a\xf8\x3e\xd4\x87\x8f\x85\x1f\ +\x0a\xcf\x43\xb1\x58\xb4\xc2\x1d\xd0\x18\xef\x22\xdc\x4f\xf8\x16\ +\xd4\x17\xf6\xc1\x13\x23\xc8\x3f\x58\x78\x68\xe2\x9a\x3a\xc2\xd9\ +\xf9\x35\xe1\x31\x89\x67\x0d\xe1\x22\xe1\x7d\xd0\xb3\xed\xac\x02\ +\xfa\x0e\x81\xc6\x69\x8d\xfd\x72\xed\x5c\x20\x5c\x0d\xad\xb1\xec\ +\x75\xdf\x80\x7e\x7b\x3b\x2c\xa7\xec\x10\x9f\xcf\x84\x7b\x0b\x0f\ +\x10\x3e\x85\xad\x7b\x57\xce\x57\x91\x3a\xca\x77\x1e\x34\x39\x3c\ +\xe3\x6e\x67\xf7\x59\x9b\x2f\x85\x9e\x7b\xd8\x17\x4c\x2a\x28\x9b\ +\x71\x65\xcf\xc0\xb5\xc4\x9c\xb1\x6f\xe2\xf9\xe1\xc2\xaf\x4c\x37\ +\xd7\xc3\xb8\x9c\xf2\x99\x87\x38\xa7\xec\x95\x8e\x35\x39\xab\x12\ +\x3e\xb0\x2f\x63\x9f\xb9\xde\x9e\x2d\x46\xbe\x18\x31\x8f\x31\xd7\ +\x9c\x60\xd7\x94\xcd\x9e\x2f\x7c\xc3\xbd\x15\x1a\x33\xce\x09\xe7\ +\x63\x6d\x42\x77\x16\x70\xad\x33\x26\x61\x4f\x31\xef\x0d\xd8\x2f\ +\xb1\x0f\x86\xe2\x35\x11\xf9\xbf\x1d\x1f\x27\x3c\x37\xe7\x3b\x1d\ +\x01\x13\x15\x0f\xd9\x0d\xd4\xe2\x9c\xc4\xdc\xce\x5c\x58\x64\x4f\ +\x10\x5c\xb7\xcc\x05\xe7\x94\xb0\x81\x35\xef\xee\xc4\x35\xfb\x41\ +\xf6\x07\xfb\x0b\x8f\x10\xee\x91\xf2\x3e\xf3\x1f\x73\x3b\xcf\x39\ +\xec\xa9\x59\x47\xf9\xdd\xe1\x0b\x68\x4f\x38\x3f\xe5\x7d\x9e\xdb\ +\x5f\x87\xe6\x06\xf6\xcf\x47\x41\xf7\x09\xd7\x33\xf3\x51\x96\xf3\ +\xd9\xc5\xd0\x3c\x79\x52\xe2\x1e\x73\xdd\x25\x19\xde\x1f\x30\xdd\ +\xfc\x7e\xc9\xbe\x99\x7b\x3d\x4f\x6d\x62\x4d\x5e\x64\x7f\x53\x3f\ +\xbf\x3b\xf0\x1b\x44\x38\x93\x31\x37\xb1\x3f\xba\x10\xe9\x79\x89\ +\x67\x04\xc6\xee\x7e\x68\xbd\x7f\x08\x7a\x66\xe1\xfc\x9c\x9f\xf2\ +\x3e\x73\x39\xeb\x43\xe8\x2d\x43\xce\x59\x9d\xc1\x87\xf1\xa6\xf3\ +\x23\x68\x0e\x0c\x75\x9e\x36\xb0\x8f\x5e\x98\xf2\xfe\x5c\x1b\xcb\ +\x3a\xf9\x30\x34\x5f\x34\xa0\xf5\x80\xb9\x6d\x2d\x46\xfe\x2e\xcb\ +\xf8\x85\x6f\x5f\xec\x21\x27\x9b\x0d\x5c\x7b\xcc\xb3\xac\xed\x23\ +\xcd\x09\xc7\xc7\xf8\x8e\xe1\x70\x38\x1c\x0e\x87\xc3\xe1\x70\x38\ +\x1c\x0e\x87\xc3\xe1\x70\x38\x1c\x0e\x87\xc3\xe1\x70\x38\x1c\x0e\ +\x87\xc3\xe1\x70\x54\x18\xff\x03\x57\x3a\x56\xa8\ \x00\x00\x52\xd0\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -3168,6 +3406,1845 @@ \xef\x7d\x9f\x7d\xe6\xa9\x76\x0f\xd4\xa9\x58\x3c\x14\x92\x24\x49\ \x92\x24\x49\x92\x64\x39\xff\x0f\x1b\xcb\x93\xc1\xa8\xfa\xf9\xac\ \x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x6b\x97\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x06\x40\x00\x00\x06\x40\x08\x03\x00\x00\x00\x16\xd2\x7e\x95\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x04\x67\x41\x4d\x41\x00\x00\xb1\x8f\x0b\xfc\x61\x05\x00\x00\x03\ +\x00\x50\x4c\x54\x45\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x33\x00\x00\x66\x00\x00\x99\x00\x00\xcc\x00\x00\xff\x00\ +\x33\x00\x00\x33\x33\x00\x33\x66\x00\x33\x99\x00\x33\xcc\x00\x33\ +\xff\x00\x66\x00\x00\x66\x33\x00\x66\x66\x00\x66\x99\x00\x66\xcc\ +\x00\x66\xff\x00\x99\x00\x00\x99\x33\x00\x99\x66\x00\x99\x99\x00\ +\x99\xcc\x00\x99\xff\x00\xcc\x00\x00\xcc\x33\x00\xcc\x66\x00\xcc\ +\x99\x00\xcc\xcc\x00\xcc\xff\x00\xff\x00\x00\xff\x33\x00\xff\x66\ +\x00\xff\x99\x00\xff\xcc\x00\xff\xff\x33\x00\x00\x33\x00\x33\x33\ +\x00\x66\x33\x00\x99\x33\x00\xcc\x33\x00\xff\x33\x33\x00\x33\x33\ +\x33\x33\x33\x66\x33\x33\x99\x33\x33\xcc\x33\x33\xff\x33\x66\x00\ +\x33\x66\x33\x33\x66\x66\x33\x66\x99\x33\x66\xcc\x33\x66\xff\x33\ +\x99\x00\x33\x99\x33\x33\x99\x66\x33\x99\x99\x33\x99\xcc\x33\x99\ +\xff\x33\xcc\x00\x33\xcc\x33\x33\xcc\x66\x33\xcc\x99\x33\xcc\xcc\ +\x33\xcc\xff\x33\xff\x00\x33\xff\x33\x33\xff\x66\x33\xff\x99\x33\ +\xff\xcc\x33\xff\xff\x66\x00\x00\x66\x00\x33\x66\x00\x66\x66\x00\ +\x99\x66\x00\xcc\x66\x00\xff\x66\x33\x00\x66\x33\x33\x66\x33\x66\ +\x66\x33\x99\x66\x33\xcc\x66\x33\xff\x66\x66\x00\x66\x66\x33\x66\ +\x66\x66\x66\x66\x99\x66\x66\xcc\x66\x66\xff\x66\x99\x00\x66\x99\ +\x33\x66\x99\x66\x66\x99\x99\x66\x99\xcc\x66\x99\xff\x66\xcc\x00\ +\x66\xcc\x33\x66\xcc\x66\x66\xcc\x99\x66\xcc\xcc\x66\xcc\xff\x66\ +\xff\x00\x66\xff\x33\x66\xff\x66\x66\xff\x99\x66\xff\xcc\x66\xff\ +\xff\x99\x00\x00\x99\x00\x33\x99\x00\x66\x99\x00\x99\x99\x00\xcc\ +\x99\x00\xff\x99\x33\x00\x99\x33\x33\x99\x33\x66\x99\x33\x99\x99\ +\x33\xcc\x99\x33\xff\x99\x66\x00\x99\x66\x33\x99\x66\x66\x99\x66\ +\x99\x99\x66\xcc\x99\x66\xff\x99\x99\x00\x99\x99\x33\x99\x99\x66\ +\x99\x99\x99\x99\x99\xcc\x99\x99\xff\x99\xcc\x00\x99\xcc\x33\x99\ +\xcc\x66\x99\xcc\x99\x99\xcc\xcc\x99\xcc\xff\x99\xff\x00\x99\xff\ +\x33\x99\xff\x66\x99\xff\x99\x99\xff\xcc\x99\xff\xff\xcc\x00\x00\ +\xcc\x00\x33\xcc\x00\x66\xcc\x00\x99\xcc\x00\xcc\xcc\x00\xff\xcc\ +\x33\x00\xcc\x33\x33\xcc\x33\x66\xcc\x33\x99\xcc\x33\xcc\xcc\x33\ +\xff\xcc\x66\x00\xcc\x66\x33\xcc\x66\x66\xcc\x66\x99\xcc\x66\xcc\ +\xcc\x66\xff\xcc\x99\x00\xcc\x99\x33\xcc\x99\x66\xcc\x99\x99\xcc\ +\x99\xcc\xcc\x99\xff\xcc\xcc\x00\xcc\xcc\x33\xcc\xcc\x66\xcc\xcc\ +\x99\xcc\xcc\xcc\xcc\xcc\xff\xcc\xff\x00\xcc\xff\x33\xcc\xff\x66\ +\xcc\xff\x99\xcc\xff\xcc\xcc\xff\xff\xff\x00\x00\xff\x00\x33\xff\ +\x00\x66\xff\x00\x99\xff\x00\xcc\xff\x00\xff\xff\x33\x00\xff\x33\ +\x33\xff\x33\x66\xff\x33\x99\xff\x33\xcc\xff\x33\xff\xff\x66\x00\ +\xff\x66\x33\xff\x66\x66\xff\x66\x99\xff\x66\xcc\xff\x66\xff\xff\ +\x99\x00\xff\x99\x33\xff\x99\x66\xff\x99\x99\xff\x99\xcc\xff\x99\ +\xff\xff\xcc\x00\xff\xcc\x33\xff\xcc\x66\xff\xcc\x99\xff\xcc\xcc\ +\xff\xcc\xff\xff\xff\x00\xff\xff\x33\xff\xff\x66\xff\xff\x99\xff\ +\xff\xcc\xff\xff\xff\xaf\x56\x4d\x1c\x00\x00\x00\x28\x74\x52\x4e\ +\x53\x34\xbb\xeb\xfe\x78\x9b\x54\xdd\x62\x86\xaa\x45\xca\x92\x71\ +\x5a\xb2\xa3\xf0\xe3\xd1\xc3\x3c\x89\x4a\x68\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\x2c\xf5\xce\x00\x00\x00\ +\x09\x70\x48\x59\x73\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7\x6f\ +\xa8\x64\x00\x00\x67\xec\x49\x44\x41\x54\x78\x5e\xed\xdd\x6b\x43\ +\x14\xb9\x16\x46\x61\x40\x6e\x22\x72\x17\x74\xfe\xff\x0f\x1d\xc4\ +\x57\x4b\x94\x2d\xdd\x3b\xa9\xaa\x37\xbb\xd6\xf3\xe9\x9c\x19\x07\ +\x93\x50\x61\x69\x57\x77\xea\xe0\x3f\x00\x4e\xbe\xdd\x7f\xf8\xe1\ +\xee\xe1\xe2\x4a\xff\x0c\xb0\x44\x40\x00\x1b\x07\xdf\x4e\x2e\xef\ +\x94\x0f\x39\xba\x7d\xd4\xbf\x04\xec\x10\x10\xc0\xc1\xa7\xab\x8b\ +\x33\x35\xe3\x4f\xf7\xc7\xfa\x35\x80\x19\x02\x02\xac\xec\xf4\xe3\ +\xcd\xcf\x57\xad\x02\x47\x24\x04\x96\x08\x08\xb0\x9e\xf3\xcf\x5f\ +\xfe\x78\xc9\x2a\x70\x7f\xaa\xff\x02\x30\x42\x40\x80\x35\x3c\x7e\ +\x3b\xb9\x54\x1c\x76\x73\xa1\xff\x10\xf0\x41\x40\x80\x85\x7d\x3d\ +\x0e\x6f\x77\xfc\xcb\xbd\xfe\x73\xc0\x06\x01\x01\x96\x73\xfd\x74\ +\x78\xa4\x1e\x24\x5c\xeb\xab\x00\x26\x08\x08\xb0\x88\x9d\x6f\x77\ +\xfc\xc3\x37\x7d\x2d\xc0\x03\x01\x01\x66\xf6\xe9\xea\xf6\x41\x05\ +\x68\xc5\x07\x0b\x61\x85\x80\x00\xf3\x49\xde\xee\x88\x9d\xeb\x0b\ +\x03\x0e\x08\x08\x30\x8b\xb6\xdb\x1d\x21\x76\x2c\x8c\x70\x39\x02\ +\x9d\x1d\x9c\x7f\xfe\xf3\x40\x92\x7e\x78\x2f\x16\x8c\x10\x10\xa0\ +\x9f\x8e\xb7\x3b\x22\x87\xfa\xad\x80\xf5\x11\x10\xa0\x8b\xf7\x0f\ +\x24\xe9\x84\xdb\x20\xb0\x41\x40\x80\x56\xd7\x4f\x87\xb3\xbd\x64\ +\xf5\xb7\x3b\xfd\xae\xc0\xea\x08\x08\x90\xb7\xf7\x81\x24\x3d\x7c\ +\xd6\x6f\x0e\xac\x8d\x80\x00\x29\xdd\xdf\xa1\xbb\x3b\x8d\x00\x58\ +\x1b\x01\x01\xf6\x75\xbd\xd4\xed\x8e\xc0\x89\xc6\x01\xac\x8c\x80\ +\x00\x7b\xe8\x71\x20\x49\x33\xee\x82\xc0\x04\x01\x01\x76\xf2\x78\ +\xb5\xc2\xed\x8e\x00\x6f\xc4\x82\x07\x02\x02\xbc\x67\xc5\xdb\x1d\ +\x6f\xfb\xa2\x81\x01\xeb\x22\x20\xc0\x3f\x9c\x7e\x9c\xe5\x40\x92\ +\x56\x1a\x1d\xb0\x2e\x02\x02\xbc\xe9\xe0\xfc\x64\xbe\x03\x49\x5a\ +\xf1\x80\x5b\x58\x20\x20\xc0\x9f\x16\x38\x90\xa4\x11\xef\xc3\x82\ +\x05\x02\x02\xfc\xe6\xf4\xf8\xc6\xeb\x76\xc7\xdb\x1e\x34\x5c\x60\ +\x55\x04\x04\xf8\x61\xd9\x03\x49\xda\xf0\x46\x5e\x58\x20\x20\xc0\ +\xc1\x1a\x07\x92\xb4\xd1\xc8\x81\x55\x11\x10\x6c\x9a\xdd\x3b\x74\ +\x77\xf4\xa8\xf1\x03\x6b\x22\x20\xd8\xaa\xb5\x0f\x24\x69\xf2\x55\ +\x93\x00\xd6\x44\x40\xb0\x41\x16\x07\x92\x34\xb9\xd6\x4c\x80\x35\ +\x11\x10\x6c\x8a\xd3\x81\x24\x2d\x38\xcc\x04\x0e\x08\x08\xb6\x62\ +\xd4\xdb\x1d\x6f\xfa\xa6\x49\x01\x6b\x22\x20\xd8\x00\xd3\x03\x49\ +\x1a\x10\x10\x38\x20\x20\x28\xcd\xfa\x40\x92\x06\x04\x04\x0e\x08\ +\x08\xaa\xf2\x3f\x90\xa4\x01\x01\x81\x03\x02\x82\x82\x06\x39\x90\ +\xa4\x01\x01\x81\x03\x02\x82\x5a\x46\x3a\x90\xa4\x01\x01\x81\x03\ +\x02\x82\x2a\xbe\x1f\x48\xb2\x85\x76\xbc\x20\x20\x70\x40\x40\x50\ +\x40\xa9\x77\xe8\xee\x84\x80\xc0\x01\x01\xc1\xd8\x4e\x47\x3e\x90\ +\x24\x8f\x80\xc0\x01\x01\xc1\xb0\xc6\x3f\x90\x24\x8f\x80\xc0\x01\ +\x01\xc1\x80\x1e\xc7\x3b\x7f\xbd\x33\x02\x02\x07\x04\x04\x63\xd9\ +\xde\xed\x8e\x37\x11\x10\x38\x20\x20\x18\x46\xbd\x03\x49\xf2\x08\ +\x08\x1c\x10\x10\x8c\x60\xcb\xb7\x3b\xde\x44\x40\xe0\x80\x80\xc0\ +\x5b\xe9\x03\x49\xf2\x08\x08\x1c\x10\x10\xd8\xfa\x5a\xfe\x40\x92\ +\x3c\x02\x02\x07\x04\x04\x8e\xae\x9f\xb8\xdd\xf1\x4f\x04\x04\x0e\ +\x08\x08\xbc\x6c\xea\x40\x92\x3c\x02\x02\x07\x04\x04\x36\xb8\xdd\ +\xb1\x3b\x02\x02\x07\x04\x04\x0e\x36\x7a\x20\x49\x1e\x01\x81\x03\ +\x02\x82\x95\x5d\x3f\xf1\x0e\xdd\xfd\x11\x10\x38\x20\x20\x58\x0d\ +\x07\x92\xe4\x11\x10\x38\x20\x20\x58\x03\x07\x92\x34\x22\x20\x70\ +\x40\x40\xb0\xb0\x6b\x6e\x77\x74\x40\x40\xe0\x80\x80\x60\x39\x1c\ +\x48\xd2\x0d\x01\x81\x03\x02\x82\x25\x3c\xf2\x0e\xdd\xbe\x08\x08\ +\x1c\x10\x10\xcc\x8c\xdb\x1d\x73\x20\x20\x70\x40\x40\x30\x1f\x0e\ +\x24\x99\x0d\x01\x81\x03\x02\x82\x39\x1c\x9c\x73\x20\xc9\xac\x08\ +\x08\x1c\x10\x10\x74\xc6\x81\x24\x4b\x20\x20\x70\x40\x40\xd0\xcf\ +\xe9\x31\xef\xd0\x5d\x08\x01\x81\x03\x02\x82\x2e\xae\x9f\x0e\x79\ +\xc9\x6a\x41\x04\x04\x0e\x08\x08\x1a\x71\x20\xc9\x1a\x08\x08\x1c\ +\x10\x10\xe4\xf1\x0e\xdd\xd5\x10\x10\x38\x20\x20\x48\xe1\x40\x92\ +\x75\x11\x10\x38\x20\x20\xd8\x17\x07\x92\x18\x20\x20\x70\x40\x40\ +\xb0\xbb\xc7\x2b\x6e\x77\x98\x20\x20\x70\x40\x40\xb0\x13\x6e\x77\ +\xf4\x74\x74\x73\xa2\xff\x95\x45\x40\xe0\x80\x80\xe0\x3d\xa7\x1f\ +\x39\x90\xa4\x9f\xb3\x8b\xe3\xaf\xdf\x57\x55\xff\x37\x8b\x80\xc0\ +\x01\x01\x41\x8c\x03\x49\xba\x7a\xb8\xbd\x7a\xd4\xca\x12\x10\x94\ +\x40\x40\xf0\x26\x0e\x24\xe9\xe9\xee\xf2\xf3\xb9\x16\xf6\x27\xfd\ +\x9b\x2c\x02\x02\x07\x04\x04\x7f\x3a\x3d\xbe\xe1\x76\x47\x37\x47\ +\x87\x4f\xa7\x5a\xd8\x57\xf4\xaf\xb3\x08\x08\x1c\x10\x10\xfc\x86\ +\x03\x49\x7a\x3a\xbb\xf9\xf8\x72\xbb\xe3\x4d\xfa\x35\x59\x04\x04\ +\x0e\x08\x08\x5e\x1c\x7c\xe3\x76\x47\x47\x0f\xb7\x57\x9f\xb4\xb2\ +\x01\xfd\xc2\x2c\x02\x02\x07\x04\x04\xbc\x43\xb7\xa7\xbb\xcb\x93\ +\x6f\xbb\xec\x2a\xfd\xf2\x2c\x02\x02\x07\x04\x64\xd3\x4e\x3f\x1e\ +\x72\x20\x49\x37\x77\x87\x4f\xd7\x5a\xd8\xf7\xe9\xbf\xc9\x22\x20\ +\x70\x40\x40\xb6\x8a\x03\x49\x7a\xba\xbf\xf9\xf8\xe6\xad\xf2\x98\ +\xfe\xc3\x2c\x02\x02\x07\x04\x64\x7b\x38\x90\xa4\xab\xb3\x8b\xe3\ +\x77\x6e\x77\xbc\x49\xff\x75\x16\x01\x81\x03\x02\xb2\x29\xdc\xee\ +\xe8\xea\xf2\xe4\xdb\xf4\xc9\xc0\x3d\xe9\x4b\x64\x11\x10\x38\x20\ +\x20\x5b\xc1\x81\x24\x3d\xdd\x7d\xf9\xeb\x93\x81\x7b\xd2\x17\xca\ +\x22\x20\x70\x40\x40\x36\xe0\xfc\x33\xef\xd0\xed\xe7\xfe\xe6\xe3\ +\xee\xb7\xca\x63\xfa\x6a\x59\x04\x04\x0e\x08\x48\x69\x1c\x48\xd2\ +\xd5\xcf\x83\x10\x7b\xd0\x97\xcc\x22\x20\x70\x40\x40\xaa\xe2\x40\ +\x92\xae\x2e\x4f\x7e\x3b\x08\xb1\x07\x7d\xdd\x2c\x02\x02\x07\x04\ +\xa4\xa0\xeb\x27\x6e\x77\xf4\xd3\x7e\xbb\xe3\x4d\xfa\xea\x59\x04\ +\x04\x0e\x08\x48\x29\x1c\x48\xd2\xd5\xd1\xe1\xbe\x9f\xee\xd8\x9d\ +\x7e\x8b\x2c\x02\x02\x07\x04\xa4\x8a\x4f\x57\xbc\x43\xb7\xa3\x9e\ +\xb7\x3b\xde\xa4\xdf\x27\x8b\x80\xc0\x01\x01\x29\xe0\xf4\xe3\x0d\ +\x07\x92\xf4\xf3\xfe\x41\x88\x3d\xe8\x37\xcb\x22\x20\x70\x40\x40\ +\xc6\xc6\x81\x24\x3d\xdd\x5d\x9e\x9c\x2f\xb5\x23\xf4\x5b\x66\x11\ +\x10\x38\x20\x20\xa3\x7a\xfc\xc6\x81\x24\x1d\xed\x75\x10\x62\x0f\ +\xfa\x7d\xb3\x08\x08\x1c\x10\x90\x01\x71\x20\x49\x57\xf7\x37\xc7\ +\xb3\xdd\x2a\x8f\xe9\x37\xcf\x22\x20\x70\x40\x40\xc6\x72\xfd\xf1\ +\x86\x77\xe8\xf6\x73\xb6\xc8\xed\x8e\x37\x69\x04\x59\x04\x04\x0e\ +\x08\xc8\x30\xb8\xdd\xd1\xd5\x8e\xcf\x7d\x9a\x8d\x86\x91\x45\x40\ +\xe0\x80\x80\x0c\x80\x03\x49\xba\xba\xfb\xf2\x79\xd9\xdb\x1d\x6f\ +\xd2\x60\xb2\x08\x08\x1c\x10\x10\x6f\xdc\xee\xe8\x6a\xff\xe7\x3e\ +\xcd\x46\x23\xca\x22\x20\x70\x40\x40\x6c\x71\x20\x49\x57\xb3\x7f\ +\x32\x70\x4f\x1a\x56\x16\x01\x81\x03\x02\x62\xe8\xe0\x9c\x03\x49\ +\x7a\xea\x7e\x10\x62\x0f\x1a\x5b\x16\x01\x81\x03\x02\xe2\x85\xdb\ +\x1d\x5d\xcd\x74\x10\x62\x0f\x1a\x61\x16\x01\x81\x03\x02\x62\x83\ +\x03\x49\xba\x3a\x3a\xec\xf2\xdc\xa7\xd9\x68\x98\x59\x04\x04\x0e\ +\x08\x88\x83\xeb\xa7\x43\x5e\xb2\xea\xc7\xed\x76\xc7\x9b\x34\xd6\ +\x2c\x02\x02\x07\x04\x64\x5d\x1c\x48\xd2\xd7\xc3\xad\xe1\xed\x8e\ +\x37\x69\xc0\x59\x04\x04\x0e\x08\xc8\x6a\x78\x87\x6e\x57\xdf\x0f\ +\x42\xd4\xca\x0e\x41\xc3\xce\x22\x20\x70\x40\x40\xd6\x70\xcd\xed\ +\x8e\x9e\x8e\x96\x3e\x08\xb1\x07\x8d\x3d\x8b\x80\xc0\x01\x01\x59\ +\x18\x07\x92\x74\x75\xb6\xca\x41\x88\x3d\x68\x02\x59\x04\x04\x0e\ +\x08\xc8\x62\x1e\xaf\xb8\xdd\xd1\xd3\x32\xcf\x7d\x9a\x8d\x66\x91\ +\x45\x40\xe0\x80\x80\x2c\x81\xdb\x1d\x5d\xdd\xad\x7d\x10\x62\x0f\ +\x9a\x4b\x16\x01\x81\x03\x02\x32\xb3\xd3\x8f\x1c\x48\xd2\xd1\xe2\ +\xcf\x7d\x9a\x8d\x26\x94\x45\x40\xe0\x80\x80\xcc\x86\x03\x49\xfa\ +\x32\x3a\x08\xb1\x07\xcd\x2a\x8b\x80\xc0\x01\x01\x99\x03\x07\x92\ +\xf4\x35\xc4\x27\x03\xf7\xa4\xa9\x65\x11\x10\x38\x20\x20\x9d\x9d\ +\x1e\xdf\x70\xbb\xa3\xa3\xcb\x93\x6f\x83\x7c\x32\x70\x4f\x9a\x5f\ +\x16\x01\x81\x03\x02\xd2\x0f\x07\x92\x74\x65\x7c\x10\x62\x0f\x9a\ +\x65\x16\x01\x81\x03\x02\xd2\xc3\x01\x07\x92\x74\x75\x74\xe3\x7d\ +\x10\x62\x0f\x9a\x6a\x16\x01\x81\x03\x02\xd2\x88\x77\xe8\xf6\x55\ +\xf1\x76\xc7\x9b\x34\xdf\x2c\x02\x02\x07\x04\x24\x8f\xf3\xd7\xfb\ +\x7a\x70\x7c\xee\xd3\x6c\x34\xe9\x2c\x02\x02\x07\x04\x24\x85\x03\ +\x49\xba\xba\xbb\x2c\x7d\xbb\xe3\x4d\x9a\x7a\x16\x01\x81\x03\x02\ +\xb2\x27\x0e\x24\xe9\xeb\xe8\xb0\xd4\xa7\x3b\x76\xa7\xf9\x67\x11\ +\x10\x38\x20\x20\xbb\xe3\x76\x47\x5f\x67\x37\x1b\xb9\xdd\xf1\x26\ +\x2d\x42\x16\x01\x81\x03\x02\xb2\x13\x0e\x24\xe9\x6b\xf0\x83\x10\ +\x7b\xd0\x4a\x64\x11\x10\x38\x20\x20\xef\xe1\x40\x92\xae\xbe\x3f\ +\xf7\x89\x8b\xee\x99\xd6\x23\x8b\x80\xc0\x01\x7b\x39\xc6\x81\x24\ +\x7d\xd5\x39\x08\xb1\x07\x2d\x4a\x16\x01\x81\x03\x02\xf2\x26\x0e\ +\x24\xe9\xab\xd8\x41\x88\x3d\x68\x65\xb2\x08\x08\x1c\x10\x90\x3f\ +\x71\x20\x49\x5f\x67\x17\xc7\x5b\xbf\xdd\xf1\x26\x2d\x4f\x16\x01\ +\x81\x03\x02\x32\xf9\x7e\x20\x09\xed\xe8\xa8\xc2\x73\x9f\x66\xa3\ +\x35\xca\x22\x20\x70\xc0\x06\x7f\xf1\x89\x77\xe8\x76\x55\xfc\x20\ +\xc4\x1e\xb4\x52\x59\x04\x04\x0e\x08\x08\x07\x92\xf4\xc5\xed\x8e\ +\xdd\x68\xb9\xb2\x08\x08\x1c\x6c\x3a\x20\x1c\x48\xd2\xd7\x66\x0e\ +\x42\xec\x41\x6b\x96\x45\x40\xe0\x60\xa3\x01\x79\xe4\xfc\xf5\xbe\ +\x2e\x37\x75\x10\x62\x0f\x5a\xb8\x2c\x02\x02\x07\xdb\x0b\x08\x07\ +\x92\xf4\xc5\xed\x8e\x1c\x2d\x5f\x16\x01\x81\x83\x4d\x05\x84\x03\ +\x49\xfa\xda\xec\x41\x88\x3d\x68\x0d\xb3\x08\x08\x1c\x6c\x25\x20\ +\xdc\xee\xe8\x8b\xdb\x1d\xad\xb4\x90\x59\x04\x04\x0e\xea\x07\x84\ +\x03\x49\x3a\xe3\x20\xc4\x2e\xb4\x9a\x59\x04\x04\x0e\x4a\x07\x84\ +\xdb\x1d\x9d\x71\x10\x62\x3f\x5a\xd2\x2c\x02\x02\x07\x55\x7f\x1e\ +\x5c\x3f\x71\xbb\xa3\xa7\x23\x0e\x42\xec\x4c\x0b\x9b\x45\x40\xe0\ +\xa0\x5e\x40\x38\x90\xa4\xb3\xfb\x9b\x63\x6e\x95\xf7\xa7\xd5\xcd\ +\x22\x20\x70\x50\x2a\x20\xdc\xee\xe8\xec\x8c\xdb\x1d\xb3\xd1\x12\ +\x67\x11\x10\x38\xa8\x12\x10\x0e\x24\xe9\x8c\x83\x10\x67\xa6\x75\ +\xce\x22\x20\x70\x50\xe0\x87\xc4\xf5\x13\xef\xd0\xed\x89\xe7\x3e\ +\x2d\x42\xab\x9d\x45\x40\xe0\x60\xe8\x80\x70\x20\x49\x67\xf7\x7c\ +\x32\x70\x31\x5a\xf2\x2c\x02\x02\x07\xa3\x06\x84\x77\xe8\x76\xc6\ +\x27\x03\x17\xa6\x75\xcf\x22\x20\x70\x30\x60\x40\xae\xb9\xdd\xd1\ +\xd7\xe5\xc9\x37\x0e\x42\x5c\x9c\x16\x3f\x8b\x80\xc0\xc1\x58\x01\ +\xe1\x40\x92\xbe\x38\x08\x71\x3d\xfa\x16\x64\x11\x10\x38\x18\x25\ +\x20\x8f\x57\x27\xbc\x43\xb7\x27\x3e\x19\xb8\x32\x7d\x1f\xb2\x08\ +\x08\x1c\x0c\x10\x10\x6e\x77\x74\xc6\xed\x0e\x07\xfa\x66\x64\x11\ +\x10\x38\xf0\x0e\x08\x07\x92\x74\xf6\x70\xcb\x73\x9f\x4c\xe8\x3b\ +\x92\x45\x40\xe0\xc0\x35\x20\x07\xe7\x1c\x48\xd2\xd5\xdd\xe5\x09\ +\x3f\x73\x9c\xe8\xfb\x92\xc5\x37\x13\x0e\x0c\x03\xc2\x81\x24\x9d\ +\x71\xbb\xc3\x91\xbe\x39\x59\x04\x04\x0e\xbc\x02\x72\x7a\xcc\x3b\ +\x74\xbb\x3a\xbb\xe1\x76\x87\x29\x7d\x87\xb2\x08\x08\x1c\xd8\x04\ +\xe4\xfa\xe9\x90\x97\xac\x7a\xe2\xb9\x4f\xde\xf4\x6d\xca\x22\x20\ +\x70\x60\x10\x10\x0e\x24\xe9\xec\xfb\xed\x0e\x6e\x95\xbb\xd3\x37\ +\x2b\x8b\x80\xc0\xc1\xba\x01\xe1\x1d\xba\x9d\x71\x10\xe2\x30\xf4\ +\x1d\xcb\x22\x20\x70\xb0\x5a\x40\x38\x90\xa4\xb3\xfb\x1b\x0e\x42\ +\x1c\x89\xbe\x6d\x59\x04\x04\x0e\xd6\x08\x08\x07\x92\x74\xc6\x27\ +\x03\x07\xa4\xef\x5d\x16\x01\x81\x83\x65\x03\xf2\x78\xc5\xed\x8e\ +\xbe\xb8\xdd\x31\x2a\x7d\x03\xb3\x08\x08\x1c\x2c\x16\x10\x6e\x77\ +\x74\xc6\x41\x88\x63\xd3\xb7\x31\x8b\x80\xc0\xc1\x12\x01\x39\xfd\ +\xc8\x81\x24\x5d\x1d\xdd\x7c\xe4\x56\xf9\xe8\xf4\xbd\xcc\x22\x20\ +\x70\x30\x6f\x40\x38\x90\xa4\x37\x6e\x77\x54\xa1\x6f\x68\x16\x01\ +\x81\x83\xd9\x02\xc2\x81\x24\xbd\x3d\x9c\x70\x10\x62\x21\xfa\xae\ +\x66\x11\x10\x38\x98\x23\x20\xa7\xc7\x37\xdc\xee\xe8\x89\xdb\x1d\ +\x05\xe9\x7b\x9b\x45\x40\xe0\xa0\x73\x40\x38\x90\xa4\xb3\xa3\x43\ +\x3e\xdd\x51\x93\xbe\xc1\x59\x04\x04\x0e\xba\x05\xe4\xe0\x1b\xb7\ +\x3b\xfa\xe2\x76\x47\x69\xfa\x2e\x67\x11\x10\x38\xe8\x11\x10\xde\ +\xa1\xdb\x1b\x07\x21\xd6\xa7\x6f\x75\x16\x01\x81\x83\xc6\x80\x9c\ +\x72\x20\x49\x5f\x77\x97\x9f\xcf\xe7\xb8\x2f\x05\x37\xfa\x86\x67\ +\x11\x10\x38\xc8\xff\xb0\xe2\x40\x92\xce\x38\x08\x71\x53\xf4\x5d\ +\xcf\x22\x20\x70\x90\x09\x08\x07\x92\xf4\xc6\x41\x88\xdb\xa3\x6f\ +\x7d\x16\x01\x81\x83\x3d\x03\xc2\xed\x8e\xde\xce\x2e\xb8\xdd\xb1\ +\x49\xfa\xfe\x67\x11\x10\x38\xd8\x3d\x20\x1c\x48\xd2\xdb\xe5\xc9\ +\x37\x6e\x77\x6c\x96\x2e\x82\x2c\x02\x02\x07\x3b\xfd\x04\xe3\x76\ +\x47\x67\x7c\x32\x10\xba\x14\xb2\x08\x08\x1c\xbc\x13\x10\x0e\x24\ +\xe9\x8d\xdb\x1d\x78\xa1\xeb\x21\x8b\x80\xc0\x41\x1c\x90\xaf\x1c\ +\x48\xd2\xd9\xd9\xc5\x31\xb7\x3b\x20\xba\x28\xb2\x08\x08\x1c\xbc\ +\x1d\x90\x83\x27\xfe\xde\xd1\xd5\x25\x07\x21\xe2\x35\x5d\x19\x59\ +\x04\x04\x0e\xde\x0a\xc8\x31\x7f\xf3\xe8\x87\xdb\x1d\x78\x93\xae\ +\x8f\x2c\x02\x02\x07\x7f\x07\xe4\x49\x57\x28\x5a\x71\x10\x22\x62\ +\xba\x48\xb2\x08\x08\x1c\xfc\x19\x90\x2b\xde\x6e\xd5\x03\x07\x21\ +\xe2\x1d\xba\x52\xb2\x08\x08\x1c\xfc\x11\x10\x3e\x61\xde\x8c\x83\ +\x10\xb1\x0b\x5d\x2e\x59\x04\x04\x0e\x5e\x05\xe4\x4a\x17\x27\x52\ +\xee\x2e\x4f\x38\x08\x11\x3b\xd2\x45\x93\x45\x40\xe0\xe0\xf7\x1f\ +\x78\xb7\xba\x36\xb1\xb7\x23\x0e\x42\xc4\x7e\x74\xe5\x64\x11\x10\ +\x38\xf8\x2d\x20\x87\xba\x34\xb1\x97\xfb\x9b\x63\x6e\x95\x63\x6f\ +\xba\x7c\xb2\x08\x08\x1c\x4c\x01\xe1\xf6\xc7\xde\xb8\xdd\x81\x34\ +\x5d\x43\x59\x04\x04\x0e\x7e\x05\xe4\x8b\x2e\x4c\xec\x84\x83\x10\ +\xd1\x46\x17\x52\x16\x01\x81\x83\x9f\x3f\x05\x2f\x74\x5d\xe2\x3d\ +\x77\x5f\xb8\xdd\x81\x76\xba\x9c\xb2\x08\x08\x1c\x28\x20\xbc\xff\ +\x6a\x17\x1c\x84\x88\x6e\x74\x4d\x65\x11\x10\x38\x50\x40\x74\x55\ +\x22\xc2\x27\x03\xd1\x97\x2e\xac\x2c\x02\x02\x07\x3f\x02\xc2\xd1\ +\x89\xff\x70\x79\xf2\x8d\x83\x10\xd1\x9b\xae\xae\x2c\x02\x02\x07\ +\x2f\x01\x39\xd6\x45\x89\xd7\x38\x08\x11\xb3\xd1\x35\x96\x45\x40\ +\xe0\xe0\x25\x20\x9c\x7f\xf5\x97\xa3\xc3\x8f\xdc\x2a\xc7\x8c\x74\ +\xa1\x65\x11\x10\x38\xf8\x1e\x90\xcf\xba\x26\xf1\x82\xdb\x1d\x58\ +\x80\xae\xb6\x2c\x02\x02\x07\xdf\x03\xa2\x4b\x12\xdf\x3f\x19\xc8\ +\xed\x0e\x2c\x42\x97\x5c\x16\x01\x81\x83\xe7\x80\x70\x07\xe4\xd9\ +\xf7\x83\x10\xb5\x24\xc0\x02\x74\xe1\x65\x11\x10\x38\x78\x0e\xc8\ +\xbd\x2e\xc9\xad\x3a\x3a\x7c\xe2\xd3\x1d\x58\x9a\xae\xbe\x2c\x02\ +\x02\x07\x07\xff\x7d\xd5\x15\xb9\x45\x67\x37\xdc\xee\xc0\x3a\x74\ +\x09\x66\x1d\x3e\x01\x81\xe3\xe3\xab\xeb\x85\x4e\xe9\x3b\xd8\xea\ +\x2d\x74\x0e\x42\xc4\xaa\x74\x1d\x02\x73\xb9\xbb\xbc\xbd\x9a\xfb\ +\x0f\xc8\x07\xdb\x7b\x05\xeb\x8e\x83\x10\xb1\x3e\x5d\x8d\xc0\xbc\ +\x1e\x4e\xe6\x7c\x85\xfe\x60\x53\x17\xf2\x1d\xcf\x7d\x82\x09\x5d\ +\x92\xc0\xfc\x0e\x67\xbb\x65\x76\x70\xad\xdf\xa2\x3a\x0e\x42\x84\ +\x15\x5d\x97\xc0\x22\x0e\xe7\xf9\xf1\x77\xb0\x81\x5b\x20\x7c\x32\ +\x10\x7e\x74\x71\x02\x0b\x39\x7a\xd2\xa5\xd7\xd3\xc1\x8d\xbe\x7a\ +\x4d\x1c\x84\x08\x53\xba\x42\x81\xe5\xdc\xea\xe2\xeb\xe7\xa0\xea\ +\x93\x6c\x39\x08\x11\xd6\x74\x9d\x02\x4b\xba\xd0\xe5\xd7\xcb\xc1\ +\x91\xbe\x70\x21\xf7\x37\x1c\x84\x08\x77\xba\x58\x81\x65\x9d\xe8\ +\x02\xec\xe3\xa0\xd6\x49\xbc\xdc\xee\xc0\x20\x74\xc5\x02\x0b\x3b\ +\xea\xf9\xd2\xcc\x81\xbe\xe8\xf8\x2e\x4f\x38\x08\x11\xe3\xd0\x65\ +\x0b\x2c\xee\x8b\xae\xc1\x0e\x2a\x04\x84\xdb\x1d\x18\x8f\x2e\x5e\ +\x60\x05\x1f\x75\x15\x36\x1b\x3c\x20\x47\x87\x7c\xba\x03\x43\xd2\ +\x15\x0c\xac\xa1\xd7\x5f\x42\xc6\x0d\x08\xb7\x3b\x30\x32\x5d\xc6\ +\xc0\x2a\x8e\xfa\x1c\x05\x38\x64\x40\x38\x08\x11\xc3\xd3\xb5\x0c\ +\xac\xa4\xcb\xcb\x58\x83\x05\xe4\xfb\x73\x9f\x38\x08\x11\x05\xe8\ +\x8a\x06\xd6\x72\xa8\x4b\xb1\xc5\x38\x01\xe1\x20\x44\x54\xa2\xcb\ +\x1a\x58\xcd\xa5\xae\xc5\x06\x43\x04\xe4\xfe\xe6\x98\x5b\xe5\x28\ +\x65\xdc\x9b\x8f\xa8\xe3\x4c\x57\x63\x9e\xfb\x75\x7c\xc6\xed\x0e\ +\x54\x74\xa2\x0b\x1c\x58\xd1\xbd\x2e\xc7\x34\xe3\x80\xf0\xdc\x27\ +\xd4\x55\xeb\x04\x08\x8c\xea\x4e\xd7\x63\x96\x65\x40\xee\xbe\x7c\ +\xe6\x76\x07\x2a\xfb\xa6\x4b\x1d\x58\x57\xe3\xdf\x41\xdc\x02\xc2\ +\x73\x9f\xb0\x05\x87\xba\xde\x81\x95\xb5\xdd\x07\x31\x0a\x08\x9f\ +\x0c\xc4\x66\xe8\x9a\x07\x56\xd7\xf4\x5e\x2c\x8f\x80\x70\x10\x22\ +\x36\xe5\xab\x2e\x7c\x60\x7d\x2d\x9f\x07\x59\x3b\x20\x1c\x84\x88\ +\x0d\x7a\xd2\xe5\x0f\x18\x68\x78\xd6\xed\x8a\x01\xe1\x20\x44\x6c\ +\x15\xb7\x40\xe0\x24\x7f\xef\x60\x9d\x80\x70\xbb\x03\x9b\x76\xaf\ +\x8d\x00\x38\x38\xd2\x75\xb9\xbf\xc5\x03\xc2\x41\x88\x80\x36\x03\ +\xe0\x21\x7d\xba\xfb\x82\x01\xe1\x20\x44\xe0\x07\x6d\x09\xc0\x44\ +\xf6\x68\xde\x65\x02\x72\xc4\x41\x88\xc0\x44\xfb\x02\x70\xa1\x2b\ +\x73\x5f\xb3\x07\xe4\x8c\x83\x10\x81\xd7\x1e\xb5\x39\x00\x17\xc9\ +\x17\xb1\xe6\x0c\x08\xb7\x3b\x80\xb7\x7c\xd2\x0e\x01\x6c\xe4\x3e\ +\x4e\x31\x4f\x40\xee\x38\x08\x11\x08\x2d\x78\xe7\x11\xd8\x4d\xee\ +\x9d\x58\xdd\x2f\x65\x9e\xfb\x04\xbc\x47\x9b\x05\xf0\x71\xa2\x8b\ +\x73\x2f\x3d\x03\xc2\x41\x88\xc0\x4e\xb4\x63\x00\x23\xba\x38\xf7\ +\xd2\x29\x20\x7c\x32\x10\xd8\x1d\x4f\x03\x81\x9f\xcc\x5f\x41\xda\ +\x03\xf2\x70\xf2\x8d\x83\x10\x81\x7d\x5c\x6a\xf3\x00\x46\x74\x75\ +\xee\xa3\x35\x20\x9f\xf5\x75\x00\xec\xec\x56\xdb\x07\x30\x92\xf8\ +\x69\xde\x1a\x90\x63\x7d\x1d\x00\x3b\xbb\xd2\xf6\x01\x9c\xe8\xf2\ +\xdc\x03\x01\x01\x96\xa7\xed\x03\x38\xd9\xff\xaf\x20\x04\x04\x58\ +\xde\x99\xf6\x0f\x60\x64\xff\xcf\x82\x10\x10\x60\x79\x9f\xb5\x7f\ +\x00\x27\x7b\x7f\x86\x8f\x80\x00\x2b\xd0\xfe\x01\x9c\xec\xfd\x74\ +\x5b\x02\x02\xac\x80\x37\xf2\xc2\x91\x2e\xcf\x9d\x11\x10\x60\x05\ +\xe7\xda\x40\x80\x93\x2b\x5d\x9f\xbb\x22\x20\xc0\x1a\xb4\x81\x00\ +\x27\xfb\xbe\x86\x45\x40\x80\x35\x68\x03\x01\x56\x74\x79\xee\x8a\ +\x80\x00\x6b\xd0\x06\x02\xac\xec\x79\x1e\x2e\x01\x01\xd6\xa0\x0d\ +\x04\x58\xd9\xf3\x44\x45\x02\x02\xac\x41\x1b\x08\xb0\xf2\xa0\xeb\ +\x73\x47\x04\x04\x58\x83\x36\x10\xe0\x45\xd7\xe7\x8e\x08\x08\xb0\ +\x06\x6d\x20\xc0\xcb\x7e\x0f\x76\x22\x20\xc0\x1a\xb4\x81\x00\x2f\ +\xfb\xfd\x48\x27\x20\xc0\x1a\xb4\x81\x00\x2f\x17\xba\x40\x77\x43\ +\x40\x80\x35\x68\x03\x01\x5e\xf6\xbb\x8b\x4e\x40\x80\x35\x68\x03\ +\x01\x66\x74\x81\xee\x86\x80\x00\x6b\xd0\x06\x02\xcc\xe8\x02\xdd\ +\x0d\x01\x01\xd6\xa0\x0d\x04\x98\x79\xd4\x15\xba\x13\x02\x02\xac\ +\x41\x1b\x08\x30\xb3\xd7\xfb\x78\x09\x08\xb0\x06\x6d\x20\xc0\xcc\ +\xb9\xae\xd0\x9d\x10\x10\x60\x0d\xda\x40\x80\x99\xbd\x7e\xa6\x13\ +\x10\x60\x0d\xda\x40\x80\x19\x02\x02\xd8\xd3\x06\x02\xcc\x7c\xd4\ +\x15\xba\x13\x02\x02\xac\x41\x1b\x08\x30\x43\x40\x00\x7b\xda\x40\ +\x59\xdf\xf4\x65\x80\x3f\xdd\xe9\x1a\x49\x22\x20\x80\x3d\x6d\xa0\ +\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ +\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ +\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ +\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ +\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ +\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ +\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ +\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ +\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ +\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ +\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ +\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ +\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ +\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ +\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ +\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ +\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ +\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ +\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ +\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ +\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ +\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ +\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ +\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ +\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ +\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ +\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ +\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ +\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ +\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ +\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ +\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ +\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ +\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ +\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ +\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ +\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ +\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ +\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ +\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ +\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ +\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ +\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ +\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ +\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ +\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ +\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ +\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ +\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ +\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ +\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ +\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ +\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ +\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ +\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ +\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ +\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ +\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ +\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ +\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ +\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ +\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ +\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ +\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ +\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ +\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ +\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ +\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ +\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ +\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ +\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ +\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ +\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ +\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ +\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ +\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ +\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ +\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ +\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ +\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ +\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ +\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ +\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ +\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ +\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ +\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ +\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ +\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ +\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ +\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ +\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ +\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ +\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ +\xaa\xd3\x06\xca\x3a\x39\x5d\x95\x26\x91\xa6\x2f\xb3\x4d\x9f\xb4\ +\x08\x73\x21\x20\x40\x75\xda\x40\x83\xba\xd6\x2c\xb2\xf4\x65\xb6\ +\xe9\x41\x8b\x30\x17\x02\x02\x54\xa7\x0d\x34\x28\x02\xd2\x80\x80\ +\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ +\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ +\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ +\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ +\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ +\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ +\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ +\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ +\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ +\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ +\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ +\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ +\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ +\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ +\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ +\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ +\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ +\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ +\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ +\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ +\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ +\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ +\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ +\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ +\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ +\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ +\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ +\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ +\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ +\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ +\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ +\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ +\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ +\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ +\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ +\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ +\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ +\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ +\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ +\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ +\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ +\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ +\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ +\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ +\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ +\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ +\xa1\x0d\x94\xf5\xf1\x60\x55\x9a\x44\x9a\xbe\xcc\x36\x69\x0d\x66\ +\x43\x40\x80\xea\xb4\x81\xb2\xbe\xe9\xcb\x00\x7f\x22\x20\x40\x75\ +\xda\x40\x59\x04\x04\x11\x02\x02\x54\xa7\x0d\x94\x45\x40\x10\x21\ +\x20\x40\x75\xda\x40\x59\x04\x04\x11\x02\x02\x54\xa7\x0d\x94\x45\ +\x40\x10\x21\x20\x40\x75\xda\x40\x59\x04\x04\x11\x02\x02\x54\xa7\ +\x0d\x94\x45\x40\x10\x21\x20\x40\x75\xda\x40\x59\x04\x04\x11\x02\ +\x02\x54\xa7\x0d\x94\x45\x40\x10\x21\x20\x40\x75\xda\x40\x59\x04\ +\x04\x11\x02\x02\x54\xa7\x0d\x94\x45\x40\x10\x21\x20\x40\x75\xda\ +\x40\x59\x04\x04\x11\x02\x02\x54\xa7\x0d\x94\x45\x40\x10\x21\x20\ +\x40\x75\xda\x40\x59\x04\x04\x11\x02\x02\x54\xa7\x0d\x94\x45\x40\ +\x10\x21\x20\x40\x75\xda\x40\x59\x04\x04\x11\x02\x02\x54\xa7\x0d\ +\x94\x45\x40\x10\x21\x20\x40\x75\xda\x40\x59\x04\x04\x11\x02\x02\ +\x54\xa7\x0d\x94\x45\x40\x10\x21\x20\x40\x75\xda\x40\x59\x04\x04\ +\x11\x02\x02\x54\xa7\x0d\x94\x45\x40\x10\x21\x20\x8d\xbe\x69\x70\ +\xc6\x1e\x35\xd4\x72\x1a\x2f\xde\x59\x5c\x6a\x6c\x56\x34\xb6\x2c\ +\x02\x82\x08\x01\x69\xf5\xa0\xd1\xf9\xba\xd1\x48\xab\x79\xd2\xfc\ +\xac\x68\x6c\x5e\x34\xb6\x2c\x02\x82\x08\x01\x69\xf5\x49\xa3\x33\ +\xa6\x91\x56\xa3\xd9\x59\xf9\xac\xb1\x79\xd1\xe0\xb2\x08\x08\x22\ +\x04\xa4\xd9\x85\x86\xe7\xeb\x42\x23\xad\xe5\x44\xb3\x73\x72\xa4\ +\xb1\x99\xd1\xe8\xb2\x08\x08\x22\x04\xa4\x9d\xe3\x4b\xf1\xaf\x69\ +\xa0\xb5\x68\x6e\x56\xae\x35\x36\x33\x1a\x5d\x16\x01\x41\x84\x80\ +\xb4\x3b\xd6\xf8\x7c\xdd\x6a\xa4\x95\xdc\x68\x6e\x4e\xbe\x68\x6c\ +\x6e\x34\xbc\x2c\x02\x82\x08\x01\xe9\xe0\x4c\x03\xf4\xa5\x81\x16\ +\xf2\xa8\x99\x59\xd1\xd8\xec\x68\x78\x59\x04\x04\x11\x02\xd2\xc1\ +\xa9\x06\xe8\xeb\x44\x23\xad\xe3\x8b\x66\xe6\xc4\xf3\x0e\xfa\x33\ +\x8d\x2f\x8b\x80\x20\x42\x40\x7a\x38\xd4\x08\x7d\x69\xa0\x65\x7c\ +\xd5\xbc\x9c\xdc\x6b\x6c\x7e\x34\xc0\x2c\x02\x82\x08\x01\xe9\x42\ +\x23\xf4\x65\xfb\x87\xe3\x24\xc7\x4f\xdf\x9c\x6a\x6c\x7e\x34\xc0\ +\x2c\x02\x82\x08\x01\xe9\xe2\xb3\x86\xe8\x4b\x03\x2d\xe2\x5c\xb3\ +\x72\x72\xa8\xb1\x19\xd2\x08\xb3\x08\x08\x22\x04\xa4\x8f\x23\x8d\ +\xd1\xd6\x93\x06\x5a\xc3\xbd\x66\xe5\x44\x43\x73\xa4\x11\x66\x11\ +\x10\x44\x08\x48\x1f\x8e\x7f\x24\x7e\xe5\x4e\x03\x2d\xe1\x4a\x93\ +\x72\xe2\x5c\x68\x0d\x31\x8b\x80\x20\x42\x40\x3a\xb9\xd4\x20\x6d\ +\x59\xaf\xde\x9e\x0c\xff\xbe\xe7\x7b\x07\xfd\x99\xc6\x98\x45\x40\ +\x10\x21\x20\x9d\x58\x7e\x2e\xe1\x77\xa6\xa7\x6c\x64\x7c\xd4\x94\ +\x9c\xf8\xde\x41\x7f\xa6\x31\x66\x11\x10\x44\x08\x48\x2f\xb7\x1a\ +\xa5\xad\x2b\x0d\x74\x7c\x9a\x90\x13\xef\x13\x8f\x35\xc8\x2c\x02\ +\x82\x08\x01\xe9\xa6\x71\x29\x67\x67\xfd\x22\xcb\x3e\x1c\xdf\xf2\ +\xa6\xa1\x99\xd2\x20\xb3\x08\x08\x22\x04\xa4\x1b\xfb\x23\xb1\xaa\ +\xfc\x1c\xd0\x74\x9c\xec\xb5\x0f\x96\xa7\x51\x66\x11\x10\x44\x08\ +\x48\x3f\xee\x47\x62\x9d\x69\x9c\x83\x33\x3c\x3e\xdf\x7d\x65\x35\ +\xcc\x2c\x02\x82\x08\x01\xe9\xc7\xf1\x78\x8d\x57\x4c\x0f\x1b\xdf\ +\x4f\xeb\x55\x34\x87\xaf\x1a\x9b\x2b\x0d\x33\x8b\x80\x20\x42\x40\ +\x3a\x72\x3c\x61\xfc\x77\x0f\x1a\xe7\xd0\x0c\xcf\x1d\xb3\x7f\x66\ +\xb0\xc6\x99\x45\x40\x10\x21\x20\x3d\x69\xa0\xb6\xac\xdf\x6b\xba\ +\x1b\xc3\xbf\xe6\xf9\x7f\x46\x53\x03\xcd\x22\x20\x88\x10\x90\x9e\ +\x9e\x34\x52\x57\x05\xfe\x0a\x62\x78\x8a\x62\xf9\x3f\xd8\x10\x10\ +\x44\x08\x48\x57\xee\x47\x62\xb9\xbf\x58\xff\xae\x6b\x4d\xc4\xc8\ +\x00\xef\x4d\xd0\x48\xb3\x08\x08\x22\x04\xa4\x2b\xf7\x23\xb1\x5c\ +\x9f\xb9\xba\x33\xc3\x77\xba\x7d\xd2\xd0\x8c\x69\xa4\x59\x04\x04\ +\x11\x02\xd2\x97\xfb\x91\x58\x8f\x1a\xe7\xa0\xbe\x69\x1a\x46\x2e\ +\x34\x34\x67\x1a\x6a\x16\x01\x41\x84\x80\xf4\xd5\x3a\xc7\xb9\x19\ +\x3f\xb4\x62\x17\x7e\x2f\x11\x0e\x71\xca\xb1\xc6\x9a\x45\x40\x10\ +\x21\x20\x9d\x9d\x68\xb0\xae\x0e\x34\xce\x21\x19\x7e\xd8\x7f\x88\ +\x13\xc6\x34\xd6\x2c\x02\x82\x08\x01\xe9\xad\x71\x45\xe7\x66\xff\ +\x99\x85\x7f\xf1\x5b\xdb\x31\xde\xd7\xa6\xc1\x66\x11\x10\x44\x08\ +\x48\x6f\x8e\x0f\x3b\xfa\x9d\x86\x39\x22\xc3\x53\x14\xc7\xb8\xa7\ +\xa4\xc1\x66\x11\x10\x44\x08\x48\x77\xe6\x47\x62\xdd\x6a\x98\x03\ +\xd2\x0c\x8c\x0c\xb2\x98\x1a\x6d\x16\x01\x41\x84\x80\x74\xf7\x49\ +\xc3\x75\xa5\x61\x8e\xc7\xef\x89\x2b\xa3\x3c\x27\x58\xc3\xcd\x22\ +\x20\x88\x10\x90\xfe\xcc\x8f\xc4\x3a\xd1\x30\x87\xa3\xf1\x1b\x19\ +\xe5\x19\x5d\x1a\x6e\x16\x01\x41\x84\x80\xcc\x40\xe3\x75\xa5\x51\ +\x8e\xc6\xaf\xcb\xc3\x9c\x0c\xa3\xf1\x66\x11\x10\x44\x08\xc8\x0c\ +\x1c\x9f\xd9\xfd\x9b\xcf\x1a\xe6\x58\x0c\x5f\x19\x1c\xe6\x53\x99\ +\x1a\x6f\x16\x01\x41\x84\x80\xcc\xe1\x5e\x23\x36\xa5\x51\x8e\xc5\ +\xef\x33\xfe\xe3\xbc\x16\xa8\x01\x67\x11\x10\x44\x08\xc8\x1c\x0c\ +\x8f\xfc\xfb\xdd\x5e\xdf\x35\x13\xa7\x1a\xbb\x8f\x23\x8d\x6c\x00\ +\x1a\x71\x16\x01\x41\x84\x80\xcc\xe2\x8b\x86\xec\x69\x94\x37\x0f\ +\xfd\xce\xef\xcd\xd1\x03\xfd\x58\xd5\x88\xb3\x08\x08\x22\x04\x64\ +\x1e\x1a\xb2\xa9\x91\x56\xf2\x07\xbf\x63\x8e\x2f\x35\xb2\x11\x68\ +\xc8\x59\x04\x04\x11\x02\x32\x0f\xc3\x0f\x4d\xff\x66\xa0\x57\x5f\ +\xc4\xef\xae\xd2\x48\x87\x8a\x69\xc8\x59\x04\x04\x11\x02\x32\x13\ +\xef\x47\x4b\x8d\xf6\x57\x10\xbf\x53\x14\x87\x7a\x2b\x9b\xc6\x9c\ +\x45\x40\x10\x21\x20\x33\x31\x7c\x72\xc5\x6f\xee\x35\xca\x51\x34\ +\x5e\xa6\xfd\x8d\xf5\x77\x38\x0d\x3a\x8b\x80\x20\x42\x40\xe6\x62\ +\xf8\xf0\xee\xdf\x8c\xf5\x33\xc1\xef\x59\xf3\xe7\x1a\xd9\x18\x34\ +\xe8\x2c\x02\x82\x08\x01\x99\x8b\xf7\x91\x58\x63\xfd\x15\x44\x83\ +\xf6\x31\xd8\xa3\x81\x35\xea\x2c\x02\x82\x08\x01\x99\xcd\x85\x86\ +\xed\x69\xa4\x3f\x42\xfb\x3d\xa4\x4b\x03\x1b\x85\x46\x9d\x45\x40\ +\x10\x21\x20\xf3\xb1\x7b\xe1\xfe\x77\x67\x1a\xe4\x08\x34\x64\x1f\ +\xa3\x1d\x06\xa3\x61\x67\x11\x10\x44\x08\xc8\x7c\x0c\x1f\xc0\xfa\ +\x9b\x6b\x8d\xd2\x9f\xdd\x29\x8a\xc3\xbd\x0b\x5a\xe3\xce\x22\x20\ +\x88\x10\x90\x19\x59\x3f\x5a\x6a\x98\xa3\x64\x1f\x35\x60\x1f\xe3\ +\xb4\x57\x34\xee\x2c\x02\x82\x08\x01\x99\x91\xdf\xf9\x4d\xbf\xfb\ +\xaa\x51\xba\xb3\x3b\x16\x66\xb0\x3b\xe8\xcf\x34\xf0\x2c\x02\x82\ +\x08\x01\x99\xd3\xa1\x46\x6e\x69\x90\xb3\x38\xbe\x6a\xb8\x3e\x34\ +\xb0\x81\x68\xe0\x59\x04\x04\x11\x02\x32\x2b\x8d\xdc\xd3\x27\x0d\ +\xd2\x9b\xdd\xe7\x69\x9e\x34\xb0\x81\x68\xe4\x59\x04\x04\x11\x02\ +\x32\x2b\xeb\x23\xb1\x0e\x35\x48\x6b\x76\xa7\x28\x8e\xf6\x21\xfe\ +\xef\x34\xf4\x2c\x02\x82\x08\x01\x99\x97\xf5\x91\x58\x23\x3c\x51\ +\xcf\xee\x14\xc5\x53\x0d\x6c\x24\x1a\x7a\x16\x01\x41\x84\x80\xcc\ +\xcb\xef\x18\xf2\xdf\xdc\x68\x90\xc6\xec\xde\x0a\x3d\xc4\x5f\xdb\ +\xfe\xa4\xb1\x67\x11\x10\x44\x08\xc8\xcc\xfc\x9e\xc4\xfa\x1b\x8d\ +\xd1\x98\xdd\xdf\xe0\x34\xae\xb1\x68\xec\x59\x04\x04\x11\x02\x32\ +\x33\xbf\x4f\x31\xfc\xe6\x42\x83\xb4\xf5\x51\x03\xb5\xb1\xd7\x05\ +\x6f\x43\x83\xcf\x22\x20\x88\x10\x90\xb9\xdd\x6a\xf4\x96\x34\x46\ +\x5b\x8d\x97\x67\x77\x23\xde\x41\x7f\xa6\xd1\x67\x11\x10\x44\x08\ +\xc8\xec\xdc\x7e\x08\xfe\xee\x56\x63\x34\x65\xf7\x26\xb6\x11\xef\ +\xa0\x3f\xd3\xe8\xb3\x08\x08\x22\x04\x64\x76\xd6\x47\x62\x69\x8c\ +\xa6\x34\x48\x1b\x03\xbc\xeb\xe0\x4d\x1a\x7e\x16\x01\x41\x84\x80\ +\xcc\xcf\xf9\x48\xac\x13\x8d\xd1\x92\xdd\x81\xf8\x1a\xd7\x70\x34\ +\xfc\x2c\x02\x82\x08\x01\x99\x9f\xdf\x61\x1c\xbf\xd1\x18\x1d\xb5\ +\x5e\x2f\xdd\x8d\x7a\x01\x12\x10\xcc\x85\x80\x2c\xc0\xee\x3c\xf2\ +\xdf\x18\x1f\xcc\xe1\x76\x8a\xe2\x48\x8f\x50\x79\x4d\x13\xc8\x22\ +\x20\x88\x10\x90\x25\x68\x02\x8e\xee\x34\x44\x3f\x76\xcf\x04\x1e\ +\xe5\xf8\xe2\xbf\x69\x02\x59\x04\x04\x11\x02\xb2\x84\x27\xcd\xc0\ +\xd1\x5e\xdf\xc2\x25\xb9\x9d\xa2\x38\xea\x1d\xf4\x67\x9a\x41\x16\ +\x01\x41\x84\x80\x2c\xc2\xf8\x48\x2c\xd7\xbf\x82\x5c\x6b\x7c\x36\ +\x34\xae\x11\x69\x06\x59\x04\x04\x11\x02\xb2\x08\xe7\x23\xb1\x4c\ +\x97\xd5\xed\xbd\x6b\x03\x5f\x7d\x04\x04\x73\x21\x20\xcb\x30\x3e\ +\x12\xcb\xf3\x09\xdf\x57\x1a\x9d\x8b\x71\xef\xa0\x3f\xd3\x1c\xb2\ +\x08\x08\x22\x04\x64\x19\xad\x73\x9f\xd3\x95\xc6\x68\xc5\xed\x45\ +\xbf\x31\x9e\xbe\x15\xd0\x1c\xb2\x08\x08\x22\x04\x64\x21\x27\x9a\ +\x84\x21\xc7\x03\x9e\xdc\x3e\xbe\x6f\x7f\xec\xe4\x3f\x69\x12\x59\ +\x04\x04\x11\x02\xb2\x94\xc6\x95\x9e\xd3\xb9\x86\x68\xc4\x6c\xb5\ +\x7c\xdf\xec\xbc\x13\xcd\x22\x8b\x80\x20\x42\x40\x96\xe2\xf6\xa2\ +\xfe\x6f\xfc\x5e\xdf\x77\x3b\x45\x71\xec\x4b\x8f\x80\x60\x2e\x04\ +\x64\x31\xc6\x47\x62\x5d\x6b\x88\x36\x34\x2e\x17\x0f\x1a\xd6\xa8\ +\x34\x8d\x2c\x02\x82\x08\x01\x59\x8c\xdd\x27\xab\x27\x6e\x3f\x20\ +\xdd\x4e\x51\x1c\xe1\xe1\xf1\xff\xa2\x69\x64\x11\x10\x44\x08\xc8\ +\x72\x8c\x8f\xc4\x32\x7b\xce\x85\x46\xe5\xc2\xfc\xa9\x29\xef\xd3\ +\x3c\xb2\x08\x08\x22\x04\x64\x41\x9a\x87\xa1\x4b\x8d\xd0\xc3\xa1\ +\x46\x65\x62\xf0\x3b\xe8\xcf\x34\x91\x2c\x02\x82\x08\x01\x59\x90\ +\xdd\x13\xbe\x27\x4e\x1f\x73\x70\x7b\xad\xcf\xf2\x73\x32\x7b\xd1\ +\x44\xb2\x08\x08\x22\x04\x64\x49\xf7\x9a\x89\x9f\x2f\x1a\xa1\x03\ +\xb3\x4f\xed\x8f\x7e\x07\xfd\x99\x66\x92\x45\x40\x10\x21\x20\x4b\ +\xb2\x3b\x20\x70\xe2\x73\x9f\xd8\x6d\x91\x46\xbf\x83\xfe\x4c\x33\ +\xc9\x22\x20\x88\x10\x90\x45\xb9\x3d\x23\x69\xe2\x73\x58\xb9\xd9\ +\xdb\x9d\xad\x1f\xfa\xbb\x23\x4d\x25\x8b\x80\x20\x42\x40\x96\xa5\ +\xa9\x18\xd2\x00\x57\xf7\x4d\xe3\x31\xe1\x79\xd4\xe4\x9e\x34\x97\ +\x2c\x02\x82\x08\x01\x59\x96\xdb\x47\xac\x27\x2e\xa7\x3d\x99\x9d\ +\xa2\x58\xe2\x87\xa7\xe6\x92\x45\x40\x10\x21\x20\x0b\xf3\x7d\xb4\ +\x94\x06\xb8\x32\xb3\x53\x14\xbd\xde\xdf\x9c\xa5\xc9\x64\x11\x10\ +\x44\x08\xc8\xc2\x7c\x8f\xc4\xf2\xf8\xb8\x5c\xe3\x05\xd9\xdb\x81\ +\x86\x35\x36\x4d\x26\x8b\x80\x20\x42\x40\x96\xe6\xf6\xa8\xef\x89\ +\x06\xb8\x2a\xb3\xa7\xc7\x7f\xd6\xb0\x06\xa7\xd9\x64\x11\x10\x44\ +\x08\xc8\xd2\x7c\x8f\xc4\x72\xf8\x69\xa9\xa1\x98\x28\x71\x07\xfd\ +\x99\xa6\x93\x45\x40\x10\x21\x20\x8b\x73\x3b\x29\x70\xa2\x01\xae\ +\xe8\x56\x23\x31\x61\xf8\xa0\x94\x14\x4d\x27\x8b\x80\x20\x42\x40\ +\x96\x67\xf6\x32\xff\x64\xfd\xbf\x82\x68\x20\x26\x9c\x3e\x9e\xdf\ +\x44\xf3\xc9\x22\x20\x88\x10\x90\xe5\xb9\x3d\xae\xf5\x97\xd5\x4f\ +\x0d\x34\x3b\xaf\x58\xa3\x1a\x9f\xe6\x93\x45\x40\x10\x21\x20\x2b\ +\xb0\x7d\xb4\xd4\x5e\xdf\xce\xfe\x1e\x35\x0c\x13\x45\xee\xa0\x3f\ +\xd3\x84\xb2\x08\x08\x22\x04\x64\x05\xa7\x9a\x90\x9d\x95\xff\x0a\ +\xe2\x75\xd0\xcb\xbd\x46\x55\x80\x66\x94\x45\x40\x10\x21\x20\x6b\ +\x30\x7b\xe0\xc5\x64\xd5\x25\x36\xeb\xaa\xdd\x73\x7e\xf3\x34\xa3\ +\x2c\x02\x82\x08\x01\x59\x85\x66\x64\x67\xd5\xf7\xad\x7a\x7d\x42\ +\xe6\x50\xa3\xaa\x40\x53\xca\x22\x20\x88\x10\x90\x55\xd8\x1e\x89\ +\xb5\xe2\xc3\x93\xce\x35\x04\x13\x1a\x55\x09\x9a\x52\x16\x01\x41\ +\x84\x80\xac\xc3\xf5\x48\xac\x15\x5f\xf8\xf7\x7a\xda\xd6\x93\x46\ +\x55\x82\xe6\x94\x45\x40\x10\x21\x20\xeb\x30\xfb\xe3\xf6\x64\xb5\ +\xcf\xce\x79\xbd\xb9\xb9\xd0\x1d\xf4\x67\x9a\x54\x16\x01\x41\x84\ +\x80\xac\xc4\xec\xb9\xad\xbf\x9c\x69\x7c\x8b\x6b\xbc\x12\x3b\x2b\ +\x74\x07\xfd\x99\x26\x95\x45\x40\x10\x21\x20\x2b\x31\xfb\xcc\xc3\ +\x64\xa5\x1f\x9d\x5e\xa7\x28\x56\xba\x83\xfe\x4c\xb3\xca\x22\x20\ +\x88\x10\x90\xb5\x98\x1d\xfb\xf4\xcb\x83\xc6\xb7\x30\xaf\xbf\x80\ +\x68\x50\x55\x68\x56\x59\x04\x04\x11\x02\xb2\x1a\xaf\x1f\x99\x93\ +\x53\x8d\x6f\x51\x27\xfa\xcd\x3d\xec\x75\x59\x0f\x40\xd3\xca\x22\ +\x20\x88\x10\x90\xd5\xb8\x1e\x89\xb5\xca\x43\xf8\xf4\x7b\x7b\x58\ +\xed\x3e\xd0\x5c\x34\xaf\x2c\x02\x82\x08\x01\x59\x8f\xeb\x91\x58\ +\x5f\x35\xbe\x05\x79\x1d\x71\xbf\xca\xdf\xc1\xe6\xa4\x79\x65\x11\ +\x10\x44\x08\xc8\x7a\xbe\x6a\x5e\x6e\x96\x3f\xc5\xdc\xeb\x1d\x05\ +\xc5\xee\xa0\x3f\xd3\xc4\xb2\x08\x08\x22\x04\x64\x45\xae\x47\x62\ +\x3d\x6a\x7c\x8b\xf1\x3a\x45\x51\x83\x2a\x44\x13\xcb\x22\x20\x88\ +\x10\x90\x35\x69\x62\x6e\x96\xfe\x23\xb8\xd7\x5f\xc5\xea\x5d\x66\ +\x04\x04\x73\x21\x20\x6b\xf2\xfa\xf0\xc3\xe4\x40\xe3\x5b\x88\xd5\ +\x29\x8a\xe5\xee\xa0\x3f\xd3\xd4\xb2\x08\x08\x22\x04\x64\x55\xa6\ +\x47\x62\xdd\x68\x78\xcb\xb8\xd6\xef\xea\x61\x85\xb7\x10\xcc\x4e\ +\x53\xcb\x22\x20\x88\x10\x90\x55\xb9\x1e\x89\xa5\xe1\x2d\xc3\xea\ +\xdd\x68\xcb\xb6\x73\x21\x9a\x5b\x16\x01\x41\x84\x80\xac\xcb\xf4\ +\x48\xac\x0b\x0d\x6f\x09\x57\xfa\x3d\x2d\xac\xfe\x58\xf8\x59\x68\ +\x72\x59\x04\x04\x11\x02\xb2\xae\xd6\x35\x99\x8b\x86\xb7\x04\xab\ +\x97\xf1\x2a\x5e\x63\x04\x04\xb3\x21\x20\x2b\x33\x3d\x12\xeb\x44\ +\xc3\x9b\xdf\x47\xfd\x8e\x16\x2a\xde\x41\x7f\xa6\xd9\x65\x11\x10\ +\x44\x08\xc8\xda\x1a\xbf\x03\x73\xd1\xe8\xe6\x67\x35\xff\x4f\x1a\ +\x54\x31\x9a\x5d\x16\x01\x41\x84\x80\xac\xcd\xea\x16\xc0\xe4\xb3\ +\x86\x37\x37\xab\x87\xfb\x2e\x79\xeb\x67\x49\x9a\x5e\x16\x01\x41\ +\x84\x80\xac\xce\xf3\x48\xac\xa5\xee\x26\xeb\xb7\xb3\x50\xf3\x0e\ +\xfa\x33\xcd\x2f\x8b\x80\x20\x42\x40\x56\xf7\x49\xd3\x33\xb3\xcc\ +\x43\xc1\xad\x6e\x01\x5d\x69\x50\xe5\x68\x7e\x59\x04\x04\x11\x02\ +\xb2\xbe\x1b\xcd\xcf\xcb\x32\x7f\x1c\xd7\x6f\x66\x61\xa5\x47\x69\ +\x2d\x40\x13\xcc\x22\x20\x88\x10\x10\x03\x9a\x9f\x99\x25\x96\xdb\ +\xea\x38\xc9\xc5\xcf\x90\x5c\x8c\x26\x98\x45\x40\x10\x21\x20\x06\ +\xac\xde\xc9\xfa\xcb\x91\x46\x37\x23\xab\x57\xef\x6e\x35\xa8\x82\ +\x34\xc3\x2c\x02\x82\x08\x01\x71\x70\xaf\x19\x7a\x99\xff\x96\x80\ +\xd3\xe7\xf0\xcb\xde\x41\x7f\xa6\x29\x66\x11\x10\x44\x08\x88\x03\ +\xaf\xe3\x04\x7f\x9a\xfd\xaf\x20\x56\xd3\x2e\x7b\x07\xfd\x99\xa6\ +\x98\x45\x40\x10\x21\x20\x16\xbc\x9e\xa8\xf4\xd3\xdc\x3f\x38\x9c\ +\xde\xc0\xbc\xca\x93\xe0\x97\xa2\x39\x66\x11\x10\x44\x08\x88\x07\ +\x4d\xd1\xcb\xcc\x07\x7b\x7c\xd3\x6f\x63\xa1\xee\x1d\xf4\x67\x9a\ +\x63\x16\x01\x41\x84\x80\x78\xb0\xfa\x40\xf6\x2f\xe7\x1a\xdd\x3c\ +\x9c\xee\xfc\x2c\x77\xf6\xd7\x1a\x34\xc9\x2c\x02\x82\x08\x01\x31\ +\xd1\xf8\x8d\x98\xc7\xac\x7f\x05\x39\xd6\x6f\xe2\x60\x81\x77\x9c\ +\xad\x49\xb3\xcc\x22\x20\x88\x10\x10\x13\x9e\x47\x62\x9d\x6a\x74\ +\x73\x70\x4a\xe6\xbc\x7f\xd5\x5a\x9d\x66\x99\x45\x40\x10\x21\x20\ +\x2e\xac\x1e\x0c\xfe\xd3\x8c\xb7\x96\x9d\x5e\xb4\x2b\x7d\x07\xfd\ +\x99\xa6\x99\x45\x40\x10\x21\x20\x2e\x3c\x8f\xc4\x9a\xef\x09\xe1\ +\xfa\x0d\x2c\x68\x48\x65\x69\x9a\x59\x04\x04\x11\x02\x62\xe3\x42\ +\xd3\xb4\xf2\x45\x83\xeb\xce\xe9\x14\xc5\xda\x77\xd0\x9f\x69\x9e\ +\x59\x04\x04\x11\x02\xe2\xc3\xe9\xa6\xc0\x2f\x73\x3d\x62\x49\x5f\ +\xde\x41\xf1\x3b\xe8\xcf\x34\xd1\x2c\x02\x82\x08\x01\xf1\xe1\xf4\ +\xb6\xa4\x5f\x0e\x35\xb8\xce\x9c\x4e\x20\x2e\x7e\x07\xfd\x99\x26\ +\x9a\x45\x40\x10\x21\x20\x46\x2c\x8f\xc4\x3a\xd0\xe0\xba\x7a\xd4\ +\x17\x77\x30\xdb\xab\x74\x3e\x34\xd3\x2c\x02\x82\x08\x01\x31\x72\ +\xaa\x89\x5a\xb9\xd1\xe0\xba\x72\x3a\x45\x51\x43\xaa\x4c\x33\xcd\ +\x22\x20\x88\x10\x10\x27\x56\x8f\xc7\xf8\x49\x63\xeb\xc9\xa9\x94\ +\x4b\x3d\xfc\x7d\x4d\x9a\x6a\x16\x01\x41\x84\x80\x58\xd1\x4c\xad\ +\x5c\x68\x6c\x1d\x19\x9d\xa2\x58\xff\x0e\xfa\x33\xcd\x35\x8b\x80\ +\x20\x42\x40\xac\x58\x1e\x89\xa5\xb1\xf5\x73\xae\x2f\xec\xe0\x5a\ +\x63\x2a\x4d\x73\xcd\x22\x20\x88\x10\x10\x2f\x47\x9a\xab\x93\xee\ +\x1f\x93\x30\x7a\xb3\xc0\x4c\x6f\x32\x33\xa3\xc9\x66\x11\x10\x44\ +\x08\x88\x17\xab\x23\xce\x7f\xd2\xd8\x7a\x71\x7a\xbb\xb2\x86\x54\ +\x9c\x26\x9b\x45\x40\x10\x21\x20\x66\x1c\x8f\xc4\xea\x7c\x9f\xb9\ +\xf1\x9a\xeb\xe9\x49\x43\x2a\x4e\xb3\xcd\xaa\xfc\xb0\x46\xb4\x21\ +\x20\x66\x9c\x3e\x21\xf1\x8b\xc6\xd6\xc7\x47\x7d\x51\x03\xf7\x1a\ +\x52\x75\x9a\xee\xa0\x5a\x6f\x53\xe9\xcb\x6c\xd3\x83\x16\x61\x2e\ +\x04\xc4\x8d\xd3\x21\x51\x3f\x75\xfd\x83\xba\xd1\x5f\x40\xe6\x3c\ +\xad\xde\x89\xa6\x3b\x28\x02\xd2\x80\x80\x4c\xb6\x11\x10\xa7\x1f\ +\xb0\x3f\xdd\x69\x68\x3d\x9c\xe8\x6b\x1a\xd8\xc6\x1d\xf4\x67\x9a\ +\xef\xa0\x08\x48\x03\x02\x32\xd9\x48\x40\x1c\x8f\xc4\xda\xeb\xfb\ +\xfc\x6f\xfa\x8a\x0e\x34\xa2\xfa\x34\xdf\x41\x11\x90\x06\x04\x64\ +\xb2\x91\x80\x38\x7d\xcc\xee\xa7\x7e\x1f\xb7\x33\x3a\x45\xb1\x63\ +\x15\xcd\x69\xc2\x83\x22\x20\x0d\x08\xc8\x64\x2b\x01\x71\x3c\x12\ +\xab\xd7\xda\xb7\x5e\x03\x1d\xcd\xfa\xc0\x77\x2f\x9a\xf1\xa0\x08\ +\x48\x03\x02\x32\xd9\x4a\x40\x1c\x8f\xc4\xea\xf5\x7e\xa5\x2f\xfa\ +\x7a\x06\xb6\x72\x07\xfd\x99\x66\x3c\x28\x02\xd2\x80\x80\x4c\x36\ +\x13\x10\xc7\x4b\xbe\xcf\x87\xc9\xbe\xea\xab\x19\x98\xe5\x94\x61\ +\x53\x9a\xf2\xa0\x08\x48\x03\x02\x32\xd9\x4e\x40\x9e\x34\x63\x23\ +\x7d\xfe\x0a\x62\xf4\x31\x49\x8d\x68\x13\x34\xe5\x41\x11\x90\x06\ +\x04\x64\xb2\x9d\x80\x38\x1e\x89\xd5\xe3\xb9\x7d\xd7\xfa\x5a\x06\ +\xf6\xba\x72\x47\xa7\x39\x0f\x8a\x80\x34\x20\x20\x93\x0d\x05\xc4\ +\xe9\xbc\x5a\xe9\x71\xcf\xd9\xe7\xfd\x65\x1b\xba\x83\xfe\x4c\x93\ +\x1e\x14\x01\x69\x40\x40\x26\x1b\x0a\x88\xd5\x23\xfb\xa4\xfd\xa6\ +\xf3\x95\xbe\x92\x81\xaf\x1a\xd2\x36\x68\xd2\x83\x22\x20\x0d\x08\ +\xc8\x64\x4b\x01\x31\x3c\x12\xab\xfd\x52\xf4\x79\x61\x6e\x86\x87\ +\x64\x39\xd3\xac\x07\x45\x40\x1a\x10\x90\xc9\x96\x02\xe2\x78\x24\ +\x56\xeb\x9f\xda\x7d\x4e\x51\xec\x79\x34\xcb\x08\x34\xed\x41\x11\ +\x90\x06\x04\x64\xb2\xa9\x80\xb4\x7e\x67\x66\x70\xa9\x91\x65\xf9\ +\xcc\x68\x5b\x57\x12\x01\xd9\x30\x02\x32\xd9\xd6\xb6\x37\xba\x61\ +\xf0\xd3\x27\x0d\x2d\xc7\xe7\x14\xc5\x6d\xdd\x41\x7f\xa6\x79\x0f\ +\x8a\x80\x34\x20\x20\x93\x8d\xfd\xb9\xd1\xef\x48\xac\x2f\x1a\x59\ +\x8e\xbe\x88\x81\xb6\x10\x0e\x48\xf3\x1e\x14\x01\x69\x40\x40\x26\ +\x1b\x0b\xc8\x27\x4d\xdb\xc8\xa3\x86\x96\x71\xa1\xaf\xb1\xbe\x5b\ +\x8d\x68\x3b\x34\xf1\x41\x11\x90\x06\x04\x64\xb2\xb5\x57\xae\x8d\ +\x0e\xae\x95\x96\x07\x68\xe8\x4b\xac\x6f\x6b\x77\xd0\x9f\x69\xe6\ +\x83\x22\x20\x0d\x08\xc8\x64\x6b\x01\x31\xbc\xf2\x35\xb0\x04\x9f\ +\x03\x22\x37\xf8\x84\x6f\xcd\x7c\x50\x04\xa4\x01\x01\x99\x6c\x2e\ +\x20\x46\x4f\x0f\x97\xf4\xe7\x27\x7c\x5e\x8f\x9b\x7b\x47\x39\xd2\ +\xd4\x07\x45\x40\x1a\x10\x90\xc9\xe6\x02\xf2\xdf\xbd\x66\xee\x43\ +\x03\xdb\x9b\xcf\x27\xeb\x5b\xee\xe3\x8c\x4a\x53\x1f\x14\x01\x69\ +\x40\x40\x26\xdb\x0b\x88\xd1\xe1\x83\x92\xbc\x01\xed\xf3\x8c\xac\ +\xed\xdd\x41\x7f\xa6\xb9\x0f\x8a\x80\x34\x20\x20\x93\xed\x05\xc4\ +\xe9\xf9\x4b\xa2\x81\xed\xc9\xe6\x2d\xc9\x1b\xbc\x83\xfe\x4c\x93\ +\x1f\x14\x01\x69\x40\x40\x26\x1b\x0c\x88\xdf\xc5\x7f\xa2\x81\xed\ +\xe5\x9b\xfe\xe3\xf5\xf5\x79\x2e\xd6\x68\x34\xf9\x41\x11\x90\x06\ +\x04\x64\xb2\xc5\x80\xf8\x7c\x7c\xfb\x27\x0d\x6c\x2f\x36\xa7\x28\ +\xce\xbd\x9d\x4c\x69\xf6\x83\x22\x20\x0d\x08\xc8\x64\x8b\x01\x69\ +\xfd\x06\xf5\xf7\x59\x03\xdb\x83\xcf\xbb\xc9\x0e\x34\xa2\x8d\xd1\ +\xec\x07\x45\x40\x1a\x10\x90\xc9\x26\x03\x62\x77\x24\x56\xe2\x2e\ +\x82\x4d\x04\x53\xaf\xbf\x15\xa0\xe9\x0f\x8a\x80\x34\x20\x20\x93\ +\x4d\x06\xc4\xe9\x31\xe2\x3f\xec\xf5\x3d\xff\xee\xb3\xfe\xc3\xd5\ +\x1d\x69\x40\x9b\xa3\xf9\x0f\x8a\x80\x34\x20\x20\x93\x6d\x06\xc4\ +\xee\x48\xac\xbd\xff\x0a\xa2\xff\x6e\x7d\x3d\x1e\xeb\x3e\x24\xcd\ +\x7f\x50\x04\xa4\x01\x01\x99\x6c\x33\x20\x46\xa7\x10\xca\x9e\xdf\ +\x07\x9b\x47\x63\xb5\x3e\xcf\x64\x5c\x5a\x80\x41\x11\x90\x06\x04\ +\x64\xb2\xd1\x80\xd8\x6d\x80\x3d\x5f\x09\xd2\x7f\xb5\x3e\x8d\x67\ +\x83\xb4\x00\x83\x22\x20\x0d\x08\xc8\x64\xab\x01\xb1\x3b\x12\x6b\ +\xaf\xe3\x08\x6d\xce\x14\xde\xea\x1d\xf4\x67\x5a\x81\x41\x11\x90\ +\x06\x04\x64\xb2\xd5\x80\xd8\x1d\x89\x75\xaf\x71\xed\xe2\x51\xff\ +\xcd\xea\x36\x7b\x07\xfd\x99\x96\x60\x50\x04\xa4\x01\x01\x99\x6c\ +\x36\x20\x3e\x27\x49\xc9\x1e\x9f\xe7\xb6\x39\x45\x71\xb3\x77\xd0\ +\x9f\x69\x09\x06\x45\x40\x1a\x10\x90\xc9\x66\x03\x62\xf4\x30\x8d\ +\x1f\x76\x7f\xa8\xb8\x4d\xfb\xda\x1e\xc7\x3b\x38\xad\xc1\xa0\x08\ +\x48\x03\x02\x32\xd9\x6e\x40\xec\xf6\xc0\xce\x7b\xda\xe6\x14\x45\ +\x8d\x67\x9b\xb4\x06\x83\x22\x20\x0d\x08\xc8\x64\xc3\x01\xb1\xf9\ +\x2c\x9e\xec\x7a\x59\xda\x9c\xa2\x98\x38\x80\xa5\x10\x2d\xc2\xa0\ +\x08\x48\x03\x02\x32\xd9\x70\x40\x7c\x8e\x23\x94\x53\x8d\xeb\x1d\ +\x2e\xb7\xff\xf7\xb9\xed\x5f\x90\x56\x61\x50\x04\xa4\x01\x01\x99\ +\x6c\x39\x20\x3e\x07\xa2\xff\xb0\xdb\x87\xf2\x6c\x1e\x88\xd5\xfa\ +\x33\x68\x70\x5a\x85\x41\x11\x90\x06\x04\x64\xb2\xe5\x80\xd8\x1d\ +\x89\xf5\x55\xe3\xfa\x27\x97\x9b\xff\x9b\xbe\x83\xfe\x4c\xcb\x30\ +\x28\x02\xd2\x80\x80\x4c\x36\x1d\x10\x9b\xcf\x53\xc8\xa1\xc6\xf5\ +\x4f\xfa\xb5\xab\xd3\x70\x36\x4b\xcb\x30\x28\x02\xd2\x80\x80\x4c\ +\x36\x1d\x10\x9f\x23\xa5\x44\xc3\xfa\x97\x63\xfd\xd2\xb5\xed\x75\ +\x95\x56\xa4\x75\x18\x14\x01\x69\x40\x40\x26\xdb\x0e\x48\xeb\xb7\ +\xaa\xb7\x5b\x0d\xeb\x1f\x4c\xde\xc3\xbb\xf1\x3b\xe8\xcf\xb4\x10\ +\x83\x22\x20\x0d\x08\xc8\x64\xe3\x01\x71\xf9\xf3\xfc\x4f\x1a\x56\ +\xcc\xe5\x20\xfa\x1d\xdf\x31\x56\x98\x16\x62\x50\x04\xa4\x01\x01\ +\x99\x6c\x3c\x20\x3e\x1f\xca\xfb\xe1\xdd\x8f\x56\x98\x9c\x43\xbf\ +\xd3\xdd\x9a\xda\xb4\x12\x83\x22\x20\x0d\x08\xc8\x64\xeb\x01\x31\ +\x3b\x12\xeb\xdd\x07\x4b\xe9\xd7\xad\x4d\xa3\xd9\x32\xad\xc4\xa0\ +\x08\x48\x03\x02\x32\xd9\x7a\x40\xdc\x8e\xc4\x7a\xe7\x54\x77\x93\ +\xa7\xb9\xef\x75\x89\x16\xa5\xa5\x18\x14\x01\x69\x40\x40\x26\x9b\ +\x0f\x88\xd9\x56\x78\xe7\x48\x45\x8f\x4f\xae\xec\x7e\xee\x63\x61\ +\x5a\x8b\x41\x11\x90\x06\x04\x64\x42\x40\x9e\xb4\x12\x26\x3e\x69\ +\x58\x6f\x6a\xfd\x6e\x77\xb2\xd3\x07\x1e\xab\xd3\x5a\x0c\x8a\x80\ +\x34\x20\x20\x13\x02\x62\x76\x24\xd6\x8d\x46\xf5\x26\x8f\xf3\x1f\ +\xff\x39\xc4\xcd\xd0\x62\x0c\x8a\x80\x34\x20\x20\x13\x02\xf2\xdf\ +\xb9\x96\xc2\x84\x46\xf5\xa6\xc6\x2b\xab\x8f\x77\x6f\xf4\x6f\x83\ +\x56\x63\x50\x04\xa4\x01\x01\x99\x10\x10\xa3\x07\xfc\xbd\xf8\xc7\ +\xb7\xdf\xe3\x1c\xc5\xbd\xae\xcf\xba\xb4\x1a\x83\x22\x20\x0d\x08\ +\xc8\x84\x80\xb8\x1d\x89\xf5\x8f\xcf\x78\x7f\xd1\x2f\x59\x15\x77\ +\xd0\x7f\xd0\x72\x0c\x8a\x80\x34\x20\x20\x13\x02\xf2\xcc\xeb\x48\ +\xac\xf8\x16\xb5\x7e\xc1\xba\xfe\x79\x97\x7f\x43\xb4\x1c\x83\x22\ +\x20\x0d\x08\xc8\x84\x80\x7c\x67\x71\x6f\xe1\xa7\xf0\x1e\xf5\x47\ +\xfd\x82\x55\x5d\x68\x30\x9b\xa7\xf5\x18\x14\x01\x69\x40\x40\x26\ +\x04\xe4\x3b\x93\xcf\xe7\x89\x06\xf5\x17\x87\x47\x11\x72\x07\xfd\ +\x27\x2d\xc8\xa0\x08\x48\x03\x02\x32\x21\x20\x2f\xac\x8e\xc4\x0a\ +\xbe\x27\x16\xe7\x28\x72\xbd\xfc\xa4\x05\x19\x14\x01\x69\x40\x40\ +\x26\xfc\x40\x78\xf1\x55\xcb\x61\x21\xb8\x4d\x7d\xa2\x7f\xbd\x26\ +\xee\xa0\xff\xa2\x15\x19\x14\x01\x69\x40\x40\x26\x04\xe4\x87\x1b\ +\xad\x87\x85\x03\x0d\xea\x35\x87\x1b\x35\xdc\x41\xff\x45\x2b\x32\ +\x28\x02\xd2\x80\x80\x4c\x08\x88\x68\x3d\x2c\xbc\x79\xa8\xbb\xc3\ +\x87\x40\x76\x78\xe0\xd5\x66\x68\x49\x06\x45\x40\x1a\x10\x90\x09\ +\x01\x11\x8b\xb7\x38\xc9\x91\xc6\xf4\x8a\xc1\xb1\xc1\xdc\x41\xff\ +\x8d\xd6\x64\x50\x04\xa4\x01\x01\x99\x10\x90\x9f\x1c\xde\xe3\xf4\ +\xd3\x5b\x1f\x05\xd1\xbf\x5a\xd3\x3b\x67\xcd\x6f\x8b\xd6\x64\x50\ +\x04\xa4\x01\x01\x99\x10\x90\x9f\x3c\xce\x09\xf9\xe1\x8d\x0f\x5b\ +\x18\x3c\x7c\x77\xee\x7d\x33\x16\x2d\x4a\xd6\xed\xb7\x55\x69\x12\ +\x69\xfa\x32\xdb\xd4\x5a\xdf\xf7\x10\x90\x21\x59\x1c\x14\xf2\xc3\ +\x1b\xaf\x15\x19\x3c\x09\xe4\x51\x43\xc1\x77\x5a\x94\xac\xe6\x1f\ +\xe1\x28\x8b\x80\x0c\xa9\x75\x29\x7b\x3a\xd5\x98\x26\xfa\x17\x2b\ +\xe2\x0e\xfa\x2b\x5a\x95\x2c\x02\x82\x08\x01\x19\x93\xc3\x07\x2d\ +\xe4\xaf\xd7\xb0\xd6\x7f\x12\x08\x77\xd0\x5f\xd3\xb2\x64\x11\x10\ +\x44\x08\xc8\xa0\x1a\xbf\x71\x1d\xfd\xf5\xd3\x7a\xfd\xa7\x5e\xf1\ +\x13\xef\x35\x2d\x4b\x16\xcb\x89\x08\x01\x19\x94\xd1\x91\x58\x7f\ +\xbc\x86\x75\xaa\x7f\xbc\x1e\xee\xa0\xff\x41\xeb\x92\x45\x40\x10\ +\x21\x20\xa3\x32\xb8\x53\x2d\x7f\xdc\x70\xb8\xd0\x3f\x5e\x0f\x77\ +\xd0\xff\xa0\x75\xc9\x22\x20\x88\x10\x90\x51\x59\x9c\x57\xf8\xe2\ +\x8f\xd7\xb0\x56\x7f\x71\xed\x44\x03\xc1\x4f\x5a\x98\x2c\x02\x82\ +\x08\x01\x19\xd6\xfa\x7f\xd2\xff\xe9\xd5\x67\x09\x57\xff\x8c\xca\ +\x9b\x9f\x8d\xdf\x36\xad\x4c\x16\x01\x41\x84\x80\x8c\x4b\xcb\xb2\ +\xbe\x57\xaf\x61\xad\x7e\x8c\xc9\xb9\x06\x82\x5f\xb4\x32\x59\x04\ +\x04\x11\x02\x32\x2e\x9b\x23\xb1\x5e\xbd\x86\xa5\x7f\xb6\x9a\x4b\ +\x8d\x03\x13\x2d\x4d\x16\x01\x41\x84\x80\x0c\xcc\xe6\x48\xac\xdf\ +\x4e\x4e\xff\xa6\x7f\xb4\x1a\x8d\x03\xbf\xd1\xd2\x64\x11\x10\x44\ +\x08\xc8\xc0\xd6\x7f\xc3\xac\xfc\x76\xdb\x7a\xed\x43\x56\xde\x3c\ +\x5e\x7e\xeb\xb4\x36\x59\x04\x04\x11\x02\x32\x32\x83\x63\xd3\x5f\ +\xfc\x76\xdf\x5a\xff\x64\x2d\xdc\x41\x7f\x8b\x16\x27\x8b\x80\x20\ +\x42\x40\x86\xa6\x95\x59\xdd\xaf\x4f\x5e\xac\xfd\xf9\x46\xee\xa0\ +\xbf\x45\x8b\x93\x45\x40\x10\x21\x20\x43\x73\x39\x12\xeb\xd7\x75\ +\x70\xa9\x7f\xb0\x92\x2f\x1a\x06\x5e\xd1\xea\x64\x11\x10\x44\x08\ +\xc8\xd8\xd6\x3f\x77\xea\xc5\xaf\xc3\x43\xf4\xff\xd7\xa2\x51\xe0\ +\x35\xad\x4e\x16\x01\x41\x84\x80\x8c\x6d\xf5\x37\x3d\x89\x86\xb3\ +\xf2\xa3\xa4\xb8\x83\xfe\x36\x2d\x4f\x16\x01\x41\x84\x80\x0c\xce\ +\xe4\x48\x2c\xdd\x7b\x58\x77\x34\xf7\x3f\x06\x81\x3f\x69\x7d\xb2\ +\x08\x08\x22\x04\x64\x70\x8f\x5a\x9c\x95\xdd\xfc\x18\x8d\xfe\xdf\ +\x4a\xe6\x7e\x7c\xe7\xb0\xb4\x3e\x59\x04\x04\x11\x02\x32\xba\x5b\ +\xad\xce\xba\x7e\x7c\x18\x7d\xdd\xf7\x60\x1d\xbe\x8c\x01\x7f\xd3\ +\x02\x65\x11\x10\x44\x08\xc8\xf0\x1a\xbf\x85\x9d\xbc\x7c\x18\x7d\ +\xdd\xcf\xa5\xbc\xac\x06\xde\xa0\x05\xca\x22\x20\x88\x10\x90\xe1\ +\xad\x7c\xe3\x5a\x9e\xbe\x0f\x45\xff\x7b\x1d\x7b\x5d\x8b\xdb\xa2\ +\x15\xca\x22\x20\x88\x10\x90\xf1\x9d\x69\x7d\x56\xf5\xfd\x8d\xbc\ +\xe7\xfa\xdf\xab\xe0\x0e\x7a\x4c\x4b\x94\x45\x40\x10\x21\x20\xe3\ +\xf3\x38\x12\xeb\x79\x20\x37\xfa\x9f\xab\xf8\xe3\xc1\xba\xf8\x8d\ +\x96\x28\x8b\x80\x20\x42\x40\x0a\xb0\x38\x12\xeb\xf9\xa7\x8c\xfe\ +\xd7\x2a\xb8\x83\xfe\x0f\x5a\xa3\x2c\x02\x82\x08\x01\xa9\x40\x0b\ +\xb4\xaa\x9b\x75\xff\x26\xa4\x95\xc0\x5b\xb4\x46\x59\x04\x04\x11\ +\x02\x52\xc1\x93\x56\x68\x4d\x77\xab\x1e\xcc\xb5\xd7\x85\xb8\x39\ +\x5a\xa4\x2c\x02\x82\x08\x01\x29\xc1\xe1\x48\xac\x87\xc6\x6b\xa9\ +\xc5\x99\xd6\x01\x6f\xd2\x2a\x65\x11\x10\x44\x08\x48\x09\xab\xbe\ +\xff\xc9\xc0\x57\xad\x03\xde\xa4\x55\xca\x22\x20\x88\x10\x90\x1a\ +\x56\x3e\x46\x7d\x65\x3a\x48\x05\x01\x2d\x53\x16\x01\x41\x84\x80\ +\xd4\x60\x72\x24\xd6\x3a\x7e\x9c\xa3\x82\x90\xd6\x29\x8b\x80\x20\ +\x42\x40\x8a\xf0\x38\x12\x6b\x1d\x5c\x18\xef\xd0\x3a\x65\x11\x10\ +\x44\x08\x48\x15\x8d\xdf\xc9\x81\x71\x07\xfd\x3d\x5a\xa8\x2c\x02\ +\x82\x08\x01\xa9\x62\xed\xa7\x91\xaf\xe7\xe5\x1c\x47\xfc\x83\x16\ +\x2a\x8b\x80\x20\x42\x40\xca\xb0\x38\x12\x6b\x05\x17\x9a\x3f\x42\ +\x5a\xa9\x2c\x02\x82\x08\x01\x29\xe3\xab\x96\x69\x63\xb8\x83\xfe\ +\x3e\x2d\x55\x16\x01\x41\x84\x80\xd4\xb1\xea\x59\x86\xab\xe1\xaa\ +\x78\x9f\x96\x2a\x8b\x80\x20\x42\x40\x0a\xd1\x3a\x6d\x0a\x77\xd0\ +\x77\xa0\xb5\xca\x22\x20\x88\x10\x90\x42\x3e\x6a\xa1\xb6\x84\x3b\ +\xe8\x3b\xd0\x5a\x65\x11\x10\x44\x08\x48\x25\xf7\x5a\xa9\xed\xb8\ +\xd5\xcc\xf1\x2f\x5a\xac\x2c\x02\x82\x08\x01\xa9\xe4\x5a\x2b\xb5\ +\x19\xdc\x41\xdf\x89\x56\x2b\x8b\x80\x20\x42\x40\x4a\xd9\xda\x91\ +\x58\x57\x9a\x37\xfe\x49\xab\x95\x45\x40\x10\x21\x20\xa5\xb4\x2e\ +\xf1\x60\xbe\x3f\x88\x1d\xef\xd3\x72\x65\x11\x10\x44\x08\x48\x2d\ +\x6b\x3e\xd4\x69\x79\x8f\x9a\x35\xfe\x4d\xcb\x95\x45\x40\x10\x21\ +\x20\xc5\x34\x7e\x43\x87\xc2\x1d\xf4\x1d\x69\xbd\xb2\x08\x08\x22\ +\x04\xa4\x98\x0d\x1d\x89\xc5\x1d\xf4\x5d\x69\xc1\xb2\x08\x08\x22\ +\x04\xa4\x9a\x07\xad\x56\x7d\xfc\x5c\xdb\x95\x16\x2c\x8b\x85\x46\ +\x84\x80\x54\xf3\x49\xab\x55\xde\xa5\x26\x8c\x77\x69\xc5\xb2\x08\ +\x08\x22\x04\xa4\x9c\xad\x1c\x89\x75\xa0\xf9\xe2\x5d\x5a\xb1\x2c\ +\x02\x82\x08\x01\xa9\x47\xcb\x55\xdc\x89\x66\x8b\xf7\x69\xc9\xb2\ +\x08\x08\x22\x04\xa4\x9e\x4d\x1c\x89\x75\xa4\xc9\x62\x07\x5a\xb3\ +\x2c\x02\x82\x08\x01\x29\x68\x0b\x47\x62\xf1\x43\x6d\x0f\x5a\xb3\ +\x2c\xd6\x1a\x11\x02\x52\xd0\xa9\x16\xac\x30\xee\xa0\xef\x43\x8b\ +\x96\x45\x40\x10\x21\x20\x15\x1d\x6a\xc5\xea\xd2\x44\xb1\x13\x2d\ +\x5a\x16\x01\x41\x84\x80\x94\xa4\x15\x2b\xeb\xb3\xe6\x89\x9d\x68\ +\xd5\xb2\x08\x08\x22\x04\xa4\xa4\xcf\x5a\xb2\xa2\xb8\x83\xbe\x1f\ +\x2d\x5b\x16\x01\x41\x84\x80\xd4\x74\xa4\x35\xab\xe9\x5a\xb3\xc4\ +\x6e\xb4\x6c\x59\x04\x04\x11\x02\x52\xd3\x37\xad\x59\x49\x5f\x34\ +\x49\xec\x48\xeb\x96\x45\x40\x10\x21\x20\x45\x55\x3e\x12\x4b\x53\ +\xc4\xae\xb4\x6e\x59\x04\x04\x11\x02\x52\xd4\xa3\x16\xad\xa0\x27\ +\x4d\x11\xbb\xd2\xc2\x65\x11\x10\x44\x08\x48\x55\x17\x5a\xb5\x72\ +\xee\x35\x41\xec\x4c\x2b\x97\x45\x40\x10\x21\x20\x65\x35\x7e\x6b\ +\x6d\x71\x07\x7d\x6f\x5a\xb9\x2c\x02\x82\x08\x01\x29\xeb\x58\xcb\ +\x56\xcc\xa1\xa6\x87\xdd\x69\xe9\xb2\x08\x08\x22\x04\xa4\xae\x33\ +\xad\x5b\x2d\x9a\x1c\xf6\xa0\xa5\xcb\x22\x20\x88\x10\x90\xba\x4a\ +\x1e\x89\xb5\xd7\x15\x87\x1f\xb4\x76\x59\x04\x04\x11\x02\x52\x58\ +\xc1\x23\xb1\xb8\x83\x9e\xa1\xc5\xcb\x22\x20\x88\x10\x90\xca\xb4\ +\x70\x85\x9c\x6a\x66\xd8\x87\x16\x2f\x8b\x80\x20\x42\x40\x2a\x2b\ +\x77\x24\xd6\x8d\x26\x86\xbd\x68\xf5\xb2\x08\x08\x22\x04\xa4\xb4\ +\x6a\x47\x62\x69\x5a\xd8\x8f\x56\x2f\x8b\x80\x20\x42\x40\x4a\x3b\ +\xd7\xd2\x15\xb1\xd7\xe5\x86\x5f\xb4\x7c\x59\x04\x04\x11\x02\x52\ +\xdb\xa5\xd6\xae\x84\x33\x4d\x0a\x7b\xd2\xfa\x65\x11\x10\x44\x08\ +\x48\x6d\xa5\x8e\xc4\xfa\xaa\x49\x61\x4f\x5a\xbf\x2c\x02\x82\x08\ +\x01\x29\xee\x56\x8b\x57\x00\x77\xd0\xb3\xb4\x80\x59\x04\x04\x11\ +\x02\x52\x5d\xe3\x77\xd8\xc7\x9d\x26\x84\xbd\x69\x05\xb3\x08\x08\ +\x22\x04\xa4\xba\x32\x47\x62\xf1\xed\x4f\xd3\x0a\x66\x11\x10\x44\ +\x08\x48\x79\x45\x8e\xc4\xe2\x0e\x7a\x9e\x96\x30\x8b\x80\x20\x42\ +\x40\xca\xfb\xaa\xe5\x1b\x1c\x77\xd0\xf3\xb4\x84\x59\x04\x04\x11\ +\x02\x52\xdf\x8d\xd6\x6f\x68\x17\x9a\x0c\x12\xb4\x86\x59\x04\x04\ +\x11\x02\xb2\x01\x5a\xbf\x91\x71\x07\xbd\x85\x16\x31\x8b\x80\x20\ +\x42\x40\x36\xe0\xa3\x16\x70\x60\x7c\xef\x5b\x68\x11\xb3\x08\x08\ +\x22\x04\x64\x0b\x86\x3f\x12\xeb\x41\x13\x41\x8a\x56\x31\x8b\x80\ +\x20\x42\x40\xb6\x60\xf8\x23\xb1\x3e\x69\x22\x48\xd1\x2a\x66\x11\ +\x10\x44\x08\xc8\x26\x0c\x7e\x24\x16\x77\xd0\xdb\x68\x19\xb3\x08\ +\x08\x22\x04\x64\x13\x5a\x97\x7e\x5d\xdc\x41\x6f\xa4\x75\xcc\x22\ +\x20\x88\x10\x90\x6d\x38\xd1\x1a\x0e\xe9\x4a\x93\x40\x92\xd6\x31\ +\x8b\x80\x20\x42\x40\x36\xa2\xf1\x1b\xbd\x26\xee\xa0\xb7\xd2\x42\ +\x66\x11\x10\x44\x08\xc8\x46\x5c\x69\x11\x07\xf4\xa8\x29\x20\x4b\ +\x0b\x99\x45\x40\x10\x21\x20\x5b\x31\xec\x91\x58\x27\x9a\x00\xd2\ +\xb4\x92\x59\x04\x04\x11\x02\xb2\x15\x9f\xb4\x8a\xa3\xe1\x0e\x7a\ +\x3b\x2d\x65\x16\x01\x41\x84\x80\x6c\xc6\xa0\x47\x62\xf1\xd3\xab\ +\x9d\x96\x32\x8b\x6f\x01\x22\x04\x64\x3b\xb4\x8c\x63\xb9\xd4\xe0\ +\xd1\x40\x6b\x99\x45\x40\x10\x21\x20\xdb\x31\xe4\x91\x58\x07\x1a\ +\x3c\x1a\x68\x2d\xb3\x08\x08\x22\x04\x64\x43\xee\xb5\x90\x03\xe1\ +\x33\xe8\x3d\x68\x31\xb3\x08\x08\x22\x04\x64\x43\x4e\xb5\x90\x03\ +\x39\xd2\xd0\xd1\x42\x8b\x99\x45\x40\x10\x21\x20\x5b\xf2\x45\x2b\ +\x39\x10\xde\xc4\xdb\x81\xd6\x32\x8b\x80\x20\x42\x40\xb6\x64\xc4\ +\xb7\xf2\xf2\x31\xc2\x76\x5a\xca\x2c\x02\x82\x08\x01\xd9\x92\x5b\ +\xad\xe4\x48\x38\xc8\xa4\x9d\x96\x32\x8b\x80\x20\x42\x40\x36\x64\ +\xcc\xcf\x12\x72\x94\x62\x33\xad\x64\x16\x01\x41\x84\x80\x6c\xc8\ +\x98\xa7\x99\xf0\x51\xf4\x66\x5a\xc9\x2c\x02\x82\x08\x01\xd9\x8e\ +\x27\xad\xe3\x68\x78\x2b\x6f\x2b\x2d\x64\x16\x01\x41\x84\x80\x6c\ +\x46\xeb\xf2\xaf\x87\x07\xda\x36\xd2\x3a\x66\x11\x10\x44\x08\xc8\ +\x66\x3c\x68\x19\xc7\x73\xa6\x19\x20\x49\xeb\x98\x45\x40\x10\x21\ +\x20\x5b\x71\xac\x55\x1c\x11\xdf\xf9\x36\x5a\xc6\x2c\x02\x82\x08\ +\x01\xd9\x0a\x2d\xe2\x90\xb8\x8f\xde\x46\xcb\x98\x45\x40\x10\x21\ +\x20\x1b\x31\xe0\x87\xd0\x7f\x73\xa8\x59\x20\x45\xab\x98\x45\x40\ +\x10\x21\x20\xdb\x70\xae\x35\x1c\xd5\xa9\xe6\x81\x0c\x2d\x62\x16\ +\x01\x41\x84\x80\x6c\x43\xe3\xf7\x79\x75\xf7\x9a\x07\x32\xb4\x88\ +\x59\x04\x04\x11\x02\xb2\x09\x17\x5a\xc2\x71\xed\x75\xa5\xe1\x35\ +\xad\x61\x16\x01\x41\x84\x80\x6c\xc1\x57\xad\xe0\xc8\x34\x15\x24\ +\x68\x09\xb3\x08\x08\x22\x04\x64\x0b\x06\x7c\x92\xd4\x5f\xb8\x8f\ +\x9e\xa7\x25\xcc\x22\x20\x88\x10\x90\x0d\xf8\xac\x05\x1c\xdb\xb5\ +\x66\x83\xbd\x69\x05\xb3\x08\x08\x22\x04\xa4\xbe\x47\xad\xdf\xe0\ +\x78\x38\x61\x9a\x56\x30\x8b\x80\x20\x42\x40\xea\x1b\xf7\x0c\x93\ +\xd7\x3e\x6b\x3e\xd8\x97\x16\x30\x8b\x80\x20\x42\x40\xca\x1b\xf9\ +\x0c\x93\xd7\x34\x21\xec\x4b\xeb\x97\x45\x40\x10\x21\x20\xe5\x69\ +\xf5\x0a\xb8\xd4\x8c\xb0\x27\xad\x5f\x16\x01\x41\x84\x80\x54\x37\ +\xf6\x19\x26\xaf\xf1\x93\x2c\x47\xcb\x97\xc5\xb2\x23\x42\x40\x8a\ +\xfb\xa6\xc5\x2b\x81\x43\x15\x73\xb4\x7c\x59\x04\x04\x11\x02\x52\ +\x5c\xe3\x37\xd8\xcc\xad\x66\x85\xbd\x68\xf5\xb2\x08\x08\x22\x04\ +\xa4\xb6\x1b\xad\x5d\x15\x8f\x9a\x17\xf6\xa1\xc5\xcb\x22\x20\x88\ +\x10\x90\xd2\x4e\xb5\x74\x65\x3c\x68\x62\xd8\x87\x16\x2f\x8b\x80\ +\x20\x42\x40\x4a\x3b\xd2\xd2\xd5\xc1\x45\x90\xa0\xb5\xcb\x22\x20\ +\x88\x10\x90\xca\x4e\xb4\x72\x85\x70\x1f\x3d\x41\x6b\x97\x45\x40\ +\x10\x21\x20\x85\x15\x39\xc3\xe4\xb5\x0b\x4d\x0e\xbb\xd3\xd2\x65\ +\x11\x10\x44\x08\x48\x61\x67\x5a\xb8\x5a\xbe\x6a\x76\xd8\x99\x56\ +\x2e\x8b\x80\x20\x42\x40\xea\xfa\xa8\x75\x2b\xe6\x4c\xd3\xc3\xce\ +\xb4\x72\x59\x04\x04\x11\x02\x52\x97\x96\xad\x9c\xbd\x2e\x3a\x3c\ +\xd3\xc2\x65\x11\x10\x44\x08\x48\x59\x97\x5a\xb6\x7a\x34\x41\xec\ +\x4a\xeb\x96\x45\x40\x10\x21\x20\x55\x5d\x69\xd5\x0a\xe2\xe1\x84\ +\x7b\xd2\xba\x65\x11\x10\x44\x08\x48\x55\x8d\xdf\x59\x6b\xa7\x9a\ +\x23\x76\xa3\x65\xcb\x22\x20\x88\x10\x90\xa2\xaa\x9d\x61\xf2\xca\ +\xbd\x26\x89\xdd\x68\xd9\xb2\x08\x08\x22\x04\xa4\xa6\x6b\xad\x59\ +\x51\x4f\x9a\x26\x76\xa2\x55\xcb\x22\x20\x88\x10\x90\x9a\xea\x9d\ +\x61\xf2\x9a\xa6\x89\x9d\x68\xd1\xb2\x08\x08\x22\x04\xa4\xa4\x5b\ +\x2d\x59\x59\x5f\x34\x51\xec\x42\x8b\x96\x45\x40\x10\x21\x20\x15\ +\x7d\xd5\x8a\x15\x76\xae\xa9\x62\x07\x5a\xb3\x2c\x02\x82\x08\x01\ +\xa9\xa8\xe6\x19\x26\xaf\x1c\x69\xaa\xd8\x81\xd6\x2c\x8b\x80\x20\ +\x42\x40\x0a\xfa\xac\x05\x2b\xed\xb3\x26\x8b\xf7\x69\xc9\xb2\x08\ +\x08\x22\x04\xa4\x20\xad\x57\x71\x07\x9a\x2d\xde\xa5\x15\xcb\x22\ +\x20\x88\x10\x90\x7a\x1e\xb4\x5e\xc5\x5d\x6a\xba\x78\x97\x56\x2c\ +\x8b\x80\x20\x42\x40\xca\x39\xd6\x72\x95\xc7\xcf\xb5\x5d\x69\xc1\ +\xb2\x58\x68\x44\x08\x48\x39\x5a\xad\xfa\x78\x38\xe1\xae\xb4\x60\ +\x59\x04\x04\x11\x02\x52\xcd\xa1\x56\x6b\x03\x6e\x35\x65\xbc\x43\ +\xeb\x95\x45\x40\x10\x21\x20\xc5\x9c\x6b\xb1\x36\xe1\x93\x26\x8d\ +\x7f\xd3\x72\x65\x11\x10\x44\x08\x48\x31\x8d\xdf\xd0\xb1\xf0\x70\ +\xc2\xdd\x68\xb9\xb2\x08\x08\x22\x04\xa4\x96\x0b\xad\xd5\x46\x70\ +\x49\xec\x44\xab\x95\x45\x40\x10\x21\x20\xa5\x6c\xe0\x0c\x93\x57\ +\xb8\x8f\xbe\x13\xad\x56\x16\x01\x41\x84\x80\x94\x72\xaf\xa5\xda\ +\x8c\x1b\x4d\x1c\xff\xa2\xc5\xca\x22\x20\x88\x10\x90\x4a\x36\x71\ +\x86\xc9\x6b\x5f\x35\x75\xfc\x83\xd6\x2a\x8b\x80\x20\x42\x40\x0a\ +\x79\xd4\x42\x6d\x09\xf7\xd1\x77\xa0\xb5\xca\x22\x20\x88\x10\x90\ +\x42\x36\x72\x86\xc9\x6b\x7b\x5d\x82\x1b\xa5\xa5\xca\x22\x20\x88\ +\x10\x90\x3a\x3e\x6a\x9d\x36\x46\xb3\x47\x4c\x2b\x95\x45\x40\x10\ +\x21\x20\x75\x68\x99\xb6\xe6\x50\xd3\x47\x48\x2b\x95\x45\x40\x10\ +\x21\x20\x65\x7c\xd1\x32\x6d\xce\xa9\x16\x00\x11\x2d\x54\x16\x01\ +\x41\x84\x80\x54\xf1\x4d\xab\xb4\x3d\xf7\x5a\x01\x44\xb4\x50\x59\ +\x04\x04\x11\x02\x52\x45\xe3\x77\x72\x64\x3c\x9c\xf0\x1d\x5a\xa7\ +\x2c\x02\x82\x08\x01\x29\xe2\x46\x8b\xb4\x49\x5a\x03\x04\xb4\x4c\ +\x59\x04\x04\x11\x02\x52\xc3\xa9\xd6\x68\x9b\xbe\x68\x15\xf0\x36\ +\x2d\x53\x16\x01\x41\x84\x80\xd4\x70\xa4\x35\xda\xa8\x73\x2d\x03\ +\xde\xa4\x55\xca\x22\x20\x88\x10\x90\x12\x4e\xb4\x44\x5b\x75\xa4\ +\x75\xc0\x9b\xb4\x4a\x59\x04\x04\x11\x02\x52\xc1\x16\xcf\x30\x79\ +\xed\x44\x2b\x81\xb7\x68\x91\xb2\x8e\xce\x56\xd5\xfa\x36\x6d\x7d\ +\x99\x6d\x9a\xfb\x53\x52\x04\xa4\x82\x33\xad\xd0\x4a\x1e\x0d\x1e\ +\xa3\xfb\xa8\xa5\xc0\x1b\xb4\x46\x83\xba\xd6\x2c\xb2\xf4\x65\xb6\ +\xe9\x41\x8b\x30\x17\x02\x52\xc0\xca\x67\x98\x9c\xfd\x77\xac\xff\ +\xb5\xa2\xb9\x37\xca\xd0\xb4\x46\x83\x22\x20\x0d\x08\xc8\x84\x80\ +\x04\xb4\x3e\x6b\x39\xb1\x78\x09\xed\x4a\x8b\x81\xbf\x69\x89\x06\ +\x45\x40\x1a\x10\x90\x09\x01\x79\xdb\xa5\xd6\x67\x2d\xcf\x1b\x5c\ +\xff\x6b\x4d\x3c\x9c\x30\xa6\x25\x1a\x14\x01\x69\x40\x40\x26\x04\ +\xe4\x4d\x57\x5a\x9e\xd5\x3c\x8f\x61\xed\x86\x7d\x77\xfb\x63\x39\ +\xf0\x37\xad\xd0\xa0\x08\x48\x03\x02\x32\x21\x20\x6f\x6a\xfc\x16\ +\x36\xfb\x7e\x89\x5a\x3c\x0a\xf1\xd3\x8f\xf5\xc0\x5f\xb4\x40\x83\ +\x22\x20\x0d\x08\xc8\x84\x80\xbc\x65\xf5\x33\x4c\xbe\x9f\x44\x75\ +\xad\xff\xbd\x2a\x1e\x4e\x18\xd1\x02\x0d\x8a\x80\x34\x20\x20\x13\ +\x02\xf2\x86\xf5\x7f\x74\xbf\xbc\x4d\x5f\xff\x7b\x5d\x5c\x20\x01\ +\xad\xcf\xa0\x08\x48\x03\x02\x32\xe1\xe7\xc3\x1b\xd6\x3f\xc3\xe4\ +\x65\x18\xf7\xfa\x3f\xab\xe2\x3e\x7a\x40\xeb\x33\x28\x02\xd2\x80\ +\x80\x4c\x08\xc8\xdf\x6e\xb5\x36\xeb\xf9\xf1\x51\xd7\x0b\xfd\xbf\ +\x75\xdd\xbc\x8c\x05\x7f\xd2\xf2\x0c\x8a\x80\x34\x20\x20\x13\x02\ +\xf2\x97\xaf\x5a\x9a\x15\xfd\x38\xc7\x70\xf5\xb7\x82\xfd\xc0\xc3\ +\x09\xdf\xa4\xd5\x19\x14\x01\x69\x40\x40\x26\x04\xe4\x2f\x2b\x9f\ +\x61\xf2\x9d\x46\xa2\xff\xb7\x32\x1e\x4e\xf8\x26\xad\xce\xa0\x08\ +\x48\x03\x02\x32\x21\x20\x7f\x7a\xd2\xca\xac\xe8\x52\x43\x69\xbc\ +\x90\x7a\x79\xd2\x70\xf0\x3b\x2d\xce\xa0\x08\x48\x03\x02\x32\x21\ +\x20\x7f\xd2\xc2\xac\xe9\xe7\x37\xc5\xe0\x3c\xc5\x17\x1a\x0e\x7e\ +\xa7\xb5\x19\x14\x01\x69\x40\x40\x26\x04\xe4\x0f\x0e\x9f\xff\xd6\ +\x50\x1c\xce\x53\x7c\xc1\xc3\x09\xdf\xa0\xb5\x19\x14\x01\x69\x40\ +\x40\x26\x04\xe4\x35\x87\x9f\xd9\xd3\x87\xf7\xf4\x0f\x56\xd7\xfa\ +\xe3\xa6\x22\x2d\xcd\xa0\x08\x48\x03\x02\x32\x21\x20\xaf\x39\xdc\ +\x76\x98\xee\x39\xb8\x3c\x54\x97\xfb\xe8\x7f\xd3\xd2\x0c\x8a\x80\ +\x34\x20\x20\x13\x02\xf2\x8a\xc5\x5d\x87\x03\x0d\xc6\xe5\x93\x20\ +\xcf\xbe\x1f\xad\x82\x57\xb4\x32\x83\x22\x20\x0d\x08\xc8\x84\x80\ +\xfc\xee\x5c\xab\xb2\xaa\xdf\x8e\x9f\xb2\x18\xcf\x0b\x0d\x08\xbf\ +\x68\x61\x06\x45\x40\x1a\x10\x90\x09\x01\xf9\x9d\xc3\x0b\x58\xaf\ +\xbe\xff\xfa\x47\xeb\xfb\xf9\xce\x62\xfc\xa4\x85\x19\x14\x01\x69\ +\x40\x40\x26\x04\xe4\x37\x1e\xaf\x18\x69\x30\x2f\x0c\x3e\xd4\x28\ +\xdf\x34\x22\x88\xd6\x65\x50\x04\xa4\x01\x01\x99\x10\x90\x89\xc1\ +\x19\x26\xcf\x5e\x5d\x9d\x16\xcf\x04\x79\x71\xa4\x11\x41\xb4\x2e\ +\x83\x22\x20\x0d\x08\xc8\x84\x80\x4c\x2c\x4e\xbf\x7d\xfd\x1d\xf1\ +\x68\xda\x8b\x13\x0d\x09\x3f\x68\x59\x06\x45\x40\x1a\x10\x90\x09\ +\x01\xf9\xc5\xe4\x4f\xfb\x1a\x8d\xe8\x1f\x3a\x78\xd4\x90\xf0\x42\ +\xab\x32\x28\x02\xd2\x80\x80\x4c\x08\xc8\x4f\x8f\x5a\x91\x95\xfd\ +\xf1\xa9\x6f\x97\xd3\x4c\x9e\xcd\xbd\x6d\x06\xa3\x55\x19\x14\x01\ +\x69\x40\x40\x26\x04\xe4\xa7\x07\xad\xc8\xca\xfe\xb8\x59\x6d\x72\ +\xa4\xfb\x8b\x2b\x8d\x09\xdf\x69\x51\x06\x45\x40\x1a\x10\x90\x09\ +\x01\x91\x8f\x5a\x90\xb5\x69\x38\xbf\xe8\x1f\x3b\xe0\xe1\x84\xbf\ +\xd3\xa2\x0c\x8a\x80\x34\x20\x20\x13\x02\x22\x5a\x8f\xb5\xfd\xf5\ +\xfc\x3f\x93\xbf\x18\xbd\xb8\xd0\x98\xf0\x4c\x6b\x32\x28\x02\xd2\ +\x80\x80\x4c\x08\xc8\x0f\x5f\xb4\x1e\x6b\xfb\x6b\x63\xbb\x9c\xc8\ +\xfb\xe2\xab\x06\x05\x02\xb2\x61\x04\x64\x42\x40\x5e\x7c\xd3\x72\ +\xac\xed\x8d\x57\x89\xf4\x6f\x2c\xfc\x76\xca\xca\xe6\x69\x49\x06\ +\x45\x40\x1a\x10\x90\x09\x01\x79\xd1\xf8\x2d\xeb\xe6\x8d\x0f\x5b\ +\x38\x3c\xa0\xe4\x97\xbd\xae\xcd\xda\xb4\x22\x83\x22\x20\x0d\x08\ +\xc8\x84\x80\x7c\x77\xa3\xd5\x58\xdd\x1b\x9f\xb5\x70\x7a\x1f\x16\ +\x87\x2a\x4e\xb4\x20\x83\x22\x20\x0d\x08\xc8\x84\x80\x3c\x3b\xd5\ +\x62\xac\xee\xcd\x97\x88\xf4\xef\x3c\xfc\x75\x93\x7f\xb3\xb4\x20\ +\x83\x22\x20\x0d\x08\xc8\x84\x80\x3c\x73\x79\x6e\xd3\xdb\xdf\x0d\ +\x9b\xbf\x1e\xbd\x38\xd5\xa8\x36\x4f\xeb\x31\x28\x02\xd2\x80\x80\ +\x4c\x08\xc8\x7f\xff\x9d\x68\x2d\xd6\xa7\x01\xbd\x66\x74\x1e\xd6\ +\x33\x1e\x4e\x28\x5a\x8f\x41\x11\x90\x06\x04\x64\x42\x40\x5c\xce\ +\x30\x79\x76\xa8\x11\xfd\xc1\xe3\x90\xc7\x9f\xa6\x07\xee\x6e\x9b\ +\x96\x63\x50\x04\xa4\x01\x01\x99\x10\x10\xa3\x67\x6e\x04\x2f\x0f\ +\x59\x7d\x14\x84\xfb\xe8\xa2\xd5\x18\x14\x01\x69\x40\x40\x26\x04\ +\xc4\xe5\x0c\x93\x7f\x1c\x15\xd2\x78\x41\x75\xf6\xc7\x71\x8f\x5b\ +\xa5\xd5\x18\x14\x01\x69\x40\x40\x26\x04\x44\x0b\x61\x20\x7c\xe2\ +\xc6\x93\x7e\x81\x89\xd6\x1f\x3e\x35\x68\x31\x06\x45\x40\x1a\x10\ +\x90\xc9\xe6\x03\x62\xf4\x39\xbd\x03\x0d\xe9\x6f\xfa\x05\x26\x78\ +\x38\xe1\x77\x5a\x8c\x41\x11\x90\x06\x04\x64\xb2\xf5\x80\x18\x7d\ +\x4c\xef\x1f\x97\xa5\xcf\xcb\x6c\x2f\x78\x38\xe1\x33\xad\xc5\xa0\ +\x08\x48\x03\x02\x32\xd9\x7a\x40\x8c\x6e\x2f\xfc\xeb\x71\x1b\x46\ +\xc3\xfc\x2e\xfe\xbb\xd2\x76\x68\x29\x06\x45\x40\x1a\x10\x90\xc9\ +\xc6\x03\x62\xf4\x21\xbd\x7f\xbe\x30\x64\xf6\x46\xac\x4b\x0d\x6b\ +\xcb\xb4\x14\x83\x22\x20\x0d\x08\xc8\x64\xdb\x01\xb9\xd6\x2a\x38\ +\xf8\xe3\x51\x84\x7f\xf0\xfa\x2c\xc8\x3b\x83\xdd\x04\xad\xc4\xa0\ +\x08\x48\x03\x02\x32\xd9\x76\x40\x6c\xce\x30\x79\xf7\xa4\x74\x97\ +\xf3\xe6\x85\x87\x13\x12\x90\xed\x22\x20\x93\x4d\x07\xe4\x56\x8b\ +\xe0\xe0\xbd\x33\xa6\x7c\x3e\xee\xf8\xe2\x56\xc3\xda\x2e\x2d\xc4\ +\xa0\x08\x48\x03\x02\x32\xd9\x72\x40\x3e\x69\x0d\x1c\xbc\x7b\x57\ +\xc1\xe6\xc4\x60\x79\xe3\xe0\xf9\x6d\xd1\x3a\x0c\x8a\x80\x34\x20\ +\x20\x93\x2d\x07\xc4\xe9\x0f\xf5\x9f\x34\xa6\x98\xd5\x83\xa5\xe6\ +\xdf\x44\xf6\xb4\x0e\x83\x22\x20\x0d\x08\xc8\x64\xc3\x01\x71\xfa\ +\x7c\x77\x70\x8c\xe2\xef\x9c\xfe\xbe\xf4\xdd\xb6\xef\x9e\x11\x90\ +\x0d\x23\x20\x93\x0d\xff\x18\xd0\x0a\x58\xd0\x90\xfe\xe9\x50\xbf\ +\xd6\xc4\xd6\xef\xa3\x6b\x19\x06\x45\x40\x1a\x10\x90\xc9\x76\x03\ +\xe2\xf4\x92\xd0\x6e\xb7\xa4\xf5\x8b\x5d\x5c\x68\x58\x1b\xa5\x55\ +\x18\x14\x01\x69\x40\x40\x26\x9b\x0d\x88\xd5\x47\xf3\x34\xa6\x77\ +\x38\xbd\x69\xec\xbb\xaf\x1a\xd7\x36\x69\x11\x06\x45\x40\x1a\x10\ +\x90\xc9\x66\x03\xd2\xf8\x4d\xea\xea\xb3\xc6\xf4\x1e\xfd\x72\x17\ +\xef\x7c\x74\xa5\x38\x2d\xc2\xa0\x08\x48\x03\x02\x32\xd9\x6a\x40\ +\x9c\x6e\x28\xec\x7c\x37\xe1\xb3\xfe\x03\x17\x7b\x5d\xa9\xd5\x68\ +\x0d\x06\x45\x40\x1a\x10\x90\xc9\x46\x03\x72\xae\xe9\x5b\xd8\xfd\ +\x7b\xa0\xff\xc0\x86\x86\xb5\x49\x5a\x82\x41\x11\x90\x06\x04\x64\ +\xb2\xd1\x80\x18\x9d\x61\xb2\xcf\xe3\x35\xcc\x8e\x75\xdf\xe5\xdd\ +\xc7\x65\x69\x09\x06\x45\x40\x1a\x10\x90\xc9\x36\x03\x62\x75\x3b\ +\x7a\x9f\x83\x09\x9d\xee\xdc\x7c\xd7\xfa\x73\x68\x60\x5a\x81\x41\ +\x11\x90\x06\x04\x64\xb2\xc9\x80\x7c\xd5\xe4\x2d\xec\x75\x2b\xda\ +\xec\x58\xf7\x0f\xf7\x1a\xd7\x06\x69\x05\x06\x45\x40\x1a\x10\x90\ +\xc9\x26\x03\x62\x75\x36\xfa\x7b\xa7\x28\xbe\x66\x76\xac\xfb\xce\ +\x6f\x20\xab\x47\x0b\x30\x28\x02\xd2\x80\x80\x4c\xb6\x18\x10\xab\ +\x37\x33\xed\xf9\x6c\x26\xb3\x63\xdd\x37\x7c\x1f\x5d\xf3\x1f\x14\ +\x01\x69\x40\x40\x26\x1b\x0c\x48\xeb\x92\xf5\xf5\xfe\x29\x8a\xaf\ +\x99\x1d\xeb\xfe\xe1\x8b\xc6\xb5\x39\x9a\xff\xa0\x08\x48\x03\x02\ +\x32\xd9\x60\x40\x1e\x34\x75\x0b\x7b\xbf\x8f\xc9\xed\x58\xf7\x0f\ +\xe7\x1a\xd8\xd6\x68\xfa\x83\x22\x20\x0d\x08\xc8\x64\x7b\x01\xf1\ +\xba\x0f\xad\x41\xed\xc1\xec\x58\xf7\x7d\xde\x85\x5c\x8a\xa6\x9f\ +\x75\x79\xb1\xaa\xd6\xc7\xb9\xe8\xcb\x6c\xd3\x93\x16\x61\x2e\x04\ +\xc4\x99\x26\xee\x21\xf1\x60\x3f\xb7\x63\xdd\x3f\x9c\x68\x60\x1b\ +\xa3\xd9\x67\xf1\x54\x79\x44\x08\x88\xb1\x2f\x9a\xb8\x07\x0d\x6a\ +\x2f\x66\xc7\xba\x6f\xf5\xe1\x84\x9a\x7c\x16\x01\x41\x84\x80\xf8\ +\xf2\x7a\x17\x53\xee\x4d\xb0\xfa\x8f\x6d\xec\xf9\x46\xb2\x22\x34\ +\xf9\x2c\x02\x82\x08\x01\xf1\xd5\xf8\xbd\xe9\x2b\xf9\x4c\x26\xb7\ +\x63\xdd\x3f\x5c\x69\x60\x9b\xa2\xb9\x67\x11\x10\x44\x08\x88\xad\ +\x1b\x4d\xdb\xc3\x5e\xdf\xe9\xdf\xe8\x3f\xb7\xb1\xc9\x87\x13\x6a\ +\xee\x59\x04\x04\x11\x02\xe2\xca\xeb\x3d\xb0\xe9\x73\x40\xdc\x8e\ +\x75\xdf\xe4\xc3\x09\x35\xf5\x2c\x02\x82\x08\x01\x71\xe5\x75\x10\ +\x48\xfe\x67\x88\xbe\x80\x8f\x7d\x3f\x0e\x59\x80\x66\x9e\x45\x40\ +\x10\x21\x20\xa6\x4e\x34\x69\x0f\x0d\x0f\xf4\x73\x3b\xd6\x7d\x8b\ +\x0f\x27\xd4\xcc\xb3\x08\x08\x22\x04\xc4\xd3\xa3\xe6\x6c\xa2\xe5\ +\xc3\xc0\x8d\x97\x58\x7f\x1b\xbb\x97\xf6\x4c\x13\xcf\x22\x20\x88\ +\x10\x10\x4f\x5e\xc7\x48\x35\xbd\xf9\xd5\xed\x58\xf7\x0d\xde\x47\ +\xd7\xc4\xb3\x08\x08\x22\x04\xc4\x92\xd9\xeb\x3e\x6d\xb7\x0d\xdc\ +\x8e\x75\xff\x70\xa3\x81\x6d\x86\xe6\x9d\x45\x40\x10\x21\x20\x96\ +\x34\x63\x13\x8d\x3f\x70\xed\x8e\x75\xff\xf0\x55\x23\xdb\x0a\x4d\ +\x3b\x8b\x80\x20\x42\x40\x1c\x99\x1d\x42\xa8\x51\xa5\xb9\x1d\xeb\ +\xbe\xb9\xfb\xe8\x9a\x76\x16\x01\x41\x84\x80\x18\xba\xd2\x84\x4d\ +\x24\x4e\x51\x7c\xcd\xee\x58\xf7\xfd\xae\xdb\xf1\x69\xd6\x59\x04\ +\x04\x11\x02\x62\xa8\xf1\x9b\xd2\x9b\x46\xd5\xc0\xed\x58\xf7\xad\ +\x3d\x9c\x50\x93\xce\x22\x20\x88\x10\x10\x3f\x5e\x67\x98\xf4\x78\ +\x94\xb8\xdd\xb1\xee\xfb\x3f\x1c\x6b\x68\x9a\x74\x16\x01\x41\x84\ +\x80\xd8\xb9\xd6\x74\x4d\x74\x79\xd3\xab\xdd\xb1\xee\xcd\x8f\xb9\ +\x1b\x8a\xe6\x9c\x45\x40\x10\x21\x20\x76\x8e\x34\x5d\x13\x7d\x56\ +\x5d\x5f\xcc\xc7\xa6\x1e\x4e\xa8\x39\x67\x11\x10\x44\x08\x88\x1b\ +\xb3\x03\xd0\xd3\xa7\x28\xbe\x66\x77\xac\x7b\x8f\x57\xe6\x86\xa1\ +\x29\x67\x11\x10\x44\x08\x88\x19\xb7\xdb\x05\xbd\x7e\x78\xe8\xcb\ +\x19\xd1\xc0\xb6\x40\x33\xce\x22\x20\x88\x10\x10\x33\x66\x9f\x99\ +\xe8\xf6\x89\x09\xbb\x63\xdd\xb7\xf4\x70\x42\xcd\x38\x8b\x80\x20\ +\x42\x40\xbc\x3c\x69\xae\x2e\x4e\x35\xae\x76\xfa\x82\x46\xb6\xf3\ +\x73\x51\x13\xce\x22\x20\x88\x10\x10\x2f\x9a\xaa\x8b\x8e\x7f\x4a\ +\xb7\x3b\xd6\x7d\x43\xf7\xd1\x35\xe1\x2c\x02\x82\x08\x01\xb1\xf2\ +\xa0\xa9\xba\xe8\xf9\xf0\xa5\xc6\x4b\x6d\x06\x27\x1a\x59\x79\x9a\ +\x6f\x16\x01\x41\x84\x80\x38\x71\x3b\xf9\xbc\xeb\xb1\xb5\x76\xc7\ +\xba\x7f\xf8\xf0\xa8\xa1\x55\xa7\xe9\x66\x11\x10\x44\x08\x88\x13\ +\x4d\xd4\x86\x86\xd5\x89\xdd\xb1\xee\x1f\x1e\x34\xb2\xea\x34\xdd\ +\x2c\x02\x82\x08\x01\x31\xe2\xf6\x79\xed\xe6\x53\x14\x5f\xf3\x3b\ +\xd6\xfd\xc3\x95\x86\x56\x9c\x66\x9b\x45\x40\x10\x21\x20\x3e\xce\ +\x35\x4f\x1b\x1a\x57\x37\x76\xc7\xba\x6f\xe5\xe1\x84\x9a\x6d\x16\ +\x01\x41\x84\x80\xf8\x30\x3b\xc3\xa4\xff\x67\xb5\xfd\x8e\x75\xff\ +\x70\xa1\xa1\xd5\xa6\xc9\x66\x11\x10\x44\x08\x88\x0d\xb7\xd3\x3e\ +\x66\xf8\xd3\xb9\xdf\xb1\xee\x5d\xdf\x67\x66\x4b\x73\xcd\x22\x20\ +\x88\x10\x10\x17\x5f\x35\x4b\x1b\x33\x2c\xb7\xdf\xb1\xee\xdb\x78\ +\x38\xa1\xe6\x9a\x45\x40\x10\x21\x20\x2e\xdc\xde\xa3\x34\xcb\xc7\ +\xec\xfc\x8e\x75\x2f\xff\xc2\xe8\x77\x9a\x6a\x16\x01\x41\x84\x80\ +\x98\xb0\x3b\x2b\xea\x5c\x03\xeb\x4b\x5f\xdc\xc8\x16\xee\xa3\x6b\ +\xaa\x59\x04\x04\x11\x02\xe2\xe1\x51\x73\xb4\x31\xd3\x4b\x3b\x7e\ +\xc7\xba\x6f\xe1\xe1\x84\x9a\x69\x16\x01\x41\x84\x80\x78\x70\x3b\ +\xc3\xa4\xe3\x29\x8a\xaf\xe9\xcb\x3b\x99\x6b\xaa\x3e\x34\xd1\x2c\ +\x02\x82\x08\x01\xb1\x60\x77\xcc\xc7\x6c\x67\x9d\xfb\x1d\xeb\xde\ +\xeb\x99\x59\xc6\x34\xd1\x2c\x02\x82\x08\x01\xb1\xa0\x19\xfa\x98\ +\xef\x94\x28\xfd\x06\x4e\xf6\xba\x8a\x47\xa4\x79\x66\x11\x10\x44\ +\x08\x88\x83\x2f\x9a\xa1\x8d\x19\xef\x0b\xf8\x1d\xeb\x5e\xff\xe1\ +\x84\x9a\x66\x16\x01\x41\x84\x80\x18\xb0\x3b\xc3\x64\xd6\x9f\xa8\ +\x8d\x97\xdc\x1c\xaa\xdf\x47\xd7\x34\xb3\x08\x08\x22\x04\xc4\x80\ +\xdd\x8f\xd4\xce\xa7\x28\xbe\x66\x78\xac\xfb\x87\x6b\x8d\xad\x28\ +\xcd\x32\x8b\x80\x20\x42\x40\xd6\x77\xa1\xf9\xf9\xd0\xc0\x66\xe2\ +\x77\xac\x7b\xf5\x87\x13\x6a\x96\x59\x04\x04\x11\x02\xb2\x3a\xbf\ +\x23\x06\x9f\x34\xb2\x99\x18\x1e\xeb\xde\xff\xe0\x48\x2b\x9a\x64\ +\x16\x01\x41\x84\x80\xac\xce\xee\x0f\xe4\xb3\x7f\x36\xdb\xef\x58\ +\xf7\xe2\xf7\xd1\x35\xc7\x2c\x02\x82\x08\x01\x59\x9b\xdf\x07\x23\ +\x66\x5f\x67\xc3\x63\xdd\xe7\xfb\xe0\x8b\x03\xcd\x31\x8b\x80\x20\ +\x42\x40\x56\x66\x77\x86\xc9\x12\x9f\xab\x33\x3c\xd6\xbd\xf4\x4f\ +\x49\x4d\x31\x8b\x80\x20\x42\x40\x56\xe6\xf7\x72\xce\x02\x3f\x2e\ +\x0c\x8f\x75\x2f\x7d\xa8\xa2\xa6\x98\x45\x40\x10\x21\x20\xeb\xf2\ +\xfb\x58\xdd\x22\x0f\xc8\x30\x3c\xd6\x7d\xde\xf7\x2e\xaf\x4b\x33\ +\xcc\x22\x20\x88\x10\x90\x75\x69\x6a\x46\x96\x39\x5a\x50\xbf\x99\ +\x95\xf9\x8e\x6f\x59\x9b\x26\x98\x45\x40\x10\x21\x20\xab\xf2\xbb\ +\x19\xb0\xd0\xcd\x64\xc3\x63\xdd\x3f\x3c\x68\x6c\xf5\x68\x82\x59\ +\x04\x04\x11\x02\xb2\xa6\x2b\xcd\xcc\xc8\x52\x7f\x0c\xd7\x6f\x67\ +\xe5\x4a\x63\x2b\x47\xf3\xcb\x22\x20\x88\x10\x90\x35\x35\xae\xfe\ +\x0c\x6e\x34\xb2\xd9\x19\x1e\xeb\x5e\xf7\x3e\xba\xe6\x97\x45\x40\ +\x10\x21\x20\x2b\x32\xbc\x95\xac\x91\x2d\x40\xbf\xa1\x95\x0b\x8d\ +\xad\x1a\x4d\x2f\x8b\x80\x20\x42\x40\xd6\x63\xf8\x79\xba\x05\xdf\ +\x89\xe4\x78\xac\xfb\x87\xaf\x1a\x5c\x31\x9a\x5d\x16\x01\x41\x84\ +\x80\xac\xe7\x48\xf3\x32\xa2\x91\x2d\xc2\xef\xf5\xbb\x85\xde\xc3\ +\xbc\x3c\xcd\x2e\x8b\x80\x20\x42\x40\x56\x73\xa2\x69\x19\x99\xf9\ +\x14\xc5\xd7\x1c\x8f\x75\xdf\xef\x82\x1e\x86\x26\x97\x45\x40\x10\ +\x21\x20\x6b\x31\xfc\x34\xf6\xc2\x37\x91\x0d\x8f\x75\x2f\x7a\xa8\ +\xa2\xe6\x96\x45\x40\x10\x21\x20\x6b\x31\x3c\x92\x76\xe1\x05\x76\ +\x3c\xd6\xbd\xe6\xc3\x09\x35\xb7\x2c\x02\x82\x08\x01\x59\xc9\x93\ +\x26\x65\x64\x81\x53\x14\x5f\x73\x3c\xd6\x7d\xa1\x4f\xe2\x2f\x4b\ +\x53\xcb\x22\x20\x88\x10\x90\x95\x68\x4e\x4e\x16\xff\x39\xe1\x78\ +\xac\xfb\xf2\x19\x5d\x80\xa6\x96\x45\x40\x10\x21\x20\xeb\x78\xd0\ +\x9c\x8c\xac\xf0\x0e\x24\xc7\x63\xdd\x97\x7d\x27\xc1\x32\x34\xb3\ +\x2c\x02\x82\x08\x01\x59\x85\xe1\x19\x26\x6b\xbc\x76\xe3\x78\xac\ +\x7b\xc5\xfb\xe8\x9a\x58\x16\x01\x41\x84\x80\xac\x42\x33\x72\xf2\ +\x45\x43\x5b\x94\xe3\xb1\xee\xeb\xac\xc4\xac\x34\xb1\x2c\x02\x82\ +\x08\x01\x59\x83\xe3\xcf\xcd\x75\x0e\x33\xd7\x6f\xee\xe5\x5c\x83\ +\x2b\x43\xf3\xca\x22\x20\x88\x10\x90\x15\x9c\x6b\x42\x4e\x16\x3b\ +\x45\xf1\x35\xc7\x63\xdd\x3f\x1c\x69\x70\x65\x68\x5e\x59\x04\x04\ +\x11\x02\xb2\x02\xc3\x33\x4c\x56\x7b\xe1\x5f\xbf\xbd\x97\xcf\x1a\ +\x5c\x15\x9a\x56\x16\x01\x41\x84\x80\x2c\xef\x42\xf3\x71\x72\xa2\ +\xb1\x2d\xce\xf1\x58\xf7\x0f\x1f\x0e\x34\xba\x22\x34\xab\x2c\x02\ +\x82\x08\x01\x59\xdc\x57\x4d\xc7\x8a\xc6\xb6\x02\x0d\xc0\xcb\x42\ +\xcf\x65\x5c\x8a\x66\x95\x45\x40\x10\x21\x20\x8b\x73\x3c\x02\x6a\ +\xc5\xcf\x3e\x58\x1e\xeb\x5e\xec\x67\xa6\x26\x95\x45\x40\x10\x21\ +\x20\x4b\xe3\x51\x7c\x7f\x68\xbc\x04\xe7\x51\xeb\xe1\x84\x9a\x54\ +\x16\x01\x41\x84\x80\x2c\xac\x75\x11\x66\xb1\xea\xca\x5a\x1e\xeb\ +\xbe\xe4\xa3\xb5\xe6\xa7\x39\x65\x11\x10\x44\x08\xc8\xc2\x0c\xcf\ +\x30\x59\xfb\xf8\x27\xcb\x63\xdd\x3f\x7c\xd2\xe8\x2a\xd0\x94\xb2\ +\x08\x08\x22\x04\x64\x59\x96\x7f\xdc\x5e\xf9\x83\x73\x96\xc7\xba\ +\x97\x7a\x38\xa1\xa6\x94\x45\x40\x10\x21\x20\xcb\xd2\x54\xac\x3c\ +\x68\x6c\xab\xb1\x3c\xd6\xbd\xc6\x5f\x78\x7f\xd0\x8c\xb2\x08\x08\ +\x22\x04\x64\x51\x5f\x34\x15\x2b\xab\x3f\x01\xc3\xf2\x58\xf7\x4a\ +\xf7\xd1\x35\xa3\x2c\x02\x82\x08\x01\x59\x92\xe3\x19\x26\x0e\x67\ +\x07\x5a\x1e\xeb\xbe\xd6\xe9\x2e\x33\xd0\x84\xb2\x08\x08\x22\x04\ +\x64\x49\x8d\xab\x3d\x8f\x75\x4e\x51\x7c\xc5\xf3\x58\xf7\x0f\x5f\ +\x35\xbc\xe1\x69\x3e\x59\x04\x04\x11\x02\xb2\x20\xc7\x33\x4c\x3c\ +\xfe\x9c\x6d\x79\xac\x7b\x9d\xfb\xe8\x9a\x4f\x16\x01\x41\x84\x80\ +\x2c\xc7\xf3\xa5\x7e\x0d\x6e\x65\x1a\x8c\x99\xbd\x2e\x6f\x63\x9a\ +\x4e\x16\x01\x41\x84\x80\x2c\xc7\xf2\xf3\x0e\xab\x9d\xa2\xf8\x9a\ +\xe5\xb1\xee\x65\x1e\x4e\xa8\xd9\x64\x11\x10\x44\x08\xc8\x62\x3c\ +\xcf\x9d\xd5\xe0\x56\xa7\xe1\x98\x39\xd4\xe8\x06\xa7\xd9\x64\x11\ +\x10\x44\x08\xc8\x52\x1e\x35\x0b\x2f\x36\x2f\xd2\x78\xe6\x75\xfd\ +\xb7\x38\x77\xa1\xc9\x64\x11\x10\x44\x08\xc8\x52\x2c\x3f\x2d\x67\ +\xf4\x59\x07\x8d\xc8\xcc\xca\xa7\xbc\x74\xa2\xc9\x64\x11\x10\x44\ +\x08\xc8\x42\x3c\x4f\x2d\x37\x5a\x52\xcf\x05\xaa\xf1\x70\x42\xcd\ +\x25\x8b\x80\x20\x42\x40\x16\xa2\x39\x78\xb1\xfa\xf3\x75\xe3\xa5\ +\x38\x17\x8d\x6e\x68\x9a\x4a\x16\x01\x41\x84\x80\x2c\xc3\xf3\xb3\ +\xd6\x2b\x9f\xa2\xf8\x9a\xe7\xb1\xee\x0e\x1f\xd4\x6f\xa6\xa9\x64\ +\x11\x10\x44\x08\xc8\x22\xae\x34\x05\x2f\xab\x9f\xa2\xf8\x9a\xe7\ +\xb1\xee\x5e\x95\xcd\xd1\x4c\xb2\x08\x08\x22\x04\x64\x11\x9e\x2f\ +\xcf\x98\x1d\xd5\xe1\x79\xac\xfb\x87\x23\x0d\x6f\x60\x9a\x49\x16\ +\x01\x41\x84\x80\x2c\xe1\x46\x33\xf0\x62\xf7\xe2\x8c\xe7\xb1\xee\ +\x2e\x9f\xb5\x6c\xa0\x89\x64\x11\x10\x44\x08\xc8\x02\x3c\xcf\x30\ +\x71\x38\x45\xf1\x35\xd3\x75\xf2\x5b\xa8\x7d\x69\x1e\x59\x04\x04\ +\x11\x02\xb2\x80\x23\x4d\xc0\x8b\xe1\x69\xe5\x9e\x6f\x35\x70\xbb\ +\x57\xb4\x3f\xcd\x23\x8b\x80\x20\x42\x40\xe6\x77\xa2\xf1\x9b\xd1\ +\xe8\x9c\x98\x1e\xeb\xfe\xe1\x4a\xe3\x1b\x95\xa6\x91\x45\x40\x10\ +\x21\x20\xb3\x33\xfd\xa9\x68\xf9\xca\xbe\xe7\xb1\xee\xc3\x3f\x9c\ +\x50\xd3\xc8\x22\x20\x88\x10\x90\xd9\x79\xde\x1a\x36\xfd\x99\xa8\ +\xd1\xb9\xb9\xd5\xf0\x06\xa5\x59\x64\x11\x10\x44\x08\xc8\xdc\x4c\ +\x8f\xe8\xd8\xeb\x3b\xb7\x1c\xd3\x63\xdd\x3f\x7c\xd2\xf8\xc6\xa4\ +\x49\x64\x11\x10\x44\x08\xc8\xdc\x34\x78\x33\xb6\x2f\xca\x68\x7c\ +\x6e\xc6\x7e\x38\xa1\x26\x91\x45\x40\x10\x21\x20\x33\x33\x7d\x63\ +\x91\xed\x5a\x9a\x1e\xeb\x3e\xea\xeb\xa7\x3f\x68\x0e\x59\x04\x04\ +\x11\x02\x32\x2f\xd3\x03\x9e\x8c\x4f\x29\xd7\x08\xdd\x0c\x7d\x1f\ +\x5d\x73\xc8\x22\x20\x88\x10\x90\x79\x69\xe8\x6e\x8c\xcf\x77\x32\ +\xbd\x67\xe4\xf8\xb1\x99\x9d\x69\x0a\x59\x04\x04\x11\x02\x32\x2b\ +\xd3\xb7\xa5\x5a\x7f\x32\xae\xf1\x92\x9c\xcd\xc0\x0f\x27\xd4\x0c\ +\xb2\x08\x08\x22\x04\x64\x4e\xe7\x1a\xb9\x1b\xb3\x53\x14\x5f\x33\ +\x7d\xd5\x6f\xe4\x87\x13\x6a\x06\x59\x04\x04\x11\x02\x32\x27\xcf\ +\x33\x4c\xdc\x1f\x71\x61\x7a\xac\xfb\x87\x27\x8d\x6f\x3c\x9a\x40\ +\x16\x01\x41\x84\x80\xcc\xe8\x42\x03\x77\x63\x7e\x38\xa0\xe9\xb1\ +\xee\x03\x3f\x9c\x50\xe3\xcf\x22\x20\x88\x10\x90\xf9\x7c\xd5\xb8\ +\xdd\xd8\xdf\x0e\x36\x3d\xd6\x7d\xdc\x87\x13\x6a\xfc\x59\x04\x04\ +\x11\x02\x32\x1f\xd7\x97\x62\x34\x3c\x5f\xae\xc7\xba\x7f\xb8\xd6\ +\x00\x47\xa3\xe1\x67\x11\x10\x44\x08\xc8\x6c\x5c\x3f\x12\x37\xc0\ +\xf3\x91\x4c\x3f\x7d\x39\xec\x7d\x74\x0d\x3f\x8b\x80\x20\x42\x40\ +\xe6\xd2\x3a\xdb\xb9\x8c\xf0\x89\x38\xd7\x63\xdd\x3f\x7c\xd6\x00\ +\x07\xa3\xd1\x67\x11\x10\x44\x08\xc8\x5c\x1e\x34\x6a\x37\x43\xbc\ +\x97\xc8\xf4\xf3\x33\xa3\xde\x47\xd7\xe0\xb3\x08\x08\x22\x04\x64\ +\x26\xae\x9f\x66\x38\xd2\xf8\xcc\x69\xb4\x76\x2e\x35\xbe\xb1\x68\ +\xf0\x59\x04\x04\x11\x02\x32\x13\x8d\xd9\xce\x20\x8b\xe8\x7a\xac\ +\xfb\x98\x3f\x4c\x35\xf6\x2c\x02\x82\x08\x01\x99\x87\xeb\x6b\x30\ +\xc3\xdc\x06\xd6\x78\xed\x0c\xf2\x37\xb8\xd7\x34\xf6\x2c\x02\x82\ +\x08\x01\x99\x85\xeb\x19\x26\xce\xa7\x28\xbe\xe6\xfa\x1e\xb6\x11\ +\xde\xc4\xf6\x17\x0d\x3d\x8b\x80\x20\x42\x40\x66\xd1\xb8\xac\xb3\ +\xb1\x3e\x45\xf1\x35\x8d\xd8\x8f\xf9\xe7\xf8\xdf\xa2\x91\x67\x11\ +\x10\x44\x08\xc8\x1c\x5c\xcf\x30\xf1\x3e\x45\xf1\x35\xd7\x63\xdd\ +\x47\x8a\xf0\x4f\x1a\x79\x16\x01\x41\x84\x80\xcc\xc0\xf6\x93\xd4\ +\x43\x9d\xc5\xe1\xfa\xb7\xb8\x0f\x57\x1a\xe0\x38\x34\xf0\x2c\x02\ +\x82\x08\x01\x99\x81\xeb\x19\x26\x1f\x0e\x34\xc0\x21\xb8\xbe\x11\ +\x7a\xc0\x87\x13\x6a\xe0\x59\x04\x04\x11\x02\xd2\xdf\x89\xc6\x6b\ +\xe7\x42\x03\x1c\x84\x6d\x87\x07\x5b\x47\x02\x82\xd9\x10\x90\xee\ +\x1e\x35\x5c\x3f\x1a\xe0\x28\x6c\x8f\x75\x1f\xe9\x56\xd2\x0b\x0d\ +\x3b\x8b\x80\x20\x42\x40\xba\x73\x3d\x8c\x7c\xbc\x37\xa0\xda\xae\ +\xe4\x99\x06\x38\x0a\x0d\x3b\x8b\x80\x20\x42\x40\x7a\xb3\x7d\xf7\ +\xd0\x78\x2f\xdd\xdb\xbe\x19\x61\xbf\xeb\x7e\x7d\x1a\x75\x16\x01\ +\x41\x84\x80\xf4\xa6\xc1\xfa\x19\xec\x87\xde\x77\xae\xc7\xba\x8f\ +\xf6\x6a\xa0\x06\x9d\x45\x40\x10\x21\x20\x9d\x7d\xd1\x60\xed\x8c\ +\x78\x06\x87\xed\xb1\xee\xfe\x4f\x75\x7c\x45\x83\xce\x22\x20\x88\ +\x10\x90\xbe\x7c\x6f\xfc\x8e\xf7\xe9\x85\x67\xb6\xc7\xba\x7f\x38\ +\xd5\x08\x87\xa0\x31\x67\x11\x10\x44\x08\x48\x5f\x8d\xeb\x39\x9f\ +\x41\x1f\xa6\xa7\xd1\xfb\x19\x6a\x3d\x35\xe6\x2c\x02\x82\x08\x01\ +\xe9\xea\x46\x43\xf5\x33\xe8\xe3\xbc\x6d\x8f\x75\x1f\xe3\xc1\x5c\ +\xa2\x21\x67\x11\x10\x44\x08\x48\x4f\xbe\x6f\x1b\x1a\xf0\x00\xa7\ +\x1f\x34\x7e\x43\x1a\xe0\x08\x34\xe2\x2c\x02\x82\x08\x01\xe9\xe9\ +\x48\x23\xf5\x33\xda\x47\xdf\x7e\xb1\x3d\xd6\x7d\xa4\x83\xc5\x34\ +\xe2\x2c\x02\x82\x08\x01\xe9\xc8\xf6\x0c\x93\xb1\x4e\x51\x7c\x4d\ +\x33\x30\x34\xce\xab\x82\x1a\x70\x16\x01\x41\x84\x80\xf4\xe3\xfb\ +\xa6\xd3\x11\x9f\x61\xf1\x93\xed\x07\x33\x07\x7a\x63\xb4\x06\x9c\ +\x45\x40\x10\x21\x20\xfd\xd8\x9e\xbc\x31\xde\xe9\x7f\xbf\x6b\xbc\ +\x44\x67\x34\xcc\xd9\x30\x1a\x6f\x16\x01\x41\x84\x80\x74\xe3\xfb\ +\x47\xe5\xd1\x4e\x51\x7c\xcd\xf6\x58\xf7\x71\x8e\xc7\xd7\x70\xb3\ +\x08\x08\x22\x04\xa4\x1b\x8d\xd2\xd0\x67\x8d\x70\x50\xb6\xc7\xba\ +\x7f\xb8\xd4\x08\xdd\x69\xb8\x59\x04\x04\x11\x02\xd2\x8b\xef\xb9\ +\x4d\x63\xff\x05\xc4\xf9\xd3\xfd\xa3\xfc\x68\xd5\x68\xb3\x08\x08\ +\x22\x04\xa4\x93\x2b\x0d\xd2\xd0\x5e\xdf\x24\x47\xbe\x37\x97\x06\ +\x39\xe1\x58\xa3\xcd\x22\x20\x88\x10\x90\x4e\x1a\x17\x72\x46\x23\ +\x9e\xa2\xf8\x9a\xef\xe7\x33\x3f\xdc\x6a\x88\xde\x34\xd8\x2c\x02\ +\x82\x08\x01\xe9\xc3\xf7\xd4\xbf\x31\x4f\x51\x7c\xcd\xf8\xe5\xc1\ +\x21\xde\x20\xad\xb1\x66\x11\x10\x44\x08\x48\x17\xd7\x1a\xa2\xa1\ +\xd1\x9e\x9e\xf7\x16\xe3\x4f\xd8\x0c\x71\x46\x8c\xc6\x9a\x45\x40\ +\x10\x21\x20\x5d\xf8\x9e\x61\x32\xea\x29\x8a\xaf\x19\xff\x05\xcf\ +\xfa\x85\x55\xd1\x50\xb3\x08\x08\x22\x04\xa4\x07\xdf\x33\x63\xc7\ +\x3d\x45\xf1\x35\xcd\xc6\xd0\x08\xf7\xd1\x35\xd4\x2c\x02\x82\x08\ +\x01\xe9\xe0\xab\x06\xe8\x68\xd8\x53\x14\x5f\x33\x4e\xf4\x00\x1f\ +\xf3\xd7\x48\xb3\x08\x08\x22\x04\xa4\x03\xdf\xb7\x99\x8e\x7c\x8a\ +\xe2\x6b\x9a\x8f\x23\xff\x46\x6b\xa0\x59\x04\x04\x11\x02\xd2\xce\ +\xf7\xc4\xf1\x71\x0e\xdb\x78\x97\xf1\x22\xfb\xbf\x4d\x41\x03\xcd\ +\x22\x20\x88\x10\x90\x66\xad\xd3\x9a\xd3\xd0\xa7\x28\xbe\xa6\x19\ +\x39\xda\x6b\x17\xac\x41\xe3\xcc\x22\x20\x88\x10\x90\x66\x0f\x1a\ +\x9e\x23\x0d\xb1\x02\xe3\xb3\x2a\xed\x97\x59\xc3\xcc\x22\x20\x88\ +\x10\x90\x56\xc6\x87\xc5\x8e\x73\xde\xf8\x2e\x1a\x2f\xd5\x39\x1d\ +\x6a\x88\xae\x34\xcc\x2c\x02\x82\x08\x01\x69\xa5\xc1\x59\xd2\x10\ +\x6b\x70\x2e\xb5\xf9\x87\x6d\x34\xca\x2c\x02\x82\x08\x01\x69\x64\ +\xfc\x11\x37\xff\xd7\xe6\xf7\xe3\x7b\xac\xfb\x87\x7b\x0d\xd1\x94\ +\x46\x99\x45\x40\x10\x21\x20\x6d\xce\x35\x36\x47\xe3\x9f\xa2\xf8\ +\x9a\xf1\xb1\xee\x1f\x9e\x34\x46\x4f\x1a\x64\x16\x01\x41\x84\x80\ +\xb4\x31\x7e\x61\xbe\xc2\x29\x8a\xaf\x19\x7f\xde\xc6\xfb\xd5\x42\ +\x8d\x31\x8b\x80\x20\x42\x40\x9a\x5c\x68\x68\x8e\x2a\x9c\xa2\xf8\ +\x9a\xf1\xb1\xee\xde\x9f\xd8\xd4\x18\xb3\x08\x08\x22\x04\xa4\x85\ +\xf3\x4f\xb4\x1a\xa7\x28\xbe\x66\x7c\xac\xfb\x87\x73\x8d\xd1\x91\ +\x86\x98\x45\x40\x10\x21\x20\x2d\x8c\x6f\xeb\x56\x39\x45\xf1\x15\ +\xe3\x63\xdd\xad\xef\x38\x69\x88\x59\x04\x04\x11\x02\xd2\xe0\x44\ +\x03\xb3\x54\xe4\x14\xc5\xd7\x9c\xdf\xf3\x66\xfc\xa1\x1b\x8d\x30\ +\x8b\x80\x20\x42\x40\xf2\x1e\x35\x2e\x4b\xee\x9f\x6d\x4b\xd2\xec\ +\x2c\xf9\x3e\x9c\x50\x03\xcc\x22\x20\x88\x10\x90\x3c\xe7\x37\x05\ +\xd5\x39\x45\xf1\x35\xe3\x63\xdd\x3f\x5c\x6a\x8c\x7e\x34\xc0\x2c\ +\x02\x82\x08\x01\x49\x73\x3e\x9c\xa9\xd2\x29\x8a\xaf\x69\x7e\x96\ +\x6c\xdf\x37\xad\xf1\x65\x11\x10\x44\x08\x48\x9a\x46\xe5\x49\x63\ +\xac\xc7\xf9\xec\x7c\xdb\x87\x13\x6a\x7c\x59\x04\x04\x11\x02\x92\ +\xf5\x45\xa3\xb2\x54\xea\x14\xc5\xd7\x34\x43\x4b\xae\x7f\xef\xd3\ +\xf0\xb2\x08\x08\x22\x04\x24\xc9\xf9\x5c\x8d\x21\x9e\xd3\x9d\x65\ +\xfd\xca\xe1\x27\x0d\xd2\x8c\x46\x97\x45\x40\x10\x21\x20\x49\x8d\ +\x0b\x37\xaf\xbd\xbe\x2d\xa3\x39\xd2\x24\x1d\x99\x7e\xfa\x5f\xa3\ +\xcb\x22\x20\x88\x10\x90\x9c\x1b\x8d\xc9\x52\xb5\x53\x14\x5f\x73\ +\x3e\xd6\xdd\xed\x3e\x9d\x68\x70\x59\x04\x04\x11\x02\x92\x72\xad\ +\x21\x79\x2a\x77\x8a\xe2\x6b\xce\x9f\xff\xf7\x7c\xf1\x50\x83\xcb\ +\x22\x20\x88\x10\x90\x14\xe7\x9f\x61\x05\x4f\x51\x7c\xcd\xfa\xf6\ +\xd3\x8d\x06\x69\x45\x63\xcb\x22\x20\x88\x10\x90\x0c\xeb\x33\x4c\ +\x2a\x9e\xa2\xf8\x9a\xf5\x27\x38\x1d\x8f\x90\xd1\xd0\xb2\x08\x08\ +\x22\x04\x24\xc1\xf9\x4c\x3f\xe7\x0f\x44\xf7\x62\x7d\x08\xb2\xe3\ +\xdf\xff\x34\xb4\x2c\x02\x82\x08\x01\x49\xb0\xfe\x13\x70\xcd\x53\ +\x14\x5f\x73\x3e\xd6\x7d\xbf\x3d\xb1\x0c\x8d\x2c\x8b\x80\x20\x42\ +\x40\xf6\xf7\xa4\xf1\x78\x2a\x7a\x8a\xe2\x2b\xde\x7f\x05\xd4\x20\ +\x8d\x68\x60\x59\x04\x04\x11\x02\xb2\x3f\x0d\xc7\x94\x06\x59\x9b\ +\xf3\xb1\xee\x86\x09\xd7\xc0\xb2\x08\x08\x22\x04\x64\x6f\xd6\xaf\ +\x9f\xd4\x3d\x45\xf1\x35\xcd\xd6\x93\xdd\xbb\x18\x34\xae\x2c\x02\ +\x82\x08\x01\xd9\xd7\x95\x46\x63\x4a\xa3\xac\xce\xf9\x58\x77\xbf\ +\x0f\x72\x6a\x5c\x59\x04\x04\x11\x02\xb2\xaf\xc6\x15\x9b\xd9\x67\ +\x8d\xb2\x3c\xcd\xd7\x93\xdb\x77\x41\xc3\xca\x22\x20\x88\x10\x90\ +\x7d\x7d\xb2\xa6\x41\xd6\x77\xa0\x09\x7b\xd2\x20\x5d\x68\x03\x65\ +\x11\x10\x44\x08\x08\x50\x9d\x36\x50\x16\x01\x41\x84\x80\x00\xd5\ +\x69\x03\x65\x11\x10\x44\x08\x08\x50\x9d\x36\x50\x16\x01\x41\x84\ +\x80\x00\xd5\x69\x03\x65\x11\x10\x44\x08\x08\x50\x9d\x36\x50\x16\ +\x01\x41\x84\x80\x00\xd5\x69\x03\x65\x11\x10\x44\x08\x08\x50\x9d\ +\x36\x50\x16\x01\x41\x84\x80\x00\xd5\x69\x03\x65\x11\x10\x44\x08\ +\x08\x50\x9d\x36\x50\x16\x01\x41\x84\x80\x00\xd5\x69\x03\x65\x11\ +\x10\x44\x08\x08\x50\x9d\x36\x50\x16\x01\x41\x84\x80\x00\xd5\x69\ +\x03\x65\x11\x10\x44\x08\x08\x50\x9d\x36\x50\x16\x01\x41\x84\x80\ +\x00\xd5\x69\x03\x65\x11\x10\x44\x08\x08\x50\x9d\x36\x50\x16\x01\ +\x41\x84\x80\x00\xd5\x69\x03\x65\x11\x10\x44\x08\x08\x50\x9d\x36\ +\x50\x16\x01\x41\x84\x80\x00\xd5\x69\x03\x65\x11\x10\x44\x08\x08\ +\x50\x9d\x36\x50\x16\x01\x41\x84\x80\x00\xd5\x69\x03\x65\x1d\x9d\ +\xad\xea\x54\xb3\xc8\xd2\x97\xd9\xa6\x43\x2d\xc2\x5c\x08\x08\x50\ +\x9d\x36\xd0\xa0\xae\x35\x8b\x2c\x7d\x99\x6d\x7a\xd0\x22\xcc\x85\ +\x80\x00\xd5\x69\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ +\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ +\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ +\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ +\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ +\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ +\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ +\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ +\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ +\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ +\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ +\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ +\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ +\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ +\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ +\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ +\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ +\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ +\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ +\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ +\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ +\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ +\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ +\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ +\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ +\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ +\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ +\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ +\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ +\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ +\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ +\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ +\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ +\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ +\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ +\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ +\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ +\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ +\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ +\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ +\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ +\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ +\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ +\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ +\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ +\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ +\x03\x65\x7d\x39\x59\xd5\xa3\x66\x91\xa5\x2f\xb3\x4d\x73\xff\xd0\ +\x24\x20\x40\x75\xda\x40\x59\xdf\xf4\x65\x80\x3f\x11\x10\xa0\x3a\ +\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ +\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ +\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ +\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ +\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ +\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ +\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ +\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ +\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ +\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ +\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ +\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ +\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ +\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ +\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ +\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ +\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ +\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ +\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ +\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ +\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ +\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ +\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ +\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ +\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ +\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ +\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ +\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ +\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ +\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ +\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ +\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ +\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ +\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ +\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ +\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ +\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ +\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ +\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ +\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ +\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ +\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ +\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ +\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ +\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ +\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ +\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ +\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ +\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ +\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ +\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ +\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ +\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ +\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ +\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ +\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ +\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ +\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ +\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ +\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ +\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ +\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ +\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ +\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ +\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ +\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ +\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ +\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ +\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ +\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ +\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ +\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ +\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ +\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ +\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ +\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ +\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ +\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ +\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ +\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ +\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ +\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ +\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ +\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ +\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ +\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ +\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ +\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ +\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ +\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ +\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ +\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ +\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ +\x01\x01\xaa\xd3\x06\xca\xba\xbc\x00\xde\xa6\x4b\x24\x8b\x80\x00\ +\xf6\xb4\x81\x00\x33\x04\x04\xb0\xa7\x0d\x04\x98\x21\x20\x80\x3d\ +\x6d\x20\xc0\xcc\x5e\x3f\xd3\x09\x08\xb0\x06\x6d\x20\xc0\xcc\xb9\ +\xae\xd0\x9d\x10\x10\x60\x0d\xda\x40\x80\x99\x53\x5d\xa1\x3b\x21\ +\x20\xc0\x1a\xb4\x81\x00\x33\x8f\xba\x42\x77\x42\x40\x80\x35\x68\ +\x03\x01\x66\x74\x81\xee\x86\x80\x00\x6b\xd0\x06\x02\xcc\xe8\x02\ +\xdd\x0d\x01\x01\xd6\xa0\x0d\x04\x78\x39\xd3\x05\xba\x1b\x02\x02\ +\xac\x41\x1b\x08\xf0\x72\xa3\x0b\x74\x37\x04\x04\x58\x83\x36\x10\ +\xe0\x65\xaf\xcf\x11\x12\x10\x60\x15\xda\x40\x80\x97\x6b\x5d\xa0\ +\xbb\x21\x20\xc0\x1a\xb4\x81\x00\x2f\xba\x3e\x77\x44\x40\x80\x35\ +\x68\x03\x01\x56\x8e\x74\x7d\xee\x88\x80\x00\x6b\xd0\x06\x02\xac\ +\x5c\xe8\xfa\xdc\x11\x01\x01\xd6\xa0\x0d\x04\x58\xd9\xf3\x49\x65\ +\x04\x04\x58\x83\x36\x10\x60\x45\x97\xe7\xae\x08\x08\xb0\x06\x6d\ +\x20\xc0\xc9\x83\x2e\xcf\x5d\x11\x10\x60\x0d\xda\x40\x80\x93\xfd\ +\x3e\x05\x42\x40\x80\x75\x68\x03\x01\x4e\x74\x75\xee\x8c\x80\x00\ +\x6b\xd0\x06\x02\x8c\xec\xfb\x0a\x16\x01\x01\x56\xa1\x0d\x04\x18\ +\xd9\xfb\xe7\x39\x01\x01\xd6\xa0\x0d\x04\x18\xd1\xc5\xb9\x3b\x02\ +\x02\xac\x41\x1b\x08\xf0\xb1\xe7\xa7\x08\x9f\x11\x10\x60\x0d\xda\ +\x40\x80\x8f\x03\x5d\x9c\xbb\x23\x20\xc0\x1a\xb4\x81\x00\x1b\x87\ +\xba\x36\xf7\xd0\x1a\x90\xa3\x9b\xe3\x53\x7d\x29\x00\xbb\x3a\xd5\ +\x06\x02\x6c\x3c\xea\xe2\xdc\x43\x6b\x40\x5e\xdc\x1d\x3e\xed\x77\ +\x88\x3c\xb0\x71\xc7\xda\x3b\x80\x8b\x2f\xba\x36\xf7\xd1\x25\x20\ +\x2f\xee\x2e\x4f\xce\xf7\x7f\x09\x0d\xd8\xa4\x13\x6d\x1b\xc0\xc5\ +\x27\x5d\x9b\xfb\xe8\x17\x90\x1f\x1e\x6e\xaf\x32\xc3\x00\xb6\xe5\ +\x42\x1b\x06\x30\x91\xf9\x0b\x48\xf7\x80\xbc\x38\xbb\x38\xfe\xaa\ +\xaf\x0f\xe0\x0d\x37\xda\x2b\x80\x09\x5d\x99\xfb\x99\x25\x20\x2f\ +\x8e\x0e\x3f\x72\x7b\x1d\x78\xdb\x17\x6d\x13\xc0\xc3\x67\x5d\x99\ +\xfb\x99\x2f\x20\x2f\xee\xbe\x7c\x3e\xd7\xef\x04\xe0\x97\x43\xed\ +\x10\xc0\xc2\xbd\x2e\xcc\x3d\xcd\x1c\x90\x1f\x1e\x4e\xae\x12\x6f\ +\x10\x03\xea\xe2\x1e\x08\xac\x24\xdf\x47\xbb\x48\x40\x5e\x70\x63\ +\x04\xf8\xe5\x56\xdb\x02\x70\x90\xf8\x0c\xe1\x8b\xe5\x02\xf2\xe2\ +\xe8\xe6\x23\x9f\x18\x01\xf8\x1c\x08\x9c\x24\x5f\xc0\x5a\x3c\x20\ +\x2f\xb8\x31\x82\xcd\xbb\xd6\x66\x00\x0c\xa4\x3f\x7b\xb1\x46\x40\ +\x7e\xb8\x3c\xf9\xc6\x8d\x11\x6c\x96\xb6\x01\xb0\xbe\x7d\x1f\x64\ +\x3b\x59\x2f\x20\x2f\xb8\x31\x82\x8d\xd2\x0e\x00\x56\x97\xbd\x01\ +\xf2\x6c\xe5\x80\xbc\xb8\xbf\xe1\x13\x23\xd8\x1a\x5d\xfc\xc0\xda\ +\xd2\x37\x40\x9e\x39\x04\xe4\x05\x07\x32\x62\x53\x74\xdd\x03\x2b\ +\x3b\xd2\x15\x99\x62\x13\x90\x17\x77\x97\x27\xdf\x38\x90\x11\x5b\ +\xa0\x4b\x1e\x58\xd7\x5d\xd3\x4f\x5c\xaf\x80\xfc\xc0\x81\x8c\xa8\ +\x4f\x17\x3b\xb0\xae\xb6\xdb\x07\x8e\x01\x79\x71\x76\xc3\xed\x75\ +\x14\xa6\xeb\x1c\x58\x55\xe3\x8d\x03\xdb\x80\xbc\x38\xe2\xc6\x08\ +\x8a\xd2\x25\x0e\xac\xe9\x9b\x2e\xc7\x2c\xef\x80\xbc\xf8\x7e\x63\ +\x44\xa3\x05\xaa\xd0\xd5\x0d\xac\xa8\xf9\xed\xaf\x03\x04\xe4\x87\ +\x87\x5b\x0e\x64\x44\x21\xba\xae\x81\xd5\xdc\xb5\xff\x48\x1d\x26\ +\x20\x2f\xf8\xdc\x21\xaa\xd0\x25\x0d\xac\xa5\xe5\xf3\x1f\x3f\x8d\ +\x15\x90\x17\xdc\x18\x41\x01\xba\x9a\x81\x95\x5c\xea\x4a\x6c\x32\ +\x60\x40\x5e\x70\x20\x23\xc6\xa6\x0b\x19\x58\x47\xee\x09\x84\x7f\ +\x1a\x35\x20\x3f\x70\x20\x23\x46\xa5\x4b\x18\x58\xc3\x5d\xa7\xd3\ +\xa3\xc6\x0e\xc8\x0b\x6e\x8c\x60\x40\xba\x7a\x81\x15\x74\x79\xf9\ +\xea\xbb\x02\x01\x79\xc1\x81\x8c\x18\x8b\x2e\x5c\x60\x71\x77\x57\ +\xba\x08\xdb\x1d\xdc\xe9\x6b\x56\xc0\x81\x8c\x18\x86\xae\x59\x60\ +\x69\x17\xba\x04\x7b\x28\x15\x90\x1f\x38\x90\x11\x03\xd0\xd5\x0a\ +\x2c\xeb\xac\xeb\x41\x83\x07\x67\xfa\xb2\xc5\x70\x20\x23\xbc\xe9\ +\x42\x05\x96\x74\xdf\xf9\x54\x8f\x83\x43\x7d\xe1\x8a\xee\x6f\x8e\ +\xb9\x31\x02\x4f\xba\x46\x81\xe5\x9c\x75\xff\xec\xc3\xc1\x89\xbe\ +\x74\x59\x7c\xee\x10\x8e\x74\x79\x02\x4b\x79\x98\xe1\x07\xe1\xc1\ +\x37\x7d\xf1\xe2\x2e\x4f\xce\xb9\x31\x02\x23\xba\x30\x81\x65\xdc\ +\xce\xf2\x91\xb9\x83\x2d\x5d\xc8\xdc\x18\x81\x0d\x5d\x93\xc0\x02\ +\x6e\xe6\x7a\x15\xe6\xe0\xbf\x7a\x6f\xc3\xfa\x37\x3e\x77\x08\x07\ +\xba\x1c\x81\x99\x9d\x9d\xcc\x78\x27\xf8\xe0\xbf\x0b\xfd\x36\x9b\ +\x72\x74\xc8\xe7\x0e\xb1\x2a\x5d\x89\xc0\x7c\x8e\x0e\x3f\xcf\x7c\ +\x03\xf8\xe0\xbf\x6b\xfd\x5e\xdb\xc3\x81\x8c\x58\x8f\x2e\xc2\xac\ +\xfb\x07\x20\xf2\xe5\xf0\xf6\xf3\xc7\xeb\x25\xce\x09\x3c\xf8\x6f\ +\x73\xaf\x61\xfd\xe1\xf2\x84\x27\x55\x61\x79\xba\xfc\xb2\x78\x48\ +\x27\x1c\x3c\x07\xa4\xfc\x1b\x79\x77\xc0\x8d\x11\x2c\x4c\x57\x5e\ +\x16\x01\x81\x83\xe7\x80\x54\x39\x4f\xb1\x19\x07\x32\x62\x39\xba\ +\xe8\xb2\x08\x08\x1c\x7c\xff\x70\xc4\x8d\xae\x49\x3c\xe3\xc6\x08\ +\x16\xa1\xeb\x2d\x8b\x80\xc0\xc1\xf7\x80\xf0\x57\x90\xbf\x70\x20\ +\x23\x66\xa6\x2b\x2d\x8b\x80\xc0\xc1\xcb\x8f\xc9\x4d\xbe\x93\xf7\ +\x7d\x67\x17\xc7\x7c\xee\x10\x33\xd1\x45\x96\x45\x40\xe0\xe0\xc7\ +\x9f\xb3\x37\xfe\x46\xac\x7f\xe1\xc6\x08\x66\xa1\xeb\x2b\x8b\x80\ +\xc0\xc1\x8f\x80\x9c\xeb\xaa\xc4\xdb\xee\x66\xff\x3c\x0e\xb6\x46\ +\x97\x56\x16\x01\x81\x03\xbd\xd2\xcf\x8b\x58\xef\xbb\xe3\x40\x46\ +\xf4\xa3\xab\x2a\x8b\x80\xc0\xc1\xcf\x9f\x88\x0f\xba\x2e\xf1\x0e\ +\x0e\x64\x44\x17\xba\x9e\xb2\x08\x08\x1c\xfc\xfa\x23\xf5\xbd\x2e\ +\x4c\xec\xe0\xec\x86\xcf\x1d\xa2\x8d\x2e\xa5\x2c\x02\x02\x07\xd3\ +\x6b\x32\xdc\x48\xdf\x13\x07\x32\xa2\x81\xae\xa2\x2c\x02\x02\x07\ +\xbf\xbd\xa8\x7f\xa4\x4b\x13\x7b\xe0\x73\x87\xc8\xd1\x05\x94\x45\ +\x40\xe0\xe0\xf7\xbb\xc2\x67\xba\x36\xb1\xaf\x07\x0e\x64\xc4\x9e\ +\x74\xe9\x64\x11\x10\x38\xf8\x3d\x20\xff\x1d\xea\xe2\x44\x06\x07\ +\x32\x62\x0f\xba\x6a\xb2\x08\x08\x1c\xbc\x0a\xc8\x7f\x57\xba\x3a\ +\x91\x75\x7f\xf3\x91\x4f\x8c\x60\x07\xba\x60\xb2\x08\x08\x1c\xbc\ +\x0e\xc8\x7f\xff\x7d\xd1\xf5\x89\x06\xdc\x18\xc1\xbb\x74\xad\x64\ +\x11\x10\x38\xf8\x33\x20\xff\x9d\x72\x27\xa4\x93\xcb\x93\x6f\xdc\ +\x18\x41\x44\x57\x49\x16\x01\x81\x83\xbf\x02\xf2\x9c\x10\xfe\x16\ +\xd2\x0f\x37\x46\xf0\x36\x5d\x20\x59\x04\x04\x0e\xde\x08\xc8\xb3\ +\x8f\x7c\x30\xbd\x27\x0e\x64\xc4\x5f\x74\x6d\x64\x11\x10\x38\x78\ +\x3b\x20\xcf\xae\x4f\x2e\x75\xa9\xa2\x8b\xbb\xc3\x27\x6e\xaf\xe3\ +\x17\x5d\x16\x59\x04\x04\x0e\xc2\x80\xbc\xb8\x7e\x3a\xe4\x03\xea\ +\x3d\xdd\xf1\xa4\x2a\xfc\xa0\x2b\x22\x8b\x80\xc0\xc1\x0e\x3f\xcd\ +\x4e\x3f\xde\x70\x50\x56\x57\x1c\xc8\x08\x02\x82\x0a\x76\xfd\xe3\ +\xf0\xa7\xab\x5b\xee\x8b\x74\x75\x76\x73\xcc\x8d\x91\x0d\xd3\x65\ +\x90\x45\x40\xe0\x60\xaf\xd7\x53\x0e\xce\x3f\x5f\xf2\x92\x56\x4f\ +\x47\xdc\x18\xd9\x2a\x5d\x01\x59\x04\x04\x0e\x12\x2f\xc8\x5f\x3f\ +\x1d\x72\xee\x62\x4f\xdf\x9f\x54\xa5\xb5\xc5\x66\xe8\x9b\x9f\x45\ +\x40\xe0\x20\x7b\x47\xf7\xeb\xf1\x05\x9f\x38\xec\xea\xe1\x96\x03\ +\x19\xb7\x44\xdf\xf6\x2c\x02\x02\x07\xd9\x80\xbc\xe0\xc6\x48\x6f\ +\x7c\xee\x70\x33\xf4\x1d\xcf\x22\x20\x70\xd0\x14\x90\x1f\xce\x3f\ +\x7f\xe1\xc6\x48\x4f\xdc\x18\xd9\x02\x7d\xb3\xb3\x08\x08\x1c\x74\ +\x08\xc8\x8b\xeb\x8f\xdc\x18\xe9\x8a\x03\x19\x8b\xd3\xf7\x39\x8b\ +\x80\xc0\x41\xaf\x80\xbc\xe0\xc6\x48\x6f\x1c\xc8\x58\x96\xbe\xc3\ +\x59\x04\x04\x0e\xba\x06\xe4\xc5\xe3\x37\x0e\x41\xe9\x8b\x1b\x23\ +\x15\xe9\x9b\x9b\x45\x40\xe0\xa0\x7f\x40\x7e\xe0\xc6\x48\x67\x1c\ +\xc8\x58\x8c\xbe\xaf\x59\x04\x04\x0e\xe6\x0a\xc8\x0b\x0e\x41\xe9\ +\xec\xee\x0b\xb7\xd7\xab\xd0\xb7\x34\x8b\x80\xc0\xc1\xac\x01\x79\ +\xf1\xe9\xea\x96\x1b\x23\x5d\x71\x20\x63\x05\xfa\x66\x66\x11\x10\ +\x38\x58\xe8\x27\xd1\xc1\xb7\x13\x0e\x41\xe9\xea\x8c\x03\x19\xc7\ +\xa6\xef\x63\x16\x01\x81\x83\x45\xff\x28\xcb\x21\x28\x9d\xdd\x73\ +\x20\xe3\xb0\xf4\x2d\xcc\x22\x20\x70\xb0\xfc\x6b\x21\xa7\xc7\x37\ +\xbc\xa4\xd5\x13\x4f\xaa\x1a\x92\xbe\x7b\x59\x04\x04\x0e\x56\x7a\ +\x31\x9d\x43\x50\x3a\xfb\x7e\x20\x23\x37\x46\x46\xa2\x6f\x5c\x16\ +\x01\x81\x83\x55\x7f\xe8\x70\x3a\x7c\x67\x3c\xa9\x6a\x1c\xfa\x96\ +\x65\x11\x10\x38\x58\xff\x4f\xad\xa7\x1c\x82\xd2\x17\x9f\x3b\x1c\ +\x82\xbe\x5b\x59\x04\x04\x0e\x4c\x5e\xf6\xe0\x10\x94\xce\x8e\x0e\ +\xf9\xdc\xa1\x37\x7d\xa3\xb2\x08\x08\x1c\x38\xbd\x6e\xfe\x78\xc5\ +\x21\x28\x5d\x71\x20\xa3\x31\x7d\x8f\xb2\x08\x08\x1c\xf8\xdd\x78\ +\xe5\x10\x94\xce\x2e\x4f\x78\x52\x95\x21\x7d\x77\xb2\x08\x08\x1c\ +\xf8\x05\xe4\xc5\xe9\xc7\x43\x0e\x41\xe9\x89\x1b\x23\x6e\xf4\x8d\ +\xc9\x22\x20\x70\x60\x1a\x90\x17\xdc\x18\xe9\xec\xfe\xe6\x23\x9f\ +\x18\x71\xa1\xef\x49\x16\x01\x81\x03\xe7\x80\xbc\xe0\x10\x94\xce\ +\xb8\x31\xe2\x41\xdf\x8e\x2c\x02\x02\x07\xf6\x01\xf9\xe1\xfa\xe9\ +\x90\x8a\xf4\xc4\x93\xaa\xd6\xa6\x6f\x44\x16\x01\x81\x83\x41\x02\ +\xf2\x82\x43\x50\x3a\x3b\xbb\x38\xe6\x73\x87\x6b\xd1\xf7\x20\x8b\ +\x80\xc0\xc1\x48\x01\x79\xc1\x21\x28\x9d\xf1\xa4\xaa\x75\x68\xf9\ +\xb3\x08\x08\x1c\x0c\x17\x90\x17\x07\xe7\xdc\x18\xe9\x8a\x03\x19\ +\x17\xa7\x95\xcf\x22\x20\x70\x30\x66\x40\x7e\xe0\x10\x94\xbe\x38\ +\x90\x71\x49\x5a\xf4\x2c\x02\x02\x07\xc3\xff\xc0\xe0\xbd\xbe\x9d\ +\x71\x20\xe3\x32\xb4\xdc\x59\x04\x04\x0e\x6a\xfc\x89\x93\x43\x50\ +\x3a\x3b\xbb\xf9\xc8\xe7\x0e\xe7\xa5\x95\xce\x22\x20\x70\x50\xe9\ +\x25\x0b\x0e\x41\xe9\x8b\x03\x19\xe7\xa4\x45\xce\x22\x20\x70\x50\ +\xee\x35\xef\xeb\x8f\x37\x1c\x82\xd2\xd1\xdd\x25\x9f\x3b\x9c\x85\ +\xd6\x37\x8b\x80\xc0\x41\xcd\x9b\xa6\xdc\x18\xe9\xec\xe1\x96\x03\ +\x19\x3b\xd3\xca\x66\x11\x10\x38\xa8\x19\x90\x17\x8f\xdf\xb8\x31\ +\xd2\x15\x07\x32\xf6\xa4\x45\xcd\x22\x20\x70\x50\x38\x20\x3f\x70\ +\x08\x4a\x5f\x47\x1c\xc8\xd8\x87\xd6\x33\x8b\x80\xc0\x41\xf9\x80\ +\xbc\x38\x3d\xe6\xc6\x48\x4f\x1c\xc8\xd8\x4e\x4b\x99\x45\x40\xe0\ +\x60\x1b\x01\x79\xc1\x21\x28\x9d\x3d\x70\x20\x63\x03\x2d\x62\x16\ +\x01\x81\x83\x0d\x05\xe4\x05\x87\xa0\x74\xc6\x8d\x91\x24\xad\x5f\ +\x16\x01\x81\x83\xad\x05\xe4\x87\xeb\x27\x0e\x41\xe9\x89\x03\x19\ +\xf7\xa7\xa5\xcb\x22\x20\x70\xb0\xcd\x80\xbc\xe0\xbd\xbe\x7d\x71\ +\x20\xe3\x5e\xb4\x6a\x59\x04\x04\x0e\x36\x1c\x90\x17\x8f\x57\x27\ +\xdc\x18\xe9\xe8\xee\xf2\xe4\xdb\xd6\xaf\xa9\xdd\x68\xc1\xb2\x08\ +\x08\x1c\xb0\xd9\xbf\xe3\x10\x94\xbe\x38\x90\xf1\x7d\x5a\xaa\x2c\ +\x02\x02\x07\x04\xe4\x17\x0e\x41\xe9\xeb\xec\xe6\x98\x1b\x23\x31\ +\xad\x52\x16\x01\x81\x03\x02\xf2\x1a\x37\x46\xfa\x3a\xe2\xc6\x48\ +\x40\x0b\x94\x45\x40\xe0\x80\x80\xbc\x81\x43\x50\xfa\xe2\x49\x55\ +\x6f\xd0\xda\x64\x11\x10\x38\x60\x5f\x87\x38\x04\xa5\x2f\x0e\x64\ +\x7c\x45\xab\x92\x45\x40\xe0\x80\x80\xfc\xdb\x29\x37\x46\xba\xe2\ +\x73\x87\x3f\x69\x41\xb2\x08\x08\x1c\x10\x90\x1d\x70\x08\x4a\x5f\ +\x3c\xa9\xea\x99\xd6\x22\x8b\x80\xc0\x01\x01\xd9\xd5\xc1\x37\x0e\ +\x41\xe9\x69\xeb\x07\x32\x6a\x19\xb2\x08\x08\x1c\x10\x90\xfd\x70\ +\x08\x4a\x5f\x97\x27\x5b\xbd\x31\xa2\x05\xc8\x22\x20\x70\x40\x40\ +\x12\x78\xaf\x6f\x5f\x9b\xbc\x31\xa2\xb9\x67\x11\x10\x38\x20\x20\ +\x59\xdc\x18\xe9\x6b\x6b\x07\x32\x6a\xda\x59\x04\x04\x0e\x08\x48\ +\x1b\x0e\x41\xe9\xea\xee\xcb\xe7\xad\x7c\xee\x50\x33\xce\x22\x20\ +\x70\x40\x40\x3a\x38\xfd\xc8\x8d\x91\x9e\x36\x71\x20\xa3\xe6\x9a\ +\x45\x40\xe0\x80\x80\xf4\xc2\x8d\x91\xbe\xce\x8a\x1f\xc8\xa8\x69\ +\x66\x11\x10\x38\x20\x20\x5d\x3d\x7e\xe3\x74\xf8\x9e\xee\xeb\x1e\ +\xc8\xa8\x19\x66\x11\x10\x38\x20\x20\x33\xe0\xc6\x48\x57\x35\x9f\ +\x54\xa5\xc9\x65\x11\x10\x38\x20\x20\x73\xe1\x10\x94\xae\xca\x1d\ +\xc8\xa8\x79\x65\x11\x10\x38\x20\x20\xb3\xfa\xc4\x8d\x91\xae\x0a\ +\x3d\xa9\x4a\x33\xca\x22\x20\x70\x40\x40\xe6\xc7\x21\x28\x7d\xd5\ +\xf8\xdc\xa1\x26\x93\x45\x40\xe0\x80\x80\x2c\x85\xd3\xe1\xbb\x1a\ +\xfe\x40\x46\xcd\x23\x8b\x80\xc0\x01\x01\x59\xd4\xe9\xf1\x0d\x2f\ +\x69\xf5\x33\xf2\x81\x8c\x9a\x42\x16\x01\x81\x03\x02\xb2\x3c\x0e\ +\x41\xe9\x6b\xcc\x03\x19\x35\xf8\x2c\x02\x02\x07\x04\x64\x2d\xe7\ +\xdc\x18\xe9\x69\xb8\x1b\x23\x1a\x77\x16\x01\x81\x03\x02\xb2\x2a\ +\x0e\x41\xe9\xea\xfe\xe6\xe3\x30\x9f\x18\xd1\x90\xb3\x08\x08\x1c\ +\x10\x90\xf5\x71\x08\x4a\x57\x83\xdc\x18\xd1\x68\xb3\x08\x08\x1c\ +\x10\x10\x13\x8f\x57\x27\x97\xfa\xd9\x80\x0e\x2e\x4f\xbe\x79\xdf\ +\x18\xd1\x38\xb3\x08\x08\x1c\x10\x10\x2b\x1c\x82\xd2\x95\xf3\x8d\ +\x11\x0d\x31\x8b\x80\xc0\x01\x01\xf1\xc3\x21\x28\x5d\x99\x3e\xa9\ +\x4a\xa3\xcb\x22\x20\x70\x40\x40\x4c\x71\x63\xa4\x2b\xbf\x03\x19\ +\x35\xb0\x2c\x02\x02\x07\x04\xc4\xd9\xf7\x43\x50\xf4\x03\x03\xed\ +\xee\x9c\x9e\x54\xa5\x31\x65\x11\x10\x38\x20\x20\xfe\x38\x04\xa5\ +\xab\x87\xdb\x63\x87\x03\x19\x35\x9a\x2c\x02\x02\x07\x04\x64\x10\ +\x1c\x82\xd2\xd5\xd9\xcd\xda\xb7\xd7\x35\x90\x2c\x02\x02\x07\x04\ +\x64\x24\x1c\x82\xd2\xd5\xd1\xe1\xd3\x7a\xb7\xd7\x35\x86\x2c\x02\ +\x02\x07\x04\x64\x38\x07\x1c\x82\xd2\xd3\xf7\x27\x55\x69\x65\x17\ +\xa5\xdf\x3e\x8b\x80\xc0\x01\x01\x19\x14\x87\xa0\x74\xf5\x70\xbb\ +\xf4\x81\x8c\xfa\x8d\xb3\x08\x08\x1c\x10\x90\x91\xf1\x5e\xdf\xae\ +\x16\xfd\xdc\xa1\x7e\xcf\x2c\x02\x02\x07\x04\x64\x78\x1c\x82\xd2\ +\xd5\xd1\xe1\x32\x07\x32\xea\xb7\xcb\x22\x20\x70\x40\x40\x8a\xe0\ +\x10\x94\x9e\x16\x38\x90\x51\xbf\x53\x16\x01\x81\x03\x02\x52\xc9\ +\x35\x87\xa0\xf4\x34\xeb\x81\x8c\xfa\x3d\xb2\x08\x08\x1c\x10\x90\ +\x72\xb8\x31\xd2\xd5\x5c\x37\x46\xf4\xe5\xb3\x08\x08\x1c\x10\x90\ +\x9a\x1e\x39\x04\xa5\xa7\x19\x0e\x64\xd4\x57\xce\x22\x20\x70\x40\ +\x40\x2a\xe3\x10\x94\x9e\xfa\x1e\xc8\xa8\x2f\x9a\x45\x40\xe0\x80\ +\x80\x94\xc7\xe9\xf0\x5d\xf5\x3a\x90\x51\x5f\x2e\x8b\x80\xc0\x01\ +\x01\xd9\x06\x0e\x41\xe9\xea\xe1\xf6\xaa\xf5\x40\x46\x7d\xa5\x2c\ +\x02\x02\x07\x04\x64\x43\x38\x04\xa5\xab\xb3\x9b\xe3\x86\x1b\x23\ +\xfa\x22\x59\x04\x04\x0e\x08\xc8\xe6\x5c\x3f\x71\x08\x4a\x3f\x47\ +\xd9\x1b\x23\xfa\xef\xb3\x08\x08\x1c\x10\x90\x6d\xe2\xbd\xbe\x3d\ +\x7d\x3f\x90\x71\xdf\x9d\xa4\xff\x34\x8b\x80\xc0\x01\x01\xd9\xb0\ +\x47\x6e\x8c\xf4\xb4\xdf\x8d\x11\xfd\x47\x59\x04\x04\x0e\x08\xc8\ +\xe6\x71\x08\x4a\x4f\x3b\x7f\xee\x50\xbf\x3e\x8b\x80\xc0\x01\x01\ +\xc1\x77\xd7\x1f\x6f\xb8\x31\xd2\xcd\xd1\xe1\xfb\x9f\x3b\xd4\x2f\ +\xcd\x22\x20\x70\x40\x40\xf0\x0b\x37\x46\x7a\x7a\xe7\x40\x46\xfd\ +\xaa\x2c\x02\x02\x07\x04\x04\xaf\x71\x08\x4a\x57\x97\x27\xc1\x93\ +\xaa\xf4\xef\xb3\x08\x08\x1c\x10\x10\xbc\x85\x1b\x23\x3d\x9d\x5d\ +\x1c\xff\x75\x7b\x5d\xff\x2a\x8b\x80\xc0\x01\x01\x41\x88\x43\x50\ +\x7a\xfa\xe3\x40\x46\xfd\xd3\x2c\x02\x02\x07\x04\x04\xff\xc6\x21\ +\x28\x3d\xdd\x7d\xf9\xac\xcf\x1d\xea\x1f\x64\x11\x10\x38\x20\x20\ +\xd8\xc1\xc1\x37\x0e\x41\xe9\xe8\xf2\xe4\xdb\xa9\xfe\x67\x16\x01\ +\x81\x03\x02\x82\x9d\x71\x08\x8a\x0f\x02\x02\x07\x04\x04\xfb\xf9\ +\x7a\x7c\xc3\x7b\x7d\xd7\x47\x40\xe0\x80\x80\x20\x81\x1b\x23\x6b\ +\x23\x20\x70\x40\x40\x90\xc6\x7b\x7d\xd7\x43\x40\xe0\x80\x80\xa0\ +\xcd\xe9\x47\x6e\x8c\xac\x80\x80\xc0\x01\x01\x41\x07\x1c\x82\xb2\ +\x34\x02\x02\x07\x04\x04\xbd\x3c\x5e\x71\x08\xca\x62\x08\x08\x1c\ +\x10\x10\xf4\xc5\x8d\x91\x45\x10\x10\x38\x20\x20\x98\x01\x87\xa0\ +\xcc\x8d\x80\xc0\x01\x01\xc1\x5c\xb8\x31\x32\x23\x02\x02\x07\x04\ +\x04\xb3\xe2\x10\x94\x79\x10\x10\x38\x20\x20\x58\xc0\xf5\xd3\x21\ +\x15\xe9\x8a\x80\xc0\x01\x01\xc1\x52\x4e\x39\x04\xa5\x1f\x02\x02\ +\x07\x04\x04\x8b\xe2\x10\x94\x3e\x08\x08\x1c\x10\x10\x2c\xef\xe0\ +\x9c\x1b\x23\x8d\x08\x08\x1c\x10\x10\xac\x85\x43\x50\x1a\x10\x10\ +\x38\x20\x20\x58\x15\xef\xf5\xcd\x21\x20\x70\x40\x40\xb0\x3e\x0e\ +\x41\xd9\x1b\x01\x81\x03\x02\x02\x17\x1c\x82\xb2\x07\x02\x02\x07\ +\x04\x04\x56\xae\x39\x04\x65\x27\x04\x04\x0e\x08\x08\xfc\x70\x63\ +\xe4\x5d\x04\x04\x0e\x08\x08\x4c\x7d\x3f\x04\x45\x3f\x2d\xf1\x17\ +\x02\x02\x07\x04\x04\xd6\x38\x04\xe5\x6d\x04\x04\x0e\x08\x08\xfc\ +\x71\x08\xca\x5f\x08\x08\x1c\x10\x10\x0c\x82\x43\x50\x7e\x47\x40\ +\xe0\x80\x80\x60\x24\x1c\x82\x22\x04\x04\x0e\x08\x08\xc6\x73\xfa\ +\xb4\xf9\x43\x50\x08\x08\x1c\x10\x10\x0c\x6a\xdb\xef\xf5\x25\x20\ +\x70\x40\x40\x30\xb2\xcd\x1e\x82\x42\x40\xe0\x80\x80\x60\x7c\x1b\ +\x3c\x04\x85\x80\xc0\x01\x01\x41\x11\xdb\x3a\x04\x85\x80\xc0\x01\ +\x01\x41\x25\x9b\xb9\x31\x42\x40\xe0\x80\x80\xa0\x9c\xc7\x0d\x1c\ +\x82\x42\x40\xe0\x80\x80\xa0\xa8\xda\x87\xa0\x10\x10\x38\x20\x20\ +\xa8\xec\xb4\xea\x8d\x11\x02\x02\x07\x04\x04\xe5\x55\x3c\x04\x85\ +\x80\xc0\x01\x01\xc1\x36\x14\x3b\x04\x85\x80\xc0\x01\x01\xc1\x96\ +\x5c\x57\x39\x04\xe5\x5c\x13\x02\xd6\x44\x40\xb0\x39\x15\xde\xeb\ +\x7b\xaa\xb9\x00\x6b\x22\x20\xd8\xa6\xc1\x6f\x8c\x7c\xd2\x34\x80\ +\x35\x11\x10\x6c\xd9\xb0\x87\xa0\x68\xfc\xc0\xaa\x08\x08\x36\xef\ +\xfa\xe3\x78\x37\x46\x34\x74\x60\x55\x04\x04\xf8\x6e\xac\x1b\x23\ +\x67\x1a\x35\xb0\x2a\x02\x02\xfc\x32\xcc\x21\x28\x37\x1a\x30\xb0\ +\x2a\x02\x02\xfc\x61\x80\x1b\x23\xc7\x1a\x2a\xb0\x2a\x02\x02\xbc\ +\xc5\xfb\x10\x14\xf6\x2d\x2c\x70\x21\x02\xa1\x4f\x57\xb7\x96\x37\ +\x46\x8e\x34\x3e\x60\x5d\x04\x04\xf8\xb7\x83\x6f\x76\x87\xa0\x9c\ +\x68\x68\xc0\xba\x08\x08\xb0\x0b\xab\x43\x50\x1e\x35\x28\x60\x5d\ +\x04\x04\xd8\xd9\xe9\xf1\x8d\xc3\x4b\x5a\x0f\x1a\x0e\xb0\x32\x02\ +\x02\xec\x67\xfd\x43\x50\x38\x49\x11\x26\x08\x08\x90\x71\xfe\x79\ +\xb5\x1b\x23\x7c\x8a\x10\x2e\x08\x08\x90\x76\xba\xca\x21\x28\xd7\ +\xfa\xdd\x81\xb5\x11\x10\xa0\xcd\xd2\x87\xa0\x5c\xea\xf7\x05\x56\ +\x47\x40\x80\x0e\x1e\xaf\x16\x3b\x04\x45\xbf\x23\xb0\x3e\x02\x02\ +\x74\xb3\xc4\x21\x28\x9c\x62\x02\x1f\x04\x04\xe8\x6b\xde\x43\x50\ +\x0e\xf5\xbb\x00\x06\x08\x08\x30\x83\xb9\x6e\x8c\xf0\x0e\x2c\x38\ +\x21\x20\xc0\x5c\xfa\x1f\x82\xc2\x21\x58\xb0\x42\x40\x80\x79\x5d\ +\x3f\x1d\xf6\xaa\xc8\x11\xfb\x15\x56\xb8\x20\x81\x05\x74\x39\x04\ +\xe5\x5e\x5f\x0c\x30\x41\x40\x80\xa5\x34\x1e\x82\xc2\xfd\x0f\xb8\ +\x21\x20\xc0\xa2\x0e\xce\x93\x37\x46\x6e\xf5\x05\x00\x1b\x04\x04\ +\x58\xc1\xde\x87\xa0\xdc\x71\x80\x09\xfc\x10\x10\x60\x2d\x7b\xbc\ +\xd7\x97\x47\x48\xc1\x11\x01\x01\x56\xb5\xcb\x21\x28\x17\xfa\xb5\ +\x80\x17\x02\x02\x18\xf8\xc7\x21\x28\x47\x1f\xf5\x6b\x00\x37\x04\ +\x04\x70\x71\xfd\xf7\x21\x28\x67\x9f\x3f\xe9\x5f\x02\x7e\x08\x08\ +\x60\xe5\xeb\xb7\xa7\x9b\xcb\x87\x87\xb3\x2f\x37\x27\xc7\x5f\xf5\ +\xcf\x00\x4f\x04\x04\x00\x90\x42\x40\x00\x00\x29\x04\x04\x00\x90\ +\x42\x40\x00\x00\x29\x04\x04\x00\x90\x42\x40\x00\x00\x29\x04\x04\ +\x00\x90\x42\x40\x00\x00\x29\x04\x04\x00\x90\x42\x40\x00\x00\x29\ +\x04\x04\x00\x90\x42\x40\x00\x00\x29\x04\x04\x00\x90\xf0\xdf\x7f\ +\xff\x03\x6a\xf8\x3b\x61\xbf\x6a\xd6\x0d\x00\x00\x00\x00\x49\x45\ +\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x07\x0a\ +\x3c\ +\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x69\x73\x6f\ +\x2d\x38\x38\x35\x39\x2d\x31\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\ +\x20\x47\x65\x6e\x65\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\ +\x65\x20\x49\x6c\x6c\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\ +\x2e\x30\x2e\x30\x2c\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\ +\x20\x50\x6c\x75\x67\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\ +\x65\x72\x73\x69\x6f\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\ +\x6c\x64\x20\x30\x29\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\ +\x43\x54\x59\x50\x45\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\ +\x20\x22\x2d\x2f\x2f\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\ +\x47\x20\x31\x2e\x31\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\ +\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\ +\x61\x70\x68\x69\x63\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\ +\x54\x44\x2f\x73\x76\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\ +\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ +\x31\x22\x20\x69\x64\x3d\x22\x43\x61\x70\x61\x5f\x31\x22\x20\x78\ +\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ +\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ +\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\ +\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\ +\x2f\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\ +\x30\x70\x78\x22\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\ +\x77\x69\x64\x74\x68\x3d\x22\x34\x38\x38\x2e\x34\x34\x36\x70\x78\ +\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x34\x38\x38\x2e\x34\x34\ +\x36\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\ +\x30\x20\x34\x38\x38\x2e\x34\x34\x36\x20\x34\x38\x38\x2e\x34\x34\ +\x36\x22\x20\x73\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\ +\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\ +\x30\x20\x30\x20\x34\x38\x38\x2e\x34\x34\x36\x20\x34\x38\x38\x2e\ +\x34\x34\x36\x3b\x22\x0d\x0a\x09\x20\x78\x6d\x6c\x3a\x73\x70\x61\ +\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\ +\x3c\x67\x3e\x0d\x0a\x09\x3c\x67\x3e\x0d\x0a\x09\x09\x3c\x67\x3e\ +\x0d\x0a\x09\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\ +\x35\x33\x2e\x30\x32\x39\x2c\x39\x30\x2e\x32\x32\x33\x68\x31\x38\ +\x32\x2e\x34\x30\x34\x63\x35\x2e\x34\x32\x37\x2c\x30\x2c\x39\x2e\ +\x38\x37\x33\x2d\x34\x2e\x34\x33\x2c\x39\x2e\x38\x37\x33\x2d\x39\ +\x2e\x38\x36\x39\x56\x30\x48\x31\x34\x33\x2e\x31\x33\x37\x76\x38\ +\x30\x2e\x33\x35\x34\x43\x31\x34\x33\x2e\x31\x33\x37\x2c\x38\x35\ +\x2e\x37\x39\x33\x2c\x31\x34\x37\x2e\x35\x37\x31\x2c\x39\x30\x2e\ +\x32\x32\x33\x2c\x31\x35\x33\x2e\x30\x32\x39\x2c\x39\x30\x2e\x32\ +\x32\x33\x0d\x0a\x09\x09\x09\x09\x7a\x22\x2f\x3e\x0d\x0a\x09\x09\ +\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x38\x30\x2e\x38\ +\x31\x37\x2c\x31\x32\x32\x2e\x38\x36\x34\x4c\x33\x37\x37\x2e\x38\ +\x38\x2c\x31\x39\x2e\x34\x39\x34\x76\x36\x30\x2e\x38\x35\x39\x63\ +\x30\x2c\x32\x33\x2e\x34\x30\x34\x2d\x31\x39\x2e\x30\x34\x33\x2c\ +\x34\x32\x2e\x34\x34\x37\x2d\x34\x32\x2e\x34\x34\x37\x2c\x34\x32\ +\x2e\x34\x34\x37\x48\x31\x35\x33\x2e\x30\x32\x39\x0d\x0a\x09\x09\ +\x09\x09\x63\x2d\x32\x33\x2e\x34\x30\x39\x2c\x30\x2d\x34\x32\x2e\ +\x34\x34\x37\x2d\x31\x39\x2e\x30\x34\x33\x2d\x34\x32\x2e\x34\x34\ +\x37\x2d\x34\x32\x2e\x34\x34\x37\x56\x30\x48\x34\x34\x2e\x38\x32\ +\x33\x43\x32\x30\x2e\x30\x36\x38\x2c\x30\x2c\x30\x2e\x30\x30\x32\ +\x2c\x32\x30\x2e\x30\x37\x2c\x30\x2e\x30\x30\x32\x2c\x34\x34\x2e\ +\x38\x30\x38\x76\x33\x39\x38\x2e\x38\x33\x31\x0d\x0a\x09\x09\x09\ +\x09\x63\x30\x2c\x32\x34\x2e\x37\x33\x36\x2c\x32\x30\x2e\x30\x36\ +\x36\x2c\x34\x34\x2e\x38\x30\x38\x2c\x34\x34\x2e\x38\x32\x31\x2c\ +\x34\x34\x2e\x38\x30\x38\x68\x33\x39\x38\x2e\x38\x31\x33\x63\x32\ +\x34\x2e\x37\x34\x2c\x30\x2c\x34\x34\x2e\x38\x30\x38\x2d\x32\x30\ +\x2e\x30\x36\x38\x2c\x34\x34\x2e\x38\x30\x38\x2d\x34\x34\x2e\x38\ +\x30\x38\x56\x31\x34\x31\x2e\x33\x32\x35\x0d\x0a\x09\x09\x09\x09\ +\x43\x34\x38\x38\x2e\x34\x34\x34\x2c\x31\x33\x34\x2e\x33\x39\x32\ +\x2c\x34\x38\x35\x2e\x36\x39\x38\x2c\x31\x32\x37\x2e\x37\x35\x38\ +\x2c\x34\x38\x30\x2e\x38\x31\x37\x2c\x31\x32\x32\x2e\x38\x36\x34\ +\x7a\x20\x4d\x34\x31\x32\x2e\x34\x36\x31\x2c\x33\x38\x35\x2e\x36\ +\x36\x36\x63\x30\x2c\x31\x34\x2e\x34\x33\x34\x2d\x31\x31\x2e\x37\ +\x30\x33\x2c\x32\x36\x2e\x31\x35\x34\x2d\x32\x36\x2e\x31\x36\x38\ +\x2c\x32\x36\x2e\x31\x35\x34\x48\x31\x30\x32\x2e\x31\x33\x37\x0d\ +\x0a\x09\x09\x09\x09\x63\x2d\x31\x34\x2e\x34\x35\x31\x2c\x30\x2d\ +\x32\x36\x2e\x31\x35\x33\x2d\x31\x31\x2e\x37\x32\x32\x2d\x32\x36\ +\x2e\x31\x35\x33\x2d\x32\x36\x2e\x31\x35\x34\x56\x32\x34\x39\x2e\ +\x33\x30\x33\x63\x30\x2d\x31\x34\x2e\x34\x33\x2c\x31\x31\x2e\x37\ +\x30\x32\x2d\x32\x36\x2e\x31\x34\x38\x2c\x32\x36\x2e\x31\x35\x33\ +\x2d\x32\x36\x2e\x31\x34\x38\x68\x32\x38\x34\x2e\x31\x35\x36\x0d\ +\x0a\x09\x09\x09\x09\x63\x31\x34\x2e\x34\x36\x35\x2c\x30\x2c\x32\ +\x36\x2e\x31\x36\x38\x2c\x31\x31\x2e\x37\x32\x2c\x32\x36\x2e\x31\ +\x36\x38\x2c\x32\x36\x2e\x31\x34\x38\x56\x33\x38\x35\x2e\x36\x36\ +\x36\x7a\x22\x2f\x3e\x0d\x0a\x09\x09\x09\x3c\x70\x61\x74\x68\x20\ +\x64\x3d\x22\x4d\x33\x35\x36\x2e\x34\x39\x37\x2c\x32\x36\x35\x2e\ +\x31\x33\x31\x48\x31\x33\x31\x2e\x39\x34\x39\x63\x2d\x39\x2e\x30\ +\x30\x38\x2c\x30\x2d\x31\x36\x2e\x32\x39\x34\x2c\x37\x2e\x32\x37\ +\x33\x2d\x31\x36\x2e\x32\x39\x34\x2c\x31\x36\x2e\x32\x38\x73\x37\ +\x2e\x32\x38\x36\x2c\x31\x36\x2e\x32\x38\x2c\x31\x36\x2e\x32\x39\ +\x34\x2c\x31\x36\x2e\x32\x38\x68\x32\x32\x34\x2e\x35\x34\x39\x0d\ +\x0a\x09\x09\x09\x09\x63\x38\x2e\x39\x38\x38\x2c\x30\x2c\x31\x36\ +\x2e\x32\x37\x37\x2d\x37\x2e\x32\x37\x33\x2c\x31\x36\x2e\x32\x37\ +\x37\x2d\x31\x36\x2e\x32\x38\x53\x33\x36\x35\x2e\x34\x38\x37\x2c\ +\x32\x36\x35\x2e\x31\x33\x31\x2c\x33\x35\x36\x2e\x34\x39\x37\x2c\ +\x32\x36\x35\x2e\x31\x33\x31\x7a\x22\x2f\x3e\x0d\x0a\x09\x09\x09\ +\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x33\x32\x33\x2e\x39\x33\ +\x36\x2c\x33\x33\x30\x2e\x32\x36\x34\x48\x31\x36\x34\x2e\x35\x30\ +\x38\x63\x2d\x38\x2e\x39\x39\x34\x2c\x30\x2d\x31\x36\x2e\x32\x38\ +\x2c\x37\x2e\x32\x37\x33\x2d\x31\x36\x2e\x32\x38\x2c\x31\x36\x2e\ +\x32\x38\x63\x30\x2c\x38\x2e\x39\x38\x39\x2c\x37\x2e\x32\x38\x36\ +\x2c\x31\x36\x2e\x32\x38\x2c\x31\x36\x2e\x32\x38\x2c\x31\x36\x2e\ +\x32\x38\x68\x31\x35\x39\x2e\x34\x32\x37\x0d\x0a\x09\x09\x09\x09\ +\x63\x38\x2e\x39\x39\x34\x2c\x30\x2c\x31\x36\x2e\x32\x38\x31\x2d\ +\x37\x2e\x32\x39\x31\x2c\x31\x36\x2e\x32\x38\x31\x2d\x31\x36\x2e\ +\x32\x38\x43\x33\x34\x30\x2e\x32\x31\x37\x2c\x33\x33\x37\x2e\x35\ +\x33\x37\x2c\x33\x33\x32\x2e\x39\x33\x2c\x33\x33\x30\x2e\x32\x36\ +\x34\x2c\x33\x32\x33\x2e\x39\x33\x36\x2c\x33\x33\x30\x2e\x32\x36\ +\x34\x7a\x22\x2f\x3e\x0d\x0a\x09\x09\x3c\x2f\x67\x3e\x0d\x0a\x09\ +\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\ +\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\ +\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\ +\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\x2f\x67\ +\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\ +\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\x2f\ +\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\ +\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\ +\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\ +\x3c\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\ +\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\ +\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\ \x00\x00\x04\xcf\ \x00\ \x00\x80\x9c\x78\x9c\xed\x9c\xcf\x6b\x24\x45\x14\xc7\x9f\x5e\x12\ @@ -3266,6 +5343,10 @@ \x0a\x61\x5a\xa7\ \x00\x69\ \x00\x63\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0c\ +\x05\xac\x5e\xdf\ +\x00\x74\ +\x00\x6f\x00\x52\x00\x61\x00\x73\x00\x74\x00\x65\x00\x72\x00\x2e\x00\x69\x00\x63\x00\x6f\ \x00\x10\ \x02\xd9\x93\xe7\ \x00\x69\ @@ -3284,6 +5365,10 @@ \x02\x8c\x59\xa7\ \x00\x70\ \x00\x6c\x00\x61\x00\x79\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0e\ +\x08\x91\xae\xbf\ +\x00\x52\ +\x00\x65\x00\x64\x00\x48\x00\x69\x00\x64\x00\x72\x00\x69\x00\x63\x00\x61\x00\x2e\x00\x69\x00\x63\x00\x6f\ \x00\x0a\ \x0c\xf7\x1b\xc7\ \x00\x63\ @@ -3300,6 +5385,14 @@ \x0d\x91\xc1\x87\ \x00\x63\ \x00\x6f\x00\x6f\x00\x72\x00\x64\x00\x43\x00\x61\x00\x70\x00\x74\x00\x75\x00\x72\x00\x65\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0b\ +\x09\x49\xee\x87\ +\x00\x74\ +\x00\x6f\x00\x65\x00\x78\x00\x63\x00\x65\x00\x6c\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x08\ +\x08\xc8\x55\xe7\ +\x00\x73\ +\x00\x61\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x0a\ \x04\xa1\x18\x1f\ \x00\x63\ @@ -3310,17 +5403,21 @@ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ \x00\x00\x00\x14\x00\x02\x00\x00\x00\x02\x00\x00\x00\x03\ -\x00\x00\x00\x36\x00\x02\x00\x00\x00\x09\x00\x00\x00\x05\ +\x00\x00\x00\x36\x00\x02\x00\x00\x00\x0d\x00\x00\x00\x05\ \x00\x00\x00\x46\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x00\xe8\x00\x00\x00\x00\x00\x01\x00\x00\x0e\xe6\ -\x00\x00\x00\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x04\x0e\ -\x00\x00\x01\x32\x00\x00\x00\x00\x00\x01\x00\x00\x9e\xe8\ -\x00\x00\x00\x82\x00\x00\x00\x00\x00\x01\x00\x00\x06\x81\ -\x00\x00\x01\x78\x00\x01\x00\x00\x00\x01\x00\x00\xc4\x42\ -\x00\x00\x00\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x0a\xb9\ -\x00\x00\x01\x18\x00\x00\x00\x00\x00\x01\x00\x00\x97\x1a\ -\x00\x00\x00\xfe\x00\x00\x00\x00\x00\x01\x00\x00\x44\x46\ -\x00\x00\x01\x52\x00\x00\x00\x00\x00\x01\x00\x00\xa2\xb1\ +\x00\x00\x01\x06\x00\x00\x00\x00\x00\x01\x00\x00\x17\x7b\ +\x00\x00\x00\x7a\x00\x00\x00\x00\x00\x01\x00\x00\x0c\xa3\ +\x00\x00\x01\x72\x00\x00\x00\x00\x00\x01\x00\x00\xad\x7e\ +\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x01\x00\x00\x0f\x16\ +\x00\x00\x01\xea\x00\x01\x00\x00\x00\x01\x00\x01\x45\x81\ +\x00\x00\x00\x5c\x00\x01\x00\x00\x00\x01\x00\x00\x04\x0e\ +\x00\x00\x00\xd2\x00\x00\x00\x00\x00\x01\x00\x00\x13\x4e\ +\x00\x00\x01\x1c\x00\x01\x00\x00\x00\x01\x00\x00\x4c\xdb\ +\x00\x00\x01\xd4\x00\x00\x00\x00\x00\x01\x00\x01\x3e\x73\ +\x00\x00\x01\xb8\x00\x00\x00\x00\x00\x01\x00\x00\xd2\xd8\ +\x00\x00\x01\x58\x00\x00\x00\x00\x00\x01\x00\x00\xa5\xb0\ +\x00\x00\x01\x3e\x00\x00\x00\x00\x00\x01\x00\x00\x52\xdc\ +\x00\x00\x01\x92\x00\x00\x00\x00\x00\x01\x00\x00\xb1\x47\ " def qInitResources(): From aeb328f1a2363831fc571446cf1191bc0abba9a3 Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Sun, 19 Aug 2018 21:38:27 -0500 Subject: [PATCH 100/142] =?UTF-8?q?Se=20corrige=20en=20la=20funci=C3=B3n?= =?UTF-8?q?=20GeoGetRunoff()=20para=20que=20tomes=20los=20valores=20e1=20y?= =?UTF-8?q?=20Epsi=20especificados=20por=20el=20usuario?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPlugin_dockwidget.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 45a0904..436d745 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -194,7 +194,7 @@ def clickEventBasin2WMF(): self.segundaCarga = True #Cargado de la cuenca Area, self.EPSG, dxp, self.noData, self.umbral = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), - Simhidro, SimSed) + Simhidro, SimSed) #self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), Simhidro, SimSed) self.TableStart() #Actualiza tabla de Nc y comboBox @@ -203,7 +203,7 @@ def clickEventBasin2WMF(): self.TabNC.NewEntry(self.HSutils.DicBasinNc[k],k, self.Tabla_Prop_NC) self.VarFromNC.addItem(k) #Area, self.EPSG, dxp, self.noData, self.umbral = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), - # Simhidro, SimSed) + # Simhidro, SimSed) #print self.umbral #Habilita los botones de visualizacion de red hidrica y divisoria self.Boton_verDivisoria.setEnabled(True) @@ -390,9 +390,12 @@ def clickEventGeoRasterProp(): ListaVar.extend(['OCG_coef']) if self.checkBoxKubota.isChecked(): self.HSutils.Basin_GeoGetKubota() - ListaVar.extend(['kubota_coef']) + ListaVar.extend(['kubota_coef']) if self.checkBoxRunoff.isChecked(): - self.HSutils.Basin_GeoGetRunoff() + #Obtiene los parametros e1 y Epsilon de las cajitas + E1 = self.RunoffE1.value() + Epsi = self.RunoffEpsi.value() + self.HSutils.Basin_GeoGetRunoff(e1=E1,Epsilon=Epsi) ListaVar.extend(['Runoff_coef']) #mensaje de caso de exito From c6c30892256d29abdc652601fe8847db25b3eb28 Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Sun, 19 Aug 2018 22:30:03 -0500 Subject: [PATCH 101/142] Se ponen warnings para cuando se quiera calcular runoff y kubota sin tener h1max y manning cargados --- qgisplugin/HydroSEDPlugin_dockwidget.py | 36 ++++++++++++++++++------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 436d745..afa94e6 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -389,17 +389,35 @@ def clickEventGeoRasterProp(): self.HSutils.Basin_GeoGetOCG() ListaVar.extend(['OCG_coef']) if self.checkBoxKubota.isChecked(): - self.HSutils.Basin_GeoGetKubota() - ListaVar.extend(['kubota_coef']) + try: + self.HSutils.Basin_GeoGetKubota() + ListaVar.extend(['kubota_coef']) + self.iface.messageBar().pushInfo(u'HidroSIG:', + u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.') + except: + #Pone un mensaje de error por si h1_max no ha sido calculado + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + u'No ha sido cargado h1_max, Kubota no puede calcularse', + level=QgsMessageBar.WARNING, duration=5) if self.checkBoxRunoff.isChecked(): - #Obtiene los parametros e1 y Epsilon de las cajitas - E1 = self.RunoffE1.value() - Epsi = self.RunoffEpsi.value() - self.HSutils.Basin_GeoGetRunoff(e1=E1,Epsilon=Epsi) - ListaVar.extend(['Runoff_coef']) + try: + #Obtiene los parametros e1 y Epsilon de las cajitas + E1 = self.RunoffE1.value() + Epsi = self.RunoffEpsi.value() + self.HSutils.Basin_GeoGetRunoff(e1=E1,Epsilon=Epsi) + ListaVar.extend(['Runoff_coef']) + self.iface.messageBar().pushInfo(u'HidroSIG:', + u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.') + except: + #Pone un mensaje de error por si Manning no ha sido calculado + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + u'No ha sido cargado Manning, Runoff no puede calcularse', + level=QgsMessageBar.WARNING, duration=5) + + #mensaje de caso de exito (para runoff y kubota se muestran por separado) + if self.checkBoxRunoff.isChecked()==False and self.checkBoxKubota.isChecked()==False: + self.iface.messageBar().pushInfo(u'HidroSIG:',u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.') - #mensaje de caso de exito - self.iface.messageBar().pushInfo(u'HidroSIG:',u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.') #Actualiza la tabla de variables temporales for k in ListaVar: self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[k],k, self.Tabla_Prop_WMF) From 90e2110407b71f41f7696b337226c14de6b88fcc Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Mon, 20 Aug 2018 10:28:53 -0500 Subject: [PATCH 102/142] =?UTF-8?q?Se=20corrige=20bug=20en=20el=20que=20la?= =?UTF-8?q?s=20variables=20del=20NC=20no=20se=20pod=C3=ADan=20actualizar?= =?UTF-8?q?=20despu=C3=A9s=20de=20borrar=20o=20enviar=20variables=20del=20?= =?UTF-8?q?NC=20a=20WMF=20(no=20se=20estaba=20actualizando=20el=20NC2Save)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPluginUtils.py | 2 +- qgisplugin/HydroSEDPlugin_dockwidget.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 7759625..b17484c 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -253,7 +253,7 @@ def Basin_LoadBasin(self, PathNC, LoadSim = False, LoadSed = False): shape = g.groups[grupoKey].variables[k].shape MapaRaster = False for s in shape: - if s == self.cuenca.ncells: MapaRaster = True + if s == self.cuenca.ncells: MapaRaster = True #Actualiza el diccionario self.DicBasinNc.update({k: {'nombre':k, diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index afa94e6..6f91bd0 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -395,7 +395,7 @@ def clickEventGeoRasterProp(): self.iface.messageBar().pushInfo(u'HidroSIG:', u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.') except: - #Pone un mensaje de error por si h1_max no ha sido calculado + #Pone un mensaje de error por si h1_max no ha sido calculado self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'No ha sido cargado h1_max, Kubota no puede calcularse', level=QgsMessageBar.WARNING, duration=5) @@ -409,7 +409,7 @@ def clickEventGeoRasterProp(): self.iface.messageBar().pushInfo(u'HidroSIG:', u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.') except: - #Pone un mensaje de error por si Manning no ha sido calculado + #Pone un mensaje de error por si Manning no ha sido calculado self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'No ha sido cargado Manning, Runoff no puede calcularse', level=QgsMessageBar.WARNING, duration=5) @@ -998,6 +998,7 @@ def handleClickEventButton_Eliminar_Desde_NC (): self.Tabla_Prop_NC.removeRow (selectedItems) self.TabNC.DelEntry(ItemName) self.HSutils.DicBasinNc.pop(ItemName) + self.HSutils.Nc2Save.remove(ItemName) #self.HSutils.Nc2Erase.append(ItemName) #Mensaje de exito self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'La variable '+ItemName + ' ha sido borrada') @@ -1064,6 +1065,7 @@ def handleClickEventButton_NC2WMF(): self.Tabla_Prop_NC.removeRow (selectedItems) self.TabNC.DelEntry(VarName) self.HSutils.DicBasinNc.pop(VarName) + self.HSutils.Nc2Save.remove(VarName) #Mensaje de exito self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'La variable '+VarName+' ha sido movida de NC a WMF') else: From bed8f8cfa7970a7e8546eae6e154db682b7a40bf Mon Sep 17 00:00:00 2001 From: vanesalo10 <41450387+vanesalo10@users.noreply.github.com> Date: Mon, 20 Aug 2018 18:56:33 -0500 Subject: [PATCH 103/142] Delete wmf.py --- wmf/wmf.py | 4600 ---------------------------------------------------- 1 file changed, 4600 deletions(-) delete mode 100644 wmf/wmf.py diff --git a/wmf/wmf.py b/wmf/wmf.py deleted file mode 100644 index 113ab48..0000000 --- a/wmf/wmf.py +++ /dev/null @@ -1,4600 +0,0 @@ -#!Modelos: acoplado con cuencas presenta una serie de modelos hidrologicos distribuidos -#!Copyright (C) <2016> - -#!This program is free software: you can redistribute it and/or modify -#!it under the terms of the GNU General Public License as published by -#!the Free Software Foundation, either version 3 of the License, or -#!(at your option) any later version. - -#!This program is distributed in the hope that it will be useful, -#!but WITHOUT ANY WARRANTY; without even the implied warranty of -#!MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#!GNU General Public License for more details. - -#!You should have received a copy of the GNU General Public License -#!along with this program. If not, see . -#Algo -import matplotlib -matplotlib.use('Agg') -from cu import * -from models import * -import numpy as np -import pylab as pl -import osgeo.ogr, osgeo.osr -import gdal -from scipy.spatial import Delaunay -from scipy.stats import norm -import os -import pandas as pd -import datetime as datetime -from multiprocessing import Pool -import matplotlib.path as mplPath -try: - import netcdf as netcdf -except: - try: - import netCDF4 as netcdf - except: - print 'No netcdf en esta maquina, se desabilita la funcion SimuBasin.save_SimuBasin' - pass -try: - from mpl_toolkits.basemap import Basemap, addcyclic, shiftgrid, cm - from matplotlib.patches import Polygon - from matplotlib.collections import PatchCollection -except: - print 'No se logra importar basemap, por lo tanto no funciona Plot_basin' - pass -try: - from deap import base, creator - from deap import tools - FlagCalib_NSGAII = True -except: - print 'No se logra importar deap tools, por lo tanto se deshabilita SimuBasin.Calib_NSGAII' - FlagCalib_NSGAII = False -try: - import rasterio.features as __fea__ - FlagBasinPolygon = True -except: - print 'No se logra importar rasterio, se deshabilita obtencion de poligono de cuenca' - FlagBasinPolygon = False - -import random -#Variable codigo EPSG -Global_EPSG = -9999 - -#----------------------------------------------------------------------- -#Ploteo de variables -#----------------------------------------------------------------------- -def plot_sim_single(Qs,Qo=None,mrain=None,Dates=None,ruta=None, - figsize=(8,4.5),ids=None,legend=True,ax1 = None,**kwargs): - '''ENTRADAS: - Qs = Caudal simulado, variable tipo lista - Qo = Caudal observado, variable tipo lista - mrain = Lluvia media observada,variable tipo lista - Dates = Indice de tiempo (Datetime), variable tipo lista - ids = Identificador de puntos de control - ax1 = axis o entorno para graficar - **kwargs = Argumentos por defecto, se pueden cambiar. - Estos argumentos son: - - ARGUMENTOS POR DEFECTO - rain_alpha': 0.4, Transparencia de la lluvia - rain_color': blue, Color de la lluvia - rain_lw : 0, Ancho de linea de lluvia - rain_ylabel: Precipitation [$mm$], Etiqueta del eje y de la lluvia - label_size: 14, Tamano de fuente - rain_ylim : Se ajusta, Limite del eje y - ColorSim : ['r','g','k','c','y'], Colores para simulacion de caudal - Qs_lw : 1.5, Ancho de linea de caudal simulado - Qo_lw : 2.0, Ancho de linea de caudal observado - Qs_color : red, Color de linea de caudal simulado - Qo_color : blue, Color de linea de caudal observado - Qo_label : Observed, Leyenda de caudal observado - Qs_label : Simulated, Leyenda de caudal simulado - xlabel : Time [$min$], Etiqueta del eje x - ylabel : Streamflow $[m^3/seg], Etiqueta del eje y - legend_loc : upper center, Ubicacion de la leyenda - bbox_to_anchor : (0.5,-0.12), Ajuste de la caja de la leyenda - legend_ncol : 4, Numero de columnas para la leyenda - ''' - #Argumentos kw - show = kwargs.get('show',True) - if ax1 == None: - fig=pl.figure(facecolor='w',edgecolor='w',figsize=figsize) - ax1=fig.add_subplot(111) - else: - show = False - #Fechas - if Dates==None: - if len(Qs.shape)>1: - ejeX=range(len(Qs[0])) - else: - ejeX = range(len(Qs)) - else: - ejeX=Dates - #Grafica la lluvia - if mrain is not None: - ax1AX=pl.gca() - ax2=ax1.twinx() - ax2AX=pl.gca() - alpha = kwargs.get('rain_alpha',0.4) - color = kwargs.get('rain_color','blue') - lw = kwargs.get('rain_lw',0) - ax2.fill_between(ejeX,0,mrain,alpha=alpha,color=color,lw=lw) - ylabel = kwargs.get('rain_ylabel','Precipitation [$mm$]') - label_size = kwargs.get('label_size',14) - ax2.set_ylabel(ylabel,size=label_size) - ylim = kwargs.get('rain_ylim',ax2AX.get_ylim() [::-1]) - ax2AX.set_ylim(ylim) - else: - ax2 = None - #grafica las hidrografas - ColorSim=kwargs.get('ColorSim',['r','g','k','c','y']) - Qs_lw = kwargs.get('Qs_lw',1.5) - Qo_lw = kwargs.get('Qo_lw',2.0) - Qs_color = kwargs.get('Qs_color','r') - Qo_color = kwargs.get('Qo_color','b') - Qo_label = kwargs.get('Qo_label','Observed') - Qs_label = kwargs.get('Qs_label','Simulated') - if len(Qs.shape)>1: - if ids is None: - ids = np.arange(1,Qs.shape[0]+1) - for i,c,d in zip(Qs,ColorSim,ids): - ax1.plot(ejeX,i,c,lw=Qs_lw,label=str(d)) - else: - ax1.plot(ejeX,Qs,Qs_color,lw=Qs_lw,label=Qs_label) - if Qo is not None: ax1.plot(ejeX,Qo,Qo_color,lw=Qo_lw,label=Qo_label) - #Pone elementos en la figura - xlabel = kwargs.get('xlabel','Time [$min$]') - ylabel = kwargs.get('ylabel','Streamflow $[m^3/seg]$') - label_size = kwargs.get('label_size', 16) - ax1.set_xlabel(xlabel,size=label_size) - ax1.set_ylabel(ylabel,size=label_size) - ax1.grid(True) - loc = kwargs.get('legend_loc','upper center') - bbox_to_anchor = kwargs.get('bbox_to_anchor',(0.5,-0.12)) - ncol = kwargs.get('legend_ncol',4) - if legend == True: - lgn1=ax1.legend(loc=loc, bbox_to_anchor=bbox_to_anchor, - fancybox=True, shadow=True, ncol=ncol) - if ruta is not None: - pl.savefig(ruta, bbox_inches='tight') - if show == True: - pl.show() - return ax1, ax2 - -def plot_mean_storage(Mean_Storage, Dates = None, mrain = None, - rute = None, **kwargs): - 'Funcion: plot_mean_storage\n'\ - 'Descripcion: Plotea como se encuentran los almacenamientos medios en la cuenca.\n'\ - 'Parametros Obligatorios:.\n'\ - ' -Mean_Storage: almacenamiento medio en cada uno de los tanques (5,Npasos).\n'\ - ' Esta es la variables obtenida por wmf.SimuBasin.run_shia como Mean_Storage.\n'\ - 'Parametros Opcionales:.\n'\ - ' -Dates: Fechas para el plot\n'\ - ' -marin: Lluvia promedio sobre la cuenca\n'\ - ' -rute: Ruta donde se va a guardar\n'\ - ' -kwargs: algunos argumentos de set del plot\n'\ - ' - figsize: tamano de la figura.\n'\ - ' - color: Color de los plot.\n'\ - ' - lw: ancho de la linea del plot.\n'\ - ' - labelsize: tamano de los label.\n'\ - ' - ysize: tamano de la fuente en el eje Y.\n'\ - 'Retorno:.\n'\ - ' Plot de los almacenamientos medios.\n'\ - #Argumentos kw - figsize = kwargs.get('figsize',(13,9)) - color = kwargs.get('color','k') - lw = kwargs.get('lw',4) - labelsize = kwargs.get('labelsize', 14) - ysize = kwargs.get('ysize', 16) - show = kwargs.get('show',True) - alpha = kwargs.get('alpha',0.5) - colorRain = kwargs.get('colorRain','b') - lwRain = kwargs.get('lwRain',0.1) - #Inicio de la funcion - if Dates==None: - ejeX=range(Mean_Storage.shape[1]) - else: - ejeX=Dates - #figura - fig = pl.figure(figsize = figsize) - nombres = ['Hu','Runoff','Hg','Sub','Stream'] - for c,i in enumerate(Mean_Storage): - ax = fig.add_subplot(5,1,c+1) - ax.plot(ejeX, i, color, lw = lw) - ax.grid() - # Deja el eje X solo en el ultimo plot - if c<4: - ax.set_xticklabels([]) - ax.tick_params(labelsize = labelsize) - #Pinta la lluvia en el primer plot - if c == 0 and mrain is not None: - ax2=ax.twinx() - ax2AX=pl.gca() - ax2.fill_between(ejeX,0,mrain,alpha=alpha,color=colorRain,lw=lwRain) - ylim = ax2AX.get_ylim()[::-1]; ylim = list(ylim); ylim[1] = 0 - ax2AX.set_ylim(ylim) - #Nombre de cada tanque - ax.set_ylabel(nombres[c], size = ysize) - if rute is not None: - pl.savefig(rute, bbox_inches='tight') - if show == True: - pl.show() - if c == 0 and mrain is not None: - return ax, ax2 - else: - return ax - -#----------------------------------------------------------------------- -#Lectura de informacion y mapas -#----------------------------------------------------------------------- -def read_map_raster(ruta_map,isDEMorDIR=False,dxp=None, noDataP = None,isDIR = False,DIRformat = 'r.watershed'): - 'Funcion: read_map\n'\ - 'Descripcion: Lee un mapa raster soportado por GDAL.\n'\ - 'Parametros Obligatorios:.\n'\ - ' -ruta_map: Ruta donde se encuentra el mapa.\n'\ - 'Parametros Opcionales:.\n'\ - ' -isDEMorDIR: Pasa las propiedades de los mapas al modulo cuencas \n'\ - ' escrito en fortran \n'\ - ' -dxp: tamano plano del mapa\n'\ - ' -noDataP: Valor para datos nulos en el mapa (-9999)\n'\ - ' -DIRformat: donde se ha conseguido el mapa dir (r.watershed) \n'\ - ' - r.watershed: mapa de direcciones obtenido por la funcion de GRASS\n'\ - ' - opentopo: mapa de direcciones de http://www.opentopography.org/\n'\ - ' -isDIR: (FALSE) es este un mapa de direcciones\n'\ - 'Retorno:.\n'\ - ' Si no es DEM o DIR retorna todas las propieades del elemento en un vector.\n'\ - ' En el siguiente orden: ncols,nrows,xll,yll,dx,nodata.\n'\ - ' Si es DEM o DIR le pasa las propieades a cuencas para el posterior trazado.\n'\ - ' de cuencas y tramos.\n' \ - #Abre el mapa - direction=gdal.Open(ruta_map) - #Proyecction - proj = osgeo.osr.SpatialReference(wkt=direction.GetProjection()) - EPSG_code = proj.GetAttrValue('AUTHORITY',1) - #lee la informacion del mapa - ncols=direction.RasterXSize - nrows=direction.RasterYSize - banda=direction.GetRasterBand(1) - noData=banda.GetNoDataValue() - geoT=direction.GetGeoTransform() - dx=geoT[1] - dy = np.abs(geoT[-1]) - xll=geoT[0]; yll=geoT[3]-nrows*dy - #lee el mapa - Mapa=direction.ReadAsArray() - direction.FlushCache() - del direction - if isDEMorDIR==True: - cu.ncols=ncols - cu.nrows=nrows - if noDataP is not None: - cu.nodata = noDataP - Mapa[Mapa<0] = cu.nodata - else: - cu.nodata=noData - cu.dx=dx - cu.dy = dy - cu.xll=xll - cu.yll=yll - if dxp==None: - cu.dxp=30.0 - else: - cu.dxp=dxp - #Guarda la variable para el proyecto - global Global_EPSG - Global_EPSG = EPSG_code - # si es un dir se fija si es de r.watershed - if isDIR: - if DIRformat == 'r.watershed': - Mapa[Mapa<=0] = cu.nodata.astype(int) - Mapa = cu.dir_reclass_rwatershed(Mapa.T,cu.ncols,cu.nrows) - return Mapa, EPSG_code - if DIRformat == 'opentopo': - Mapa[Mapa<=0] = cu.nodata.astype(int) - Mapa = cu.dir_reclass_opentopo(Mapa.T,cu.ncols,cu.nrows) - return Mapa, EPSG_code - #retorna el mapa - return Mapa.T,EPSG_code - else: - return Mapa.T,[ncols,nrows,xll,yll,dx,dy,noData],EPSG_code - -def read_map_points(ruta_map, ListAtr = None): - 'Funcion: read_map_points\n'\ - 'Descripcion: Lee un mapa vectorial de puntos soportado por GDAL.\n'\ - 'Parametros Obligatorios:.\n'\ - ' -ruta_map: Ruta donde se encuentra el mapa.\n'\ - 'Parametros Opcionales:.\n'\ - ' -ListAtr: Lista con los nombres de los atributos de las columnas\n'\ - ' que se quieren leer dentro de la variable Dict\n'\ - 'Retorno:.\n'\ - ' Si ListAtr == None: Retorna unicamente las coordenadas.\n'\ - ' Si ListAtr == [Nombre1, Nombre2, ...]: Retorna: Coord y diccionario con variables.\n'\ - #Obtiene el acceso - dr = osgeo.ogr.Open(ruta_map) - l = dr.GetLayer() - #Lee las coordenadas - Cord = [] - for i in range(l.GetFeatureCount()): - f = l.GetFeature(i) - g = f.GetGeometryRef() - pt = [g.GetX(),g.GetY()] - Cord.append(pt) - Cord = np.array(Cord).T - #Si hay atributos para buscar los lee y los m - if ListAtr is not None: - Dict = {} - for j in ListAtr: - #Busca si el atributo esta - pos = f.GetFieldIndex(j) - #Si esta lee la info del atributo - if pos is not -1: - vals = [] - for i in range(l.GetFeatureCount()): - f = l.GetFeature(i) - vals.append(f.GetField(pos)) - Dict.update({j:np.array(vals)}) - #Cierra el mapa - dr.Destroy() - return Cord, Dict - else: - #Cierra el mapa - dr.Destroy() - return Cord - -def Save_Array2Raster(Array, ArrayProp, ruta, EPSG = 4326, Format = 'GTiff'): - dst_filename = ruta - #Formato de condiciones del mapa - x_pixels = Array.shape[0] # number of pixels in x - y_pixels = Array.shape[1] # number of pixels in y - PIXEL_SIZE = ArrayProp[4] # size of the pixel... - x_min = ArrayProp[2] - y_max = ArrayProp[3] + ArrayProp[4] * ArrayProp[1] # x_min & y_max are like the "top left" corner. - driver = gdal.GetDriverByName(Format) - #Para encontrar el formato de GDAL - NP2GDAL_CONVERSION = { - "uint8": 1, - "int8": 1, - "uint16": 2, - "int16": 3, - "uint32": 4, - "int32": 5, - "float32": 6, - "float64": 7, - "complex64": 10, - "complex128": 11, - } - gdaltype = NP2GDAL_CONVERSION[Array.dtype.name] - # Crea el driver - dataset = driver.Create( - dst_filename, - x_pixels, - y_pixels, - 1, - gdaltype,) - #coloca la referencia espacial - dataset.SetGeoTransform(( - x_min, # 0 - PIXEL_SIZE, # 1 - 0, # 2 - y_max, # 3 - 0, # 4 - -PIXEL_SIZE)) - #coloca la proyeccion a partir de un EPSG - proj = osgeo.osr.SpatialReference() - texto = 'EPSG:' + str(EPSG) - proj.SetWellKnownGeogCS( texto ) - dataset.SetProjection(proj.ExportToWkt()) - #Coloca el nodata - band = dataset.GetRasterBand(1) - if ArrayProp[-1] == None: - band.SetNoDataValue(wmf.cu.nodata.astype(int).max()) - else: - band.SetNoDataValue(-9999) - #Guarda el mapa - dataset.GetRasterBand(1).WriteArray(Array.T) - dataset.FlushCache() - -def Save_Points2Map(XY,ids,ruta,EPSG = 4326, Dict = None, - DriverFormat='ESRI Shapefile'): - 'Funcion: Save_Points2Map\n'\ - 'Descripcion: Guarda coordenadas X,Y en un mapa tipo puntos.\n'\ - 'Parametros Opcionales:.\n'\ - 'XY: Coordenadas de los puntos X,Y.\n'\ - 'ids: Numero que representa a cada punto.\n'\ - 'ruta: Ruta de escritura de los puntos.\n'\ - 'Opcionales:.\n'\ - 'EPSG : Codigo del tipo de proyeccion usada, defecto 4326 de WGS84.\n'\ - 'Dict : Diccionario con prop de los puntos, Defecto: None.\n'\ - 'DriverFormat : Formato del archivo vectorial, Defecto: ESRI Shapefile.\n'\ - 'Retorno:.\n'\ - ' Escribe el mapa en la ruta especificada.\n'\ - #Genera el shapefile - spatialReference = osgeo.osr.SpatialReference() - spatialReference.ImportFromEPSG(EPSG) - driver = osgeo.ogr.GetDriverByName(DriverFormat) - if os.path.exists(ruta): - driver.DeleteDataSource(ruta) - shapeData = driver.CreateDataSource(ruta) - layer = shapeData.CreateLayer('layer1', spatialReference, osgeo.ogr.wkbPoint) - layerDefinition = layer.GetLayerDefn() - new_field=osgeo.ogr.FieldDefn('Estacion',osgeo.ogr.OFTReal) - layer.CreateField(new_field) - if Dict is not None: - for p in Dict.keys(): - tipo = type(Dict[p][0]) - if tipo is np.float64: - new_field=osgeo.ogr.FieldDefn(p[:10],osgeo.ogr.OFTReal) - elif tipo is np.int64: - new_field=osgeo.ogr.FieldDefn(p[:10],osgeo.ogr.OFTInteger) - elif tipo is str: - new_field=osgeo.ogr.FieldDefn(p[:10],osgeo.ogr.OFTString) - layer.CreateField(new_field) - #Mete todos los puntos - featureIndex=0 - contador=0 - #Calcula el tamano de la muestra - N=np.size(XY,axis=1) - if N>1: - for i in XY.T: - if i[0]<>-9999.0 and i[1]<>-9999.0: - #inserta el punto - point = osgeo.ogr.Geometry(osgeo.ogr.wkbPoint) - point.SetPoint(0, float(i[0]), float(i[1])) - feature = osgeo.ogr.Feature(layerDefinition) - feature.SetGeometry(point) - feature.SetFID(featureIndex) - feature.SetField('Estacion',ids[contador]) - #Le coloca lo del diccionario - if Dict is not None: - for p in Dict.keys(): - tipo = type(Dict[p][0]) - if tipo is np.float64: - feature.SetField(p[:10],float("%.2f" % Dict[p][contador])) - elif tipo is np.int64: - feature.SetField(p[:10],int("%d" % Dict[p][contador])) - elif tipo is str: - feature.SetField(p[:10],Dict[p][contador]) - #Actualiza contadores - contador+=1 - layer.CreateFeature(feature) - point.Destroy() - feature.Destroy() - else: - point = osgeo.ogr.Geometry(osgeo.ogr.wkbPoint) - point.SetPoint(0, float(XY[0,0]), float(XY[1,0])) - feature = osgeo.ogr.Feature(layerDefinition) - feature.SetGeometry(point) - feature.SetFID(featureIndex) - feature.SetField('Estacion',ids) - for p in Dict.keys(): - feature.SetField(p[:p.index('[')].strip()[:10],float("%.2f" % Param[p])) - contador+=1 - layer.CreateFeature(feature) - point.Destroy() - feature.Destroy() - shapeData.Destroy() - -def __ListaRadarNames__(ruta,FechaI,FechaF,fmt,exten,string,dt): - 'Funcion: OCG_param\n'\ - 'Descripcion: Obtiene una lista con los nombres para leer datos de radar.\n'\ - 'Parametros:.\n'\ - ' -FechaI, FechaF: Fechas inicial y final en formato datetime.\n'\ - ' -fmt : Formato en el que se pasa FechaI a texto, debe couincidir con.\n'\ - ' el del texto que se tenga en los archivos.\n'\ - ' -exten : Extension de los archivos .asc, .nc, .bin ...\n'\ - ' -string : texto antes de la fecha.\n'\ - ' -dt : Intervalos de tiempo entre los eventos.\n'\ - 'Retorno:.\n'\ - ' Lista : la lista de python con los nombres de los binarios.\n'\ - #Crea lista de fechas y mira que archivos estan en esas fechas - Dates=[FechaI]; date=FechaI - while datei: - Flag = True - c2 = c - c3 = 0 - while Flag: - if i= Y.size: Flag = False - else: - Flag=False - Pos.append(c2) - c+=1 - # Obtiene la segunda derivada de la corriente corregida - Y = pd.Series(Y) - Y = Y.rolling(window).mean() - l = Y[np.isnan(Y)].shape[0] - Y[:l]=Y[l+1] - slope = np.diff(Y,1) - slope = np.hstack([slope,slope[-1]]) - return Y,np.abs(slope) - -#----------------------------------------------------------------------- -#Clase de cuencas -#----------------------------------------------------------------------- - -class Basin: - - #------------------------------------------------------ - # Subrutinas de trazado de cuenca y obtencion de parametros - #------------------------------------------------------ - #Inicia la cuenca - def __init__(self,lat=0,lon=0,DEM=None,DIR=None,name='NaN',stream=None, - umbral=1000, ruta = None, useCauceMap = None): - 'Descripcion: Inicia la variable de la cuenca, y la traza \n'\ - ' obtiene las propiedades basicas de la cuenca. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'lat : Coordenada en X de la salida de la cuenca.\n'\ - 'lon : Coordenada en Y de la salida de la cuenca.\n'\ - 'name : Nombre con el que se va a conocer la cuenca.\n'\ - 'stream : Opcional, si se coloca, las coordenadas no tienen.\n'\ - ' que ser exactas, estas se van a corregir para ubicarse.\n'\ - ' en el punto mas cercano dentro de la corriente, este.\n'\ - ' debe ser un objeto del tipo stream.\n'\ - 'umbral : umbral minimo para la creacion de cauce (defecto =1000).\n'\ - 'ruta : Ruta donde se encuentra un archivo binario de la cuenca.\n'\ - 'useCauceMap : Si se asigna un mapa binario donde 1 es cauce y 0 es ladera.\n'\ - ' el trazador corregira las coordenadas para que estas lleguen a una celda.\n'\ - ' tipo cauce y se trace la cuenca de forma correcta (esta opcion deshabilita \n'\ - ' a stream)\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con las variables iniciadas.\n'\ - #Relaciona con el DEM y el DIR - self.DEM=DEM - self.DIR=DIR - #Si se da la opcion de que use el useCauceMap deshabilita stream - if useCauceMap is not None: - stream = None - #Si se entrega cauce corrige coordenadas - if ruta == None: - # Si se da el stream corrige por corriente - if stream is not None: - error=[] - for i in stream.structure.T: - error.append( np.sqrt((lat-i[0])**2+(lon-i[1])**2) ) - loc=np.argmin(error) - lat=stream.structure[0,loc] - lon=stream.structure[1,loc] - if useCauceMap is not None and useCauceMap.shape == DEM.shape: - lat,lon = cu.stream_find_to_corr(lat,lon,DEM,DIR,useCauceMap, - cu.ncols,cu.nrows) - #copia la direccion de los mapas de DEM y DIR, para no llamarlos mas - self.name=name - #Traza la cuenca - self.ncells = cu.basin_find(lat,lon,DIR, - cu.ncols,cu.nrows) - self.structure = cu.basin_cut(self.ncells) - self.umbral = umbral - else: - self.__Load_BasinNc(ruta) - #Genera el poligono de la cuenca - self.__GetBasinPolygon__() - #Cargador de cuenca - def __Load_BasinNc(self,ruta,Var2Search=None): - 'Descripcion: Lee una cuenca posteriormente guardada\n'\ - ' La cuenca debio ser guardada con Basin.Save_Basin2nc\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'ruta : ruta donde se encuentra ubicada la cuenca guardada\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : La cuenca con sus parametros ya cargada.\n'\ - #Abre el archivo binario de la cuenca - self.rutaNC = ruta - gr = netcdf.Dataset(ruta,'a') - #obtiene las prop de la cuenca - self.name = gr.nombre - self.ncells = gr.ncells - self.umbral = gr.umbral - #Obtiene las prop de los mapas - cu.ncols=gr.ncols - cu.nrows=gr.nrows - cu.nodata=gr.noData - cu.dx=gr.dx - cu.xll=gr.xll - cu.yll=gr.yll - cu.dxp=gr.dxp - #Obtiene las variables vectoriales - self.structure = gr.variables['structure'][:] - #Cierra el archivo - gr.close() - - def Load_BasinVar(self, varName): - 'Descripcion: Lee una variable especifica del netCDf de la cuenca\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'varName: nombre de la variable guardada\n'\ - 'Retornos\n'\ - '----------\n'\ - 'var : Retorna la variable como un numpy array.\n'\ - #Lectura del netCDf y lectura de variable - gr = netcdf.Dataset(self.rutaNC,'a') - Var = gr.variables[varName][:] - gr.close() - return Var - - #Guardado de de la cuenca en nc - def Save_Basin2nc(self,ruta,qmed=None,q233=None,q5=None, - ExtraVar=None): - 'Descripcion: guarda una cuenca previamente ejecutada\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'ruta : Ruta donde la cuenca sera guardada.\n'\ - 'qmed : Matriz con caudal medio estimado.\n'\ - 'q233 : Matriz con caudal minimo de 2.33.\n'\ - 'q5 : Matriz con caudal minimo de 5.\n'\ - 'ExtraVar: Diccionario con variables extras que se quieran guardar,.\n'\ - ' se guardan como flotantes.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con las variables iniciadas.\n'\ - #Diccionario con las propiedades - Dict = {'nombre':self.name, - 'noData':cu.nodata, - 'ncells':self.ncells, - 'umbral':self.umbral, - 'dxp':cu.dxp, - 'dx':cu.dx, - 'xll':cu.xll, - 'yll':cu.yll, - 'ncols':cu.ncols, - 'nrows':cu.nrows} - #abre el archivo - gr = netcdf.Dataset(ruta,'w',format='NETCDF4') - #Establece tamano de las variables - DimNcell = gr.createDimension('ncell',self.ncells) - DimCol3 = gr.createDimension('col3',3) - #Crea variables - VarStruc = gr.createVariable('structure','i4',('col3','ncell'),zlib=True) - VarQmed = gr.createVariable('q_med','f4',('ncell',),zlib=True) - VarQ233 = gr.createVariable('q_233','f4',('ncell',),zlib=True) - VarQ5 = gr.createVariable('q_5','f4',('ncell',),zlib=True) - #Variables opcionales - if type(ExtraVar) is dict: - for k in ExtraVar.keys(): - Var = gr.createVariable(k,'f4',('ncell',),zlib=True) - Var[:] = ExtraVar[k] - #Asigna valores a las variables - VarStruc[:] = self.structure - if qmed is not None: - VarQmed[:] = qmed - if q233 is not None: - VarQ233[:] = q233 - if q5 is not None: - VarQ5[:] = q5 - #asignlas prop a la cuenca - gr.setncatts(Dict) - #Cierra el archivo - gr.close() - #Sale del programa - return - #Parametros Geomorfologicos - def GetGeo_Parameters(self,rutaParamASC=None,plotTc=False, - rutaTcPlot = None, figsize=(8,5), GetPerim=True): - 'Descripcion: Obtiene los parametros geomorfologicos de la cuenca \n'\ - ' y los tiempos de concentracion calculados por diferentes metodologias. \n'\ - '\n'\ - 'Parametros\n'\ - ' rutaParamASC: ruta del ascii donde se escriben los param.\n'\ - ' plotTc: Plotea o no los tiempos de concentracion.\n'\ - ' rutaTcPlot: Si se da se guarda la figura de tiempos de concentracion.\n'\ - '----------\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'GeoParameters : Parametros de la cuenca calculados.\n'\ - 'Tc : Tiempo de concentracion calculado para la cuenca.\n'\ - #Calcula lo que se necesita para sacar los parametros - acum,longCeld,slope,Elev=cu.basin_basics(self.structure, - self.DEMvec,self.DIRvec,self.ncells) - Lpma,puntto=cu.basin_findlong(self.structure,self.ncells) - cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod(self.structure, - acum,self.umbral,self.ncells) - ppal_nceldas,punto = cu.basin_ppalstream_find(self.structure, - nodos,longCeld,Elev,self.ncells) - ppal = cu.basin_ppalstream_cut(ppal_nceldas,self.ncells) - self.hipso_main,self.hipso_basin=cu.basin_ppal_hipsometric( - self.structure,Elev,punto,30,ppal_nceldas,self.ncells) - self.main_stream=ppal - #Obtiene los parametros - Perim = self.Polygon.shape[1]*cu.dxp/1000. - Area=(self.ncells*cu.dxp**2)/1e6 - TotalCauces = self.CellCauce*self.CellLong - TotalCauces = TotalCauces.sum() / 1000. #[km] - Densidad = TotalCauces / Area #[km/km2] - Lcau=ppal[1,-1]/1000.0 - Scau=np.polyfit(ppal[1,::-1],ppal[0],1)[0]*100 - Scue=slope.mean()*100 - Hmin=Elev[-1]; Hmax=Elev[puntto]; Hmean=Elev.mean() - HCmax=Elev[punto] - x,y = cu.basin_coordxy(self.structure,self.ncells) - CentXY = [np.median(x),np.median(y)] - #Genera un diccionario con las propiedades de la cuenca - self.GeoParameters={'Area_[km2]': Area, - 'Pend_Cauce_[%]':Scau, - 'Long_Cauce_[km]': Lcau, - 'Pend_Cuenca_[%]': Scue, - 'Long_Cuenca_[km]': Lpma, - 'Hmax_[m]':Hmax, - 'Hmin_[m]':Hmin, - 'Hmean_[m]':Hmean, - 'H_Cauce_Max_[m]':HCmax, - 'Centro_[X]': CentXY[0], - 'Centro_[Y]': CentXY[1], - 'Long_tot_cauces_[km]': TotalCauces, - 'Densidad_drenaje_[km/km2]': Densidad} - if GetPerim: - self.GeoParameters.update({'Perimetro_[km]':Perim}) - #Calcula los tiempos de concentracion - Tiempos={} - Tc=0.3*(Lcau/(Scue**0.25))**0.75 - Tiempos.update({'US Army': Tc}) - Tc=0.3*(Lcau/((Hmax-Hmin)/Lcau)**0.25)**0.75 - Tiempos.update({'Direccion Carreteras Espana': Tc}) - Tc=(0.02*(Lpma*1000.0)**0.77)/((Scau/100.0)**0.385)/60.0 - Tiempos.update({'Kiprich': Tc}) - Tc=8.157*((Area**0.316)/(((Scau*100)**0.17)*Scue**0.565)) - Tiempos.update({'Campo y Munera': Tc}) - Tc=(4*np.sqrt(Area)+1.5*Lcau)/(0.8*np.sqrt(Hmean)) - Tiempos.update({'Giandotti':Tc}) - Tc=0.4623*(Lcau**0.5)*((Scue/100.0)**(-0.25)) - Tiempos.update({'John Stone': Tc}) - Tc=(Lcau/Area)*(np.sqrt(Area)/Scau) - Tiempos.update({'Ventura': Tc}) - Tc=0.3*(Lcau/(((HCmax-Hmin)/Lcau)*100)**0.25)**0.75 - Tiempos.update({'Temez': Tc}) - self.Tc=Tiempos - #Si se habilita la funcion para guardar el ascii de param lo hace - if rutaParamASC is not None: - self.__WriteGeoParam__(rutaParamASC) - # Grafica Tc si se habilita - if plotTc is True: - self.Plot_Tc(ruta = rutaTcPlot, figsize=figsize) - #Funcion para escribir los parametros de la cuenca en un ascii - def __WriteGeoParam__(self,ruta): - f=open(ruta,'w') - f.write('------------------------------------------------------------ \n') - f.write('Parametros Cuenca \n') - f.write('------------------------------------------------------------ \n') - k=self.GeoParameters.keys() - for i in k: - v=self.GeoParameters[i] - if type(v) is not list: - f.write('%s : %.4f \n' % (i,v)) - f.write('------------------------------------------------------------ \n') - f.write('Tiempos de concentracion \n') - f.write('------------------------------------------------------------ \n') - k=self.Tc.keys() - for i in k: - v=self.Tc[i] - f.write('%s : %.4f \n' % (i,v)) - f.close() - - #Obtiene la envolvente de la cuenca - def __GetBasinPolygon__(self): - 'Descripcion: obtiene la envolvente de la cuenca, en coordenadas \n'\ - ' x,y, esta informacion luego sirve para plot y para escribir el\n'\ - ' shpfile de la cuenca\n'\ - #Evalua si se cuenta con rasterio en el sistema o no. - if FlagBasinPolygon: - #Obtiene mapa raster, propiedades geo y formato para escribir - Map, Prop = self.Transform_Basin2Map(np.ones(self.ncells)) - tt = [Prop[2], Prop[4].tolist(), 0.0, - Prop[1]*Prop[-2] + Prop[3], 0.0, -1*Prop[5].tolist()] - #Obtiene los shps con la forma de la o las envolventes de cuenca - Map = Map.T - mask = Map != -9999. - shapes = __fea__.shapes(Map, mask=mask, transform=tt) - #Obtiene el poligono de la cuenca completo - Shtemp = [] - flag = True - while flag: - try: - Shtemp.append(shapes.next()) - except: - flag = False - DicPoly = {} - for Sh in Shtemp: - Coord = Sh[0]['coordinates'] - Value = int(Sh[1]) - DicPoly.update({str(Value):{}}) - for cont,co in enumerate(Coord): - DicPoly[str(Value)].update({str(cont):np.array(co).T}) - #Por si hay mas de un poligono al interior - Tam = 0 - for k in DicPoly['1'].keys(): - if DicPoly['1'][k].size > Tam: - Tam = DicPoly['1'][k].size - goodKey = k - self.Polygon = DicPoly['1'][goodKey] - return 0 - else: - return 1 - - #Parametros por mapas (distribuidos) - def GetGeo_Cell_Basics(self): - 'Descripcion: Obtiene: area acumulada, long de celdas, Pendiente \n'\ - ' y Elevacion en cada elemento de la cuenca. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : no necesita nada es autocontenido.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'CellAcum : Cantidad de celdas acumuladas.\n'\ - 'CellLong : Longitud de cada una de las celdas [mts].\n'\ - 'CellSlope : Pendiente de cada una de las celdas [y/x].\n'\ - 'CellHeight : Elevacion de cada una de las celdas [m.s.n.m].\n'\ - #obtiene los parametros basicos por celdas - acum,longCeld,S0,Elev=cu.basin_basics(self.structure, - self.DEMvec,self.DIRvec,self.ncells) - self.CellAcum=acum; self.CellLong=longCeld - self.CellSlope=S0; self.CellHeight=Elev - #Obtiene el canal en la cuenca - self.CellCauce = np.zeros(self.ncells) - self.CellCauce[self.CellAcum>self.umbral]=1 - def GetGeo_StreamOrder(self, MajorBasins = False, umbral = 100, verbose = False, FirtsOrder = 1): - 'Descripcion: Obtiene el orden de horton para cada celda de \n'\ - ' cada ladera y para las celdas de cada cauce.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : no necesita nada es autocontenido.\n'\ - 'MajorBasins : Obtiene binarios con las sub-cuencas drenando.\n'\ - ' unicamente a cuencas de orden mayor (ej: todas las orden 2 que \n'\ - ' drenan a orden 3 o major).\n'\ - 'umbral: Cantidad minima de celdas para considerar canal (aplica cuando\n'\ - ' se obtienen las sub-cuencas mayores.\n'\ - 'verbose: Muestra el paso de calculo de cuencas mayores.\n'\ - 'FirtsOrder: Primer orden a partir dle cual se analizan ordenes mayores.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'CellHorton_Hill : Orden de horton de cada ladera.\n'\ - 'CellHorton_Stream : Orden de horton de cada elemento de cauce.\n'\ - #obtiene los parametros basicos por celdas - cauce,nodos_fin,n_nodos = cu.basin_subbasin_nod(self.structure,self.CellAcum,self.umbral,self.ncells) - sub_pert,sub_basin = cu.basin_subbasin_find(self.structure,nodos_fin,n_nodos,self.ncells) - sub_basins = cu.basin_subbasin_cut(n_nodos) - sub_horton,nod_horton = cu.basin_subbasin_horton(sub_basins,self.ncells,n_nodos) - self.CellHorton_Hill,sub_basin = cu.basin_subbasin_find(self.structure,nod_horton,n_nodos,self.ncells) - #Obtiene el canal en la cuenca - self.CellHorton_Stream = self.CellCauce * self.CellHorton_Hill - #Obtiene las cuencas mayores - if MajorBasins: - pos = np.where(models.control>0)[1] - X,Y = cu.basin_coordxy(self.structure, self.ncells) - DictBasins = {} - for Orden in range(FirtsOrder,self.CellHorton_Hill[-1]): - #Encuentra cuencas de un orden que drenen a un orden mayor - pos2 = np.where(self.CellHorton_Stream[pos] == Orden)[0] - drena = self.ncells - self.structure[0] - pos3 = np.where(self.CellHorton_Stream[drena[pos[pos2]]] > Orden)[0] - #Las ubica en un mapa dentro d ela cuenca - SubCuencas = np.zeros(self.ncells) - cont = 1 - for x,y in zip(X[pos[pos2[pos3]]], Y[pos[pos2[pos3]]]): - #Traza la cuenca - cuTemp = SimuBasin(x,y, self.DEM, self.DIR, umbral=umbral) - #La pega en una mascara con las cub-cuencas - Map, prop = cuTemp.Transform_Basin2Map(np.ones(cuTemp.ncells),) - Map[Map == -9999] = 0 - Var = self.Transform_Map2Basin(Map, prop) - Var[Var == 0] = -9999 - Var[Var == 1] = cont - ptemp = np.where(Var == cont)[0] - #Lo pega en la mascara de sub-uencas - SubCuencas[ptemp] = SubCuencas[ptemp] + Var[ptemp] - cont+=1 - #Agrega al diccionario - DictBasins.update({str(Orden):SubCuencas}) - #Si es verbose muestra en que paso va - if verbose: - print 'Sub-cuencas orden '+str(Orden)+' calculadas' - #Traza la cuenca original para no danar la estructura de guardado - cuTemp = SimuBasin(X[-1], Y[-1], self.DEM, self.DIR, umbral = umbral) - #Retorna el diccionario con las sub-cuencas mayore - return DictBasins - def GetGeo_IsoChrones(self,Tc,Niter=4): - 'Descripcion: Obtiene el tiempo de viaje aproximado de cada \n'\ - ' celda a la salida de la cuenca, para eso usa el tiempo de . \n'\ - ' concentracion obtenido por la funcion GetGeo_Parameters . \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - ' self : no necesita nada es autocontenido.\n'\ - ' Tc : Valor escalar de tiempo de concentracion.\n'\ - ' Niter: Cantidad de iteraciones para aproximar vel, defecto 4.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'isochrones : Mapa de viaje de cada celda a la salida [hrs].\n'\ - #Calcula la velocidad adecuada para que el tiempo coincida - acum,longCeld,S0,Elev=cu.basin_basics(self.structure, - self.DEM,self.DIR,cu.ncols,cu.nrows,self.ncells) - rangos=[50,25,1] - for i in range(Niter): - times=[] - for r in rangos: - speed = r*S0**(0.5) - time = cu.basin_time_to_out(self.structure, - longCeld,speed,self.ncells)/3600.0 - times.append(time[np.isfinite(time)].mean()) - for j in range(2): - if Tc>times[j] and Tc=i) & (time0], bins = binsN) - #Variables del elemento - self.width_hits = hn - self.width_distances = bn[:-1]/1000. - #Estandariza en terminos de probabilidad - hc = hc.astype(float); hc = hc / hc.sum() - hn = hn.astype(float); hn = hn / hn.sum() - #Grafica - fig = pl.figure(figsize=figsize) - ax = fig.add_subplot(111) - ax.plot(bc[:-1]/1000.0, hc, ccolor, lw = 3, label = 'Basin Width') - ax.plot(bn[:-1]/1000.0, hn, ncolor,lw = 3, label = 'Network Width') - ax.grid(True) - ax.set_xlabel('Distance to Outlet [$km$]', size = 16) - ax.set_ylabel('PDF', size = 16) - ax.fill_between(bc[:-1]/1000.0, hc, color = ccolor, alpha = 0.3) - ax.fill_between(bn[:-1]/1000.0, hn, color = ncolor, alpha = 0.3) - ax.set_ylim(0, np.max([hc.max(), hn.max()])+0.01) - ax.tick_params(labelsize = 15) - ax.legend(loc = 0) - ax2 = ax.twinx() - ax2.plot(bc[:-1]/1000.0, hc.cumsum(), ccolor, lw = 3, ls = '--', label = 'Basin Width') - ax2.plot(bn[:-1]/1000.0, hn.cumsum(), ncolor, lw = 3, ls = '--',label = 'Network Width') - ax2.tick_params(labelsize = 15) - ax2.set_ylabel('CDF', size = 16) - #Guarda la figura - if ruta is not None: - pl.savefig(ruta, bbox_inches='tight',pad_inches = 0.25) - if show: - pl.show() - #Retorna ejes de manipulacion - return ax,ax2 - - def GetGeo_Ppal_Hipsometric(self,umbral=1000, - intervals = 30): - 'Descripcion: Calcula y grafica la curva hipsometrica de\n'\ - ' la cuenca.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'umbral : cantidad minima de celdas para el trazado.\n'\ - 'intervals: Cantidad de intervalos en los cuales se haran .\n'\ - ' los muestreos de la curva hipsometrica.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Hipso : Curva hipsometrica en formato vectorial, contiene.\n'\ - ' - Curva sobre cauce ppal.\n'\ - ' - Curva como histograma de la cuenca.\n'\ - 'Figura: Figura de ambas curvas.\n'\ - # Obtiene los nodos de la red hidrica - cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( - self.structure, - self.CellAcum, - umbral, - self.ncells) - # Obtiene el cauce ppal - ppal_nceldas,punto = cu.basin_ppalstream_find( - self.structure, - nodos, - self.CellLong, - self.CellHeight, - self.ncells) - self.ppal_stream = cu.basin_ppalstream_cut(ppal_nceldas, - self.ncells) - #Corrige el perfil del cauce ppal - self.ppal_stream[0],self.ppal_slope = __ModifyElevErode__(self.ppal_stream[0]) - # Obtiene la curva hipsometrica - self.hipso_ppal, self.hipso_basin = cu.basin_ppal_hipsometric( - self.structure, - self.CellHeight, - punto, - intervals, - ppal_nceldas) - self.hipso_ppal[1],self.hipso_ppal_slope = __ModifyElevErode__(self.hipso_ppal[1]) - def GetGeo_IT(self): - 'Descripcion: Calcula el indice topografico para cada celda (Beven)\n'\ - ' Internamente calcula el area para cada elemento y la pendiente en radianes.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : no necesita nada es autocontenido.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'IT : Indice topografico adimensional, a mayor valor se supone un suelo mas humedo.\n'\ - #Obtiene el area - acum = cu.basin_acum(self.structure, self.ncells) - #Obtiene la pendiente en radianes - acum,longCeld,slope,Elev=cu.basin_basics(self.structure, - self.DEMvec,self.DIRvec,self.ncells) - slope = np.arctan(slope) - slope[slope == 0] = 0.0001 - return np.log((acum*cu.dxp) / np.tan(slope)) - - def GetGeo_HAND(self,umbral=1000): - 'Descripcion: Calcula Height Above the Nearest Drainage (HAND) \n'\ - ' y Horizontal Distance to the Nearest Drainage (HDND) (Renno, 2008). \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : no necesita nada es autocontenido.\n'\ - 'umbral : cantidad minima de celdas para el trazado.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'HAND : Elevacion sobre la red de drenaje cercana [mts].\n'\ - 'HDND : Distancia horizontal a la red de drenaje cercana [mts].\n'\ - #obtiene los parametros basicos por celdas - acum,longCeld,S0,Elev=cu.basin_basics(self.structure, - self.DEMvec,self.DIRvec,self.ncells) - cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( - self.structure,acum,umbral,self.ncells) - hand,hdnd,hand_destiny = cu.geo_hand(self.structure,Elev,longCeld,cauce,self.ncells) - handC=np.zeros(self.ncells) - handC[hand<5.3]=1 - handC[(hand>=5.3) & (hand<=15.0)]=2 - handC[(hand>15.0) & (S0<0.076)]=4 - handC[(hand>15.0) & (S0>=0.076)]=3 - self.CellHAND=hand - self.CellHAND_class=handC - self.CellHDND=hdnd - self.CellHAND_drainCell=hand_destiny - - def GetGeo_Sections(self, NumCeldas = 6): - 'Descripcion: Obtiene secciones transversales a traves de todos.\n'\ - ' los elementos de la red de drenaje, las secciones se obtienen\n'\ - ' en la direccion perpendicular al flujo, es decir si el mapa de\n'\ - ' direcciones indica en una celda la direccion norte, las secciones\n'\ - ' se obtienen en lsa direcciones oriente, occidente, con NumCeldas\n'\ - ' a cada lado de la celda tipo cauce.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'NumCeldas: Cantidad de celdas para elaborar secciones a ambos lados.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self.Sections : Secciones a traves de los elementos del cauce.\n'\ - ' su tamano es [NumCeldas*2 + 1, self.ncells]\n'\ - #Obtiene mapa de cauces - self.GetGeo_Cell_Basics() - #Obtiene vector de direcciones - directions = self.Transform_Map2Basin(self.DIR, - [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy ,0.0]) - #Obtiene las secciones - self.Sections, self.Sections_Cells = cu.basin_stream_sections(self.structure, - self.CellCauce, directions, self.DEM, NumCeldas, - self.ncells, cu.ncols, cu.nrows) - - #------------------------------------------------------ - # Subrutinas para el calculo de extremos mediante hidrografa unitaria sintetica - #------------------------------------------------------ - def GetHU_Snyder(self,Area,Tc,Cp=0.8,Fc=2.9,pequena='si'): - 'Descripcion: Obtiene HU segun Snyder.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'Area: area de la cuenca en km2.\n'\ - 'Tc: Tiempo de concentracion en Horas.\n'\ - 'Cp : Factor de escalamiento [0.8].\n'\ - 'Fc : Factor de escalamiento [2.9].\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Tiempo : Tiempo total de duracion [M].\n'\ - 'Q : Caudal unitario.\n'\ - 'HU : Reglas del hidrograma unitario.\n'\ - #Calcula parametros para la hidrografa - Tr=0.6*Tc # [h] - T=0.1*Tc # [h] - Ts=Tr/5.5 # [h] - up=Cp*640/(Tr+(T-Ts)/4) #pie3/s/mi2/Pulg - Up=up*0.386*Area - Up=Up*(0.3048)**3.0/25.4 - Tp=T/2+Tr # horas - Tb=3+3*Tr/24 # dias - W50=770/up**1.08 - W75=440/up**1.08 - # Factor de multiplicacion - tb=Tp*Fc #horas - #obtiene las coordenadas del hidrograma - HU=[[0,0]] - At=(Tp-W50/3)*60; Aq=0.5*Up; HU.append([At,Aq]) - Bt=(Tp-W75/3)*60; Bq=0.75*Up; HU.append([Bt,Bq]) - Tpt=Tp*60; Tpq=Up; HU.append([Tpt,Tpq]) - Dt=(Tp+2*W75/3)*60; Dq=0.75*Up; HU.append([Dt,Dq]) - Et=(Tp+2*W50/3)*60; Eq=0.5*Up; HU.append([Et,Eq]) - if pequena=='si': - Tbt=tb*60 - else: - Tbt=Tb*60 - HU.append([Tbt,0]) - HU=np.array(HU).T - #Obtiene los intervalod de tiempo - Dt=Tc*0.1*60 #min - Tiempo=np.arange(0,Tbt+Dt,Dt) - #Obtiene la HU para los intervalos de tiempo necesarios - Q=np.zeros(Tiempo.size) - for cont,t in enumerate(Tiempo): - for h1,h2 in zip(HU.T[:-1],HU.T[1:]): - if t>h1[0] and tt1: - Q[cont]=HU[1,2]*np.exp((t1-t[1])/(3*k)) - if t[1]to: - Q[cont]=HU[1,1]*np.exp((to-t[1])/k) - return Tiempo*60,Q,HU - def GetHU_SCS(self,AreaCuenca,Tc,N=25): - 'Descripcion: Obtiene HU segun SCS.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'AreaCuenca: area de la cuenca en km2.\n'\ - 'Tc: Tiempo de concentracion en Horas.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Tiempo : Tiempo total de duracion [M].\n'\ - 'Q : Caudal unitario.\n'\ - 'HU : Reglas del hidrograma unitario.\n'\ - #Parametros fijos - ttp=np.array([0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1, - 1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0,2.2,2.4,2.6,2.8,3.0,3.2, - 3.4,3.6,3.8,4.0,4.5,5.0]) - UUp=np.array([0.0,0.03,0.1,0.19,0.31,0.47,0.66,0.82,0.93,0.99,1.0,0.99,0.93,0.86, - 0.78,0.68,0.56,0.46,0.39,0.33,0.28,0.21,0.15,0.11,0.08,0.06,0.04,0.03,0.02,0.02,0.01, - 0.01,0.0]) - #Parametros de la hidrografa - Trezago=(3.0/5.0)*float(Tc) - Tlluvia=0.133*Tc - Tpico=Tlluvia/2.0+Trezago - Upa=484.0*AreaCuenca*0.386/Tpico - Upm=Upa*0.3048**3/25.4 - #Obtiene el HU - HU=[] - for t,u in zip(ttp,UUp): - uTemp=u*Upa - HU.append([t*Tpico,uTemp*0.3048**3/25.4]) - HU=np.array(HU) - #Obtiene los intervalod de tiempo - Dt=Tc*0.1*60 #min - #Obtiene la HU para los intervalos de tiempo necesarios - Q=[]; flag=True - Tiempo=[];t=0.0 - for i in range(N): - for h1,h2 in zip(HU[:-1],HU[1:]): - if t>=h1[0] and t0: - L.append(((i-Ia)**2)/(i-Ia+S)) - else: - L.append(0) - lluviaTrTemp.append(L) - lluviaTrTemp=np.array(lluviaTrTemp) - lluviaTrEfect=lluviaTrTemp[:,1:]-lluviaTrTemp[:,:-1] - lluviaTrEfect[lluviaTrEfect<0]=0 - lluviaTrEfect=np.insert(lluviaTrEfect,0,lluviaTrTemp[:,0],axis=1) - if plot=='si': - #if Tr==None or len(Tr)<>IntTr.size(): - # Lista=[2.33,5,10,25,50,100,500,1000] - # Tr=[l for l in Lista[:IntTr.size]] - fig=pl.figure(edgecolor='w',facecolor='w') - ax=fig.add_subplot(111) - X=np.linspace(0,Dur,lluviaTrEfect.shape[1]) - Grosor=np.arange(0.5,4,0.2) - for l,le,t,g in zip(lluviaTr,lluviaTrEfect,Tr,Grosor): - ax.plot(X,l,c='b',lw=g,label=str(t)) - if CN is not None: - for l,le,t,g in zip(lluviaTr,lluviaTrEfect,Tr,Grosor): - ax.plot(X,le,c='r',lw=g,label=str(t)) - ax.set_xlabel('Tiempo $[h]$',size=16) - ax.set_ylabel('Precipitacion $[mm]$',size=16) - ax.grid(True) - ax.tick_params(labelsize=15) - pl.legend(loc=0,ncol=2) - if ruta is not None: - pl.savefig(ruta,bbox_inches='tight') - pl.show() - if CN is not None: - return lluviaTr,np.array(lluviaTrEfect),S - else: - return lluviaTr - #Convolucion de la tormenta de diseno - def GetHU_Convolution(self,Tiempo,Qhu,lluvEfect): - 'Descripcion: Realia la convolucion de los hidrogramas unitarios \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'Tiempo : Vector de la duracion de la hidrografa unitaria [Nt].\n'\ - 'Qhu : Valores del caudal unitario de la hidrografa unitaria [Nt].\n'\ - 'lluvEfect : Lluvia efectiva en un evento de tormenta cualquiera [Nt, Tr].\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Qtr : Hidrografa para cada periodo de retorno [M, Tr].\n'\ - 'QmaxTr : Caudal maximo para cada periodo de retorno [Tr].\n'\ - 'Tiempo : Tiempo total de duracion [M].\n'\ - #Calcula el caudal convulucionado - Qtr=[]; QmaxTr=[] - for le in lluvEfect: - Qi=np.array([i*Qhu for i in le]) - Qconv=np.zeros(Qhu.size+lluvEfect.shape[1]-1) - for cont,q in enumerate(Qi): - Qconv[cont:cont+Qhu.size]=Qconv[cont:cont+Qhu.size]+q - Qtr.append(Qconv) - QmaxTr.append(Qconv.max()) - #Calcula el tiempo para toda la hidrografa - Dt=Tiempo[1]-Tiempo[0]; Tlast=Tiempo[-1] - T=list(Tiempo) - for i in range(1,lluvEfect.shape[1]): - T.append(Tlast+i*Dt) - return np.array(Qtr), np.array(QmaxTr),np.array(T) - #Grafica los hidrogramas sinteticos - def PlotHU_Synthetic(self,DictHU,ruta = None): - fig=pl.figure(edgecolor='w',facecolor='w') - ax=fig.add_subplot(111) - colors = ['b','r','k','g','m'] - for co,k in enumerate(DictHU.keys()): - ax.plot(DictHU[k]['time'], - DictHU[k]['HU'], - c=colors[co],lw=1.5,label=k) - ax.grid(True) - ax.set_xlabel('Tiempo $[min]$',size=14) - ax.set_ylabel('HU $[m^3/seg/mm]$',size=14) - ax.legend(loc=0) - if ruta is not None: - pl.savefig(ruta,bbox_inches='tight') - pl.show() - - #------------------------------------------------------ - # Trabajo con mapas externos y variables fisicas - #------------------------------------------------------ - def Transform_Map2Basin(self,Map,MapProp): - 'Descripcion: A partir de un mapa leido obtiene un vector \n'\ - ' con la forma de la cuenca, el cual luego puede ser agregado a esta. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'Map : Matriz con la informacion del mapa.\n'\ - 'MapProp : Propiedades del mapa.\n'\ - ' 1. Ncols Mapa.\n'\ - ' 2. Nrows Mapa.\n'\ - ' 3. Xll Mapa.\n'\ - ' 4. Yll Mapa.\n'\ - ' 5. dx Mapa.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'vecMap : Vector conla informacion del mapa al interio de la cuenca.\n'\ - #Comienza le codifgo - vec = cu.basin_map2basin(self.structure, - Map,MapProp[2],MapProp[3],MapProp[4],MapProp[5], - cu.nodata, - self.ncells, - MapProp[0],MapProp[1]) - return vec - def Transform_Basin2Map(self, BasinVar, ruta = None, DriverFormat='GTiff', - EPSG=4326): - 'Descripcion: A partir de un vector con propiedades de la cuenca en celdas\n'\ - ' obtiene un mapa (matriz) con las propiedades del DEM, este puede ser escrito \n'\ - ' en algun formato legible por GDAL. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : la cuenca misma.\n'\ - 'BasinVar : Vector con la variable de la cuenca a escribir [ncells].\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Map : Matriz con la variable de la cuenca, donde no hay cuenca es wmf.cu.nodata .\n'\ - ' el tamano de la matriz es igual a DEM.shape.\n'\ - # Convierte la variable a mapa - map_ncols,map_nrows = cu.basin_2map_find(self.structure,self.ncells) - M,mxll,myll = cu.basin_2map(self.structure, BasinVar, - map_ncols, map_nrows, self.ncells) - # Si exporta el mapa lo guarda si no simplemente devuelve la matriz - if ruta is not None: - Save_Array2Raster(M, [map_ncols,map_nrows,mxll,myll,cu.dx,cu.nodata], - ruta = ruta, EPSG = EPSG, Format = DriverFormat) - return M, [map_ncols,map_nrows,mxll,myll,cu.dx,cu.dy,cu.nodata] - - def Transform_Hills2Basin(self,HillsMap): - 'Descripcion: A partir de un vector con propiedades de las laderas\n'\ - ' obtiene un vector con las propiedades por celda, ojo estas \n'\ - ' quedan con las formas de las laderas y la variable queda agregada. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : la cuenca misma.\n'\ - 'MapHills : Vector con las variables por laderas [nhills].\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'CellMap : Vector con la variable agregada por laderas, pero .\n'\ - ' pasada a celdas.\n'\ - #Genera el mapa de basin vacio - CellMap = np.ones(self.ncells) - #itera por la cantidad de elementos y les va asignando - for i,k in enumerate(HillsMap[::-1]): - CellMap[self.hills_own==i+1] = k - return CellMap - def Transform_Basin2Hills(self,CellMap,mask=None,SumMeanMax=0): - 'Descripcion: A partir de un vector tipo Basin obtiene un\n'\ - ' vector del tipo laderas, en donde las propiedades se \n'\ - ' agregan para cada ladera. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : la cuenca misma.\n'\ - 'CellMap : Vector con las propiedades por celdas [ncells].\n'\ - 'mask : Celdas sobre las cuales se agrega la variable (1), y\n'\ - ' sobre las que no (0).\n'\ - 'SumMeanMax : si la variable sera agregada como un promedio (0)\n'\ - ' o como una suma (1), o como el maximo valor (2).\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'HillsMap : Vector con las prop agregadas a laderas .\n'\ - #Si hay mascara la tiene en cuenta - if mask is not None: - Ma = np.zeros(self.ncells) - if type(mask) is float or type(mask) is int: - Ma[CellMap==mask] = 1 - elif type(mask) is np.ndarray: - Ma = np.copy(mask) - else: - Ma = np.ones(self.ncells) - #Pasa el mapa de celdas a mapa de laderas - HillsMap = cu.basin_subbasin_map2subbasin(self.hills_own, - CellMap, self.nhills, Ma, SumMeanMax, self.ncells) - return HillsMap - - def Transform_Basin2Polygon(self, Vector,): - 'Descripcion: convierte una variable de topologia de la cuenca en varios poligonos\n'\ - ' cada poligono corresponde al numero de esa variable\n'\ - 'parametros\n'\ - '----------\n'\ - 'Vector: Vector con la topologia de la cuenca que contiene los datos a transformar' - 'Retorna\n'\ - '----------\n'\ - 'DicPoly: Diccionario donde el key indica el poligono encontrado y contiene las coord'\ - #Obtiene mapa raster, propiedades geo y formato para escribir - Map, Prop = self.Transform_Basin2Map(Vector) - tt = [Prop[2], Prop[4].tolist(), 0.0, - Prop[1]*Prop[-2] + Prop[3], 0.0, -1*Prop[5].tolist()] - #Obtiene los shps con la forma de la o las envolventes de cuenca - Map = Map.T - mask = Map != -9999. - shapes = __fea__.shapes(Map, mask=mask, transform=tt) - #Obtiene el poligono de la cuenca completo - DicPoly = {} - for Sh in shapes: - Coord = Sh[0]['coordinates'] - Value = int(Sh[1]) - DicPoly.update({str(Value):{}}) - for cont,co in enumerate(Coord): - DicPoly[str(Value)].update({str(cont):np.array(co).T}) - return DicPoly - - #------------------------------------------------------ - # Trabajo con datos puntuales puntos - #------------------------------------------------------ - def Points_Points2Stream(self,coordXY,ids): - 'Descripcion: toma las coordenadas de puntos XY y las mueve\n'\ - ' hacia los cauces de la cuenca\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'coordXY : coordenadas de los puntos [2,Ncoord].\n'\ - 'ids : Identificacion de los puntos que se van a mover.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'coordXYNew : Coordenadas transportadas a los cauces.\n'\ - 'basin_pts : Vector con la forma de la cuenca con los puntos.\n'\ - ' donde quedaron localizadas las coordenadas.\n'\ - 'idsOrdered : El orden en que quedaron los Ids ingresados.\n'\ - 'Ver Tambien\n'\ - '----------\n'\ - 'Points_Point2Basin\n'\ - #Obtiene el cauce - self.GetGeo_Cell_Basics() - #modifica los puntos - res_coord,basin_pts,xy_new = cu.basin_stream_point2stream( - self.structure, - self.CellCauce, - ids, - coordXY, - coordXY.shape[1], - self.ncells) - return xy_new, basin_pts, basin_pts[basin_pts<>0] - def Points_Points2Basin(self,coordXY,ids): - 'Descripcion: toma las coordenadas de puntos XY y las pone\n'\ - ' en la cuenca, no las mueve hacia los cuaces\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'coordXY : coordenadas de los puntos [2,Ncoord].\n'\ - 'ids : Identificacion de los puntos que se van a mover.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'basin_pts : Vector con la forma de la cuenca con los puntos.\n'\ - ' donde quedaron localizadas las coordenadas.\n'\ - 'idsOrdered : El orden en que quedaron los Ids ingresados.\n'\ - 'Ver Tambien\n'\ - '----------\n'\ - 'Points_Point2Stream\n'\ - #Obtiene el cauce - self.GetGeo_Cell_Basics() - #modifica los puntos - res_coord,basin_pts = cu.basin_point2var( - self.structure, - ids, - coordXY, - coordXY.shape[1], - self.ncells) - return basin_pts,basin_pts[basin_pts<>0] - #------------------------------------------------------ - # Caudales de largo plazo y regionalizacion - #------------------------------------------------------ - #Caudal de largo plazo - def GetQ_Balance(self,Precipitation, Tipo_ETR = 1, mu_choud = 1.37): - 'Descripcion: Calcula el caudal medio por balance de largo plazo\n'\ - ' para ello requiere conocer la precipitacion y el metodo de\n'\ - ' estimacion de la evaporacion.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : no necesita nada es autocontenido.\n'\ - 'Precipitation : Cantidad anual de lluvia, escalar o vector.\n'\ - 'Elevacion : Elevacion en cada punto de la cuenca.\n'\ - 'Tipo_ETR : Tipo de ecuacion para calcular la evaporacion.\n'\ - ' -1. Turc.\n'\ - ' -2. Cenicafe Budyko.\n'\ - ' -3. Choundry.\n'\ - ' Defecto: 1.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self.CellQmed : Caudal medio calculado para toda la cuenca.\n'\ - 'self.CellETR : ETR calculada para toda la cuenca.\n'\ - #Calcula las propiedades de la cuenca - self.GetGeo_Cell_Basics() - #Determina si la precipitacion es un vector o un escalar - if type(Precipitation) is int or type(Precipitation) is float: - precip = np.ones(self.ncells)*Precipitation - elif type(Precipitation) is np.ndarray: - precip = Precipitation - #Calcula el qmed - self.CellQmed,self.CellETR = cu.basin_qmed( - self.structure, - self.CellHeight, - precip, - Tipo_ETR, - mu_choud, - self.ncells,) - - #Caudales extremos - def GetQ_Max(self,Qmed,Coef=[6.71, 3.29], Expo= [0.82, 0.64], Cv = 0.5, - Tr = [2.33, 5, 10, 25, 50, 100], Dist = 'gumbel', metodo = 'poveda', - Expo2 = [0.7745, 0.4608]): - 'Descripcion: Calcula el caudal maximo para diferentes\n'\ - ' periodos de retorno. Recibe como entrada el caudal medio \n'\ - ' calculado con GetQ_Balance.\n'\ - ' el calculo se hace a partir de la ecuacion:.\n'\ - ' MedMax = Coef[0] * Qmed ** Exp[0] .\n'\ - ' DesMax = Coef[1] * Qmed ** Exp[1] .\n'\ - ' Qmax = MedMax + K(Tr) * DesMax.\n'\ - ' Donde K es un coeficiente que depende de Tr y f(x).\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'Qmed : Caudal medio calculado con GetQ_Balance.\n'\ - 'Coef : Coeficientes para media y desviacion [6.71, 3.29].\n'\ - 'Expo : Exponentes para media y desviacion [0.82, 0.64].\n'\ - 'Cv : Coeficiente de escalamiento [0.5].\n'\ - 'Tr : Periodo de retorno [2.33, 5, 10, 25, 50, 100].\n'\ - 'Dist : Distrbucion [gumbel/lognorm].\n'\ - 'metodo: Poveda (u = cQA^a) o atlas (u = C(P-E)^a A^b), en este segundo caso Qmed = P-E.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'CellQmax : Caudal maximo para los diferentes periodos.\n'\ - # Calcula la media y desviacion - if metodo == 'poveda': - MedMax = Coef[0] * Qmed ** Expo[0] - DesMax = Coef[1] * Qmed ** Expo[1] - elif metodo == 'atlas': - Acum = cu.basin_acum(self.structure, self.ncells) - Acum = Acum * (cu.dxp**2)/1e6 - MedMax = Coef[0] * (Qmed ** Expo[0]) * (Acum**Expo2[0]) - DesMax = Coef[1] * (Qmed ** Expo[1]) * (Acum**Expo2[1]) - #Itera para todos los periodos de retorno - Qmax=[] - for t in Tr: - #Calcula k - if Dist is 'gumbel': - k=-1*(0.45+0.78*np.log(-1*np.log(1-1/float(t)))) - elif Dist is 'lognorm': - Ztr=norm.ppf(1-1/float(t)) - k=(np.exp(Ztr*np.sqrt(np.log(1+Cv**2))-0.5*np.log(1-Cv**2))-1)/Cv - #Calcula el caudal maximo - Qmax.append(list(MedMax+k*DesMax)) - return np.array(Qmax) - - def GetQ_Min(self,Qmed,Coef=[0.4168, 0.2], Expo= [1.058, 0.98], Cv = 0.5, - Tr = [2.33, 5, 10, 25, 50, 100], Dist = 'gumbel'): - 'Descripcion: Calcula el caudal minimo para diferentes\n'\ - ' periodos de retorno. Recibe como entrada el caudal medio \n'\ - ' calculado con GetQ_Balance.\n'\ - ' el calculo se hace a partir de la ecuacion:.\n'\ - ' MedMin = Coef[0] * Qmed ** Exp[0] .\n'\ - ' DesMin = Coef[1] * Qmed ** Exp[1] .\n'\ - ' Qmin = MedMin + K(Tr) * DesMin.\n'\ - ' Donde K es un coeficiente que depende de Tr y f(x).\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'Qmed : Caudal medio calculado con GetQ_Balance.\n'\ - 'Coef : Coeficientes para media y desviacion [6.71, 3.29].\n'\ - 'Expo : Exponentes para media y desviacion [0.82, 0.64].\n'\ - 'Cv : Coeficiente de escalamiento [0.5].\n'\ - 'Tr : Periodo de retorno [2.33, 5, 10, 25, 50, 100].\n'\ - 'Dist : Distrbucion [gumbel/lognorm].\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'CellQmax : Caudal maximo para los diferentes periodos.\n'\ - # Calcula la media y desviacion - MedMin = Coef[0] * Qmed ** Expo[0] - DesMin = Coef[1] * Qmed ** Expo[1] - #Itera para todos los periodos de retorno - Qmin=[] - for t in Tr: - #Calcula k - if Dist is 'gumbel': - k = (-1*np.sqrt(6)/np.pi)*(0.5772+np.log(-1*np.log(1/float(t)))) - elif Dist is 'lognorm': - Ztr=norm.ppf(1/float(t)) - k = 1*(np.exp(Ztr*np.sqrt(np.log(1+Cv**2))-0.5*np.log(1-Cv**2))-1)/Cv - #Calcula el caudal maximo - Qmin.append(list(MedMin+k*DesMin)) - return np.array(Qmin) - - #------------------------------------------------------ - # Guardado shp de cuencas y redes hidricas - #------------------------------------------------------ - def Save_Net2Map(self,ruta,dx=cu.dxp,umbral=None, - qmed=None,Dict=None,DriverFormat='ESRI Shapefile', - EPSG=4326, NumTramo = True, formato = '%.2f'): - 'Descripcion: Guarda la red hidrica simulada de la cuenca en .shp \n'\ - ' Puede contener un diccionario con propiedades de la red hidrica. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : no necesita nada es autocontenido.\n'\ - 'ruta : Lugar y nombre donde se va a guardar la red hidrica.\n'\ - 'dx : Longitud de las celdas planas (Valor de Dx plano asignado a wmf.cu.dxp).\n'\ - 'umbral : cantidad de celdas necesarias para corriente (Valor del umbral asignado a self.umbral).\n'\ - 'qmed : caudal medio calculado por alguna metodologia.\n'\ - 'Dict : Diccionario con parametros de la red hidrica que se quieren imprimir.\n'\ - 'DriverFormat : nombre del tipo de archivo vectorial de salida (ver OsGeo).\n'\ - 'EPSG : Codigo de proyeccion utilizada para los datos, defecto WGS84.\n'\ - 'NumTramo: Poner o no el numero de tramo en cada elemento de la red.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Escribe un archivo vectorial con la estructura de la red hidrica y sus propiedades.\n'\ - #varia el umbral en funcion de self - if umbral == None: - umbral = self.umbral - #division de la cuenca - acum=cu.basin_acum(self.structure,self.ncells) - cauce,nod_f,n_nodos=cu.basin_subbasin_nod(self.structure,acum,umbral,self.ncells) - sub_pert,sub_basin=cu.basin_subbasin_find(self.structure,nod_f,n_nodos,self.ncells) - sub_basins=cu.basin_subbasin_cut(n_nodos) - sub_horton,nod_hort=cu.basin_subbasin_horton(sub_basins,self.ncells,n_nodos) - sub_hort=cu.basin_subbasin_find(self.structure,nod_hort,n_nodos,self.ncells)[0] - cauceHorton=sub_hort*cauce - #Obtiene la red en manera vectorial - nodos = cu.basin_stream_nod(self.structure,acum,umbral,self.ncells)[1] - netsize = cu.basin_netxy_find(self.structure,nodos,cauceHorton,self.ncells) - net=cu.basin_netxy_cut(netsize,self.ncells) - #Para net con caudal medio - if qmed is not None: - netsize = cu.basin_netxy_find(self.structure,nodos,cauce*qmed,self.ncells) - netQmed=cu.basin_netxy_cut(netsize,self.ncells) - #Para net con tramos - if NumTramo: - netsize2 = cu.basin_netxy_find(self.structure,nodos,sub_pert*cauce,self.ncells) - netTramo = cu.basin_netxy_cut(netsize2,self.ncells) - #Cortes - cortes=np.where(net[0,:]==-999) - cortes=cortes[0].tolist() - cortes.insert(0,0) - #Escribe el shp de la red hidrica - spatialReference = osgeo.osr.SpatialReference() - spatialReference.ImportFromEPSG(EPSG) - driver = osgeo.ogr.GetDriverByName(DriverFormat) - if os.path.exists(ruta): - driver.DeleteDataSource(ruta) - shapeData = driver.CreateDataSource(ruta) - layer = shapeData.CreateLayer('layer1', spatialReference, osgeo.ogr.wkbLineString) - layerDefinition = layer.GetLayerDefn() - new_field=osgeo.ogr.FieldDefn('Long[km]',osgeo.ogr.OFTReal) - layer.CreateField(new_field) - new_field=osgeo.ogr.FieldDefn('Horton',osgeo.ogr.OFTInteger) - layer.CreateField(new_field) - #coloca los nodos - if NumTramo: - new_field=osgeo.ogr.FieldDefn('Tramo',osgeo.ogr.OFTInteger) - layer.CreateField(new_field) - if qmed is not None: - new_field=osgeo.ogr.FieldDefn('Qmed[m3s]',osgeo.ogr.OFTReal) - layer.CreateField(new_field) - if Dict is not None: - if type(Dict==dict): - netDict=[] - for k in Dict.keys(): - new_field=osgeo.ogr.FieldDefn(k[:10],osgeo.ogr.OFTReal) - layer.CreateField(new_field) - netsizeT = cu.basin_netxy_find(self.structure,nodos,cauce*Dict[k],self.ncells) - netDict.append(cu.basin_netxy_cut(netsize,self.ncells)) - #Para cada tramo - featureFID=0 - for i,j in zip(cortes[:-1],cortes[1:]): - line = osgeo.ogr.Geometry(osgeo.ogr.wkbLineString) - for x,y in zip(net[1,i+1:j],net[2,i+1:j]): - line.AddPoint_2D(float(x),float(y)) - feature = osgeo.ogr.Feature(layerDefinition) - feature.SetGeometry(line) - feature.SetFID(0) - feature.SetField('Long[km]',(net[1,i+1:j].size*dx)/1000.0) - feature.SetField('Horton',int(net[0,i+1])) - if qmed is not None: - feature.SetField('Qmed[m3s]',float(netQmed[0,i+1])) - if NumTramo: - feature.SetField('Tramo',int(netTramo[0,i+1])) - if Dict is not None: - if type(Dict==dict): - for n,k in zip(netDict,Dict.keys()): - feature.SetField(k[:10],float(formato % n[0,i+1])) - #featureFID+=1 - layer.CreateFeature(feature) - line.Destroy() - feature.Destroy() - shapeData.Destroy() - def Save_Basin2Map(self,ruta,dx=30.0,Param={}, - DriverFormat='ESRI Shapefile',EPSG=4326, GeoParam = False): - 'Descripcion: Guarda un archivo vectorial de la cuenca en .shp \n'\ - ' Puede contener un diccionario con propiedades. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : no necesita nada es autocontenido.\n'\ - 'ruta : Lugar y nombre donde se va a guardar la cuenca.\n'\ - 'dx : Longitud de las celdas planas.\n'\ - 'DriverFormat : nombre del tipo de archivo vectorial de salida (ver OsGeo).\n'\ - 'EPSG : Codigo de proyeccion utilizada para los datos, defecto WGS84.\n'\ - 'GeoParam: (False) determina si calcular de una los parametros geomorfo o no.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Escribe un archivo vectorial de la cuenca.\n'\ - #Obtiene el perimetro de la cuenca - #nperim = cu.basin_perim_find(self.structure,self.ncells) - #basinPerim=cu.basin_perim_cut(nperim) - - #Parametros geomorfo - if GeoParam: - self.GetGeo_Parameters() - DictParam = {} - for k in self.GeoParameters.keys(): - DictParam.update({k[:8]: self.GeoParameters[k]}) - #Genera el shapefile - spatialReference = osgeo.osr.SpatialReference() - spatialReference.ImportFromEPSG(EPSG) - driver = osgeo.ogr.GetDriverByName(DriverFormat) - if os.path.exists(ruta): - driver.DeleteDataSource(ruta) - shapeData = driver.CreateDataSource(ruta) - layer = shapeData.CreateLayer('layer1', spatialReference, osgeo.ogr.wkbPolygon) - layerDefinition = layer.GetLayerDefn() - for p in Param.keys(): - #new_field=osgeo.ogr.FieldDefn(p[:p.index('[')].strip()[:10],osgeo.ogr.OFTReal) - new_field=osgeo.ogr.FieldDefn(p,osgeo.ogr.OFTReal) - layer.CreateField(new_field) - if GeoParam: - for p in DictParam.keys(): - new_field=osgeo.ogr.FieldDefn(p,osgeo.ogr.OFTReal) - layer.CreateField(new_field) - #Calcula el tamano de la muestra - ring = osgeo.ogr.Geometry(osgeo.ogr.wkbLinearRing) - for i in self.Polygon.T: - ring.AddPoint(x=float(i[0]),y=float(i[1])) - poly=osgeo.ogr.Geometry(osgeo.ogr.wkbPolygon) - poly.AddGeometry(ring) - feature = osgeo.ogr.Feature(layerDefinition) - feature.SetGeometry(poly) - feature.SetFID(0) - for p in Param.keys(): - #feature.SetField(p[:p.index('[')].strip()[:10],float("%.2f" % Param[p])) - feature.SetField(p,float("%.2f" % Param[p])) - #Si calcula parametros geomorfo - if GeoParam: - for p in DictParam.keys(): - feature.SetField(p,float("%.2f" % DictParam[p])) - layer.CreateFeature(feature) - poly.Destroy() - ring.Destroy() - feature.Destroy() - shapeData.Destroy() - - #------------------------------------------------------ - # Graficas de la cuenca - #------------------------------------------------------ - def Plot_basin(self,vec=None,Min=None, - Max=None,ruta=None,figsize=(10,7), - ZeroAsNaN ='no',extra_lat=0.0,extra_long=0.0,lines_spaces='Default', - xy=None,xycolor='b',colorTable=None,alpha=1.0,vmin=None,vmax=None, - colorbar=True, colorbarLabel = None,axis=None,rutaShp=None,shpWidth = 0.7, - shpColor = 'r',axloc = 111, fig = None, EPSG = 4326,backMap = False, - **kwargs): - #Plotea en la terminal como mapa un vector de la cuenca - 'Funcion: Plot_basin\n'\ - 'Descripcion: Genera un plot del mapa entregado.\n'\ - 'del mismo en forma de mapa \n'\ - 'Parametros Obligatorios:.\n'\ - ' -basin: Vector con la forma de la cuenca.\n'\ - ' -vec: Vector con los valores a plotear.\n'\ - 'Parametros Opcionales:.\n'\ - ' -Min: Valor minimo del plot, determina el rango de colores.\n'\ - ' -Max: Valor maximo del plot, determina el rango de colores.\n'\ - ' -ruta: Ruta en la cual se guarda la grafica.\n'\ - ' -colorbar: Muestra o no la barra de colores, defecto: True.\n'\ - ' -figsize: tamano de la ventana donde se muestra la cuenca.\n'\ - ' -ZeroAsNaN: Convierte los valores de cero en NaN.\n'\ - ' -rutaShp: Ruta a un vectorial que se quiera mostrar en el mapa.\n'\ - ' -shpWidth: Ancho de las lineas del shp cargado.\n'\ - ' -shpColor: Color de las lineas del shp cargado.\n'\ - ' -backMap: Pone de fondo un mapa tipo arcGIS.\n'\ - 'Otros argumentos:.\n'\ - ' -axis = Entorno de grafica que contiene elementos de las figuras.\n'\ - ' -parallels = Grafica Paralelos, list-like.\n'\ - ' -parallels_labels = Etiquetas de los paralelos, list-like.\n'\ - ' labels = [left,right,top,bottom].\n'\ - ' Ejemplo:\n'\ - ' m.drawparallels(parallels,labels=[False,True,True,False]).\n'\ - ' -parallels_offset: desplazamiento de las coordenadas en X.\n'\ - ' -meridians = Grafica Meridianos, list-like.\n'\ - ' -meridians_labels = Etiquetas de los meridianos, list-like.\n'\ - ' -meridians_offset: desplazamiento de las coordeandas en Y.\n'\ - ' -per_color = Color del perimetro.\n'\ - ' -per_lw = Ancho de linea del perimetro.\n'\ - ' -colorbarLabel = Titulo del colorbar.\n'\ - ' -xy_edgecolor = Color de la linea exterior del scatter .\n'\ - ' -xy_lw = Ancho de linea del Scatter .\n'\ - ' -xy_s = Tamano del scatter.\n'\ - ' -xy_colorbar: Coloca o no barra de colores del scatter enviado (False).\n'\ - ' -show = boolean, si es True muestra la grafica.\n'\ - ' -cbar_ticks: (None) ubicacion de los ticks del cbar.\n'\ - ' -cbar_ticklabels: (None) Labels a poner sobre los ticks.\n'\ - ' -cbar_ticksize: (14) Tamano de los ticks.\n'\ - ' -ShpIsPolygon: Indica si ese shp cargado es poligono (True) o no (False).\n'\ - ' -shpAlpha: transparencia del shp (0.5).\n'\ - 'Retorno:.\n'\ - ' -Actualizacion del binario .int\n'\ - ' -m = Para continuar graficando encima del entorno creado en Basemap\n'\ - ' Ejemplo:.\n'\ - ' m = Plot_basin(**args).\n'\ - ' m.scatter(coordenada_x,coordenada_y).\n' - #Prop de la barra de colores - cbar_ticklabels = kwargs.get('cbar_ticklabels', None) - cbar_ticks = kwargs.get('cbar_ticks', None) - cbar_ticksize = kwargs.get('cbar_ticksize', 14) - show = kwargs.get('show', True) - ShpIsPolygon = kwargs.get('ShpIsPolygon',None) - shpAlpha = kwargs.get('shpAlpha',0.5) - xy_colorbar = kwargs.get('xy_colorbar', False) - if lines_spaces == 'Default': - lines_spaces = cu.dx*cu.ncols*0.05 - #El mapa - Mcols,Mrows=cu.basin_2map_find(self.structure,self.ncells) - Map,mxll,myll=cu.basin_2map(self.structure,self.structure[0] - ,Mcols,Mrows,self.ncells) - longs=np.array([mxll+0.5*cu.dx+i*cu.dx for i in range(Mcols)]) - lats=np.array([myll+0.5*cu.dy+i*cu.dy for i in range(Mrows)]) - X,Y=np.meshgrid(longs,lats) - Y=Y[::-1] - show = kwargs.get('show',True) - if fig is None: - fig = pl.figure(figsize = figsize) - if axis == None: - ax = fig.add_subplot(axloc) - else: - show = False - m = Basemap(projection='merc', - llcrnrlat=lats.min()-extra_lat, - urcrnrlat=lats.max()+extra_lat, - llcrnrlon=longs.min()-extra_long, - urcrnrlon=longs.max()+extra_long, - resolution='c', - epsg = EPSG) - parallels = kwargs.get('parallels',np.arange(lats.min(), - lats.max(),lines_spaces)) - parallels_labels = kwargs.get('parallels_labels',[1,0,0,0]) - parallel_offset = kwargs.get('parallels_offset', 0.001) - m.drawparallels(parallels, - labels = parallels_labels, - fmt="%.2f", - rotation='vertical', - xoffset=parallel_offset) - meridians = kwargs.get('meridians', np.arange(longs.min(), - longs.max(),lines_spaces)) - meridians_labels = kwargs.get('meridians_labels', [0,0,1,0]) - meridians_offset = kwargs.get('meridians_offset', 0.001) - m.drawmeridians(meridians, - labels=meridians_labels, - fmt="%.2f", - yoffset=meridians_offset) - Xm,Ym=m(X,Y) - #plotea el mapa de fondo de arcGIS - if backMap: - m.arcgisimage(server='http://server.arcgisonline.com/ArcGIS', service='World_Topo_Map', xpixels = 1500, verbose = True) - #Plotea el contorno de la cuenca y la red - xp,yp = m(self.Polygon[0], self.Polygon[1]) - per_color = kwargs.get('per_color','r') - per_lw = kwargs.get('per_lw',2) - m.plot(xp, yp, color=per_color,lw=per_lw) - #hay una variable la monta - if vec is not None: - if vmin is None: - vmin = vec.min() - if vmax is None: - vmax = vec.max() - MapVec,mxll,myll=cu.basin_2map(self.structure,vec,Mcols,Mrows, - self.ncells) - MapVec[MapVec==cu.nodata]=np.nan - if ZeroAsNaN is 'si': - MapVec[MapVec == 0] = np.nan - if colorTable is not None: - cs = m.contourf(Xm, Ym, MapVec.T, 25, alpha=alpha,cmap=colorTable, - vmin=vmin,vmax=vmax) - else: - cs = m.contourf(Xm, Ym, MapVec.T, 25, alpha=alpha, - vmin=vmin,vmax=vmax) - cbar_label_size = kwargs.get('cbar_label_size',16) - if colorbar: - cbar = m.colorbar(cs,location='bottom',pad="5%") - if colorbarLabel is not None: - cbar.set_label(colorbarLabel, size = cbar_label_size) - if cbar_ticks is not None: - cbar.set_ticks(cbar_ticks) - if cbar_ticklabels is not None: - cbar.ax.set_yticklabels(cbar_ticklabels, size = cbar_ticksize,) - cbar.ax.set_xticklabels(cbar_ticklabels, size = cbar_ticksize,) - #Si hay coordenadas de algo las plotea - xy_edgecolor = kwargs.get('xy_edgecolor','black') - xy_lw = kwargs.get('xy_lw',30) - xy_s = kwargs.get('xy_s',0.5) - if xy is not None: - xc,yc=m(xy[0],xy[1]) - sx = m.scatter(xc,yc,c=xycolor, - s=xy_s, - linewidth=xy_lw, - edgecolor=xy_edgecolor) - if xy_colorbar: - pl.colorbar(sx) - #Si hay una ruta a un shp lo plotea - if rutaShp is not None: - if type(rutaShp) == str: - m.readshapefile(rutaShp, 'mapashp', linewidth = shpWidth, color = shpColor) - elif type(rutaShp) == list: - for c,shape in enumerate(rutaShp): - m.readshapefile(shape, 'mapashp', linewidth = shpWidth[c], color = shpColor[c]) - if ShpIsPolygon[c]: - patches = [] - for shape in m.mapashp: - patches.append(Polygon(np.array(shape), True)) - ax.add_collection(PatchCollection(patches, facecolor= shpColor[c], - edgecolor=shpColor[c], linewidths=shpWidth[c], zorder=2, alpha = shpAlpha[c])) - #Guarda - if ruta is not None: - pl.savefig(ruta, bbox_inches='tight',pad_inches = 0.25) - if show is True: - pl.show() - if xy is None: - return m,ax - else: - return m, ax, sx - #Grafica de plot para montar en paginas web o presentaciones - def Plot_basinClean(self, vec, ruta = None, umbral = 0.0, - vmin = 0.0, vmax = None, show_cbar = False, **kwargs): - 'Funcion: Plot_basinClean\n'\ - 'Descripcion: Genera un plot del mapa entregado en un lienzo limpio.\n'\ - 'Parametros Obligatorios:.\n'\ - ' -vec: Vector con los valores a plotear.\n'\ - 'Parametros Opcionales:.\n'\ - ' -ruta: ruta donde se guarda el png.\n'\ - ' -umbral: Umbral a partir del cual se plotea variable.\n'\ - ' -vmin: Valor minimo de la variable.\n'\ - ' -vmax: valor maximo de la variable.\n'\ - ' -show_cbar: muestra o no el Cbar del plot.\n'\ - 'Otros argumentos:.\n'\ - ' -cmap: Esquema de colores.\n'\ - ' -figsize = Tamano de la figura.\n'\ - ' -cbar_aspect: (20) relacion largo ancho del cbar.\n'\ - ' -cbar_ticks: (None) ubicacion de los ticks del cbar.\n'\ - ' -cbar_ticklabels: (None) Labels a poner sobre los ticks.\n'\ - ' -cbar_ticksize: (14) Tamano de los ticks.\n'\ - ' -show: SE muestra por defecto la figura (True).\n'\ - ' -interpolation: Tipo de interpolacion utilizada por la funcion imshow (ver opciones en matplotlib).\n'\ - 'Retorno:.\n'\ - ' -Figura se muestra y se guarda.\n'\ - ' -Coordenadas de los bordes del mapa.\n'\ - #Argumentos kw - cmap = kwargs.get('cmap','Spectral') - figsize = kwargs.get('figsize', (10,8)) - cbar_aspect = kwargs.get('cbar_aspect', 20) - cbar_ticklabels = kwargs.get('cbar_ticklabels', None) - cbar_ticks = kwargs.get('cbar_ticks', None) - cbar_ticksize = kwargs.get('cbar_ticksize', 14) - interpolation = kwargs.get('None') - show = kwargs.get('show', True) - #Obtiene la matriz - M,p = self.Transform_Basin2Map(vec) - M[(M == -9999) | (Mumbral)[0] - elif type(umbral) == np.ndarray and umbral.shape[0] == self.ncells: - pos = np.where(umbral == 1)[0] - x,y = cu.basin_coordxy(self.structure, self.ncells) - #Vector para pintar si no tiene el vec_c usa vec - if vec_c is None: - vec_c = np.copy(vec) - #Compara o no - if q_compare is not None: - vec = vec/q_compare.astype(float) - #Figura - fig = pl.figure(figsize=figsize) - ax = fig.add_subplot(111) - sca = pl.scatter(x[pos],y[pos], - s = vec[pos]*escala, - c = vec_c[pos], - lw = 0, - vmin = vmin, - vmax = vmax, - cmap = cmap, - norm = norm) - ax.patch.set_facecolor('w') - ax.patch.set_alpha(0.0) - if grid: - pl.grid(True) - #colorca colorbar - if show_cbar: - cbar = pl.colorbar(sca, aspect = cbar_aspect, ) - if cbar_ticks is not None: - cbar.set_ticks(cbar_ticks) - if cbar_ticklabels is not None: - cbar.ax.set_yticklabels(cbar_ticklabels, size = cbar_ticksize,) - - ax.set_xlim(x[pos].min(),x[pos].max()) - ax.set_ylim(y[pos].min(),y[pos].max()) - #Quita ejes - if clean: - ax.set_xticklabels([]) - ax.set_yticklabels([]) - ax.axis('off') - if clean == False: - ax.set_xlabel('Latitud', size = size) - ax.set_ylabel('Longitud', size = size) - ax.tick_params(labelsize = ticksize) - #Guarda transparente y ajustando bordes - if ruta is not None: - pl.savefig(ruta, - bbox_inches = 'tight', - pad_inches = 0, - transparent = transparent, - edgecolor = 'none', - facecolor = 'none') - if show: - pl.show() - pl.close(fig) - #Retorna las 4 coordenadas de las esquinas - return [x[pos].min(), x[pos].max(), y[pos].min(), y[pos].max()] - - - # Grafica barras de tiempos de concentracion - def Plot_Tc(self,ruta=None,figsize=(8,6),**kwargs): - keys=self.Tc.keys() - keys[2]=u'Carr Espana' - Media=np.array(self.Tc.values()).mean() - Desv=np.array(self.Tc.values()).std() - Mediana=np.percentile(self.Tc.values(),50) - rango=[Media-Desv,Media+Desv] - color1 = kwargs.get('color1','b') - color2 = kwargs.get('color2','r') - colores=[] - for t in self.Tc.values(): - if t>rango[0] and tself.ncells: - Nsize = self.ncells - pos = np.random.choice(self.ncells,Nsize) - h,b=np.histogram(self.CellSlope[pos],bins=np.arange(bins[0],bins[1],bins[2])) - b=(b[:-1]+b[1:])/2.0 - h=h.astype(float)/h.astype(float).sum() - if fig is None: - fig=pl.figure(figsize = figsize, edgecolor='w',facecolor='w') - ax=fig.add_subplot(111) - ax.plot(b,h,lw=lw) - ax.grid(True) - ax.tick_params(labelsize = axissize) - ax.set_xlabel('Pendiente',size=labelsize) - ax.set_ylabel('$pdf [\%]$',size=labelsize) - if ruta is not None: - pl.savefig(ruta,bbox_inches='tight') - if show: - pl.show() - return ax - - #Plot de histograma de tiempos de viajes en la cuenca - def Plot_Travell_Hist(self,ruta=None,Nint=10.0): - #comparacion histogramas de tiempos de respuestas - bins=np.arange(0,np.ceil(self.CellTravelTime.max()), - np.ceil(self.CellTravelTime.max())/Nint) - h_lib,b_lib=np.histogram(self.CellTravelTime,bins=bins) - h_lib=h_lib.astype(float)/h_lib.sum() - b_lib=(b_lib[:-1]+b_lib[1:])/2.0 - hc_lib=np.cumsum(h_lib) - fig=pl.figure(facecolor='w',edgecolor='w') - ax=fig.add_subplot(111) - ax.plot(b_lib,h_lib,'b',lw=2,label='Tiempos') - ax2=ax.twinx() - ax2.plot(b_lib,hc_lib,'r',lw=2) - ax2.set_ylim(0,1.1) - ax.set_xlim(0,np.ceil(self.CellTravelTime.max())) - ax.grid(True) - ax.set_xlabel('Tiempo $t [hrs]$',size=14) - ax.set_ylabel('$pdf[\%]$',size=14) - ax2.set_ylabel('$cdf[\%]$',size=14) - ax.set_xticks(b_lib) - ax.legend(loc=4) - if ruta is not None: - pl.savefig(ruta,bbox_inches='tight') - pl.show() - #Plot de curva hipsometrica - def Plot_Hipsometric(self,ruta=None,ventana=10,normed=False, - figsize = (8,6)): - #Suaviza la elevacion en el cuace ppal - elevPpal=pd.Series(self.hipso_ppal[1]) - elevBasin=self.hipso_basin[1] - if normed==True: - elevPpal=elevPpal-elevPpal.min() - elevPpal=(elevPpal/elevPpal.max())*100.0 - elevBasin=elevBasin-elevBasin.min() - elevBasin=(elevBasin/elevBasin.max())*100.0 - elevPpal=pd.rolling_mean(elevPpal,ventana) - ppal_acum=(self.hipso_ppal[0]/self.hipso_ppal[0,-1])*100 - basin_acum=(self.hipso_basin[0]/self.hipso_basin[0,0])*100 - #Genera el plot - fig=pl.figure(edgecolor='w',facecolor='w',figsize = figsize) - ax=fig.add_subplot(111) - #box = ax.get_position() - #ax.set_position([box.x0, box.y0 + box.height * 0.1, - # box.width, box.height * 0.9]) - ax.plot(ppal_acum,elevPpal,c='b',lw=3,label='Cacuce Principal') - ax.plot(basin_acum,elevBasin,c='r',lw=3,label='Cuenca') - ax.tick_params(labelsize = 14) - ax.grid() - ax.set_xlabel('Porcentaje Area Acumulada $[\%]$',size=16) - if normed==False: - ax.set_ylabel('Elevacion $[m.s.n.m]$',size=16) - elif normed==True: - ax.set_ylabel('Elevacion $[\%]$',size=16) - lgn1=ax.legend(loc=0) - if ruta is not None: - pl.savefig(ruta, bbox_inches='tight') - pl.close('all') - else: - pl.show() -class SimuBasin(Basin): - - def __init__(self,lat=None,lon=None,DEM=None,DIR=None,rute = None, name='NaN',stream=None, - umbral=500,useCauceMap = None, - noData=-999,modelType='cells',SimSed=False,SimSlides=False,dt=60, - SaveStorage='no',SaveSpeed='no',retorno = 0, - SeparateFluxes = 'no',SeparateRain='no',ShowStorage='no', SimFloods = 'no', - controlNodos = True, storageConstant = 0.001): - 'Descripcion: Inicia un objeto para simulacion \n'\ - ' el objeto tiene las propieades de una cuenca con. \n'\ - ' la diferencia de que inicia las variables requeridas. \n'\ - ' para simular. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'lat : Coordenada en X de la salida de la cuenca.\n'\ - 'lon : Coordenada en Y de la salida de la cuenca.\n'\ - 'name : Nombre con el que se va a conocer la cuenca.\n'\ - ' (defecto = NaN).\n'\ - 'stream : Opcional, si se coloca, las coordenadas no tienen.\n'\ - ' que ser exactas, estas se van a corregir para ubicarse.\n'\ - ' en el punto mas cercano dentro de la corriente, este.\n'\ - ' debe ser un objeto del tipo stream.\n'\ - 'useCauceMap: Utiliza un mapa de 1 y 0 representando las celdas que.\n'\ - ' son canal, con este mapa corrige el punto de trazado de la cuenca.\n'\ - 'umbral : Cantidad minima de celdas para la creacion de cauces.\n'\ - ' (defecto = 500 ).\n'\ - 'noData : Valor correspondiente a valores sin dato (defecto = -999).\n'\ - 'modelType : Tipo de modelo, por celdas o por laderas (defecto = cells).\n'\ - ' opciones: .\n'\ - ' cells => modela por celdas.\n'\ - ' hills => modela por laderas.\n'\ - 'SimSed : Simula si, o no simula sedimentos no.\n'\ - 'SimSlides : Simula si, o no simula deslizamientos no.\n'\ - 'dt : Tamano del intervlao de tiempo en que trabaj el modelo (defecto=60seg) [secs].\n'\ - 'SaveStorage : Guarda o no el almacenamiento.\n'\ - 'SaveSpeed : Guarda o no mapas de velocidad.\n'\ - 'rute : por defecto es None, si se coloca la ruta, el programa no.\n'\ - ' hace una cuenca, si no que trata de leer una en el lugar especificado.\n'\ - ' Ojo: la cuenca debio ser guardada con la funcion: Save_SimuBasin().\n'\ - 'retorno : (defecto = 0), si es cero no se considera alm maximo en .\n'\ - ' el tanque 3, si es 1, si se considera.\n'\ - 'SeparateFluxes : Separa el flujo en base, sub-superficial y escorrentia.\n'\ - 'SeparateRain : Separa el flujo proveniente de convectivas y de estratiformes.\n'\ - 'ShowStorage : Muestra en la salida del modelo el alm promedio en cada uno de los tanques.\n'\ - 'controlNodos: Coloca por defecto puntos de control en todos los nodos (True) o no (False).\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con las variables iniciadas.\n'\ - #Variables de radar - self.radarDates = [] - self.radarPos = [] - self.radarMeanRain = [] - self.radarCont = 1 - #Si no hay ruta y el global del codigo EPSG existe, traza la cuenca - if rute is None and int(Global_EPSG) > 0: - #Si se entrega cauce corrige coordenadas - if stream is not None: - error=[] - for i in stream.structure.T: - error.append( np.sqrt((lat-i[0])**2+(lon-i[1])**2) ) - loc=np.argmin(error) - lat=stream.structure[0,loc] - lon=stream.structure[1,loc] - if useCauceMap is not None and useCauceMap.shape == DEM.shape: - lat,lon = cu.stream_find_to_corr(lat,lon,DEM,DIR,useCauceMap, - cu.ncols,cu.nrows) - #copia la direccion de los mapas de DEM y DIR, para no llamarlos mas - self.name=name - self.DEM=DEM - self.DIR=DIR - self.modelType=modelType - self.nodata=noData - self.umbral = umbral - self.epsg = Global_EPSG - #Traza la cuenca - self.ncells = cu.basin_find(lat,lon,DIR, - cu.ncols,cu.nrows) - self.structure = cu.basin_cut(self.ncells) - #Obtiene las propiedades para el tamano de la cuenca. - self.DEMvec = self.Transform_Map2Basin(DEM, - [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy]) - self.DIRvec = self.Transform_Map2Basin(DIR, - [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy]) - acum=cu.basin_acum(self.structure,self.ncells) - cauce,nodos,self.nhills = cu.basin_subbasin_nod(self.structure - ,acum,umbral,self.ncells) - self.hills_own,sub_basin = cu.basin_subbasin_find(self.structure, - nodos,self.nhills,self.ncells) - self.hills = cu.basin_subbasin_cut(self.nhills) - models.drena=self.structure - #Determina la cantidad de celdas para alojar - if modelType=='cells': - N=self.ncells - elif modelType=='hills': - N=self.nhills - #aloja variables - models.v_coef = np.ones((4,N)) - models.h_coef = np.ones((4,N)) - models.v_exp = np.ones((4,N)) - models.h_exp = np.ones((4,N)) - models.max_capilar = np.ones((1,N)) - models.max_gravita = np.ones((1,N)) - models.storage = np.zeros((5,N)) - models.dt = dt - models.calc_niter = 5 - models.retorno = 0 - models.verbose = 0 - #Define los puntos de control - models.control = np.zeros((1,N)) - #Si se da la opcion de puntos de control en toda la red lo hace - if controlNodos: - if modelType == 'cells': - self.GetGeo_Cell_Basics() - cauce,nodos,n_nodos = cu.basin_subbasin_nod( - self.structure, - self.CellAcum, - umbral, - self.ncells) - pos = np.where(nodos<>0)[0] - x,y = cu.basin_coordxy(self.structure,self.ncells) - idsOrd,xy = self.set_Control(np.vstack([x[pos],y[pos]]),nodos[pos]) - elif modelType == 'hills': - models.control = np.ones((1,self.nhills)) * nodos[nodos<>0] - #Puntos de control de humedad sin control por defecto - models.control_h = np.zeros((1,N)) - #Define las simulaciones que se van a hacer - models.sim_sediments=0 - if SimSed is 'si': - models.sim_sediments=1 - models.sim_slides=0 - if SimSlides: - models.sim_slides=1 - models.save_storage=0 - if SaveStorage is 'si': - models.save_storage=1 - models.save_speed=0 - if SaveSpeed is 'si': - models.save_speed=1 - models.separate_fluxes = 0 - if SeparateFluxes is 'si': - models.separate_fluxes = 1 - models.separate_rain = 0 - if SeparateRain is 'si': - models.separate_rain = 1 - models.show_storage = 0 - if ShowStorage is 'si': - models.show_storage = 1 - if SimFloods == 'si': - models.sim_floods = 1 - models.storage_constant = storageConstant - #Determina que la geomorfologia no se ha estimado - self.isSetGeo = False - # si hay tura lee todo lo de la cuenca - elif rute is not None: - self.__Load_SimuBasin(rute, SimSlides) - # Obtiene la envolvente de la cuenca - self.__GetBasinPolygon__() - - def __Load_SimuBasin(self,ruta, sim_slides = False): - 'Descripcion: Lee una cuenca posteriormente guardada\n'\ - ' La cuenca debio ser guardada con SimuBasin.save_SimuBasin\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'ruta : ruta donde se encuentra ubicada la cuenca guardada\n'\ - 'Opcionales\n'\ - '----------\n'\ - 'sim_slides : (False, True) Carga variables de modelos de deslizamientos previmaente guardadas.\n'\ - 'sim_sed : (False, True) Carga variables de modelo de sedimentos previamente guardadas\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : La cuenca con sus parametros ya cargada.\n'\ - #Abre el archivo binario de la cuenca - self.rutaNC = ruta - gr = netcdf.Dataset(ruta,'a') - #obtiene las prop de la cuenca - self.name = gr.nombre - self.modelType = gr.modelType.encode() - self.nodata = gr.noData - self.umbral = gr.umbral - self.ncells = gr.ncells - self.nhills = gr.nhills - self.epsg = gr.epsg - models.dt = gr.dt - models.dxp = gr.dxp - models.retorno = gr.retorno - try: - models.storage_constant = gr.storageConst - except: - models.storage_constant = 0.0 - #Si carga deslizamientos - if sim_slides: - models.sim_slides = 1 - models.sl_fs = gr.sl_fs - models.gullienogullie = gr.sl_gullie - models.sl_gammaw = gr.sl_gammaw - #Nueva metodologia de geoespacial de la cuenca - cu.ncols = gr.ncols - cu.nrows = gr.nrows - cu.xll = gr.xll - cu.yll = gr.yll - cu.dx = gr.dx - cu.dy = gr.dy - cu.dxp = gr.dxp - cu.nodata = gr.noData - #de acuerdo al tipo de modeloe stablece numero de elem - if self.modelType[0] is 'c': - N = self.ncells - elif self.modelType[0] is 'h': - N = self.nhills - #Obtiene las variables base - GrupoBase = gr.groups['base'] - self.structure = GrupoBase.variables['structure'][:] - self.hills = GrupoBase.variables['hills'][:] - self.hills_own = GrupoBase.variables['hills_own'][:] - #Obtiene las geomorfologicas - GrupoGeo = gr.groups['Geomorfo'] - self.DEMvec = GrupoGeo.variables['DEM'][:] - self.DIRvec = GrupoGeo.variables['DIR'][:] - self.DEM = self.Transform_Basin2Map(self.DEMvec) - self.DIR = self.Transform_Basin2Map(self.DIRvec) - #obtiene las propieades del modelo - GrupoSimHid = gr.groups['SimHidro'] - models.h_coef = np.ones((4,N)) * GrupoSimHid.variables['h_coef'][:] - models.v_coef = np.ones((4,N)) * GrupoSimHid.variables['v_coef'][:] - models.h_exp = np.ones((4,N)) * GrupoSimHid.variables['h_exp'][:] - models.v_exp = np.ones((4,N)) * GrupoSimHid.variables['v_exp'][:] - models.max_capilar = np.ones((1,N)) * GrupoSimHid.variables['h1_max'][:] - models.max_gravita = np.ones((1,N)) * GrupoSimHid.variables['h3_max'][:] - #Variable de drena de acuerdo al tipo de modelo - if self.modelType[0] is 'c': - models.drena = np.ones((3,N)) *GrupoSimHid.variables['drena'][:] - elif self.modelType[0] is 'h': - models.drena = np.ones((1,N)) * GrupoSimHid.variables['drena'][:] - models.unit_type = np.ones((1,N)) * GrupoSimHid.variables['unit_type'][:] - models.hill_long = np.ones((1,N)) * GrupoSimHid.variables['hill_long'][:] - models.hill_slope = np.ones((1,N)) * GrupoSimHid.variables['hill_slope'][:] - models.stream_long = np.ones((1,N)) * GrupoSimHid.variables['stream_long'][:] - models.stream_slope = np.ones((1,N)) * GrupoSimHid.variables['stream_slope'][:] - models.stream_width = np.ones((1,N)) * GrupoSimHid.variables['stream_width'][:] - models.elem_area = np.ones((1,N)) * GrupoSimHid.variables['elem_area'][:] - models.speed_type = np.ones((3)) * GrupoSimHid.variables['speed_type'][:] - models.storage = np.ones((5,N)) * GrupoSimHid.variables['storage'][:] - models.control = np.ones((1,N)) * GrupoSimHid.variables['control'][:] - models.control_h = np.ones((1,N)) * GrupoSimHid.variables['control_h'][:] - - #Propiedades de deslizamientos - if sim_slides: - GrupoSlides = gr.groups['SimSlides'] - models.sl_gammas = np.ones((1,N)) * GrupoSlides.variables['gamma_soil'][:] - models.sl_cohesion = np.ones((1,N)) * GrupoSlides.variables['cohesion'][:] - models.sl_frictionangle = np.ones((1,N)) * GrupoSlides.variables['friction_angle'][:] - models.sl_radslope = np.ones((1,N)) * GrupoSlides.variables['rad_slope'][:] - models.sl_zs = np.ones((1,N)) * GrupoSlides.variables['z_soil'][:] - #Cierra el archivo - gr.close() - #Determina que por defecto debe estar set la geomorfologia - self.isSetGeo = True - - #------------------------------------------------------ - # Subrutinas de lluvia, interpolacion, lectura, escritura, agrega funcion para variar evp en - # el tiempo - #------------------------------------------------------ - def __GetEVP_Serie__(self, index): - '''Descripcion: Genera una serie que pondera la evp ''' - rng=index - rad=np.zeros(rng.size) - for pos,time in enumerate(rng): - Hora=time - # Dia del Ano - dn = Hora.timetuple().tm_yday - Theta_d = (2 * np.pi * (dn-1))/ 365. - # (d/d)2 - an = [1.000110, 0.034221, 0.000719] - bn = [0, 0.001280, 0.000077] - # - d = 0 - tmp = 0 - for i in range(3): - tmp = (an[i] * np.cos(i*Theta_d)) + (bn[i] * np.sin(i*Theta_d)) - d = d + tmp - # Delta - a_n = [0.006918, -0.399912, -0.006758, -0.002697] - b_n = [0, 0.070257, 0.000907, 0.001480] - # - Delta = 0 - tmp = 0 - for i in range(4): - tmp = (a_n[i] * np.cos(i*Theta_d)) + (b_n[i] * np.sin(i*Theta_d)) - Delta = Delta + tmp - #Angulo horario (cada minuto) - Minutos = (Hora.hour * 60) + Hora.minute - Horario = 180 - (0.25 * Minutos) - Horario = (Horario * np.pi)/180. - # Coseno de Theta - Latitud = (6.2593 * np.pi)/180. - Cos_Theta = (np.sin(Latitud)*np.sin(Delta)) + (np.cos(Latitud)*np.cos(Delta)*np.cos(Horario)) - # Radiacion Teorica - So = 1367 #w/m2 - Q = So * d * Cos_Theta - # Escala entre 0 y 1 - rad_max=1369.8721876806876 - Q=1*Q/rad_max - #Guarda - rad[pos]=Q - #Se vuelven cero los valores negativos. - rad[rad<0]=0 - #Serie - rad=pd.Series(rad,index=rng) - models.evpserie = np.copy(rad.values) - return rad - - def rain_interpolate_mit(self,coord,registers,ruta, umbral = 0.01): - 'Descripcion: Interpola la lluvia mediante una malla\n'\ - ' irregular de triangulos, genera campos que son. \n'\ - ' guardados en un binario para luego ser leido por el. \n'\ - ' modelo en el momento de simular. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : .\n'\ - 'coord : Array (2,Ncoord) con las coordenadas de estaciones.\n'\ - 'registers : Array (Nest,Nregisters) con los registros de lluvia.\n'\ - 'ruta : Ruta con nombre en donde se guardara el binario con.\n'\ - ' la informacion de lluvia.\n'\ - 'umbral: Umbral a partir del cual se considera que un campo contiene lluvia\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Guarda el binario, no hay retorno\n'\ - 'meanRain : La serie de lluvia promedio interpolada para la cuenca\n'\ - '\n'\ - 'Mirar Tambien\n'\ - '----------\n'\ - 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ - 'rain_read_bin: Lee binario de registros para ver que tiene.\n'\ - 'rain_ncf2bin: Convierte ncf a binario en formato del modelo (para imagenes de radar).\n'\ - #Mira si los registros son un data frame de pandas - isPandas=False - if type(registers)==pd.core.frame.DataFrame: - reg=registers.values.T - isPandas=True - else: - reg=registers - #inventa estaciones en las esquinas del DEM - for i,j in zip([0,0,1,1],[0,1,1,0]): - x=cu.xll+cu.ncols*cu.dx*i - y=cu.yll+cu.nrows*cu.dx*j - d=np.sqrt((coord[0,:]-x)**2+(coord[1,:]-y)**2) - pos=np.argmin(d) - #Actualiza las coordenadas - coord=np.vstack((coord.T,np.array([x,y]))).T - #pone lluvia en ese registro - reg=np.vstack((reg,reg[pos])) - #Obtiene las coordenadas de cada celda de la cuenca - x,y = cu.basin_coordxy(self.structure,self.ncells) - xy_basin=np.vstack((x,y)) - #Obtiene la malla irregular - TIN_mesh=Delaunay(coord.T) - TIN_mesh=TIN_mesh.vertices.T+1 - #Obtiene las pertenencias en la cuenca a la malla - #TIN_perte = models.rain_pre_mit(xy_basin,TIN_mesh,coord,self.ncells, - # TIN_mesh.shape[1],coord.shape[1]) - c = 1 - TIN_perte = np.zeros((1,self.ncells)) - for t in TIN_mesh.T: - t = t-1 - t = np.append(t, t[0]) - Poly = np.vstack([coord[0][t], coord[1][t]]) - bbPath = mplPath.Path(Poly.T, closed=True) - Contiene = bbPath.contains_points(xy_basin.T) - TIN_perte[0][Contiene == True] = c - c+=1 - #Revisa si todas las celdas quedaron asignadas - if len(TIN_perte[TIN_perte == 0]) == 0: - #Selecciona si es por laderas o por celdas - if self.modelType[0] is 'h': - maskVector = np.copy(self.hills_own) - elif self.modelType[0] is 'c': - maskVector = np.ones(self.ncells) - #Interpola con tin - meanRain,posIds = models.rain_mit(xy_basin, - coord, - reg, - TIN_mesh, - TIN_perte, - self.nhills, - ruta, - umbral, - maskVector, - self.ncells, - coord.shape[1], - TIN_mesh.shape[1], - reg.shape[1]) - #Guarda un archivo con informacion de la lluvia - f=open(ruta[:-3]+'hdr','w') - f.write('Numero de celdas: %d \n' % self.ncells) - f.write('Numero de laderas: %d \n' % self.nhills) - f.write('Numero de registros: %d \n' % reg.shape[1]) - f.write('Numero de campos no cero: %d \n' % posIds.max()) - f.write('Tipo de interpolacion: TIN\n') - f.write('IDfecha, Record, Lluvia, Fecha \n') - if isPandas: - dates=registers.index.to_pydatetime() - c = 1 - for d,pos,m in zip(dates,posIds,meanRain): - f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) - c+=1 - f.close() - return meanRain, posIds - else: - print 'Error: Existen celdas de la cuenca sin asignacion de triangulos, se retornan las coordenadas no asignadas' - pos = np.where(TIN_perte == 0)[1] - return xy_basin[0,pos], xy_basin[1,pos] - - def rain_interpolate_idw(self,coord,registers,ruta,p=1,umbral=0.0): - 'Descripcion: Interpola la lluvia mediante la metodologia\n'\ - ' del inverso de la distancia ponderado. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : .\n'\ - 'coord : Array (2,Ncoord) con las coordenadas de estaciones.\n'\ - 'registers : DataFrame de pandas (Nest,Nregisters) con los registros de lluvia.\n'\ - 'p : exponente para la interpolacion de lluvia.\n'\ - 'ruta : Ruta con nombre en donde se guardara el binario con.\n'\ - ' la informacion de lluvia.\n'\ - 'umbral : Umbral de suma total de lluvia bajo el cual se considera\n'\ - ' que un intervalo tiene suficiente agua como para generar reaccion\n'\ - ' (umbral = 0.0) a medida que incremente se generaran archivos mas\n'\ - ' livianos, igualmente existe la posibilidad de borrar informacion.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Guarda el binario, no hay retorno\n'\ - 'meanRain : La serie de lluvia promedio interpolada para la cuenca\n'\ - '\n'\ - 'Mirar Tambien\n'\ - '----------\n'\ - 'rain_interpolate_mit: interpola campos mediante la metodologia idw.\n'\ - 'rain_read_bin: Lee binario de registros para ver que tiene.\n'\ - 'rain_ncf2bin: Convierte ncf a binario en formato del modelo (para imagenes de radar).\n'\ - #Mira si los registros son un data frame de pandas - isPandas=False - if type(registers)==pd.core.frame.DataFrame: - reg=registers.values.T - isPandas=True - else: - reg=registers - #Obtiene las coordenadas de cada celda de la cuenca - x,y = cu.basin_coordxy(self.structure,self.ncells) - xy_basin=np.vstack((x,y)) - #Interpola con idw - if self.modelType[0] is 'h': - meanRain,posIds = models.rain_idw(xy_basin, coord, reg, p, self.nhills, - ruta, umbral, self.hills_own, self.ncells, coord.shape[1],reg.shape[1]) - elif self.modelType[0] is 'c': - meanRain,posIds = models.rain_idw(xy_basin, coord, reg, p, self.nhills, - ruta, umbral, np.ones(self.ncells), self.ncells, coord.shape[1],reg.shape[1]) - #Guarda un archivo con informacion de la lluvia - f=open(ruta[:-3]+'hdr','w') - f.write('Numero de celdas: %d \n' % self.ncells) - f.write('Numero de laderas: %d \n' % self.nhills) - f.write('Numero de registros: %d \n' % reg.shape[1]) - f.write('Numero de campos no cero: %d \n' % posIds.max()) - f.write('Tipo de interpolacion: IDW, p= %.2f \n' % p) - f.write('IDfecha, Record, Lluvia, Fecha \n') - if isPandas: - dates=registers.index.to_pydatetime() - c = 1 - for d,pos,m in zip(dates,posIds,meanRain): - f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) - c+=1 - f.close() - return meanRain,posIds - - def rain_radar2basin_from_asc(self,ruta_in,ruta_out,fechaI,fechaF,dt, - pre_string,post_string,fmt = '%Y%m%d%H%M',conv_factor=1.0/12.0, - umbral = 0.0): - 'Descripcion: Genera campos de lluvia a partir de archivos asc. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : .\n'\ - 'ruta_in: Ruta donde se encuentran loas .asc.\n'\ - 'ruta_out: Ruta donde escribe el binario con la lluvia.\n'\ - 'fechaI: Fecha de inicio de registros.\n'\ - 'fechaF: Fecha de finalizacion de registros.\n'\ - 'dt: Intervalo de tiempo entre registros.\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Guarda el binario, no hay retorno\n'\ - 'meanRain : La serie de lluvia promedio.\n'\ - 'meanRain : La serie de lluvia promedio.\n'\ - '\n'\ - 'Mirar Tambien\n'\ - '----------\n'\ - 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ - 'rain_radar2basin_from_array: Mete campos de lluvia mediante multiples arrays.\n'\ - #Edita la ruta de salida - if ruta_out.endswith('.hdr') or ruta_out.endswith('.bin'): - ruta_bin = ruta_out[:-3]+'.bin' - ruta_hdr = ruta_out[:-3]+'.hdr' - else: - ruta_bin = ruta_out+'.bin' - ruta_hdr = ruta_out+'.hdr' - #Establece la cantidad de elementos de acuerdo al tipo de cuenca - if self.modelType[0] is 'c': - N = self.ncells - elif self.modelType[0] is 'h': - N = self.nhills - #Guarda la primera entrada como un mapa de ceros - models.write_int_basin(ruta_bin,np.zeros((1,N)),1,N,1) - #Genera la lista de las fechas. - ListDates,dates = __ListaRadarNames__(ruta_in, - fechaI,fechaF, - fmt,post_string,pre_string,dt) - #Lee los mapas y los transforma - cont = 1 - meanRain = [] - posIds = [] - for l in ListDates: - Map,p = read_map_raster(ruta_in + l) - vec = self.Transform_Map2Basin(Map,p) * conv_factor - #Si el mapa tiene mas agua de un umbral - if vec.sum() > umbral: - #Actualiza contador, lluvia media y pocisiones - cont +=1 - meanRain.append(vec.mean()) - posIds.append(cont) - #Guarda el vector - vec = vec*1000; vec = vec.astype(int) - models.write_int_basin(ruta_bin,np.zeros((1,N))+vec,cont,N,1) - else: - #lluvia media y pocisiones - meanRain.append(0.0) - posIds.append(1) - posIds = np.array(posIds) - meanRain = np.array(meanRain) - #Guarda un archivo con informacion de la lluvia - f=open(ruta_hdr[:-3]+'hdr','w') - f.write('Numero de celdas: %d \n' % self.ncells) - f.write('Numero de laderas: %d \n' % self.nhills) - f.write('Numero de registros: %d \n' % meanRain.shape[0]) - f.write('Numero de campos no cero: %d \n' % posIds.max()) - f.write('Tipo de interpolacion: radar \n') - f.write('IDfecha, Record, Lluvia, Fecha \n') - c = 1 - for d,pos,m in zip(dates,posIds,meanRain): - f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) - c+=1 - f.close() - return np.array(meanRain),np.array(posIds) - - def rain_radar2basin_from_array(self,vec=None,ruta_out=None,fecha=None,dt=None, - status='update',umbral = 0.01, doit = False): - 'Descripcion: Genera campos de lluvia a partir de archivos array\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : .\n'\ - 'vec: Array en forma de la cuenca con la informacion.\n'\ - 'ruta_out: Ruta donde escribe el binario con la lluvia.\n'\ - 'fecha: Fecha del registro actual.\n'\ - 'dt: Intervalo de tiempo entre registros.\n'\ - 'status: Estado en el cual se encuentra el binario que se va a pasar a campo.\n'\ - ' update: (Defecto) Con este estado se genera un binario y se agregan nuevos campos.\n'\ - ' old: Estado para abrir y tomar las propiedades de self.radar.. para la generacion de un binario.\n'\ - ' close: Cierra un binario que se ha generado mediante update.\n'\ - ' reset: Reinicia las condiciones de self.radar... para la creacion de un campo nuevo.\n'\ - 'doit: Independiente del umbral escribe el binario en la siguiente entrada.\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Guarda el binario, no hay retorno\n'\ - 'meanRain : La serie de lluvia promedio.\n'\ - '\n'\ - 'Mirar Tambien\n'\ - '----------\n'\ - 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ - 'rain_radar2basin_from_asc: Mete campos de lluvia mediante multiples arrays.\n'\ - #Edita la ruta de salida - if ruta_out is not None: - if ruta_out.endswith('.hdr') or ruta_out.endswith('.bin'): - ruta_bin = ruta_out[:-3]+'.bin' - ruta_hdr = ruta_out[:-3]+'.hdr' - else: - ruta_bin = ruta_out+'.bin' - ruta_hdr = ruta_out+'.hdr' - #Establece la cantidad de elementos de acuerdo al tipo de cuenca - if self.modelType[0] is 'c': - N = self.ncells - elif self.modelType[0] is 'h': - N = self.nhills - try: - if vec.shape[0] == self.ncells: - vec = self.Transform_Basin2Hills(vec,sumORmean=1) - except: - pass - # De acerudo al estado actualiza las variables o guarda el - # binario final - actualizo = 1 - if status == 'update': - #Entrada 1 es la entrada de campos sin lluvia - if len(self.radarDates) == 0: - models.write_int_basin(ruta_bin,np.zeros((1,N)),1,N,1) - if vec.mean() > umbral or doit: - #Actualiza contador, lluvia media y pocisiones - self.radarCont +=1 - self.radarMeanRain.append(vec.mean()) - self.radarPos.append(self.radarCont) - #Guarda el vector - vec = vec*1000; vec = vec.astype(int) - models.write_int_basin(ruta_bin,np.zeros((1,N))+vec, - self.radarCont,N,1) - actualizo = 0 - else: - #lluvia media y pocisiones - self.radarMeanRain.append(0.0) - self.radarPos.append(1) - self.radarDates.append(fecha) - #Si ya no va a agregar nada, no agrega mas campos y genera el .hdr - elif status == 'close': - self.radarMeanRain = np.array(self.radarMeanRain) - self.radarPos = np.array(self.radarPos) - #Guarda un archivo con informacion de la lluvia - f=open(ruta_hdr[:-3]+'hdr','w') - f.write('Numero de celdas: %d \n' % self.ncells) - f.write('Numero de laderas: %d \n' % self.nhills) - f.write('Numero de registros: %d \n' % self.radarMeanRain.shape[0]) - f.write('Numero de campos no cero: %d \n' % self.radarPos.max()) - f.write('Tipo de interpolacion: radar \n') - f.write('IDfecha, Record, Lluvia, Fecha \n') - c = 1 - for d,pos,m in zip(self.radarDates, - self.radarPos,self.radarMeanRain): - f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) - c+=1 - f.close() - #Vuelve las variables listas de nuevo - self.radarMeanRain = self.radarMeanRain.tolist() - self.radarPos = self.radarPos.tolist() - elif status == 'reset': - #Variables de radar - self.radarDates = [] - self.radarPos = [] - self.radarMeanRain = [] - self.radarCont = 1 - elif status == 'old': - #si es un archivo viejo, lo abre para tomar las variables y continuar en ese punto - f=open(ruta_hdr[:-3]+'hdr','r') - Lista = f.readlines() - self.radarCont = int(Lista[3].split()[-1]) - cantidadIds = int(Lista[2].split()[-1]) - f.close() - #Abre con numpy para simplificar las cosas - a = np.loadtxt(ruta_hdr,skiprows=6,dtype='str').T - if self.radarCont >= 1 and cantidadIds > 1: - self.radarPos = [int(i.split(',')[0]) for i in a[1]] - self.radarMeanRain = [float(i.split(',')[0]) for i in a[2]] - for i in a[3]: - d = datetime.datetime.strptime(i,'%Y-%m-%d-%H:%M') - self.radarDates.append(d) - else: - self.radarPos = [int(a[1].split(',')[0])] - self.radarMeanRain = [float(a[2].split(',')[0])] - self.radarDates = [datetime.datetime.strptime(a[-1], '%Y-%m-%d-%H:%M')] - return actualizo - - #------------------------------------------------------ - # Subrutinas para preparar modelo - #------------------------------------------------------ - def set_Geomorphology(self,umbrales=[30,500],stream_width=None): - 'Descripcion: calcula las propiedades geomorfologicas necesarias \n'\ - ' para la simulacion. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'umbrales : Lista con la cantidad de celdas necesarias .\n'\ - ' para que una celda sea: ladera, carcava o cauce .\n'\ - 'stream_width = Ancho del canal en cada tramo (opcional).\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con las variables geomorfologicas de simulacion iniciadas.\n'\ - ' models.drena : Numero de celda o ladera destino. \n'\ - ' models.nceldas : Numero de celdas o laderas. \n'\ - ' models.unit_type : tipo de celda, en el caso de ladera no aplica.\n'\ - ' 1: Celda tipo ladera.\n'\ - ' 2: Celda tipo transitorio.\n'\ - ' 3: Celda tipo cauce.\n'\ - ' models.hill_long : Longitud promedio de la ladera (o celda). \n'\ - ' - Celdas: Longitud de cada elemento (cu.dxp) para ortogonal y 1.43*cu.dxp para diagonal. \n'\ - ' - Laderas: Promedio de las longitudes recorridas entre una celda y la corriente de la ladera. \n'\ - ' models.hill_slope : Pendiente de cada ladera (promedio) o celda.\n'\ - ' models.stream_long : Longitud de cada tramo de cuace. \n'\ - ' - Celdas: Es cu.dxp: ortogonal, 1.42*cu.dxp: Diagonal. \n'\ - ' - Laderas: Es la Longitud de los elementos del cauce que componen la ladera. \n'\ - ' models.stream_slope : Pendiente de cada tramo de cauce. \n'\ - ' - Celdas: Es la pendiente estimada por self.GetGeo_Cell_Basics(). \n'\ - ' - Laderas: Pendiente promedio de las laderas. \n'\ - ' models.stream_width : Ancho de cada tramo de cauce. \n'\ - ' - Celdas: No aplica y se hacen todos iguales a la unidad. \n'\ - ' - Laderas: Es el ancho del canal calculado a partir de geomrofologia o entregado. \n'\ - ' models.elem_area : Area de cada celda (cu.dxp**2) o ladera (nceldasLadera * cu.dxp**2). \n'\ - #Obtiene lo basico para luego pasar argumentos - acum,hill_long,pend,elev = cu.basin_basics(self.structure, - self.DEMvec,self.DIRvec,self.ncells) - #Obtiene la pendiente y la longitud de las corrientes - cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( - self.structure,acum,umbrales[1],self.ncells) - stream_s,stream_l = cu.basin_stream_slope( - self.structure,elev,hill_long,nodos,n_cauce,self.ncells) - stream_s[np.isnan(stream_s)]=self.nodata - #Obtiene para metros por subn cuencas - sub_horton,nod_horton = cu.basin_subbasin_horton(self.hills,self.ncells, - self.hills.shape[1]) - sub_basin_long,max_long,nodo_max_long = cu.basin_subbasin_long( - self.hills_own,cauce,hill_long,self.hills, - sub_horton,self.hills.shape[1],self.ncells) - #Obtiene las propiedades por laderas de los cauces - stream_slope,stream_long = cu.basin_subbasin_stream_prop( - self.hills_own,cauce,hill_long, - pend,self.hills.shape[1],self.ncells) - #opbtiene el ancho si noe s dado lo asume igual a uno - if stream_width is None: - stream_width=np.ones(self.ncells) - #De acuerdo a si el modelo es por laderas o por celdas agrega lass varaibeles - if self.modelType[0]=='c': - #Obtiene el tipo de celdas - unit_type = cu.basin_stream_type(self.structure, - acum,umbrales,len(umbrales),self.ncells) - #Asigna variables - models.drena = np.ones((1,self.ncells))*self.structure - models.nceldas = self.ncells - models.unit_type = np.ones((1,self.ncells))*unit_type - models.hill_long = np.ones((1,self.ncells))*hill_long - models.hill_slope = np.ones((1,self.ncells))*pend - models.stream_long = np.ones((1,self.ncells))*np.percentile(hill_long, 40) - models.stream_slope = np.ones((1,self.ncells))*pend - models.stream_width = np.ones((1,self.ncells))*stream_width - models.elem_area = np.ones((1,self.ncells))*cu.dxp**2.0 - elif self.modelType[0]=='h': - N=self.hills.shape[1] - models.drena = np.ones((1,N))*self.hills[1] - models.nceldas = self.hills.shape[1] - models.unit_type = np.ones((1,N))*np.ones(N)*3 - models.hill_long = np.ones((1,N))*sub_basin_long - models.hill_slope = np.ones((1,N))*self.Transform_Basin2Hills(pend) - models.stream_long = np.ones((1,N))*stream_long - models.stream_slope = np.ones((1,N))*stream_slope - models.stream_width = np.ones((1,N))*cu.basin_subbasin_map2subbasin( - self.hills_own,stream_width,self.nhills,cauce,0,self.ncells) - no0min = models.stream_width[models.stream_width<>0].min() - models.stream_width[models.stream_width==0] = no0min - models.elem_area = np.ones((1,N))*np.array([self.hills_own[self.hills_own==i].shape[0] for i in range(1,self.hills.shape[1]+1)])*cu.dxp**2.0 - #Ajusta variable de que la geomorfologia esta calculada - self.isSetGeo = True - - def set_Speed_type(self,types=np.ones(3)): - 'Descripcion: Especifica el tipo de velocidad a usar en cada \n'\ - ' nivel del modelo. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'types : tipos de velocidad .\n'\ - ' 1. Velocidad tipo embalse lineal, no se especifica h_exp.\n'\ - ' 2. Velocidad onda cinematica, se debe especificar h_exp.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con la variable models.speed_type especificada.\n'\ - #Especifica la ecuacion de velocidad a usar en cada nivel del modelo - for c,i in enumerate(types): - if i==1 or i==2: - models.speed_type[c]=i - else: - models.speed_type[c]=1 - - def set_Floods(self,var,VarName, umbral = 1000, NumCeldas = 6, Default = False): - 'Descripcion: Aloja las variables del sub modelo de inundaciones\n'\ - '\n'\ - 'Parametros\n'\ - 'Mierda PUTA\n'\ - '----------\n'\ - 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ - 'varName: Nombre de la variable a ingresar en el modelo.\n'\ - ' GammaWater : Densidad del agua (Defecto: 1000).\n'\ - ' GammaSoil : Densidad del sedimento (Defecto: 2600).\n'\ - ' VelArea: Factor conversion Velocidad - Area (Defecto: 1/200).\n'\ - ' Cmax: Maxima concentracion de sedimentos (Defecto 0.75).\n'\ - ' MaxIter: Cantidad maxima de iteraciones para obtener la mancha de inunudacion.\n'\ - ' VelUmbral: Velocidad minima para que se de el flujo de escombros ( Defecto: 3 m/s).\n'\ - ' Stream_W: Ancho del canal en cada celda (ncells).\n'\ - ' Stream_D50: Tamano de particula percentil 50 (ncells).\n'\ - ' HAND: Modelo de elevacion relativa de celda ladera a celda cauce (ncells), no se ponde nada.\n'\ - ' umbral: Umbral para determinar corriente segun HAND debe coincidir con el umbral del modelo.\n'\ - ' Slope: Pendiente del canal, (no se ponde variable)\n'\ - ' Default: Poner o no parametros por defecto (False)\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ - ' wmf.models.flood_dw.\n'\ - ' wmf.models.flood_dsed.\n'\ - ' wmf.models.flood_av.\n'\ - ' wmf.models.flood_cmax.\n'\ - ' wmf.models.flood_d50.\n'\ - ' wmf.models.flood_hand.\n'\ - ' wmf.models.flood_aquien.\n'\ - #Si el modelo es tipo ladera agrega la variable - if self.modelType[0] == 'h': - return 'El modelo por laderas no simula inundaciones.' - #Pone el gamma del agua por defecto - if Default: - models.flood_dw = 1000 - models.flood_dsed = 2600 - models.flood_av = 1./200.0 - models.flood_cmax = 0.75 - models.flood_umbral = 3.0 - models.flood_max_iter = 10 - models.flood_step = 1.0 - #Obtiene el vector que va a alojar en el modelo - if VarName <> 'GammaWater' and VarName <> 'GammaSoil' and VarName <> 'VelArea' and VarName <> 'Cmax' and VarName <> 'VelUmbral': - isVec=False - if type(var) is str: - #Si es un string lee el mapa alojado en esa ruta - Map,Pp = read_map_raster(var) - Vec = self.Transform_Map2Basin(Map,Pp) - isVec=True - elif type(var) is int or float: - Vec = np.ones((1,self.ncells))*var - isVec=True - elif type(var) is np.ndarray and var.shape[0] == self.ncells: - Vec = var - isVec=True - #finalmente mete la variable en el modelo - N = self.ncells - if VarName is 'Stream_W' : - models.flood_w = np.ones((1,N))*Vec - elif VarName is 'Stream_D50': - models.flood_d50 = np.ones((1,N))*Vec - elif VarName is 'HAND': - self.GetGeo_HAND(umbral = umbral) - models.flood_hand = np.ones((1,N))*np.copy(self.CellHAND) - models.flood_aquien = np.ones((1,N))*np.copy(self.CellHAND_drainCell) - elif VarName is 'Slope': - self.GetGeo_Cell_Basics() - models.flood_slope = np.ones((1,N))*np.sin(np.arctan(self.CellSlope)) - elif VarName is 'Sections': - self.GetGeo_Sections(NumCeldas = NumCeldas) - models.flood_sections = np.ones((NumCeldas*2+1,N)) * self.Sections - models.flood_sec_cells = np.ones((NumCeldas*2+1,N)) * self.Sections_Cells - elif VarName == 'GammaWater': - models.flood_dw = var - elif VarName == 'GammaSoil': - models.flood_dsed = var - elif VarName == 'VelArea': - models.flood_av = var - elif VarName == 'Cmax': - models.flood_cmax = var - elif VarName == 'VelUmbral': - models.flood_umbral = var - elif VarName == 'MaxIter': - models.flood_max_iter = var - - def set_PhysicVariables(self,modelVarName,var,pos,mask=None): - 'Descripcion: Coloca las variables fisicas en el modelo \n'\ - ' Se debe assignarel nombre del tipo de variable, la variable\n'\ - ' y la posicion en que esta va a ser insertada\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Objeto de la cuenca 2que luego se va a simular.\n'\ - 'modelVarName : Nombre de la variable del modelo que se va a incertar.\n'\ - ' - h_coef: coeficientes horizontales\n'\ - ' [0]: Flujo de Escorrentia.\n'\ - ' [1]: Flujo Sub-superficial.\n'\ - ' [2]: Flujo subterraneo.\n'\ - ' [3]: Flujo en cauces.\n'\ - ' - h_exp: exponentes del tipo v = h_coef*(A**h_exp)\n'\ - ' [0]: Escorrentia.\n'\ - ' [1]: sub-superficial.\n'\ - ' [2]: subterraneo.\n'\ - ' [3]: cauce.\n'\ - ' - v_coef.\n'\ - ' [0]: Tasa evaporacion.\n'\ - ' [1]: Infiltracion.\n'\ - ' [2]: Percolacion.\n'\ - ' [3]: Perdidas (0).\n'\ - ' - v_exp: procesos verticales no lineales\n'\ - ' (no implementado dentro del modelo)\n' - ' - capilar.\n'\ - ' - gravit.\n'\ - 'var : variable que ingresa en el modelo, esta puede ser:.\n'\ - ' - Ruta: una ruta del tipo string.\n'\ - ' - Escalar : Un valor escalar que se asignara a toda la cuenca.\n'\ - ' - Vector : Un vector con la informacion leida (1,ncells).\n'\ - 'pos : Posicion de insercion, aplica para : h_coef, v_coef,.\n'\ - ' h_exp, v_exp.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Guarda el binario, no hay retorno\n'\ - '\n'\ - 'Mirar Tambien\n'\ - '----------\n'\ - 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ - 'rain_read_bin: Lee binario de registros para ver que tiene.\n'\ - 'rain_ncf2bin: Convierte ncf a binario en formato del modelo (para imagenes de radar).\n'\ - - #Obtiene el vector que va a alojar en el modelo - isVec=False - if type(var) is str: - #Si es un string lee el mapa alojado en esa ruta - Map,Pp = read_map_raster(var) - Vec = self.Transform_Map2Basin(Map,Pp) - isVec=True - elif type(var) is int or float: - Vec = np.ones((1,self.ncells))*var - isVec=True - elif type(var) is np.ndarray and var.shape[0] == self.ncells: - Vec = var - isVec=True - #Si el modelo es tipo ladera agrega la variable - if self.modelType[0] is 'h': - Vec = self.Transform_Basin2Hills(Vec,mask=mask) - #finalmente mete la variable en el modelo - if modelVarName is 'h_coef': - models.h_coef[pos] = Vec - elif modelVarName is 'h_exp': - models.h_exp[pos] = Vec - elif modelVarName is 'v_coef': - models.v_coef[pos] = Vec - elif modelVarName is 'v_exp': - models.v_exp[pos] = Vec - elif modelVarName is 'capilar': - models.max_capilar[0] = Vec - elif modelVarName is 'gravit': - models.max_gravita[0] = Vec - - def set_Storage(self,var,pos,hour_scale=False): - 'Descripcion: \n'\ - ' Establece el almacenamiento inicial del modelo\n'\ - ' la variable puede ser un valor, una ruta o un vector.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'var : Variable con la cual se va a iniciar el almancenamiento.\n'\ - ' - ruta : es una ruta a un archivo binario de almacenamiento.\n'\ - ' - escalar : valor de almacenamiento constate para toda la cuenca.\n'\ - ' - vector : Vector con valores para cadda unidad de la cuenca.\n'\ - 'pos : Posicion de insercion,.\n'\ - ' - 0 : alm cpailar.\n'\ - ' - 1 : alm superficial.\n'\ - ' - 2 : alm sub-superficial.\n'\ - ' - 3 : alm subterraneo.\n'\ - ' - 4 : alm cauce.\n'\ - ' - fecha: en caso de que var sea la ruta a StOhdr:\n'\ - ' - valor: puede ser un entero con la posicion.\n'\ - ' - str fecha: puede ser un srint con la fecha: YYYY-MM-DD-HH:MM :\n'\ - 'hour_scale: Buscar fechas a escala horaria o minutos?.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Guarda el binario, no hay retorno\n'\ - '\n'\ - 'Mirar Tambien\n'\ - '----------\n'\ - 'save_storage(slef,storage).\n'\ - #Determina el tipo de unidades del modelo - if self.modelType[0] is 'c': - N = self.ncells - elif self.modelType[0] is 'h': - N = self.nhills - #Obtiene el vector que va a alojar en el modelo - isVec=False - if type(var) is str: - var_bin,var_hdr = __Add_hdr_bin_2route__(var,storage = True) - if type(pos) is not str: - #Si es un string lee el binario de almacenamiento alojado en esa ruta - Vec,res = models.read_float_basin_ncol(var_bin,pos+1,N,5) - if type(pos) == str: - # Lee las fechas - L = np.loadtxt(var_hdr,skiprows = 5, usecols = (0,6), dtype = str) - if hour_scale == False: - Fechas = [datetime.datetime.strptime(i[1], '%Y-%m-%d-%H:%M') for i in L] - else: - Fechas = [datetime.datetime.strptime(i[1][:-3], '%Y-%m-%d-%H') for i in L] - try: - if hour_scale == False: - posFecha = Fechas.index(datetime.datetime.strptime(pos, '%Y-%m-%d-%H:%M')) - else: - posFecha = Fechas.index(datetime.datetime.strptime(pos[:-3], '%Y-%m-%d-%H')) - except: - print 'Error: no se encuentra la fecha especificada en el archivo '+var - Vec,res = models.read_float_basin_ncol(var_bin,posFecha+1,N,5) - isVec=True - for p in range(5): - models.storage[p] = Vec[p] - elif type(var) is int or float: - Vec = np.ones((1,N))*var - isVec=True - models.storage[pos] = Vec - elif type(var) is np.ndarray and var.shape[0] == N: - Vec = var - isVec=True - models.storage[pos] = Vec - - def set_Control(self,coordXY,ids,tipo = 'Q'): - 'Descripcion: \n'\ - ' Establece los puntos deonde se va a realizar control del caudal\n'\ - ' y de la humedad simulada.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'coordXY : Coordenadas de los puntos de control [2,Ncontrol].\n'\ - 'ids : Identificacion de los puntos de control.\n'\ - 'tipo: Control para caudal [Q] o para humedad [H].\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Define los puntos de control en las variables:\n'\ - ' - models.control : control de caudal y sedimentos.\n'\ - ' - models.control_h : control de la humedad del suelo.\n'\ - 'IdsControl : El orden en que quedaron los puntos de control al interior.\n'\ - '\n'\ - 'Mirar Tambien\n'\ - '----------\n'\ - 'set_record, set_storage.\n'\ - #Obtiene los puntos donde hay coordenadas - if tipo is 'Q': - xyNew, basinPts, order = self.Points_Points2Stream(coordXY,ids) - if self.modelType[0] is 'c': - models.control[0] = basinPts - IdsConvert = basinPts[basinPts<>0] - elif self.modelType[0] is 'h': - unitario = basinPts / basinPts - pos = self.hills_own * self.CellCauce * unitario - posGrande = self.hills_own * self.CellCauce * basinPts - IdsConvert = posGrande[posGrande<>0] / pos[pos<>0] - models.control[0][pos[pos<>0].astype(int).tolist()] = IdsConvert - elif tipo is 'H': - xyNew = coordXY - basinPts, order = self.Points_Points2Basin(coordXY,ids) - if self.modelType[0] == 'c': - models.control_h[0] = basinPts - IdsConvert = basinPts[basinPts<>0] - elif self.modelType[0] == 'h': - unitario = basinPts / basinPts - pos = self.hills_own * unitario - posGrande = self.hills_own * basinPts - IdsConvert = posGrande[posGrande<>0] / pos[pos<>0] - models.control_h[0][pos[pos<>0].astype(int).tolist()] = IdsConvert - return IdsConvert,xyNew - - - def set_sediments(self,var,VarName, wi = [0.036, 2.2e-4, 8.6e-7], - diametro = [0.35, 0.016, 0.001], G = 9.8): - 'Descripcion: Alojas las variables requeridas para la ejecucion\n'\ - ' del modelo de sedimentos.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ - 'varName: Nombre de la variable a ingresar en el modelo.\n'\ - ' Krus : Erosividad del suelo (RUSLE).\n'\ - ' Crus : Cobertura del suelo (RUSLE).\n'\ - ' Prus : Practicas proteccion (RUSLE).\n'\ - ' PArLiAc : Porcentaje Arenas, Limos y Arcillas.\n'\ - ' wi : velocidad de caida de cada particula de sed [m/s].\n'\ - ' diametro : diametro de cada tipo de sedimento [mm].\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ - ' wmf.models.krus.\n'\ - ' wmf.models.crus.\n'\ - ' wmf.models.prus.\n'\ - ' wmf.models.parliac.\n'\ - ' wmf.models.wi.\n'\ - ' wmf.models.diametro.\n'\ - #Determina el tipo de unidades del modelo - if self.modelType[0] is 'c': - N = self.ncells - elif self.modelType[0] is 'h': - N = self.nhills - #Se fija que tipo de variable es - isVec=False - if type(var) is str: - #Si es un string lee el mapa alojado en esa ruta - Map,Pp = read_map_raster(var) - Vec = self.Transform_Map2Basin(Map,Pp) - isVec=True - elif type(var) is int or float: - Vec = np.ones((1,self.ncells))*var - isVec=True - elif type(var) is np.ndarray and var.shape[0] == self.ncells: - Vec = var - isVec=True - #Si el modelo es tipo ladera agrega la variable - if self.modelType[0] is 'h': - Vec = self.Transform_Basin2Hills(Vec,mask=mask) - #Inicia las variables - if VarName == 'Krus': - models.krus = np.ones((1,N))*Vec - if VarName == 'Prus': - models.prus = np.ones((1,N))*Vec - if VarName == 'Crus': - models.crus = np.ones((1,N))*Vec - if VarName == 'PArLiAc': - models.parliac = np.ones((3,N))*Vec - #Variables de diametro y velocidad de caida - models.wi = wi - models.diametro = diametro - models.g = G - - def set_Slides(self,var,VarName): - 'Descripcion: Alojas las variables requeridas para la ejecucion\n'\ - ' del modelo de deslizamientos.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ - 'varName: Nombre de la variable a ingresar en el modelo.\n'\ - ' Zs : Profundidad del suelo.\n'\ - ' GammaSoil: Densidad del suelo.\n'\ - ' Cohesion: Cohesion del suelo.\n'\ - ' FrictionAngle : Angulo de friccion del suelo.\n'\ - ' FS: Factor de Seguridad, en este caso se envia una constante.\n'\ - ' RadSlope : .\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ - ' wmf.models.sl_zs.\n'\ - ' wmf.models.sl_gammas.\n'\ - ' wmf.models.sl_cohesion.\n'\ - ' wmf.models.sl_frictionangle.\n'\ - ' wmf.models.sl_radslope.\n'\ - ' wmf.models.sl_fs.\n'\ - #Pone el gamma del agua por defecto - models.sl_gammaw = 9.8 - #Obtiene el vector que va a alojar en el modelo - if VarName <> 'FS': - isVec=False - if type(var) is str: - #Si es un string lee el mapa alojado en esa ruta - Map,Pp = read_map_raster(var) - Vec = self.Transform_Map2Basin(Map,Pp) - isVec=True - elif type(var) is int or float: - Vec = np.ones((1,self.ncells))*var - isVec=True - elif type(var) is np.ndarray and var.shape[0] == self.ncells: - Vec = var - isVec=True - #Si el modelo es tipo ladera agrega la variable - if self.modelType[0] == 'h': - return 'El modelo por laderas no simula deslizamientos.' - #finalmente mete la variable en el modelo - N = self.ncells - if VarName is 'GammaSoil' : - models.sl_gammas = np.ones((1,N))*Vec - elif VarName is 'Cohesion': - models.sl_cohesion = np.ones((1,N))*Vec - elif VarName is 'FrictionAngle': - models.sl_frictionangle = np.ones((1,N))*np.deg2rad(Vec) - elif VarName is 'Zs': - models.sl_zs = np.ones((1,N))*Vec - elif VarName is 'FS': - models.sl_fs = var - elif VarName is 'Slope': - models.sl_radslope = np.ones((1,N))*np.arctan(Vec) - models.sl_radslope[models.sl_radslope == 0] = 0.01 - #------------------------------------------------------ - # Guardado y Cargado de modelos de cuencas preparados - #------------------------------------------------------ - def Save_SimuBasin(self,ruta,SimSlides = False, - ExtraVar = None): - 'Descripcion: guarda una cuenca previamente ejecutada\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'ruta : Ruta donde la cuenca sera guardada.\n'\ - 'ruta_dem : direccion donde se aloja el DEM (se recomienda absoluta).\n'\ - 'ruta_dir : direccion donde se aloja el DIR (se recomienda absoluta).\n'\ - 'SimSlides: indica a la funcion si va a guardar o no informacion para la simulacion.\n'\ - ' de deslizamientos.\n'\ - 'ExtraVar: Variables extras de simulacion deben ir en un diccionario.\n'\ - ' Forma del diccionario Dict = {"varName": {"Data": vector[ncells], "type": "tipo"}}.\n'\ - ' Los tipos de variables son: flotante: "f4", entero "i4".\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con las variables iniciadas.\n'\ - #Si esta o no set el Geomorphology, de acuerdo a eso lo estima por defecto - if self.isSetGeo is False: - self.set_Geomorphology() - print 'Aviso: SE ha estimado la geomorfologia con los umbrales por defecto umbral = [30, 500]' - #Guarda la cuenca - if self.modelType[0] is 'c': - N = self.ncells - elif self.modelType[0] is 'h': - N = self.nhills - Dict = {'nombre':self.name, - 'modelType':self.modelType,'noData':cu.nodata,'umbral':self.umbral, - 'ncells':self.ncells,'nhills':self.nhills, - 'dt':models.dt,'Nelem':N,'dxp':cu.dxp,'retorno':models.retorno, - 'storageConst' :models.storage_constant, - 'ncols':cu.ncols, - 'nrows':cu.nrows, - 'xll':cu.xll, - 'yll':cu.yll, - 'dx':cu.dx, - 'dy':cu.dy, - 'epsg': self.epsg} - if SimSlides: - Dict.update({'sl_fs':models.sl_fs, 'sl_gullie':models.sl_gullienogullie, 'sl_gammaw':models.sl_gammaw}) - #abre el archivo - gr = netcdf.Dataset(ruta,'w',format='NETCDF4') - #Grupo base - GrupoBase = gr.createGroup('base') - GrupoSimHid = gr.createGroup('SimHidro') - GrupoSimSed = gr.createGroup('SimSediments') - GrupoSimSli = gr.createGroup('SimSlides') - GrupoHidro = gr.createGroup('Hidro') - GrupoGeo = gr.createGroup('Geomorfo') - GrupoCalib = gr.createGroup('Parametros') - #Variables grupo base - DimNcell = GrupoBase.createDimension('ncell',self.ncells) - DimNhill = GrupoBase.createDimension('nhills',self.nhills) - DimCol3 = GrupoBase.createDimension('col3',3) - DimCol2 = GrupoBase.createDimension('col2',2) - VarStruc = GrupoBase.createVariable('structure','i4',('col3','ncell'),zlib=True) - VarHills = GrupoBase.createVariable('hills','i4',('col2','nhills'),zlib=True) - VarHills_own = GrupoBase.createVariable('hills_own','i4',('ncell',),zlib=True) - VarStruc[:] = self.structure - VarHills[:] = self.hills - VarHills_own[:] = self.hills_own - #Variables de Simulacion hidrologica - DimNelem = GrupoSimHid.createDimension('Nelem',N) - DimCol3 = GrupoSimHid.createDimension('col3',3) - DimCol2 = GrupoSimHid.createDimension('col2',2) - DimCol4 = GrupoSimHid.createDimension('col4',4) - DimCol5 = GrupoSimHid.createDimension('col5',5) - VarH_coef = GrupoSimHid.createVariable('h_coef','f4',('col4','Nelem'),zlib=True) - VarV_coef = GrupoSimHid.createVariable('v_coef','f4',('col4','Nelem'),zlib=True) - VarH_exp = GrupoSimHid.createVariable('h_exp','f4',('col4','Nelem'),zlib=True) - VarV_exp = GrupoSimHid.createVariable('v_exp','f4',('col4','Nelem'),zlib=True) - Var_H1max = GrupoSimHid.createVariable('h1_max','f4',('Nelem',),zlib = True) - Var_H3max = GrupoSimHid.createVariable('h3_max','f4',('Nelem',),zlib = True) - Control = GrupoSimHid.createVariable('control','i4',('Nelem',),zlib = True) - ControlH = GrupoSimHid.createVariable('control_h','i4',('Nelem',),zlib = True) - if self.modelType[0] is 'c': - drena = GrupoSimHid.createVariable('drena','i4',('col3','Nelem'),zlib = True) - elif self.modelType[0] is 'h': - drena = GrupoSimHid.createVariable('drena','i4',('Nelem'),zlib = True) - unitType = GrupoSimHid.createVariable('unit_type','i4',('Nelem',),zlib = True) - hill_long = GrupoSimHid.createVariable('hill_long','f4',('Nelem',),zlib = True) - hill_slope = GrupoSimHid.createVariable('hill_slope','f4',('Nelem',),zlib = True) - stream_long = GrupoSimHid.createVariable('stream_long','f4',('Nelem',),zlib = True) - stream_slope = GrupoSimHid.createVariable('stream_slope','f4',('Nelem',),zlib = True) - stream_width = GrupoSimHid.createVariable('stream_width','f4',('Nelem',),zlib = True) - elem_area = GrupoSimHid.createVariable('elem_area','f4',('Nelem',),zlib = True) - speed_type = GrupoSimHid.createVariable('speed_type','i4',('col3',),zlib = True) - storage = GrupoSimHid.createVariable('storage','i4',('col5','Nelem'),zlib = True) - VarH_coef[:] = models.h_coef - VarV_coef[:] = models.v_coef - VarH_exp[:] = models.h_exp - VarV_exp[:] = models.v_exp - Var_H1max[:] = models.max_capilar - Var_H3max[:] = models.max_gravita - Control[:] = models.control - ControlH[:] = models.control_h - drena[:] = models.drena - unitType[:] = models.unit_type - hill_long[:] = models.hill_long - hill_slope[:] = models.hill_slope - stream_long[:] = models.stream_long - stream_slope[:] = models.stream_slope - stream_width[:] = models.stream_width - elem_area[:] = models.elem_area - speed_type[:] = models.speed_type - storage[:] = models.storage - #Variables grupo GEomorfologia - DimNcell = GrupoGeo.createDimension('ncell',self.ncells) - VarDEM = GrupoGeo.createVariable('DEM','f4',('ncell',),zlib = True) - VarDIR = GrupoGeo.createVariable('DIR','i4',('ncell',),zlib = True) - VarDEM[:] = self.DEMvec - VarDIR[:] = self.DIRvec - #Variables de deslizamientos - if SimSlides: - DimNelem = GrupoSimSli.createDimension('Nelem',N) - frictionAngle = GrupoSimSli.createVariable('friction_angle','f4',('Nelem',),zlib = True) - Cohesion = GrupoSimSli.createVariable('cohesion','f4',('Nelem',),zlib = True) - GammaSoil = GrupoSimSli.createVariable('gamma_soil','f4',('Nelem',),zlib = True) - ZSoil = GrupoSimSli.createVariable('z_soil','f4',('Nelem',),zlib = True) - RadSlope = GrupoSimSli.createVariable('rad_slope','f4',('Nelem',),zlib = True) - frictionAngle[:] = models.sl_frictionangle - Cohesion[:] = models.sl_cohesion - GammaSoil[:] = models.sl_gammas - ZSoil[:] = models.sl_zs - RadSlope[:] = models.sl_radslope - #Introduce variables extras en caso de que el usuario las incluyera - if type(ExtraVar) is dict: - for k in ExtraVar.keys(): - Var = gr.createVariable(k,ExtraVar[k]['type'],('ncell',),zlib=True) - Var[:] = ExtraVar[k]['Data'] - #asigna las prop a la cuenca - gr.setncatts(Dict) - #Cierra el archivo - gr.close() - #Sale del programa - return - - #------------------------------------------------------ - # Ejecucion del modelo - #------------------------------------------------------ - def run_shia(self,Calibracion, - rain_rute, N_intervals, start_point = 1, StorageLoc = None, HspeedLoc = None,ruta_storage = None, ruta_speed = None, - ruta_conv = None, ruta_stra = None, ruta_retorno = None,kinematicN = 5, QsimDataFrame = True, EvpVariable = False): - 'Descripcion: Ejecuta el modelo una ves este es preparado\n'\ - ' Antes de su ejecucion se deben tener listas todas las . \n'\ - ' variables requeridas . \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Cuenca a ejecutar con todo listo para ser ejecutada.\n'\ - 'Calibracion : Parametros de calibracion del modelo, orden:.\n'\ - ' - Evaporacion.\n'\ - ' - Infiltracion.\n'\ - ' - Percolacion.\n'\ - ' - Perdidas.\n'\ - ' - Vel Superficial .\n'\ - ' - Vel Sub-superficial.\n'\ - ' - Vel Subterranea.\n'\ - ' - Vel Cauce.\n'\ - ' - Max Capilar.\n'\ - ' - Max Gravitacional.\n'\ - 'rain_rute : Ruta donde se encuentra el archivo binario de lluvia:.\n'\ - ' generado por rain_interpolate_* o por rain_radar2basin.\n'\ - 'N_intervals : Numero de intervalos de tiempo.\n'\ - 'start_point : Punto donde comienza a usar registros de lluvia.\n'\ - ' los binarios generados por rain_* generan un archivo de texto.\n'\ - ' que contiene fechas par aayudar a ubicar el punto de inicio deseado.\n'\ - 'StorageLoc: Variable local de almacenamiento, esto es en el caso de que no se.\n'\ - ' desee usar la configuracion global de almacenamiento del modelo (5, N).\n'\ - 'HspeedLoc: Variable local para setear la velocidad horizontal inicial de ejecucion.\n'\ - 'ruta_storage : Ruta donde se guardan los estados del modelo en cada intervalo.\n'\ - ' de tiempo, esta es opcional, solo se guardan si esta variable es asignada.\n'\ - 'ruta_conv : Ruta al binario y hdr indicando las nubes que son convectivas.\n'\ - 'ruta_stra : Ruta al binario y hdr indicando las nubes que son estratiformes.\n'\ - 'ruta_retorno : Ruta al binario y hdr en donde escribe la serie con los milimetros retornados al tanque runoff.\n'\ - 'kinematicN: Cantidad de iteraciones para la solucion de la onda cinematica.\n'\ - ' De forma continua: 5 iteraciones, recomendado para cuando el modelo se\n'\ - ' ejecuta en forma continua Ej: cu.run_shia(Calib, rain_rute, 100)\n'\ - ' Por intervalos: 10 iteraciones, recomendado cuando el modelo se ejecuta\n'\ - ' por intervalos de un paso ej:\n'\ - ' for i in range(1,N)\n'\ - ' Results = cu.run_shia(Calib, ruta_rain, 1, i)\n'\ - ' for c,j in enumerate(Results[''Storage'']):\n'\ - ' cu.set_Storage(j,c)\n'\ - 'QsimDataFrame: Retorna un data frame con los caudales simulados indicando su id de acuerdo con el\n'\ - ' que guarda la funcion Save_Net2Map con la opcion NumTramo = True. \n'\ - 'EvpVariable: (False) Asume que la evp del modelo cambia en funcion o no de la radiacion\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Qsim : Caudal simulado en los puntos de control.\n'\ - 'Hsim : Humedad simulada en los puntos de control.\n'\ - #genera las rutas - rain_ruteBin,rain_ruteHdr = __Add_hdr_bin_2route__(rain_rute) - #Obtiene las fechas - Rain = read_mean_rain(rain_ruteHdr, N_intervals, start_point) - # De acuerdo al tipo de modelo determina la cantidad de elementos - if self.modelType[0] is 'c': - N = self.ncells - elif self.modelType[0] is 'h': - N = self.nhills - #prepara variables globales - models.rain_first_point = start_point - models.calc_niter = kinematicN - #Prepara terminos para control - if np.count_nonzero(models.control) == 0 : - NcontrolQ = 1 - else: - NcontrolQ = np.count_nonzero(models.control)+1 - if np.count_nonzero(models.control_h) == 0 : - NcontrolH = 1 - else: - NcontrolH = np.count_nonzero(models.control_h) - #Prepara variables de guardado de almacenamiento - if ruta_storage is not None: - models.save_storage = 1 - ruta_sto_bin, ruta_sto_hdr = __Add_hdr_bin_2route__(ruta_storage, - storage = True) - else: - models.save_storage = 0 - ruta_sto_bin = 'no_guardo_nada.StObin' - ruta_sto_hdr = 'no_guardo_nada.StOhdr' - #prepara variable para guardado de velocidad - if ruta_speed is not None: - models.save_speed = 1 - ruta_speed_bin, ruta_speed_hdr = __Add_hdr_bin_2route__(ruta_speed, - storage = True) - else: - models.save_speed = 0 - ruta_speed_bin = 'no_guardo_nada.bin' - ruta_speed_hdr = 'no_guardo_nada.hdr' - #Prepara variables para el almacenamiento de retorno - if ruta_retorno is not None: - models.save_retorno = 1 - ruta_ret_bin, ruta_ret_hdr = __Add_hdr_bin_2route__(ruta_retorno) - else: - models.save_retorno = 0 - ruta_ret_bin = 'no_guardo_nada.bin' - ruta_ret_hdr = 'no_guardo_nada.hdr' - #Variables de separacion de flujo por tipo de lluvia - if ruta_conv is not None and ruta_stra is not None: - ruta_binConv,ruta_hdrConv = __Add_hdr_bin_2route__(ruta_conv) - ruta_binStra,ruta_hdrStra = __Add_hdr_bin_2route__(ruta_stra) - models.separate_rain = 1 - else: - models.separate_rain = 0 - ruta_binConv = 'none' - ruta_hdrConv = 'none' - ruta_binStra = 'none' - ruta_hdrStra = 'none' - #Prepara la variable de almacenamiento - if StorageLoc is not None: - if StorageLoc.shape <> (5, N): - print 'Error: almacenamiento debe ser: (5,'+str(N)+'), y es: ('+str(StorageLoc.shape[0])+','+str(StorageLoc.shape[1])+')' - StorageLoc = np.zeros((5,N))*-9999.0 - else: - StorageLoc = np.zeros((5,N))*-9999.0 - #Prepara la variable de velocidad horizontal inicial - if HspeedLoc is not None: - if HspeedLoc.shape <> (4, N): - print 'Error: velocidad debe ser: (4,'+str(N)+'), y es: ('+str(HspeedLoc.shape[0])+','+str(HspeedLoc.shape[1])+')' - HspeedLoc = np.zeros((4,N))*-9999.0 - else: - HspeedLoc = np.zeros((4,N))*-9999.0 - #Implementa o no la EVP variable en funcion de la radiacion - if EvpVariable: - Rad = self.__GetEVP_Serie__(Rain.index) - else: - models.evpserie = np.ones(N_intervals) - # Ejecuta el modelo - Qsim,Qsed,Qseparated,Humedad,St1,St3,Balance,Speed,Area,Alm,Qsep_byrain = models.shia_v1( - rain_ruteBin, - rain_ruteHdr, - Calibracion, - #N, - NcontrolQ, - NcontrolH, - N_intervals, - StorageLoc, - HspeedLoc, - N, - ruta_sto_bin, - ruta_speed_bin, - ruta_binConv, - ruta_binStra, - ruta_hdrConv, - ruta_hdrStra, - ruta_ret_bin) - #Retorno de variables de acuerdo a lo simulado - Retornos={'Qsim' : Qsim} - Retornos.update({'Balance' : Balance}) - Retornos.update({'Storage' : Alm}) - if np.count_nonzero(models.control_h)>0: - Retornos.update({'Humedad' : Humedad}) - Retornos.update({'Humedad_t1' : St1}) - Retornos.update({'Humedad_t2' : St3}) - if models.sim_sediments == 1: - Retornos.update({'Sediments' : Qsed}) - if models.separate_fluxes == 1: - Retornos.update({'Fluxes' : Qseparated}) - if models.separate_rain == 1: - Retornos.update({'Rain_sep' : Qsep_byrain}) - if models.show_storage == 1: - Retornos.update({'Mean_Storage' : np.copy(models.mean_storage)}) - if models.save_storage == 1: - rutaStorageHdr = __Add_hdr_bin_2route__(ruta_storage) - #Caso en el que se registra el alm medio - if models.show_storage == 1: - __Save_storage_hdr__(ruta_sto_hdr,rain_ruteHdr,N_intervals, - start_point,self,Mean_Storage = np.copy(models.mean_storage)) - #Caso en el que no hay alm medio para cada uno de los - else: - __Save_storage_hdr__(ruta_sto_hdr,rain_ruteHdr,N_intervals, - start_point,self,Mean_Storage=np.zeros((5,N))*-9999) - #Area de la seccion - if models.show_area == 1: - Retornos.update({'Sec_Area': Area}) - #Velocidades - if models.show_speed == 1: - Retornos.update({'Speed' : Speed}) - if models.show_mean_speed == 1: - Retornos.update({'Mean_Speed' : np.copy(models.mean_speed)}) - if models.save_speed == 1: - rutaSpeedHdr = __Add_hdr_bin_2route__(ruta_speed) - #Caso en el que hay velocidad media para todos los tanques - if models.show_mean_speed == 1: - __Save_speed_hdr__(ruta_speed_hdr,rain_ruteHdr,N_intervals, - start_point,self,Mean_Speed = np.copy(models.mean_speed)) - #Caso en el que no hay alm medio para cada uno de los - else: - __Save_speed_hdr__(ruta_speed_hdr,rain_ruteHdr,N_intervals, - start_point,self) - - if models.save_retorno == 1: - if models.show_mean_retorno == 1: - __Save_retorno_hdr__(ruta_ret_hdr, rain_ruteHdr, N_intervals, - start_point, self, Mean_retorno = models.mean_retorno) - else: - __Save_retorno_hdr__(ruta_ret_hdr, rain_ruteHdr, N_intervals, - start_point, self) - - #Campo de lluvia acumulado para el evento - Retornos.update({'Rain_Acum': models.acum_rain}) - Retornos.update({'Rain_hietogram': models.mean_rain}) - #Retornos en caso de simular deslizamientos - if models.sim_slides == 1: - Retornos.update({'Slides_Map': np.copy(models.sl_slideocurrence)}) - Retornos.update({'Slides_NCell_Serie': np.copy(models.sl_slidencelltime)}) - Retornos.update({'Slides_Acum':np.copy(models.sl_slideacumulate)}) - #Caudal simulado en un dataframe - if QsimDataFrame: - #Obtiene ids - ids = models.control[models.control<>0] - Qdict = {} - for i,j in zip(Retornos['Qsim'][1:], ids): - Qdict.update({str(j): i}) - Qdict = pd.DataFrame(Qdict, index=Rain.index) - #Si separa flujos, entrega el caudal tambien en data frame por flujos - if models.separate_fluxes == 1: - Qsep = [] - tupla = [] - for z,i,j in zip(Retornos['Qsim'][1:], Retornos['Fluxes'][1:], ids): - tupla.append((str(j),'run')) - tupla.append((str(j),'sub')) - tupla.append((str(j),'sup')) - Qsep.extend([i[0],i[1],z-i[0]-i[1]]) - index = pd.MultiIndex.from_tuples(tupla, names=['reach','flux']) - Qsep = np.array(Qsep) - QsepDict = pd.DataFrame(Qsep.T, index=Rain.index, columns=index) - #Si simula sedimentos, hace el dataframe - if models.sim_sediments == 1: - Qsedi = [] - tupla = [] - for z,i,j in zip(Retornos['Qsim'][1:], Retornos['Sediments'][1:], ids): - tupla.append((str(j),'Sand')) - tupla.append((str(j),'Lime')) - tupla.append((str(j),'Clay')) - Qsedi.extend([i[0],i[1],i[2]])# [i[0],i[1],z-i[0]-i[1]]) - index = pd.MultiIndex.from_tuples(tupla, names=['reach','Sediments']) - Qsedi = np.array(Qsedi) - QsediDict = pd.DataFrame(Qsedi.T, index=Rain.index, columns=index) - if models.separate_fluxes == 1 and models.sim_sediments == 0: - return Retornos, Qdict, QsepDict - if models.separate_fluxes == 1 and models.sim_sediments == 1: - return Retornos, Qdict, QsepDict, QsediDict - if models.separate_fluxes == 0 and models.sim_sediments == 1: - return Retornos, Qdict, QsediDict - return Retornos, Qdict - return Retornos - - def efficiencia(self, Qobs, Qsim): - 'Descripcion: Calcula diferentes indices de desempeno del modelo\n'\ - ' nash, qpico, rmse, rmseLog, t_pico\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'Qobs : Caudal observado.\n'\ - 'Qsim : Caudal simulado.\n'\ - 'Retornos\n'\ - '----------\n'\ - 'DicEff: diccionario con la eficiencia obtenida en cada param.\n'\ - #Comienza a evaluar cada parametro - DictEff = {'Nash': __eval_nash__(Qobs, Qsim)} - DictEff.update({'Qpico': __eval_q_pico__(Qobs, Qsim)}) - DictEff.update({'Tpico': __eval_t_pico__(Qobs, Qsim, models.dt)}) - DictEff.update({'RmseLog': __eval_rmse_log__(Qobs, Qsim)}) - DictEff.update({'Rmse': __eval_rmse__(Qobs, Qsim)}) - return DictEff - - def Calib_NSGAII(self, nsga_el, nodo_eval, pop_size = 40, process = 4, - NGEN = 6, MUTPB = 0.5, CXPB = 0.5): - 'Descripcion: Algoritmo para calibrar de forma automatica el modelo\n'\ - ' hidrologico utilizando DEAP y su funcion de seleccion NSGAII.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - ' - nsga_el : un objeto de la clase nsgaii_element, el cual determinara las reglas.\n'\ - ' para la generacion de calibraciones.\n'\ - ' - nodo_eval: nodo donde se evalua el modelo.\n'\ - ' - pop_size: tamano de la poblacion (cantidad de calibraciones a evaluar, multiplo de 4).\n'\ - ' - process: Cantidad de procesadores que se utilizaran en la generacion.\n'\ - ' - NGEN: Cantidad de generaciones para obtener la poblacion final.\n'\ - ' - MUTPB: Probabilidad generica de que un gen mute.\n'\ - ' - CXPB: Probabilidad generica de que dos genes se crucen.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - ' - pop: poblacion final.\n'\ - ' - Qsim: Caudales simulados en el punto evaluado.\n'\ - ' - fitness: desempeno de la poblacion obtenida.\n'\ - #Check de que la poblacion sea multiplo de 4 - Flag = True - while Flag: - if np.mod(pop_size,4) == 0: - Flag = False - else: - pop_size += 1 - #Inicia el elemento nsga con los parametros de el - nsga_el.set_nsgaII() - #Crea las poblaciones y las ejecuciones - pop = nsga_el.toolbox.population(pop_size) - Ejecs = map(nsga_el.__crea_ejec__, pop) - #Ejecuta a la poblacion - QsimPar = __ejec_parallel__(Ejecs, process, nodo_eval) - fitnesses = map(nsga_el.toolbox.evaluate, QsimPar) - for ind, fit in zip(pop, fitnesses): - ind.fitness.values = fit - #Itera la poblacion hasta encontrar a la mejor - #toolbox = base.Toolbox() - for g in range(NGEN): - offspring = tools.selTournamentDCD(pop, len(pop)) - offspring = map(nsga_el.toolbox.clone, offspring) - # Apply crossover and mutation on the offspring - for child1, child2 in zip(offspring[::2], offspring[1::2]): - if random.random() < CXPB: - nsga_el.toolbox.mate(child1[0], child2[0]) - del child1.fitness.values - del child2.fitness.values - #Muta a algunos de los genomas - for mutant in offspring: - if random.random() < MUTPB: - nsga_el.toolbox.mutate(mutant[0]) - del mutant.fitness.values - #Ejecuta a la nueva generacion - Ejecs = map(nsga_el.__crea_ejec__, offspring) - QsimPar = __ejec_parallel__(Ejecs, process, nodo_eval) - #Identifica a la gente que no cumple de la generacion - Qsim_invalid = [] - invalid_ind = [] - for i,q in zip(offspring, QsimPar): - if not i.fitness.valid: - Qsim_invalid.append(q) - invalid_ind.append(i) - #Evaluate the individuals with an invalid fitness - fitnesses = map(nsga_el.toolbox.evaluate, Qsim_invalid) - for ind, fit in zip(invalid_ind, fitnesses): - ind.fitness.values = fit - #Toma la siguiente generacion - pop = nsga_el.toolbox.select(pop + offspring, pop_size) - #Retorno - return pop, QsimPar, np.array(fitnesses).T - - -class nsgaii_element: - def __init__(self, rutaLluvia, Qobs, npasos, inicio, SimuBasinElem ,evp =[0,1], infil = [1,200], perco = [1, 40], - losses = [0,1],velRun = [0.1, 1], velSub = [0.1, 1], velSup =[0.1, 1], - velStream = [0.1, 1], Hu = [0.1, 1], Hg = [0.1, 1], - probCruce = np.ones(10)*0.5, probMutacion = np.ones(10)*0.5, - rangosMutacion = [[0,1], [1,200], [1,40], [0,1], [0.1,1], [0.1, 1], [0.1,1], [0.1,1], [0.1, 1], [0.1,1]], - MaxMinOptima = (1.0, -1.0), CrowDist = 0.5): - 'Descripcion: Inicia el objeto de calibracion genetica tipo NSGAII\n'\ - ' este objeto contiene las reglas principales para la implementacion\n'\ - ' de todo el algoritmo de calibracion genetico.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - ' -rutaLluvia : Ruta donde se encuentra el archivo de lluvia binario.\n'\ - ' -Qobs: Array numpy con el caudal observado [npasos].\n'\ - ' -npasos: Cantidad de pasos en simulacion.\n'\ - ' -inicio: Punto de inicio en la simulacion.\n'\ - ' -SimuBasinElem: Objeto de simulacion.\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con las variables iniciadas.\n'\ - #Rangos parametros - self.evp_range = evp - self.infil_range = infil - self.perco_range = perco - self.losses_range = losses - self.velRun_range = velRun - self.velSub_range = velSub - self.velSup_range = velSup - self.velStream_range = velStream - self.hu_range = Hu - self.hg_range = Hg - #Establece propiedades para ejecucion - self.npasos = npasos - self.inicio = inicio - self.ruta_lluvia = rutaLluvia - self.Qobs = Qobs - self.simelem = SimuBasinElem - #Propiedades de cruce y mutacion - self.prob_cruce = probCruce - self.prob_mutacion = probMutacion - self.rangos_mutacion = rangosMutacion - self.optimiza = MaxMinOptima - self.crowdist = CrowDist - - def __crea_calibracion__(self): - #Evp - if self.evp_range[0] <> self.evp_range[1]: - evp = np.random.uniform(self.evp_range[0], self.evp_range[1],1)[0] - else: - evp = self.evp_range[0] - #Infiltracion - if self.infil_range[0] <> self.infil_range[1]: - infil = np.random.uniform(self.infil_range[0], self.infil_range[1],1)[0] - else: - infil = self.infil_range[0] - #Percolacion - if self.perco_range[0] <> self.perco_range[1]: - perco = np.random.uniform(self.perco_range[0], self.perco_range[1],1)[0] - else: - perco = self.perco_range[0] - #Perdidas - if self.losses_range[0] <> self.losses_range[1]: - losses = np.random.uniform(self.losses_range[0], self.losses_range[1],1)[0] - else: - losses = self.losses_range[0] - #runoff - if self.velRun_range[0] <> self.velRun_range[1]: - velRun = np.random.uniform(self.velRun_range[0], self.velRun_range[1],1)[0] - else: - velRun = self.velRun_range[0] - #Vel subsuperficial - if self.velSub_range[0] <> self.velSub_range[1]: - velSub = np.random.uniform(self.velSub_range[0], self.velSub_range[1],1)[0] - else: - velSub = self.velSub_range[0] - #Vel acuifero - if self.velSup_range[0] <> self.velSup_range[1]: - velSup = np.random.uniform(self.velSup_range[0], self.velSup_range[1],1)[0] - else: - velSup = self.velSup_range[0] - #Vel cauce - if self.velStream_range[0] <> self.velStream_range[1]: - velStream = np.random.uniform(self.velStream_range[0], self.velStream_range[1],1)[0] - else: - velStream = self.velStream_range[0] - #almacenamiento hu - if self.hu_range[0] <> self.hu_range[1]: - hu = np.random.uniform(self.hu_range[0], self.hu_range[1],1)[0] - else: - hu = self.hu_range[0] - #almacenamiento hg - if self.hg_range[0] <> self.hg_range[1]: - hg = np.random.uniform(self.hg_range[0], self.hg_range[1],1)[0] - else: - hg = self.hg_range[0] - #Retorna una calibracion aleatoria - return [evp, infil, perco, losses, velRun, velSub, velSup, velStream, hu, hg] - - def __crea_ejec__(self, calibracion): - return [calibracion, self.ruta_lluvia, self.npasos, self.inicio, self.simelem] - - def __evalfunc__(self, Qsim, f1 = __eval_nash__, f2 = __eval_q_pico__): - E1 = f1(self.Qobs, Qsim) - E2 = f2(self.Qobs, Qsim) - return E1, E2 - - def __cruce__(self, indi1, indi2): - for i,u in zip(range(10), self.prob_cruce): - p = np.random.uniform(0,1,1) - if p>u: - a = indi1[i]; b = indi2[i] - indi1[i] = b - indi2[i] = a - return indi1, indi2 - - def __mutacion__(self, indi): - c = 0 - for i,u in zip(range(10), self.prob_mutacion): - p = np.random.uniform(0,1,1) - if p>u: - indi[i] = np.random.uniform(self.rangos_mutacion[c][0],self.rangos_mutacion[c][0],1)[0] - c+=1 - return indi - - def set_nsgaII(self): - self.toolbox = base.Toolbox() - creator.create("FitnessMin", base.Fitness, - weights = self.optimiza, - crowding_dist = self.crowdist) - creator.create("Individual", list, fitness=creator.FitnessMin) - self.toolbox.register("attr1", self.__crea_calibracion__) - self.toolbox.register("individual", tools.initRepeat, creator.Individual, - self.toolbox.attr1, n=1) - self.toolbox.register("population", tools.initRepeat, list, self.toolbox.individual) - self.toolbox.register("evaluate", self.__evalfunc__) - self.toolbox.register("mate", self.__cruce__) - self.toolbox.register("mutate", self.__mutacion__) - self.toolbox.register("select", tools.selNSGA2) - -class Stream: - #------------------------------------------------------ - # Subrutinas de trazado de corriente y obtencion de parametros - #------------------------------------------------------ - #Inicia la cuenca - def __init__(self,lat,lon,DEM,DIR,name='NaN'): - 'Descripcion: Traza un cauce e inicia la variable de este \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'lat : Coordenada en X del punto mas alto del cauce.\n'\ - 'lon : Coordenada en Y del punto mas alto del cauce.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con las variables iniciadas y estructura del cauce.\n'\ - #Realiza copia de los mapas y obtiene el cauce - self.DEM = DEM - self.DIR = DIR - self.ncells = cu.stream_find(lat,lon,self.DEM, - self.DIR,cu.ncols,cu.nrows) - self.structure = cu.stream_cut(self.ncells) - #------------------------------------------------------ - # Guardado shp de cauce - #------------------------------------------------------ - def Save_Stream2Map(self,ruta,DriverFormat='ESRI Shapefile', - EPSG=4326): - 'Descripcion: Guarda el cauce trazado en un mapa \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'ruta : Nombre del lugar donde se va a guardar el cauce.\n'\ - 'DriverFormat : Tipo de mapa vectorial.\n'\ - 'EPSG : Codigo de tipo de proyeccion usada (defecto 4326).\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Guarda el cauce en el formato especificado.\n'\ - #Escribe el shp del cauce - if ruta.endswith('.shp')==False: - ruta=ruta+'.shp' - spatialReference = osgeo.osr.SpatialReference() - spatialReference.ImportFromEPSG(EPSG) - driver = osgeo.ogr.GetDriverByName(DriverFormat) - if os.path.exists(ruta): - driver.DeleteDataSource(ruta) - shapeData = driver.CreateDataSource(ruta) - layer = shapeData.CreateLayer('layer1', - spatialReference, osgeo.ogr.wkbLineString) - layerDefinition = layer.GetLayerDefn() - line = osgeo.ogr.Geometry(osgeo.ogr.wkbLineString) - for x,y in zip(self.structure[0],self.structure[1]): - line.AddPoint_2D(float(x),float(y)) - feature = osgeo.ogr.Feature(layerDefinition) - feature.SetGeometry(line) - feature.SetFID(0) - layer.CreateFeature(feature) - line.Destroy() - feature.Destroy() - shapeData.Destroy() - #------------------------------------------------------ - # Plot de variables - #------------------------------------------------------ - def Plot_Profile(self,ruta=None): - 'Descripcion: Grafica el perfil del cauce trazado \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'ruta : Nombre de la imagen si se va a guardar la imagen del cauce.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Guarda el cauce en el formato especificado.\n'\ - #Escribe el shp del cauce - fig=pl.figure(facecolor='w',edgecolor='w') - ax=fig.add_subplot(111) - ax.plot(self.structure[3],self.structure[2],lw=2) - ax.set_xlabel('Distancia $[mts]$',size=14) - ax.set_ylabel('Elevacion $[m.s.n.m]$',size=14) - ax.grid(True) - if ruta is not None: - pl.savefig(ruta,bbox_inches='tight') - pl.show() - #def Plot_Map(self,ruta=None - From b003781141ab0e542a2d22cb260cfd8c664c7ade Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 21 Aug 2018 10:08:34 -0500 Subject: [PATCH 104/142] Revert "Qgis alexa" --- qgisplugin/HydroSEDPlots.py | 2 +- qgisplugin/HydroSEDPluginUtils.py | 2 +- qgisplugin/HydroSEDPlugin_dockwidget.py | 39 +- qgisplugin/resources.py | 2117 +---------- wmf/wmf.py | 4599 +++++++++++++++++++++++ 5 files changed, 4619 insertions(+), 2140 deletions(-) create mode 100644 wmf/wmf.py diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py index 296a136..9765ce9 100644 --- a/qgisplugin/HydroSEDPlots.py +++ b/qgisplugin/HydroSEDPlots.py @@ -222,7 +222,7 @@ def VarHistogram(self, var, pathFigure, ncells): '''Hace el plot de un histograma de una variable seleccionada''' #Seleccion de datos if ncells > 10000: - pos = np.random.choice(len(var), 10000) + pos = np.random.choice(ncells, 10000) else: pos = range(10000) #Obtiene la pdf y cdf de la variable diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index b17484c..7759625 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -253,7 +253,7 @@ def Basin_LoadBasin(self, PathNC, LoadSim = False, LoadSed = False): shape = g.groups[grupoKey].variables[k].shape MapaRaster = False for s in shape: - if s == self.cuenca.ncells: MapaRaster = True + if s == self.cuenca.ncells: MapaRaster = True #Actualiza el diccionario self.DicBasinNc.update({k: {'nombre':k, diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 6f91bd0..45a0904 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -194,7 +194,7 @@ def clickEventBasin2WMF(): self.segundaCarga = True #Cargado de la cuenca Area, self.EPSG, dxp, self.noData, self.umbral = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), - Simhidro, SimSed) + Simhidro, SimSed) #self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), Simhidro, SimSed) self.TableStart() #Actualiza tabla de Nc y comboBox @@ -203,7 +203,7 @@ def clickEventBasin2WMF(): self.TabNC.NewEntry(self.HSutils.DicBasinNc[k],k, self.Tabla_Prop_NC) self.VarFromNC.addItem(k) #Area, self.EPSG, dxp, self.noData, self.umbral = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), - # Simhidro, SimSed) + # Simhidro, SimSed) #print self.umbral #Habilita los botones de visualizacion de red hidrica y divisoria self.Boton_verDivisoria.setEnabled(True) @@ -389,35 +389,14 @@ def clickEventGeoRasterProp(): self.HSutils.Basin_GeoGetOCG() ListaVar.extend(['OCG_coef']) if self.checkBoxKubota.isChecked(): - try: - self.HSutils.Basin_GeoGetKubota() - ListaVar.extend(['kubota_coef']) - self.iface.messageBar().pushInfo(u'HidroSIG:', - u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.') - except: - #Pone un mensaje de error por si h1_max no ha sido calculado - self.iface.messageBar().pushMessage (u'Hydro-SIG:', - u'No ha sido cargado h1_max, Kubota no puede calcularse', - level=QgsMessageBar.WARNING, duration=5) + self.HSutils.Basin_GeoGetKubota() + ListaVar.extend(['kubota_coef']) if self.checkBoxRunoff.isChecked(): - try: - #Obtiene los parametros e1 y Epsilon de las cajitas - E1 = self.RunoffE1.value() - Epsi = self.RunoffEpsi.value() - self.HSutils.Basin_GeoGetRunoff(e1=E1,Epsilon=Epsi) - ListaVar.extend(['Runoff_coef']) - self.iface.messageBar().pushInfo(u'HidroSIG:', - u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.') - except: - #Pone un mensaje de error por si Manning no ha sido calculado - self.iface.messageBar().pushMessage (u'Hydro-SIG:', - u'No ha sido cargado Manning, Runoff no puede calcularse', - level=QgsMessageBar.WARNING, duration=5) - - #mensaje de caso de exito (para runoff y kubota se muestran por separado) - if self.checkBoxRunoff.isChecked()==False and self.checkBoxKubota.isChecked()==False: - self.iface.messageBar().pushInfo(u'HidroSIG:',u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.') + self.HSutils.Basin_GeoGetRunoff() + ListaVar.extend(['Runoff_coef']) + #mensaje de caso de exito + self.iface.messageBar().pushInfo(u'HidroSIG:',u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.') #Actualiza la tabla de variables temporales for k in ListaVar: self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[k],k, self.Tabla_Prop_WMF) @@ -998,7 +977,6 @@ def handleClickEventButton_Eliminar_Desde_NC (): self.Tabla_Prop_NC.removeRow (selectedItems) self.TabNC.DelEntry(ItemName) self.HSutils.DicBasinNc.pop(ItemName) - self.HSutils.Nc2Save.remove(ItemName) #self.HSutils.Nc2Erase.append(ItemName) #Mensaje de exito self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'La variable '+ItemName + ' ha sido borrada') @@ -1065,7 +1043,6 @@ def handleClickEventButton_NC2WMF(): self.Tabla_Prop_NC.removeRow (selectedItems) self.TabNC.DelEntry(VarName) self.HSutils.DicBasinNc.pop(VarName) - self.HSutils.Nc2Save.remove(VarName) #Mensaje de exito self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'La variable '+VarName+' ha sido movida de NC a WMF') else: diff --git a/qgisplugin/resources.py b/qgisplugin/resources.py index 15f6aa7..33b6a0d 100644 --- a/qgisplugin/resources.py +++ b/qgisplugin/resources.py @@ -76,146 +76,6 @@ \x81\xa3\x32\xb1\xfb\xf4\x0c\x30\xb8\xb1\x82\x9b\xb0\x09\x60\x30\ \xb1\xfb\xf4\xcc\xbf\xa0\xe9\x6e\xae\x5a\xdf\x4b\x81\x00\x00\x00\ \x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x08\x91\ -\x00\ -\x00\x80\xdc\x78\x9c\xed\x5c\x6b\x4c\x54\x47\x14\x1e\x14\x15\x7c\ -\xa2\x54\x40\x41\xc4\x22\x6a\x00\x5f\xf8\x8a\x68\xe5\x29\x58\x35\ -\x8a\xaf\x60\xe3\x13\x51\xf1\x15\x15\x5f\x05\x93\xa6\x0b\x34\x96\ -\xfa\xa8\x5a\x29\x50\xa0\x34\x02\x41\xa5\x58\xaa\x51\x34\x5a\x4d\ -\xed\x3b\x6d\x7f\x37\xa9\x55\xab\xa8\x8d\x49\x5b\x6d\x6b\x53\x69\ -\xda\x3a\x3d\xdf\xdc\x7b\xb7\xeb\xba\x7b\x59\xca\x92\x82\x3d\x5f\ -\xf2\x65\x76\xf7\xde\x39\x67\xbe\xb9\x67\xce\x9c\xb9\x24\x08\xe1\ -\x21\x3c\x45\x6c\xac\xa0\x36\x44\x0c\xa3\x36\x49\x08\x11\x12\xa2\ -\x7f\xf7\x11\x62\x23\xfd\x16\x10\xa0\x7f\xf7\x16\xa2\x30\x45\x08\ -\x1f\x1f\xfd\xbb\xa7\x10\x17\x9f\x13\x62\x18\xf5\xa1\xdb\x84\x45\ -\x68\xbf\x33\x18\x0c\x86\x1b\x21\xdd\xc0\xf6\x0c\xd6\xcf\xfa\x59\ -\x3f\xeb\x67\xfd\xac\x9f\xf5\xb3\x7e\xd6\xcf\xfa\x59\x3f\xeb\x67\ -\xfd\xac\xbf\x2d\xf3\x49\xd2\xc2\xfa\xdb\x80\xfe\x95\x2b\x57\xba\ -\x4c\xfb\xbe\x85\x85\x85\x2e\xf3\xb1\xbe\xc5\x05\x17\x5c\x21\xeb\ -\x67\xfd\xac\x9f\xf5\xb3\x7e\xd6\xcf\xfa\x59\x3f\xeb\x67\xfd\xac\ -\x9f\xf5\xbb\x4b\x7f\x3b\x23\xeb\x67\xfd\xee\x80\xd5\x66\x8b\xd6\ -\x70\x0b\xfa\xb2\x7e\xd6\xcf\xfa\x59\x3f\xeb\x67\xfd\xac\x9f\xf5\ -\xb3\x7e\xd6\xdf\xde\xf4\xff\x07\x74\xbb\xfe\x76\x46\xd6\xcf\xfa\ -\xff\x4b\x58\xc7\xd2\x9c\xf7\x66\x0e\xde\x9d\xb5\x57\xb0\x7e\xd6\ -\xcf\xfa\x59\x3f\xeb\x67\xfd\xff\x6b\xfd\x2d\x64\x7b\x05\xeb\x6f\ -\x43\xfa\xf1\x7f\x02\x42\x84\xf6\xbf\x02\xda\xe9\xff\x09\xf0\x20\ -\xf6\x26\xf6\x31\xa1\x77\x2b\xfa\xf7\x21\x5e\x23\xde\x35\x61\x56\ -\x2b\xfa\x87\xf6\xfb\xc2\x3c\x56\xf2\x5a\xd9\xff\x8f\x4d\xf8\xb7\ -\xb0\xff\x27\xd6\x7f\x37\x17\xfc\x6f\x77\x83\x1f\xac\x61\x47\x6b\ -\xfb\x69\xa1\xad\x31\x33\xff\xef\x0b\x6d\x0e\x9c\x31\x87\x98\x6b\ -\x47\xfc\x96\x25\xfe\xc9\x1d\xcf\x0b\xc7\x6b\xfb\x1e\xf1\xa1\xa7\ -\xa7\xa7\xf4\xf2\xf2\x92\x5d\xba\x74\x79\x84\xc6\x18\xba\x76\xed\ -\x2a\xbb\x75\xeb\xf6\x08\x3b\x75\xea\xa4\xae\xa9\xbe\xde\x5e\xaa\ -\xbf\x22\x7d\xc6\x6f\x7a\x5f\x5f\xdd\x7f\xae\x99\xc6\x91\x23\x47\ -\xca\x55\xab\x56\xc9\x25\x4b\x96\x28\x2e\x5f\xbe\x5c\xa6\xa6\xa6\ -\xca\x8e\x1d\x3b\xaa\x71\xe4\xe6\xe6\xca\x03\x07\x0e\xc8\xbd\x7b\ -\xf7\x2a\x16\x15\x15\xc9\xe4\xe4\x64\xd5\x37\x7a\x52\xf4\xf5\xa2\ -\xe2\x82\x0b\xaf\xec\xcd\xbf\x04\xe2\xf3\xc4\x89\x13\xbf\xa3\x6b\ -\xbf\xea\x73\x0c\xbc\x68\xe6\x7f\xcc\x98\x31\x72\xd3\xa6\x4d\x32\ -\x23\x23\x43\x71\xdd\xba\x75\x72\xd9\xb2\x65\x56\xff\xfb\xf7\xef\ -\x97\xe5\xe5\xe5\xb2\xa4\xa4\x44\xb1\xba\xba\x5a\xce\x9a\x35\x4b\ -\xf5\x8d\x89\x89\xb9\x5a\x5b\x57\x53\x5f\x5a\x5e\x72\x1e\xc4\xe7\ -\xd8\xb8\x67\x6e\x36\xc7\x7f\x54\x54\x94\xdc\xb0\x61\x83\xb5\x56\ -\xc4\x18\x30\x0f\x86\xff\x3d\x7b\xf6\x28\xbf\xc6\x7b\xd8\x8a\x8a\ -\x0a\x39\x73\xe6\x4c\xcd\x7f\x6c\xcc\xb5\xea\x63\x55\x67\x0b\x48\ -\x37\x88\xcf\x53\xa6\x4c\xb9\xc5\xfe\x5d\xf7\x3f\x7e\xfc\x78\xb9\ -\x7d\xfb\x76\x35\x06\x70\xf3\xe6\xcd\x2a\x1e\xe1\x1f\x31\x8d\x78\ -\x3b\x72\xe4\x88\xf2\x0b\xd6\xd5\xd5\xc9\xb9\x73\xe7\xaa\xbe\x89\ -\xc9\x89\xdf\x9c\xbb\x70\xe6\x24\xfc\x82\xf8\x9c\x90\x18\xd7\x60\ -\xe7\xdf\x34\xfe\xfd\xfd\xfd\xe5\xe8\xd1\xa3\xe5\x88\x11\x23\x14\ -\xb1\x1e\xc2\xc3\xc3\xa5\x87\x87\x87\x1a\x43\x5c\x5c\x9c\x9c\x36\ -\x6d\x9a\x4c\x4a\x4a\x52\x84\xf6\xc1\x83\x07\xab\xbe\x81\x41\x81\ -\xf7\x92\x92\x12\xaf\x60\x1e\x40\x7c\x0e\x0e\x0e\xfa\x85\xae\xfd\ -\x6c\xe3\x7f\x87\xd0\xf2\x9c\x3d\x91\x03\x1e\xc2\x4f\x87\x0e\x1d\ -\x1e\xa3\xd9\x98\x5d\xe0\x5d\x1b\xff\x5e\x42\xcb\xf5\xf6\x1c\x84\ -\xfb\xa6\x4e\x9d\xaa\xe6\xd8\x58\xdf\x58\xeb\x79\x79\x79\xea\xd9\ -\x77\xee\xdc\xd9\x74\xfd\xbb\xe8\xdf\x19\x54\xfe\xc7\x7c\x62\x4d\ -\x1b\xeb\x1b\x6b\x1d\xfe\x0c\xff\x66\xeb\xbf\x85\xfe\xd5\xfe\x37\ -\x7d\xfa\x74\x15\x57\x46\x7c\xc3\x07\x74\x1a\xfe\xcd\xe2\xff\x49\ -\xf0\xdf\xd4\xfc\x9b\xad\x3f\x77\xf8\x37\xe2\x0f\x3a\x41\x3c\x6f\ -\xc4\x1c\xd6\x3e\xd6\x1f\xae\x63\x8c\x98\x27\x30\x25\x25\x45\x0e\ -\x19\x32\xc4\x1d\xfe\x71\x5d\xed\xa5\xd8\x53\xb1\xcf\x1a\xf4\xf6\ -\xf6\x56\xeb\xbf\x09\x1f\x4d\xd1\xf7\x31\x8f\x8f\x02\xeb\x12\xb9\ -\xe1\x45\x07\x7c\x99\xf8\x5b\xbf\x7e\xfd\x54\x7e\x44\x8e\x36\x88\ -\xef\xf8\x1d\xd7\x89\xf9\x4e\xfa\xc3\x6e\x4b\xcf\x2e\x3f\xd8\xe7\ -\x66\x10\xdf\xf1\xbb\xd0\x72\x58\x6b\x41\xc5\x86\xfd\xde\x04\xe2\ -\x3b\x7e\x17\xae\x3d\xe3\x16\xf9\x6f\x42\x7f\x6b\xfb\xbf\xdf\xc4\ -\xf3\xb7\xdd\xe3\xdc\x0d\x9c\x4d\xaf\x08\xc7\xfb\x96\xc1\xab\xfa\ -\x38\x4d\x81\xf7\x04\x01\xc4\x51\xa2\x4d\xbe\x27\x58\x2c\xb4\x35\ -\x94\x63\xc3\x5d\xc4\x59\x42\x7b\x3f\xd0\x52\x7c\x28\x1c\xe7\x86\ -\x4a\x37\xd9\x3f\xe3\xc4\x7e\x89\x9b\xec\xd7\x3b\xb1\xff\x86\x9b\ -\xec\x9f\x76\x62\xff\x75\x37\xd8\x06\x4e\x38\xb1\xff\x26\xd1\x9f\ -\xe8\xa7\xb7\x06\x03\xec\xd8\x5f\x68\x75\x0a\x80\x98\x40\x6c\x20\ -\x46\x2c\x3a\xbf\x71\x62\xff\x0e\xf1\x53\xe2\xc7\xc4\x4f\x6c\xf8\ -\x19\xf1\x0b\x9d\x9f\xeb\xed\x3a\xdd\x7e\x85\x23\x5b\xc3\x87\x0f\ -\x97\xb3\x67\xcf\x56\x35\x28\xea\x9e\x41\x83\x06\xa9\x33\xde\x8a\ -\x15\x2b\xe4\x96\x2d\x5b\x64\x66\x66\xa6\x5c\xbb\x76\xad\xf4\xf3\ -\xf3\x93\x81\x81\x81\x0f\xd2\xd3\xd3\x2e\xa7\xa5\x2f\xbd\x8c\x16\ -\xf7\x92\x8d\x57\x75\xfb\x6f\x38\xb2\x1f\x1f\x1f\x2f\xb7\x6e\xdd\ -\x2a\xd7\xaf\x5f\xaf\x5a\xd4\xbf\x46\xdd\x85\xba\x00\x2c\x2d\x2d\ -\x95\x21\x21\x21\x54\x1f\x0f\x6f\xa8\x3b\x79\xfc\x74\x4d\xed\xd1\ -\xfa\xda\x13\xb5\xf5\x51\x51\x23\x1f\x08\x6d\xaf\x02\x8a\x1d\xd9\ -\xa7\xf3\x80\x35\x87\xa3\x8d\x8c\x8c\x54\xf6\x77\xed\xda\x25\xcb\ -\xca\xca\x14\x0f\x1e\x3c\x28\x83\x83\x83\x65\x44\x44\xc4\xad\xb7\ -\x2a\xcb\xcf\x15\xd1\x59\xae\xbc\xa2\xf4\x3c\x8d\xa5\xb1\x29\xfb\ -\xa8\xcf\x31\x07\x6b\xd6\xac\x51\x2d\x6a\x78\xd8\x47\x0d\x55\x59\ -\x59\xa9\x88\xfa\x62\xe0\xc0\x81\x74\x2d\xe2\xe6\xb1\xb7\x8f\x9c\ -\xa9\x38\x5a\x75\xf6\x68\x4d\xf5\x59\xb2\x6f\x3b\xfe\x12\x47\xf6\ -\xa3\xa3\xa3\xe5\xea\xd5\xab\xe5\xd2\xa5\x4b\x55\x8b\xb3\x01\xec\ -\x5b\x2c\x16\x59\x50\x50\xa0\xb8\x7b\xf7\x6e\x39\x60\xc0\x00\x39\ -\x2c\x7c\xd8\xed\xa2\xd2\xa2\xf7\x5e\x2b\x38\x70\xb1\xb0\xb8\xe0\ -\x22\xcd\x57\xa3\x1e\x33\x4e\xed\xa3\xce\xe9\xd5\xab\x97\xec\xd9\ -\xb3\xa7\x6a\x61\x1b\xb5\x47\xdf\xbe\x7d\x55\x9e\x07\x71\x46\xd1\ -\xdf\x13\xfc\xde\xbf\x7f\xff\x9f\x0c\xa2\x56\x11\xda\xf9\x06\x08\ -\x27\x4e\x27\x26\x13\xa7\xea\xfc\x9c\xce\xc8\x72\xe3\xc6\x8d\x6a\ -\xec\x68\x47\x8d\x1a\xa5\xce\x17\x0b\x17\x2e\xb4\x9e\xb9\x71\xe6\ -\x87\x0f\x27\xb1\x9c\x23\x9c\xe3\x44\x7a\x7a\xba\x3c\x7e\xfc\xb8\ -\x3c\x7c\xf8\xb0\x6a\x67\xcc\x98\xa1\xea\x36\xc4\x0f\xea\x46\x10\ -\xf1\x13\x16\x16\xf6\x6f\xec\xd7\x2f\x5e\xbc\x58\xd5\x9d\x78\x86\ -\xf0\x81\x33\x18\xec\xe7\xe7\xe7\xab\x5a\x15\x3c\x74\xe8\x90\x0c\ -\x0d\x0d\xfd\x37\xf6\x4f\xdb\x8e\xbf\xb6\xb6\xd6\x3a\xfe\x7d\xfb\ -\xf6\xc9\xaa\xaa\x2a\x15\x3f\xc5\xc5\xc5\xd6\x33\x9f\x03\x5a\x4c\ -\xec\x7f\x80\xf5\xb5\x6d\xdb\x36\xeb\xfa\x1a\x3b\x76\xac\xea\x87\ -\xbd\x7c\xd2\xa4\x49\x8a\x13\x26\x4c\x90\x3d\x7a\xf4\x70\x66\x7f\ -\xb7\x89\xfd\xd7\x84\x96\x53\x3e\xd2\x79\x89\x78\x03\x71\xd1\xa7\ -\x4f\x1f\xd9\xbb\x77\x6f\xd5\xfa\xf8\xf8\x18\xef\x85\xbe\xd2\xef\ -\xc1\xbd\x1f\xeb\x7d\xd7\x9a\xd8\xef\x29\xb4\x3c\xe8\xa7\x13\x35\ -\x6d\xee\xd0\xa1\x43\xd5\x19\x3d\x2d\x2d\x4d\xad\x6b\xbc\x2f\x40\ -\xfe\xa1\x6b\x73\x88\x4f\xd9\xdc\x8f\xbe\x5d\x4d\xec\x3b\x42\x36\ -\x72\x1e\xea\x2c\xbc\x0b\xc0\xdc\x21\x6f\x50\xbc\xc3\x7e\x7c\x33\ -\x6d\x39\x42\x1e\xf2\xe2\x82\x05\x0b\xd4\x39\x66\xfe\xfc\xf9\x2a\ -\xbf\xfa\xfa\xfa\xc2\xfe\x4c\x37\xd8\xcf\xa4\xb9\xfe\x9e\x9e\xc1\ -\x4d\x3a\x47\x34\x50\xdb\x40\x67\xa9\x5b\xb4\xe6\xf0\x5e\xc4\xe9\ -\xf8\x51\x27\xa1\xe8\x0a\x11\xcd\xaa\x93\x50\x7f\x0d\x21\x86\xea\ -\x6d\xbf\x66\x8e\x75\x2b\xf1\x86\xd0\xfe\x0e\x81\xb6\x9c\xe8\xd9\ -\x8c\xfe\x2f\x89\x47\x63\xf5\x6c\x33\xfb\x67\xdb\xf5\x7f\xdb\x85\ -\x3e\xd0\x18\x46\x1c\x28\xb4\xbd\xcd\xb6\x3f\xf6\x58\xec\xd3\xcf\ -\x0a\xed\x59\xe2\xf3\x5c\xe2\x02\xa1\xfd\x3b\x6c\xec\xe5\xd0\x78\ -\x9d\x78\x99\xf2\xec\x5d\x9c\x25\x91\xe3\xb1\x2f\xd1\x39\xf0\xaf\ -\x84\x84\x84\xdf\x29\x37\x36\x52\x9d\xdd\x48\xf9\xf8\x7e\x7c\x7c\ -\xec\xb7\x31\xb1\x53\xee\x50\x7c\x60\xaf\x1f\x2a\x6c\x6a\x2e\xe4\ -\x69\xec\xc9\xd9\xd9\xd9\x72\xd1\xa2\x45\x2a\x87\xe2\x0c\x7b\xea\ -\xd4\x29\xb5\x17\x91\xed\xbb\x55\xd5\x15\xe7\xcb\xde\x2a\xfb\x2c\ -\x32\x32\x02\xfd\xf1\x98\xdf\xb5\xed\x8f\xf3\xec\xce\x9d\x3b\x25\ -\xf2\x5c\x40\x40\x80\xca\x3b\xf5\xf5\xf5\x46\xff\x3b\xc7\xde\x39\ -\x76\xaa\xb2\xba\xf2\x12\xad\x89\xaf\x74\xff\xe7\x6d\xfb\x63\xad\ -\xe0\x8c\x8c\xf7\xa8\xd8\x43\x10\xd7\xc8\xf3\x89\x89\x89\x18\xcf\ -\xbd\x8c\x8c\x55\x5f\x52\xad\xf0\x35\xed\x7f\x5f\x0b\x2d\x46\x9e\ -\x13\xda\x9e\x91\x4d\xfd\x2f\x8e\x1b\x37\x4e\xce\x99\x33\x07\xef\ -\x52\x55\x0e\x9a\x3c\x79\xb2\x5a\x0f\xc8\x53\x14\xb3\x0f\x75\xc2\ -\x17\x62\x24\xd4\xf6\x41\x50\x9c\x67\x61\x7d\x42\x2f\x74\x63\x0f\ -\x44\x5e\xc6\xf7\xac\xac\x2c\xdb\x77\xd1\xa0\xa3\xfe\x96\x1d\x3b\ -\x76\x28\xbd\xd8\xaf\x83\x82\x82\x64\x4e\x4e\x8e\xac\xa9\xa9\x51\ -\xfa\xed\xfa\xdf\xb0\xef\x4f\xe3\xb2\x50\xee\xfc\x23\x35\x35\xb5\ -\x91\x9e\x5b\x63\xf7\xee\xdd\x1f\x62\x9f\xc1\x5c\x60\x8d\xd3\x98\ -\xff\x14\xda\x39\xf9\x0f\xa1\xd5\x6a\x61\x76\xb1\x84\xf9\x48\xd1\ -\x63\x63\x19\xcd\xff\x6d\xec\x2f\x78\xcf\x80\xfc\x4c\xf6\x51\x93\ -\x25\xe8\x71\x84\xd6\x2c\x97\xf9\xd3\xf3\xba\x8e\x71\xe3\x79\xce\ -\x9b\x37\x0f\x7b\xf9\x0b\x26\xf7\xdb\x63\x00\xcd\xff\x07\xb4\xcf\ -\x34\x90\x9d\x2b\x18\x0b\xf9\xcf\x6c\x46\x7f\x06\x83\xc1\x60\x30\ -\x18\x0c\x06\x83\xc1\x60\x30\x18\x0c\x06\x83\xc1\x60\x30\x18\x0c\ -\x06\x83\xc1\x60\x30\x18\x0c\x06\xa3\x8d\xe2\x6f\xb6\xa9\x79\x63\ -\ \x00\x00\x02\x6f\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -1252,104 +1112,6 @@ \x02\x40\x8b\x80\x00\xd0\x22\x20\x00\xb4\x08\x08\x00\x2d\x02\x02\ \x40\xc3\xff\xfe\xef\xff\x01\xe5\xf9\xa3\x47\x4e\x17\x0b\xed\x00\ \x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x05\xfd\ -\x00\ -\x00\x80\xdc\x78\x9c\xed\x5c\x57\x88\x5d\x55\x14\x5d\x63\x12\x63\ -\x4c\x9b\x18\x35\x63\xe5\x59\x89\x05\x89\x82\x88\x05\x1c\x5b\x34\ -\xa4\x68\x3e\xfc\x10\x25\x7e\xf8\x21\xa2\xc9\x57\x2c\x58\x62\xd4\ -\x58\xd0\x88\x10\xa3\x12\x30\x22\x16\x44\x90\xd8\xb1\x44\x62\x41\ -\x04\x11\xb1\x80\x20\xa2\xa2\x62\x2f\xb1\xc4\xd8\x35\xee\xc5\xde\ -\x87\xb9\x79\x79\x33\xb7\x9d\x37\xef\xde\xf7\xf6\x82\xc5\x9b\x7b\ -\xef\xb9\xbb\x9d\x73\xf6\x3e\xfb\x7e\x0c\xd0\x87\xb1\x18\x1c\x84\ -\xfc\x36\x30\x53\x7e\x67\x03\x68\x34\xec\xba\x1f\x58\x22\xf7\x06\ -\x06\xec\x7a\x02\x70\xe7\x19\x40\x7f\xbf\x5d\x8f\x05\x36\x9c\x05\ -\xcc\x94\x77\x64\x18\x96\x43\xef\x3b\x1c\x0e\x87\xc3\xe1\x70\x38\ -\x1c\x19\xb1\x25\xc1\x5e\xc4\x16\xf4\x76\x0c\x7a\xdd\x7f\xa2\xd7\ -\x63\xe0\xfe\x7b\x0c\xdc\xff\xde\xf6\x9f\x70\xff\x7b\x3b\x06\xb1\ -\xfd\x6f\x95\x57\x87\x63\x15\x90\xd7\xa6\x3c\xfe\xd5\xc1\x7f\x22\ -\xa6\x4f\xee\x7f\x75\xfd\x1c\x0e\x31\x7d\xaa\x63\x0c\x62\xdb\xdb\ -\x0d\x31\x88\x2d\xaf\xea\x31\x68\x87\xad\x1e\x83\xfa\xfb\xdf\x8e\ -\x18\x54\x19\x75\x5b\xb3\xb1\x51\xe7\x3a\x5e\x16\xdd\x70\x96\x29\ -\x8a\x6e\x3b\xd3\xe5\x41\x9a\x7f\xdd\x1e\x83\x2c\x7e\x75\xf3\x5a\ -\xc8\xea\x4b\xaf\xfb\xdf\x3c\xb6\xdb\xe2\x90\x15\xed\xcc\x8d\x75\ -\x88\x69\xcc\xfa\x50\xc7\x3a\x53\xb6\x46\xd6\xbd\xce\xb6\xb2\x2f\ -\xcd\xfe\xbc\xe7\x8b\xaa\xfa\x5f\xe4\x9c\x50\x47\x3f\x5b\x21\xab\ -\xdd\xdd\xe6\x37\x11\x7b\x8f\xd7\x09\x65\x7c\xe8\x75\xff\x63\xbc\ -\xdf\x49\xc4\x5a\xc3\x75\x8c\x41\xcc\x3d\x5c\xc7\x5c\xd0\xca\xce\ -\xd8\x7b\xa0\xaa\xfe\x0f\x67\x67\x3b\xfc\xaf\x5a\x0c\x46\xb2\xaf\ -\x88\xed\x59\xe2\x58\xa5\x18\xa4\xd9\xd5\x2e\xff\xab\x12\x83\xbc\ -\xfe\xa7\xd9\x1d\x73\x2d\xb5\x1b\x59\xed\x29\xea\x7f\x19\x39\xa3\ -\x81\x58\x7e\xe5\x19\x57\x55\xff\x63\xcb\xad\x03\xaa\x34\x17\x9d\ -\x80\xfb\xdf\xdb\xfe\x3b\x1c\x8e\x1a\x83\xff\x27\xa0\x01\xfd\x5f\ -\x01\xfe\x7f\x02\x1c\x19\xd1\x27\x9c\xde\x41\xfd\xd3\x84\x9b\x84\ -\x4f\x77\x48\xff\x04\xe1\x2b\xd0\xba\x7f\x62\x87\x6c\x58\x62\xfa\ -\x5f\x36\x7b\x46\x1b\x33\x84\x3f\x08\xff\x13\xee\xd8\x01\xfd\xc4\ -\x4a\x68\x0c\x66\x67\x18\xbb\x53\x13\xb9\x86\xfa\x4a\xea\x5f\x0a\ -\xf5\x7f\x55\x93\xec\x39\xc2\x15\xc2\x1b\x8d\xeb\x85\x1b\x85\x3f\ -\x62\xe8\xbc\xf8\x8b\x8d\x2d\x83\xdd\x84\x3f\x0b\x7f\x17\xfe\x89\ -\x6d\xfb\xd1\x66\xd2\x56\xc6\xec\x1a\xe1\x95\x28\xbf\x6e\x26\x0b\ -\xbf\x36\xd9\x2f\x98\xdc\xeb\x85\xd7\x0a\x4f\x83\xc6\x98\x3c\x5d\ -\xf8\x87\x8d\xbb\xa7\xa4\xce\x24\x38\x7f\x57\x9b\xdc\x75\x29\x63\ -\xe7\x25\x6c\x78\x16\xf1\xd6\xec\xce\xc2\xcf\x4d\xee\x93\xc2\xf1\ -\x29\x36\x7c\x23\xfc\x1e\xe5\xe7\x3e\x89\xb0\x0f\x82\x0d\xdb\x8f\ -\x30\x76\x2a\xe2\xac\x7d\x98\x8c\x05\xc2\x9f\x4c\xf7\x46\xfb\xe5\ -\x7a\x3f\x35\x82\xfc\x34\xf4\x0b\xff\x32\xce\x87\xfa\xf5\xb8\xd9\ -\xf0\xb7\x70\xd9\x28\xe8\xa7\xef\x2b\x12\xf7\x18\xfb\x47\x31\x34\ -\x1f\x7c\x36\x23\x83\x2c\xae\x87\xbc\xfb\x91\xf1\x9f\x86\x6d\xe7\ -\x7b\x12\x34\x37\x07\x1b\xbe\x85\xee\xc1\x24\xb8\x0e\x42\x9e\xda\ -\x20\xdc\x2c\xbc\x22\xa7\xfe\xe1\x40\xfd\xbf\x41\xf7\xd9\x23\x66\ -\xc3\xbf\xd0\x9c\x70\xbc\xf0\x26\xb3\x29\xd8\xc7\xb9\xfa\x55\x78\ -\x79\x04\xdd\xdc\x7f\x61\x0d\x04\x79\xcb\x4c\x7f\xc8\x81\x41\xe7\ -\x73\xd8\x3a\x4f\xed\x10\x41\x7f\x98\x7b\xfa\x3f\x27\x71\xff\x14\ -\x68\x8e\x0c\x3e\xdf\x16\x41\x57\x33\x16\x26\xe4\x7f\xd7\xe2\xf9\ -\x38\xe1\x33\xf6\x9c\x39\x68\x5e\x44\xdd\x53\xa0\x73\xf8\x8f\xf0\ -\x4d\x68\x4d\x1a\x6c\x31\xee\xa2\x84\x8d\xac\x81\x53\x23\xe8\xe6\ -\xfa\x7f\xcc\x64\xae\x11\x2e\xb6\xbf\x5f\x6a\x1a\xc7\xfd\xf5\x3c\ -\xb4\x66\xbe\x63\x63\x9e\x80\xce\x7d\x19\xec\x6e\xb2\x28\x97\xeb\ -\x8f\xeb\x7f\x93\xdd\x5b\x90\x18\x37\xdd\xee\x7d\x02\xcd\x57\x9b\ -\xed\xfa\xaa\x92\xfa\x2f\x83\xae\xeb\xe5\x89\x7b\x94\xcf\x7c\x7c\ -\x5d\xe2\x1e\xf3\x15\xf7\xc1\x4a\xbb\x9e\x6b\x63\xca\xea\xbf\x05\ -\xea\x47\x73\x9e\x63\x5c\x93\x39\x8d\xf9\x6a\xb0\x69\x5c\xf3\x98\ -\x22\xe0\x59\x86\xf9\x6e\x4a\x49\x39\x45\x41\xfb\x63\xd5\xd4\x4a\ -\x82\xdf\x09\x06\x84\xb3\xe0\xdf\x09\x22\x81\x39\x82\x7d\x4b\xcc\ -\x73\x60\x12\xec\x0d\x98\xe3\x6f\x68\x93\xfc\x31\xc2\x7b\xa1\x75\ -\xe6\xc0\x36\xe9\x18\x84\xf6\x35\x67\xb6\x49\x3e\xcf\xee\x6f\x0b\ -\xef\xc2\xd0\xde\x65\x2e\x67\x4f\x7f\xb2\xf0\x6c\x68\x4e\xbd\x59\ -\x78\x3b\xb4\x76\xe5\xc1\x58\x93\xcd\xba\xf0\x22\xb4\x1e\xbd\x2b\ -\xfc\x54\xf8\x81\xdd\x67\xde\xfc\x52\xf8\x00\x8a\x9d\x57\x43\x3d\ -\xe5\xb9\x9f\x75\x6f\xa9\xd9\xbf\x27\x74\x7d\x51\x17\x7b\x34\x9e\ -\xc7\xc7\x14\x90\xcf\x75\xc4\x5a\xf9\xaa\x70\xaf\x16\xcf\x8f\x84\ -\xfa\x42\x1f\x76\x2d\x20\x9f\x58\x0e\xf5\xe1\x3d\xe1\x41\x2d\x9e\ -\x33\xfd\xf0\xac\x52\xa4\x67\x3b\x5a\xf8\x3e\xd4\x87\x8f\x85\x1f\ -\x0a\xcf\x43\xb1\x58\xb4\xc2\x1d\xd0\x18\xef\x22\xdc\x4f\xf8\x16\ -\xd4\x17\xf6\xc1\x13\x23\xc8\x3f\x58\x78\x68\xe2\x9a\x3a\xc2\xd9\ -\xf9\x35\xe1\x31\x89\x67\x0d\xe1\x22\xe1\x7d\xd0\xb3\xed\xac\x02\ -\xfa\x0e\x81\xc6\x69\x8d\xfd\x72\xed\x5c\x20\x5c\x0d\xad\xb1\xec\ -\x75\xdf\x80\x7e\x7b\x3b\x2c\xa7\xec\x10\x9f\xcf\x84\x7b\x0b\x0f\ -\x10\x3e\x85\xad\x7b\x57\xce\x57\x91\x3a\xca\x77\x1e\x34\x39\x3c\ -\xe3\x6e\x67\xf7\x59\x9b\x2f\x85\x9e\x7b\xd8\x17\x4c\x2a\x28\x9b\ -\x71\x65\xcf\xc0\xb5\xc4\x9c\xb1\x6f\xe2\xf9\xe1\xc2\xaf\x4c\x37\ -\xd7\xc3\xb8\x9c\xf2\x99\x87\x38\xa7\xec\x95\x8e\x35\x39\xab\x12\ -\x3e\xb0\x2f\x63\x9f\xb9\xde\x9e\x2d\x46\xbe\x18\x31\x8f\x31\xd7\ -\x9c\x60\xd7\x94\xcd\x9e\x2f\x7c\xc3\xbd\x15\x1a\x33\xce\x09\xe7\ -\x63\x6d\x42\x77\x16\x70\xad\x33\x26\x61\x4f\x31\xef\x0d\xd8\x2f\ -\xb1\x0f\x86\xe2\x35\x11\xf9\xbf\x1d\x1f\x27\x3c\x37\xe7\x3b\x1d\ -\x01\x13\x15\x0f\xd9\x0d\xd4\xe2\x9c\xc4\xdc\xce\x5c\x58\x64\x4f\ -\x10\x5c\xb7\xcc\x05\xe7\x94\xb0\x81\x35\xef\xee\xc4\x35\xfb\x41\ -\xf6\x07\xfb\x0b\x8f\x10\xee\x91\xf2\x3e\xf3\x1f\x73\x3b\xcf\x39\ -\xec\xa9\x59\x47\xf9\xdd\xe1\x0b\x68\x4f\x38\x3f\xe5\x7d\x9e\xdb\ -\x5f\x87\xe6\x06\xf6\xcf\x47\x41\xf7\x09\xd7\x33\xf3\x51\x96\xf3\ -\xd9\xc5\xd0\x3c\x79\x52\xe2\x1e\x73\xdd\x25\x19\xde\x1f\x30\xdd\ -\xfc\x7e\xc9\xbe\x99\x7b\x3d\x4f\x6d\x62\x4d\x5e\x64\x7f\x53\x3f\ -\xbf\x3b\xf0\x1b\x44\x38\x93\x31\x37\xb1\x3f\xba\x10\xe9\x79\x89\ -\x67\x04\xc6\xee\x7e\x68\xbd\x7f\x08\x7a\x66\xe1\xfc\x9c\x9f\xf2\ -\x3e\x73\x39\xeb\x43\xe8\x2d\x43\xce\x59\x9d\xc1\x87\xf1\xa6\xf3\ -\x23\x68\x0e\x0c\x75\x9e\x36\xb0\x8f\x5e\x98\xf2\xfe\x5c\x1b\xcb\ -\x3a\xf9\x30\x34\x5f\x34\xa0\xf5\x80\xb9\x6d\x2d\x46\xfe\x2e\xcb\ -\xf8\x85\x6f\x5f\xec\x21\x27\x9b\x0d\x5c\x7b\xcc\xb3\xac\xed\x23\ -\xcd\x09\xc7\xc7\xf8\x8e\xe1\x70\x38\x1c\x0e\x87\xc3\xe1\x70\x38\ -\x1c\x0e\x87\xc3\xe1\x70\x38\x1c\x0e\x87\xc3\xe1\x70\x38\x1c\x0e\ -\x87\xc3\xe1\x70\x54\x18\xff\x03\x57\x3a\x56\xa8\ \x00\x00\x52\xd0\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -3406,1845 +3168,6 @@ \xef\x7d\x9f\x7d\xe6\xa9\x76\x0f\xd4\xa9\x58\x3c\x14\x92\x24\x49\ \x92\x24\x49\x92\x64\x39\xff\x0f\x1b\xcb\x93\xc1\xa8\xfa\xf9\xac\ \x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x6b\x97\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x06\x40\x00\x00\x06\x40\x08\x03\x00\x00\x00\x16\xd2\x7e\x95\ -\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ -\x04\x67\x41\x4d\x41\x00\x00\xb1\x8f\x0b\xfc\x61\x05\x00\x00\x03\ -\x00\x50\x4c\x54\x45\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x33\x00\x00\x66\x00\x00\x99\x00\x00\xcc\x00\x00\xff\x00\ -\x33\x00\x00\x33\x33\x00\x33\x66\x00\x33\x99\x00\x33\xcc\x00\x33\ -\xff\x00\x66\x00\x00\x66\x33\x00\x66\x66\x00\x66\x99\x00\x66\xcc\ -\x00\x66\xff\x00\x99\x00\x00\x99\x33\x00\x99\x66\x00\x99\x99\x00\ -\x99\xcc\x00\x99\xff\x00\xcc\x00\x00\xcc\x33\x00\xcc\x66\x00\xcc\ -\x99\x00\xcc\xcc\x00\xcc\xff\x00\xff\x00\x00\xff\x33\x00\xff\x66\ -\x00\xff\x99\x00\xff\xcc\x00\xff\xff\x33\x00\x00\x33\x00\x33\x33\ -\x00\x66\x33\x00\x99\x33\x00\xcc\x33\x00\xff\x33\x33\x00\x33\x33\ -\x33\x33\x33\x66\x33\x33\x99\x33\x33\xcc\x33\x33\xff\x33\x66\x00\ -\x33\x66\x33\x33\x66\x66\x33\x66\x99\x33\x66\xcc\x33\x66\xff\x33\ -\x99\x00\x33\x99\x33\x33\x99\x66\x33\x99\x99\x33\x99\xcc\x33\x99\ -\xff\x33\xcc\x00\x33\xcc\x33\x33\xcc\x66\x33\xcc\x99\x33\xcc\xcc\ -\x33\xcc\xff\x33\xff\x00\x33\xff\x33\x33\xff\x66\x33\xff\x99\x33\ -\xff\xcc\x33\xff\xff\x66\x00\x00\x66\x00\x33\x66\x00\x66\x66\x00\ -\x99\x66\x00\xcc\x66\x00\xff\x66\x33\x00\x66\x33\x33\x66\x33\x66\ -\x66\x33\x99\x66\x33\xcc\x66\x33\xff\x66\x66\x00\x66\x66\x33\x66\ -\x66\x66\x66\x66\x99\x66\x66\xcc\x66\x66\xff\x66\x99\x00\x66\x99\ -\x33\x66\x99\x66\x66\x99\x99\x66\x99\xcc\x66\x99\xff\x66\xcc\x00\ -\x66\xcc\x33\x66\xcc\x66\x66\xcc\x99\x66\xcc\xcc\x66\xcc\xff\x66\ -\xff\x00\x66\xff\x33\x66\xff\x66\x66\xff\x99\x66\xff\xcc\x66\xff\ -\xff\x99\x00\x00\x99\x00\x33\x99\x00\x66\x99\x00\x99\x99\x00\xcc\ -\x99\x00\xff\x99\x33\x00\x99\x33\x33\x99\x33\x66\x99\x33\x99\x99\ -\x33\xcc\x99\x33\xff\x99\x66\x00\x99\x66\x33\x99\x66\x66\x99\x66\ -\x99\x99\x66\xcc\x99\x66\xff\x99\x99\x00\x99\x99\x33\x99\x99\x66\ -\x99\x99\x99\x99\x99\xcc\x99\x99\xff\x99\xcc\x00\x99\xcc\x33\x99\ -\xcc\x66\x99\xcc\x99\x99\xcc\xcc\x99\xcc\xff\x99\xff\x00\x99\xff\ -\x33\x99\xff\x66\x99\xff\x99\x99\xff\xcc\x99\xff\xff\xcc\x00\x00\ -\xcc\x00\x33\xcc\x00\x66\xcc\x00\x99\xcc\x00\xcc\xcc\x00\xff\xcc\ -\x33\x00\xcc\x33\x33\xcc\x33\x66\xcc\x33\x99\xcc\x33\xcc\xcc\x33\ -\xff\xcc\x66\x00\xcc\x66\x33\xcc\x66\x66\xcc\x66\x99\xcc\x66\xcc\ -\xcc\x66\xff\xcc\x99\x00\xcc\x99\x33\xcc\x99\x66\xcc\x99\x99\xcc\ -\x99\xcc\xcc\x99\xff\xcc\xcc\x00\xcc\xcc\x33\xcc\xcc\x66\xcc\xcc\ -\x99\xcc\xcc\xcc\xcc\xcc\xff\xcc\xff\x00\xcc\xff\x33\xcc\xff\x66\ -\xcc\xff\x99\xcc\xff\xcc\xcc\xff\xff\xff\x00\x00\xff\x00\x33\xff\ -\x00\x66\xff\x00\x99\xff\x00\xcc\xff\x00\xff\xff\x33\x00\xff\x33\ -\x33\xff\x33\x66\xff\x33\x99\xff\x33\xcc\xff\x33\xff\xff\x66\x00\ -\xff\x66\x33\xff\x66\x66\xff\x66\x99\xff\x66\xcc\xff\x66\xff\xff\ -\x99\x00\xff\x99\x33\xff\x99\x66\xff\x99\x99\xff\x99\xcc\xff\x99\ -\xff\xff\xcc\x00\xff\xcc\x33\xff\xcc\x66\xff\xcc\x99\xff\xcc\xcc\ -\xff\xcc\xff\xff\xff\x00\xff\xff\x33\xff\xff\x66\xff\xff\x99\xff\ -\xff\xcc\xff\xff\xff\xaf\x56\x4d\x1c\x00\x00\x00\x28\x74\x52\x4e\ -\x53\x34\xbb\xeb\xfe\x78\x9b\x54\xdd\x62\x86\xaa\x45\xca\x92\x71\ -\x5a\xb2\xa3\xf0\xe3\xd1\xc3\x3c\x89\x4a\x68\x00\x00\x00\x00\x00\ -\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\x2c\xf5\xce\x00\x00\x00\ -\x09\x70\x48\x59\x73\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7\x6f\ -\xa8\x64\x00\x00\x67\xec\x49\x44\x41\x54\x78\x5e\xed\xdd\x6b\x43\ -\x14\xb9\x16\x46\x61\x40\x6e\x22\x72\x17\x74\xfe\xff\x0f\x1d\xc4\ -\x57\x4b\x94\x2d\xdd\x3b\xa9\xaa\x37\xbb\xd6\xf3\xe9\x9c\x19\x07\ -\x93\x50\x61\x69\x57\x77\xea\xe0\x3f\x00\x4e\xbe\xdd\x7f\xf8\xe1\ -\xee\xe1\xe2\x4a\xff\x0c\xb0\x44\x40\x00\x1b\x07\xdf\x4e\x2e\xef\ -\x94\x0f\x39\xba\x7d\xd4\xbf\x04\xec\x10\x10\xc0\xc1\xa7\xab\x8b\ -\x33\x35\xe3\x4f\xf7\xc7\xfa\x35\x80\x19\x02\x02\xac\xec\xf4\xe3\ -\xcd\xcf\x57\xad\x02\x47\x24\x04\x96\x08\x08\xb0\x9e\xf3\xcf\x5f\ -\xfe\x78\xc9\x2a\x70\x7f\xaa\xff\x02\x30\x42\x40\x80\x35\x3c\x7e\ -\x3b\xb9\x54\x1c\x76\x73\xa1\xff\x10\xf0\x41\x40\x80\x85\x7d\x3d\ -\x0e\x6f\x77\xfc\xcb\xbd\xfe\x73\xc0\x06\x01\x01\x96\x73\xfd\x74\ -\x78\xa4\x1e\x24\x5c\xeb\xab\x00\x26\x08\x08\xb0\x88\x9d\x6f\x77\ -\xfc\xc3\x37\x7d\x2d\xc0\x03\x01\x01\x66\xf6\xe9\xea\xf6\x41\x05\ -\x68\xc5\x07\x0b\x61\x85\x80\x00\xf3\x49\xde\xee\x88\x9d\xeb\x0b\ -\x03\x0e\x08\x08\x30\x8b\xb6\xdb\x1d\x21\x76\x2c\x8c\x70\x39\x02\ -\x9d\x1d\x9c\x7f\xfe\xf3\x40\x92\x7e\x78\x2f\x16\x8c\x10\x10\xa0\ -\x9f\x8e\xb7\x3b\x22\x87\xfa\xad\x80\xf5\x11\x10\xa0\x8b\xf7\x0f\ -\x24\xe9\x84\xdb\x20\xb0\x41\x40\x80\x56\xd7\x4f\x87\xb3\xbd\x64\ -\xf5\xb7\x3b\xfd\xae\xc0\xea\x08\x08\x90\xb7\xf7\x81\x24\x3d\x7c\ -\xd6\x6f\x0e\xac\x8d\x80\x00\x29\xdd\xdf\xa1\xbb\x3b\x8d\x00\x58\ -\x1b\x01\x01\xf6\x75\xbd\xd4\xed\x8e\xc0\x89\xc6\x01\xac\x8c\x80\ -\x00\x7b\xe8\x71\x20\x49\x33\xee\x82\xc0\x04\x01\x01\x76\xf2\x78\ -\xb5\xc2\xed\x8e\x00\x6f\xc4\x82\x07\x02\x02\xbc\x67\xc5\xdb\x1d\ -\x6f\xfb\xa2\x81\x01\xeb\x22\x20\xc0\x3f\x9c\x7e\x9c\xe5\x40\x92\ -\x56\x1a\x1d\xb0\x2e\x02\x02\xbc\xe9\xe0\xfc\x64\xbe\x03\x49\x5a\ -\xf1\x80\x5b\x58\x20\x20\xc0\x9f\x16\x38\x90\xa4\x11\xef\xc3\x82\ -\x05\x02\x02\xfc\xe6\xf4\xf8\xc6\xeb\x76\xc7\xdb\x1e\x34\x5c\x60\ -\x55\x04\x04\xf8\x61\xd9\x03\x49\xda\xf0\x46\x5e\x58\x20\x20\xc0\ -\xc1\x1a\x07\x92\xb4\xd1\xc8\x81\x55\x11\x10\x6c\x9a\xdd\x3b\x74\ -\x77\xf4\xa8\xf1\x03\x6b\x22\x20\xd8\xaa\xb5\x0f\x24\x69\xf2\x55\ -\x93\x00\xd6\x44\x40\xb0\x41\x16\x07\x92\x34\xb9\xd6\x4c\x80\x35\ -\x11\x10\x6c\x8a\xd3\x81\x24\x2d\x38\xcc\x04\x0e\x08\x08\xb6\x62\ -\xd4\xdb\x1d\x6f\xfa\xa6\x49\x01\x6b\x22\x20\xd8\x00\xd3\x03\x49\ -\x1a\x10\x10\x38\x20\x20\x28\xcd\xfa\x40\x92\x06\x04\x04\x0e\x08\ -\x08\xaa\xf2\x3f\x90\xa4\x01\x01\x81\x03\x02\x82\x82\x06\x39\x90\ -\xa4\x01\x01\x81\x03\x02\x82\x5a\x46\x3a\x90\xa4\x01\x01\x81\x03\ -\x02\x82\x2a\xbe\x1f\x48\xb2\x85\x76\xbc\x20\x20\x70\x40\x40\x50\ -\x40\xa9\x77\xe8\xee\x84\x80\xc0\x01\x01\xc1\xd8\x4e\x47\x3e\x90\ -\x24\x8f\x80\xc0\x01\x01\xc1\xb0\xc6\x3f\x90\x24\x8f\x80\xc0\x01\ -\x01\xc1\x80\x1e\xc7\x3b\x7f\xbd\x33\x02\x02\x07\x04\x04\x63\xd9\ -\xde\xed\x8e\x37\x11\x10\x38\x20\x20\x18\x46\xbd\x03\x49\xf2\x08\ -\x08\x1c\x10\x10\x8c\x60\xcb\xb7\x3b\xde\x44\x40\xe0\x80\x80\xc0\ -\x5b\xe9\x03\x49\xf2\x08\x08\x1c\x10\x10\xd8\xfa\x5a\xfe\x40\x92\ -\x3c\x02\x02\x07\x04\x04\x8e\xae\x9f\xb8\xdd\xf1\x4f\x04\x04\x0e\ -\x08\x08\xbc\x6c\xea\x40\x92\x3c\x02\x02\x07\x04\x04\x36\xb8\xdd\ -\xb1\x3b\x02\x02\x07\x04\x04\x0e\x36\x7a\x20\x49\x1e\x01\x81\x03\ -\x02\x82\x95\x5d\x3f\xf1\x0e\xdd\xfd\x11\x10\x38\x20\x20\x58\x0d\ -\x07\x92\xe4\x11\x10\x38\x20\x20\x58\x03\x07\x92\x34\x22\x20\x70\ -\x40\x40\xb0\xb0\x6b\x6e\x77\x74\x40\x40\xe0\x80\x80\x60\x39\x1c\ -\x48\xd2\x0d\x01\x81\x03\x02\x82\x25\x3c\xf2\x0e\xdd\xbe\x08\x08\ -\x1c\x10\x10\xcc\x8c\xdb\x1d\x73\x20\x20\x70\x40\x40\x30\x1f\x0e\ -\x24\x99\x0d\x01\x81\x03\x02\x82\x39\x1c\x9c\x73\x20\xc9\xac\x08\ -\x08\x1c\x10\x10\x74\xc6\x81\x24\x4b\x20\x20\x70\x40\x40\xd0\xcf\ -\xe9\x31\xef\xd0\x5d\x08\x01\x81\x03\x02\x82\x2e\xae\x9f\x0e\x79\ -\xc9\x6a\x41\x04\x04\x0e\x08\x08\x1a\x71\x20\xc9\x1a\x08\x08\x1c\ -\x10\x10\xe4\xf1\x0e\xdd\xd5\x10\x10\x38\x20\x20\x48\xe1\x40\x92\ -\x75\x11\x10\x38\x20\x20\xd8\x17\x07\x92\x18\x20\x20\x70\x40\x40\ -\xb0\xbb\xc7\x2b\x6e\x77\x98\x20\x20\x70\x40\x40\xb0\x13\x6e\x77\ -\xf4\x74\x74\x73\xa2\xff\x95\x45\x40\xe0\x80\x80\xe0\x3d\xa7\x1f\ -\x39\x90\xa4\x9f\xb3\x8b\xe3\xaf\xdf\x57\x55\xff\x37\x8b\x80\xc0\ -\x01\x01\x41\x8c\x03\x49\xba\x7a\xb8\xbd\x7a\xd4\xca\x12\x10\x94\ -\x40\x40\xf0\x26\x0e\x24\xe9\xe9\xee\xf2\xf3\xb9\x16\xf6\x27\xfd\ -\x9b\x2c\x02\x02\x07\x04\x04\x7f\x3a\x3d\xbe\xe1\x76\x47\x37\x47\ -\x87\x4f\xa7\x5a\xd8\x57\xf4\xaf\xb3\x08\x08\x1c\x10\x10\xfc\x86\ -\x03\x49\x7a\x3a\xbb\xf9\xf8\x72\xbb\xe3\x4d\xfa\x35\x59\x04\x04\ -\x0e\x08\x08\x5e\x1c\x7c\xe3\x76\x47\x47\x0f\xb7\x57\x9f\xb4\xb2\ -\x01\xfd\xc2\x2c\x02\x02\x07\x04\x04\xbc\x43\xb7\xa7\xbb\xcb\x93\ -\x6f\xbb\xec\x2a\xfd\xf2\x2c\x02\x02\x07\x04\x64\xd3\x4e\x3f\x1e\ -\x72\x20\x49\x37\x77\x87\x4f\xd7\x5a\xd8\xf7\xe9\xbf\xc9\x22\x20\ -\x70\x40\x40\xb6\x8a\x03\x49\x7a\xba\xbf\xf9\xf8\xe6\xad\xf2\x98\ -\xfe\xc3\x2c\x02\x02\x07\x04\x64\x7b\x38\x90\xa4\xab\xb3\x8b\xe3\ -\x77\x6e\x77\xbc\x49\xff\x75\x16\x01\x81\x03\x02\xb2\x29\xdc\xee\ -\xe8\xea\xf2\xe4\xdb\xf4\xc9\xc0\x3d\xe9\x4b\x64\x11\x10\x38\x20\ -\x20\x5b\xc1\x81\x24\x3d\xdd\x7d\xf9\xeb\x93\x81\x7b\xd2\x17\xca\ -\x22\x20\x70\x40\x40\x36\xe0\xfc\x33\xef\xd0\xed\xe7\xfe\xe6\xe3\ -\xee\xb7\xca\x63\xfa\x6a\x59\x04\x04\x0e\x08\x48\x69\x1c\x48\xd2\ -\xd5\xcf\x83\x10\x7b\xd0\x97\xcc\x22\x20\x70\x40\x40\xaa\xe2\x40\ -\x92\xae\x2e\x4f\x7e\x3b\x08\xb1\x07\x7d\xdd\x2c\x02\x02\x07\x04\ -\xa4\xa0\xeb\x27\x6e\x77\xf4\xd3\x7e\xbb\xe3\x4d\xfa\xea\x59\x04\ -\x04\x0e\x08\x48\x29\x1c\x48\xd2\xd5\xd1\xe1\xbe\x9f\xee\xd8\x9d\ -\x7e\x8b\x2c\x02\x02\x07\x04\xa4\x8a\x4f\x57\xbc\x43\xb7\xa3\x9e\ -\xb7\x3b\xde\xa4\xdf\x27\x8b\x80\xc0\x01\x01\x29\xe0\xf4\xe3\x0d\ -\x07\x92\xf4\xf3\xfe\x41\x88\x3d\xe8\x37\xcb\x22\x20\x70\x40\x40\ -\xc6\xc6\x81\x24\x3d\xdd\x5d\x9e\x9c\x2f\xb5\x23\xf4\x5b\x66\x11\ -\x10\x38\x20\x20\xa3\x7a\xfc\xc6\x81\x24\x1d\xed\x75\x10\x62\x0f\ -\xfa\x7d\xb3\x08\x08\x1c\x10\x90\x01\x71\x20\x49\x57\xf7\x37\xc7\ -\xb3\xdd\x2a\x8f\xe9\x37\xcf\x22\x20\x70\x40\x40\xc6\x72\xfd\xf1\ -\x86\x77\xe8\xf6\x73\xb6\xc8\xed\x8e\x37\x69\x04\x59\x04\x04\x0e\ -\x08\xc8\x30\xb8\xdd\xd1\xd5\x8e\xcf\x7d\x9a\x8d\x86\x91\x45\x40\ -\xe0\x80\x80\x0c\x80\x03\x49\xba\xba\xfb\xf2\x79\xd9\xdb\x1d\x6f\ -\xd2\x60\xb2\x08\x08\x1c\x10\x10\x6f\xdc\xee\xe8\x6a\xff\xe7\x3e\ -\xcd\x46\x23\xca\x22\x20\x70\x40\x40\x6c\x71\x20\x49\x57\xb3\x7f\ -\x32\x70\x4f\x1a\x56\x16\x01\x81\x03\x02\x62\xe8\xe0\x9c\x03\x49\ -\x7a\xea\x7e\x10\x62\x0f\x1a\x5b\x16\x01\x81\x03\x02\xe2\x85\xdb\ -\x1d\x5d\xcd\x74\x10\x62\x0f\x1a\x61\x16\x01\x81\x03\x02\x62\x83\ -\x03\x49\xba\x3a\x3a\xec\xf2\xdc\xa7\xd9\x68\x98\x59\x04\x04\x0e\ -\x08\x88\x83\xeb\xa7\x43\x5e\xb2\xea\xc7\xed\x76\xc7\x9b\x34\xd6\ -\x2c\x02\x02\x07\x04\x64\x5d\x1c\x48\xd2\xd7\xc3\xad\xe1\xed\x8e\ -\x37\x69\xc0\x59\x04\x04\x0e\x08\xc8\x6a\x78\x87\x6e\x57\xdf\x0f\ -\x42\xd4\xca\x0e\x41\xc3\xce\x22\x20\x70\x40\x40\xd6\x70\xcd\xed\ -\x8e\x9e\x8e\x96\x3e\x08\xb1\x07\x8d\x3d\x8b\x80\xc0\x01\x01\x59\ -\x18\x07\x92\x74\x75\xb6\xca\x41\x88\x3d\x68\x02\x59\x04\x04\x0e\ -\x08\xc8\x62\x1e\xaf\xb8\xdd\xd1\xd3\x32\xcf\x7d\x9a\x8d\x66\x91\ -\x45\x40\xe0\x80\x80\x2c\x81\xdb\x1d\x5d\xdd\xad\x7d\x10\x62\x0f\ -\x9a\x4b\x16\x01\x81\x03\x02\x32\xb3\xd3\x8f\x1c\x48\xd2\xd1\xe2\ -\xcf\x7d\x9a\x8d\x26\x94\x45\x40\xe0\x80\x80\xcc\x86\x03\x49\xfa\ -\x32\x3a\x08\xb1\x07\xcd\x2a\x8b\x80\xc0\x01\x01\x99\x03\x07\x92\ -\xf4\x35\xc4\x27\x03\xf7\xa4\xa9\x65\x11\x10\x38\x20\x20\x9d\x9d\ -\x1e\xdf\x70\xbb\xa3\xa3\xcb\x93\x6f\x83\x7c\x32\x70\x4f\x9a\x5f\ -\x16\x01\x81\x03\x02\xd2\x0f\x07\x92\x74\x65\x7c\x10\x62\x0f\x9a\ -\x65\x16\x01\x81\x03\x02\xd2\xc3\x01\x07\x92\x74\x75\x74\xe3\x7d\ -\x10\x62\x0f\x9a\x6a\x16\x01\x81\x03\x02\xd2\x88\x77\xe8\xf6\x55\ -\xf1\x76\xc7\x9b\x34\xdf\x2c\x02\x02\x07\x04\x24\x8f\xf3\xd7\xfb\ -\x7a\x70\x7c\xee\xd3\x6c\x34\xe9\x2c\x02\x02\x07\x04\x24\x85\x03\ -\x49\xba\xba\xbb\x2c\x7d\xbb\xe3\x4d\x9a\x7a\x16\x01\x81\x03\x02\ -\xb2\x27\x0e\x24\xe9\xeb\xe8\xb0\xd4\xa7\x3b\x76\xa7\xf9\x67\x11\ -\x10\x38\x20\x20\xbb\xe3\x76\x47\x5f\x67\x37\x1b\xb9\xdd\xf1\x26\ -\x2d\x42\x16\x01\x81\x03\x02\xb2\x13\x0e\x24\xe9\x6b\xf0\x83\x10\ -\x7b\xd0\x4a\x64\x11\x10\x38\x20\x20\xef\xe1\x40\x92\xae\xbe\x3f\ -\xf7\x89\x8b\xee\x99\xd6\x23\x8b\x80\xc0\x01\x7b\x39\xc6\x81\x24\ -\x7d\xd5\x39\x08\xb1\x07\x2d\x4a\x16\x01\x81\x03\x02\xf2\x26\x0e\ -\x24\xe9\xab\xd8\x41\x88\x3d\x68\x65\xb2\x08\x08\x1c\x10\x90\x3f\ -\x71\x20\x49\x5f\x67\x17\xc7\x5b\xbf\xdd\xf1\x26\x2d\x4f\x16\x01\ -\x81\x03\x02\x32\xf9\x7e\x20\x09\xed\xe8\xa8\xc2\x73\x9f\x66\xa3\ -\x35\xca\x22\x20\x70\xc0\x06\x7f\xf1\x89\x77\xe8\x76\x55\xfc\x20\ -\xc4\x1e\xb4\x52\x59\x04\x04\x0e\x08\x08\x07\x92\xf4\xc5\xed\x8e\ -\xdd\x68\xb9\xb2\x08\x08\x1c\x6c\x3a\x20\x1c\x48\xd2\xd7\x66\x0e\ -\x42\xec\x41\x6b\x96\x45\x40\xe0\x60\xa3\x01\x79\xe4\xfc\xf5\xbe\ -\x2e\x37\x75\x10\x62\x0f\x5a\xb8\x2c\x02\x02\x07\xdb\x0b\x08\x07\ -\x92\xf4\xc5\xed\x8e\x1c\x2d\x5f\x16\x01\x81\x83\x4d\x05\x84\x03\ -\x49\xfa\xda\xec\x41\x88\x3d\x68\x0d\xb3\x08\x08\x1c\x6c\x25\x20\ -\xdc\xee\xe8\x8b\xdb\x1d\xad\xb4\x90\x59\x04\x04\x0e\xea\x07\x84\ -\x03\x49\x3a\xe3\x20\xc4\x2e\xb4\x9a\x59\x04\x04\x0e\x4a\x07\x84\ -\xdb\x1d\x9d\x71\x10\x62\x3f\x5a\xd2\x2c\x02\x02\x07\x55\x7f\x1e\ -\x5c\x3f\x71\xbb\xa3\xa7\x23\x0e\x42\xec\x4c\x0b\x9b\x45\x40\xe0\ -\xa0\x5e\x40\x38\x90\xa4\xb3\xfb\x9b\x63\x6e\x95\xf7\xa7\xd5\xcd\ -\x22\x20\x70\x50\x2a\x20\xdc\xee\xe8\xec\x8c\xdb\x1d\xb3\xd1\x12\ -\x67\x11\x10\x38\xa8\x12\x10\x0e\x24\xe9\x8c\x83\x10\x67\xa6\x75\ -\xce\x22\x20\x70\x50\xe0\x87\xc4\xf5\x13\xef\xd0\xed\x89\xe7\x3e\ -\x2d\x42\xab\x9d\x45\x40\xe0\x60\xe8\x80\x70\x20\x49\x67\xf7\x7c\ -\x32\x70\x31\x5a\xf2\x2c\x02\x02\x07\xa3\x06\x84\x77\xe8\x76\xc6\ -\x27\x03\x17\xa6\x75\xcf\x22\x20\x70\x30\x60\x40\xae\xb9\xdd\xd1\ -\xd7\xe5\xc9\x37\x0e\x42\x5c\x9c\x16\x3f\x8b\x80\xc0\xc1\x58\x01\ -\xe1\x40\x92\xbe\x38\x08\x71\x3d\xfa\x16\x64\x11\x10\x38\x18\x25\ -\x20\x8f\x57\x27\xbc\x43\xb7\x27\x3e\x19\xb8\x32\x7d\x1f\xb2\x08\ -\x08\x1c\x0c\x10\x10\x6e\x77\x74\xc6\xed\x0e\x07\xfa\x66\x64\x11\ -\x10\x38\xf0\x0e\x08\x07\x92\x74\xf6\x70\xcb\x73\x9f\x4c\xe8\x3b\ -\x92\x45\x40\xe0\xc0\x35\x20\x07\xe7\x1c\x48\xd2\xd5\xdd\xe5\x09\ -\x3f\x73\x9c\xe8\xfb\x92\xc5\x37\x13\x0e\x0c\x03\xc2\x81\x24\x9d\ -\x71\xbb\xc3\x91\xbe\x39\x59\x04\x04\x0e\xbc\x02\x72\x7a\xcc\x3b\ -\x74\xbb\x3a\xbb\xe1\x76\x87\x29\x7d\x87\xb2\x08\x08\x1c\xd8\x04\ -\xe4\xfa\xe9\x90\x97\xac\x7a\xe2\xb9\x4f\xde\xf4\x6d\xca\x22\x20\ -\x70\x60\x10\x10\x0e\x24\xe9\xec\xfb\xed\x0e\x6e\x95\xbb\xd3\x37\ -\x2b\x8b\x80\xc0\xc1\xba\x01\xe1\x1d\xba\x9d\x71\x10\xe2\x30\xf4\ -\x1d\xcb\x22\x20\x70\xb0\x5a\x40\x38\x90\xa4\xb3\xfb\x1b\x0e\x42\ -\x1c\x89\xbe\x6d\x59\x04\x04\x0e\xd6\x08\x08\x07\x92\x74\xc6\x27\ -\x03\x07\xa4\xef\x5d\x16\x01\x81\x83\x65\x03\xf2\x78\xc5\xed\x8e\ -\xbe\xb8\xdd\x31\x2a\x7d\x03\xb3\x08\x08\x1c\x2c\x16\x10\x6e\x77\ -\x74\xc6\x41\x88\x63\xd3\xb7\x31\x8b\x80\xc0\xc1\x12\x01\x39\xfd\ -\xc8\x81\x24\x5d\x1d\xdd\x7c\xe4\x56\xf9\xe8\xf4\xbd\xcc\x22\x20\ -\x70\x30\x6f\x40\x38\x90\xa4\x37\x6e\x77\x54\xa1\x6f\x68\x16\x01\ -\x81\x83\xd9\x02\xc2\x81\x24\xbd\x3d\x9c\x70\x10\x62\x21\xfa\xae\ -\x66\x11\x10\x38\x98\x23\x20\xa7\xc7\x37\xdc\xee\xe8\x89\xdb\x1d\ -\x05\xe9\x7b\x9b\x45\x40\xe0\xa0\x73\x40\x38\x90\xa4\xb3\xa3\x43\ -\x3e\xdd\x51\x93\xbe\xc1\x59\x04\x04\x0e\xba\x05\xe4\xe0\x1b\xb7\ -\x3b\xfa\xe2\x76\x47\x69\xfa\x2e\x67\x11\x10\x38\xe8\x11\x10\xde\ -\xa1\xdb\x1b\x07\x21\xd6\xa7\x6f\x75\x16\x01\x81\x83\xc6\x80\x9c\ -\x72\x20\x49\x5f\x77\x97\x9f\xcf\xe7\xb8\x2f\x05\x37\xfa\x86\x67\ -\x11\x10\x38\xc8\xff\xb0\xe2\x40\x92\xce\x38\x08\x71\x53\xf4\x5d\ -\xcf\x22\x20\x70\x90\x09\x08\x07\x92\xf4\xc6\x41\x88\xdb\xa3\x6f\ -\x7d\x16\x01\x81\x83\x3d\x03\xc2\xed\x8e\xde\xce\x2e\xb8\xdd\xb1\ -\x49\xfa\xfe\x67\x11\x10\x38\xd8\x3d\x20\x1c\x48\xd2\xdb\xe5\xc9\ -\x37\x6e\x77\x6c\x96\x2e\x82\x2c\x02\x02\x07\x3b\xfd\x04\xe3\x76\ -\x47\x67\x7c\x32\x10\xba\x14\xb2\x08\x08\x1c\xbc\x13\x10\x0e\x24\ -\xe9\x8d\xdb\x1d\x78\xa1\xeb\x21\x8b\x80\xc0\x41\x1c\x90\xaf\x1c\ -\x48\xd2\xd9\xd9\xc5\x31\xb7\x3b\x20\xba\x28\xb2\x08\x08\x1c\xbc\ -\x1d\x90\x83\x27\xfe\xde\xd1\xd5\x25\x07\x21\xe2\x35\x5d\x19\x59\ -\x04\x04\x0e\xde\x0a\xc8\x31\x7f\xf3\xe8\x87\xdb\x1d\x78\x93\xae\ -\x8f\x2c\x02\x02\x07\x7f\x07\xe4\x49\x57\x28\x5a\x71\x10\x22\x62\ -\xba\x48\xb2\x08\x08\x1c\xfc\x19\x90\x2b\xde\x6e\xd5\x03\x07\x21\ -\xe2\x1d\xba\x52\xb2\x08\x08\x1c\xfc\x11\x10\x3e\x61\xde\x8c\x83\ -\x10\xb1\x0b\x5d\x2e\x59\x04\x04\x0e\x5e\x05\xe4\x4a\x17\x27\x52\ -\xee\x2e\x4f\x38\x08\x11\x3b\xd2\x45\x93\x45\x40\xe0\xe0\xf7\x1f\ -\x78\xb7\xba\x36\xb1\xb7\x23\x0e\x42\xc4\x7e\x74\xe5\x64\x11\x10\ -\x38\xf8\x2d\x20\x87\xba\x34\xb1\x97\xfb\x9b\x63\x6e\x95\x63\x6f\ -\xba\x7c\xb2\x08\x08\x1c\x4c\x01\xe1\xf6\xc7\xde\xb8\xdd\x81\x34\ -\x5d\x43\x59\x04\x04\x0e\x7e\x05\xe4\x8b\x2e\x4c\xec\x84\x83\x10\ -\xd1\x46\x17\x52\x16\x01\x81\x83\x9f\x3f\x05\x2f\x74\x5d\xe2\x3d\ -\x77\x5f\xb8\xdd\x81\x76\xba\x9c\xb2\x08\x08\x1c\x28\x20\xbc\xff\ -\x6a\x17\x1c\x84\x88\x6e\x74\x4d\x65\x11\x10\x38\x50\x40\x74\x55\ -\x22\xc2\x27\x03\xd1\x97\x2e\xac\x2c\x02\x02\x07\x3f\x02\xc2\xd1\ -\x89\xff\x70\x79\xf2\x8d\x83\x10\xd1\x9b\xae\xae\x2c\x02\x02\x07\ -\x2f\x01\x39\xd6\x45\x89\xd7\x38\x08\x11\xb3\xd1\x35\x96\x45\x40\ -\xe0\xe0\x25\x20\x9c\x7f\xf5\x97\xa3\xc3\x8f\xdc\x2a\xc7\x8c\x74\ -\xa1\x65\x11\x10\x38\xf8\x1e\x90\xcf\xba\x26\xf1\x82\xdb\x1d\x58\ -\x80\xae\xb6\x2c\x02\x02\x07\xdf\x03\xa2\x4b\x12\xdf\x3f\x19\xc8\ -\xed\x0e\x2c\x42\x97\x5c\x16\x01\x81\x83\xe7\x80\x70\x07\xe4\xd9\ -\xf7\x83\x10\xb5\x24\xc0\x02\x74\xe1\x65\x11\x10\x38\x78\x0e\xc8\ -\xbd\x2e\xc9\xad\x3a\x3a\x7c\xe2\xd3\x1d\x58\x9a\xae\xbe\x2c\x02\ -\x02\x07\x07\xff\x7d\xd5\x15\xb9\x45\x67\x37\xdc\xee\xc0\x3a\x74\ -\x09\x66\x1d\x3e\x01\x81\xe3\xe3\xab\xeb\x85\x4e\xe9\x3b\xd8\xea\ -\x2d\x74\x0e\x42\xc4\xaa\x74\x1d\x02\x73\xb9\xbb\xbc\xbd\x9a\xfb\ -\x0f\xc8\x07\xdb\x7b\x05\xeb\x8e\x83\x10\xb1\x3e\x5d\x8d\xc0\xbc\ -\x1e\x4e\xe6\x7c\x85\xfe\x60\x53\x17\xf2\x1d\xcf\x7d\x82\x09\x5d\ -\x92\xc0\xfc\x0e\x67\xbb\x65\x76\x70\xad\xdf\xa2\x3a\x0e\x42\x84\ -\x15\x5d\x97\xc0\x22\x0e\xe7\xf9\xf1\x77\xb0\x81\x5b\x20\x7c\x32\ -\x10\x7e\x74\x71\x02\x0b\x39\x7a\xd2\xa5\xd7\xd3\xc1\x8d\xbe\x7a\ -\x4d\x1c\x84\x08\x53\xba\x42\x81\xe5\xdc\xea\xe2\xeb\xe7\xa0\xea\ -\x93\x6c\x39\x08\x11\xd6\x74\x9d\x02\x4b\xba\xd0\xe5\xd7\xcb\xc1\ -\x91\xbe\x70\x21\xf7\x37\x1c\x84\x08\x77\xba\x58\x81\x65\x9d\xe8\ -\x02\xec\xe3\xa0\xd6\x49\xbc\xdc\xee\xc0\x20\x74\xc5\x02\x0b\x3b\ -\xea\xf9\xd2\xcc\x81\xbe\xe8\xf8\x2e\x4f\x38\x08\x11\xe3\xd0\x65\ -\x0b\x2c\xee\x8b\xae\xc1\x0e\x2a\x04\x84\xdb\x1d\x18\x8f\x2e\x5e\ -\x60\x05\x1f\x75\x15\x36\x1b\x3c\x20\x47\x87\x7c\xba\x03\x43\xd2\ -\x15\x0c\xac\xa1\xd7\x5f\x42\xc6\x0d\x08\xb7\x3b\x30\x32\x5d\xc6\ -\xc0\x2a\x8e\xfa\x1c\x05\x38\x64\x40\x38\x08\x11\xc3\xd3\xb5\x0c\ -\xac\xa4\xcb\xcb\x58\x83\x05\xe4\xfb\x73\x9f\x38\x08\x11\x05\xe8\ -\x8a\x06\xd6\x72\xa8\x4b\xb1\xc5\x38\x01\xe1\x20\x44\x54\xa2\xcb\ -\x1a\x58\xcd\xa5\xae\xc5\x06\x43\x04\xe4\xfe\xe6\x98\x5b\xe5\x28\ -\x65\xdc\x9b\x8f\xa8\xe3\x4c\x57\x63\x9e\xfb\x75\x7c\xc6\xed\x0e\ -\x54\x74\xa2\x0b\x1c\x58\xd1\xbd\x2e\xc7\x34\xe3\x80\xf0\xdc\x27\ -\xd4\x55\xeb\x04\x08\x8c\xea\x4e\xd7\x63\x96\x65\x40\xee\xbe\x7c\ -\xe6\x76\x07\x2a\xfb\xa6\x4b\x1d\x58\x57\xe3\xdf\x41\xdc\x02\xc2\ -\x73\x9f\xb0\x05\x87\xba\xde\x81\x95\xb5\xdd\x07\x31\x0a\x08\x9f\ -\x0c\xc4\x66\xe8\x9a\x07\x56\xd7\xf4\x5e\x2c\x8f\x80\x70\x10\x22\ -\x36\xe5\xab\x2e\x7c\x60\x7d\x2d\x9f\x07\x59\x3b\x20\x1c\x84\x88\ -\x0d\x7a\xd2\xe5\x0f\x18\x68\x78\xd6\xed\x8a\x01\xe1\x20\x44\x6c\ -\x15\xb7\x40\xe0\x24\x7f\xef\x60\x9d\x80\x70\xbb\x03\x9b\x76\xaf\ -\x8d\x00\x38\x38\xd2\x75\xb9\xbf\xc5\x03\xc2\x41\x88\x80\x36\x03\ -\xe0\x21\x7d\xba\xfb\x82\x01\xe1\x20\x44\xe0\x07\x6d\x09\xc0\x44\ -\xf6\x68\xde\x65\x02\x72\xc4\x41\x88\xc0\x44\xfb\x02\x70\xa1\x2b\ -\x73\x5f\xb3\x07\xe4\x8c\x83\x10\x81\xd7\x1e\xb5\x39\x00\x17\xc9\ -\x17\xb1\xe6\x0c\x08\xb7\x3b\x80\xb7\x7c\xd2\x0e\x01\x6c\xe4\x3e\ -\x4e\x31\x4f\x40\xee\x38\x08\x11\x08\x2d\x78\xe7\x11\xd8\x4d\xee\ -\x9d\x58\xdd\x2f\x65\x9e\xfb\x04\xbc\x47\x9b\x05\xf0\x71\xa2\x8b\ -\x73\x2f\x3d\x03\xc2\x41\x88\xc0\x4e\xb4\x63\x00\x23\xba\x38\xf7\ -\xd2\x29\x20\x7c\x32\x10\xd8\x1d\x4f\x03\x81\x9f\xcc\x5f\x41\xda\ -\x03\xf2\x70\xf2\x8d\x83\x10\x81\x7d\x5c\x6a\xf3\x00\x46\x74\x75\ -\xee\xa3\x35\x20\x9f\xf5\x75\x00\xec\xec\x56\xdb\x07\x30\x92\xf8\ -\x69\xde\x1a\x90\x63\x7d\x1d\x00\x3b\xbb\xd2\xf6\x01\x9c\xe8\xf2\ -\xdc\x03\x01\x01\x96\xa7\xed\x03\x38\xd9\xff\xaf\x20\x04\x04\x58\ -\xde\x99\xf6\x0f\x60\x64\xff\xcf\x82\x10\x10\x60\x79\x9f\xb5\x7f\ -\x00\x27\x7b\x7f\x86\x8f\x80\x00\x2b\xd0\xfe\x01\x9c\xec\xfd\x74\ -\x5b\x02\x02\xac\x80\x37\xf2\xc2\x91\x2e\xcf\x9d\x11\x10\x60\x05\ -\xe7\xda\x40\x80\x93\x2b\x5d\x9f\xbb\x22\x20\xc0\x1a\xb4\x81\x00\ -\x27\xfb\xbe\x86\x45\x40\x80\x35\x68\x03\x01\x56\x74\x79\xee\x8a\ -\x80\x00\x6b\xd0\x06\x02\xac\xec\x79\x1e\x2e\x01\x01\xd6\xa0\x0d\ -\x04\x58\xd9\xf3\x44\x45\x02\x02\xac\x41\x1b\x08\xb0\xf2\xa0\xeb\ -\x73\x47\x04\x04\x58\x83\x36\x10\xe0\x45\xd7\xe7\x8e\x08\x08\xb0\ -\x06\x6d\x20\xc0\xcb\x7e\x0f\x76\x22\x20\xc0\x1a\xb4\x81\x00\x2f\ -\xfb\xfd\x48\x27\x20\xc0\x1a\xb4\x81\x00\x2f\x17\xba\x40\x77\x43\ -\x40\x80\x35\x68\x03\x01\x5e\xf6\xbb\x8b\x4e\x40\x80\x35\x68\x03\ -\x01\x66\x74\x81\xee\x86\x80\x00\x6b\xd0\x06\x02\xcc\xe8\x02\xdd\ -\x0d\x01\x01\xd6\xa0\x0d\x04\x98\x79\xd4\x15\xba\x13\x02\x02\xac\ -\x41\x1b\x08\x30\xb3\xd7\xfb\x78\x09\x08\xb0\x06\x6d\x20\xc0\xcc\ -\xb9\xae\xd0\x9d\x10\x10\x60\x0d\xda\x40\x80\x99\xbd\x7e\xa6\x13\ -\x10\x60\x0d\xda\x40\x80\x19\x02\x02\xd8\xd3\x06\x02\xcc\x7c\xd4\ -\x15\xba\x13\x02\x02\xac\x41\x1b\x08\x30\x43\x40\x00\x7b\xda\x40\ -\x59\xdf\xf4\x65\x80\x3f\xdd\xe9\x1a\x49\x22\x20\x80\x3d\x6d\xa0\ -\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ -\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ -\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ -\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ -\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ -\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ -\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ -\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ -\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ -\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ -\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ -\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ -\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ -\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ -\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ -\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ -\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ -\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ -\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ -\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ -\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ -\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ -\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ -\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ -\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ -\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ -\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ -\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ -\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ -\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ -\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ -\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ -\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ -\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ -\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ -\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ -\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ -\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ -\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ -\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ -\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ -\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ -\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ -\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ -\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ -\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ -\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ -\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ -\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ -\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ -\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ -\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ -\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ -\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ -\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ -\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ -\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ -\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ -\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ -\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ -\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ -\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ -\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ -\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ -\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ -\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ -\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ -\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ -\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ -\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ -\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ -\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ -\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ -\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ -\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ -\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ -\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ -\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ -\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ -\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ -\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ -\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ -\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ -\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ -\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ -\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ -\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ -\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ -\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ -\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ -\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ -\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ -\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ -\xaa\xd3\x06\xca\x3a\x39\x5d\x95\x26\x91\xa6\x2f\xb3\x4d\x9f\xb4\ -\x08\x73\x21\x20\x40\x75\xda\x40\x83\xba\xd6\x2c\xb2\xf4\x65\xb6\ -\xe9\x41\x8b\x30\x17\x02\x02\x54\xa7\x0d\x34\x28\x02\xd2\x80\x80\ -\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ -\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ -\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ -\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ -\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ -\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ -\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ -\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ -\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ -\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ -\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ -\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ -\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ -\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ -\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ -\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ -\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ -\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ -\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ -\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ -\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ -\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ -\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ -\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ -\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ -\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ -\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ -\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ -\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ -\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ -\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ -\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ -\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ -\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ -\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ -\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ -\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ -\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ -\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ -\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ -\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ -\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ -\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ -\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\ -\x02\xd2\x80\x80\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\ -\x4c\x08\x08\x90\xa1\x0d\x34\x28\x02\xd2\x80\x80\x4c\x08\x08\x90\ -\xa1\x0d\x94\xf5\xf1\x60\x55\x9a\x44\x9a\xbe\xcc\x36\x69\x0d\x66\ -\x43\x40\x80\xea\xb4\x81\xb2\xbe\xe9\xcb\x00\x7f\x22\x20\x40\x75\ -\xda\x40\x59\x04\x04\x11\x02\x02\x54\xa7\x0d\x94\x45\x40\x10\x21\ -\x20\x40\x75\xda\x40\x59\x04\x04\x11\x02\x02\x54\xa7\x0d\x94\x45\ -\x40\x10\x21\x20\x40\x75\xda\x40\x59\x04\x04\x11\x02\x02\x54\xa7\ -\x0d\x94\x45\x40\x10\x21\x20\x40\x75\xda\x40\x59\x04\x04\x11\x02\ -\x02\x54\xa7\x0d\x94\x45\x40\x10\x21\x20\x40\x75\xda\x40\x59\x04\ -\x04\x11\x02\x02\x54\xa7\x0d\x94\x45\x40\x10\x21\x20\x40\x75\xda\ -\x40\x59\x04\x04\x11\x02\x02\x54\xa7\x0d\x94\x45\x40\x10\x21\x20\ -\x40\x75\xda\x40\x59\x04\x04\x11\x02\x02\x54\xa7\x0d\x94\x45\x40\ -\x10\x21\x20\x40\x75\xda\x40\x59\x04\x04\x11\x02\x02\x54\xa7\x0d\ -\x94\x45\x40\x10\x21\x20\x40\x75\xda\x40\x59\x04\x04\x11\x02\x02\ -\x54\xa7\x0d\x94\x45\x40\x10\x21\x20\x40\x75\xda\x40\x59\x04\x04\ -\x11\x02\x02\x54\xa7\x0d\x94\x45\x40\x10\x21\x20\x8d\xbe\x69\x70\ -\xc6\x1e\x35\xd4\x72\x1a\x2f\xde\x59\x5c\x6a\x6c\x56\x34\xb6\x2c\ -\x02\x82\x08\x01\x69\xf5\xa0\xd1\xf9\xba\xd1\x48\xab\x79\xd2\xfc\ -\xac\x68\x6c\x5e\x34\xb6\x2c\x02\x82\x08\x01\x69\xf5\x49\xa3\x33\ -\xa6\x91\x56\xa3\xd9\x59\xf9\xac\xb1\x79\xd1\xe0\xb2\x08\x08\x22\ -\x04\xa4\xd9\x85\x86\xe7\xeb\x42\x23\xad\xe5\x44\xb3\x73\x72\xa4\ -\xb1\x99\xd1\xe8\xb2\x08\x08\x22\x04\xa4\x9d\xe3\x4b\xf1\xaf\x69\ -\xa0\xb5\x68\x6e\x56\xae\x35\x36\x33\x1a\x5d\x16\x01\x41\x84\x80\ -\xb4\x3b\xd6\xf8\x7c\xdd\x6a\xa4\x95\xdc\x68\x6e\x4e\xbe\x68\x6c\ -\x6e\x34\xbc\x2c\x02\x82\x08\x01\xe9\xe0\x4c\x03\xf4\xa5\x81\x16\ -\xf2\xa8\x99\x59\xd1\xd8\xec\x68\x78\x59\x04\x04\x11\x02\xd2\xc1\ -\xa9\x06\xe8\xeb\x44\x23\xad\xe3\x8b\x66\xe6\xc4\xf3\x0e\xfa\x33\ -\x8d\x2f\x8b\x80\x20\x42\x40\x7a\x38\xd4\x08\x7d\x69\xa0\x65\x7c\ -\xd5\xbc\x9c\xdc\x6b\x6c\x7e\x34\xc0\x2c\x02\x82\x08\x01\xe9\x42\ -\x23\xf4\x65\xfb\x87\xe3\x24\xc7\x4f\xdf\x9c\x6a\x6c\x7e\x34\xc0\ -\x2c\x02\x82\x08\x01\xe9\xe2\xb3\x86\xe8\x4b\x03\x2d\xe2\x5c\xb3\ -\x72\x72\xa8\xb1\x19\xd2\x08\xb3\x08\x08\x22\x04\xa4\x8f\x23\x8d\ -\xd1\xd6\x93\x06\x5a\xc3\xbd\x66\xe5\x44\x43\x73\xa4\x11\x66\x11\ -\x10\x44\x08\x48\x1f\x8e\x7f\x24\x7e\xe5\x4e\x03\x2d\xe1\x4a\x93\ -\x72\xe2\x5c\x68\x0d\x31\x8b\x80\x20\x42\x40\x3a\xb9\xd4\x20\x6d\ -\x59\xaf\xde\x9e\x0c\xff\xbe\xe7\x7b\x07\xfd\x99\xc6\x98\x45\x40\ -\x10\x21\x20\x9d\x58\x7e\x2e\xe1\x77\xa6\xa7\x6c\x64\x7c\xd4\x94\ -\x9c\xf8\xde\x41\x7f\xa6\x31\x66\x11\x10\x44\x08\x48\x2f\xb7\x1a\ -\xa5\xad\x2b\x0d\x74\x7c\x9a\x90\x13\xef\x13\x8f\x35\xc8\x2c\x02\ -\x82\x08\x01\xe9\xa6\x71\x29\x67\x67\xfd\x22\xcb\x3e\x1c\xdf\xf2\ -\xa6\xa1\x99\xd2\x20\xb3\x08\x08\x22\x04\xa4\x1b\xfb\x23\xb1\xaa\ -\xfc\x1c\xd0\x74\x9c\xec\xb5\x0f\x96\xa7\x51\x66\x11\x10\x44\x08\ -\x48\x3f\xee\x47\x62\x9d\x69\x9c\x83\x33\x3c\x3e\xdf\x7d\x65\x35\ -\xcc\x2c\x02\x82\x08\x01\xe9\xc7\xf1\x78\x8d\x57\x4c\x0f\x1b\xdf\ -\x4f\xeb\x55\x34\x87\xaf\x1a\x9b\x2b\x0d\x33\x8b\x80\x20\x42\x40\ -\x3a\x72\x3c\x61\xfc\x77\x0f\x1a\xe7\xd0\x0c\xcf\x1d\xb3\x7f\x66\ -\xb0\xc6\x99\x45\x40\x10\x21\x20\x3d\x69\xa0\xb6\xac\xdf\x6b\xba\ -\x1b\xc3\xbf\xe6\xf9\x7f\x46\x53\x03\xcd\x22\x20\x88\x10\x90\x9e\ -\x9e\x34\x52\x57\x05\xfe\x0a\x62\x78\x8a\x62\xf9\x3f\xd8\x10\x10\ -\x44\x08\x48\x57\xee\x47\x62\xb9\xbf\x58\xff\xae\x6b\x4d\xc4\xc8\ -\x00\xef\x4d\xd0\x48\xb3\x08\x08\x22\x04\xa4\x2b\xf7\x23\xb1\x5c\ -\x9f\xb9\xba\x33\xc3\x77\xba\x7d\xd2\xd0\x8c\x69\xa4\x59\x04\x04\ -\x11\x02\xd2\x97\xfb\x91\x58\x8f\x1a\xe7\xa0\xbe\x69\x1a\x46\x2e\ -\x34\x34\x67\x1a\x6a\x16\x01\x41\x84\x80\xf4\xd5\x3a\xc7\xb9\x19\ -\x3f\xb4\x62\x17\x7e\x2f\x11\x0e\x71\xca\xb1\xc6\x9a\x45\x40\x10\ -\x21\x20\x9d\x9d\x68\xb0\xae\x0e\x34\xce\x21\x19\x7e\xd8\x7f\x88\ -\x13\xc6\x34\xd6\x2c\x02\x82\x08\x01\xe9\xad\x71\x45\xe7\x66\xff\ -\x99\x85\x7f\xf1\x5b\xdb\x31\xde\xd7\xa6\xc1\x66\x11\x10\x44\x08\ -\x48\x6f\x8e\x0f\x3b\xfa\x9d\x86\x39\x22\xc3\x53\x14\xc7\xb8\xa7\ -\xa4\xc1\x66\x11\x10\x44\x08\x48\x77\xe6\x47\x62\xdd\x6a\x98\x03\ -\xd2\x0c\x8c\x0c\xb2\x98\x1a\x6d\x16\x01\x41\x84\x80\x74\xf7\x49\ -\xc3\x75\xa5\x61\x8e\xc7\xef\x89\x2b\xa3\x3c\x27\x58\xc3\xcd\x22\ -\x20\x88\x10\x90\xfe\xcc\x8f\xc4\x3a\xd1\x30\x87\xa3\xf1\x1b\x19\ -\xe5\x19\x5d\x1a\x6e\x16\x01\x41\x84\x80\xcc\x40\xe3\x75\xa5\x51\ -\x8e\xc6\xaf\xcb\xc3\x9c\x0c\xa3\xf1\x66\x11\x10\x44\x08\xc8\x0c\ -\x1c\x9f\xd9\xfd\x9b\xcf\x1a\xe6\x58\x0c\x5f\x19\x1c\xe6\x53\x99\ -\x1a\x6f\x16\x01\x41\x84\x80\xcc\xe1\x5e\x23\x36\xa5\x51\x8e\xc5\ -\xef\x33\xfe\xe3\xbc\x16\xa8\x01\x67\x11\x10\x44\x08\xc8\x1c\x0c\ -\x8f\xfc\xfb\xdd\x5e\xdf\x35\x13\xa7\x1a\xbb\x8f\x23\x8d\x6c\x00\ -\x1a\x71\x16\x01\x41\x84\x80\xcc\xe2\x8b\x86\xec\x69\x94\x37\x0f\ -\xfd\xce\xef\xcd\xd1\x03\xfd\x58\xd5\x88\xb3\x08\x08\x22\x04\x64\ -\x1e\x1a\xb2\xa9\x91\x56\xf2\x07\xbf\x63\x8e\x2f\x35\xb2\x11\x68\ -\xc8\x59\x04\x04\x11\x02\x32\x0f\xc3\x0f\x4d\xff\x66\xa0\x57\x5f\ -\xc4\xef\xae\xd2\x48\x87\x8a\x69\xc8\x59\x04\x04\x11\x02\x32\x13\ -\xef\x47\x4b\x8d\xf6\x57\x10\xbf\x53\x14\x87\x7a\x2b\x9b\xc6\x9c\ -\x45\x40\x10\x21\x20\x33\x31\x7c\x72\xc5\x6f\xee\x35\xca\x51\x34\ -\x5e\xa6\xfd\x8d\xf5\x77\x38\x0d\x3a\x8b\x80\x20\x42\x40\xe6\x62\ -\xf8\xf0\xee\xdf\x8c\xf5\x33\xc1\xef\x59\xf3\xe7\x1a\xd9\x18\x34\ -\xe8\x2c\x02\x82\x08\x01\x99\x8b\xf7\x91\x58\x63\xfd\x15\x44\x83\ -\xf6\x31\xd8\xa3\x81\x35\xea\x2c\x02\x82\x08\x01\x99\xcd\x85\x86\ -\xed\x69\xa4\x3f\x42\xfb\x3d\xa4\x4b\x03\x1b\x85\x46\x9d\x45\x40\ -\x10\x21\x20\xf3\xb1\x7b\xe1\xfe\x77\x67\x1a\xe4\x08\x34\x64\x1f\ -\xa3\x1d\x06\xa3\x61\x67\x11\x10\x44\x08\xc8\x7c\x0c\x1f\xc0\xfa\ -\x9b\x6b\x8d\xd2\x9f\xdd\x29\x8a\xc3\xbd\x0b\x5a\xe3\xce\x22\x20\ -\x88\x10\x90\x19\x59\x3f\x5a\x6a\x98\xa3\x64\x1f\x35\x60\x1f\xe3\ -\xb4\x57\x34\xee\x2c\x02\x82\x08\x01\x99\x91\xdf\xf9\x4d\xbf\xfb\ -\xaa\x51\xba\xb3\x3b\x16\x66\xb0\x3b\xe8\xcf\x34\xf0\x2c\x02\x82\ -\x08\x01\x99\xd3\xa1\x46\x6e\x69\x90\xb3\x38\xbe\x6a\xb8\x3e\x34\ -\xb0\x81\x68\xe0\x59\x04\x04\x11\x02\x32\x2b\x8d\xdc\xd3\x27\x0d\ -\xd2\x9b\xdd\xe7\x69\x9e\x34\xb0\x81\x68\xe4\x59\x04\x04\x11\x02\ -\x32\x2b\xeb\x23\xb1\x0e\x35\x48\x6b\x76\xa7\x28\x8e\xf6\x21\xfe\ -\xef\x34\xf4\x2c\x02\x82\x08\x01\x99\x97\xf5\x91\x58\x23\x3c\x51\ -\xcf\xee\x14\xc5\x53\x0d\x6c\x24\x1a\x7a\x16\x01\x41\x84\x80\xcc\ -\xcb\xef\x18\xf2\xdf\xdc\x68\x90\xc6\xec\xde\x0a\x3d\xc4\x5f\xdb\ -\xfe\xa4\xb1\x67\x11\x10\x44\x08\xc8\xcc\xfc\x9e\xc4\xfa\x1b\x8d\ -\xd1\x98\xdd\xdf\xe0\x34\xae\xb1\x68\xec\x59\x04\x04\x11\x02\x32\ -\x33\xbf\x4f\x31\xfc\xe6\x42\x83\xb4\xf5\x51\x03\xb5\xb1\xd7\x05\ -\x6f\x43\x83\xcf\x22\x20\x88\x10\x90\xb9\xdd\x6a\xf4\x96\x34\x46\ -\x5b\x8d\x97\x67\x77\x23\xde\x41\x7f\xa6\xd1\x67\x11\x10\x44\x08\ -\xc8\xec\xdc\x7e\x08\xfe\xee\x56\x63\x34\x65\xf7\x26\xb6\x11\xef\ -\xa0\x3f\xd3\xe8\xb3\x08\x08\x22\x04\x64\x76\xd6\x47\x62\x69\x8c\ -\xa6\x34\x48\x1b\x03\xbc\xeb\xe0\x4d\x1a\x7e\x16\x01\x41\x84\x80\ -\xcc\xcf\xf9\x48\xac\x13\x8d\xd1\x92\xdd\x81\xf8\x1a\xd7\x70\x34\ -\xfc\x2c\x02\x82\x08\x01\x99\x9f\xdf\x61\x1c\xbf\xd1\x18\x1d\xb5\ -\x5e\x2f\xdd\x8d\x7a\x01\x12\x10\xcc\x85\x80\x2c\xc0\xee\x3c\xf2\ -\xdf\x18\x1f\xcc\xe1\x76\x8a\xe2\x48\x8f\x50\x79\x4d\x13\xc8\x22\ -\x20\x88\x10\x90\x25\x68\x02\x8e\xee\x34\x44\x3f\x76\xcf\x04\x1e\ -\xe5\xf8\xe2\xbf\x69\x02\x59\x04\x04\x11\x02\xb2\x84\x27\xcd\xc0\ -\xd1\x5e\xdf\xc2\x25\xb9\x9d\xa2\x38\xea\x1d\xf4\x67\x9a\x41\x16\ -\x01\x41\x84\x80\x2c\xc2\xf8\x48\x2c\xd7\xbf\x82\x5c\x6b\x7c\x36\ -\x34\xae\x11\x69\x06\x59\x04\x04\x11\x02\xb2\x08\xe7\x23\xb1\x4c\ -\x97\xd5\xed\xbd\x6b\x03\x5f\x7d\x04\x04\x73\x21\x20\xcb\x30\x3e\ -\x12\xcb\xf3\x09\xdf\x57\x1a\x9d\x8b\x71\xef\xa0\x3f\xd3\x1c\xb2\ -\x08\x08\x22\x04\x64\x19\xad\x73\x9f\xd3\x95\xc6\x68\xc5\xed\x45\ -\xbf\x31\x9e\xbe\x15\xd0\x1c\xb2\x08\x08\x22\x04\x64\x21\x27\x9a\ -\x84\x21\xc7\x03\x9e\xdc\x3e\xbe\x6f\x7f\xec\xe4\x3f\x69\x12\x59\ -\x04\x04\x11\x02\xb2\x94\xc6\x95\x9e\xd3\xb9\x86\x68\xc4\x6c\xb5\ -\x7c\xdf\xec\xbc\x13\xcd\x22\x8b\x80\x20\x42\x40\x96\xe2\xf6\xa2\ -\xfe\x6f\xfc\x5e\xdf\x77\x3b\x45\x71\xec\x4b\x8f\x80\x60\x2e\x04\ -\x64\x31\xc6\x47\x62\x5d\x6b\x88\x36\x34\x2e\x17\x0f\x1a\xd6\xa8\ -\x34\x8d\x2c\x02\x82\x08\x01\x59\x8c\xdd\x27\xab\x27\x6e\x3f\x20\ -\xdd\x4e\x51\x1c\xe1\xe1\xf1\xff\xa2\x69\x64\x11\x10\x44\x08\xc8\ -\x72\x8c\x8f\xc4\x32\x7b\xce\x85\x46\xe5\xc2\xfc\xa9\x29\xef\xd3\ -\x3c\xb2\x08\x08\x22\x04\x64\x41\x9a\x87\xa1\x4b\x8d\xd0\xc3\xa1\ -\x46\x65\x62\xf0\x3b\xe8\xcf\x34\x91\x2c\x02\x82\x08\x01\x59\x90\ -\xdd\x13\xbe\x27\x4e\x1f\x73\x70\x7b\xad\xcf\xf2\x73\x32\x7b\xd1\ -\x44\xb2\x08\x08\x22\x04\x64\x49\xf7\x9a\x89\x9f\x2f\x1a\xa1\x03\ -\xb3\x4f\xed\x8f\x7e\x07\xfd\x99\x66\x92\x45\x40\x10\x21\x20\x4b\ -\xb2\x3b\x20\x70\xe2\x73\x9f\xd8\x6d\x91\x46\xbf\x83\xfe\x4c\x33\ -\xc9\x22\x20\x88\x10\x90\x45\xb9\x3d\x23\x69\xe2\x73\x58\xb9\xd9\ -\xdb\x9d\xad\x1f\xfa\xbb\x23\x4d\x25\x8b\x80\x20\x42\x40\x96\xa5\ -\xa9\x18\xd2\x00\x57\xf7\x4d\xe3\x31\xe1\x79\xd4\xe4\x9e\x34\x97\ -\x2c\x02\x82\x08\x01\x59\x96\xdb\x47\xac\x27\x2e\xa7\x3d\x99\x9d\ -\xa2\x58\xe2\x87\xa7\xe6\x92\x45\x40\x10\x21\x20\x0b\xf3\x7d\xb4\ -\x94\x06\xb8\x32\xb3\x53\x14\xbd\xde\xdf\x9c\xa5\xc9\x64\x11\x10\ -\x44\x08\xc8\xc2\x7c\x8f\xc4\xf2\xf8\xb8\x5c\xe3\x05\xd9\xdb\x81\ -\x86\x35\x36\x4d\x26\x8b\x80\x20\x42\x40\x96\xe6\xf6\xa8\xef\x89\ -\x06\xb8\x2a\xb3\xa7\xc7\x7f\xd6\xb0\x06\xa7\xd9\x64\x11\x10\x44\ -\x08\xc8\xd2\x7c\x8f\xc4\x72\xf8\x69\xa9\xa1\x98\x28\x71\x07\xfd\ -\x99\xa6\x93\x45\x40\x10\x21\x20\x8b\x73\x3b\x29\x70\xa2\x01\xae\ -\xe8\x56\x23\x31\x61\xf8\xa0\x94\x14\x4d\x27\x8b\x80\x20\x42\x40\ -\x96\x67\xf6\x32\xff\x64\xfd\xbf\x82\x68\x20\x26\x9c\x3e\x9e\xdf\ -\x44\xf3\xc9\x22\x20\x88\x10\x90\xe5\xb9\x3d\xae\xf5\x97\xd5\x4f\ -\x0d\x34\x3b\xaf\x58\xa3\x1a\x9f\xe6\x93\x45\x40\x10\x21\x20\x2b\ -\xb0\x7d\xb4\xd4\x5e\xdf\xce\xfe\x1e\x35\x0c\x13\x45\xee\xa0\x3f\ -\xd3\x84\xb2\x08\x08\x22\x04\x64\x05\xa7\x9a\x90\x9d\x95\xff\x0a\ -\xe2\x75\xd0\xcb\xbd\x46\x55\x80\x66\x94\x45\x40\x10\x21\x20\x6b\ -\x30\x7b\xe0\xc5\x64\xd5\x25\x36\xeb\xaa\xdd\x73\x7e\xf3\x34\xa3\ -\x2c\x02\x82\x08\x01\x59\x85\x66\x64\x67\xd5\xf7\xad\x7a\x7d\x42\ -\xe6\x50\xa3\xaa\x40\x53\xca\x22\x20\x88\x10\x90\x55\xd8\x1e\x89\ -\xb5\xe2\xc3\x93\xce\x35\x04\x13\x1a\x55\x09\x9a\x52\x16\x01\x41\ -\x84\x80\xac\xc3\xf5\x48\xac\x15\x5f\xf8\xf7\x7a\xda\xd6\x93\x46\ -\x55\x82\xe6\x94\x45\x40\x10\x21\x20\xeb\x30\xfb\xe3\xf6\x64\xb5\ -\xcf\xce\x79\xbd\xb9\xb9\xd0\x1d\xf4\x67\x9a\x54\x16\x01\x41\x84\ -\x80\xac\xc4\xec\xb9\xad\xbf\x9c\x69\x7c\x8b\x6b\xbc\x12\x3b\x2b\ -\x74\x07\xfd\x99\x26\x95\x45\x40\x10\x21\x20\x2b\x31\xfb\xcc\xc3\ -\x64\xa5\x1f\x9d\x5e\xa7\x28\x56\xba\x83\xfe\x4c\xb3\xca\x22\x20\ -\x88\x10\x90\xb5\x98\x1d\xfb\xf4\xcb\x83\xc6\xb7\x30\xaf\xbf\x80\ -\x68\x50\x55\x68\x56\x59\x04\x04\x11\x02\xb2\x1a\xaf\x1f\x99\x93\ -\x53\x8d\x6f\x51\x27\xfa\xcd\x3d\xec\x75\x59\x0f\x40\xd3\xca\x22\ -\x20\x88\x10\x90\xd5\xb8\x1e\x89\xb5\xca\x43\xf8\xf4\x7b\x7b\x58\ -\xed\x3e\xd0\x5c\x34\xaf\x2c\x02\x82\x08\x01\x59\x8f\xeb\x91\x58\ -\x5f\x35\xbe\x05\x79\x1d\x71\xbf\xca\xdf\xc1\xe6\xa4\x79\x65\x11\ -\x10\x44\x08\xc8\x7a\xbe\x6a\x5e\x6e\x96\x3f\xc5\xdc\xeb\x1d\x05\ -\xc5\xee\xa0\x3f\xd3\xc4\xb2\x08\x08\x22\x04\x64\x45\xae\x47\x62\ -\x3d\x6a\x7c\x8b\xf1\x3a\x45\x51\x83\x2a\x44\x13\xcb\x22\x20\x88\ -\x10\x90\x35\x69\x62\x6e\x96\xfe\x23\xb8\xd7\x5f\xc5\xea\x5d\x66\ -\x04\x04\x73\x21\x20\x6b\xf2\xfa\xf0\xc3\xe4\x40\xe3\x5b\x88\xd5\ -\x29\x8a\xe5\xee\xa0\x3f\xd3\xd4\xb2\x08\x08\x22\x04\x64\x55\xa6\ -\x47\x62\xdd\x68\x78\xcb\xb8\xd6\xef\xea\x61\x85\xb7\x10\xcc\x4e\ -\x53\xcb\x22\x20\x88\x10\x90\x55\xb9\x1e\x89\xa5\xe1\x2d\xc3\xea\ -\xdd\x68\xcb\xb6\x73\x21\x9a\x5b\x16\x01\x41\x84\x80\xac\xcb\xf4\ -\x48\xac\x0b\x0d\x6f\x09\x57\xfa\x3d\x2d\xac\xfe\x58\xf8\x59\x68\ -\x72\x59\x04\x04\x11\x02\xb2\xae\xd6\x35\x99\x8b\x86\xb7\x04\xab\ -\x97\xf1\x2a\x5e\x63\x04\x04\xb3\x21\x20\x2b\x33\x3d\x12\xeb\x44\ -\xc3\x9b\xdf\x47\xfd\x8e\x16\x2a\xde\x41\x7f\xa6\xd9\x65\x11\x10\ -\x44\x08\xc8\xda\x1a\xbf\x03\x73\xd1\xe8\xe6\x67\x35\xff\x4f\x1a\ -\x54\x31\x9a\x5d\x16\x01\x41\x84\x80\xac\xcd\xea\x16\xc0\xe4\xb3\ -\x86\x37\x37\xab\x87\xfb\x2e\x79\xeb\x67\x49\x9a\x5e\x16\x01\x41\ -\x84\x80\xac\xce\xf3\x48\xac\xa5\xee\x26\xeb\xb7\xb3\x50\xf3\x0e\ -\xfa\x33\xcd\x2f\x8b\x80\x20\x42\x40\x56\xf7\x49\xd3\x33\xb3\xcc\ -\x43\xc1\xad\x6e\x01\x5d\x69\x50\xe5\x68\x7e\x59\x04\x04\x11\x02\ -\xb2\xbe\x1b\xcd\xcf\xcb\x32\x7f\x1c\xd7\x6f\x66\x61\xa5\x47\x69\ -\x2d\x40\x13\xcc\x22\x20\x88\x10\x10\x03\x9a\x9f\x99\x25\x96\xdb\ -\xea\x38\xc9\xc5\xcf\x90\x5c\x8c\x26\x98\x45\x40\x10\x21\x20\x06\ -\xac\xde\xc9\xfa\xcb\x91\x46\x37\x23\xab\x57\xef\x6e\x35\xa8\x82\ -\x34\xc3\x2c\x02\x82\x08\x01\x71\x70\xaf\x19\x7a\x99\xff\x96\x80\ -\xd3\xe7\xf0\xcb\xde\x41\x7f\xa6\x29\x66\x11\x10\x44\x08\x88\x03\ -\xaf\xe3\x04\x7f\x9a\xfd\xaf\x20\x56\xd3\x2e\x7b\x07\xfd\x99\xa6\ -\x98\x45\x40\x10\x21\x20\x16\xbc\x9e\xa8\xf4\xd3\xdc\x3f\x38\x9c\ -\xde\xc0\xbc\xca\x93\xe0\x97\xa2\x39\x66\x11\x10\x44\x08\x88\x07\ -\x4d\xd1\xcb\xcc\x07\x7b\x7c\xd3\x6f\x63\xa1\xee\x1d\xf4\x67\x9a\ -\x63\x16\x01\x41\x84\x80\x78\xb0\xfa\x40\xf6\x2f\xe7\x1a\xdd\x3c\ -\x9c\xee\xfc\x2c\x77\xf6\xd7\x1a\x34\xc9\x2c\x02\x82\x08\x01\x31\ -\xd1\xf8\x8d\x98\xc7\xac\x7f\x05\x39\xd6\x6f\xe2\x60\x81\x77\x9c\ -\xad\x49\xb3\xcc\x22\x20\x88\x10\x10\x13\x9e\x47\x62\x9d\x6a\x74\ -\x73\x70\x4a\xe6\xbc\x7f\xd5\x5a\x9d\x66\x99\x45\x40\x10\x21\x20\ -\x2e\xac\x1e\x0c\xfe\xd3\x8c\xb7\x96\x9d\x5e\xb4\x2b\x7d\x07\xfd\ -\x99\xa6\x99\x45\x40\x10\x21\x20\x2e\x3c\x8f\xc4\x9a\xef\x09\xe1\ -\xfa\x0d\x2c\x68\x48\x65\x69\x9a\x59\x04\x04\x11\x02\x62\xe3\x42\ -\xd3\xb4\xf2\x45\x83\xeb\xce\xe9\x14\xc5\xda\x77\xd0\x9f\x69\x9e\ -\x59\x04\x04\x11\x02\xe2\xc3\xe9\xa6\xc0\x2f\x73\x3d\x62\x49\x5f\ -\xde\x41\xf1\x3b\xe8\xcf\x34\xd1\x2c\x02\x82\x08\x01\xf1\xe1\xf4\ -\xb6\xa4\x5f\x0e\x35\xb8\xce\x9c\x4e\x20\x2e\x7e\x07\xfd\x99\x26\ -\x9a\x45\x40\x10\x21\x20\x46\x2c\x8f\xc4\x3a\xd0\xe0\xba\x7a\xd4\ -\x17\x77\x30\xdb\xab\x74\x3e\x34\xd3\x2c\x02\x82\x08\x01\x31\x72\ -\xaa\x89\x5a\xb9\xd1\xe0\xba\x72\x3a\x45\x51\x43\xaa\x4c\x33\xcd\ -\x22\x20\x88\x10\x10\x27\x56\x8f\xc7\xf8\x49\x63\xeb\xc9\xa9\x94\ -\x4b\x3d\xfc\x7d\x4d\x9a\x6a\x16\x01\x41\x84\x80\x58\xd1\x4c\xad\ -\x5c\x68\x6c\x1d\x19\x9d\xa2\x58\xff\x0e\xfa\x33\xcd\x35\x8b\x80\ -\x20\x42\x40\xac\x58\x1e\x89\xa5\xb1\xf5\x73\xae\x2f\xec\xe0\x5a\ -\x63\x2a\x4d\x73\xcd\x22\x20\x88\x10\x10\x2f\x47\x9a\xab\x93\xee\ -\x1f\x93\x30\x7a\xb3\xc0\x4c\x6f\x32\x33\xa3\xc9\x66\x11\x10\x44\ -\x08\x88\x17\xab\x23\xce\x7f\xd2\xd8\x7a\x71\x7a\xbb\xb2\x86\x54\ -\x9c\x26\x9b\x45\x40\x10\x21\x20\x66\x1c\x8f\xc4\xea\x7c\x9f\xb9\ -\xf1\x9a\xeb\xe9\x49\x43\x2a\x4e\xb3\xcd\xaa\xfc\xb0\x46\xb4\x21\ -\x20\x66\x9c\x3e\x21\xf1\x8b\xc6\xd6\xc7\x47\x7d\x51\x03\xf7\x1a\ -\x52\x75\x9a\xee\xa0\x5a\x6f\x53\xe9\xcb\x6c\xd3\x83\x16\x61\x2e\ -\x04\xc4\x8d\xd3\x21\x51\x3f\x75\xfd\x83\xba\xd1\x5f\x40\xe6\x3c\ -\xad\xde\x89\xa6\x3b\x28\x02\xd2\x80\x80\x4c\xb6\x11\x10\xa7\x1f\ -\xb0\x3f\xdd\x69\x68\x3d\x9c\xe8\x6b\x1a\xd8\xc6\x1d\xf4\x67\x9a\ -\xef\xa0\x08\x48\x03\x02\x32\xd9\x48\x40\x1c\x8f\xc4\xda\xeb\xfb\ -\xfc\x6f\xfa\x8a\x0e\x34\xa2\xfa\x34\xdf\x41\x11\x90\x06\x04\x64\ -\xb2\x91\x80\x38\x7d\xcc\xee\xa7\x7e\x1f\xb7\x33\x3a\x45\xb1\x63\ -\x15\xcd\x69\xc2\x83\x22\x20\x0d\x08\xc8\x64\x2b\x01\x71\x3c\x12\ -\xab\xd7\xda\xb7\x5e\x03\x1d\xcd\xfa\xc0\x77\x2f\x9a\xf1\xa0\x08\ -\x48\x03\x02\x32\xd9\x4a\x40\x1c\x8f\xc4\xea\xf5\x7e\xa5\x2f\xfa\ -\x7a\x06\xb6\x72\x07\xfd\x99\x66\x3c\x28\x02\xd2\x80\x80\x4c\x36\ -\x13\x10\xc7\x4b\xbe\xcf\x87\xc9\xbe\xea\xab\x19\x98\xe5\x94\x61\ -\x53\x9a\xf2\xa0\x08\x48\x03\x02\x32\xd9\x4e\x40\x9e\x34\x63\x23\ -\x7d\xfe\x0a\x62\xf4\x31\x49\x8d\x68\x13\x34\xe5\x41\x11\x90\x06\ -\x04\x64\xb2\x9d\x80\x38\x1e\x89\xd5\xe3\xb9\x7d\xd7\xfa\x5a\x06\ -\xf6\xba\x72\x47\xa7\x39\x0f\x8a\x80\x34\x20\x20\x93\x0d\x05\xc4\ -\xe9\xbc\x5a\xe9\x71\xcf\xd9\xe7\xfd\x65\x1b\xba\x83\xfe\x4c\x93\ -\x1e\x14\x01\x69\x40\x40\x26\x1b\x0a\x88\xd5\x23\xfb\xa4\xfd\xa6\ -\xf3\x95\xbe\x92\x81\xaf\x1a\xd2\x36\x68\xd2\x83\x22\x20\x0d\x08\ -\xc8\x64\x4b\x01\x31\x3c\x12\xab\xfd\x52\xf4\x79\x61\x6e\x86\x87\ -\x64\x39\xd3\xac\x07\x45\x40\x1a\x10\x90\xc9\x96\x02\xe2\x78\x24\ -\x56\xeb\x9f\xda\x7d\x4e\x51\xec\x79\x34\xcb\x08\x34\xed\x41\x11\ -\x90\x06\x04\x64\xb2\xa9\x80\xb4\x7e\x67\x66\x70\xa9\x91\x65\xf9\ -\xcc\x68\x5b\x57\x12\x01\xd9\x30\x02\x32\xd9\xd6\xb6\x37\xba\x61\ -\xf0\xd3\x27\x0d\x2d\xc7\xe7\x14\xc5\x6d\xdd\x41\x7f\xa6\x79\x0f\ -\x8a\x80\x34\x20\x20\x93\x8d\xfd\xb9\xd1\xef\x48\xac\x2f\x1a\x59\ -\x8e\xbe\x88\x81\xb6\x10\x0e\x48\xf3\x1e\x14\x01\x69\x40\x40\x26\ -\x1b\x0b\xc8\x27\x4d\xdb\xc8\xa3\x86\x96\x71\xa1\xaf\xb1\xbe\x5b\ -\x8d\x68\x3b\x34\xf1\x41\x11\x90\x06\x04\x64\xb2\xb5\x57\xae\x8d\ -\x0e\xae\x95\x96\x07\x68\xe8\x4b\xac\x6f\x6b\x77\xd0\x9f\x69\xe6\ -\x83\x22\x20\x0d\x08\xc8\x64\x6b\x01\x31\xbc\xf2\x35\xb0\x04\x9f\ -\x03\x22\x37\xf8\x84\x6f\xcd\x7c\x50\x04\xa4\x01\x01\x99\x6c\x2e\ -\x20\x46\x4f\x0f\x97\xf4\xe7\x27\x7c\x5e\x8f\x9b\x7b\x47\x39\xd2\ -\xd4\x07\x45\x40\x1a\x10\x90\xc9\xe6\x02\xf2\xdf\xbd\x66\xee\x43\ -\x03\xdb\x9b\xcf\x27\xeb\x5b\xee\xe3\x8c\x4a\x53\x1f\x14\x01\x69\ -\x40\x40\x26\xdb\x0b\x88\xd1\xe1\x83\x92\xbc\x01\xed\xf3\x8c\xac\ -\xed\xdd\x41\x7f\xa6\xb9\x0f\x8a\x80\x34\x20\x20\x93\xed\x05\xc4\ -\xe9\xf9\x4b\xa2\x81\xed\xc9\xe6\x2d\xc9\x1b\xbc\x83\xfe\x4c\x93\ -\x1f\x14\x01\x69\x40\x40\x26\x1b\x0c\x88\xdf\xc5\x7f\xa2\x81\xed\ -\xe5\x9b\xfe\xe3\xf5\xf5\x79\x2e\xd6\x68\x34\xf9\x41\x11\x90\x06\ -\x04\x64\xb2\xc5\x80\xf8\x7c\x7c\xfb\x27\x0d\x6c\x2f\x36\xa7\x28\ -\xce\xbd\x9d\x4c\x69\xf6\x83\x22\x20\x0d\x08\xc8\x64\x8b\x01\x69\ -\xfd\x06\xf5\xf7\x59\x03\xdb\x83\xcf\xbb\xc9\x0e\x34\xa2\x8d\xd1\ -\xec\x07\x45\x40\x1a\x10\x90\xc9\x26\x03\x62\x77\x24\x56\xe2\x2e\ -\x82\x4d\x04\x53\xaf\xbf\x15\xa0\xe9\x0f\x8a\x80\x34\x20\x20\x93\ -\x4d\x06\xc4\xe9\x31\xe2\x3f\xec\xf5\x3d\xff\xee\xb3\xfe\xc3\xd5\ -\x1d\x69\x40\x9b\xa3\xf9\x0f\x8a\x80\x34\x20\x20\x93\x6d\x06\xc4\ -\xee\x48\xac\xbd\xff\x0a\xa2\xff\x6e\x7d\x3d\x1e\xeb\x3e\x24\xcd\ -\x7f\x50\x04\xa4\x01\x01\x99\x6c\x33\x20\x46\xa7\x10\xca\x9e\xdf\ -\x07\x9b\x47\x63\xb5\x3e\xcf\x64\x5c\x5a\x80\x41\x11\x90\x06\x04\ -\x64\xb2\xd1\x80\xd8\x6d\x80\x3d\x5f\x09\xd2\x7f\xb5\x3e\x8d\x67\ -\x83\xb4\x00\x83\x22\x20\x0d\x08\xc8\x64\xab\x01\xb1\x3b\x12\x6b\ -\xaf\xe3\x08\x6d\xce\x14\xde\xea\x1d\xf4\x67\x5a\x81\x41\x11\x90\ -\x06\x04\x64\xb2\xd5\x80\xd8\x1d\x89\x75\xaf\x71\xed\xe2\x51\xff\ -\xcd\xea\x36\x7b\x07\xfd\x99\x96\x60\x50\x04\xa4\x01\x01\x99\x6c\ -\x36\x20\x3e\x27\x49\xc9\x1e\x9f\xe7\xb6\x39\x45\x71\xb3\x77\xd0\ -\x9f\x69\x09\x06\x45\x40\x1a\x10\x90\xc9\x66\x03\x62\xf4\x30\x8d\ -\x1f\x76\x7f\xa8\xb8\x4d\xfb\xda\x1e\xc7\x3b\x38\xad\xc1\xa0\x08\ -\x48\x03\x02\x32\xd9\x6e\x40\xec\xf6\xc0\xce\x7b\xda\xe6\x14\x45\ -\x8d\x67\x9b\xb4\x06\x83\x22\x20\x0d\x08\xc8\x64\xc3\x01\xb1\xf9\ -\x2c\x9e\xec\x7a\x59\xda\x9c\xa2\x98\x38\x80\xa5\x10\x2d\xc2\xa0\ -\x08\x48\x03\x02\x32\xd9\x70\x40\x7c\x8e\x23\x94\x53\x8d\xeb\x1d\ -\x2e\xb7\xff\xf7\xb9\xed\x5f\x90\x56\x61\x50\x04\xa4\x01\x01\x99\ -\x6c\x39\x20\x3e\x07\xa2\xff\xb0\xdb\x87\xf2\x6c\x1e\x88\xd5\xfa\ -\x33\x68\x70\x5a\x85\x41\x11\x90\x06\x04\x64\xb2\xe5\x80\xd8\x1d\ -\x89\xf5\x55\xe3\xfa\x27\x97\x9b\xff\x9b\xbe\x83\xfe\x4c\xcb\x30\ -\x28\x02\xd2\x80\x80\x4c\x36\x1d\x10\x9b\xcf\x53\xc8\xa1\xc6\xf5\ -\x4f\xfa\xb5\xab\xd3\x70\x36\x4b\xcb\x30\x28\x02\xd2\x80\x80\x4c\ -\x36\x1d\x10\x9f\x23\xa5\x44\xc3\xfa\x97\x63\xfd\xd2\xb5\xed\x75\ -\x95\x56\xa4\x75\x18\x14\x01\x69\x40\x40\x26\xdb\x0e\x48\xeb\xb7\ -\xaa\xb7\x5b\x0d\xeb\x1f\x4c\xde\xc3\xbb\xf1\x3b\xe8\xcf\xb4\x10\ -\x83\x22\x20\x0d\x08\xc8\x64\xe3\x01\x71\xf9\xf3\xfc\x4f\x1a\x56\ -\xcc\xe5\x20\xfa\x1d\xdf\x31\x56\x98\x16\x62\x50\x04\xa4\x01\x01\ -\x99\x6c\x3c\x20\x3e\x1f\xca\xfb\xe1\xdd\x8f\x56\x98\x9c\x43\xbf\ -\xd3\xdd\x9a\xda\xb4\x12\x83\x22\x20\x0d\x08\xc8\x64\xeb\x01\x31\ -\x3b\x12\xeb\xdd\x07\x4b\xe9\xd7\xad\x4d\xa3\xd9\x32\xad\xc4\xa0\ -\x08\x48\x03\x02\x32\xd9\x7a\x40\xdc\x8e\xc4\x7a\xe7\x54\x77\x93\ -\xa7\xb9\xef\x75\x89\x16\xa5\xa5\x18\x14\x01\x69\x40\x40\x26\x9b\ -\x0f\x88\xd9\x56\x78\xe7\x48\x45\x8f\x4f\xae\xec\x7e\xee\x63\x61\ -\x5a\x8b\x41\x11\x90\x06\x04\x64\x42\x40\x9e\xb4\x12\x26\x3e\x69\ -\x58\x6f\x6a\xfd\x6e\x77\xb2\xd3\x07\x1e\xab\xd3\x5a\x0c\x8a\x80\ -\x34\x20\x20\x13\x02\x62\x76\x24\xd6\x8d\x46\xf5\x26\x8f\xf3\x1f\ -\xff\x39\xc4\xcd\xd0\x62\x0c\x8a\x80\x34\x20\x20\x13\x02\xf2\xdf\ -\xb9\x96\xc2\x84\x46\xf5\xa6\xc6\x2b\xab\x8f\x77\x6f\xf4\x6f\x83\ -\x56\x63\x50\x04\xa4\x01\x01\x99\x10\x10\xa3\x07\xfc\xbd\xf8\xc7\ -\xb7\xdf\xe3\x1c\xc5\xbd\xae\xcf\xba\xb4\x1a\x83\x22\x20\x0d\x08\ -\xc8\x84\x80\xb8\x1d\x89\xf5\x8f\xcf\x78\x7f\xd1\x2f\x59\x15\x77\ -\xd0\x7f\xd0\x72\x0c\x8a\x80\x34\x20\x20\x13\x02\xf2\xcc\xeb\x48\ -\xac\xf8\x16\xb5\x7e\xc1\xba\xfe\x79\x97\x7f\x43\xb4\x1c\x83\x22\ -\x20\x0d\x08\xc8\x84\x80\x7c\x67\x71\x6f\xe1\xa7\xf0\x1e\xf5\x47\ -\xfd\x82\x55\x5d\x68\x30\x9b\xa7\xf5\x18\x14\x01\x69\x40\x40\x26\ -\x04\xe4\x3b\x93\xcf\xe7\x89\x06\xf5\x17\x87\x47\x11\x72\x07\xfd\ -\x27\x2d\xc8\xa0\x08\x48\x03\x02\x32\x21\x20\x2f\xac\x8e\xc4\x0a\ -\xbe\x27\x16\xe7\x28\x72\xbd\xfc\xa4\x05\x19\x14\x01\x69\x40\x40\ -\x26\xfc\x40\x78\xf1\x55\xcb\x61\x21\xb8\x4d\x7d\xa2\x7f\xbd\x26\ -\xee\xa0\xff\xa2\x15\x19\x14\x01\x69\x40\x40\x26\x04\xe4\x87\x1b\ -\xad\x87\x85\x03\x0d\xea\x35\x87\x1b\x35\xdc\x41\xff\x45\x2b\x32\ -\x28\x02\xd2\x80\x80\x4c\x08\x88\x68\x3d\x2c\xbc\x79\xa8\xbb\xc3\ -\x87\x40\x76\x78\xe0\xd5\x66\x68\x49\x06\x45\x40\x1a\x10\x90\x09\ -\x01\x11\x8b\xb7\x38\xc9\x91\xc6\xf4\x8a\xc1\xb1\xc1\xdc\x41\xff\ -\x8d\xd6\x64\x50\x04\xa4\x01\x01\x99\x10\x90\x9f\x1c\xde\xe3\xf4\ -\xd3\x5b\x1f\x05\xd1\xbf\x5a\xd3\x3b\x67\xcd\x6f\x8b\xd6\x64\x50\ -\x04\xa4\x01\x01\x99\x10\x90\x9f\x3c\xce\x09\xf9\xe1\x8d\x0f\x5b\ -\x18\x3c\x7c\x77\xee\x7d\x33\x16\x2d\x4a\xd6\xed\xb7\x55\x69\x12\ -\x69\xfa\x32\xdb\xd4\x5a\xdf\xf7\x10\x90\x21\x59\x1c\x14\xf2\xc3\ -\x1b\xaf\x15\x19\x3c\x09\xe4\x51\x43\xc1\x77\x5a\x94\xac\xe6\x1f\ -\xe1\x28\x8b\x80\x0c\xa9\x75\x29\x7b\x3a\xd5\x98\x26\xfa\x17\x2b\ -\xe2\x0e\xfa\x2b\x5a\x95\x2c\x02\x82\x08\x01\x19\x93\xc3\x07\x2d\ -\xe4\xaf\xd7\xb0\xd6\x7f\x12\x08\x77\xd0\x5f\xd3\xb2\x64\x11\x10\ -\x44\x08\xc8\xa0\x1a\xbf\x71\x1d\xfd\xf5\xd3\x7a\xfd\xa7\x5e\xf1\ -\x13\xef\x35\x2d\x4b\x16\xcb\x89\x08\x01\x19\x94\xd1\x91\x58\x7f\ -\xbc\x86\x75\xaa\x7f\xbc\x1e\xee\xa0\xff\x41\xeb\x92\x45\x40\x10\ -\x21\x20\xa3\x32\xb8\x53\x2d\x7f\xdc\x70\xb8\xd0\x3f\x5e\x0f\x77\ -\xd0\xff\xa0\x75\xc9\x22\x20\x88\x10\x90\x51\x59\x9c\x57\xf8\xe2\ -\x8f\xd7\xb0\x56\x7f\x71\xed\x44\x03\xc1\x4f\x5a\x98\x2c\x02\x82\ -\x08\x01\x19\xd6\xfa\x7f\xd2\xff\xe9\xd5\x67\x09\x57\xff\x8c\xca\ -\x9b\x9f\x8d\xdf\x36\xad\x4c\x16\x01\x41\x84\x80\x8c\x4b\xcb\xb2\ -\xbe\x57\xaf\x61\xad\x7e\x8c\xc9\xb9\x06\x82\x5f\xb4\x32\x59\x04\ -\x04\x11\x02\x32\x2e\x9b\x23\xb1\x5e\xbd\x86\xa5\x7f\xb6\x9a\x4b\ -\x8d\x03\x13\x2d\x4d\x16\x01\x41\x84\x80\x0c\xcc\xe6\x48\xac\xdf\ -\x4e\x4e\xff\xa6\x7f\xb4\x1a\x8d\x03\xbf\xd1\xd2\x64\x11\x10\x44\ -\x08\xc8\xc0\xd6\x7f\xc3\xac\xfc\x76\xdb\x7a\xed\x43\x56\xde\x3c\ -\x5e\x7e\xeb\xb4\x36\x59\x04\x04\x11\x02\x32\x32\x83\x63\xd3\x5f\ -\xfc\x76\xdf\x5a\xff\x64\x2d\xdc\x41\x7f\x8b\x16\x27\x8b\x80\x20\ -\x42\x40\x86\xa6\x95\x59\xdd\xaf\x4f\x5e\xac\xfd\xf9\x46\xee\xa0\ -\xbf\x45\x8b\x93\x45\x40\x10\x21\x20\x43\x73\x39\x12\xeb\xd7\x75\ -\x70\xa9\x7f\xb0\x92\x2f\x1a\x06\x5e\xd1\xea\x64\x11\x10\x44\x08\ -\xc8\xd8\xd6\x3f\x77\xea\xc5\xaf\xc3\x43\xf4\xff\xd7\xa2\x51\xe0\ -\x35\xad\x4e\x16\x01\x41\x84\x80\x8c\x6d\xf5\x37\x3d\x89\x86\xb3\ -\xf2\xa3\xa4\xb8\x83\xfe\x36\x2d\x4f\x16\x01\x41\x84\x80\x0c\xce\ -\xe4\x48\x2c\xdd\x7b\x58\x77\x34\xf7\x3f\x06\x81\x3f\x69\x7d\xb2\ -\x08\x08\x22\x04\x64\x70\x8f\x5a\x9c\x95\xdd\xfc\x18\x8d\xfe\xdf\ -\x4a\xe6\x7e\x7c\xe7\xb0\xb4\x3e\x59\x04\x04\x11\x02\x32\xba\x5b\ -\xad\xce\xba\x7e\x7c\x18\x7d\xdd\xf7\x60\x1d\xbe\x8c\x01\x7f\xd3\ -\x02\x65\x11\x10\x44\x08\xc8\xf0\x1a\xbf\x85\x9d\xbc\x7c\x18\x7d\ -\xdd\xcf\xa5\xbc\xac\x06\xde\xa0\x05\xca\x22\x20\x88\x10\x90\xe1\ -\xad\x7c\xe3\x5a\x9e\xbe\x0f\x45\xff\x7b\x1d\x7b\x5d\x8b\xdb\xa2\ -\x15\xca\x22\x20\x88\x10\x90\xf1\x9d\x69\x7d\x56\xf5\xfd\x8d\xbc\ -\xe7\xfa\xdf\xab\xe0\x0e\x7a\x4c\x4b\x94\x45\x40\x10\x21\x20\xe3\ -\xf3\x38\x12\xeb\x79\x20\x37\xfa\x9f\xab\xf8\xe3\xc1\xba\xf8\x8d\ -\x96\x28\x8b\x80\x20\x42\x40\x0a\xb0\x38\x12\xeb\xf9\xa7\x8c\xfe\ -\xd7\x2a\xb8\x83\xfe\x0f\x5a\xa3\x2c\x02\x82\x08\x01\xa9\x40\x0b\ -\xb4\xaa\x9b\x75\xff\x26\xa4\x95\xc0\x5b\xb4\x46\x59\x04\x04\x11\ -\x02\x52\xc1\x93\x56\x68\x4d\x77\xab\x1e\xcc\xb5\xd7\x85\xb8\x39\ -\x5a\xa4\x2c\x02\x82\x08\x01\x29\xc1\xe1\x48\xac\x87\xc6\x6b\xa9\ -\xc5\x99\xd6\x01\x6f\xd2\x2a\x65\x11\x10\x44\x08\x48\x09\xab\xbe\ -\xff\xc9\xc0\x57\xad\x03\xde\xa4\x55\xca\x22\x20\x88\x10\x90\x1a\ -\x56\x3e\x46\x7d\x65\x3a\x48\x05\x01\x2d\x53\x16\x01\x41\x84\x80\ -\xd4\x60\x72\x24\xd6\x3a\x7e\x9c\xa3\x82\x90\xd6\x29\x8b\x80\x20\ -\x42\x40\x8a\xf0\x38\x12\x6b\x1d\x5c\x18\xef\xd0\x3a\x65\x11\x10\ -\x44\x08\x48\x15\x8d\xdf\xc9\x81\x71\x07\xfd\x3d\x5a\xa8\x2c\x02\ -\x82\x08\x01\xa9\x62\xed\xa7\x91\xaf\xe7\xe5\x1c\x47\xfc\x83\x16\ -\x2a\x8b\x80\x20\x42\x40\xca\xb0\x38\x12\x6b\x05\x17\x9a\x3f\x42\ -\x5a\xa9\x2c\x02\x82\x08\x01\x29\xe3\xab\x96\x69\x63\xb8\x83\xfe\ -\x3e\x2d\x55\x16\x01\x41\x84\x80\xd4\xb1\xea\x59\x86\xab\xe1\xaa\ -\x78\x9f\x96\x2a\x8b\x80\x20\x42\x40\x0a\xd1\x3a\x6d\x0a\x77\xd0\ -\x77\xa0\xb5\xca\x22\x20\x88\x10\x90\x42\x3e\x6a\xa1\xb6\x84\x3b\ -\xe8\x3b\xd0\x5a\x65\x11\x10\x44\x08\x48\x25\xf7\x5a\xa9\xed\xb8\ -\xd5\xcc\xf1\x2f\x5a\xac\x2c\x02\x82\x08\x01\xa9\xe4\x5a\x2b\xb5\ -\x19\xdc\x41\xdf\x89\x56\x2b\x8b\x80\x20\x42\x40\x4a\xd9\xda\x91\ -\x58\x57\x9a\x37\xfe\x49\xab\x95\x45\x40\x10\x21\x20\xa5\xb4\x2e\ -\xf1\x60\xbe\x3f\x88\x1d\xef\xd3\x72\x65\x11\x10\x44\x08\x48\x2d\ -\x6b\x3e\xd4\x69\x79\x8f\x9a\x35\xfe\x4d\xcb\x95\x45\x40\x10\x21\ -\x20\xc5\x34\x7e\x43\x87\xc2\x1d\xf4\x1d\x69\xbd\xb2\x08\x08\x22\ -\x04\xa4\x98\x0d\x1d\x89\xc5\x1d\xf4\x5d\x69\xc1\xb2\x08\x08\x22\ -\x04\xa4\x9a\x07\xad\x56\x7d\xfc\x5c\xdb\x95\x16\x2c\x8b\x85\x46\ -\x84\x80\x54\xf3\x49\xab\x55\xde\xa5\x26\x8c\x77\x69\xc5\xb2\x08\ -\x08\x22\x04\xa4\x9c\xad\x1c\x89\x75\xa0\xf9\xe2\x5d\x5a\xb1\x2c\ -\x02\x82\x08\x01\xa9\x47\xcb\x55\xdc\x89\x66\x8b\xf7\x69\xc9\xb2\ -\x08\x08\x22\x04\xa4\x9e\x4d\x1c\x89\x75\xa4\xc9\x62\x07\x5a\xb3\ -\x2c\x02\x82\x08\x01\x29\x68\x0b\x47\x62\xf1\x43\x6d\x0f\x5a\xb3\ -\x2c\xd6\x1a\x11\x02\x52\xd0\xa9\x16\xac\x30\xee\xa0\xef\x43\x8b\ -\x96\x45\x40\x10\x21\x20\x15\x1d\x6a\xc5\xea\xd2\x44\xb1\x13\x2d\ -\x5a\x16\x01\x41\x84\x80\x94\xa4\x15\x2b\xeb\xb3\xe6\x89\x9d\x68\ -\xd5\xb2\x08\x08\x22\x04\xa4\xa4\xcf\x5a\xb2\xa2\xb8\x83\xbe\x1f\ -\x2d\x5b\x16\x01\x41\x84\x80\xd4\x74\xa4\x35\xab\xe9\x5a\xb3\xc4\ -\x6e\xb4\x6c\x59\x04\x04\x11\x02\x52\xd3\x37\xad\x59\x49\x5f\x34\ -\x49\xec\x48\xeb\x96\x45\x40\x10\x21\x20\x45\x55\x3e\x12\x4b\x53\ -\xc4\xae\xb4\x6e\x59\x04\x04\x11\x02\x52\xd4\xa3\x16\xad\xa0\x27\ -\x4d\x11\xbb\xd2\xc2\x65\x11\x10\x44\x08\x48\x55\x17\x5a\xb5\x72\ -\xee\x35\x41\xec\x4c\x2b\x97\x45\x40\x10\x21\x20\x65\x35\x7e\x6b\ -\x6d\x71\x07\x7d\x6f\x5a\xb9\x2c\x02\x82\x08\x01\x29\xeb\x58\xcb\ -\x56\xcc\xa1\xa6\x87\xdd\x69\xe9\xb2\x08\x08\x22\x04\xa4\xae\x33\ -\xad\x5b\x2d\x9a\x1c\xf6\xa0\xa5\xcb\x22\x20\x88\x10\x90\xba\x4a\ -\x1e\x89\xb5\xd7\x15\x87\x1f\xb4\x76\x59\x04\x04\x11\x02\x52\x58\ -\xc1\x23\xb1\xb8\x83\x9e\xa1\xc5\xcb\x22\x20\x88\x10\x90\xca\xb4\ -\x70\x85\x9c\x6a\x66\xd8\x87\x16\x2f\x8b\x80\x20\x42\x40\x2a\x2b\ -\x77\x24\xd6\x8d\x26\x86\xbd\x68\xf5\xb2\x08\x08\x22\x04\xa4\xb4\ -\x6a\x47\x62\x69\x5a\xd8\x8f\x56\x2f\x8b\x80\x20\x42\x40\x4a\x3b\ -\xd7\xd2\x15\xb1\xd7\xe5\x86\x5f\xb4\x7c\x59\x04\x04\x11\x02\x52\ -\xdb\xa5\xd6\xae\x84\x33\x4d\x0a\x7b\xd2\xfa\x65\x11\x10\x44\x08\ -\x48\x6d\xa5\x8e\xc4\xfa\xaa\x49\x61\x4f\x5a\xbf\x2c\x02\x82\x08\ -\x01\x29\xee\x56\x8b\x57\x00\x77\xd0\xb3\xb4\x80\x59\x04\x04\x11\ -\x02\x52\x5d\xe3\x77\xd8\xc7\x9d\x26\x84\xbd\x69\x05\xb3\x08\x08\ -\x22\x04\xa4\xba\x32\x47\x62\xf1\xed\x4f\xd3\x0a\x66\x11\x10\x44\ -\x08\x48\x79\x45\x8e\xc4\xe2\x0e\x7a\x9e\x96\x30\x8b\x80\x20\x42\ -\x40\xca\xfb\xaa\xe5\x1b\x1c\x77\xd0\xf3\xb4\x84\x59\x04\x04\x11\ -\x02\x52\xdf\x8d\xd6\x6f\x68\x17\x9a\x0c\x12\xb4\x86\x59\x04\x04\ -\x11\x02\xb2\x01\x5a\xbf\x91\x71\x07\xbd\x85\x16\x31\x8b\x80\x20\ -\x42\x40\x36\xe0\xa3\x16\x70\x60\x7c\xef\x5b\x68\x11\xb3\x08\x08\ -\x22\x04\x64\x0b\x86\x3f\x12\xeb\x41\x13\x41\x8a\x56\x31\x8b\x80\ -\x20\x42\x40\xb6\x60\xf8\x23\xb1\x3e\x69\x22\x48\xd1\x2a\x66\x11\ -\x10\x44\x08\xc8\x26\x0c\x7e\x24\x16\x77\xd0\xdb\x68\x19\xb3\x08\ -\x08\x22\x04\x64\x13\x5a\x97\x7e\x5d\xdc\x41\x6f\xa4\x75\xcc\x22\ -\x20\x88\x10\x90\x6d\x38\xd1\x1a\x0e\xe9\x4a\x93\x40\x92\xd6\x31\ -\x8b\x80\x20\x42\x40\x36\xa2\xf1\x1b\xbd\x26\xee\xa0\xb7\xd2\x42\ -\x66\x11\x10\x44\x08\xc8\x46\x5c\x69\x11\x07\xf4\xa8\x29\x20\x4b\ -\x0b\x99\x45\x40\x10\x21\x20\x5b\x31\xec\x91\x58\x27\x9a\x00\xd2\ -\xb4\x92\x59\x04\x04\x11\x02\xb2\x15\x9f\xb4\x8a\xa3\xe1\x0e\x7a\ -\x3b\x2d\x65\x16\x01\x41\x84\x80\x6c\xc6\xa0\x47\x62\xf1\xd3\xab\ -\x9d\x96\x32\x8b\x6f\x01\x22\x04\x64\x3b\xb4\x8c\x63\xb9\xd4\xe0\ -\xd1\x40\x6b\x99\x45\x40\x10\x21\x20\xdb\x31\xe4\x91\x58\x07\x1a\ -\x3c\x1a\x68\x2d\xb3\x08\x08\x22\x04\x64\x43\xee\xb5\x90\x03\xe1\ -\x33\xe8\x3d\x68\x31\xb3\x08\x08\x22\x04\x64\x43\x4e\xb5\x90\x03\ -\x39\xd2\xd0\xd1\x42\x8b\x99\x45\x40\x10\x21\x20\x5b\xf2\x45\x2b\ -\x39\x10\xde\xc4\xdb\x81\xd6\x32\x8b\x80\x20\x42\x40\xb6\x64\xc4\ -\xb7\xf2\xf2\x31\xc2\x76\x5a\xca\x2c\x02\x82\x08\x01\xd9\x92\x5b\ -\xad\xe4\x48\x38\xc8\xa4\x9d\x96\x32\x8b\x80\x20\x42\x40\x36\x64\ -\xcc\xcf\x12\x72\x94\x62\x33\xad\x64\x16\x01\x41\x84\x80\x6c\xc8\ -\x98\xa7\x99\xf0\x51\xf4\x66\x5a\xc9\x2c\x02\x82\x08\x01\xd9\x8e\ -\x27\xad\xe3\x68\x78\x2b\x6f\x2b\x2d\x64\x16\x01\x41\x84\x80\x6c\ -\x46\xeb\xf2\xaf\x87\x07\xda\x36\xd2\x3a\x66\x11\x10\x44\x08\xc8\ -\x66\x3c\x68\x19\xc7\x73\xa6\x19\x20\x49\xeb\x98\x45\x40\x10\x21\ -\x20\x5b\x71\xac\x55\x1c\x11\xdf\xf9\x36\x5a\xc6\x2c\x02\x82\x08\ -\x01\xd9\x0a\x2d\xe2\x90\xb8\x8f\xde\x46\xcb\x98\x45\x40\x10\x21\ -\x20\x1b\x31\xe0\x87\xd0\x7f\x73\xa8\x59\x20\x45\xab\x98\x45\x40\ -\x10\x21\x20\xdb\x70\xae\x35\x1c\xd5\xa9\xe6\x81\x0c\x2d\x62\x16\ -\x01\x41\x84\x80\x6c\x43\xe3\xf7\x79\x75\xf7\x9a\x07\x32\xb4\x88\ -\x59\x04\x04\x11\x02\xb2\x09\x17\x5a\xc2\x71\xed\x75\xa5\xe1\x35\ -\xad\x61\x16\x01\x41\x84\x80\x6c\xc1\x57\xad\xe0\xc8\x34\x15\x24\ -\x68\x09\xb3\x08\x08\x22\x04\x64\x0b\x06\x7c\x92\xd4\x5f\xb8\x8f\ -\x9e\xa7\x25\xcc\x22\x20\x88\x10\x90\x0d\xf8\xac\x05\x1c\xdb\xb5\ -\x66\x83\xbd\x69\x05\xb3\x08\x08\x22\x04\xa4\xbe\x47\xad\xdf\xe0\ -\x78\x38\x61\x9a\x56\x30\x8b\x80\x20\x42\x40\xea\x1b\xf7\x0c\x93\ -\xd7\x3e\x6b\x3e\xd8\x97\x16\x30\x8b\x80\x20\x42\x40\xca\x1b\xf9\ -\x0c\x93\xd7\x34\x21\xec\x4b\xeb\x97\x45\x40\x10\x21\x20\xe5\x69\ -\xf5\x0a\xb8\xd4\x8c\xb0\x27\xad\x5f\x16\x01\x41\x84\x80\x54\x37\ -\xf6\x19\x26\xaf\xf1\x93\x2c\x47\xcb\x97\xc5\xb2\x23\x42\x40\x8a\ -\xfb\xa6\xc5\x2b\x81\x43\x15\x73\xb4\x7c\x59\x04\x04\x11\x02\x52\ -\x5c\xe3\x37\xd8\xcc\xad\x66\x85\xbd\x68\xf5\xb2\x08\x08\x22\x04\ -\xa4\xb6\x1b\xad\x5d\x15\x8f\x9a\x17\xf6\xa1\xc5\xcb\x22\x20\x88\ -\x10\x90\xd2\x4e\xb5\x74\x65\x3c\x68\x62\xd8\x87\x16\x2f\x8b\x80\ -\x20\x42\x40\x4a\x3b\xd2\xd2\xd5\xc1\x45\x90\xa0\xb5\xcb\x22\x20\ -\x88\x10\x90\xca\x4e\xb4\x72\x85\x70\x1f\x3d\x41\x6b\x97\x45\x40\ -\x10\x21\x20\x85\x15\x39\xc3\xe4\xb5\x0b\x4d\x0e\xbb\xd3\xd2\x65\ -\x11\x10\x44\x08\x48\x61\x67\x5a\xb8\x5a\xbe\x6a\x76\xd8\x99\x56\ -\x2e\x8b\x80\x20\x42\x40\xea\xfa\xa8\x75\x2b\xe6\x4c\xd3\xc3\xce\ -\xb4\x72\x59\x04\x04\x11\x02\x52\x97\x96\xad\x9c\xbd\x2e\x3a\x3c\ -\xd3\xc2\x65\x11\x10\x44\x08\x48\x59\x97\x5a\xb6\x7a\x34\x41\xec\ -\x4a\xeb\x96\x45\x40\x10\x21\x20\x55\x5d\x69\xd5\x0a\xe2\xe1\x84\ -\x7b\xd2\xba\x65\x11\x10\x44\x08\x48\x55\x8d\xdf\x59\x6b\xa7\x9a\ -\x23\x76\xa3\x65\xcb\x22\x20\x88\x10\x90\xa2\xaa\x9d\x61\xf2\xca\ -\xbd\x26\x89\xdd\x68\xd9\xb2\x08\x08\x22\x04\xa4\xa6\x6b\xad\x59\ -\x51\x4f\x9a\x26\x76\xa2\x55\xcb\x22\x20\x88\x10\x90\x9a\xea\x9d\ -\x61\xf2\x9a\xa6\x89\x9d\x68\xd1\xb2\x08\x08\x22\x04\xa4\xa4\x5b\ -\x2d\x59\x59\x5f\x34\x51\xec\x42\x8b\x96\x45\x40\x10\x21\x20\x15\ -\x7d\xd5\x8a\x15\x76\xae\xa9\x62\x07\x5a\xb3\x2c\x02\x82\x08\x01\ -\xa9\xa8\xe6\x19\x26\xaf\x1c\x69\xaa\xd8\x81\xd6\x2c\x8b\x80\x20\ -\x42\x40\x0a\xfa\xac\x05\x2b\xed\xb3\x26\x8b\xf7\x69\xc9\xb2\x08\ -\x08\x22\x04\xa4\x20\xad\x57\x71\x07\x9a\x2d\xde\xa5\x15\xcb\x22\ -\x20\x88\x10\x90\x7a\x1e\xb4\x5e\xc5\x5d\x6a\xba\x78\x97\x56\x2c\ -\x8b\x80\x20\x42\x40\xca\x39\xd6\x72\x95\xc7\xcf\xb5\x5d\x69\xc1\ -\xb2\x58\x68\x44\x08\x48\x39\x5a\xad\xfa\x78\x38\xe1\xae\xb4\x60\ -\x59\x04\x04\x11\x02\x52\xcd\xa1\x56\x6b\x03\x6e\x35\x65\xbc\x43\ -\xeb\x95\x45\x40\x10\x21\x20\xc5\x9c\x6b\xb1\x36\xe1\x93\x26\x8d\ -\x7f\xd3\x72\x65\x11\x10\x44\x08\x48\x31\x8d\xdf\xd0\xb1\xf0\x70\ -\xc2\xdd\x68\xb9\xb2\x08\x08\x22\x04\xa4\x96\x0b\xad\xd5\x46\x70\ -\x49\xec\x44\xab\x95\x45\x40\x10\x21\x20\xa5\x6c\xe0\x0c\x93\x57\ -\xb8\x8f\xbe\x13\xad\x56\x16\x01\x41\x84\x80\x94\x72\xaf\xa5\xda\ -\x8c\x1b\x4d\x1c\xff\xa2\xc5\xca\x22\x20\x88\x10\x90\x4a\x36\x71\ -\x86\xc9\x6b\x5f\x35\x75\xfc\x83\xd6\x2a\x8b\x80\x20\x42\x40\x0a\ -\x79\xd4\x42\x6d\x09\xf7\xd1\x77\xa0\xb5\xca\x22\x20\x88\x10\x90\ -\x42\x36\x72\x86\xc9\x6b\x7b\x5d\x82\x1b\xa5\xa5\xca\x22\x20\x88\ -\x10\x90\x3a\x3e\x6a\x9d\x36\x46\xb3\x47\x4c\x2b\x95\x45\x40\x10\ -\x21\x20\x75\x68\x99\xb6\xe6\x50\xd3\x47\x48\x2b\x95\x45\x40\x10\ -\x21\x20\x65\x7c\xd1\x32\x6d\xce\xa9\x16\x00\x11\x2d\x54\x16\x01\ -\x41\x84\x80\x54\xf1\x4d\xab\xb4\x3d\xf7\x5a\x01\x44\xb4\x50\x59\ -\x04\x04\x11\x02\x52\x45\xe3\x77\x72\x64\x3c\x9c\xf0\x1d\x5a\xa7\ -\x2c\x02\x82\x08\x01\x29\xe2\x46\x8b\xb4\x49\x5a\x03\x04\xb4\x4c\ -\x59\x04\x04\x11\x02\x52\xc3\xa9\xd6\x68\x9b\xbe\x68\x15\xf0\x36\ -\x2d\x53\x16\x01\x41\x84\x80\xd4\x70\xa4\x35\xda\xa8\x73\x2d\x03\ -\xde\xa4\x55\xca\x22\x20\x88\x10\x90\x12\x4e\xb4\x44\x5b\x75\xa4\ -\x75\xc0\x9b\xb4\x4a\x59\x04\x04\x11\x02\x52\xc1\x16\xcf\x30\x79\ -\xed\x44\x2b\x81\xb7\x68\x91\xb2\x8e\xce\x56\xd5\xfa\x36\x6d\x7d\ -\x99\x6d\x9a\xfb\x53\x52\x04\xa4\x82\x33\xad\xd0\x4a\x1e\x0d\x1e\ -\xa3\xfb\xa8\xa5\xc0\x1b\xb4\x46\x83\xba\xd6\x2c\xb2\xf4\x65\xb6\ -\xe9\x41\x8b\x30\x17\x02\x52\xc0\xca\x67\x98\x9c\xfd\x77\xac\xff\ -\xb5\xa2\xb9\x37\xca\xd0\xb4\x46\x83\x22\x20\x0d\x08\xc8\x84\x80\ -\x04\xb4\x3e\x6b\x39\xb1\x78\x09\xed\x4a\x8b\x81\xbf\x69\x89\x06\ -\x45\x40\x1a\x10\x90\x09\x01\x79\xdb\xa5\xd6\x67\x2d\xcf\x1b\x5c\ -\xff\x6b\x4d\x3c\x9c\x30\xa6\x25\x1a\x14\x01\x69\x40\x40\x26\x04\ -\xe4\x4d\x57\x5a\x9e\xd5\x3c\x8f\x61\xed\x86\x7d\x77\xfb\x63\x39\ -\xf0\x37\xad\xd0\xa0\x08\x48\x03\x02\x32\x21\x20\x6f\x6a\xfc\x16\ -\x36\xfb\x7e\x89\x5a\x3c\x0a\xf1\xd3\x8f\xf5\xc0\x5f\xb4\x40\x83\ -\x22\x20\x0d\x08\xc8\x84\x80\xbc\x65\xf5\x33\x4c\xbe\x9f\x44\x75\ -\xad\xff\xbd\x2a\x1e\x4e\x18\xd1\x02\x0d\x8a\x80\x34\x20\x20\x13\ -\x02\xf2\x86\xf5\x7f\x74\xbf\xbc\x4d\x5f\xff\x7b\x5d\x5c\x20\x01\ -\xad\xcf\xa0\x08\x48\x03\x02\x32\xe1\xe7\xc3\x1b\xd6\x3f\xc3\xe4\ -\x65\x18\xf7\xfa\x3f\xab\xe2\x3e\x7a\x40\xeb\x33\x28\x02\xd2\x80\ -\x80\x4c\x08\xc8\xdf\x6e\xb5\x36\xeb\xf9\xf1\x51\xd7\x0b\xfd\xbf\ -\x75\xdd\xbc\x8c\x05\x7f\xd2\xf2\x0c\x8a\x80\x34\x20\x20\x13\x02\ -\xf2\x97\xaf\x5a\x9a\x15\xfd\x38\xc7\x70\xf5\xb7\x82\xfd\xc0\xc3\ -\x09\xdf\xa4\xd5\x19\x14\x01\x69\x40\x40\x26\x04\xe4\x2f\x2b\x9f\ -\x61\xf2\x9d\x46\xa2\xff\xb7\x32\x1e\x4e\xf8\x26\xad\xce\xa0\x08\ -\x48\x03\x02\x32\x21\x20\x7f\x7a\xd2\xca\xac\xe8\x52\x43\x69\xbc\ -\x90\x7a\x79\xd2\x70\xf0\x3b\x2d\xce\xa0\x08\x48\x03\x02\x32\x21\ -\x20\x7f\xd2\xc2\xac\xe9\xe7\x37\xc5\xe0\x3c\xc5\x17\x1a\x0e\x7e\ -\xa7\xb5\x19\x14\x01\x69\x40\x40\x26\x04\xe4\x0f\x0e\x9f\xff\xd6\ -\x50\x1c\xce\x53\x7c\xc1\xc3\x09\xdf\xa0\xb5\x19\x14\x01\x69\x40\ -\x40\x26\x04\xe4\x35\x87\x9f\xd9\xd3\x87\xf7\xf4\x0f\x56\xd7\xfa\ -\xe3\xa6\x22\x2d\xcd\xa0\x08\x48\x03\x02\x32\x21\x20\xaf\x39\xdc\ -\x76\x98\xee\x39\xb8\x3c\x54\x97\xfb\xe8\x7f\xd3\xd2\x0c\x8a\x80\ -\x34\x20\x20\x13\x02\xf2\x8a\xc5\x5d\x87\x03\x0d\xc6\xe5\x93\x20\ -\xcf\xbe\x1f\xad\x82\x57\xb4\x32\x83\x22\x20\x0d\x08\xc8\x84\x80\ -\xfc\xee\x5c\xab\xb2\xaa\xdf\x8e\x9f\xb2\x18\xcf\x0b\x0d\x08\xbf\ -\x68\x61\x06\x45\x40\x1a\x10\x90\x09\x01\xf9\x9d\xc3\x0b\x58\xaf\ -\xbe\xff\xfa\x47\xeb\xfb\xf9\xce\x62\xfc\xa4\x85\x19\x14\x01\x69\ -\x40\x40\x26\x04\xe4\x37\x1e\xaf\x18\x69\x30\x2f\x0c\x3e\xd4\x28\ -\xdf\x34\x22\x88\xd6\x65\x50\x04\xa4\x01\x01\x99\x10\x90\x89\xc1\ -\x19\x26\xcf\x5e\x5d\x9d\x16\xcf\x04\x79\x71\xa4\x11\x41\xb4\x2e\ -\x83\x22\x20\x0d\x08\xc8\x84\x80\x4c\x2c\x4e\xbf\x7d\xfd\x1d\xf1\ -\x68\xda\x8b\x13\x0d\x09\x3f\x68\x59\x06\x45\x40\x1a\x10\x90\x09\ -\x01\xf9\xc5\xe4\x4f\xfb\x1a\x8d\xe8\x1f\x3a\x78\xd4\x90\xf0\x42\ -\xab\x32\x28\x02\xd2\x80\x80\x4c\x08\xc8\x4f\x8f\x5a\x91\x95\xfd\ -\xf1\xa9\x6f\x97\xd3\x4c\x9e\xcd\xbd\x6d\x06\xa3\x55\x19\x14\x01\ -\x69\x40\x40\x26\x04\xe4\xa7\x07\xad\xc8\xca\xfe\xb8\x59\x6d\x72\ -\xa4\xfb\x8b\x2b\x8d\x09\xdf\x69\x51\x06\x45\x40\x1a\x10\x90\x09\ -\x01\x91\x8f\x5a\x90\xb5\x69\x38\xbf\xe8\x1f\x3b\xe0\xe1\x84\xbf\ -\xd3\xa2\x0c\x8a\x80\x34\x20\x20\x13\x02\x22\x5a\x8f\xb5\xfd\xf5\ -\xfc\x3f\x93\xbf\x18\xbd\xb8\xd0\x98\xf0\x4c\x6b\x32\x28\x02\xd2\ -\x80\x80\x4c\x08\xc8\x0f\x5f\xb4\x1e\x6b\xfb\x6b\x63\xbb\x9c\xc8\ -\xfb\xe2\xab\x06\x05\x02\xb2\x61\x04\x64\x42\x40\x5e\x7c\xd3\x72\ -\xac\xed\x8d\x57\x89\xf4\x6f\x2c\xfc\x76\xca\xca\xe6\x69\x49\x06\ -\x45\x40\x1a\x10\x90\x09\x01\x79\xd1\xf8\x2d\xeb\xe6\x8d\x0f\x5b\ -\x38\x3c\xa0\xe4\x97\xbd\xae\xcd\xda\xb4\x22\x83\x22\x20\x0d\x08\ -\xc8\x84\x80\x7c\x77\xa3\xd5\x58\xdd\x1b\x9f\xb5\x70\x7a\x1f\x16\ -\x87\x2a\x4e\xb4\x20\x83\x22\x20\x0d\x08\xc8\x84\x80\x3c\x3b\xd5\ -\x62\xac\xee\xcd\x97\x88\xf4\xef\x3c\xfc\x75\x93\x7f\xb3\xb4\x20\ -\x83\x22\x20\x0d\x08\xc8\x84\x80\x3c\x73\x79\x6e\xd3\xdb\xdf\x0d\ -\x9b\xbf\x1e\xbd\x38\xd5\xa8\x36\x4f\xeb\x31\x28\x02\xd2\x80\x80\ -\x4c\x08\xc8\x7f\xff\x9d\x68\x2d\xd6\xa7\x01\xbd\x66\x74\x1e\xd6\ -\x33\x1e\x4e\x28\x5a\x8f\x41\x11\x90\x06\x04\x64\x42\x40\x5c\xce\ -\x30\x79\x76\xa8\x11\xfd\xc1\xe3\x90\xc7\x9f\xa6\x07\xee\x6e\x9b\ -\x96\x63\x50\x04\xa4\x01\x01\x99\x10\x10\xa3\x67\x6e\x04\x2f\x0f\ -\x59\x7d\x14\x84\xfb\xe8\xa2\xd5\x18\x14\x01\x69\x40\x40\x26\x04\ -\xc4\xe5\x0c\x93\x7f\x1c\x15\xd2\x78\x41\x75\xf6\xc7\x71\x8f\x5b\ -\xa5\xd5\x18\x14\x01\x69\x40\x40\x26\x04\x44\x0b\x61\x20\x7c\xe2\ -\xc6\x93\x7e\x81\x89\xd6\x1f\x3e\x35\x68\x31\x06\x45\x40\x1a\x10\ -\x90\xc9\xe6\x03\x62\xf4\x39\xbd\x03\x0d\xe9\x6f\xfa\x05\x26\x78\ -\x38\xe1\x77\x5a\x8c\x41\x11\x90\x06\x04\x64\xb2\xf5\x80\x18\x7d\ -\x4c\xef\x1f\x97\xa5\xcf\xcb\x6c\x2f\x78\x38\xe1\x33\xad\xc5\xa0\ -\x08\x48\x03\x02\x32\xd9\x7a\x40\x8c\x6e\x2f\xfc\xeb\x71\x1b\x46\ -\xc3\xfc\x2e\xfe\xbb\xd2\x76\x68\x29\x06\x45\x40\x1a\x10\x90\xc9\ -\xc6\x03\x62\xf4\x21\xbd\x7f\xbe\x30\x64\xf6\x46\xac\x4b\x0d\x6b\ -\xcb\xb4\x14\x83\x22\x20\x0d\x08\xc8\x64\xdb\x01\xb9\xd6\x2a\x38\ -\xf8\xe3\x51\x84\x7f\xf0\xfa\x2c\xc8\x3b\x83\xdd\x04\xad\xc4\xa0\ -\x08\x48\x03\x02\x32\xd9\x76\x40\x6c\xce\x30\x79\xf7\xa4\x74\x97\ -\xf3\xe6\x85\x87\x13\x12\x90\xed\x22\x20\x93\x4d\x07\xe4\x56\x8b\ -\xe0\xe0\xbd\x33\xa6\x7c\x3e\xee\xf8\xe2\x56\xc3\xda\x2e\x2d\xc4\ -\xa0\x08\x48\x03\x02\x32\xd9\x72\x40\x3e\x69\x0d\x1c\xbc\x7b\x57\ -\xc1\xe6\xc4\x60\x79\xe3\xe0\xf9\x6d\xd1\x3a\x0c\x8a\x80\x34\x20\ -\x20\x93\x2d\x07\xc4\xe9\x0f\xf5\x9f\x34\xa6\x98\xd5\x83\xa5\xe6\ -\xdf\x44\xf6\xb4\x0e\x83\x22\x20\x0d\x08\xc8\x64\xc3\x01\x71\xfa\ -\x7c\x77\x70\x8c\xe2\xef\x9c\xfe\xbe\xf4\xdd\xb6\xef\x9e\x11\x90\ -\x0d\x23\x20\x93\x0d\xff\x18\xd0\x0a\x58\xd0\x90\xfe\xe9\x50\xbf\ -\xd6\xc4\xd6\xef\xa3\x6b\x19\x06\x45\x40\x1a\x10\x90\xc9\x76\x03\ -\xe2\xf4\x92\xd0\x6e\xb7\xa4\xf5\x8b\x5d\x5c\x68\x58\x1b\xa5\x55\ -\x18\x14\x01\x69\x40\x40\x26\x9b\x0d\x88\xd5\x47\xf3\x34\xa6\x77\ -\x38\xbd\x69\xec\xbb\xaf\x1a\xd7\x36\x69\x11\x06\x45\x40\x1a\x10\ -\x90\xc9\x66\x03\xd2\xf8\x4d\xea\xea\xb3\xc6\xf4\x1e\xfd\x72\x17\ -\xef\x7c\x74\xa5\x38\x2d\xc2\xa0\x08\x48\x03\x02\x32\xd9\x6a\x40\ -\x9c\x6e\x28\xec\x7c\x37\xe1\xb3\xfe\x03\x17\x7b\x5d\xa9\xd5\x68\ -\x0d\x06\x45\x40\x1a\x10\x90\xc9\x46\x03\x72\xae\xe9\x5b\xd8\xfd\ -\x7b\xa0\xff\xc0\x86\x86\xb5\x49\x5a\x82\x41\x11\x90\x06\x04\x64\ -\xb2\xd1\x80\x18\x9d\x61\xb2\xcf\xe3\x35\xcc\x8e\x75\xdf\xe5\xdd\ -\xc7\x65\x69\x09\x06\x45\x40\x1a\x10\x90\xc9\x36\x03\x62\x75\x3b\ -\x7a\x9f\x83\x09\x9d\xee\xdc\x7c\xd7\xfa\x73\x68\x60\x5a\x81\x41\ -\x11\x90\x06\x04\x64\xb2\xc9\x80\x7c\xd5\xe4\x2d\xec\x75\x2b\xda\ -\xec\x58\xf7\x0f\xf7\x1a\xd7\x06\x69\x05\x06\x45\x40\x1a\x10\x90\ -\xc9\x26\x03\x62\x75\x36\xfa\x7b\xa7\x28\xbe\x66\x76\xac\xfb\xce\ -\x6f\x20\xab\x47\x0b\x30\x28\x02\xd2\x80\x80\x4c\xb6\x18\x10\xab\ -\x37\x33\xed\xf9\x6c\x26\xb3\x63\xdd\x37\x7c\x1f\x5d\xf3\x1f\x14\ -\x01\x69\x40\x40\x26\x1b\x0c\x48\xeb\x92\xf5\xf5\xfe\x29\x8a\xaf\ -\x99\x1d\xeb\xfe\xe1\x8b\xc6\xb5\x39\x9a\xff\xa0\x08\x48\x03\x02\ -\x32\xd9\x60\x40\x1e\x34\x75\x0b\x7b\xbf\x8f\xc9\xed\x58\xf7\x0f\ -\xe7\x1a\xd8\xd6\x68\xfa\x83\x22\x20\x0d\x08\xc8\x64\x7b\x01\xf1\ -\xba\x0f\xad\x41\xed\xc1\xec\x58\xf7\x7d\xde\x85\x5c\x8a\xa6\x9f\ -\x75\x79\xb1\xaa\xd6\xc7\xb9\xe8\xcb\x6c\xd3\x93\x16\x61\x2e\x04\ -\xc4\x99\x26\xee\x21\xf1\x60\x3f\xb7\x63\xdd\x3f\x9c\x68\x60\x1b\ -\xa3\xd9\x67\xf1\x54\x79\x44\x08\x88\xb1\x2f\x9a\xb8\x07\x0d\x6a\ -\x2f\x66\xc7\xba\x6f\xf5\xe1\x84\x9a\x7c\x16\x01\x41\x84\x80\xf8\ -\xf2\x7a\x17\x53\xee\x4d\xb0\xfa\x8f\x6d\xec\xf9\x46\xb2\x22\x34\ -\xf9\x2c\x02\x82\x08\x01\xf1\xd5\xf8\xbd\xe9\x2b\xf9\x4c\x26\xb7\ -\x63\xdd\x3f\x5c\x69\x60\x9b\xa2\xb9\x67\x11\x10\x44\x08\x88\xad\ -\x1b\x4d\xdb\xc3\x5e\xdf\xe9\xdf\xe8\x3f\xb7\xb1\xc9\x87\x13\x6a\ -\xee\x59\x04\x04\x11\x02\xe2\xca\xeb\x3d\xb0\xe9\x73\x40\xdc\x8e\ -\x75\xdf\xe4\xc3\x09\x35\xf5\x2c\x02\x82\x08\x01\x71\xe5\x75\x10\ -\x48\xfe\x67\x88\xbe\x80\x8f\x7d\x3f\x0e\x59\x80\x66\x9e\x45\x40\ -\x10\x21\x20\xa6\x4e\x34\x69\x0f\x0d\x0f\xf4\x73\x3b\xd6\x7d\x8b\ -\x0f\x27\xd4\xcc\xb3\x08\x08\x22\x04\xc4\xd3\xa3\xe6\x6c\xa2\xe5\ -\xc3\xc0\x8d\x97\x58\x7f\x1b\xbb\x97\xf6\x4c\x13\xcf\x22\x20\x88\ -\x10\x10\x4f\x5e\xc7\x48\x35\xbd\xf9\xd5\xed\x58\xf7\x0d\xde\x47\ -\xd7\xc4\xb3\x08\x08\x22\x04\xc4\x92\xd9\xeb\x3e\x6d\xb7\x0d\xdc\ -\x8e\x75\xff\x70\xa3\x81\x6d\x86\xe6\x9d\x45\x40\x10\x21\x20\x96\ -\x34\x63\x13\x8d\x3f\x70\xed\x8e\x75\xff\xf0\x55\x23\xdb\x0a\x4d\ -\x3b\x8b\x80\x20\x42\x40\x1c\x99\x1d\x42\xa8\x51\xa5\xb9\x1d\xeb\ -\xbe\xb9\xfb\xe8\x9a\x76\x16\x01\x41\x84\x80\x18\xba\xd2\x84\x4d\ -\x24\x4e\x51\x7c\xcd\xee\x58\xf7\xfd\xae\xdb\xf1\x69\xd6\x59\x04\ -\x04\x11\x02\x62\xa8\xf1\x9b\xd2\x9b\x46\xd5\xc0\xed\x58\xf7\xad\ -\x3d\x9c\x50\x93\xce\x22\x20\x88\x10\x10\x3f\x5e\x67\x98\xf4\x78\ -\x94\xb8\xdd\xb1\xee\xfb\x3f\x1c\x6b\x68\x9a\x74\x16\x01\x41\x84\ -\x80\xd8\xb9\xd6\x74\x4d\x74\x79\xd3\xab\xdd\xb1\xee\xcd\x8f\xb9\ -\x1b\x8a\xe6\x9c\x45\x40\x10\x21\x20\x76\x8e\x34\x5d\x13\x7d\x56\ -\x5d\x5f\xcc\xc7\xa6\x1e\x4e\xa8\x39\x67\x11\x10\x44\x08\x88\x1b\ -\xb3\x03\xd0\xd3\xa7\x28\xbe\x66\x77\xac\x7b\x8f\x57\xe6\x86\xa1\ -\x29\x67\x11\x10\x44\x08\x88\x19\xb7\xdb\x05\xbd\x7e\x78\xe8\xcb\ -\x19\xd1\xc0\xb6\x40\x33\xce\x22\x20\x88\x10\x10\x33\x66\x9f\x99\ -\xe8\xf6\x89\x09\xbb\x63\xdd\xb7\xf4\x70\x42\xcd\x38\x8b\x80\x20\ -\x42\x40\xbc\x3c\x69\xae\x2e\x4e\x35\xae\x76\xfa\x82\x46\xb6\xf3\ -\x73\x51\x13\xce\x22\x20\x88\x10\x10\x2f\x9a\xaa\x8b\x8e\x7f\x4a\ -\xb7\x3b\xd6\x7d\x43\xf7\xd1\x35\xe1\x2c\x02\x82\x08\x01\xb1\xf2\ -\xa0\xa9\xba\xe8\xf9\xf0\xa5\xc6\x4b\x6d\x06\x27\x1a\x59\x79\x9a\ -\x6f\x16\x01\x41\x84\x80\x38\x71\x3b\xf9\xbc\xeb\xb1\xb5\x76\xc7\ -\xba\x7f\xf8\xf0\xa8\xa1\x55\xa7\xe9\x66\x11\x10\x44\x08\x88\x13\ -\x4d\xd4\x86\x86\xd5\x89\xdd\xb1\xee\x1f\x1e\x34\xb2\xea\x34\xdd\ -\x2c\x02\x82\x08\x01\x31\xe2\xf6\x79\xed\xe6\x53\x14\x5f\xf3\x3b\ -\xd6\xfd\xc3\x95\x86\x56\x9c\x66\x9b\x45\x40\x10\x21\x20\x3e\xce\ -\x35\x4f\x1b\x1a\x57\x37\x76\xc7\xba\x6f\xe5\xe1\x84\x9a\x6d\x16\ -\x01\x41\x84\x80\xf8\x30\x3b\xc3\xa4\xff\x67\xb5\xfd\x8e\x75\xff\ -\x70\xa1\xa1\xd5\xa6\xc9\x66\x11\x10\x44\x08\x88\x0d\xb7\xd3\x3e\ -\x66\xf8\xd3\xb9\xdf\xb1\xee\x5d\xdf\x67\x66\x4b\x73\xcd\x22\x20\ -\x88\x10\x10\x17\x5f\x35\x4b\x1b\x33\x2c\xb7\xdf\xb1\xee\xdb\x78\ -\x38\xa1\xe6\x9a\x45\x40\x10\x21\x20\x2e\xdc\xde\xa3\x34\xcb\xc7\ -\xec\xfc\x8e\x75\x2f\xff\xc2\xe8\x77\x9a\x6a\x16\x01\x41\x84\x80\ -\x98\xb0\x3b\x2b\xea\x5c\x03\xeb\x4b\x5f\xdc\xc8\x16\xee\xa3\x6b\ -\xaa\x59\x04\x04\x11\x02\xe2\xe1\x51\x73\xb4\x31\xd3\x4b\x3b\x7e\ -\xc7\xba\x6f\xe1\xe1\x84\x9a\x69\x16\x01\x41\x84\x80\x78\x70\x3b\ -\xc3\xa4\xe3\x29\x8a\xaf\xe9\xcb\x3b\x99\x6b\xaa\x3e\x34\xd1\x2c\ -\x02\x82\x08\x01\xb1\x60\x77\xcc\xc7\x6c\x67\x9d\xfb\x1d\xeb\xde\ -\xeb\x99\x59\xc6\x34\xd1\x2c\x02\x82\x08\x01\xb1\xa0\x19\xfa\x98\ -\xef\x94\x28\xfd\x06\x4e\xf6\xba\x8a\x47\xa4\x79\x66\x11\x10\x44\ -\x08\x88\x83\x2f\x9a\xa1\x8d\x19\xef\x0b\xf8\x1d\xeb\x5e\xff\xe1\ -\x84\x9a\x66\x16\x01\x41\x84\x80\x18\xb0\x3b\xc3\x64\xd6\x9f\xa8\ -\x8d\x97\xdc\x1c\xaa\xdf\x47\xd7\x34\xb3\x08\x08\x22\x04\xc4\x80\ -\xdd\x8f\xd4\xce\xa7\x28\xbe\x66\x78\xac\xfb\x87\x6b\x8d\xad\x28\ -\xcd\x32\x8b\x80\x20\x42\x40\xd6\x77\xa1\xf9\xf9\xd0\xc0\x66\xe2\ -\x77\xac\x7b\xf5\x87\x13\x6a\x96\x59\x04\x04\x11\x02\xb2\x3a\xbf\ -\x23\x06\x9f\x34\xb2\x99\x18\x1e\xeb\xde\xff\xe0\x48\x2b\x9a\x64\ -\x16\x01\x41\x84\x80\xac\xce\xee\x0f\xe4\xb3\x7f\x36\xdb\xef\x58\ -\xf7\xe2\xf7\xd1\x35\xc7\x2c\x02\x82\x08\x01\x59\x9b\xdf\x07\x23\ -\x66\x5f\x67\xc3\x63\xdd\xe7\xfb\xe0\x8b\x03\xcd\x31\x8b\x80\x20\ -\x42\x40\x56\x66\x77\x86\xc9\x12\x9f\xab\x33\x3c\xd6\xbd\xf4\x4f\ -\x49\x4d\x31\x8b\x80\x20\x42\x40\x56\xe6\xf7\x72\xce\x02\x3f\x2e\ -\x0c\x8f\x75\x2f\x7d\xa8\xa2\xa6\x98\x45\x40\x10\x21\x20\xeb\xf2\ -\xfb\x58\xdd\x22\x0f\xc8\x30\x3c\xd6\x7d\xde\xf7\x2e\xaf\x4b\x33\ -\xcc\x22\x20\x88\x10\x90\x75\x69\x6a\x46\x96\x39\x5a\x50\xbf\x99\ -\x95\xf9\x8e\x6f\x59\x9b\x26\x98\x45\x40\x10\x21\x20\xab\xf2\xbb\ -\x19\xb0\xd0\xcd\x64\xc3\x63\xdd\x3f\x3c\x68\x6c\xf5\x68\x82\x59\ -\x04\x04\x11\x02\xb2\xa6\x2b\xcd\xcc\xc8\x52\x7f\x0c\xd7\x6f\x67\ -\xe5\x4a\x63\x2b\x47\xf3\xcb\x22\x20\x88\x10\x90\x35\x35\xae\xfe\ -\x0c\x6e\x34\xb2\xd9\x19\x1e\xeb\x5e\xf7\x3e\xba\xe6\x97\x45\x40\ -\x10\x21\x20\x2b\x32\xbc\x95\xac\x91\x2d\x40\xbf\xa1\x95\x0b\x8d\ -\xad\x1a\x4d\x2f\x8b\x80\x20\x42\x40\xd6\x63\xf8\x79\xba\x05\xdf\ -\x89\xe4\x78\xac\xfb\x87\xaf\x1a\x5c\x31\x9a\x5d\x16\x01\x41\x84\ -\x80\xac\xe7\x48\xf3\x32\xa2\x91\x2d\xc2\xef\xf5\xbb\x85\xde\xc3\ -\xbc\x3c\xcd\x2e\x8b\x80\x20\x42\x40\x56\x73\xa2\x69\x19\x99\xf9\ -\x14\xc5\xd7\x1c\x8f\x75\xdf\xef\x82\x1e\x86\x26\x97\x45\x40\x10\ -\x21\x20\x6b\x31\xfc\x34\xf6\xc2\x37\x91\x0d\x8f\x75\x2f\x7a\xa8\ -\xa2\xe6\x96\x45\x40\x10\x21\x20\x6b\x31\x3c\x92\x76\xe1\x05\x76\ -\x3c\xd6\xbd\xe6\xc3\x09\x35\xb7\x2c\x02\x82\x08\x01\x59\xc9\x93\ -\x26\x65\x64\x81\x53\x14\x5f\x73\x3c\xd6\x7d\xa1\x4f\xe2\x2f\x4b\ -\x53\xcb\x22\x20\x88\x10\x90\x95\x68\x4e\x4e\x16\xff\x39\xe1\x78\ -\xac\xfb\xf2\x19\x5d\x80\xa6\x96\x45\x40\x10\x21\x20\xeb\x78\xd0\ -\x9c\x8c\xac\xf0\x0e\x24\xc7\x63\xdd\x97\x7d\x27\xc1\x32\x34\xb3\ -\x2c\x02\x82\x08\x01\x59\x85\xe1\x19\x26\x6b\xbc\x76\xe3\x78\xac\ -\x7b\xc5\xfb\xe8\x9a\x58\x16\x01\x41\x84\x80\xac\x42\x33\x72\xf2\ -\x45\x43\x5b\x94\xe3\xb1\xee\xeb\xac\xc4\xac\x34\xb1\x2c\x02\x82\ -\x08\x01\x59\x83\xe3\xcf\xcd\x75\x0e\x33\xd7\x6f\xee\xe5\x5c\x83\ -\x2b\x43\xf3\xca\x22\x20\x88\x10\x90\x15\x9c\x6b\x42\x4e\x16\x3b\ -\x45\xf1\x35\xc7\x63\xdd\x3f\x1c\x69\x70\x65\x68\x5e\x59\x04\x04\ -\x11\x02\xb2\x02\xc3\x33\x4c\x56\x7b\xe1\x5f\xbf\xbd\x97\xcf\x1a\ -\x5c\x15\x9a\x56\x16\x01\x41\x84\x80\x2c\xef\x42\xf3\x71\x72\xa2\ -\xb1\x2d\xce\xf1\x58\xf7\x0f\x1f\x0e\x34\xba\x22\x34\xab\x2c\x02\ -\x82\x08\x01\x59\xdc\x57\x4d\xc7\x8a\xc6\xb6\x02\x0d\xc0\xcb\x42\ -\xcf\x65\x5c\x8a\x66\x95\x45\x40\x10\x21\x20\x8b\x73\x3c\x02\x6a\ -\xc5\xcf\x3e\x58\x1e\xeb\x5e\xec\x67\xa6\x26\x95\x45\x40\x10\x21\ -\x20\x4b\xe3\x51\x7c\x7f\x68\xbc\x04\xe7\x51\xeb\xe1\x84\x9a\x54\ -\x16\x01\x41\x84\x80\x2c\xac\x75\x11\x66\xb1\xea\xca\x5a\x1e\xeb\ -\xbe\xe4\xa3\xb5\xe6\xa7\x39\x65\x11\x10\x44\x08\xc8\xc2\x0c\xcf\ -\x30\x59\xfb\xf8\x27\xcb\x63\xdd\x3f\x7c\xd2\xe8\x2a\xd0\x94\xb2\ -\x08\x08\x22\x04\x64\x59\x96\x7f\xdc\x5e\xf9\x83\x73\x96\xc7\xba\ -\x97\x7a\x38\xa1\xa6\x94\x45\x40\x10\x21\x20\xcb\xd2\x54\xac\x3c\ -\x68\x6c\xab\xb1\x3c\xd6\xbd\xc6\x5f\x78\x7f\xd0\x8c\xb2\x08\x08\ -\x22\x04\x64\x51\x5f\x34\x15\x2b\xab\x3f\x01\xc3\xf2\x58\xf7\x4a\ -\xf7\xd1\x35\xa3\x2c\x02\x82\x08\x01\x59\x92\xe3\x19\x26\x0e\x67\ -\x07\x5a\x1e\xeb\xbe\xd6\xe9\x2e\x33\xd0\x84\xb2\x08\x08\x22\x04\ -\x64\x49\x8d\xab\x3d\x8f\x75\x4e\x51\x7c\xc5\xf3\x58\xf7\x0f\x5f\ -\x35\xbc\xe1\x69\x3e\x59\x04\x04\x11\x02\xb2\x20\xc7\x33\x4c\x3c\ -\xfe\x9c\x6d\x79\xac\x7b\x9d\xfb\xe8\x9a\x4f\x16\x01\x41\x84\x80\ -\x2c\xc7\xf3\xa5\x7e\x0d\x6e\x65\x1a\x8c\x99\xbd\x2e\x6f\x63\x9a\ -\x4e\x16\x01\x41\x84\x80\x2c\xc7\xf2\xf3\x0e\xab\x9d\xa2\xf8\x9a\ -\xe5\xb1\xee\x65\x1e\x4e\xa8\xd9\x64\x11\x10\x44\x08\xc8\x62\x3c\ -\xcf\x9d\xd5\xe0\x56\xa7\xe1\x98\x39\xd4\xe8\x06\xa7\xd9\x64\x11\ -\x10\x44\x08\xc8\x52\x1e\x35\x0b\x2f\x36\x2f\xd2\x78\xe6\x75\xfd\ -\xb7\x38\x77\xa1\xc9\x64\x11\x10\x44\x08\xc8\x52\x2c\x3f\x2d\x67\ -\xf4\x59\x07\x8d\xc8\xcc\xca\xa7\xbc\x74\xa2\xc9\x64\x11\x10\x44\ -\x08\xc8\x42\x3c\x4f\x2d\x37\x5a\x52\xcf\x05\xaa\xf1\x70\x42\xcd\ -\x25\x8b\x80\x20\x42\x40\x16\xa2\x39\x78\xb1\xfa\xf3\x75\xe3\xa5\ -\x38\x17\x8d\x6e\x68\x9a\x4a\x16\x01\x41\x84\x80\x2c\xc3\xf3\xb3\ -\xd6\x2b\x9f\xa2\xf8\x9a\xe7\xb1\xee\x0e\x1f\xd4\x6f\xa6\xa9\x64\ -\x11\x10\x44\x08\xc8\x22\xae\x34\x05\x2f\xab\x9f\xa2\xf8\x9a\xe7\ -\xb1\xee\x5e\x95\xcd\xd1\x4c\xb2\x08\x08\x22\x04\x64\x11\x9e\x2f\ -\xcf\x98\x1d\xd5\xe1\x79\xac\xfb\x87\x23\x0d\x6f\x60\x9a\x49\x16\ -\x01\x41\x84\x80\x2c\xe1\x46\x33\xf0\x62\xf7\xe2\x8c\xe7\xb1\xee\ -\x2e\x9f\xb5\x6c\xa0\x89\x64\x11\x10\x44\x08\xc8\x02\x3c\xcf\x30\ -\x71\x38\x45\xf1\x35\xd3\x75\xf2\x5b\xa8\x7d\x69\x1e\x59\x04\x04\ -\x11\x02\xb2\x80\x23\x4d\xc0\x8b\xe1\x69\xe5\x9e\x6f\x35\x70\xbb\ -\x57\xb4\x3f\xcd\x23\x8b\x80\x20\x42\x40\xe6\x77\xa2\xf1\x9b\xd1\ -\xe8\x9c\x98\x1e\xeb\xfe\xe1\x4a\xe3\x1b\x95\xa6\x91\x45\x40\x10\ -\x21\x20\xb3\x33\xfd\xa9\x68\xf9\xca\xbe\xe7\xb1\xee\xc3\x3f\x9c\ -\x50\xd3\xc8\x22\x20\x88\x10\x90\xd9\x79\xde\x1a\x36\xfd\x99\xa8\ -\xd1\xb9\xb9\xd5\xf0\x06\xa5\x59\x64\x11\x10\x44\x08\xc8\xdc\x4c\ -\x8f\xe8\xd8\xeb\x3b\xb7\x1c\xd3\x63\xdd\x3f\x7c\xd2\xf8\xc6\xa4\ -\x49\x64\x11\x10\x44\x08\xc8\xdc\x34\x78\x33\xb6\x2f\xca\x68\x7c\ -\x6e\xc6\x7e\x38\xa1\x26\x91\x45\x40\x10\x21\x20\x33\x33\x7d\x63\ -\x91\xed\x5a\x9a\x1e\xeb\x3e\xea\xeb\xa7\x3f\x68\x0e\x59\x04\x04\ -\x11\x02\x32\x2f\xd3\x03\x9e\x8c\x4f\x29\xd7\x08\xdd\x0c\x7d\x1f\ -\x5d\x73\xc8\x22\x20\x88\x10\x90\x79\x69\xe8\x6e\x8c\xcf\x77\x32\ -\xbd\x67\xe4\xf8\xb1\x99\x9d\x69\x0a\x59\x04\x04\x11\x02\x32\x2b\ -\xd3\xb7\xa5\x5a\x7f\x32\xae\xf1\x92\x9c\xcd\xc0\x0f\x27\xd4\x0c\ -\xb2\x08\x08\x22\x04\x64\x4e\xe7\x1a\xb9\x1b\xb3\x53\x14\x5f\x33\ -\x7d\xd5\x6f\xe4\x87\x13\x6a\x06\x59\x04\x04\x11\x02\x32\x27\xcf\ -\x33\x4c\xdc\x1f\x71\x61\x7a\xac\xfb\x87\x27\x8d\x6f\x3c\x9a\x40\ -\x16\x01\x41\x84\x80\xcc\xe8\x42\x03\x77\x63\x7e\x38\xa0\xe9\xb1\ -\xee\x03\x3f\x9c\x50\xe3\xcf\x22\x20\x88\x10\x90\xf9\x7c\xd5\xb8\ -\xdd\xd8\xdf\x0e\x36\x3d\xd6\x7d\xdc\x87\x13\x6a\xfc\x59\x04\x04\ -\x11\x02\x32\x1f\xd7\x97\x62\x34\x3c\x5f\xae\xc7\xba\x7f\xb8\xd6\ -\x00\x47\xa3\xe1\x67\x11\x10\x44\x08\xc8\x6c\x5c\x3f\x12\x37\xc0\ -\xf3\x91\x4c\x3f\x7d\x39\xec\x7d\x74\x0d\x3f\x8b\x80\x20\x42\x40\ -\xe6\xd2\x3a\xdb\xb9\x8c\xf0\x89\x38\xd7\x63\xdd\x3f\x7c\xd6\x00\ -\x07\xa3\xd1\x67\x11\x10\x44\x08\xc8\x5c\x1e\x34\x6a\x37\x43\xbc\ -\x97\xc8\xf4\xf3\x33\xa3\xde\x47\xd7\xe0\xb3\x08\x08\x22\x04\x64\ -\x26\xae\x9f\x66\x38\xd2\xf8\xcc\x69\xb4\x76\x2e\x35\xbe\xb1\x68\ -\xf0\x59\x04\x04\x11\x02\x32\x13\x8d\xd9\xce\x20\x8b\xe8\x7a\xac\ -\xfb\x98\x3f\x4c\x35\xf6\x2c\x02\x82\x08\x01\x99\x87\xeb\x6b\x30\ -\xc3\xdc\x06\xd6\x78\xed\x0c\xf2\x37\xb8\xd7\x34\xf6\x2c\x02\x82\ -\x08\x01\x99\x85\xeb\x19\x26\xce\xa7\x28\xbe\xe6\xfa\x1e\xb6\x11\ -\xde\xc4\xf6\x17\x0d\x3d\x8b\x80\x20\x42\x40\x66\xd1\xb8\xac\xb3\ -\xb1\x3e\x45\xf1\x35\x8d\xd8\x8f\xf9\xe7\xf8\xdf\xa2\x91\x67\x11\ -\x10\x44\x08\xc8\x1c\x5c\xcf\x30\xf1\x3e\x45\xf1\x35\xd7\x63\xdd\ -\x47\x8a\xf0\x4f\x1a\x79\x16\x01\x41\x84\x80\xcc\xc0\xf6\x93\xd4\ -\x43\x9d\xc5\xe1\xfa\xb7\xb8\x0f\x57\x1a\xe0\x38\x34\xf0\x2c\x02\ -\x82\x08\x01\x99\x81\xeb\x19\x26\x1f\x0e\x34\xc0\x21\xb8\xbe\x11\ -\x7a\xc0\x87\x13\x6a\xe0\x59\x04\x04\x11\x02\xd2\xdf\x89\xc6\x6b\ -\xe7\x42\x03\x1c\x84\x6d\x87\x07\x5b\x47\x02\x82\xd9\x10\x90\xee\ -\x1e\x35\x5c\x3f\x1a\xe0\x28\x6c\x8f\x75\x1f\xe9\x56\xd2\x0b\x0d\ -\x3b\x8b\x80\x20\x42\x40\xba\x73\x3d\x8c\x7c\xbc\x37\xa0\xda\xae\ -\xe4\x99\x06\x38\x0a\x0d\x3b\x8b\x80\x20\x42\x40\x7a\xb3\x7d\xf7\ -\xd0\x78\x2f\xdd\xdb\xbe\x19\x61\xbf\xeb\x7e\x7d\x1a\x75\x16\x01\ -\x41\x84\x80\xf4\xa6\xc1\xfa\x19\xec\x87\xde\x77\xae\xc7\xba\x8f\ -\xf6\x6a\xa0\x06\x9d\x45\x40\x10\x21\x20\x9d\x7d\xd1\x60\xed\x8c\ -\x78\x06\x87\xed\xb1\xee\xfe\x4f\x75\x7c\x45\x83\xce\x22\x20\x88\ -\x10\x90\xbe\x7c\x6f\xfc\x8e\xf7\xe9\x85\x67\xb6\xc7\xba\x7f\x38\ -\xd5\x08\x87\xa0\x31\x67\x11\x10\x44\x08\x48\x5f\x8d\xeb\x39\x9f\ -\x41\x1f\xa6\xa7\xd1\xfb\x19\x6a\x3d\x35\xe6\x2c\x02\x82\x08\x01\ -\xe9\xea\x46\x43\xf5\x33\xe8\xe3\xbc\x6d\x8f\x75\x1f\xe3\xc1\x5c\ -\xa2\x21\x67\x11\x10\x44\x08\x48\x4f\xbe\x6f\x1b\x1a\xf0\x00\xa7\ -\x1f\x34\x7e\x43\x1a\xe0\x08\x34\xe2\x2c\x02\x82\x08\x01\xe9\xe9\ -\x48\x23\xf5\x33\xda\x47\xdf\x7e\xb1\x3d\xd6\x7d\xa4\x83\xc5\x34\ -\xe2\x2c\x02\x82\x08\x01\xe9\xc8\xf6\x0c\x93\xb1\x4e\x51\x7c\x4d\ -\x33\x30\x34\xce\xab\x82\x1a\x70\x16\x01\x41\x84\x80\xf4\xe3\xfb\ -\xa6\xd3\x11\x9f\x61\xf1\x93\xed\x07\x33\x07\x7a\x63\xb4\x06\x9c\ -\x45\x40\x10\x21\x20\xfd\xd8\x9e\xbc\x31\xde\xe9\x7f\xbf\x6b\xbc\ -\x44\x67\x34\xcc\xd9\x30\x1a\x6f\x16\x01\x41\x84\x80\x74\xe3\xfb\ -\x47\xe5\xd1\x4e\x51\x7c\xcd\xf6\x58\xf7\x71\x8e\xc7\xd7\x70\xb3\ -\x08\x08\x22\x04\xa4\x1b\x8d\xd2\xd0\x67\x8d\x70\x50\xb6\xc7\xba\ -\x7f\xb8\xd4\x08\xdd\x69\xb8\x59\x04\x04\x11\x02\xd2\x8b\xef\xb9\ -\x4d\x63\xff\x05\xc4\xf9\xd3\xfd\xa3\xfc\x68\xd5\x68\xb3\x08\x08\ -\x22\x04\xa4\x93\x2b\x0d\xd2\xd0\x5e\xdf\x24\x47\xbe\x37\x97\x06\ -\x39\xe1\x58\xa3\xcd\x22\x20\x88\x10\x90\x4e\x1a\x17\x72\x46\x23\ -\x9e\xa2\xf8\x9a\xef\xe7\x33\x3f\xdc\x6a\x88\xde\x34\xd8\x2c\x02\ -\x82\x08\x01\xe9\xc3\xf7\xd4\xbf\x31\x4f\x51\x7c\xcd\xf8\xe5\xc1\ -\x21\xde\x20\xad\xb1\x66\x11\x10\x44\x08\x48\x17\xd7\x1a\xa2\xa1\ -\xd1\x9e\x9e\xf7\x16\xe3\x4f\xd8\x0c\x71\x46\x8c\xc6\x9a\x45\x40\ -\x10\x21\x20\x5d\xf8\x9e\x61\x32\xea\x29\x8a\xaf\x19\xff\x05\xcf\ -\xfa\x85\x55\xd1\x50\xb3\x08\x08\x22\x04\xa4\x07\xdf\x33\x63\xc7\ -\x3d\x45\xf1\x35\xcd\xc6\xd0\x08\xf7\xd1\x35\xd4\x2c\x02\x82\x08\ -\x01\xe9\xe0\xab\x06\xe8\x68\xd8\x53\x14\x5f\x33\x4e\xf4\x00\x1f\ -\xf3\xd7\x48\xb3\x08\x08\x22\x04\xa4\x03\xdf\xb7\x99\x8e\x7c\x8a\ -\xe2\x6b\x9a\x8f\x23\xff\x46\x6b\xa0\x59\x04\x04\x11\x02\xd2\xce\ -\xf7\xc4\xf1\x71\x0e\xdb\x78\x97\xf1\x22\xfb\xbf\x4d\x41\x03\xcd\ -\x22\x20\x88\x10\x90\x66\xad\xd3\x9a\xd3\xd0\xa7\x28\xbe\xa6\x19\ -\x39\xda\x6b\x17\xac\x41\xe3\xcc\x22\x20\x88\x10\x90\x66\x0f\x1a\ -\x9e\x23\x0d\xb1\x02\xe3\xb3\x2a\xed\x97\x59\xc3\xcc\x22\x20\x88\ -\x10\x90\x56\xc6\x87\xc5\x8e\x73\xde\xf8\x2e\x1a\x2f\xd5\x39\x1d\ -\x6a\x88\xae\x34\xcc\x2c\x02\x82\x08\x01\x69\xa5\xc1\x59\xd2\x10\ -\x6b\x70\x2e\xb5\xf9\x87\x6d\x34\xca\x2c\x02\x82\x08\x01\x69\x64\ -\xfc\x11\x37\xff\xd7\xe6\xf7\xe3\x7b\xac\xfb\x87\x7b\x0d\xd1\x94\ -\x46\x99\x45\x40\x10\x21\x20\x6d\xce\x35\x36\x47\xe3\x9f\xa2\xf8\ -\x9a\xf1\xb1\xee\x1f\x9e\x34\x46\x4f\x1a\x64\x16\x01\x41\x84\x80\ -\xb4\x31\x7e\x61\xbe\xc2\x29\x8a\xaf\x19\x7f\xde\xc6\xfb\xd5\x42\ -\x8d\x31\x8b\x80\x20\x42\x40\x9a\x5c\x68\x68\x8e\x2a\x9c\xa2\xf8\ -\x9a\xf1\xb1\xee\xde\x9f\xd8\xd4\x18\xb3\x08\x08\x22\x04\xa4\x85\ -\xf3\x4f\xb4\x1a\xa7\x28\xbe\x66\x7c\xac\xfb\x87\x73\x8d\xd1\x91\ -\x86\x98\x45\x40\x10\x21\x20\x2d\x8c\x6f\xeb\x56\x39\x45\xf1\x15\ -\xe3\x63\xdd\xad\xef\x38\x69\x88\x59\x04\x04\x11\x02\xd2\xe0\x44\ -\x03\xb3\x54\xe4\x14\xc5\xd7\x9c\xdf\xf3\x66\xfc\xa1\x1b\x8d\x30\ -\x8b\x80\x20\x42\x40\xf2\x1e\x35\x2e\x4b\xee\x9f\x6d\x4b\xd2\xec\ -\x2c\xf9\x3e\x9c\x50\x03\xcc\x22\x20\x88\x10\x90\x3c\xe7\x37\x05\ -\xd5\x39\x45\xf1\x35\xe3\x63\xdd\x3f\x5c\x6a\x8c\x7e\x34\xc0\x2c\ -\x02\x82\x08\x01\x49\x73\x3e\x9c\xa9\xd2\x29\x8a\xaf\x69\x7e\x96\ -\x6c\xdf\x37\xad\xf1\x65\x11\x10\x44\x08\x48\x9a\x46\xe5\x49\x63\ -\xac\xc7\xf9\xec\x7c\xdb\x87\x13\x6a\x7c\x59\x04\x04\x11\x02\x92\ -\xf5\x45\xa3\xb2\x54\xea\x14\xc5\xd7\x34\x43\x4b\xae\x7f\xef\xd3\ -\xf0\xb2\x08\x08\x22\x04\x24\xc9\xf9\x5c\x8d\x21\x9e\xd3\x9d\x65\ -\xfd\xca\xe1\x27\x0d\xd2\x8c\x46\x97\x45\x40\x10\x21\x20\x49\x8d\ -\x0b\x37\xaf\xbd\xbe\x2d\xa3\x39\xd2\x24\x1d\x99\x7e\xfa\x5f\xa3\ -\xcb\x22\x20\x88\x10\x90\x9c\x1b\x8d\xc9\x52\xb5\x53\x14\x5f\x73\ -\x3e\xd6\xdd\xed\x3e\x9d\x68\x70\x59\x04\x04\x11\x02\x92\x72\xad\ -\x21\x79\x2a\x77\x8a\xe2\x6b\xce\x9f\xff\xf7\x7c\xf1\x50\x83\xcb\ -\x22\x20\x88\x10\x90\x14\xe7\x9f\x61\x05\x4f\x51\x7c\xcd\xfa\xf6\ -\xd3\x8d\x06\x69\x45\x63\xcb\x22\x20\x88\x10\x90\x0c\xeb\x33\x4c\ -\x2a\x9e\xa2\xf8\x9a\xf5\x27\x38\x1d\x8f\x90\xd1\xd0\xb2\x08\x08\ -\x22\x04\x24\xc1\xf9\x4c\x3f\xe7\x0f\x44\xf7\x62\x7d\x08\xb2\xe3\ -\xdf\xff\x34\xb4\x2c\x02\x82\x08\x01\x49\xb0\xfe\x13\x70\xcd\x53\ -\x14\x5f\x73\x3e\xd6\x7d\xbf\x3d\xb1\x0c\x8d\x2c\x8b\x80\x20\x42\ -\x40\xf6\xf7\xa4\xf1\x78\x2a\x7a\x8a\xe2\x2b\xde\x7f\x05\xd4\x20\ -\x8d\x68\x60\x59\x04\x04\x11\x02\xb2\x3f\x0d\xc7\x94\x06\x59\x9b\ -\xf3\xb1\xee\x86\x09\xd7\xc0\xb2\x08\x08\x22\x04\x64\x6f\xd6\xaf\ -\x9f\xd4\x3d\x45\xf1\x35\xcd\xd6\x93\xdd\xbb\x18\x34\xae\x2c\x02\ -\x82\x08\x01\xd9\xd7\x95\x46\x63\x4a\xa3\xac\xce\xf9\x58\x77\xbf\ -\x0f\x72\x6a\x5c\x59\x04\x04\x11\x02\xb2\xaf\xc6\x15\x9b\xd9\x67\ -\x8d\xb2\x3c\xcd\xd7\x93\xdb\x77\x41\xc3\xca\x22\x20\x88\x10\x90\ -\x7d\x7d\xb2\xa6\x41\xd6\x77\xa0\x09\x7b\xd2\x20\x5d\x68\x03\x65\ -\x11\x10\x44\x08\x08\x50\x9d\x36\x50\x16\x01\x41\x84\x80\x00\xd5\ -\x69\x03\x65\x11\x10\x44\x08\x08\x50\x9d\x36\x50\x16\x01\x41\x84\ -\x80\x00\xd5\x69\x03\x65\x11\x10\x44\x08\x08\x50\x9d\x36\x50\x16\ -\x01\x41\x84\x80\x00\xd5\x69\x03\x65\x11\x10\x44\x08\x08\x50\x9d\ -\x36\x50\x16\x01\x41\x84\x80\x00\xd5\x69\x03\x65\x11\x10\x44\x08\ -\x08\x50\x9d\x36\x50\x16\x01\x41\x84\x80\x00\xd5\x69\x03\x65\x11\ -\x10\x44\x08\x08\x50\x9d\x36\x50\x16\x01\x41\x84\x80\x00\xd5\x69\ -\x03\x65\x11\x10\x44\x08\x08\x50\x9d\x36\x50\x16\x01\x41\x84\x80\ -\x00\xd5\x69\x03\x65\x11\x10\x44\x08\x08\x50\x9d\x36\x50\x16\x01\ -\x41\x84\x80\x00\xd5\x69\x03\x65\x11\x10\x44\x08\x08\x50\x9d\x36\ -\x50\x16\x01\x41\x84\x80\x00\xd5\x69\x03\x65\x11\x10\x44\x08\x08\ -\x50\x9d\x36\x50\x16\x01\x41\x84\x80\x00\xd5\x69\x03\x65\x1d\x9d\ -\xad\xea\x54\xb3\xc8\xd2\x97\xd9\xa6\x43\x2d\xc2\x5c\x08\x08\x50\ -\x9d\x36\xd0\xa0\xae\x35\x8b\x2c\x7d\x99\x6d\x7a\xd0\x22\xcc\x85\ -\x80\x00\xd5\x69\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ -\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ -\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ -\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ -\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ -\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ -\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ -\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ -\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ -\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ -\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ -\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ -\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ -\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ -\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ -\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ -\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ -\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ -\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ -\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ -\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ -\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ -\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ -\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ -\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ -\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ -\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ -\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ -\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ -\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ -\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ -\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ -\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ -\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ -\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ -\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ -\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ -\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ -\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ -\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ -\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ -\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ -\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ -\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\ -\x34\x20\x20\x13\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\ -\x02\x02\x64\x68\x03\x0d\x8a\x80\x34\x20\x20\x13\x02\x02\x64\x68\ -\x03\x65\x7d\x39\x59\xd5\xa3\x66\x91\xa5\x2f\xb3\x4d\x73\xff\xd0\ -\x24\x20\x40\x75\xda\x40\x59\xdf\xf4\x65\x80\x3f\x11\x10\xa0\x3a\ -\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ -\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ -\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ -\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ -\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ -\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ -\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ -\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ -\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ -\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ -\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ -\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ -\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ -\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ -\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ -\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ -\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ -\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ -\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ -\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ -\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ -\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ -\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ -\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ -\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ -\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ -\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ -\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ -\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ -\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ -\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ -\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ -\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ -\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ -\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ -\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ -\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ -\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ -\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ -\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ -\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ -\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ -\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ -\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ -\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ -\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ -\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ -\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ -\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ -\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ -\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ -\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ -\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ -\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ -\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ -\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ -\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ -\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ -\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ -\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ -\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ -\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ -\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ -\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ -\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ -\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ -\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ -\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ -\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ -\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ -\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ -\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ -\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ -\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ -\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\ -\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\ -\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\ -\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\ -\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\ -\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\ -\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\ -\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\ -\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\ -\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\ -\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\ -\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\ -\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\ -\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\ -\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\ -\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\x22\x20\x88\ -\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\xd3\x06\xca\ -\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\x01\x01\xaa\ -\xd3\x06\xca\x22\x20\x88\x10\x10\xa0\x3a\x6d\xa0\x2c\x02\x82\x08\ -\x01\x01\xaa\xd3\x06\xca\xba\xbc\x00\xde\xa6\x4b\x24\x8b\x80\x00\ -\xf6\xb4\x81\x00\x33\x04\x04\xb0\xa7\x0d\x04\x98\x21\x20\x80\x3d\ -\x6d\x20\xc0\xcc\x5e\x3f\xd3\x09\x08\xb0\x06\x6d\x20\xc0\xcc\xb9\ -\xae\xd0\x9d\x10\x10\x60\x0d\xda\x40\x80\x99\x53\x5d\xa1\x3b\x21\ -\x20\xc0\x1a\xb4\x81\x00\x33\x8f\xba\x42\x77\x42\x40\x80\x35\x68\ -\x03\x01\x66\x74\x81\xee\x86\x80\x00\x6b\xd0\x06\x02\xcc\xe8\x02\ -\xdd\x0d\x01\x01\xd6\xa0\x0d\x04\x78\x39\xd3\x05\xba\x1b\x02\x02\ -\xac\x41\x1b\x08\xf0\x72\xa3\x0b\x74\x37\x04\x04\x58\x83\x36\x10\ -\xe0\x65\xaf\xcf\x11\x12\x10\x60\x15\xda\x40\x80\x97\x6b\x5d\xa0\ -\xbb\x21\x20\xc0\x1a\xb4\x81\x00\x2f\xba\x3e\x77\x44\x40\x80\x35\ -\x68\x03\x01\x56\x8e\x74\x7d\xee\x88\x80\x00\x6b\xd0\x06\x02\xac\ -\x5c\xe8\xfa\xdc\x11\x01\x01\xd6\xa0\x0d\x04\x58\xd9\xf3\x49\x65\ -\x04\x04\x58\x83\x36\x10\x60\x45\x97\xe7\xae\x08\x08\xb0\x06\x6d\ -\x20\xc0\xc9\x83\x2e\xcf\x5d\x11\x10\x60\x0d\xda\x40\x80\x93\xfd\ -\x3e\x05\x42\x40\x80\x75\x68\x03\x01\x4e\x74\x75\xee\x8c\x80\x00\ -\x6b\xd0\x06\x02\x8c\xec\xfb\x0a\x16\x01\x01\x56\xa1\x0d\x04\x18\ -\xd9\xfb\xe7\x39\x01\x01\xd6\xa0\x0d\x04\x18\xd1\xc5\xb9\x3b\x02\ -\x02\xac\x41\x1b\x08\xf0\xb1\xe7\xa7\x08\x9f\x11\x10\x60\x0d\xda\ -\x40\x80\x8f\x03\x5d\x9c\xbb\x23\x20\xc0\x1a\xb4\x81\x00\x1b\x87\ -\xba\x36\xf7\xd0\x1a\x90\xa3\x9b\xe3\x53\x7d\x29\x00\xbb\x3a\xd5\ -\x06\x02\x6c\x3c\xea\xe2\xdc\x43\x6b\x40\x5e\xdc\x1d\x3e\xed\x77\ -\x88\x3c\xb0\x71\xc7\xda\x3b\x80\x8b\x2f\xba\x36\xf7\xd1\x25\x20\ -\x2f\xee\x2e\x4f\xce\xf7\x7f\x09\x0d\xd8\xa4\x13\x6d\x1b\xc0\xc5\ -\x27\x5d\x9b\xfb\xe8\x17\x90\x1f\x1e\x6e\xaf\x32\xc3\x00\xb6\xe5\ -\x42\x1b\x06\x30\x91\xf9\x0b\x48\xf7\x80\xbc\x38\xbb\x38\xfe\xaa\ -\xaf\x0f\xe0\x0d\x37\xda\x2b\x80\x09\x5d\x99\xfb\x99\x25\x20\x2f\ -\x8e\x0e\x3f\x72\x7b\x1d\x78\xdb\x17\x6d\x13\xc0\xc3\x67\x5d\x99\ -\xfb\x99\x2f\x20\x2f\xee\xbe\x7c\x3e\xd7\xef\x04\xe0\x97\x43\xed\ -\x10\xc0\xc2\xbd\x2e\xcc\x3d\xcd\x1c\x90\x1f\x1e\x4e\xae\x12\x6f\ -\x10\x03\xea\xe2\x1e\x08\xac\x24\xdf\x47\xbb\x48\x40\x5e\x70\x63\ -\x04\xf8\xe5\x56\xdb\x02\x70\x90\xf8\x0c\xe1\x8b\xe5\x02\xf2\xe2\ -\xe8\xe6\x23\x9f\x18\x01\xf8\x1c\x08\x9c\x24\x5f\xc0\x5a\x3c\x20\ -\x2f\xb8\x31\x82\xcd\xbb\xd6\x66\x00\x0c\xa4\x3f\x7b\xb1\x46\x40\ -\x7e\xb8\x3c\xf9\xc6\x8d\x11\x6c\x96\xb6\x01\xb0\xbe\x7d\x1f\x64\ -\x3b\x59\x2f\x20\x2f\xb8\x31\x82\x8d\xd2\x0e\x00\x56\x97\xbd\x01\ -\xf2\x6c\xe5\x80\xbc\xb8\xbf\xe1\x13\x23\xd8\x1a\x5d\xfc\xc0\xda\ -\xd2\x37\x40\x9e\x39\x04\xe4\x05\x07\x32\x62\x53\x74\xdd\x03\x2b\ -\x3b\xd2\x15\x99\x62\x13\x90\x17\x77\x97\x27\xdf\x38\x90\x11\x5b\ -\xa0\x4b\x1e\x58\xd7\x5d\xd3\x4f\x5c\xaf\x80\xfc\xc0\x81\x8c\xa8\ -\x4f\x17\x3b\xb0\xae\xb6\xdb\x07\x8e\x01\x79\x71\x76\xc3\xed\x75\ -\x14\xa6\xeb\x1c\x58\x55\xe3\x8d\x03\xdb\x80\xbc\x38\xe2\xc6\x08\ -\x8a\xd2\x25\x0e\xac\xe9\x9b\x2e\xc7\x2c\xef\x80\xbc\xf8\x7e\x63\ -\x44\xa3\x05\xaa\xd0\xd5\x0d\xac\xa8\xf9\xed\xaf\x03\x04\xe4\x87\ -\x87\x5b\x0e\x64\x44\x21\xba\xae\x81\xd5\xdc\xb5\xff\x48\x1d\x26\ -\x20\x2f\xf8\xdc\x21\xaa\xd0\x25\x0d\xac\xa5\xe5\xf3\x1f\x3f\x8d\ -\x15\x90\x17\xdc\x18\x41\x01\xba\x9a\x81\x95\x5c\xea\x4a\x6c\x32\ -\x60\x40\x5e\x70\x20\x23\xc6\xa6\x0b\x19\x58\x47\xee\x09\x84\x7f\ -\x1a\x35\x20\x3f\x70\x20\x23\x46\xa5\x4b\x18\x58\xc3\x5d\xa7\xd3\ -\xa3\xc6\x0e\xc8\x0b\x6e\x8c\x60\x40\xba\x7a\x81\x15\x74\x79\xf9\ -\xea\xbb\x02\x01\x79\xc1\x81\x8c\x18\x8b\x2e\x5c\x60\x71\x77\x57\ -\xba\x08\xdb\x1d\xdc\xe9\x6b\x56\xc0\x81\x8c\x18\x86\xae\x59\x60\ -\x69\x17\xba\x04\x7b\x28\x15\x90\x1f\x38\x90\x11\x03\xd0\xd5\x0a\ -\x2c\xeb\xac\xeb\x41\x83\x07\x67\xfa\xb2\xc5\x70\x20\x23\xbc\xe9\ -\x42\x05\x96\x74\xdf\xf9\x54\x8f\x83\x43\x7d\xe1\x8a\xee\x6f\x8e\ -\xb9\x31\x02\x4f\xba\x46\x81\xe5\x9c\x75\xff\xec\xc3\xc1\x89\xbe\ -\x74\x59\x7c\xee\x10\x8e\x74\x79\x02\x4b\x79\x98\xe1\x07\xe1\xc1\ -\x37\x7d\xf1\xe2\x2e\x4f\xce\xb9\x31\x02\x23\xba\x30\x81\x65\xdc\ -\xce\xf2\x91\xb9\x83\x2d\x5d\xc8\xdc\x18\x81\x0d\x5d\x93\xc0\x02\ -\x6e\xe6\x7a\x15\xe6\xe0\xbf\x7a\x6f\xc3\xfa\x37\x3e\x77\x08\x07\ -\xba\x1c\x81\x99\x9d\x9d\xcc\x78\x27\xf8\xe0\xbf\x0b\xfd\x36\x9b\ -\x72\x74\xc8\xe7\x0e\xb1\x2a\x5d\x89\xc0\x7c\x8e\x0e\x3f\xcf\x7c\ -\x03\xf8\xe0\xbf\x6b\xfd\x5e\xdb\xc3\x81\x8c\x58\x8f\x2e\xc2\xac\ -\xfb\x07\x20\xf2\xe5\xf0\xf6\xf3\xc7\xeb\x25\xce\x09\x3c\xf8\x6f\ -\x73\xaf\x61\xfd\xe1\xf2\x84\x27\x55\x61\x79\xba\xfc\xb2\x78\x48\ -\x27\x1c\x3c\x07\xa4\xfc\x1b\x79\x77\xc0\x8d\x11\x2c\x4c\x57\x5e\ -\x16\x01\x81\x83\xe7\x80\x54\x39\x4f\xb1\x19\x07\x32\x62\x39\xba\ -\xe8\xb2\x08\x08\x1c\x7c\xff\x70\xc4\x8d\xae\x49\x3c\xe3\xc6\x08\ -\x16\xa1\xeb\x2d\x8b\x80\xc0\xc1\xf7\x80\xf0\x57\x90\xbf\x70\x20\ -\x23\x66\xa6\x2b\x2d\x8b\x80\xc0\xc1\xcb\x8f\xc9\x4d\xbe\x93\xf7\ -\x7d\x67\x17\xc7\x7c\xee\x10\x33\xd1\x45\x96\x45\x40\xe0\xe0\xc7\ -\x9f\xb3\x37\xfe\x46\xac\x7f\xe1\xc6\x08\x66\xa1\xeb\x2b\x8b\x80\ -\xc0\xc1\x8f\x80\x9c\xeb\xaa\xc4\xdb\xee\x66\xff\x3c\x0e\xb6\x46\ -\x97\x56\x16\x01\x81\x03\xbd\xd2\xcf\x8b\x58\xef\xbb\xe3\x40\x46\ -\xf4\xa3\xab\x2a\x8b\x80\xc0\xc1\xcf\x9f\x88\x0f\xba\x2e\xf1\x0e\ -\x0e\x64\x44\x17\xba\x9e\xb2\x08\x08\x1c\xfc\xfa\x23\xf5\xbd\x2e\ -\x4c\xec\xe0\xec\x86\xcf\x1d\xa2\x8d\x2e\xa5\x2c\x02\x02\x07\xd3\ -\x6b\x32\xdc\x48\xdf\x13\x07\x32\xa2\x81\xae\xa2\x2c\x02\x02\x07\ -\xbf\xbd\xa8\x7f\xa4\x4b\x13\x7b\xe0\x73\x87\xc8\xd1\x05\x94\x45\ -\x40\xe0\xe0\xf7\xbb\xc2\x67\xba\x36\xb1\xaf\x07\x0e\x64\xc4\x9e\ -\x74\xe9\x64\x11\x10\x38\xf8\x3d\x20\xff\x1d\xea\xe2\x44\x06\x07\ -\x32\x62\x0f\xba\x6a\xb2\x08\x08\x1c\xbc\x0a\xc8\x7f\x57\xba\x3a\ -\x91\x75\x7f\xf3\x91\x4f\x8c\x60\x07\xba\x60\xb2\x08\x08\x1c\xbc\ -\x0e\xc8\x7f\xff\x7d\xd1\xf5\x89\x06\xdc\x18\xc1\xbb\x74\xad\x64\ -\x11\x10\x38\xf8\x33\x20\xff\x9d\x72\x27\xa4\x93\xcb\x93\x6f\xdc\ -\x18\x41\x44\x57\x49\x16\x01\x81\x83\xbf\x02\xf2\x9c\x10\xfe\x16\ -\xd2\x0f\x37\x46\xf0\x36\x5d\x20\x59\x04\x04\x0e\xde\x08\xc8\xb3\ -\x8f\x7c\x30\xbd\x27\x0e\x64\xc4\x5f\x74\x6d\x64\x11\x10\x38\x78\ -\x3b\x20\xcf\xae\x4f\x2e\x75\xa9\xa2\x8b\xbb\xc3\x27\x6e\xaf\xe3\ -\x17\x5d\x16\x59\x04\x04\x0e\xc2\x80\xbc\xb8\x7e\x3a\xe4\x03\xea\ -\x3d\xdd\xf1\xa4\x2a\xfc\xa0\x2b\x22\x8b\x80\xc0\xc1\x0e\x3f\xcd\ -\x4e\x3f\xde\x70\x50\x56\x57\x1c\xc8\x08\x02\x82\x0a\x76\xfd\xe3\ -\xf0\xa7\xab\x5b\xee\x8b\x74\x75\x76\x73\xcc\x8d\x91\x0d\xd3\x65\ -\x90\x45\x40\xe0\x60\xaf\xd7\x53\x0e\xce\x3f\x5f\xf2\x92\x56\x4f\ -\x47\xdc\x18\xd9\x2a\x5d\x01\x59\x04\x04\x0e\x12\x2f\xc8\x5f\x3f\ -\x1d\x72\xee\x62\x4f\xdf\x9f\x54\xa5\xb5\xc5\x66\xe8\x9b\x9f\x45\ -\x40\xe0\x20\x7b\x47\xf7\xeb\xf1\x05\x9f\x38\xec\xea\xe1\x96\x03\ -\x19\xb7\x44\xdf\xf6\x2c\x02\x02\x07\xd9\x80\xbc\xe0\xc6\x48\x6f\ -\x7c\xee\x70\x33\xf4\x1d\xcf\x22\x20\x70\xd0\x14\x90\x1f\xce\x3f\ -\x7f\xe1\xc6\x48\x4f\xdc\x18\xd9\x02\x7d\xb3\xb3\x08\x08\x1c\x74\ -\x08\xc8\x8b\xeb\x8f\xdc\x18\xe9\x8a\x03\x19\x8b\xd3\xf7\x39\x8b\ -\x80\xc0\x41\xaf\x80\xbc\xe0\xc6\x48\x6f\x1c\xc8\x58\x96\xbe\xc3\ -\x59\x04\x04\x0e\xba\x06\xe4\xc5\xe3\x37\x0e\x41\xe9\x8b\x1b\x23\ -\x15\xe9\x9b\x9b\x45\x40\xe0\xa0\x7f\x40\x7e\xe0\xc6\x48\x67\x1c\ -\xc8\x58\x8c\xbe\xaf\x59\x04\x04\x0e\xe6\x0a\xc8\x0b\x0e\x41\xe9\ -\xec\xee\x0b\xb7\xd7\xab\xd0\xb7\x34\x8b\x80\xc0\xc1\xac\x01\x79\ -\xf1\xe9\xea\x96\x1b\x23\x5d\x71\x20\x63\x05\xfa\x66\x66\x11\x10\ -\x38\x58\xe8\x27\xd1\xc1\xb7\x13\x0e\x41\xe9\xea\x8c\x03\x19\xc7\ -\xa6\xef\x63\x16\x01\x81\x83\x45\xff\x28\xcb\x21\x28\x9d\xdd\x73\ -\x20\xe3\xb0\xf4\x2d\xcc\x22\x20\x70\xb0\xfc\x6b\x21\xa7\xc7\x37\ -\xbc\xa4\xd5\x13\x4f\xaa\x1a\x92\xbe\x7b\x59\x04\x04\x0e\x56\x7a\ -\x31\x9d\x43\x50\x3a\xfb\x7e\x20\x23\x37\x46\x46\xa2\x6f\x5c\x16\ -\x01\x81\x83\x55\x7f\xe8\x70\x3a\x7c\x67\x3c\xa9\x6a\x1c\xfa\x96\ -\x65\x11\x10\x38\x58\xff\x4f\xad\xa7\x1c\x82\xd2\x17\x9f\x3b\x1c\ -\x82\xbe\x5b\x59\x04\x04\x0e\x4c\x5e\xf6\xe0\x10\x94\xce\x8e\x0e\ -\xf9\xdc\xa1\x37\x7d\xa3\xb2\x08\x08\x1c\x38\xbd\x6e\xfe\x78\xc5\ -\x21\x28\x5d\x71\x20\xa3\x31\x7d\x8f\xb2\x08\x08\x1c\xf8\xdd\x78\ -\xe5\x10\x94\xce\x2e\x4f\x78\x52\x95\x21\x7d\x77\xb2\x08\x08\x1c\ -\xf8\x05\xe4\xc5\xe9\xc7\x43\x0e\x41\xe9\x89\x1b\x23\x6e\xf4\x8d\ -\xc9\x22\x20\x70\x60\x1a\x90\x17\xdc\x18\xe9\xec\xfe\xe6\x23\x9f\ -\x18\x71\xa1\xef\x49\x16\x01\x81\x03\xe7\x80\xbc\xe0\x10\x94\xce\ -\xb8\x31\xe2\x41\xdf\x8e\x2c\x02\x02\x07\xf6\x01\xf9\xe1\xfa\xe9\ -\x90\x8a\xf4\xc4\x93\xaa\xd6\xa6\x6f\x44\x16\x01\x81\x83\x41\x02\ -\xf2\x82\x43\x50\x3a\x3b\xbb\x38\xe6\x73\x87\x6b\xd1\xf7\x20\x8b\ -\x80\xc0\xc1\x48\x01\x79\xc1\x21\x28\x9d\xf1\xa4\xaa\x75\x68\xf9\ -\xb3\x08\x08\x1c\x0c\x17\x90\x17\x07\xe7\xdc\x18\xe9\x8a\x03\x19\ -\x17\xa7\x95\xcf\x22\x20\x70\x30\x66\x40\x7e\xe0\x10\x94\xbe\x38\ -\x90\x71\x49\x5a\xf4\x2c\x02\x02\x07\xc3\xff\xc0\xe0\xbd\xbe\x9d\ -\x71\x20\xe3\x32\xb4\xdc\x59\x04\x04\x0e\x6a\xfc\x89\x93\x43\x50\ -\x3a\x3b\xbb\xf9\xc8\xe7\x0e\xe7\xa5\x95\xce\x22\x20\x70\x50\xe9\ -\x25\x0b\x0e\x41\xe9\x8b\x03\x19\xe7\xa4\x45\xce\x22\x20\x70\x50\ -\xee\x35\xef\xeb\x8f\x37\x1c\x82\xd2\xd1\xdd\x25\x9f\x3b\x9c\x85\ -\xd6\x37\x8b\x80\xc0\x41\xcd\x9b\xa6\xdc\x18\xe9\xec\xe1\x96\x03\ -\x19\x3b\xd3\xca\x66\x11\x10\x38\xa8\x19\x90\x17\x8f\xdf\xb8\x31\ -\xd2\x15\x07\x32\xf6\xa4\x45\xcd\x22\x20\x70\x50\x38\x20\x3f\x70\ -\x08\x4a\x5f\x47\x1c\xc8\xd8\x87\xd6\x33\x8b\x80\xc0\x41\xf9\x80\ -\xbc\x38\x3d\xe6\xc6\x48\x4f\x1c\xc8\xd8\x4e\x4b\x99\x45\x40\xe0\ -\x60\x1b\x01\x79\xc1\x21\x28\x9d\x3d\x70\x20\x63\x03\x2d\x62\x16\ -\x01\x81\x83\x0d\x05\xe4\x05\x87\xa0\x74\xc6\x8d\x91\x24\xad\x5f\ -\x16\x01\x81\x83\xad\x05\xe4\x87\xeb\x27\x0e\x41\xe9\x89\x03\x19\ -\xf7\xa7\xa5\xcb\x22\x20\x70\xb0\xcd\x80\xbc\xe0\xbd\xbe\x7d\x71\ -\x20\xe3\x5e\xb4\x6a\x59\x04\x04\x0e\x36\x1c\x90\x17\x8f\x57\x27\ -\xdc\x18\xe9\xe8\xee\xf2\xe4\xdb\xd6\xaf\xa9\xdd\x68\xc1\xb2\x08\ -\x08\x1c\xb0\xd9\xbf\xe3\x10\x94\xbe\x38\x90\xf1\x7d\x5a\xaa\x2c\ -\x02\x02\x07\x04\xe4\x17\x0e\x41\xe9\xeb\xec\xe6\x98\x1b\x23\x31\ -\xad\x52\x16\x01\x81\x03\x02\xf2\x1a\x37\x46\xfa\x3a\xe2\xc6\x48\ -\x40\x0b\x94\x45\x40\xe0\x80\x80\xbc\x81\x43\x50\xfa\xe2\x49\x55\ -\x6f\xd0\xda\x64\x11\x10\x38\x60\x5f\x87\x38\x04\xa5\x2f\x0e\x64\ -\x7c\x45\xab\x92\x45\x40\xe0\x80\x80\xfc\xdb\x29\x37\x46\xba\xe2\ -\x73\x87\x3f\x69\x41\xb2\x08\x08\x1c\x10\x90\x1d\x70\x08\x4a\x5f\ -\x3c\xa9\xea\x99\xd6\x22\x8b\x80\xc0\x01\x01\xd9\xd5\xc1\x37\x0e\ -\x41\xe9\x69\xeb\x07\x32\x6a\x19\xb2\x08\x08\x1c\x10\x90\xfd\x70\ -\x08\x4a\x5f\x97\x27\x5b\xbd\x31\xa2\x05\xc8\x22\x20\x70\x40\x40\ -\x12\x78\xaf\x6f\x5f\x9b\xbc\x31\xa2\xb9\x67\x11\x10\x38\x20\x20\ -\x59\xdc\x18\xe9\x6b\x6b\x07\x32\x6a\xda\x59\x04\x04\x0e\x08\x48\ -\x1b\x0e\x41\xe9\xea\xee\xcb\xe7\xad\x7c\xee\x50\x33\xce\x22\x20\ -\x70\x40\x40\x3a\x38\xfd\xc8\x8d\x91\x9e\x36\x71\x20\xa3\xe6\x9a\ -\x45\x40\xe0\x80\x80\xf4\xc2\x8d\x91\xbe\xce\x8a\x1f\xc8\xa8\x69\ -\x66\x11\x10\x38\x20\x20\x5d\x3d\x7e\xe3\x74\xf8\x9e\xee\xeb\x1e\ -\xc8\xa8\x19\x66\x11\x10\x38\x20\x20\x33\xe0\xc6\x48\x57\x35\x9f\ -\x54\xa5\xc9\x65\x11\x10\x38\x20\x20\x73\xe1\x10\x94\xae\xca\x1d\ -\xc8\xa8\x79\x65\x11\x10\x38\x20\x20\xb3\xfa\xc4\x8d\x91\xae\x0a\ -\x3d\xa9\x4a\x33\xca\x22\x20\x70\x40\x40\xe6\xc7\x21\x28\x7d\xd5\ -\xf8\xdc\xa1\x26\x93\x45\x40\xe0\x80\x80\x2c\x85\xd3\xe1\xbb\x1a\ -\xfe\x40\x46\xcd\x23\x8b\x80\xc0\x01\x01\x59\xd4\xe9\xf1\x0d\x2f\ -\x69\xf5\x33\xf2\x81\x8c\x9a\x42\x16\x01\x81\x03\x02\xb2\x3c\x0e\ -\x41\xe9\x6b\xcc\x03\x19\x35\xf8\x2c\x02\x02\x07\x04\x64\x2d\xe7\ -\xdc\x18\xe9\x69\xb8\x1b\x23\x1a\x77\x16\x01\x81\x03\x02\xb2\x2a\ -\x0e\x41\xe9\xea\xfe\xe6\xe3\x30\x9f\x18\xd1\x90\xb3\x08\x08\x1c\ -\x10\x90\xf5\x71\x08\x4a\x57\x83\xdc\x18\xd1\x68\xb3\x08\x08\x1c\ -\x10\x10\x13\x8f\x57\x27\x97\xfa\xd9\x80\x0e\x2e\x4f\xbe\x79\xdf\ -\x18\xd1\x38\xb3\x08\x08\x1c\x10\x10\x2b\x1c\x82\xd2\x95\xf3\x8d\ -\x11\x0d\x31\x8b\x80\xc0\x01\x01\xf1\xc3\x21\x28\x5d\x99\x3e\xa9\ -\x4a\xa3\xcb\x22\x20\x70\x40\x40\x4c\x71\x63\xa4\x2b\xbf\x03\x19\ -\x35\xb0\x2c\x02\x02\x07\x04\xc4\xd9\xf7\x43\x50\xf4\x03\x03\xed\ -\xee\x9c\x9e\x54\xa5\x31\x65\x11\x10\x38\x20\x20\xfe\x38\x04\xa5\ -\xab\x87\xdb\x63\x87\x03\x19\x35\x9a\x2c\x02\x02\x07\x04\x64\x10\ -\x1c\x82\xd2\xd5\xd9\xcd\xda\xb7\xd7\x35\x90\x2c\x02\x02\x07\x04\ -\x64\x24\x1c\x82\xd2\xd5\xd1\xe1\xd3\x7a\xb7\xd7\x35\x86\x2c\x02\ -\x02\x07\x04\x64\x38\x07\x1c\x82\xd2\xd3\xf7\x27\x55\x69\x65\x17\ -\xa5\xdf\x3e\x8b\x80\xc0\x01\x01\x19\x14\x87\xa0\x74\xf5\x70\xbb\ -\xf4\x81\x8c\xfa\x8d\xb3\x08\x08\x1c\x10\x90\x91\xf1\x5e\xdf\xae\ -\x16\xfd\xdc\xa1\x7e\xcf\x2c\x02\x02\x07\x04\x64\x78\x1c\x82\xd2\ -\xd5\xd1\xe1\x32\x07\x32\xea\xb7\xcb\x22\x20\x70\x40\x40\x8a\xe0\ -\x10\x94\x9e\x16\x38\x90\x51\xbf\x53\x16\x01\x81\x03\x02\x52\xc9\ -\x35\x87\xa0\xf4\x34\xeb\x81\x8c\xfa\x3d\xb2\x08\x08\x1c\x10\x90\ -\x72\xb8\x31\xd2\xd5\x5c\x37\x46\xf4\xe5\xb3\x08\x08\x1c\x10\x90\ -\x9a\x1e\x39\x04\xa5\xa7\x19\x0e\x64\xd4\x57\xce\x22\x20\x70\x40\ -\x40\x2a\xe3\x10\x94\x9e\xfa\x1e\xc8\xa8\x2f\x9a\x45\x40\xe0\x80\ -\x80\x94\xc7\xe9\xf0\x5d\xf5\x3a\x90\x51\x5f\x2e\x8b\x80\xc0\x01\ -\x01\xd9\x06\x0e\x41\xe9\xea\xe1\xf6\xaa\xf5\x40\x46\x7d\xa5\x2c\ -\x02\x02\x07\x04\x64\x43\x38\x04\xa5\xab\xb3\x9b\xe3\x86\x1b\x23\ -\xfa\x22\x59\x04\x04\x0e\x08\xc8\xe6\x5c\x3f\x71\x08\x4a\x3f\x47\ -\xd9\x1b\x23\xfa\xef\xb3\x08\x08\x1c\x10\x90\x6d\xe2\xbd\xbe\x3d\ -\x7d\x3f\x90\x71\xdf\x9d\xa4\xff\x34\x8b\x80\xc0\x01\x01\xd9\xb0\ -\x47\x6e\x8c\xf4\xb4\xdf\x8d\x11\xfd\x47\x59\x04\x04\x0e\x08\xc8\ -\xe6\x71\x08\x4a\x4f\x3b\x7f\xee\x50\xbf\x3e\x8b\x80\xc0\x01\x01\ -\xc1\x77\xd7\x1f\x6f\xb8\x31\xd2\xcd\xd1\xe1\xfb\x9f\x3b\xd4\x2f\ -\xcd\x22\x20\x70\x40\x40\xf0\x0b\x37\x46\x7a\x7a\xe7\x40\x46\xfd\ -\xaa\x2c\x02\x02\x07\x04\x04\xaf\x71\x08\x4a\x57\x97\x27\xc1\x93\ -\xaa\xf4\xef\xb3\x08\x08\x1c\x10\x10\xbc\x85\x1b\x23\x3d\x9d\x5d\ -\x1c\xff\x75\x7b\x5d\xff\x2a\x8b\x80\xc0\x01\x01\x41\x88\x43\x50\ -\x7a\xfa\xe3\x40\x46\xfd\xd3\x2c\x02\x02\x07\x04\x04\xff\xc6\x21\ -\x28\x3d\xdd\x7d\xf9\xac\xcf\x1d\xea\x1f\x64\x11\x10\x38\x20\x20\ -\xd8\xc1\xc1\x37\x0e\x41\xe9\xe8\xf2\xe4\xdb\xa9\xfe\x67\x16\x01\ -\x81\x03\x02\x82\x9d\x71\x08\x8a\x0f\x02\x02\x07\x04\x04\xfb\xf9\ -\x7a\x7c\xc3\x7b\x7d\xd7\x47\x40\xe0\x80\x80\x20\x81\x1b\x23\x6b\ -\x23\x20\x70\x40\x40\x90\xc6\x7b\x7d\xd7\x43\x40\xe0\x80\x80\xa0\ -\xcd\xe9\x47\x6e\x8c\xac\x80\x80\xc0\x01\x01\x41\x07\x1c\x82\xb2\ -\x34\x02\x02\x07\x04\x04\xbd\x3c\x5e\x71\x08\xca\x62\x08\x08\x1c\ -\x10\x10\xf4\xc5\x8d\x91\x45\x10\x10\x38\x20\x20\x98\x01\x87\xa0\ -\xcc\x8d\x80\xc0\x01\x01\xc1\x5c\xb8\x31\x32\x23\x02\x02\x07\x04\ -\x04\xb3\xe2\x10\x94\x79\x10\x10\x38\x20\x20\x58\xc0\xf5\xd3\x21\ -\x15\xe9\x8a\x80\xc0\x01\x01\xc1\x52\x4e\x39\x04\xa5\x1f\x02\x02\ -\x07\x04\x04\x8b\xe2\x10\x94\x3e\x08\x08\x1c\x10\x10\x2c\xef\xe0\ -\x9c\x1b\x23\x8d\x08\x08\x1c\x10\x10\xac\x85\x43\x50\x1a\x10\x10\ -\x38\x20\x20\x58\x15\xef\xf5\xcd\x21\x20\x70\x40\x40\xb0\x3e\x0e\ -\x41\xd9\x1b\x01\x81\x03\x02\x02\x17\x1c\x82\xb2\x07\x02\x02\x07\ -\x04\x04\x56\xae\x39\x04\x65\x27\x04\x04\x0e\x08\x08\xfc\x70\x63\ -\xe4\x5d\x04\x04\x0e\x08\x08\x4c\x7d\x3f\x04\x45\x3f\x2d\xf1\x17\ -\x02\x02\x07\x04\x04\xd6\x38\x04\xe5\x6d\x04\x04\x0e\x08\x08\xfc\ -\x71\x08\xca\x5f\x08\x08\x1c\x10\x10\x0c\x82\x43\x50\x7e\x47\x40\ -\xe0\x80\x80\x60\x24\x1c\x82\x22\x04\x04\x0e\x08\x08\xc6\x73\xfa\ -\xb4\xf9\x43\x50\x08\x08\x1c\x10\x10\x0c\x6a\xdb\xef\xf5\x25\x20\ -\x70\x40\x40\x30\xb2\xcd\x1e\x82\x42\x40\xe0\x80\x80\x60\x7c\x1b\ -\x3c\x04\x85\x80\xc0\x01\x01\x41\x11\xdb\x3a\x04\x85\x80\xc0\x01\ -\x01\x41\x25\x9b\xb9\x31\x42\x40\xe0\x80\x80\xa0\x9c\xc7\x0d\x1c\ -\x82\x42\x40\xe0\x80\x80\xa0\xa8\xda\x87\xa0\x10\x10\x38\x20\x20\ -\xa8\xec\xb4\xea\x8d\x11\x02\x02\x07\x04\x04\xe5\x55\x3c\x04\x85\ -\x80\xc0\x01\x01\xc1\x36\x14\x3b\x04\x85\x80\xc0\x01\x01\xc1\x96\ -\x5c\x57\x39\x04\xe5\x5c\x13\x02\xd6\x44\x40\xb0\x39\x15\xde\xeb\ -\x7b\xaa\xb9\x00\x6b\x22\x20\xd8\xa6\xc1\x6f\x8c\x7c\xd2\x34\x80\ -\x35\x11\x10\x6c\xd9\xb0\x87\xa0\x68\xfc\xc0\xaa\x08\x08\x36\xef\ -\xfa\xe3\x78\x37\x46\x34\x74\x60\x55\x04\x04\xf8\x6e\xac\x1b\x23\ -\x67\x1a\x35\xb0\x2a\x02\x02\xfc\x32\xcc\x21\x28\x37\x1a\x30\xb0\ -\x2a\x02\x02\xfc\x61\x80\x1b\x23\xc7\x1a\x2a\xb0\x2a\x02\x02\xbc\ -\xc5\xfb\x10\x14\xf6\x2d\x2c\x70\x21\x02\xa1\x4f\x57\xb7\x96\x37\ -\x46\x8e\x34\x3e\x60\x5d\x04\x04\xf8\xb7\x83\x6f\x76\x87\xa0\x9c\ -\x68\x68\xc0\xba\x08\x08\xb0\x0b\xab\x43\x50\x1e\x35\x28\x60\x5d\ -\x04\x04\xd8\xd9\xe9\xf1\x8d\xc3\x4b\x5a\x0f\x1a\x0e\xb0\x32\x02\ -\x02\xec\x67\xfd\x43\x50\x38\x49\x11\x26\x08\x08\x90\x71\xfe\x79\ -\xb5\x1b\x23\x7c\x8a\x10\x2e\x08\x08\x90\x76\xba\xca\x21\x28\xd7\ -\xfa\xdd\x81\xb5\x11\x10\xa0\xcd\xd2\x87\xa0\x5c\xea\xf7\x05\x56\ -\x47\x40\x80\x0e\x1e\xaf\x16\x3b\x04\x45\xbf\x23\xb0\x3e\x02\x02\ -\x74\xb3\xc4\x21\x28\x9c\x62\x02\x1f\x04\x04\xe8\x6b\xde\x43\x50\ -\x0e\xf5\xbb\x00\x06\x08\x08\x30\x83\xb9\x6e\x8c\xf0\x0e\x2c\x38\ -\x21\x20\xc0\x5c\xfa\x1f\x82\xc2\x21\x58\xb0\x42\x40\x80\x79\x5d\ -\x3f\x1d\xf6\xaa\xc8\x11\xfb\x15\x56\xb8\x20\x81\x05\x74\x39\x04\ -\xe5\x5e\x5f\x0c\x30\x41\x40\x80\xa5\x34\x1e\x82\xc2\xfd\x0f\xb8\ -\x21\x20\xc0\xa2\x0e\xce\x93\x37\x46\x6e\xf5\x05\x00\x1b\x04\x04\ -\x58\xc1\xde\x87\xa0\xdc\x71\x80\x09\xfc\x10\x10\x60\x2d\x7b\xbc\ -\xd7\x97\x47\x48\xc1\x11\x01\x01\x56\xb5\xcb\x21\x28\x17\xfa\xb5\ -\x80\x17\x02\x02\x18\xf8\xc7\x21\x28\x47\x1f\xf5\x6b\x00\x37\x04\ -\x04\x70\x71\xfd\xf7\x21\x28\x67\x9f\x3f\xe9\x5f\x02\x7e\x08\x08\ -\x60\xe5\xeb\xb7\xa7\x9b\xcb\x87\x87\xb3\x2f\x37\x27\xc7\x5f\xf5\ -\xcf\x00\x4f\x04\x04\x00\x90\x42\x40\x00\x00\x29\x04\x04\x00\x90\ -\x42\x40\x00\x00\x29\x04\x04\x00\x90\x42\x40\x00\x00\x29\x04\x04\ -\x00\x90\x42\x40\x00\x00\x29\x04\x04\x00\x90\x42\x40\x00\x00\x29\ -\x04\x04\x00\x90\x42\x40\x00\x00\x29\x04\x04\x00\x90\xf0\xdf\x7f\ -\xff\x03\x6a\xf8\x3b\x61\xbf\x6a\xd6\x0d\x00\x00\x00\x00\x49\x45\ -\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x07\x0a\ -\x3c\ -\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x69\x73\x6f\ -\x2d\x38\x38\x35\x39\x2d\x31\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\ -\x20\x47\x65\x6e\x65\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\ -\x65\x20\x49\x6c\x6c\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\ -\x2e\x30\x2e\x30\x2c\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\ -\x20\x50\x6c\x75\x67\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\ -\x65\x72\x73\x69\x6f\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\ -\x6c\x64\x20\x30\x29\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\ -\x43\x54\x59\x50\x45\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\ -\x20\x22\x2d\x2f\x2f\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\ -\x47\x20\x31\x2e\x31\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\ -\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\ -\x61\x70\x68\x69\x63\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\ -\x54\x44\x2f\x73\x76\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\ -\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ -\x31\x22\x20\x69\x64\x3d\x22\x43\x61\x70\x61\x5f\x31\x22\x20\x78\ -\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\ -\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\ -\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\ -\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\ -\x2f\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\ -\x30\x70\x78\x22\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\ -\x77\x69\x64\x74\x68\x3d\x22\x34\x38\x38\x2e\x34\x34\x36\x70\x78\ -\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x34\x38\x38\x2e\x34\x34\ -\x36\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\ -\x30\x20\x34\x38\x38\x2e\x34\x34\x36\x20\x34\x38\x38\x2e\x34\x34\ -\x36\x22\x20\x73\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\ -\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\ -\x30\x20\x30\x20\x34\x38\x38\x2e\x34\x34\x36\x20\x34\x38\x38\x2e\ -\x34\x34\x36\x3b\x22\x0d\x0a\x09\x20\x78\x6d\x6c\x3a\x73\x70\x61\ -\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\ -\x3c\x67\x3e\x0d\x0a\x09\x3c\x67\x3e\x0d\x0a\x09\x09\x3c\x67\x3e\ -\x0d\x0a\x09\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\ -\x35\x33\x2e\x30\x32\x39\x2c\x39\x30\x2e\x32\x32\x33\x68\x31\x38\ -\x32\x2e\x34\x30\x34\x63\x35\x2e\x34\x32\x37\x2c\x30\x2c\x39\x2e\ -\x38\x37\x33\x2d\x34\x2e\x34\x33\x2c\x39\x2e\x38\x37\x33\x2d\x39\ -\x2e\x38\x36\x39\x56\x30\x48\x31\x34\x33\x2e\x31\x33\x37\x76\x38\ -\x30\x2e\x33\x35\x34\x43\x31\x34\x33\x2e\x31\x33\x37\x2c\x38\x35\ -\x2e\x37\x39\x33\x2c\x31\x34\x37\x2e\x35\x37\x31\x2c\x39\x30\x2e\ -\x32\x32\x33\x2c\x31\x35\x33\x2e\x30\x32\x39\x2c\x39\x30\x2e\x32\ -\x32\x33\x0d\x0a\x09\x09\x09\x09\x7a\x22\x2f\x3e\x0d\x0a\x09\x09\ -\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x38\x30\x2e\x38\ -\x31\x37\x2c\x31\x32\x32\x2e\x38\x36\x34\x4c\x33\x37\x37\x2e\x38\ -\x38\x2c\x31\x39\x2e\x34\x39\x34\x76\x36\x30\x2e\x38\x35\x39\x63\ -\x30\x2c\x32\x33\x2e\x34\x30\x34\x2d\x31\x39\x2e\x30\x34\x33\x2c\ -\x34\x32\x2e\x34\x34\x37\x2d\x34\x32\x2e\x34\x34\x37\x2c\x34\x32\ -\x2e\x34\x34\x37\x48\x31\x35\x33\x2e\x30\x32\x39\x0d\x0a\x09\x09\ -\x09\x09\x63\x2d\x32\x33\x2e\x34\x30\x39\x2c\x30\x2d\x34\x32\x2e\ -\x34\x34\x37\x2d\x31\x39\x2e\x30\x34\x33\x2d\x34\x32\x2e\x34\x34\ -\x37\x2d\x34\x32\x2e\x34\x34\x37\x56\x30\x48\x34\x34\x2e\x38\x32\ -\x33\x43\x32\x30\x2e\x30\x36\x38\x2c\x30\x2c\x30\x2e\x30\x30\x32\ -\x2c\x32\x30\x2e\x30\x37\x2c\x30\x2e\x30\x30\x32\x2c\x34\x34\x2e\ -\x38\x30\x38\x76\x33\x39\x38\x2e\x38\x33\x31\x0d\x0a\x09\x09\x09\ -\x09\x63\x30\x2c\x32\x34\x2e\x37\x33\x36\x2c\x32\x30\x2e\x30\x36\ -\x36\x2c\x34\x34\x2e\x38\x30\x38\x2c\x34\x34\x2e\x38\x32\x31\x2c\ -\x34\x34\x2e\x38\x30\x38\x68\x33\x39\x38\x2e\x38\x31\x33\x63\x32\ -\x34\x2e\x37\x34\x2c\x30\x2c\x34\x34\x2e\x38\x30\x38\x2d\x32\x30\ -\x2e\x30\x36\x38\x2c\x34\x34\x2e\x38\x30\x38\x2d\x34\x34\x2e\x38\ -\x30\x38\x56\x31\x34\x31\x2e\x33\x32\x35\x0d\x0a\x09\x09\x09\x09\ -\x43\x34\x38\x38\x2e\x34\x34\x34\x2c\x31\x33\x34\x2e\x33\x39\x32\ -\x2c\x34\x38\x35\x2e\x36\x39\x38\x2c\x31\x32\x37\x2e\x37\x35\x38\ -\x2c\x34\x38\x30\x2e\x38\x31\x37\x2c\x31\x32\x32\x2e\x38\x36\x34\ -\x7a\x20\x4d\x34\x31\x32\x2e\x34\x36\x31\x2c\x33\x38\x35\x2e\x36\ -\x36\x36\x63\x30\x2c\x31\x34\x2e\x34\x33\x34\x2d\x31\x31\x2e\x37\ -\x30\x33\x2c\x32\x36\x2e\x31\x35\x34\x2d\x32\x36\x2e\x31\x36\x38\ -\x2c\x32\x36\x2e\x31\x35\x34\x48\x31\x30\x32\x2e\x31\x33\x37\x0d\ -\x0a\x09\x09\x09\x09\x63\x2d\x31\x34\x2e\x34\x35\x31\x2c\x30\x2d\ -\x32\x36\x2e\x31\x35\x33\x2d\x31\x31\x2e\x37\x32\x32\x2d\x32\x36\ -\x2e\x31\x35\x33\x2d\x32\x36\x2e\x31\x35\x34\x56\x32\x34\x39\x2e\ -\x33\x30\x33\x63\x30\x2d\x31\x34\x2e\x34\x33\x2c\x31\x31\x2e\x37\ -\x30\x32\x2d\x32\x36\x2e\x31\x34\x38\x2c\x32\x36\x2e\x31\x35\x33\ -\x2d\x32\x36\x2e\x31\x34\x38\x68\x32\x38\x34\x2e\x31\x35\x36\x0d\ -\x0a\x09\x09\x09\x09\x63\x31\x34\x2e\x34\x36\x35\x2c\x30\x2c\x32\ -\x36\x2e\x31\x36\x38\x2c\x31\x31\x2e\x37\x32\x2c\x32\x36\x2e\x31\ -\x36\x38\x2c\x32\x36\x2e\x31\x34\x38\x56\x33\x38\x35\x2e\x36\x36\ -\x36\x7a\x22\x2f\x3e\x0d\x0a\x09\x09\x09\x3c\x70\x61\x74\x68\x20\ -\x64\x3d\x22\x4d\x33\x35\x36\x2e\x34\x39\x37\x2c\x32\x36\x35\x2e\ -\x31\x33\x31\x48\x31\x33\x31\x2e\x39\x34\x39\x63\x2d\x39\x2e\x30\ -\x30\x38\x2c\x30\x2d\x31\x36\x2e\x32\x39\x34\x2c\x37\x2e\x32\x37\ -\x33\x2d\x31\x36\x2e\x32\x39\x34\x2c\x31\x36\x2e\x32\x38\x73\x37\ -\x2e\x32\x38\x36\x2c\x31\x36\x2e\x32\x38\x2c\x31\x36\x2e\x32\x39\ -\x34\x2c\x31\x36\x2e\x32\x38\x68\x32\x32\x34\x2e\x35\x34\x39\x0d\ -\x0a\x09\x09\x09\x09\x63\x38\x2e\x39\x38\x38\x2c\x30\x2c\x31\x36\ -\x2e\x32\x37\x37\x2d\x37\x2e\x32\x37\x33\x2c\x31\x36\x2e\x32\x37\ -\x37\x2d\x31\x36\x2e\x32\x38\x53\x33\x36\x35\x2e\x34\x38\x37\x2c\ -\x32\x36\x35\x2e\x31\x33\x31\x2c\x33\x35\x36\x2e\x34\x39\x37\x2c\ -\x32\x36\x35\x2e\x31\x33\x31\x7a\x22\x2f\x3e\x0d\x0a\x09\x09\x09\ -\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x33\x32\x33\x2e\x39\x33\ -\x36\x2c\x33\x33\x30\x2e\x32\x36\x34\x48\x31\x36\x34\x2e\x35\x30\ -\x38\x63\x2d\x38\x2e\x39\x39\x34\x2c\x30\x2d\x31\x36\x2e\x32\x38\ -\x2c\x37\x2e\x32\x37\x33\x2d\x31\x36\x2e\x32\x38\x2c\x31\x36\x2e\ -\x32\x38\x63\x30\x2c\x38\x2e\x39\x38\x39\x2c\x37\x2e\x32\x38\x36\ -\x2c\x31\x36\x2e\x32\x38\x2c\x31\x36\x2e\x32\x38\x2c\x31\x36\x2e\ -\x32\x38\x68\x31\x35\x39\x2e\x34\x32\x37\x0d\x0a\x09\x09\x09\x09\ -\x63\x38\x2e\x39\x39\x34\x2c\x30\x2c\x31\x36\x2e\x32\x38\x31\x2d\ -\x37\x2e\x32\x39\x31\x2c\x31\x36\x2e\x32\x38\x31\x2d\x31\x36\x2e\ -\x32\x38\x43\x33\x34\x30\x2e\x32\x31\x37\x2c\x33\x33\x37\x2e\x35\ -\x33\x37\x2c\x33\x33\x32\x2e\x39\x33\x2c\x33\x33\x30\x2e\x32\x36\ -\x34\x2c\x33\x32\x33\x2e\x39\x33\x36\x2c\x33\x33\x30\x2e\x32\x36\ -\x34\x7a\x22\x2f\x3e\x0d\x0a\x09\x09\x3c\x2f\x67\x3e\x0d\x0a\x09\ -\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\ -\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\ -\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\ -\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\x2f\x67\ -\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\ -\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\x2f\ -\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\ -\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\ -\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\ -\x3c\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\ -\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\ -\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\ \x00\x00\x04\xcf\ \x00\ \x00\x80\x9c\x78\x9c\xed\x9c\xcf\x6b\x24\x45\x14\xc7\x9f\x5e\x12\ @@ -5343,10 +3266,6 @@ \x0a\x61\x5a\xa7\ \x00\x69\ \x00\x63\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x0c\ -\x05\xac\x5e\xdf\ -\x00\x74\ -\x00\x6f\x00\x52\x00\x61\x00\x73\x00\x74\x00\x65\x00\x72\x00\x2e\x00\x69\x00\x63\x00\x6f\ \x00\x10\ \x02\xd9\x93\xe7\ \x00\x69\ @@ -5365,10 +3284,6 @@ \x02\x8c\x59\xa7\ \x00\x70\ \x00\x6c\x00\x61\x00\x79\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x0e\ -\x08\x91\xae\xbf\ -\x00\x52\ -\x00\x65\x00\x64\x00\x48\x00\x69\x00\x64\x00\x72\x00\x69\x00\x63\x00\x61\x00\x2e\x00\x69\x00\x63\x00\x6f\ \x00\x0a\ \x0c\xf7\x1b\xc7\ \x00\x63\ @@ -5385,14 +3300,6 @@ \x0d\x91\xc1\x87\ \x00\x63\ \x00\x6f\x00\x6f\x00\x72\x00\x64\x00\x43\x00\x61\x00\x70\x00\x74\x00\x75\x00\x72\x00\x65\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x0b\ -\x09\x49\xee\x87\ -\x00\x74\ -\x00\x6f\x00\x65\x00\x78\x00\x63\x00\x65\x00\x6c\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x08\ -\x08\xc8\x55\xe7\ -\x00\x73\ -\x00\x61\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x0a\ \x04\xa1\x18\x1f\ \x00\x63\ @@ -5403,21 +3310,17 @@ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ \x00\x00\x00\x14\x00\x02\x00\x00\x00\x02\x00\x00\x00\x03\ -\x00\x00\x00\x36\x00\x02\x00\x00\x00\x0d\x00\x00\x00\x05\ +\x00\x00\x00\x36\x00\x02\x00\x00\x00\x09\x00\x00\x00\x05\ \x00\x00\x00\x46\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x01\x06\x00\x00\x00\x00\x00\x01\x00\x00\x17\x7b\ -\x00\x00\x00\x7a\x00\x00\x00\x00\x00\x01\x00\x00\x0c\xa3\ -\x00\x00\x01\x72\x00\x00\x00\x00\x00\x01\x00\x00\xad\x7e\ -\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x01\x00\x00\x0f\x16\ -\x00\x00\x01\xea\x00\x01\x00\x00\x00\x01\x00\x01\x45\x81\ -\x00\x00\x00\x5c\x00\x01\x00\x00\x00\x01\x00\x00\x04\x0e\ -\x00\x00\x00\xd2\x00\x00\x00\x00\x00\x01\x00\x00\x13\x4e\ -\x00\x00\x01\x1c\x00\x01\x00\x00\x00\x01\x00\x00\x4c\xdb\ -\x00\x00\x01\xd4\x00\x00\x00\x00\x00\x01\x00\x01\x3e\x73\ -\x00\x00\x01\xb8\x00\x00\x00\x00\x00\x01\x00\x00\xd2\xd8\ -\x00\x00\x01\x58\x00\x00\x00\x00\x00\x01\x00\x00\xa5\xb0\ -\x00\x00\x01\x3e\x00\x00\x00\x00\x00\x01\x00\x00\x52\xdc\ -\x00\x00\x01\x92\x00\x00\x00\x00\x00\x01\x00\x00\xb1\x47\ +\x00\x00\x00\xe8\x00\x00\x00\x00\x00\x01\x00\x00\x0e\xe6\ +\x00\x00\x00\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x04\x0e\ +\x00\x00\x01\x32\x00\x00\x00\x00\x00\x01\x00\x00\x9e\xe8\ +\x00\x00\x00\x82\x00\x00\x00\x00\x00\x01\x00\x00\x06\x81\ +\x00\x00\x01\x78\x00\x01\x00\x00\x00\x01\x00\x00\xc4\x42\ +\x00\x00\x00\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x0a\xb9\ +\x00\x00\x01\x18\x00\x00\x00\x00\x00\x01\x00\x00\x97\x1a\ +\x00\x00\x00\xfe\x00\x00\x00\x00\x00\x01\x00\x00\x44\x46\ +\x00\x00\x01\x52\x00\x00\x00\x00\x00\x01\x00\x00\xa2\xb1\ " def qInitResources(): diff --git a/wmf/wmf.py b/wmf/wmf.py new file mode 100644 index 0000000..e71890a --- /dev/null +++ b/wmf/wmf.py @@ -0,0 +1,4599 @@ +#!Modelos: acoplado con cuencas presenta una serie de modelos hidrologicos distribuidos +#!Copyright (C) <2016> + +#!This program is free software: you can redistribute it and/or modify +#!it under the terms of the GNU General Public License as published by +#!the Free Software Foundation, either version 3 of the License, or +#!(at your option) any later version. + +#!This program is distributed in the hope that it will be useful, +#!but WITHOUT ANY WARRANTY; without even the implied warranty of +#!MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#!GNU General Public License for more details. + +#!You should have received a copy of the GNU General Public License +#!along with this program. If not, see . +#Algo +import matplotlib +matplotlib.use('Agg') +from cu import * +from models import * +import numpy as np +import pylab as pl +import osgeo.ogr, osgeo.osr +import gdal +from scipy.spatial import Delaunay +from scipy.stats import norm +import os +import pandas as pd +import datetime as datetime +from multiprocessing import Pool +import matplotlib.path as mplPath +try: + import netcdf as netcdf +except: + try: + import netCDF4 as netcdf + except: + print 'No netcdf en esta maquina, se desabilita la funcion SimuBasin.save_SimuBasin' + pass +try: + from mpl_toolkits.basemap import Basemap, addcyclic, shiftgrid, cm + from matplotlib.patches import Polygon + from matplotlib.collections import PatchCollection +except: + print 'No se logra importar basemap, por lo tanto no funciona Plot_basin' + pass +try: + from deap import base, creator + from deap import tools + FlagCalib_NSGAII = True +except: + print 'No se logra importar deap tools, por lo tanto se deshabilita SimuBasin.Calib_NSGAII' + FlagCalib_NSGAII = False +try: + import rasterio.features as __fea__ + FlagBasinPolygon = True +except: + print 'No se logra importar rasterio, se deshabilita obtencion de poligono de cuenca' + FlagBasinPolygon = False + +import random +#Variable codigo EPSG +Global_EPSG = -9999 + +#----------------------------------------------------------------------- +#Ploteo de variables +#----------------------------------------------------------------------- +def plot_sim_single(Qs,Qo=None,mrain=None,Dates=None,ruta=None, + figsize=(8,4.5),ids=None,legend=True,ax1 = None,**kwargs): + '''ENTRADAS: + Qs = Caudal simulado, variable tipo lista + Qo = Caudal observado, variable tipo lista + mrain = Lluvia media observada,variable tipo lista + Dates = Indice de tiempo (Datetime), variable tipo lista + ids = Identificador de puntos de control + ax1 = axis o entorno para graficar + **kwargs = Argumentos por defecto, se pueden cambiar. + Estos argumentos son: + + ARGUMENTOS POR DEFECTO + rain_alpha': 0.4, Transparencia de la lluvia + rain_color': blue, Color de la lluvia + rain_lw : 0, Ancho de linea de lluvia + rain_ylabel: Precipitation [$mm$], Etiqueta del eje y de la lluvia + label_size: 14, Tamano de fuente + rain_ylim : Se ajusta, Limite del eje y + ColorSim : ['r','g','k','c','y'], Colores para simulacion de caudal + Qs_lw : 1.5, Ancho de linea de caudal simulado + Qo_lw : 2.0, Ancho de linea de caudal observado + Qs_color : red, Color de linea de caudal simulado + Qo_color : blue, Color de linea de caudal observado + Qo_label : Observed, Leyenda de caudal observado + Qs_label : Simulated, Leyenda de caudal simulado + xlabel : Time [$min$], Etiqueta del eje x + ylabel : Streamflow $[m^3/seg], Etiqueta del eje y + legend_loc : upper center, Ubicacion de la leyenda + bbox_to_anchor : (0.5,-0.12), Ajuste de la caja de la leyenda + legend_ncol : 4, Numero de columnas para la leyenda + ''' + #Argumentos kw + show = kwargs.get('show',True) + if ax1 == None: + fig=pl.figure(facecolor='w',edgecolor='w',figsize=figsize) + ax1=fig.add_subplot(111) + else: + show = False + #Fechas + if Dates==None: + if len(Qs.shape)>1: + ejeX=range(len(Qs[0])) + else: + ejeX = range(len(Qs)) + else: + ejeX=Dates + #Grafica la lluvia + if mrain is not None: + ax1AX=pl.gca() + ax2=ax1.twinx() + ax2AX=pl.gca() + alpha = kwargs.get('rain_alpha',0.4) + color = kwargs.get('rain_color','blue') + lw = kwargs.get('rain_lw',0) + ax2.fill_between(ejeX,0,mrain,alpha=alpha,color=color,lw=lw) + ylabel = kwargs.get('rain_ylabel','Precipitation [$mm$]') + label_size = kwargs.get('label_size',14) + ax2.set_ylabel(ylabel,size=label_size) + ylim = kwargs.get('rain_ylim',ax2AX.get_ylim() [::-1]) + ax2AX.set_ylim(ylim) + else: + ax2 = None + #grafica las hidrografas + ColorSim=kwargs.get('ColorSim',['r','g','k','c','y']) + Qs_lw = kwargs.get('Qs_lw',1.5) + Qo_lw = kwargs.get('Qo_lw',2.0) + Qs_color = kwargs.get('Qs_color','r') + Qo_color = kwargs.get('Qo_color','b') + Qo_label = kwargs.get('Qo_label','Observed') + Qs_label = kwargs.get('Qs_label','Simulated') + if len(Qs.shape)>1: + if ids is None: + ids = np.arange(1,Qs.shape[0]+1) + for i,c,d in zip(Qs,ColorSim,ids): + ax1.plot(ejeX,i,c,lw=Qs_lw,label=str(d)) + else: + ax1.plot(ejeX,Qs,Qs_color,lw=Qs_lw,label=Qs_label) + if Qo is not None: ax1.plot(ejeX,Qo,Qo_color,lw=Qo_lw,label=Qo_label) + #Pone elementos en la figura + xlabel = kwargs.get('xlabel','Time [$min$]') + ylabel = kwargs.get('ylabel','Streamflow $[m^3/seg]$') + label_size = kwargs.get('label_size', 16) + ax1.set_xlabel(xlabel,size=label_size) + ax1.set_ylabel(ylabel,size=label_size) + ax1.grid(True) + loc = kwargs.get('legend_loc','upper center') + bbox_to_anchor = kwargs.get('bbox_to_anchor',(0.5,-0.12)) + ncol = kwargs.get('legend_ncol',4) + if legend == True: + lgn1=ax1.legend(loc=loc, bbox_to_anchor=bbox_to_anchor, + fancybox=True, shadow=True, ncol=ncol) + if ruta is not None: + pl.savefig(ruta, bbox_inches='tight') + if show == True: + pl.show() + return ax1, ax2 + +def plot_mean_storage(Mean_Storage, Dates = None, mrain = None, + rute = None, **kwargs): + 'Funcion: plot_mean_storage\n'\ + 'Descripcion: Plotea como se encuentran los almacenamientos medios en la cuenca.\n'\ + 'Parametros Obligatorios:.\n'\ + ' -Mean_Storage: almacenamiento medio en cada uno de los tanques (5,Npasos).\n'\ + ' Esta es la variables obtenida por wmf.SimuBasin.run_shia como Mean_Storage.\n'\ + 'Parametros Opcionales:.\n'\ + ' -Dates: Fechas para el plot\n'\ + ' -marin: Lluvia promedio sobre la cuenca\n'\ + ' -rute: Ruta donde se va a guardar\n'\ + ' -kwargs: algunos argumentos de set del plot\n'\ + ' - figsize: tamano de la figura.\n'\ + ' - color: Color de los plot.\n'\ + ' - lw: ancho de la linea del plot.\n'\ + ' - labelsize: tamano de los label.\n'\ + ' - ysize: tamano de la fuente en el eje Y.\n'\ + 'Retorno:.\n'\ + ' Plot de los almacenamientos medios.\n'\ + #Argumentos kw + figsize = kwargs.get('figsize',(13,9)) + color = kwargs.get('color','k') + lw = kwargs.get('lw',4) + labelsize = kwargs.get('labelsize', 14) + ysize = kwargs.get('ysize', 16) + show = kwargs.get('show',True) + alpha = kwargs.get('alpha',0.5) + colorRain = kwargs.get('colorRain','b') + lwRain = kwargs.get('lwRain',0.1) + #Inicio de la funcion + if Dates==None: + ejeX=range(Mean_Storage.shape[1]) + else: + ejeX=Dates + #figura + fig = pl.figure(figsize = figsize) + nombres = ['Hu','Runoff','Hg','Sub','Stream'] + for c,i in enumerate(Mean_Storage): + ax = fig.add_subplot(5,1,c+1) + ax.plot(ejeX, i, color, lw = lw) + ax.grid() + # Deja el eje X solo en el ultimo plot + if c<4: + ax.set_xticklabels([]) + ax.tick_params(labelsize = labelsize) + #Pinta la lluvia en el primer plot + if c == 0 and mrain is not None: + ax2=ax.twinx() + ax2AX=pl.gca() + ax2.fill_between(ejeX,0,mrain,alpha=alpha,color=colorRain,lw=lwRain) + ylim = ax2AX.get_ylim()[::-1]; ylim = list(ylim); ylim[1] = 0 + ax2AX.set_ylim(ylim) + #Nombre de cada tanque + ax.set_ylabel(nombres[c], size = ysize) + if rute is not None: + pl.savefig(rute, bbox_inches='tight') + if show == True: + pl.show() + if c == 0 and mrain is not None: + return ax, ax2 + else: + return ax + +#----------------------------------------------------------------------- +#Lectura de informacion y mapas +#----------------------------------------------------------------------- +def read_map_raster(ruta_map,isDEMorDIR=False,dxp=None, noDataP = None,isDIR = False,DIRformat = 'r.watershed'): + 'Funcion: read_map\n'\ + 'Descripcion: Lee un mapa raster soportado por GDAL.\n'\ + 'Parametros Obligatorios:.\n'\ + ' -ruta_map: Ruta donde se encuentra el mapa.\n'\ + 'Parametros Opcionales:.\n'\ + ' -isDEMorDIR: Pasa las propiedades de los mapas al modulo cuencas \n'\ + ' escrito en fortran \n'\ + ' -dxp: tamano plano del mapa\n'\ + ' -noDataP: Valor para datos nulos en el mapa (-9999)\n'\ + ' -DIRformat: donde se ha conseguido el mapa dir (r.watershed) \n'\ + ' - r.watershed: mapa de direcciones obtenido por la funcion de GRASS\n'\ + ' - opentopo: mapa de direcciones de http://www.opentopography.org/\n'\ + ' -isDIR: (FALSE) es este un mapa de direcciones\n'\ + 'Retorno:.\n'\ + ' Si no es DEM o DIR retorna todas las propieades del elemento en un vector.\n'\ + ' En el siguiente orden: ncols,nrows,xll,yll,dx,nodata.\n'\ + ' Si es DEM o DIR le pasa las propieades a cuencas para el posterior trazado.\n'\ + ' de cuencas y tramos.\n' \ + #Abre el mapa + direction=gdal.Open(ruta_map) + #Proyecction + proj = osgeo.osr.SpatialReference(wkt=direction.GetProjection()) + EPSG_code = proj.GetAttrValue('AUTHORITY',1) + #lee la informacion del mapa + ncols=direction.RasterXSize + nrows=direction.RasterYSize + banda=direction.GetRasterBand(1) + noData=banda.GetNoDataValue() + geoT=direction.GetGeoTransform() + dx=geoT[1] + dy = np.abs(geoT[-1]) + xll=geoT[0]; yll=geoT[3]-nrows*dy + #lee el mapa + Mapa=direction.ReadAsArray() + direction.FlushCache() + del direction + if isDEMorDIR==True: + cu.ncols=ncols + cu.nrows=nrows + if noDataP is not None: + cu.nodata = noDataP + Mapa[Mapa<0] = cu.nodata + else: + cu.nodata=noData + cu.dx=dx + cu.dy = dy + cu.xll=xll + cu.yll=yll + if dxp==None: + cu.dxp=30.0 + else: + cu.dxp=dxp + #Guarda la variable para el proyecto + global Global_EPSG + Global_EPSG = EPSG_code + # si es un dir se fija si es de r.watershed + if isDIR: + if DIRformat == 'r.watershed': + Mapa[Mapa<=0] = cu.nodata.astype(int) + Mapa = cu.dir_reclass_rwatershed(Mapa.T,cu.ncols,cu.nrows) + return Mapa, EPSG_code + if DIRformat == 'opentopo': + Mapa[Mapa<=0] = cu.nodata.astype(int) + Mapa = cu.dir_reclass_opentopo(Mapa.T,cu.ncols,cu.nrows) + return Mapa, EPSG_code + #retorna el mapa + return Mapa.T,EPSG_code + else: + return Mapa.T,[ncols,nrows,xll,yll,dx,dy,noData],EPSG_code + +def read_map_points(ruta_map, ListAtr = None): + 'Funcion: read_map_points\n'\ + 'Descripcion: Lee un mapa vectorial de puntos soportado por GDAL.\n'\ + 'Parametros Obligatorios:.\n'\ + ' -ruta_map: Ruta donde se encuentra el mapa.\n'\ + 'Parametros Opcionales:.\n'\ + ' -ListAtr: Lista con los nombres de los atributos de las columnas\n'\ + ' que se quieren leer dentro de la variable Dict\n'\ + 'Retorno:.\n'\ + ' Si ListAtr == None: Retorna unicamente las coordenadas.\n'\ + ' Si ListAtr == [Nombre1, Nombre2, ...]: Retorna: Coord y diccionario con variables.\n'\ + #Obtiene el acceso + dr = osgeo.ogr.Open(ruta_map) + l = dr.GetLayer() + #Lee las coordenadas + Cord = [] + for i in range(l.GetFeatureCount()): + f = l.GetFeature(i) + g = f.GetGeometryRef() + pt = [g.GetX(),g.GetY()] + Cord.append(pt) + Cord = np.array(Cord).T + #Si hay atributos para buscar los lee y los m + if ListAtr is not None: + Dict = {} + for j in ListAtr: + #Busca si el atributo esta + pos = f.GetFieldIndex(j) + #Si esta lee la info del atributo + if pos is not -1: + vals = [] + for i in range(l.GetFeatureCount()): + f = l.GetFeature(i) + vals.append(f.GetField(pos)) + Dict.update({j:np.array(vals)}) + #Cierra el mapa + dr.Destroy() + return Cord, Dict + else: + #Cierra el mapa + dr.Destroy() + return Cord + +def Save_Array2Raster(Array, ArrayProp, ruta, EPSG = 4326, Format = 'GTiff'): + dst_filename = ruta + #Formato de condiciones del mapa + x_pixels = Array.shape[0] # number of pixels in x + y_pixels = Array.shape[1] # number of pixels in y + PIXEL_SIZE = ArrayProp[4] # size of the pixel... + x_min = ArrayProp[2] + y_max = ArrayProp[3] + ArrayProp[4] * ArrayProp[1] # x_min & y_max are like the "top left" corner. + driver = gdal.GetDriverByName(Format) + #Para encontrar el formato de GDAL + NP2GDAL_CONVERSION = { + "uint8": 1, + "int8": 1, + "uint16": 2, + "int16": 3, + "uint32": 4, + "int32": 5, + "float32": 6, + "float64": 7, + "complex64": 10, + "complex128": 11, + } + gdaltype = NP2GDAL_CONVERSION[Array.dtype.name] + # Crea el driver + dataset = driver.Create( + dst_filename, + x_pixels, + y_pixels, + 1, + gdaltype,) + #coloca la referencia espacial + dataset.SetGeoTransform(( + x_min, # 0 + PIXEL_SIZE, # 1 + 0, # 2 + y_max, # 3 + 0, # 4 + -PIXEL_SIZE)) + #coloca la proyeccion a partir de un EPSG + proj = osgeo.osr.SpatialReference() + texto = 'EPSG:' + str(EPSG) + proj.SetWellKnownGeogCS( texto ) + dataset.SetProjection(proj.ExportToWkt()) + #Coloca el nodata + band = dataset.GetRasterBand(1) + if ArrayProp[-1] == None: + band.SetNoDataValue(wmf.cu.nodata.astype(int).max()) + else: + band.SetNoDataValue(-9999) + #Guarda el mapa + dataset.GetRasterBand(1).WriteArray(Array.T) + dataset.FlushCache() + +def Save_Points2Map(XY,ids,ruta,EPSG = 4326, Dict = None, + DriverFormat='ESRI Shapefile'): + 'Funcion: Save_Points2Map\n'\ + 'Descripcion: Guarda coordenadas X,Y en un mapa tipo puntos.\n'\ + 'Parametros Opcionales:.\n'\ + 'XY: Coordenadas de los puntos X,Y.\n'\ + 'ids: Numero que representa a cada punto.\n'\ + 'ruta: Ruta de escritura de los puntos.\n'\ + 'Opcionales:.\n'\ + 'EPSG : Codigo del tipo de proyeccion usada, defecto 4326 de WGS84.\n'\ + 'Dict : Diccionario con prop de los puntos, Defecto: None.\n'\ + 'DriverFormat : Formato del archivo vectorial, Defecto: ESRI Shapefile.\n'\ + 'Retorno:.\n'\ + ' Escribe el mapa en la ruta especificada.\n'\ + #Genera el shapefile + spatialReference = osgeo.osr.SpatialReference() + spatialReference.ImportFromEPSG(EPSG) + driver = osgeo.ogr.GetDriverByName(DriverFormat) + if os.path.exists(ruta): + driver.DeleteDataSource(ruta) + shapeData = driver.CreateDataSource(ruta) + layer = shapeData.CreateLayer('layer1', spatialReference, osgeo.ogr.wkbPoint) + layerDefinition = layer.GetLayerDefn() + new_field=osgeo.ogr.FieldDefn('Estacion',osgeo.ogr.OFTReal) + layer.CreateField(new_field) + if Dict is not None: + for p in Dict.keys(): + tipo = type(Dict[p][0]) + if tipo is np.float64: + new_field=osgeo.ogr.FieldDefn(p[:10],osgeo.ogr.OFTReal) + elif tipo is np.int64: + new_field=osgeo.ogr.FieldDefn(p[:10],osgeo.ogr.OFTInteger) + elif tipo is str: + new_field=osgeo.ogr.FieldDefn(p[:10],osgeo.ogr.OFTString) + layer.CreateField(new_field) + #Mete todos los puntos + featureIndex=0 + contador=0 + #Calcula el tamano de la muestra + N=np.size(XY,axis=1) + if N>1: + for i in XY.T: + if i[0]<>-9999.0 and i[1]<>-9999.0: + #inserta el punto + point = osgeo.ogr.Geometry(osgeo.ogr.wkbPoint) + point.SetPoint(0, float(i[0]), float(i[1])) + feature = osgeo.ogr.Feature(layerDefinition) + feature.SetGeometry(point) + feature.SetFID(featureIndex) + feature.SetField('Estacion',ids[contador]) + #Le coloca lo del diccionario + if Dict is not None: + for p in Dict.keys(): + tipo = type(Dict[p][0]) + if tipo is np.float64: + feature.SetField(p[:10],float("%.2f" % Dict[p][contador])) + elif tipo is np.int64: + feature.SetField(p[:10],int("%d" % Dict[p][contador])) + elif tipo is str: + feature.SetField(p[:10],Dict[p][contador]) + #Actualiza contadores + contador+=1 + layer.CreateFeature(feature) + point.Destroy() + feature.Destroy() + else: + point = osgeo.ogr.Geometry(osgeo.ogr.wkbPoint) + point.SetPoint(0, float(XY[0,0]), float(XY[1,0])) + feature = osgeo.ogr.Feature(layerDefinition) + feature.SetGeometry(point) + feature.SetFID(featureIndex) + feature.SetField('Estacion',ids) + for p in Dict.keys(): + feature.SetField(p[:p.index('[')].strip()[:10],float("%.2f" % Param[p])) + contador+=1 + layer.CreateFeature(feature) + point.Destroy() + feature.Destroy() + shapeData.Destroy() + +def __ListaRadarNames__(ruta,FechaI,FechaF,fmt,exten,string,dt): + 'Funcion: OCG_param\n'\ + 'Descripcion: Obtiene una lista con los nombres para leer datos de radar.\n'\ + 'Parametros:.\n'\ + ' -FechaI, FechaF: Fechas inicial y final en formato datetime.\n'\ + ' -fmt : Formato en el que se pasa FechaI a texto, debe couincidir con.\n'\ + ' el del texto que se tenga en los archivos.\n'\ + ' -exten : Extension de los archivos .asc, .nc, .bin ...\n'\ + ' -string : texto antes de la fecha.\n'\ + ' -dt : Intervalos de tiempo entre los eventos.\n'\ + 'Retorno:.\n'\ + ' Lista : la lista de python con los nombres de los binarios.\n'\ + #Crea lista de fechas y mira que archivos estan en esas fechas + Dates=[FechaI]; date=FechaI + while datei: + Flag = True + c2 = c + c3 = 0 + while Flag: + if i= Y.size: Flag = False + else: + Flag=False + Pos.append(c2) + c+=1 + # Obtiene la segunda derivada de la corriente corregida + Y = pd.rolling_mean(Y,window) + l = Y[np.isnan(Y)].shape[0] + Y[:l]=Y[l+1] + slope = np.diff(Y,1) + slope = np.hstack([slope,slope[-1]]) + return Y,np.abs(slope) + +#----------------------------------------------------------------------- +#Clase de cuencas +#----------------------------------------------------------------------- + +class Basin: + + #------------------------------------------------------ + # Subrutinas de trazado de cuenca y obtencion de parametros + #------------------------------------------------------ + #Inicia la cuenca + def __init__(self,lat=0,lon=0,DEM=None,DIR=None,name='NaN',stream=None, + umbral=1000, ruta = None, useCauceMap = None): + 'Descripcion: Inicia la variable de la cuenca, y la traza \n'\ + ' obtiene las propiedades basicas de la cuenca. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'lat : Coordenada en X de la salida de la cuenca.\n'\ + 'lon : Coordenada en Y de la salida de la cuenca.\n'\ + 'name : Nombre con el que se va a conocer la cuenca.\n'\ + 'stream : Opcional, si se coloca, las coordenadas no tienen.\n'\ + ' que ser exactas, estas se van a corregir para ubicarse.\n'\ + ' en el punto mas cercano dentro de la corriente, este.\n'\ + ' debe ser un objeto del tipo stream.\n'\ + 'umbral : umbral minimo para la creacion de cauce (defecto =1000).\n'\ + 'ruta : Ruta donde se encuentra un archivo binario de la cuenca.\n'\ + 'useCauceMap : Si se asigna un mapa binario donde 1 es cauce y 0 es ladera.\n'\ + ' el trazador corregira las coordenadas para que estas lleguen a una celda.\n'\ + ' tipo cauce y se trace la cuenca de forma correcta (esta opcion deshabilita \n'\ + ' a stream)\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas.\n'\ + #Relaciona con el DEM y el DIR + self.DEM=DEM + self.DIR=DIR + #Si se da la opcion de que use el useCauceMap deshabilita stream + if useCauceMap is not None: + stream = None + #Si se entrega cauce corrige coordenadas + if ruta == None: + # Si se da el stream corrige por corriente + if stream is not None: + error=[] + for i in stream.structure.T: + error.append( np.sqrt((lat-i[0])**2+(lon-i[1])**2) ) + loc=np.argmin(error) + lat=stream.structure[0,loc] + lon=stream.structure[1,loc] + if useCauceMap is not None and useCauceMap.shape == DEM.shape: + lat,lon = cu.stream_find_to_corr(lat,lon,DEM,DIR,useCauceMap, + cu.ncols,cu.nrows) + #copia la direccion de los mapas de DEM y DIR, para no llamarlos mas + self.name=name + #Traza la cuenca + self.ncells = cu.basin_find(lat,lon,DIR, + cu.ncols,cu.nrows) + self.structure = cu.basin_cut(self.ncells) + self.umbral = umbral + else: + self.__Load_BasinNc(ruta) + #Genera el poligono de la cuenca + self.__GetBasinPolygon__() + #Cargador de cuenca + def __Load_BasinNc(self,ruta,Var2Search=None): + 'Descripcion: Lee una cuenca posteriormente guardada\n'\ + ' La cuenca debio ser guardada con Basin.Save_Basin2nc\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'ruta : ruta donde se encuentra ubicada la cuenca guardada\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : La cuenca con sus parametros ya cargada.\n'\ + #Abre el archivo binario de la cuenca + self.rutaNC = ruta + gr = netcdf.Dataset(ruta,'a') + #obtiene las prop de la cuenca + self.name = gr.nombre + self.ncells = gr.ncells + self.umbral = gr.umbral + #Obtiene las prop de los mapas + cu.ncols=gr.ncols + cu.nrows=gr.nrows + cu.nodata=gr.noData + cu.dx=gr.dx + cu.xll=gr.xll + cu.yll=gr.yll + cu.dxp=gr.dxp + #Obtiene las variables vectoriales + self.structure = gr.variables['structure'][:] + #Cierra el archivo + gr.close() + + def Load_BasinVar(self, varName): + 'Descripcion: Lee una variable especifica del netCDf de la cuenca\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'varName: nombre de la variable guardada\n'\ + 'Retornos\n'\ + '----------\n'\ + 'var : Retorna la variable como un numpy array.\n'\ + #Lectura del netCDf y lectura de variable + gr = netcdf.Dataset(self.rutaNC,'a') + Var = gr.variables[varName][:] + gr.close() + return Var + + #Guardado de de la cuenca en nc + def Save_Basin2nc(self,ruta,qmed=None,q233=None,q5=None, + ExtraVar=None): + 'Descripcion: guarda una cuenca previamente ejecutada\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'ruta : Ruta donde la cuenca sera guardada.\n'\ + 'qmed : Matriz con caudal medio estimado.\n'\ + 'q233 : Matriz con caudal minimo de 2.33.\n'\ + 'q5 : Matriz con caudal minimo de 5.\n'\ + 'ExtraVar: Diccionario con variables extras que se quieran guardar,.\n'\ + ' se guardan como flotantes.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas.\n'\ + #Diccionario con las propiedades + Dict = {'nombre':self.name, + 'noData':cu.nodata, + 'ncells':self.ncells, + 'umbral':self.umbral, + 'dxp':cu.dxp, + 'dx':cu.dx, + 'xll':cu.xll, + 'yll':cu.yll, + 'ncols':cu.ncols, + 'nrows':cu.nrows} + #abre el archivo + gr = netcdf.Dataset(ruta,'w',format='NETCDF4') + #Establece tamano de las variables + DimNcell = gr.createDimension('ncell',self.ncells) + DimCol3 = gr.createDimension('col3',3) + #Crea variables + VarStruc = gr.createVariable('structure','i4',('col3','ncell'),zlib=True) + VarQmed = gr.createVariable('q_med','f4',('ncell',),zlib=True) + VarQ233 = gr.createVariable('q_233','f4',('ncell',),zlib=True) + VarQ5 = gr.createVariable('q_5','f4',('ncell',),zlib=True) + #Variables opcionales + if type(ExtraVar) is dict: + for k in ExtraVar.keys(): + Var = gr.createVariable(k,'f4',('ncell',),zlib=True) + Var[:] = ExtraVar[k] + #Asigna valores a las variables + VarStruc[:] = self.structure + if qmed is not None: + VarQmed[:] = qmed + if q233 is not None: + VarQ233[:] = q233 + if q5 is not None: + VarQ5[:] = q5 + #asignlas prop a la cuenca + gr.setncatts(Dict) + #Cierra el archivo + gr.close() + #Sale del programa + return + #Parametros Geomorfologicos + def GetGeo_Parameters(self,rutaParamASC=None,plotTc=False, + rutaTcPlot = None, figsize=(8,5), GetPerim=True): + 'Descripcion: Obtiene los parametros geomorfologicos de la cuenca \n'\ + ' y los tiempos de concentracion calculados por diferentes metodologias. \n'\ + '\n'\ + 'Parametros\n'\ + ' rutaParamASC: ruta del ascii donde se escriben los param.\n'\ + ' plotTc: Plotea o no los tiempos de concentracion.\n'\ + ' rutaTcPlot: Si se da se guarda la figura de tiempos de concentracion.\n'\ + '----------\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'GeoParameters : Parametros de la cuenca calculados.\n'\ + 'Tc : Tiempo de concentracion calculado para la cuenca.\n'\ + #Calcula lo que se necesita para sacar los parametros + acum,longCeld,slope,Elev=cu.basin_basics(self.structure, + self.DEMvec,self.DIRvec,self.ncells) + Lpma,puntto=cu.basin_findlong(self.structure,self.ncells) + cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod(self.structure, + acum,self.umbral,self.ncells) + ppal_nceldas,punto = cu.basin_ppalstream_find(self.structure, + nodos,longCeld,Elev,self.ncells) + ppal = cu.basin_ppalstream_cut(ppal_nceldas,self.ncells) + self.hipso_main,self.hipso_basin=cu.basin_ppal_hipsometric( + self.structure,Elev,punto,30,ppal_nceldas,self.ncells) + self.main_stream=ppal + #Obtiene los parametros + Perim = self.Polygon.shape[1]*cu.dxp/1000. + Area=(self.ncells*cu.dxp**2)/1e6 + TotalCauces = self.CellCauce*self.CellLong + TotalCauces = TotalCauces.sum() / 1000. #[km] + Densidad = TotalCauces / Area #[km/km2] + Lcau=ppal[1,-1]/1000.0 + Scau=np.polyfit(ppal[1,::-1],ppal[0],1)[0]*100 + Scue=slope.mean()*100 + Hmin=Elev[-1]; Hmax=Elev[puntto]; Hmean=Elev.mean() + HCmax=Elev[punto] + x,y = cu.basin_coordxy(self.structure,self.ncells) + CentXY = [np.median(x),np.median(y)] + #Genera un diccionario con las propiedades de la cuenca + self.GeoParameters={'Area_[km2]': Area, + 'Pend_Cauce_[%]':Scau, + 'Long_Cauce_[km]': Lcau, + 'Pend_Cuenca_[%]': Scue, + 'Long_Cuenca_[km]': Lpma, + 'Hmax_[m]':Hmax, + 'Hmin_[m]':Hmin, + 'Hmean_[m]':Hmean, + 'H_Cauce_Max_[m]':HCmax, + 'Centro_[X]': CentXY[0], + 'Centro_[Y]': CentXY[1], + 'Long_tot_cauces_[km]': TotalCauces, + 'Densidad_drenaje_[km/km2]': Densidad} + if GetPerim: + self.GeoParameters.update({'Perimetro_[km]':Perim}) + #Calcula los tiempos de concentracion + Tiempos={} + Tc=0.3*(Lcau/(Scue**0.25))**0.75 + Tiempos.update({'US Army': Tc}) + Tc=0.3*(Lcau/((Hmax-Hmin)/Lcau)**0.25)**0.75 + Tiempos.update({'Direccion Carreteras Espana': Tc}) + Tc=(0.02*(Lpma*1000.0)**0.77)/((Scau/100.0)**0.385)/60.0 + Tiempos.update({'Kiprich': Tc}) + Tc=8.157*((Area**0.316)/(((Scau*100)**0.17)*Scue**0.565)) + Tiempos.update({'Campo y Munera': Tc}) + Tc=(4*np.sqrt(Area)+1.5*Lcau)/(0.8*np.sqrt(Hmean)) + Tiempos.update({'Giandotti':Tc}) + Tc=0.4623*(Lcau**0.5)*((Scue/100.0)**(-0.25)) + Tiempos.update({'John Stone': Tc}) + Tc=(Lcau/Area)*(np.sqrt(Area)/Scau) + Tiempos.update({'Ventura': Tc}) + Tc=0.3*(Lcau/(((HCmax-Hmin)/Lcau)*100)**0.25)**0.75 + Tiempos.update({'Temez': Tc}) + self.Tc=Tiempos + #Si se habilita la funcion para guardar el ascii de param lo hace + if rutaParamASC is not None: + self.__WriteGeoParam__(rutaParamASC) + # Grafica Tc si se habilita + if plotTc is True: + self.Plot_Tc(ruta = rutaTcPlot, figsize=figsize) + #Funcion para escribir los parametros de la cuenca en un ascii + def __WriteGeoParam__(self,ruta): + f=open(ruta,'w') + f.write('------------------------------------------------------------ \n') + f.write('Parametros Cuenca \n') + f.write('------------------------------------------------------------ \n') + k=self.GeoParameters.keys() + for i in k: + v=self.GeoParameters[i] + if type(v) is not list: + f.write('%s : %.4f \n' % (i,v)) + f.write('------------------------------------------------------------ \n') + f.write('Tiempos de concentracion \n') + f.write('------------------------------------------------------------ \n') + k=self.Tc.keys() + for i in k: + v=self.Tc[i] + f.write('%s : %.4f \n' % (i,v)) + f.close() + + #Obtiene la envolvente de la cuenca + def __GetBasinPolygon__(self): + 'Descripcion: obtiene la envolvente de la cuenca, en coordenadas \n'\ + ' x,y, esta informacion luego sirve para plot y para escribir el\n'\ + ' shpfile de la cuenca\n'\ + #Evalua si se cuenta con rasterio en el sistema o no. + if FlagBasinPolygon: + #Obtiene mapa raster, propiedades geo y formato para escribir + Map, Prop = self.Transform_Basin2Map(np.ones(self.ncells)) + tt = [Prop[2], Prop[4].tolist(), 0.0, + Prop[1]*Prop[-2] + Prop[3], 0.0, -1*Prop[5].tolist()] + #Obtiene los shps con la forma de la o las envolventes de cuenca + Map = Map.T + mask = Map != -9999. + shapes = __fea__.shapes(Map, mask=mask, transform=tt) + #Obtiene el poligono de la cuenca completo + Shtemp = [] + flag = True + while flag: + try: + Shtemp.append(shapes.next()) + except: + flag = False + DicPoly = {} + for Sh in Shtemp: + Coord = Sh[0]['coordinates'] + Value = int(Sh[1]) + DicPoly.update({str(Value):{}}) + for cont,co in enumerate(Coord): + DicPoly[str(Value)].update({str(cont):np.array(co).T}) + #Por si hay mas de un poligono al interior + Tam = 0 + for k in DicPoly['1'].keys(): + if DicPoly['1'][k].size > Tam: + Tam = DicPoly['1'][k].size + goodKey = k + self.Polygon = DicPoly['1'][goodKey] + return 0 + else: + return 1 + + #Parametros por mapas (distribuidos) + def GetGeo_Cell_Basics(self): + 'Descripcion: Obtiene: area acumulada, long de celdas, Pendiente \n'\ + ' y Elevacion en cada elemento de la cuenca. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'CellAcum : Cantidad de celdas acumuladas.\n'\ + 'CellLong : Longitud de cada una de las celdas [mts].\n'\ + 'CellSlope : Pendiente de cada una de las celdas [y/x].\n'\ + 'CellHeight : Elevacion de cada una de las celdas [m.s.n.m].\n'\ + #obtiene los parametros basicos por celdas + acum,longCeld,S0,Elev=cu.basin_basics(self.structure, + self.DEMvec,self.DIRvec,self.ncells) + self.CellAcum=acum; self.CellLong=longCeld + self.CellSlope=S0; self.CellHeight=Elev + #Obtiene el canal en la cuenca + self.CellCauce = np.zeros(self.ncells) + self.CellCauce[self.CellAcum>self.umbral]=1 + def GetGeo_StreamOrder(self, MajorBasins = False, umbral = 100, verbose = False, FirtsOrder = 1): + 'Descripcion: Obtiene el orden de horton para cada celda de \n'\ + ' cada ladera y para las celdas de cada cauce.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + 'MajorBasins : Obtiene binarios con las sub-cuencas drenando.\n'\ + ' unicamente a cuencas de orden mayor (ej: todas las orden 2 que \n'\ + ' drenan a orden 3 o major).\n'\ + 'umbral: Cantidad minima de celdas para considerar canal (aplica cuando\n'\ + ' se obtienen las sub-cuencas mayores.\n'\ + 'verbose: Muestra el paso de calculo de cuencas mayores.\n'\ + 'FirtsOrder: Primer orden a partir dle cual se analizan ordenes mayores.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'CellHorton_Hill : Orden de horton de cada ladera.\n'\ + 'CellHorton_Stream : Orden de horton de cada elemento de cauce.\n'\ + #obtiene los parametros basicos por celdas + cauce,nodos_fin,n_nodos = cu.basin_subbasin_nod(self.structure,self.CellAcum,self.umbral,self.ncells) + sub_pert,sub_basin = cu.basin_subbasin_find(self.structure,nodos_fin,n_nodos,self.ncells) + sub_basins = cu.basin_subbasin_cut(n_nodos) + sub_horton,nod_horton = cu.basin_subbasin_horton(sub_basins,self.ncells,n_nodos) + self.CellHorton_Hill,sub_basin = cu.basin_subbasin_find(self.structure,nod_horton,n_nodos,self.ncells) + #Obtiene el canal en la cuenca + self.CellHorton_Stream = self.CellCauce * self.CellHorton_Hill + #Obtiene las cuencas mayores + if MajorBasins: + pos = np.where(models.control>0)[1] + X,Y = cu.basin_coordxy(self.structure, self.ncells) + DictBasins = {} + for Orden in range(FirtsOrder,self.CellHorton_Hill[-1]): + #Encuentra cuencas de un orden que drenen a un orden mayor + pos2 = np.where(self.CellHorton_Stream[pos] == Orden)[0] + drena = self.ncells - self.structure[0] + pos3 = np.where(self.CellHorton_Stream[drena[pos[pos2]]] > Orden)[0] + #Las ubica en un mapa dentro d ela cuenca + SubCuencas = np.zeros(self.ncells) + cont = 1 + for x,y in zip(X[pos[pos2[pos3]]], Y[pos[pos2[pos3]]]): + #Traza la cuenca + cuTemp = SimuBasin(x,y, self.DEM, self.DIR, umbral=umbral) + #La pega en una mascara con las cub-cuencas + Map, prop = cuTemp.Transform_Basin2Map(np.ones(cuTemp.ncells),) + Map[Map == -9999] = 0 + Var = self.Transform_Map2Basin(Map, prop) + Var[Var == 0] = -9999 + Var[Var == 1] = cont + ptemp = np.where(Var == cont)[0] + #Lo pega en la mascara de sub-uencas + SubCuencas[ptemp] = SubCuencas[ptemp] + Var[ptemp] + cont+=1 + #Agrega al diccionario + DictBasins.update({str(Orden):SubCuencas}) + #Si es verbose muestra en que paso va + if verbose: + print 'Sub-cuencas orden '+str(Orden)+' calculadas' + #Traza la cuenca original para no danar la estructura de guardado + cuTemp = SimuBasin(X[-1], Y[-1], self.DEM, self.DIR, umbral = umbral) + #Retorna el diccionario con las sub-cuencas mayore + return DictBasins + def GetGeo_IsoChrones(self,Tc,Niter=4): + 'Descripcion: Obtiene el tiempo de viaje aproximado de cada \n'\ + ' celda a la salida de la cuenca, para eso usa el tiempo de . \n'\ + ' concentracion obtenido por la funcion GetGeo_Parameters . \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + ' self : no necesita nada es autocontenido.\n'\ + ' Tc : Valor escalar de tiempo de concentracion.\n'\ + ' Niter: Cantidad de iteraciones para aproximar vel, defecto 4.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'isochrones : Mapa de viaje de cada celda a la salida [hrs].\n'\ + #Calcula la velocidad adecuada para que el tiempo coincida + acum,longCeld,S0,Elev=cu.basin_basics(self.structure, + self.DEM,self.DIR,cu.ncols,cu.nrows,self.ncells) + rangos=[50,25,1] + for i in range(Niter): + times=[] + for r in rangos: + speed = r*S0**(0.5) + time = cu.basin_time_to_out(self.structure, + longCeld,speed,self.ncells)/3600.0 + times.append(time[np.isfinite(time)].mean()) + for j in range(2): + if Tc>times[j] and Tc=i) & (time0], bins = binsN) + #Variables del elemento + self.width_hits = hn + self.width_distances = bn[:-1]/1000. + #Estandariza en terminos de probabilidad + hc = hc.astype(float); hc = hc / hc.sum() + hn = hn.astype(float); hn = hn / hn.sum() + #Grafica + fig = pl.figure(figsize=figsize) + ax = fig.add_subplot(111) + ax.plot(bc[:-1]/1000.0, hc, ccolor, lw = 3, label = 'Basin Width') + ax.plot(bn[:-1]/1000.0, hn, ncolor,lw = 3, label = 'Network Width') + ax.grid(True) + ax.set_xlabel('Distance to Outlet [$km$]', size = 16) + ax.set_ylabel('PDF', size = 16) + ax.fill_between(bc[:-1]/1000.0, hc, color = ccolor, alpha = 0.3) + ax.fill_between(bn[:-1]/1000.0, hn, color = ncolor, alpha = 0.3) + ax.set_ylim(0, np.max([hc.max(), hn.max()])+0.01) + ax.tick_params(labelsize = 15) + ax.legend(loc = 0) + ax2 = ax.twinx() + ax2.plot(bc[:-1]/1000.0, hc.cumsum(), ccolor, lw = 3, ls = '--', label = 'Basin Width') + ax2.plot(bn[:-1]/1000.0, hn.cumsum(), ncolor, lw = 3, ls = '--',label = 'Network Width') + ax2.tick_params(labelsize = 15) + ax2.set_ylabel('CDF', size = 16) + #Guarda la figura + if ruta is not None: + pl.savefig(ruta, bbox_inches='tight',pad_inches = 0.25) + if show: + pl.show() + #Retorna ejes de manipulacion + return ax,ax2 + + def GetGeo_Ppal_Hipsometric(self,umbral=1000, + intervals = 30): + 'Descripcion: Calcula y grafica la curva hipsometrica de\n'\ + ' la cuenca.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'umbral : cantidad minima de celdas para el trazado.\n'\ + 'intervals: Cantidad de intervalos en los cuales se haran .\n'\ + ' los muestreos de la curva hipsometrica.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Hipso : Curva hipsometrica en formato vectorial, contiene.\n'\ + ' - Curva sobre cauce ppal.\n'\ + ' - Curva como histograma de la cuenca.\n'\ + 'Figura: Figura de ambas curvas.\n'\ + # Obtiene los nodos de la red hidrica + cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( + self.structure, + self.CellAcum, + umbral, + self.ncells) + # Obtiene el cauce ppal + ppal_nceldas,punto = cu.basin_ppalstream_find( + self.structure, + nodos, + self.CellLong, + self.CellHeight, + self.ncells) + self.ppal_stream = cu.basin_ppalstream_cut(ppal_nceldas, + self.ncells) + #Corrige el perfil del cauce ppal + self.ppal_stream[0],self.ppal_slope = __ModifyElevErode__(self.ppal_stream[0]) + # Obtiene la curva hipsometrica + self.hipso_ppal, self.hipso_basin = cu.basin_ppal_hipsometric( + self.structure, + self.CellHeight, + punto, + intervals, + ppal_nceldas) + self.hipso_ppal[1],self.hipso_ppal_slope = __ModifyElevErode__(self.hipso_ppal[1]) + def GetGeo_IT(self): + 'Descripcion: Calcula el indice topografico para cada celda (Beven)\n'\ + ' Internamente calcula el area para cada elemento y la pendiente en radianes.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'IT : Indice topografico adimensional, a mayor valor se supone un suelo mas humedo.\n'\ + #Obtiene el area + acum = cu.basin_acum(self.structure, self.ncells) + #Obtiene la pendiente en radianes + acum,longCeld,slope,Elev=cu.basin_basics(self.structure, + self.DEMvec,self.DIRvec,self.ncells) + slope = np.arctan(slope) + slope[slope == 0] = 0.0001 + return np.log((acum*cu.dxp) / np.tan(slope)) + + def GetGeo_HAND(self,umbral=1000): + 'Descripcion: Calcula Height Above the Nearest Drainage (HAND) \n'\ + ' y Horizontal Distance to the Nearest Drainage (HDND) (Renno, 2008). \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + 'umbral : cantidad minima de celdas para el trazado.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'HAND : Elevacion sobre la red de drenaje cercana [mts].\n'\ + 'HDND : Distancia horizontal a la red de drenaje cercana [mts].\n'\ + #obtiene los parametros basicos por celdas + acum,longCeld,S0,Elev=cu.basin_basics(self.structure, + self.DEMvec,self.DIRvec,self.ncells) + cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( + self.structure,acum,umbral,self.ncells) + hand,hdnd,hand_destiny = cu.geo_hand(self.structure,Elev,longCeld,cauce,self.ncells) + handC=np.zeros(self.ncells) + handC[hand<5.3]=1 + handC[(hand>=5.3) & (hand<=15.0)]=2 + handC[(hand>15.0) & (S0<0.076)]=4 + handC[(hand>15.0) & (S0>=0.076)]=3 + self.CellHAND=hand + self.CellHAND_class=handC + self.CellHDND=hdnd + self.CellHAND_drainCell=hand_destiny + + def GetGeo_Sections(self, NumCeldas = 6): + 'Descripcion: Obtiene secciones transversales a traves de todos.\n'\ + ' los elementos de la red de drenaje, las secciones se obtienen\n'\ + ' en la direccion perpendicular al flujo, es decir si el mapa de\n'\ + ' direcciones indica en una celda la direccion norte, las secciones\n'\ + ' se obtienen en lsa direcciones oriente, occidente, con NumCeldas\n'\ + ' a cada lado de la celda tipo cauce.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'NumCeldas: Cantidad de celdas para elaborar secciones a ambos lados.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self.Sections : Secciones a traves de los elementos del cauce.\n'\ + ' su tamano es [NumCeldas*2 + 1, self.ncells]\n'\ + #Obtiene mapa de cauces + self.GetGeo_Cell_Basics() + #Obtiene vector de direcciones + directions = self.Transform_Map2Basin(self.DIR, + [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy ,0.0]) + #Obtiene las secciones + self.Sections, self.Sections_Cells = cu.basin_stream_sections(self.structure, + self.CellCauce, directions, self.DEM, NumCeldas, + self.ncells, cu.ncols, cu.nrows) + + #------------------------------------------------------ + # Subrutinas para el calculo de extremos mediante hidrografa unitaria sintetica + #------------------------------------------------------ + def GetHU_Snyder(self,Area,Tc,Cp=0.8,Fc=2.9,pequena='si'): + 'Descripcion: Obtiene HU segun Snyder.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'Area: area de la cuenca en km2.\n'\ + 'Tc: Tiempo de concentracion en Horas.\n'\ + 'Cp : Factor de escalamiento [0.8].\n'\ + 'Fc : Factor de escalamiento [2.9].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Tiempo : Tiempo total de duracion [M].\n'\ + 'Q : Caudal unitario.\n'\ + 'HU : Reglas del hidrograma unitario.\n'\ + #Calcula parametros para la hidrografa + Tr=0.6*Tc # [h] + T=0.1*Tc # [h] + Ts=Tr/5.5 # [h] + up=Cp*640/(Tr+(T-Ts)/4) #pie3/s/mi2/Pulg + Up=up*0.386*Area + Up=Up*(0.3048)**3.0/25.4 + Tp=T/2+Tr # horas + Tb=3+3*Tr/24 # dias + W50=770/up**1.08 + W75=440/up**1.08 + # Factor de multiplicacion + tb=Tp*Fc #horas + #obtiene las coordenadas del hidrograma + HU=[[0,0]] + At=(Tp-W50/3)*60; Aq=0.5*Up; HU.append([At,Aq]) + Bt=(Tp-W75/3)*60; Bq=0.75*Up; HU.append([Bt,Bq]) + Tpt=Tp*60; Tpq=Up; HU.append([Tpt,Tpq]) + Dt=(Tp+2*W75/3)*60; Dq=0.75*Up; HU.append([Dt,Dq]) + Et=(Tp+2*W50/3)*60; Eq=0.5*Up; HU.append([Et,Eq]) + if pequena=='si': + Tbt=tb*60 + else: + Tbt=Tb*60 + HU.append([Tbt,0]) + HU=np.array(HU).T + #Obtiene los intervalod de tiempo + Dt=Tc*0.1*60 #min + Tiempo=np.arange(0,Tbt+Dt,Dt) + #Obtiene la HU para los intervalos de tiempo necesarios + Q=np.zeros(Tiempo.size) + for cont,t in enumerate(Tiempo): + for h1,h2 in zip(HU.T[:-1],HU.T[1:]): + if t>h1[0] and tt1: + Q[cont]=HU[1,2]*np.exp((t1-t[1])/(3*k)) + if t[1]to: + Q[cont]=HU[1,1]*np.exp((to-t[1])/k) + return Tiempo*60,Q,HU + def GetHU_SCS(self,AreaCuenca,Tc,N=25): + 'Descripcion: Obtiene HU segun SCS.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'AreaCuenca: area de la cuenca en km2.\n'\ + 'Tc: Tiempo de concentracion en Horas.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Tiempo : Tiempo total de duracion [M].\n'\ + 'Q : Caudal unitario.\n'\ + 'HU : Reglas del hidrograma unitario.\n'\ + #Parametros fijos + ttp=np.array([0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1, + 1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0,2.2,2.4,2.6,2.8,3.0,3.2, + 3.4,3.6,3.8,4.0,4.5,5.0]) + UUp=np.array([0.0,0.03,0.1,0.19,0.31,0.47,0.66,0.82,0.93,0.99,1.0,0.99,0.93,0.86, + 0.78,0.68,0.56,0.46,0.39,0.33,0.28,0.21,0.15,0.11,0.08,0.06,0.04,0.03,0.02,0.02,0.01, + 0.01,0.0]) + #Parametros de la hidrografa + Trezago=(3.0/5.0)*float(Tc) + Tlluvia=0.133*Tc + Tpico=Tlluvia/2.0+Trezago + Upa=484.0*AreaCuenca*0.386/Tpico + Upm=Upa*0.3048**3/25.4 + #Obtiene el HU + HU=[] + for t,u in zip(ttp,UUp): + uTemp=u*Upa + HU.append([t*Tpico,uTemp*0.3048**3/25.4]) + HU=np.array(HU) + #Obtiene los intervalod de tiempo + Dt=Tc*0.1*60 #min + #Obtiene la HU para los intervalos de tiempo necesarios + Q=[]; flag=True + Tiempo=[];t=0.0 + for i in range(N): + for h1,h2 in zip(HU[:-1],HU[1:]): + if t>=h1[0] and t0: + L.append(((i-Ia)**2)/(i-Ia+S)) + else: + L.append(0) + lluviaTrTemp.append(L) + lluviaTrTemp=np.array(lluviaTrTemp) + lluviaTrEfect=lluviaTrTemp[:,1:]-lluviaTrTemp[:,:-1] + lluviaTrEfect[lluviaTrEfect<0]=0 + lluviaTrEfect=np.insert(lluviaTrEfect,0,lluviaTrTemp[:,0],axis=1) + if plot=='si': + #if Tr==None or len(Tr)<>IntTr.size(): + # Lista=[2.33,5,10,25,50,100,500,1000] + # Tr=[l for l in Lista[:IntTr.size]] + fig=pl.figure(edgecolor='w',facecolor='w') + ax=fig.add_subplot(111) + X=np.linspace(0,Dur,lluviaTrEfect.shape[1]) + Grosor=np.arange(0.5,4,0.2) + for l,le,t,g in zip(lluviaTr,lluviaTrEfect,Tr,Grosor): + ax.plot(X,l,c='b',lw=g,label=str(t)) + if CN is not None: + for l,le,t,g in zip(lluviaTr,lluviaTrEfect,Tr,Grosor): + ax.plot(X,le,c='r',lw=g,label=str(t)) + ax.set_xlabel('Tiempo $[h]$',size=16) + ax.set_ylabel('Precipitacion $[mm]$',size=16) + ax.grid(True) + ax.tick_params(labelsize=15) + pl.legend(loc=0,ncol=2) + if ruta is not None: + pl.savefig(ruta,bbox_inches='tight') + pl.show() + if CN is not None: + return lluviaTr,np.array(lluviaTrEfect),S + else: + return lluviaTr + #Convolucion de la tormenta de diseno + def GetHU_Convolution(self,Tiempo,Qhu,lluvEfect): + 'Descripcion: Realia la convolucion de los hidrogramas unitarios \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'Tiempo : Vector de la duracion de la hidrografa unitaria [Nt].\n'\ + 'Qhu : Valores del caudal unitario de la hidrografa unitaria [Nt].\n'\ + 'lluvEfect : Lluvia efectiva en un evento de tormenta cualquiera [Nt, Tr].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Qtr : Hidrografa para cada periodo de retorno [M, Tr].\n'\ + 'QmaxTr : Caudal maximo para cada periodo de retorno [Tr].\n'\ + 'Tiempo : Tiempo total de duracion [M].\n'\ + #Calcula el caudal convulucionado + Qtr=[]; QmaxTr=[] + for le in lluvEfect: + Qi=np.array([i*Qhu for i in le]) + Qconv=np.zeros(Qhu.size+lluvEfect.shape[1]-1) + for cont,q in enumerate(Qi): + Qconv[cont:cont+Qhu.size]=Qconv[cont:cont+Qhu.size]+q + Qtr.append(Qconv) + QmaxTr.append(Qconv.max()) + #Calcula el tiempo para toda la hidrografa + Dt=Tiempo[1]-Tiempo[0]; Tlast=Tiempo[-1] + T=list(Tiempo) + for i in range(1,lluvEfect.shape[1]): + T.append(Tlast+i*Dt) + return np.array(Qtr), np.array(QmaxTr),np.array(T) + #Grafica los hidrogramas sinteticos + def PlotHU_Synthetic(self,DictHU,ruta = None): + fig=pl.figure(edgecolor='w',facecolor='w') + ax=fig.add_subplot(111) + colors = ['b','r','k','g','m'] + for co,k in enumerate(DictHU.keys()): + ax.plot(DictHU[k]['time'], + DictHU[k]['HU'], + c=colors[co],lw=1.5,label=k) + ax.grid(True) + ax.set_xlabel('Tiempo $[min]$',size=14) + ax.set_ylabel('HU $[m^3/seg/mm]$',size=14) + ax.legend(loc=0) + if ruta is not None: + pl.savefig(ruta,bbox_inches='tight') + pl.show() + + #------------------------------------------------------ + # Trabajo con mapas externos y variables fisicas + #------------------------------------------------------ + def Transform_Map2Basin(self,Map,MapProp): + 'Descripcion: A partir de un mapa leido obtiene un vector \n'\ + ' con la forma de la cuenca, el cual luego puede ser agregado a esta. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'Map : Matriz con la informacion del mapa.\n'\ + 'MapProp : Propiedades del mapa.\n'\ + ' 1. Ncols Mapa.\n'\ + ' 2. Nrows Mapa.\n'\ + ' 3. Xll Mapa.\n'\ + ' 4. Yll Mapa.\n'\ + ' 5. dx Mapa.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'vecMap : Vector conla informacion del mapa al interio de la cuenca.\n'\ + #Comienza le codifgo + vec = cu.basin_map2basin(self.structure, + Map,MapProp[2],MapProp[3],MapProp[4],MapProp[5], + cu.nodata, + self.ncells, + MapProp[0],MapProp[1]) + return vec + def Transform_Basin2Map(self, BasinVar, ruta = None, DriverFormat='GTiff', + EPSG=4326): + 'Descripcion: A partir de un vector con propiedades de la cuenca en celdas\n'\ + ' obtiene un mapa (matriz) con las propiedades del DEM, este puede ser escrito \n'\ + ' en algun formato legible por GDAL. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : la cuenca misma.\n'\ + 'BasinVar : Vector con la variable de la cuenca a escribir [ncells].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Map : Matriz con la variable de la cuenca, donde no hay cuenca es wmf.cu.nodata .\n'\ + ' el tamano de la matriz es igual a DEM.shape.\n'\ + # Convierte la variable a mapa + map_ncols,map_nrows = cu.basin_2map_find(self.structure,self.ncells) + M,mxll,myll = cu.basin_2map(self.structure, BasinVar, + map_ncols, map_nrows, self.ncells) + # Si exporta el mapa lo guarda si no simplemente devuelve la matriz + if ruta is not None: + Save_Array2Raster(M, [map_ncols,map_nrows,mxll,myll,cu.dx,cu.nodata], + ruta = ruta, EPSG = EPSG, Format = DriverFormat) + return M, [map_ncols,map_nrows,mxll,myll,cu.dx,cu.dy,cu.nodata] + + def Transform_Hills2Basin(self,HillsMap): + 'Descripcion: A partir de un vector con propiedades de las laderas\n'\ + ' obtiene un vector con las propiedades por celda, ojo estas \n'\ + ' quedan con las formas de las laderas y la variable queda agregada. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : la cuenca misma.\n'\ + 'MapHills : Vector con las variables por laderas [nhills].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'CellMap : Vector con la variable agregada por laderas, pero .\n'\ + ' pasada a celdas.\n'\ + #Genera el mapa de basin vacio + CellMap = np.ones(self.ncells) + #itera por la cantidad de elementos y les va asignando + for i,k in enumerate(HillsMap[::-1]): + CellMap[self.hills_own==i+1] = k + return CellMap + def Transform_Basin2Hills(self,CellMap,mask=None,SumMeanMax=0): + 'Descripcion: A partir de un vector tipo Basin obtiene un\n'\ + ' vector del tipo laderas, en donde las propiedades se \n'\ + ' agregan para cada ladera. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : la cuenca misma.\n'\ + 'CellMap : Vector con las propiedades por celdas [ncells].\n'\ + 'mask : Celdas sobre las cuales se agrega la variable (1), y\n'\ + ' sobre las que no (0).\n'\ + 'SumMeanMax : si la variable sera agregada como un promedio (0)\n'\ + ' o como una suma (1), o como el maximo valor (2).\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'HillsMap : Vector con las prop agregadas a laderas .\n'\ + #Si hay mascara la tiene en cuenta + if mask is not None: + Ma = np.zeros(self.ncells) + if type(mask) is float or type(mask) is int: + Ma[CellMap==mask] = 1 + elif type(mask) is np.ndarray: + Ma = np.copy(mask) + else: + Ma = np.ones(self.ncells) + #Pasa el mapa de celdas a mapa de laderas + HillsMap = cu.basin_subbasin_map2subbasin(self.hills_own, + CellMap, self.nhills, Ma, SumMeanMax, self.ncells) + return HillsMap + + def Transform_Basin2Polygon(self, Vector,): + 'Descripcion: convierte una variable de topologia de la cuenca en varios poligonos\n'\ + ' cada poligono corresponde al numero de esa variable\n'\ + 'parametros\n'\ + '----------\n'\ + 'Vector: Vector con la topologia de la cuenca que contiene los datos a transformar' + 'Retorna\n'\ + '----------\n'\ + 'DicPoly: Diccionario donde el key indica el poligono encontrado y contiene las coord'\ + #Obtiene mapa raster, propiedades geo y formato para escribir + Map, Prop = self.Transform_Basin2Map(Vector) + tt = [Prop[2], Prop[4].tolist(), 0.0, + Prop[1]*Prop[-2] + Prop[3], 0.0, -1*Prop[5].tolist()] + #Obtiene los shps con la forma de la o las envolventes de cuenca + Map = Map.T + mask = Map != -9999. + shapes = __fea__.shapes(Map, mask=mask, transform=tt) + #Obtiene el poligono de la cuenca completo + DicPoly = {} + for Sh in shapes: + Coord = Sh[0]['coordinates'] + Value = int(Sh[1]) + DicPoly.update({str(Value):{}}) + for cont,co in enumerate(Coord): + DicPoly[str(Value)].update({str(cont):np.array(co).T}) + return DicPoly + + #------------------------------------------------------ + # Trabajo con datos puntuales puntos + #------------------------------------------------------ + def Points_Points2Stream(self,coordXY,ids): + 'Descripcion: toma las coordenadas de puntos XY y las mueve\n'\ + ' hacia los cauces de la cuenca\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'coordXY : coordenadas de los puntos [2,Ncoord].\n'\ + 'ids : Identificacion de los puntos que se van a mover.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'coordXYNew : Coordenadas transportadas a los cauces.\n'\ + 'basin_pts : Vector con la forma de la cuenca con los puntos.\n'\ + ' donde quedaron localizadas las coordenadas.\n'\ + 'idsOrdered : El orden en que quedaron los Ids ingresados.\n'\ + 'Ver Tambien\n'\ + '----------\n'\ + 'Points_Point2Basin\n'\ + #Obtiene el cauce + self.GetGeo_Cell_Basics() + #modifica los puntos + res_coord,basin_pts,xy_new = cu.basin_stream_point2stream( + self.structure, + self.CellCauce, + ids, + coordXY, + coordXY.shape[1], + self.ncells) + return xy_new, basin_pts, basin_pts[basin_pts<>0] + def Points_Points2Basin(self,coordXY,ids): + 'Descripcion: toma las coordenadas de puntos XY y las pone\n'\ + ' en la cuenca, no las mueve hacia los cuaces\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'coordXY : coordenadas de los puntos [2,Ncoord].\n'\ + 'ids : Identificacion de los puntos que se van a mover.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'basin_pts : Vector con la forma de la cuenca con los puntos.\n'\ + ' donde quedaron localizadas las coordenadas.\n'\ + 'idsOrdered : El orden en que quedaron los Ids ingresados.\n'\ + 'Ver Tambien\n'\ + '----------\n'\ + 'Points_Point2Stream\n'\ + #Obtiene el cauce + self.GetGeo_Cell_Basics() + #modifica los puntos + res_coord,basin_pts = cu.basin_point2var( + self.structure, + ids, + coordXY, + coordXY.shape[1], + self.ncells) + return basin_pts,basin_pts[basin_pts<>0] + #------------------------------------------------------ + # Caudales de largo plazo y regionalizacion + #------------------------------------------------------ + #Caudal de largo plazo + def GetQ_Balance(self,Precipitation, Tipo_ETR = 1, mu_choud = 1.37): + 'Descripcion: Calcula el caudal medio por balance de largo plazo\n'\ + ' para ello requiere conocer la precipitacion y el metodo de\n'\ + ' estimacion de la evaporacion.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + 'Precipitation : Cantidad anual de lluvia, escalar o vector.\n'\ + 'Elevacion : Elevacion en cada punto de la cuenca.\n'\ + 'Tipo_ETR : Tipo de ecuacion para calcular la evaporacion.\n'\ + ' -1. Turc.\n'\ + ' -2. Cenicafe Budyko.\n'\ + ' -3. Choundry.\n'\ + ' Defecto: 1.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self.CellQmed : Caudal medio calculado para toda la cuenca.\n'\ + 'self.CellETR : ETR calculada para toda la cuenca.\n'\ + #Calcula las propiedades de la cuenca + self.GetGeo_Cell_Basics() + #Determina si la precipitacion es un vector o un escalar + if type(Precipitation) is int or type(Precipitation) is float: + precip = np.ones(self.ncells)*Precipitation + elif type(Precipitation) is np.ndarray: + precip = Precipitation + #Calcula el qmed + self.CellQmed,self.CellETR = cu.basin_qmed( + self.structure, + self.CellHeight, + precip, + Tipo_ETR, + mu_choud, + self.ncells,) + + #Caudales extremos + def GetQ_Max(self,Qmed,Coef=[6.71, 3.29], Expo= [0.82, 0.64], Cv = 0.5, + Tr = [2.33, 5, 10, 25, 50, 100], Dist = 'gumbel', metodo = 'poveda', + Expo2 = [0.7745, 0.4608]): + 'Descripcion: Calcula el caudal maximo para diferentes\n'\ + ' periodos de retorno. Recibe como entrada el caudal medio \n'\ + ' calculado con GetQ_Balance.\n'\ + ' el calculo se hace a partir de la ecuacion:.\n'\ + ' MedMax = Coef[0] * Qmed ** Exp[0] .\n'\ + ' DesMax = Coef[1] * Qmed ** Exp[1] .\n'\ + ' Qmax = MedMax + K(Tr) * DesMax.\n'\ + ' Donde K es un coeficiente que depende de Tr y f(x).\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'Qmed : Caudal medio calculado con GetQ_Balance.\n'\ + 'Coef : Coeficientes para media y desviacion [6.71, 3.29].\n'\ + 'Expo : Exponentes para media y desviacion [0.82, 0.64].\n'\ + 'Cv : Coeficiente de escalamiento [0.5].\n'\ + 'Tr : Periodo de retorno [2.33, 5, 10, 25, 50, 100].\n'\ + 'Dist : Distrbucion [gumbel/lognorm].\n'\ + 'metodo: Poveda (u = cQA^a) o atlas (u = C(P-E)^a A^b), en este segundo caso Qmed = P-E.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'CellQmax : Caudal maximo para los diferentes periodos.\n'\ + # Calcula la media y desviacion + if metodo == 'poveda': + MedMax = Coef[0] * Qmed ** Expo[0] + DesMax = Coef[1] * Qmed ** Expo[1] + elif metodo == 'atlas': + Acum = cu.basin_acum(self.structure, self.ncells) + Acum = Acum * (cu.dxp**2)/1e6 + MedMax = Coef[0] * (Qmed ** Expo[0]) * (Acum**Expo2[0]) + DesMax = Coef[1] * (Qmed ** Expo[1]) * (Acum**Expo2[1]) + #Itera para todos los periodos de retorno + Qmax=[] + for t in Tr: + #Calcula k + if Dist is 'gumbel': + k=-1*(0.45+0.78*np.log(-1*np.log(1-1/float(t)))) + elif Dist is 'lognorm': + Ztr=norm.ppf(1-1/float(t)) + k=(np.exp(Ztr*np.sqrt(np.log(1+Cv**2))-0.5*np.log(1-Cv**2))-1)/Cv + #Calcula el caudal maximo + Qmax.append(list(MedMax+k*DesMax)) + return np.array(Qmax) + + def GetQ_Min(self,Qmed,Coef=[0.4168, 0.2], Expo= [1.058, 0.98], Cv = 0.5, + Tr = [2.33, 5, 10, 25, 50, 100], Dist = 'gumbel'): + 'Descripcion: Calcula el caudal minimo para diferentes\n'\ + ' periodos de retorno. Recibe como entrada el caudal medio \n'\ + ' calculado con GetQ_Balance.\n'\ + ' el calculo se hace a partir de la ecuacion:.\n'\ + ' MedMin = Coef[0] * Qmed ** Exp[0] .\n'\ + ' DesMin = Coef[1] * Qmed ** Exp[1] .\n'\ + ' Qmin = MedMin + K(Tr) * DesMin.\n'\ + ' Donde K es un coeficiente que depende de Tr y f(x).\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'Qmed : Caudal medio calculado con GetQ_Balance.\n'\ + 'Coef : Coeficientes para media y desviacion [6.71, 3.29].\n'\ + 'Expo : Exponentes para media y desviacion [0.82, 0.64].\n'\ + 'Cv : Coeficiente de escalamiento [0.5].\n'\ + 'Tr : Periodo de retorno [2.33, 5, 10, 25, 50, 100].\n'\ + 'Dist : Distrbucion [gumbel/lognorm].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'CellQmax : Caudal maximo para los diferentes periodos.\n'\ + # Calcula la media y desviacion + MedMin = Coef[0] * Qmed ** Expo[0] + DesMin = Coef[1] * Qmed ** Expo[1] + #Itera para todos los periodos de retorno + Qmin=[] + for t in Tr: + #Calcula k + if Dist is 'gumbel': + k = (-1*np.sqrt(6)/np.pi)*(0.5772+np.log(-1*np.log(1/float(t)))) + elif Dist is 'lognorm': + Ztr=norm.ppf(1/float(t)) + k = 1*(np.exp(Ztr*np.sqrt(np.log(1+Cv**2))-0.5*np.log(1-Cv**2))-1)/Cv + #Calcula el caudal maximo + Qmin.append(list(MedMin+k*DesMin)) + return np.array(Qmin) + + #------------------------------------------------------ + # Guardado shp de cuencas y redes hidricas + #------------------------------------------------------ + def Save_Net2Map(self,ruta,dx=cu.dxp,umbral=None, + qmed=None,Dict=None,DriverFormat='ESRI Shapefile', + EPSG=4326, NumTramo = True, formato = '%.2f'): + 'Descripcion: Guarda la red hidrica simulada de la cuenca en .shp \n'\ + ' Puede contener un diccionario con propiedades de la red hidrica. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + 'ruta : Lugar y nombre donde se va a guardar la red hidrica.\n'\ + 'dx : Longitud de las celdas planas (Valor de Dx plano asignado a wmf.cu.dxp).\n'\ + 'umbral : cantidad de celdas necesarias para corriente (Valor del umbral asignado a self.umbral).\n'\ + 'qmed : caudal medio calculado por alguna metodologia.\n'\ + 'Dict : Diccionario con parametros de la red hidrica que se quieren imprimir.\n'\ + 'DriverFormat : nombre del tipo de archivo vectorial de salida (ver OsGeo).\n'\ + 'EPSG : Codigo de proyeccion utilizada para los datos, defecto WGS84.\n'\ + 'NumTramo: Poner o no el numero de tramo en cada elemento de la red.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Escribe un archivo vectorial con la estructura de la red hidrica y sus propiedades.\n'\ + #varia el umbral en funcion de self + if umbral == None: + umbral = self.umbral + #division de la cuenca + acum=cu.basin_acum(self.structure,self.ncells) + cauce,nod_f,n_nodos=cu.basin_subbasin_nod(self.structure,acum,umbral,self.ncells) + sub_pert,sub_basin=cu.basin_subbasin_find(self.structure,nod_f,n_nodos,self.ncells) + sub_basins=cu.basin_subbasin_cut(n_nodos) + sub_horton,nod_hort=cu.basin_subbasin_horton(sub_basins,self.ncells,n_nodos) + sub_hort=cu.basin_subbasin_find(self.structure,nod_hort,n_nodos,self.ncells)[0] + cauceHorton=sub_hort*cauce + #Obtiene la red en manera vectorial + nodos = cu.basin_stream_nod(self.structure,acum,umbral,self.ncells)[1] + netsize = cu.basin_netxy_find(self.structure,nodos,cauceHorton,self.ncells) + net=cu.basin_netxy_cut(netsize,self.ncells) + #Para net con caudal medio + if qmed is not None: + netsize = cu.basin_netxy_find(self.structure,nodos,cauce*qmed,self.ncells) + netQmed=cu.basin_netxy_cut(netsize,self.ncells) + #Para net con tramos + if NumTramo: + netsize2 = cu.basin_netxy_find(self.structure,nodos,sub_pert*cauce,self.ncells) + netTramo = cu.basin_netxy_cut(netsize2,self.ncells) + #Cortes + cortes=np.where(net[0,:]==-999) + cortes=cortes[0].tolist() + cortes.insert(0,0) + #Escribe el shp de la red hidrica + spatialReference = osgeo.osr.SpatialReference() + spatialReference.ImportFromEPSG(EPSG) + driver = osgeo.ogr.GetDriverByName(DriverFormat) + if os.path.exists(ruta): + driver.DeleteDataSource(ruta) + shapeData = driver.CreateDataSource(ruta) + layer = shapeData.CreateLayer('layer1', spatialReference, osgeo.ogr.wkbLineString) + layerDefinition = layer.GetLayerDefn() + new_field=osgeo.ogr.FieldDefn('Long[km]',osgeo.ogr.OFTReal) + layer.CreateField(new_field) + new_field=osgeo.ogr.FieldDefn('Horton',osgeo.ogr.OFTInteger) + layer.CreateField(new_field) + #coloca los nodos + if NumTramo: + new_field=osgeo.ogr.FieldDefn('Tramo',osgeo.ogr.OFTInteger) + layer.CreateField(new_field) + if qmed is not None: + new_field=osgeo.ogr.FieldDefn('Qmed[m3s]',osgeo.ogr.OFTReal) + layer.CreateField(new_field) + if Dict is not None: + if type(Dict==dict): + netDict=[] + for k in Dict.keys(): + new_field=osgeo.ogr.FieldDefn(k[:10],osgeo.ogr.OFTReal) + layer.CreateField(new_field) + netsizeT = cu.basin_netxy_find(self.structure,nodos,cauce*Dict[k],self.ncells) + netDict.append(cu.basin_netxy_cut(netsize,self.ncells)) + #Para cada tramo + featureFID=0 + for i,j in zip(cortes[:-1],cortes[1:]): + line = osgeo.ogr.Geometry(osgeo.ogr.wkbLineString) + for x,y in zip(net[1,i+1:j],net[2,i+1:j]): + line.AddPoint_2D(float(x),float(y)) + feature = osgeo.ogr.Feature(layerDefinition) + feature.SetGeometry(line) + feature.SetFID(0) + feature.SetField('Long[km]',(net[1,i+1:j].size*dx)/1000.0) + feature.SetField('Horton',int(net[0,i+1])) + if qmed is not None: + feature.SetField('Qmed[m3s]',float(netQmed[0,i+1])) + if NumTramo: + feature.SetField('Tramo',int(netTramo[0,i+1])) + if Dict is not None: + if type(Dict==dict): + for n,k in zip(netDict,Dict.keys()): + feature.SetField(k[:10],float(formato % n[0,i+1])) + #featureFID+=1 + layer.CreateFeature(feature) + line.Destroy() + feature.Destroy() + shapeData.Destroy() + def Save_Basin2Map(self,ruta,dx=30.0,Param={}, + DriverFormat='ESRI Shapefile',EPSG=4326, GeoParam = False): + 'Descripcion: Guarda un archivo vectorial de la cuenca en .shp \n'\ + ' Puede contener un diccionario con propiedades. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + 'ruta : Lugar y nombre donde se va a guardar la cuenca.\n'\ + 'dx : Longitud de las celdas planas.\n'\ + 'DriverFormat : nombre del tipo de archivo vectorial de salida (ver OsGeo).\n'\ + 'EPSG : Codigo de proyeccion utilizada para los datos, defecto WGS84.\n'\ + 'GeoParam: (False) determina si calcular de una los parametros geomorfo o no.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Escribe un archivo vectorial de la cuenca.\n'\ + #Obtiene el perimetro de la cuenca + #nperim = cu.basin_perim_find(self.structure,self.ncells) + #basinPerim=cu.basin_perim_cut(nperim) + + #Parametros geomorfo + if GeoParam: + self.GetGeo_Parameters() + DictParam = {} + for k in self.GeoParameters.keys(): + DictParam.update({k[:8]: self.GeoParameters[k]}) + #Genera el shapefile + spatialReference = osgeo.osr.SpatialReference() + spatialReference.ImportFromEPSG(EPSG) + driver = osgeo.ogr.GetDriverByName(DriverFormat) + if os.path.exists(ruta): + driver.DeleteDataSource(ruta) + shapeData = driver.CreateDataSource(ruta) + layer = shapeData.CreateLayer('layer1', spatialReference, osgeo.ogr.wkbPolygon) + layerDefinition = layer.GetLayerDefn() + for p in Param.keys(): + #new_field=osgeo.ogr.FieldDefn(p[:p.index('[')].strip()[:10],osgeo.ogr.OFTReal) + new_field=osgeo.ogr.FieldDefn(p,osgeo.ogr.OFTReal) + layer.CreateField(new_field) + if GeoParam: + for p in DictParam.keys(): + new_field=osgeo.ogr.FieldDefn(p,osgeo.ogr.OFTReal) + layer.CreateField(new_field) + #Calcula el tamano de la muestra + ring = osgeo.ogr.Geometry(osgeo.ogr.wkbLinearRing) + for i in self.Polygon.T: + ring.AddPoint(x=float(i[0]),y=float(i[1])) + poly=osgeo.ogr.Geometry(osgeo.ogr.wkbPolygon) + poly.AddGeometry(ring) + feature = osgeo.ogr.Feature(layerDefinition) + feature.SetGeometry(poly) + feature.SetFID(0) + for p in Param.keys(): + #feature.SetField(p[:p.index('[')].strip()[:10],float("%.2f" % Param[p])) + feature.SetField(p,float("%.2f" % Param[p])) + #Si calcula parametros geomorfo + if GeoParam: + for p in DictParam.keys(): + feature.SetField(p,float("%.2f" % DictParam[p])) + layer.CreateFeature(feature) + poly.Destroy() + ring.Destroy() + feature.Destroy() + shapeData.Destroy() + + #------------------------------------------------------ + # Graficas de la cuenca + #------------------------------------------------------ + def Plot_basin(self,vec=None,Min=None, + Max=None,ruta=None,figsize=(10,7), + ZeroAsNaN ='no',extra_lat=0.0,extra_long=0.0,lines_spaces='Default', + xy=None,xycolor='b',colorTable=None,alpha=1.0,vmin=None,vmax=None, + colorbar=True, colorbarLabel = None,axis=None,rutaShp=None,shpWidth = 0.7, + shpColor = 'r',axloc = 111, fig = None, EPSG = 4326,backMap = False, + **kwargs): + #Plotea en la terminal como mapa un vector de la cuenca + 'Funcion: Plot_basin\n'\ + 'Descripcion: Genera un plot del mapa entregado.\n'\ + 'del mismo en forma de mapa \n'\ + 'Parametros Obligatorios:.\n'\ + ' -basin: Vector con la forma de la cuenca.\n'\ + ' -vec: Vector con los valores a plotear.\n'\ + 'Parametros Opcionales:.\n'\ + ' -Min: Valor minimo del plot, determina el rango de colores.\n'\ + ' -Max: Valor maximo del plot, determina el rango de colores.\n'\ + ' -ruta: Ruta en la cual se guarda la grafica.\n'\ + ' -colorbar: Muestra o no la barra de colores, defecto: True.\n'\ + ' -figsize: tamano de la ventana donde se muestra la cuenca.\n'\ + ' -ZeroAsNaN: Convierte los valores de cero en NaN.\n'\ + ' -rutaShp: Ruta a un vectorial que se quiera mostrar en el mapa.\n'\ + ' -shpWidth: Ancho de las lineas del shp cargado.\n'\ + ' -shpColor: Color de las lineas del shp cargado.\n'\ + ' -backMap: Pone de fondo un mapa tipo arcGIS.\n'\ + 'Otros argumentos:.\n'\ + ' -axis = Entorno de grafica que contiene elementos de las figuras.\n'\ + ' -parallels = Grafica Paralelos, list-like.\n'\ + ' -parallels_labels = Etiquetas de los paralelos, list-like.\n'\ + ' labels = [left,right,top,bottom].\n'\ + ' Ejemplo:\n'\ + ' m.drawparallels(parallels,labels=[False,True,True,False]).\n'\ + ' -parallels_offset: desplazamiento de las coordenadas en X.\n'\ + ' -meridians = Grafica Meridianos, list-like.\n'\ + ' -meridians_labels = Etiquetas de los meridianos, list-like.\n'\ + ' -meridians_offset: desplazamiento de las coordeandas en Y.\n'\ + ' -per_color = Color del perimetro.\n'\ + ' -per_lw = Ancho de linea del perimetro.\n'\ + ' -colorbarLabel = Titulo del colorbar.\n'\ + ' -xy_edgecolor = Color de la linea exterior del scatter .\n'\ + ' -xy_lw = Ancho de linea del Scatter .\n'\ + ' -xy_s = Tamano del scatter.\n'\ + ' -xy_colorbar: Coloca o no barra de colores del scatter enviado (False).\n'\ + ' -show = boolean, si es True muestra la grafica.\n'\ + ' -cbar_ticks: (None) ubicacion de los ticks del cbar.\n'\ + ' -cbar_ticklabels: (None) Labels a poner sobre los ticks.\n'\ + ' -cbar_ticksize: (14) Tamano de los ticks.\n'\ + ' -ShpIsPolygon: Indica si ese shp cargado es poligono (True) o no (False).\n'\ + ' -shpAlpha: transparencia del shp (0.5).\n'\ + 'Retorno:.\n'\ + ' -Actualizacion del binario .int\n'\ + ' -m = Para continuar graficando encima del entorno creado en Basemap\n'\ + ' Ejemplo:.\n'\ + ' m = Plot_basin(**args).\n'\ + ' m.scatter(coordenada_x,coordenada_y).\n' + #Prop de la barra de colores + cbar_ticklabels = kwargs.get('cbar_ticklabels', None) + cbar_ticks = kwargs.get('cbar_ticks', None) + cbar_ticksize = kwargs.get('cbar_ticksize', 14) + show = kwargs.get('show', True) + ShpIsPolygon = kwargs.get('ShpIsPolygon',None) + shpAlpha = kwargs.get('shpAlpha',0.5) + xy_colorbar = kwargs.get('xy_colorbar', False) + if lines_spaces == 'Default': + lines_spaces = cu.dx*cu.ncols*0.05 + #El mapa + Mcols,Mrows=cu.basin_2map_find(self.structure,self.ncells) + Map,mxll,myll=cu.basin_2map(self.structure,self.structure[0] + ,Mcols,Mrows,self.ncells) + longs=np.array([mxll+0.5*cu.dx+i*cu.dx for i in range(Mcols)]) + lats=np.array([myll+0.5*cu.dy+i*cu.dy for i in range(Mrows)]) + X,Y=np.meshgrid(longs,lats) + Y=Y[::-1] + show = kwargs.get('show',True) + if fig is None: + fig = pl.figure(figsize = figsize) + if axis == None: + ax = fig.add_subplot(axloc) + else: + show = False + m = Basemap(projection='merc', + llcrnrlat=lats.min()-extra_lat, + urcrnrlat=lats.max()+extra_lat, + llcrnrlon=longs.min()-extra_long, + urcrnrlon=longs.max()+extra_long, + resolution='c', + epsg = EPSG) + parallels = kwargs.get('parallels',np.arange(lats.min(), + lats.max(),lines_spaces)) + parallels_labels = kwargs.get('parallels_labels',[1,0,0,0]) + parallel_offset = kwargs.get('parallels_offset', 0.001) + m.drawparallels(parallels, + labels = parallels_labels, + fmt="%.2f", + rotation='vertical', + xoffset=parallel_offset) + meridians = kwargs.get('meridians', np.arange(longs.min(), + longs.max(),lines_spaces)) + meridians_labels = kwargs.get('meridians_labels', [0,0,1,0]) + meridians_offset = kwargs.get('meridians_offset', 0.001) + m.drawmeridians(meridians, + labels=meridians_labels, + fmt="%.2f", + yoffset=meridians_offset) + Xm,Ym=m(X,Y) + #plotea el mapa de fondo de arcGIS + if backMap: + m.arcgisimage(server='http://server.arcgisonline.com/ArcGIS', service='World_Topo_Map', xpixels = 1500, verbose = True) + #Plotea el contorno de la cuenca y la red + xp,yp = m(self.Polygon[0], self.Polygon[1]) + per_color = kwargs.get('per_color','r') + per_lw = kwargs.get('per_lw',2) + m.plot(xp, yp, color=per_color,lw=per_lw) + #hay una variable la monta + if vec is not None: + if vmin is None: + vmin = vec.min() + if vmax is None: + vmax = vec.max() + MapVec,mxll,myll=cu.basin_2map(self.structure,vec,Mcols,Mrows, + self.ncells) + MapVec[MapVec==cu.nodata]=np.nan + if ZeroAsNaN is 'si': + MapVec[MapVec == 0] = np.nan + if colorTable is not None: + cs = m.contourf(Xm, Ym, MapVec.T, 25, alpha=alpha,cmap=colorTable, + vmin=vmin,vmax=vmax) + else: + cs = m.contourf(Xm, Ym, MapVec.T, 25, alpha=alpha, + vmin=vmin,vmax=vmax) + cbar_label_size = kwargs.get('cbar_label_size',16) + if colorbar: + cbar = m.colorbar(cs,location='bottom',pad="5%") + if colorbarLabel is not None: + cbar.set_label(colorbarLabel, size = cbar_label_size) + if cbar_ticks is not None: + cbar.set_ticks(cbar_ticks) + if cbar_ticklabels is not None: + cbar.ax.set_yticklabels(cbar_ticklabels, size = cbar_ticksize,) + cbar.ax.set_xticklabels(cbar_ticklabels, size = cbar_ticksize,) + #Si hay coordenadas de algo las plotea + xy_edgecolor = kwargs.get('xy_edgecolor','black') + xy_lw = kwargs.get('xy_lw',30) + xy_s = kwargs.get('xy_s',0.5) + if xy is not None: + xc,yc=m(xy[0],xy[1]) + sx = m.scatter(xc,yc,c=xycolor, + s=xy_s, + linewidth=xy_lw, + edgecolor=xy_edgecolor) + if xy_colorbar: + pl.colorbar(sx) + #Si hay una ruta a un shp lo plotea + if rutaShp is not None: + if type(rutaShp) == str: + m.readshapefile(rutaShp, 'mapashp', linewidth = shpWidth, color = shpColor) + elif type(rutaShp) == list: + for c,shape in enumerate(rutaShp): + m.readshapefile(shape, 'mapashp', linewidth = shpWidth[c], color = shpColor[c]) + if ShpIsPolygon[c]: + patches = [] + for shape in m.mapashp: + patches.append(Polygon(np.array(shape), True)) + ax.add_collection(PatchCollection(patches, facecolor= shpColor[c], + edgecolor=shpColor[c], linewidths=shpWidth[c], zorder=2, alpha = shpAlpha[c])) + #Guarda + if ruta is not None: + pl.savefig(ruta, bbox_inches='tight',pad_inches = 0.25) + if show is True: + pl.show() + if xy is None: + return m,ax + else: + return m, ax, sx + #Grafica de plot para montar en paginas web o presentaciones + def Plot_basinClean(self, vec, ruta = None, umbral = 0.0, + vmin = 0.0, vmax = None, show_cbar = False, **kwargs): + 'Funcion: Plot_basinClean\n'\ + 'Descripcion: Genera un plot del mapa entregado en un lienzo limpio.\n'\ + 'Parametros Obligatorios:.\n'\ + ' -vec: Vector con los valores a plotear.\n'\ + 'Parametros Opcionales:.\n'\ + ' -ruta: ruta donde se guarda el png.\n'\ + ' -umbral: Umbral a partir del cual se plotea variable.\n'\ + ' -vmin: Valor minimo de la variable.\n'\ + ' -vmax: valor maximo de la variable.\n'\ + ' -show_cbar: muestra o no el Cbar del plot.\n'\ + 'Otros argumentos:.\n'\ + ' -cmap: Esquema de colores.\n'\ + ' -figsize = Tamano de la figura.\n'\ + ' -cbar_aspect: (20) relacion largo ancho del cbar.\n'\ + ' -cbar_ticks: (None) ubicacion de los ticks del cbar.\n'\ + ' -cbar_ticklabels: (None) Labels a poner sobre los ticks.\n'\ + ' -cbar_ticksize: (14) Tamano de los ticks.\n'\ + ' -show: SE muestra por defecto la figura (True).\n'\ + ' -interpolation: Tipo de interpolacion utilizada por la funcion imshow (ver opciones en matplotlib).\n'\ + 'Retorno:.\n'\ + ' -Figura se muestra y se guarda.\n'\ + ' -Coordenadas de los bordes del mapa.\n'\ + #Argumentos kw + cmap = kwargs.get('cmap','Spectral') + figsize = kwargs.get('figsize', (10,8)) + cbar_aspect = kwargs.get('cbar_aspect', 20) + cbar_ticklabels = kwargs.get('cbar_ticklabels', None) + cbar_ticks = kwargs.get('cbar_ticks', None) + cbar_ticksize = kwargs.get('cbar_ticksize', 14) + interpolation = kwargs.get('None') + show = kwargs.get('show', True) + #Obtiene la matriz + M,p = self.Transform_Basin2Map(vec) + M[(M == -9999) | (Mumbral)[0] + elif type(umbral) == np.ndarray and umbral.shape[0] == self.ncells: + pos = np.where(umbral == 1)[0] + x,y = cu.basin_coordxy(self.structure, self.ncells) + #Vector para pintar si no tiene el vec_c usa vec + if vec_c is None: + vec_c = np.copy(vec) + #Compara o no + if q_compare is not None: + vec = vec/q_compare.astype(float) + #Figura + fig = pl.figure(figsize=figsize) + ax = fig.add_subplot(111) + sca = pl.scatter(x[pos],y[pos], + s = vec[pos]*escala, + c = vec_c[pos], + lw = 0, + vmin = vmin, + vmax = vmax, + cmap = cmap, + norm = norm) + ax.patch.set_facecolor('w') + ax.patch.set_alpha(0.0) + if grid: + pl.grid(True) + #colorca colorbar + if show_cbar: + cbar = pl.colorbar(sca, aspect = cbar_aspect, ) + if cbar_ticks is not None: + cbar.set_ticks(cbar_ticks) + if cbar_ticklabels is not None: + cbar.ax.set_yticklabels(cbar_ticklabels, size = cbar_ticksize,) + + ax.set_xlim(x[pos].min(),x[pos].max()) + ax.set_ylim(y[pos].min(),y[pos].max()) + #Quita ejes + if clean: + ax.set_xticklabels([]) + ax.set_yticklabels([]) + ax.axis('off') + if clean == False: + ax.set_xlabel('Latitud', size = size) + ax.set_ylabel('Longitud', size = size) + ax.tick_params(labelsize = ticksize) + #Guarda transparente y ajustando bordes + if ruta is not None: + pl.savefig(ruta, + bbox_inches = 'tight', + pad_inches = 0, + transparent = transparent, + edgecolor = 'none', + facecolor = 'none') + if show: + pl.show() + pl.close(fig) + #Retorna las 4 coordenadas de las esquinas + return [x[pos].min(), x[pos].max(), y[pos].min(), y[pos].max()] + + + # Grafica barras de tiempos de concentracion + def Plot_Tc(self,ruta=None,figsize=(8,6),**kwargs): + keys=self.Tc.keys() + keys[2]=u'Carr Espana' + Media=np.array(self.Tc.values()).mean() + Desv=np.array(self.Tc.values()).std() + Mediana=np.percentile(self.Tc.values(),50) + rango=[Media-Desv,Media+Desv] + color1 = kwargs.get('color1','b') + color2 = kwargs.get('color2','r') + colores=[] + for t in self.Tc.values(): + if t>rango[0] and tself.ncells: + Nsize = self.ncells + pos = np.random.choice(self.ncells,Nsize) + h,b=np.histogram(self.CellSlope[pos],bins=np.arange(bins[0],bins[1],bins[2])) + b=(b[:-1]+b[1:])/2.0 + h=h.astype(float)/h.astype(float).sum() + if fig is None: + fig=pl.figure(figsize = figsize, edgecolor='w',facecolor='w') + ax=fig.add_subplot(111) + ax.plot(b,h,lw=lw) + ax.grid(True) + ax.tick_params(labelsize = axissize) + ax.set_xlabel('Pendiente',size=labelsize) + ax.set_ylabel('$pdf [\%]$',size=labelsize) + if ruta is not None: + pl.savefig(ruta,bbox_inches='tight') + if show: + pl.show() + return ax + + #Plot de histograma de tiempos de viajes en la cuenca + def Plot_Travell_Hist(self,ruta=None,Nint=10.0): + #comparacion histogramas de tiempos de respuestas + bins=np.arange(0,np.ceil(self.CellTravelTime.max()), + np.ceil(self.CellTravelTime.max())/Nint) + h_lib,b_lib=np.histogram(self.CellTravelTime,bins=bins) + h_lib=h_lib.astype(float)/h_lib.sum() + b_lib=(b_lib[:-1]+b_lib[1:])/2.0 + hc_lib=np.cumsum(h_lib) + fig=pl.figure(facecolor='w',edgecolor='w') + ax=fig.add_subplot(111) + ax.plot(b_lib,h_lib,'b',lw=2,label='Tiempos') + ax2=ax.twinx() + ax2.plot(b_lib,hc_lib,'r',lw=2) + ax2.set_ylim(0,1.1) + ax.set_xlim(0,np.ceil(self.CellTravelTime.max())) + ax.grid(True) + ax.set_xlabel('Tiempo $t [hrs]$',size=14) + ax.set_ylabel('$pdf[\%]$',size=14) + ax2.set_ylabel('$cdf[\%]$',size=14) + ax.set_xticks(b_lib) + ax.legend(loc=4) + if ruta is not None: + pl.savefig(ruta,bbox_inches='tight') + pl.show() + #Plot de curva hipsometrica + def Plot_Hipsometric(self,ruta=None,ventana=10,normed=False, + figsize = (8,6)): + #Suaviza la elevacion en el cuace ppal + elevPpal=pd.Series(self.hipso_ppal[1]) + elevBasin=self.hipso_basin[1] + if normed==True: + elevPpal=elevPpal-elevPpal.min() + elevPpal=(elevPpal/elevPpal.max())*100.0 + elevBasin=elevBasin-elevBasin.min() + elevBasin=(elevBasin/elevBasin.max())*100.0 + elevPpal=pd.rolling_mean(elevPpal,ventana) + ppal_acum=(self.hipso_ppal[0]/self.hipso_ppal[0,-1])*100 + basin_acum=(self.hipso_basin[0]/self.hipso_basin[0,0])*100 + #Genera el plot + fig=pl.figure(edgecolor='w',facecolor='w',figsize = figsize) + ax=fig.add_subplot(111) + #box = ax.get_position() + #ax.set_position([box.x0, box.y0 + box.height * 0.1, + # box.width, box.height * 0.9]) + ax.plot(ppal_acum,elevPpal,c='b',lw=3,label='Cacuce Principal') + ax.plot(basin_acum,elevBasin,c='r',lw=3,label='Cuenca') + ax.tick_params(labelsize = 14) + ax.grid() + ax.set_xlabel('Porcentaje Area Acumulada $[\%]$',size=16) + if normed==False: + ax.set_ylabel('Elevacion $[m.s.n.m]$',size=16) + elif normed==True: + ax.set_ylabel('Elevacion $[\%]$',size=16) + lgn1=ax.legend(loc=0) + if ruta is not None: + pl.savefig(ruta, bbox_inches='tight') + pl.close('all') + else: + pl.show() +class SimuBasin(Basin): + + def __init__(self,lat=None,lon=None,DEM=None,DIR=None,rute = None, name='NaN',stream=None, + umbral=500,useCauceMap = None, + noData=-999,modelType='cells',SimSed=False,SimSlides=False,dt=60, + SaveStorage='no',SaveSpeed='no',retorno = 0, + SeparateFluxes = 'no',SeparateRain='no',ShowStorage='no', SimFloods = 'no', + controlNodos = True, storageConstant = 0.001): + 'Descripcion: Inicia un objeto para simulacion \n'\ + ' el objeto tiene las propieades de una cuenca con. \n'\ + ' la diferencia de que inicia las variables requeridas. \n'\ + ' para simular. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'lat : Coordenada en X de la salida de la cuenca.\n'\ + 'lon : Coordenada en Y de la salida de la cuenca.\n'\ + 'name : Nombre con el que se va a conocer la cuenca.\n'\ + ' (defecto = NaN).\n'\ + 'stream : Opcional, si se coloca, las coordenadas no tienen.\n'\ + ' que ser exactas, estas se van a corregir para ubicarse.\n'\ + ' en el punto mas cercano dentro de la corriente, este.\n'\ + ' debe ser un objeto del tipo stream.\n'\ + 'useCauceMap: Utiliza un mapa de 1 y 0 representando las celdas que.\n'\ + ' son canal, con este mapa corrige el punto de trazado de la cuenca.\n'\ + 'umbral : Cantidad minima de celdas para la creacion de cauces.\n'\ + ' (defecto = 500 ).\n'\ + 'noData : Valor correspondiente a valores sin dato (defecto = -999).\n'\ + 'modelType : Tipo de modelo, por celdas o por laderas (defecto = cells).\n'\ + ' opciones: .\n'\ + ' cells => modela por celdas.\n'\ + ' hills => modela por laderas.\n'\ + 'SimSed : Simula si, o no simula sedimentos no.\n'\ + 'SimSlides : Simula si, o no simula deslizamientos no.\n'\ + 'dt : Tamano del intervlao de tiempo en que trabaj el modelo (defecto=60seg) [secs].\n'\ + 'SaveStorage : Guarda o no el almacenamiento.\n'\ + 'SaveSpeed : Guarda o no mapas de velocidad.\n'\ + 'rute : por defecto es None, si se coloca la ruta, el programa no.\n'\ + ' hace una cuenca, si no que trata de leer una en el lugar especificado.\n'\ + ' Ojo: la cuenca debio ser guardada con la funcion: Save_SimuBasin().\n'\ + 'retorno : (defecto = 0), si es cero no se considera alm maximo en .\n'\ + ' el tanque 3, si es 1, si se considera.\n'\ + 'SeparateFluxes : Separa el flujo en base, sub-superficial y escorrentia.\n'\ + 'SeparateRain : Separa el flujo proveniente de convectivas y de estratiformes.\n'\ + 'ShowStorage : Muestra en la salida del modelo el alm promedio en cada uno de los tanques.\n'\ + 'controlNodos: Coloca por defecto puntos de control en todos los nodos (True) o no (False).\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas.\n'\ + #Variables de radar + self.radarDates = [] + self.radarPos = [] + self.radarMeanRain = [] + self.radarCont = 1 + #Si no hay ruta y el global del codigo EPSG existe, traza la cuenca + if rute is None and int(Global_EPSG) > 0: + #Si se entrega cauce corrige coordenadas + if stream is not None: + error=[] + for i in stream.structure.T: + error.append( np.sqrt((lat-i[0])**2+(lon-i[1])**2) ) + loc=np.argmin(error) + lat=stream.structure[0,loc] + lon=stream.structure[1,loc] + if useCauceMap is not None and useCauceMap.shape == DEM.shape: + lat,lon = cu.stream_find_to_corr(lat,lon,DEM,DIR,useCauceMap, + cu.ncols,cu.nrows) + #copia la direccion de los mapas de DEM y DIR, para no llamarlos mas + self.name=name + self.DEM=DEM + self.DIR=DIR + self.modelType=modelType + self.nodata=noData + self.umbral = umbral + self.epsg = Global_EPSG + #Traza la cuenca + self.ncells = cu.basin_find(lat,lon,DIR, + cu.ncols,cu.nrows) + self.structure = cu.basin_cut(self.ncells) + #Obtiene las propiedades para el tamano de la cuenca. + self.DEMvec = self.Transform_Map2Basin(DEM, + [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy]) + self.DIRvec = self.Transform_Map2Basin(DIR, + [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy]) + acum=cu.basin_acum(self.structure,self.ncells) + cauce,nodos,self.nhills = cu.basin_subbasin_nod(self.structure + ,acum,umbral,self.ncells) + self.hills_own,sub_basin = cu.basin_subbasin_find(self.structure, + nodos,self.nhills,self.ncells) + self.hills = cu.basin_subbasin_cut(self.nhills) + models.drena=self.structure + #Determina la cantidad de celdas para alojar + if modelType=='cells': + N=self.ncells + elif modelType=='hills': + N=self.nhills + #aloja variables + models.v_coef = np.ones((4,N)) + models.h_coef = np.ones((4,N)) + models.v_exp = np.ones((4,N)) + models.h_exp = np.ones((4,N)) + models.max_capilar = np.ones((1,N)) + models.max_gravita = np.ones((1,N)) + models.storage = np.zeros((5,N)) + models.dt = dt + models.calc_niter = 5 + models.retorno = 0 + models.verbose = 0 + #Define los puntos de control + models.control = np.zeros((1,N)) + #Si se da la opcion de puntos de control en toda la red lo hace + if controlNodos: + if modelType == 'cells': + self.GetGeo_Cell_Basics() + cauce,nodos,n_nodos = cu.basin_subbasin_nod( + self.structure, + self.CellAcum, + umbral, + self.ncells) + pos = np.where(nodos<>0)[0] + x,y = cu.basin_coordxy(self.structure,self.ncells) + idsOrd,xy = self.set_Control(np.vstack([x[pos],y[pos]]),nodos[pos]) + elif modelType == 'hills': + models.control = np.ones((1,self.nhills)) * nodos[nodos<>0] + #Puntos de control de humedad sin control por defecto + models.control_h = np.zeros((1,N)) + #Define las simulaciones que se van a hacer + models.sim_sediments=0 + if SimSed is 'si': + models.sim_sediments=1 + models.sim_slides=0 + if SimSlides: + models.sim_slides=1 + models.save_storage=0 + if SaveStorage is 'si': + models.save_storage=1 + models.save_speed=0 + if SaveSpeed is 'si': + models.save_speed=1 + models.separate_fluxes = 0 + if SeparateFluxes is 'si': + models.separate_fluxes = 1 + models.separate_rain = 0 + if SeparateRain is 'si': + models.separate_rain = 1 + models.show_storage = 0 + if ShowStorage is 'si': + models.show_storage = 1 + if SimFloods == 'si': + models.sim_floods = 1 + models.storage_constant = storageConstant + #Determina que la geomorfologia no se ha estimado + self.isSetGeo = False + # si hay tura lee todo lo de la cuenca + elif rute is not None: + self.__Load_SimuBasin(rute, SimSlides) + # Obtiene la envolvente de la cuenca + self.__GetBasinPolygon__() + + def __Load_SimuBasin(self,ruta, sim_slides = False): + 'Descripcion: Lee una cuenca posteriormente guardada\n'\ + ' La cuenca debio ser guardada con SimuBasin.save_SimuBasin\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'ruta : ruta donde se encuentra ubicada la cuenca guardada\n'\ + 'Opcionales\n'\ + '----------\n'\ + 'sim_slides : (False, True) Carga variables de modelos de deslizamientos previmaente guardadas.\n'\ + 'sim_sed : (False, True) Carga variables de modelo de sedimentos previamente guardadas\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : La cuenca con sus parametros ya cargada.\n'\ + #Abre el archivo binario de la cuenca + self.rutaNC = ruta + gr = netcdf.Dataset(ruta,'a') + #obtiene las prop de la cuenca + self.name = gr.nombre + self.modelType = gr.modelType.encode() + self.nodata = gr.noData + self.umbral = gr.umbral + self.ncells = gr.ncells + self.nhills = gr.nhills + self.epsg = gr.epsg + models.dt = gr.dt + models.dxp = gr.dxp + models.retorno = gr.retorno + try: + models.storage_constant = gr.storageConst + except: + models.storage_constant = 0.0 + #Si carga deslizamientos + if sim_slides: + models.sim_slides = 1 + models.sl_fs = gr.sl_fs + models.gullienogullie = gr.sl_gullie + models.sl_gammaw = gr.sl_gammaw + #Nueva metodologia de geoespacial de la cuenca + cu.ncols = gr.ncols + cu.nrows = gr.nrows + cu.xll = gr.xll + cu.yll = gr.yll + cu.dx = gr.dx + cu.dy = gr.dy + cu.dxp = gr.dxp + cu.nodata = gr.noData + #de acuerdo al tipo de modeloe stablece numero de elem + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + #Obtiene las variables base + GrupoBase = gr.groups['base'] + self.structure = GrupoBase.variables['structure'][:] + self.hills = GrupoBase.variables['hills'][:] + self.hills_own = GrupoBase.variables['hills_own'][:] + #Obtiene las geomorfologicas + GrupoGeo = gr.groups['Geomorfo'] + self.DEMvec = GrupoGeo.variables['DEM'][:] + self.DIRvec = GrupoGeo.variables['DIR'][:] + self.DEM = self.Transform_Basin2Map(self.DEMvec) + self.DIR = self.Transform_Basin2Map(self.DIRvec) + #obtiene las propieades del modelo + GrupoSimHid = gr.groups['SimHidro'] + models.h_coef = np.ones((4,N)) * GrupoSimHid.variables['h_coef'][:] + models.v_coef = np.ones((4,N)) * GrupoSimHid.variables['v_coef'][:] + models.h_exp = np.ones((4,N)) * GrupoSimHid.variables['h_exp'][:] + models.v_exp = np.ones((4,N)) * GrupoSimHid.variables['v_exp'][:] + models.max_capilar = np.ones((1,N)) * GrupoSimHid.variables['h1_max'][:] + models.max_gravita = np.ones((1,N)) * GrupoSimHid.variables['h3_max'][:] + #Variable de drena de acuerdo al tipo de modelo + if self.modelType[0] is 'c': + models.drena = np.ones((3,N)) *GrupoSimHid.variables['drena'][:] + elif self.modelType[0] is 'h': + models.drena = np.ones((1,N)) * GrupoSimHid.variables['drena'][:] + models.unit_type = np.ones((1,N)) * GrupoSimHid.variables['unit_type'][:] + models.hill_long = np.ones((1,N)) * GrupoSimHid.variables['hill_long'][:] + models.hill_slope = np.ones((1,N)) * GrupoSimHid.variables['hill_slope'][:] + models.stream_long = np.ones((1,N)) * GrupoSimHid.variables['stream_long'][:] + models.stream_slope = np.ones((1,N)) * GrupoSimHid.variables['stream_slope'][:] + models.stream_width = np.ones((1,N)) * GrupoSimHid.variables['stream_width'][:] + models.elem_area = np.ones((1,N)) * GrupoSimHid.variables['elem_area'][:] + models.speed_type = np.ones((3)) * GrupoSimHid.variables['speed_type'][:] + models.storage = np.ones((5,N)) * GrupoSimHid.variables['storage'][:] + models.control = np.ones((1,N)) * GrupoSimHid.variables['control'][:] + models.control_h = np.ones((1,N)) * GrupoSimHid.variables['control_h'][:] + + #Propiedades de deslizamientos + if sim_slides: + GrupoSlides = gr.groups['SimSlides'] + models.sl_gammas = np.ones((1,N)) * GrupoSlides.variables['gamma_soil'][:] + models.sl_cohesion = np.ones((1,N)) * GrupoSlides.variables['cohesion'][:] + models.sl_frictionangle = np.ones((1,N)) * GrupoSlides.variables['friction_angle'][:] + models.sl_radslope = np.ones((1,N)) * GrupoSlides.variables['rad_slope'][:] + models.sl_zs = np.ones((1,N)) * GrupoSlides.variables['z_soil'][:] + #Cierra el archivo + gr.close() + #Determina que por defecto debe estar set la geomorfologia + self.isSetGeo = True + + #------------------------------------------------------ + # Subrutinas de lluvia, interpolacion, lectura, escritura, agrega funcion para variar evp en + # el tiempo + #------------------------------------------------------ + def __GetEVP_Serie__(self, index): + '''Descripcion: Genera una serie que pondera la evp ''' + rng=index + rad=np.zeros(rng.size) + for pos,time in enumerate(rng): + Hora=time + # Dia del Ano + dn = Hora.timetuple().tm_yday + Theta_d = (2 * np.pi * (dn-1))/ 365. + # (d/d)2 + an = [1.000110, 0.034221, 0.000719] + bn = [0, 0.001280, 0.000077] + # + d = 0 + tmp = 0 + for i in range(3): + tmp = (an[i] * np.cos(i*Theta_d)) + (bn[i] * np.sin(i*Theta_d)) + d = d + tmp + # Delta + a_n = [0.006918, -0.399912, -0.006758, -0.002697] + b_n = [0, 0.070257, 0.000907, 0.001480] + # + Delta = 0 + tmp = 0 + for i in range(4): + tmp = (a_n[i] * np.cos(i*Theta_d)) + (b_n[i] * np.sin(i*Theta_d)) + Delta = Delta + tmp + #Angulo horario (cada minuto) + Minutos = (Hora.hour * 60) + Hora.minute + Horario = 180 - (0.25 * Minutos) + Horario = (Horario * np.pi)/180. + # Coseno de Theta + Latitud = (6.2593 * np.pi)/180. + Cos_Theta = (np.sin(Latitud)*np.sin(Delta)) + (np.cos(Latitud)*np.cos(Delta)*np.cos(Horario)) + # Radiacion Teorica + So = 1367 #w/m2 + Q = So * d * Cos_Theta + # Escala entre 0 y 1 + rad_max=1369.8721876806876 + Q=1*Q/rad_max + #Guarda + rad[pos]=Q + #Se vuelven cero los valores negativos. + rad[rad<0]=0 + #Serie + rad=pd.Series(rad,index=rng) + models.evpserie = np.copy(rad.values) + return rad + + def rain_interpolate_mit(self,coord,registers,ruta, umbral = 0.01): + 'Descripcion: Interpola la lluvia mediante una malla\n'\ + ' irregular de triangulos, genera campos que son. \n'\ + ' guardados en un binario para luego ser leido por el. \n'\ + ' modelo en el momento de simular. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : .\n'\ + 'coord : Array (2,Ncoord) con las coordenadas de estaciones.\n'\ + 'registers : Array (Nest,Nregisters) con los registros de lluvia.\n'\ + 'ruta : Ruta con nombre en donde se guardara el binario con.\n'\ + ' la informacion de lluvia.\n'\ + 'umbral: Umbral a partir del cual se considera que un campo contiene lluvia\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + 'meanRain : La serie de lluvia promedio interpolada para la cuenca\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ + 'rain_read_bin: Lee binario de registros para ver que tiene.\n'\ + 'rain_ncf2bin: Convierte ncf a binario en formato del modelo (para imagenes de radar).\n'\ + #Mira si los registros son un data frame de pandas + isPandas=False + if type(registers)==pd.core.frame.DataFrame: + reg=registers.values.T + isPandas=True + else: + reg=registers + #inventa estaciones en las esquinas del DEM + for i,j in zip([0,0,1,1],[0,1,1,0]): + x=cu.xll+cu.ncols*cu.dx*i + y=cu.yll+cu.nrows*cu.dx*j + d=np.sqrt((coord[0,:]-x)**2+(coord[1,:]-y)**2) + pos=np.argmin(d) + #Actualiza las coordenadas + coord=np.vstack((coord.T,np.array([x,y]))).T + #pone lluvia en ese registro + reg=np.vstack((reg,reg[pos])) + #Obtiene las coordenadas de cada celda de la cuenca + x,y = cu.basin_coordxy(self.structure,self.ncells) + xy_basin=np.vstack((x,y)) + #Obtiene la malla irregular + TIN_mesh=Delaunay(coord.T) + TIN_mesh=TIN_mesh.vertices.T+1 + #Obtiene las pertenencias en la cuenca a la malla + #TIN_perte = models.rain_pre_mit(xy_basin,TIN_mesh,coord,self.ncells, + # TIN_mesh.shape[1],coord.shape[1]) + c = 1 + TIN_perte = np.zeros((1,self.ncells)) + for t in TIN_mesh.T: + t = t-1 + t = np.append(t, t[0]) + Poly = np.vstack([coord[0][t], coord[1][t]]) + bbPath = mplPath.Path(Poly.T, closed=True) + Contiene = bbPath.contains_points(xy_basin.T) + TIN_perte[0][Contiene == True] = c + c+=1 + #Revisa si todas las celdas quedaron asignadas + if len(TIN_perte[TIN_perte == 0]) == 0: + #Selecciona si es por laderas o por celdas + if self.modelType[0] is 'h': + maskVector = np.copy(self.hills_own) + elif self.modelType[0] is 'c': + maskVector = np.ones(self.ncells) + #Interpola con tin + meanRain,posIds = models.rain_mit(xy_basin, + coord, + reg, + TIN_mesh, + TIN_perte, + self.nhills, + ruta, + umbral, + maskVector, + self.ncells, + coord.shape[1], + TIN_mesh.shape[1], + reg.shape[1]) + #Guarda un archivo con informacion de la lluvia + f=open(ruta[:-3]+'hdr','w') + f.write('Numero de celdas: %d \n' % self.ncells) + f.write('Numero de laderas: %d \n' % self.nhills) + f.write('Numero de registros: %d \n' % reg.shape[1]) + f.write('Numero de campos no cero: %d \n' % posIds.max()) + f.write('Tipo de interpolacion: TIN\n') + f.write('IDfecha, Record, Lluvia, Fecha \n') + if isPandas: + dates=registers.index.to_pydatetime() + c = 1 + for d,pos,m in zip(dates,posIds,meanRain): + f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) + c+=1 + f.close() + return meanRain, posIds + else: + print 'Error: Existen celdas de la cuenca sin asignacion de triangulos, se retornan las coordenadas no asignadas' + pos = np.where(TIN_perte == 0)[1] + return xy_basin[0,pos], xy_basin[1,pos] + + def rain_interpolate_idw(self,coord,registers,ruta,p=1,umbral=0.0): + 'Descripcion: Interpola la lluvia mediante la metodologia\n'\ + ' del inverso de la distancia ponderado. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : .\n'\ + 'coord : Array (2,Ncoord) con las coordenadas de estaciones.\n'\ + 'registers : DataFrame de pandas (Nest,Nregisters) con los registros de lluvia.\n'\ + 'p : exponente para la interpolacion de lluvia.\n'\ + 'ruta : Ruta con nombre en donde se guardara el binario con.\n'\ + ' la informacion de lluvia.\n'\ + 'umbral : Umbral de suma total de lluvia bajo el cual se considera\n'\ + ' que un intervalo tiene suficiente agua como para generar reaccion\n'\ + ' (umbral = 0.0) a medida que incremente se generaran archivos mas\n'\ + ' livianos, igualmente existe la posibilidad de borrar informacion.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + 'meanRain : La serie de lluvia promedio interpolada para la cuenca\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'rain_interpolate_mit: interpola campos mediante la metodologia idw.\n'\ + 'rain_read_bin: Lee binario de registros para ver que tiene.\n'\ + 'rain_ncf2bin: Convierte ncf a binario en formato del modelo (para imagenes de radar).\n'\ + #Mira si los registros son un data frame de pandas + isPandas=False + if type(registers)==pd.core.frame.DataFrame: + reg=registers.values.T + isPandas=True + else: + reg=registers + #Obtiene las coordenadas de cada celda de la cuenca + x,y = cu.basin_coordxy(self.structure,self.ncells) + xy_basin=np.vstack((x,y)) + #Interpola con idw + if self.modelType[0] is 'h': + meanRain,posIds = models.rain_idw(xy_basin, coord, reg, p, self.nhills, + ruta, umbral, self.hills_own, self.ncells, coord.shape[1],reg.shape[1]) + elif self.modelType[0] is 'c': + meanRain,posIds = models.rain_idw(xy_basin, coord, reg, p, self.nhills, + ruta, umbral, np.ones(self.ncells), self.ncells, coord.shape[1],reg.shape[1]) + #Guarda un archivo con informacion de la lluvia + f=open(ruta[:-3]+'hdr','w') + f.write('Numero de celdas: %d \n' % self.ncells) + f.write('Numero de laderas: %d \n' % self.nhills) + f.write('Numero de registros: %d \n' % reg.shape[1]) + f.write('Numero de campos no cero: %d \n' % posIds.max()) + f.write('Tipo de interpolacion: IDW, p= %.2f \n' % p) + f.write('IDfecha, Record, Lluvia, Fecha \n') + if isPandas: + dates=registers.index.to_pydatetime() + c = 1 + for d,pos,m in zip(dates,posIds,meanRain): + f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) + c+=1 + f.close() + return meanRain,posIds + + def rain_radar2basin_from_asc(self,ruta_in,ruta_out,fechaI,fechaF,dt, + pre_string,post_string,fmt = '%Y%m%d%H%M',conv_factor=1.0/12.0, + umbral = 0.0): + 'Descripcion: Genera campos de lluvia a partir de archivos asc. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : .\n'\ + 'ruta_in: Ruta donde se encuentran loas .asc.\n'\ + 'ruta_out: Ruta donde escribe el binario con la lluvia.\n'\ + 'fechaI: Fecha de inicio de registros.\n'\ + 'fechaF: Fecha de finalizacion de registros.\n'\ + 'dt: Intervalo de tiempo entre registros.\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + 'meanRain : La serie de lluvia promedio.\n'\ + 'meanRain : La serie de lluvia promedio.\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ + 'rain_radar2basin_from_array: Mete campos de lluvia mediante multiples arrays.\n'\ + #Edita la ruta de salida + if ruta_out.endswith('.hdr') or ruta_out.endswith('.bin'): + ruta_bin = ruta_out[:-3]+'.bin' + ruta_hdr = ruta_out[:-3]+'.hdr' + else: + ruta_bin = ruta_out+'.bin' + ruta_hdr = ruta_out+'.hdr' + #Establece la cantidad de elementos de acuerdo al tipo de cuenca + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + #Guarda la primera entrada como un mapa de ceros + models.write_int_basin(ruta_bin,np.zeros((1,N)),1,N,1) + #Genera la lista de las fechas. + ListDates,dates = __ListaRadarNames__(ruta_in, + fechaI,fechaF, + fmt,post_string,pre_string,dt) + #Lee los mapas y los transforma + cont = 1 + meanRain = [] + posIds = [] + for l in ListDates: + Map,p = read_map_raster(ruta_in + l) + vec = self.Transform_Map2Basin(Map,p) * conv_factor + #Si el mapa tiene mas agua de un umbral + if vec.sum() > umbral: + #Actualiza contador, lluvia media y pocisiones + cont +=1 + meanRain.append(vec.mean()) + posIds.append(cont) + #Guarda el vector + vec = vec*1000; vec = vec.astype(int) + models.write_int_basin(ruta_bin,np.zeros((1,N))+vec,cont,N,1) + else: + #lluvia media y pocisiones + meanRain.append(0.0) + posIds.append(1) + posIds = np.array(posIds) + meanRain = np.array(meanRain) + #Guarda un archivo con informacion de la lluvia + f=open(ruta_hdr[:-3]+'hdr','w') + f.write('Numero de celdas: %d \n' % self.ncells) + f.write('Numero de laderas: %d \n' % self.nhills) + f.write('Numero de registros: %d \n' % meanRain.shape[0]) + f.write('Numero de campos no cero: %d \n' % posIds.max()) + f.write('Tipo de interpolacion: radar \n') + f.write('IDfecha, Record, Lluvia, Fecha \n') + c = 1 + for d,pos,m in zip(dates,posIds,meanRain): + f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) + c+=1 + f.close() + return np.array(meanRain),np.array(posIds) + + def rain_radar2basin_from_array(self,vec=None,ruta_out=None,fecha=None,dt=None, + status='update',umbral = 0.01, doit = False): + 'Descripcion: Genera campos de lluvia a partir de archivos array\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : .\n'\ + 'vec: Array en forma de la cuenca con la informacion.\n'\ + 'ruta_out: Ruta donde escribe el binario con la lluvia.\n'\ + 'fecha: Fecha del registro actual.\n'\ + 'dt: Intervalo de tiempo entre registros.\n'\ + 'status: Estado en el cual se encuentra el binario que se va a pasar a campo.\n'\ + ' update: (Defecto) Con este estado se genera un binario y se agregan nuevos campos.\n'\ + ' old: Estado para abrir y tomar las propiedades de self.radar.. para la generacion de un binario.\n'\ + ' close: Cierra un binario que se ha generado mediante update.\n'\ + ' reset: Reinicia las condiciones de self.radar... para la creacion de un campo nuevo.\n'\ + 'doit: Independiente del umbral escribe el binario en la siguiente entrada.\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + 'meanRain : La serie de lluvia promedio.\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ + 'rain_radar2basin_from_asc: Mete campos de lluvia mediante multiples arrays.\n'\ + #Edita la ruta de salida + if ruta_out is not None: + if ruta_out.endswith('.hdr') or ruta_out.endswith('.bin'): + ruta_bin = ruta_out[:-3]+'.bin' + ruta_hdr = ruta_out[:-3]+'.hdr' + else: + ruta_bin = ruta_out+'.bin' + ruta_hdr = ruta_out+'.hdr' + #Establece la cantidad de elementos de acuerdo al tipo de cuenca + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + try: + if vec.shape[0] == self.ncells: + vec = self.Transform_Basin2Hills(vec,sumORmean=1) + except: + pass + # De acerudo al estado actualiza las variables o guarda el + # binario final + actualizo = 1 + if status == 'update': + #Entrada 1 es la entrada de campos sin lluvia + if len(self.radarDates) == 0: + models.write_int_basin(ruta_bin,np.zeros((1,N)),1,N,1) + if vec.mean() > umbral or doit: + #Actualiza contador, lluvia media y pocisiones + self.radarCont +=1 + self.radarMeanRain.append(vec.mean()) + self.radarPos.append(self.radarCont) + #Guarda el vector + vec = vec*1000; vec = vec.astype(int) + models.write_int_basin(ruta_bin,np.zeros((1,N))+vec, + self.radarCont,N,1) + actualizo = 0 + else: + #lluvia media y pocisiones + self.radarMeanRain.append(0.0) + self.radarPos.append(1) + self.radarDates.append(fecha) + #Si ya no va a agregar nada, no agrega mas campos y genera el .hdr + elif status == 'close': + self.radarMeanRain = np.array(self.radarMeanRain) + self.radarPos = np.array(self.radarPos) + #Guarda un archivo con informacion de la lluvia + f=open(ruta_hdr[:-3]+'hdr','w') + f.write('Numero de celdas: %d \n' % self.ncells) + f.write('Numero de laderas: %d \n' % self.nhills) + f.write('Numero de registros: %d \n' % self.radarMeanRain.shape[0]) + f.write('Numero de campos no cero: %d \n' % self.radarPos.max()) + f.write('Tipo de interpolacion: radar \n') + f.write('IDfecha, Record, Lluvia, Fecha \n') + c = 1 + for d,pos,m in zip(self.radarDates, + self.radarPos,self.radarMeanRain): + f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) + c+=1 + f.close() + #Vuelve las variables listas de nuevo + self.radarMeanRain = self.radarMeanRain.tolist() + self.radarPos = self.radarPos.tolist() + elif status == 'reset': + #Variables de radar + self.radarDates = [] + self.radarPos = [] + self.radarMeanRain = [] + self.radarCont = 1 + elif status == 'old': + #si es un archivo viejo, lo abre para tomar las variables y continuar en ese punto + f=open(ruta_hdr[:-3]+'hdr','r') + Lista = f.readlines() + self.radarCont = int(Lista[3].split()[-1]) + cantidadIds = int(Lista[2].split()[-1]) + f.close() + #Abre con numpy para simplificar las cosas + a = np.loadtxt(ruta_hdr,skiprows=6,dtype='str').T + if self.radarCont >= 1 and cantidadIds > 1: + self.radarPos = [int(i.split(',')[0]) for i in a[1]] + self.radarMeanRain = [float(i.split(',')[0]) for i in a[2]] + for i in a[3]: + d = datetime.datetime.strptime(i,'%Y-%m-%d-%H:%M') + self.radarDates.append(d) + else: + self.radarPos = [int(a[1].split(',')[0])] + self.radarMeanRain = [float(a[2].split(',')[0])] + self.radarDates = [datetime.datetime.strptime(a[-1], '%Y-%m-%d-%H:%M')] + return actualizo + + #------------------------------------------------------ + # Subrutinas para preparar modelo + #------------------------------------------------------ + def set_Geomorphology(self,umbrales=[30,500],stream_width=None): + 'Descripcion: calcula las propiedades geomorfologicas necesarias \n'\ + ' para la simulacion. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'umbrales : Lista con la cantidad de celdas necesarias .\n'\ + ' para que una celda sea: ladera, carcava o cauce .\n'\ + 'stream_width = Ancho del canal en cada tramo (opcional).\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables geomorfologicas de simulacion iniciadas.\n'\ + ' models.drena : Numero de celda o ladera destino. \n'\ + ' models.nceldas : Numero de celdas o laderas. \n'\ + ' models.unit_type : tipo de celda, en el caso de ladera no aplica.\n'\ + ' 1: Celda tipo ladera.\n'\ + ' 2: Celda tipo transitorio.\n'\ + ' 3: Celda tipo cauce.\n'\ + ' models.hill_long : Longitud promedio de la ladera (o celda). \n'\ + ' - Celdas: Longitud de cada elemento (cu.dxp) para ortogonal y 1.43*cu.dxp para diagonal. \n'\ + ' - Laderas: Promedio de las longitudes recorridas entre una celda y la corriente de la ladera. \n'\ + ' models.hill_slope : Pendiente de cada ladera (promedio) o celda.\n'\ + ' models.stream_long : Longitud de cada tramo de cuace. \n'\ + ' - Celdas: Es cu.dxp: ortogonal, 1.42*cu.dxp: Diagonal. \n'\ + ' - Laderas: Es la Longitud de los elementos del cauce que componen la ladera. \n'\ + ' models.stream_slope : Pendiente de cada tramo de cauce. \n'\ + ' - Celdas: Es la pendiente estimada por self.GetGeo_Cell_Basics(). \n'\ + ' - Laderas: Pendiente promedio de las laderas. \n'\ + ' models.stream_width : Ancho de cada tramo de cauce. \n'\ + ' - Celdas: No aplica y se hacen todos iguales a la unidad. \n'\ + ' - Laderas: Es el ancho del canal calculado a partir de geomrofologia o entregado. \n'\ + ' models.elem_area : Area de cada celda (cu.dxp**2) o ladera (nceldasLadera * cu.dxp**2). \n'\ + #Obtiene lo basico para luego pasar argumentos + acum,hill_long,pend,elev = cu.basin_basics(self.structure, + self.DEMvec,self.DIRvec,self.ncells) + #Obtiene la pendiente y la longitud de las corrientes + cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( + self.structure,acum,umbrales[1],self.ncells) + stream_s,stream_l = cu.basin_stream_slope( + self.structure,elev,hill_long,nodos,n_cauce,self.ncells) + stream_s[np.isnan(stream_s)]=self.nodata + #Obtiene para metros por subn cuencas + sub_horton,nod_horton = cu.basin_subbasin_horton(self.hills,self.ncells, + self.hills.shape[1]) + sub_basin_long,max_long,nodo_max_long = cu.basin_subbasin_long( + self.hills_own,cauce,hill_long,self.hills, + sub_horton,self.hills.shape[1],self.ncells) + #Obtiene las propiedades por laderas de los cauces + stream_slope,stream_long = cu.basin_subbasin_stream_prop( + self.hills_own,cauce,hill_long, + pend,self.hills.shape[1],self.ncells) + #opbtiene el ancho si noe s dado lo asume igual a uno + if stream_width is None: + stream_width=np.ones(self.ncells) + #De acuerdo a si el modelo es por laderas o por celdas agrega lass varaibeles + if self.modelType[0]=='c': + #Obtiene el tipo de celdas + unit_type = cu.basin_stream_type(self.structure, + acum,umbrales,len(umbrales),self.ncells) + #Asigna variables + models.drena = np.ones((1,self.ncells))*self.structure + models.nceldas = self.ncells + models.unit_type = np.ones((1,self.ncells))*unit_type + models.hill_long = np.ones((1,self.ncells))*hill_long + models.hill_slope = np.ones((1,self.ncells))*pend + models.stream_long = np.ones((1,self.ncells))*np.percentile(hill_long, 40) + models.stream_slope = np.ones((1,self.ncells))*pend + models.stream_width = np.ones((1,self.ncells))*stream_width + models.elem_area = np.ones((1,self.ncells))*cu.dxp**2.0 + elif self.modelType[0]=='h': + N=self.hills.shape[1] + models.drena = np.ones((1,N))*self.hills[1] + models.nceldas = self.hills.shape[1] + models.unit_type = np.ones((1,N))*np.ones(N)*3 + models.hill_long = np.ones((1,N))*sub_basin_long + models.hill_slope = np.ones((1,N))*self.Transform_Basin2Hills(pend) + models.stream_long = np.ones((1,N))*stream_long + models.stream_slope = np.ones((1,N))*stream_slope + models.stream_width = np.ones((1,N))*cu.basin_subbasin_map2subbasin( + self.hills_own,stream_width,self.nhills,cauce,0,self.ncells) + no0min = models.stream_width[models.stream_width<>0].min() + models.stream_width[models.stream_width==0] = no0min + models.elem_area = np.ones((1,N))*np.array([self.hills_own[self.hills_own==i].shape[0] for i in range(1,self.hills.shape[1]+1)])*cu.dxp**2.0 + #Ajusta variable de que la geomorfologia esta calculada + self.isSetGeo = True + + def set_Speed_type(self,types=np.ones(3)): + 'Descripcion: Especifica el tipo de velocidad a usar en cada \n'\ + ' nivel del modelo. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'types : tipos de velocidad .\n'\ + ' 1. Velocidad tipo embalse lineal, no se especifica h_exp.\n'\ + ' 2. Velocidad onda cinematica, se debe especificar h_exp.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con la variable models.speed_type especificada.\n'\ + #Especifica la ecuacion de velocidad a usar en cada nivel del modelo + for c,i in enumerate(types): + if i==1 or i==2: + models.speed_type[c]=i + else: + models.speed_type[c]=1 + + def set_Floods(self,var,VarName, umbral = 1000, NumCeldas = 6, Default = False): + 'Descripcion: Aloja las variables del sub modelo de inundaciones\n'\ + '\n'\ + 'Parametros\n'\ + 'Mierda PUTA\n'\ + '----------\n'\ + 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ + 'varName: Nombre de la variable a ingresar en el modelo.\n'\ + ' GammaWater : Densidad del agua (Defecto: 1000).\n'\ + ' GammaSoil : Densidad del sedimento (Defecto: 2600).\n'\ + ' VelArea: Factor conversion Velocidad - Area (Defecto: 1/200).\n'\ + ' Cmax: Maxima concentracion de sedimentos (Defecto 0.75).\n'\ + ' MaxIter: Cantidad maxima de iteraciones para obtener la mancha de inunudacion.\n'\ + ' VelUmbral: Velocidad minima para que se de el flujo de escombros ( Defecto: 3 m/s).\n'\ + ' Stream_W: Ancho del canal en cada celda (ncells).\n'\ + ' Stream_D50: Tamano de particula percentil 50 (ncells).\n'\ + ' HAND: Modelo de elevacion relativa de celda ladera a celda cauce (ncells), no se ponde nada.\n'\ + ' umbral: Umbral para determinar corriente segun HAND debe coincidir con el umbral del modelo.\n'\ + ' Slope: Pendiente del canal, (no se ponde variable)\n'\ + ' Default: Poner o no parametros por defecto (False)\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ + ' wmf.models.flood_dw.\n'\ + ' wmf.models.flood_dsed.\n'\ + ' wmf.models.flood_av.\n'\ + ' wmf.models.flood_cmax.\n'\ + ' wmf.models.flood_d50.\n'\ + ' wmf.models.flood_hand.\n'\ + ' wmf.models.flood_aquien.\n'\ + #Si el modelo es tipo ladera agrega la variable + if self.modelType[0] == 'h': + return 'El modelo por laderas no simula inundaciones.' + #Pone el gamma del agua por defecto + if Default: + models.flood_dw = 1000 + models.flood_dsed = 2600 + models.flood_av = 1./200.0 + models.flood_cmax = 0.75 + models.flood_umbral = 3.0 + models.flood_max_iter = 10 + models.flood_step = 1.0 + #Obtiene el vector que va a alojar en el modelo + if VarName <> 'GammaWater' and VarName <> 'GammaSoil' and VarName <> 'VelArea' and VarName <> 'Cmax' and VarName <> 'VelUmbral': + isVec=False + if type(var) is str: + #Si es un string lee el mapa alojado en esa ruta + Map,Pp = read_map_raster(var) + Vec = self.Transform_Map2Basin(Map,Pp) + isVec=True + elif type(var) is int or float: + Vec = np.ones((1,self.ncells))*var + isVec=True + elif type(var) is np.ndarray and var.shape[0] == self.ncells: + Vec = var + isVec=True + #finalmente mete la variable en el modelo + N = self.ncells + if VarName is 'Stream_W' : + models.flood_w = np.ones((1,N))*Vec + elif VarName is 'Stream_D50': + models.flood_d50 = np.ones((1,N))*Vec + elif VarName is 'HAND': + self.GetGeo_HAND(umbral = umbral) + models.flood_hand = np.ones((1,N))*np.copy(self.CellHAND) + models.flood_aquien = np.ones((1,N))*np.copy(self.CellHAND_drainCell) + elif VarName is 'Slope': + self.GetGeo_Cell_Basics() + models.flood_slope = np.ones((1,N))*np.sin(np.arctan(self.CellSlope)) + elif VarName is 'Sections': + self.GetGeo_Sections(NumCeldas = NumCeldas) + models.flood_sections = np.ones((NumCeldas*2+1,N)) * self.Sections + models.flood_sec_cells = np.ones((NumCeldas*2+1,N)) * self.Sections_Cells + elif VarName == 'GammaWater': + models.flood_dw = var + elif VarName == 'GammaSoil': + models.flood_dsed = var + elif VarName == 'VelArea': + models.flood_av = var + elif VarName == 'Cmax': + models.flood_cmax = var + elif VarName == 'VelUmbral': + models.flood_umbral = var + elif VarName == 'MaxIter': + models.flood_max_iter = var + + def set_PhysicVariables(self,modelVarName,var,pos,mask=None): + 'Descripcion: Coloca las variables fisicas en el modelo \n'\ + ' Se debe assignarel nombre del tipo de variable, la variable\n'\ + ' y la posicion en que esta va a ser insertada\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Objeto de la cuenca 2que luego se va a simular.\n'\ + 'modelVarName : Nombre de la variable del modelo que se va a incertar.\n'\ + ' - h_coef: coeficientes horizontales\n'\ + ' [0]: Flujo de Escorrentia.\n'\ + ' [1]: Flujo Sub-superficial.\n'\ + ' [2]: Flujo subterraneo.\n'\ + ' [3]: Flujo en cauces.\n'\ + ' - h_exp: exponentes del tipo v = h_coef*(A**h_exp)\n'\ + ' [0]: Escorrentia.\n'\ + ' [1]: sub-superficial.\n'\ + ' [2]: subterraneo.\n'\ + ' [3]: cauce.\n'\ + ' - v_coef.\n'\ + ' [0]: Tasa evaporacion.\n'\ + ' [1]: Infiltracion.\n'\ + ' [2]: Percolacion.\n'\ + ' [3]: Perdidas (0).\n'\ + ' - v_exp: procesos verticales no lineales\n'\ + ' (no implementado dentro del modelo)\n' + ' - capilar.\n'\ + ' - gravit.\n'\ + 'var : variable que ingresa en el modelo, esta puede ser:.\n'\ + ' - Ruta: una ruta del tipo string.\n'\ + ' - Escalar : Un valor escalar que se asignara a toda la cuenca.\n'\ + ' - Vector : Un vector con la informacion leida (1,ncells).\n'\ + 'pos : Posicion de insercion, aplica para : h_coef, v_coef,.\n'\ + ' h_exp, v_exp.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ + 'rain_read_bin: Lee binario de registros para ver que tiene.\n'\ + 'rain_ncf2bin: Convierte ncf a binario en formato del modelo (para imagenes de radar).\n'\ + + #Obtiene el vector que va a alojar en el modelo + isVec=False + if type(var) is str: + #Si es un string lee el mapa alojado en esa ruta + Map,Pp = read_map_raster(var) + Vec = self.Transform_Map2Basin(Map,Pp) + isVec=True + elif type(var) is int or float: + Vec = np.ones((1,self.ncells))*var + isVec=True + elif type(var) is np.ndarray and var.shape[0] == self.ncells: + Vec = var + isVec=True + #Si el modelo es tipo ladera agrega la variable + if self.modelType[0] is 'h': + Vec = self.Transform_Basin2Hills(Vec,mask=mask) + #finalmente mete la variable en el modelo + if modelVarName is 'h_coef': + models.h_coef[pos] = Vec + elif modelVarName is 'h_exp': + models.h_exp[pos] = Vec + elif modelVarName is 'v_coef': + models.v_coef[pos] = Vec + elif modelVarName is 'v_exp': + models.v_exp[pos] = Vec + elif modelVarName is 'capilar': + models.max_capilar[0] = Vec + elif modelVarName is 'gravit': + models.max_gravita[0] = Vec + + def set_Storage(self,var,pos,hour_scale=False): + 'Descripcion: \n'\ + ' Establece el almacenamiento inicial del modelo\n'\ + ' la variable puede ser un valor, una ruta o un vector.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'var : Variable con la cual se va a iniciar el almancenamiento.\n'\ + ' - ruta : es una ruta a un archivo binario de almacenamiento.\n'\ + ' - escalar : valor de almacenamiento constate para toda la cuenca.\n'\ + ' - vector : Vector con valores para cadda unidad de la cuenca.\n'\ + 'pos : Posicion de insercion,.\n'\ + ' - 0 : alm cpailar.\n'\ + ' - 1 : alm superficial.\n'\ + ' - 2 : alm sub-superficial.\n'\ + ' - 3 : alm subterraneo.\n'\ + ' - 4 : alm cauce.\n'\ + ' - fecha: en caso de que var sea la ruta a StOhdr:\n'\ + ' - valor: puede ser un entero con la posicion.\n'\ + ' - str fecha: puede ser un srint con la fecha: YYYY-MM-DD-HH:MM :\n'\ + 'hour_scale: Buscar fechas a escala horaria o minutos?.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'save_storage(slef,storage).\n'\ + #Determina el tipo de unidades del modelo + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + #Obtiene el vector que va a alojar en el modelo + isVec=False + if type(var) is str: + var_bin,var_hdr = __Add_hdr_bin_2route__(var,storage = True) + if type(pos) is not str: + #Si es un string lee el binario de almacenamiento alojado en esa ruta + Vec,res = models.read_float_basin_ncol(var_bin,pos+1,N,5) + if type(pos) == str: + # Lee las fechas + L = np.loadtxt(var_hdr,skiprows = 5, usecols = (0,6), dtype = str) + if hour_scale == False: + Fechas = [datetime.datetime.strptime(i[1], '%Y-%m-%d-%H:%M') for i in L] + else: + Fechas = [datetime.datetime.strptime(i[1][:-3], '%Y-%m-%d-%H') for i in L] + try: + if hour_scale == False: + posFecha = Fechas.index(datetime.datetime.strptime(pos, '%Y-%m-%d-%H:%M')) + else: + posFecha = Fechas.index(datetime.datetime.strptime(pos[:-3], '%Y-%m-%d-%H')) + except: + print 'Error: no se encuentra la fecha especificada en el archivo '+var + Vec,res = models.read_float_basin_ncol(var_bin,posFecha+1,N,5) + isVec=True + for p in range(5): + models.storage[p] = Vec[p] + elif type(var) is int or float: + Vec = np.ones((1,N))*var + isVec=True + models.storage[pos] = Vec + elif type(var) is np.ndarray and var.shape[0] == N: + Vec = var + isVec=True + models.storage[pos] = Vec + + def set_Control(self,coordXY,ids,tipo = 'Q'): + 'Descripcion: \n'\ + ' Establece los puntos deonde se va a realizar control del caudal\n'\ + ' y de la humedad simulada.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'coordXY : Coordenadas de los puntos de control [2,Ncontrol].\n'\ + 'ids : Identificacion de los puntos de control.\n'\ + 'tipo: Control para caudal [Q] o para humedad [H].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Define los puntos de control en las variables:\n'\ + ' - models.control : control de caudal y sedimentos.\n'\ + ' - models.control_h : control de la humedad del suelo.\n'\ + 'IdsControl : El orden en que quedaron los puntos de control al interior.\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'set_record, set_storage.\n'\ + #Obtiene los puntos donde hay coordenadas + if tipo is 'Q': + xyNew, basinPts, order = self.Points_Points2Stream(coordXY,ids) + if self.modelType[0] is 'c': + models.control[0] = basinPts + IdsConvert = basinPts[basinPts<>0] + elif self.modelType[0] is 'h': + unitario = basinPts / basinPts + pos = self.hills_own * self.CellCauce * unitario + posGrande = self.hills_own * self.CellCauce * basinPts + IdsConvert = posGrande[posGrande<>0] / pos[pos<>0] + models.control[0][pos[pos<>0].astype(int).tolist()] = IdsConvert + elif tipo is 'H': + xyNew = coordXY + basinPts, order = self.Points_Points2Basin(coordXY,ids) + if self.modelType[0] == 'c': + models.control_h[0] = basinPts + IdsConvert = basinPts[basinPts<>0] + elif self.modelType[0] == 'h': + unitario = basinPts / basinPts + pos = self.hills_own * unitario + posGrande = self.hills_own * basinPts + IdsConvert = posGrande[posGrande<>0] / pos[pos<>0] + models.control_h[0][pos[pos<>0].astype(int).tolist()] = IdsConvert + return IdsConvert,xyNew + + + def set_sediments(self,var,VarName, wi = [0.036, 2.2e-4, 8.6e-7], + diametro = [0.35, 0.016, 0.001], G = 9.8): + 'Descripcion: Alojas las variables requeridas para la ejecucion\n'\ + ' del modelo de sedimentos.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ + 'varName: Nombre de la variable a ingresar en el modelo.\n'\ + ' Krus : Erosividad del suelo (RUSLE).\n'\ + ' Crus : Cobertura del suelo (RUSLE).\n'\ + ' Prus : Practicas proteccion (RUSLE).\n'\ + ' PArLiAc : Porcentaje Arenas, Limos y Arcillas.\n'\ + ' wi : velocidad de caida de cada particula de sed [m/s].\n'\ + ' diametro : diametro de cada tipo de sedimento [mm].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ + ' wmf.models.krus.\n'\ + ' wmf.models.crus.\n'\ + ' wmf.models.prus.\n'\ + ' wmf.models.parliac.\n'\ + ' wmf.models.wi.\n'\ + ' wmf.models.diametro.\n'\ + #Determina el tipo de unidades del modelo + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + #Se fija que tipo de variable es + isVec=False + if type(var) is str: + #Si es un string lee el mapa alojado en esa ruta + Map,Pp = read_map_raster(var) + Vec = self.Transform_Map2Basin(Map,Pp) + isVec=True + elif type(var) is int or float: + Vec = np.ones((1,self.ncells))*var + isVec=True + elif type(var) is np.ndarray and var.shape[0] == self.ncells: + Vec = var + isVec=True + #Si el modelo es tipo ladera agrega la variable + if self.modelType[0] is 'h': + Vec = self.Transform_Basin2Hills(Vec,mask=mask) + #Inicia las variables + if VarName == 'Krus': + models.krus = np.ones((1,N))*Vec + if VarName == 'Prus': + models.prus = np.ones((1,N))*Vec + if VarName == 'Crus': + models.crus = np.ones((1,N))*Vec + if VarName == 'PArLiAc': + models.parliac = np.ones((3,N))*Vec + #Variables de diametro y velocidad de caida + models.wi = wi + models.diametro = diametro + models.g = G + + def set_Slides(self,var,VarName): + 'Descripcion: Alojas las variables requeridas para la ejecucion\n'\ + ' del modelo de deslizamientos.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ + 'varName: Nombre de la variable a ingresar en el modelo.\n'\ + ' Zs : Profundidad del suelo.\n'\ + ' GammaSoil: Densidad del suelo.\n'\ + ' Cohesion: Cohesion del suelo.\n'\ + ' FrictionAngle : Angulo de friccion del suelo.\n'\ + ' FS: Factor de Seguridad, en este caso se envia una constante.\n'\ + ' RadSlope : .\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ + ' wmf.models.sl_zs.\n'\ + ' wmf.models.sl_gammas.\n'\ + ' wmf.models.sl_cohesion.\n'\ + ' wmf.models.sl_frictionangle.\n'\ + ' wmf.models.sl_radslope.\n'\ + ' wmf.models.sl_fs.\n'\ + #Pone el gamma del agua por defecto + models.sl_gammaw = 9.8 + #Obtiene el vector que va a alojar en el modelo + if VarName <> 'FS': + isVec=False + if type(var) is str: + #Si es un string lee el mapa alojado en esa ruta + Map,Pp = read_map_raster(var) + Vec = self.Transform_Map2Basin(Map,Pp) + isVec=True + elif type(var) is int or float: + Vec = np.ones((1,self.ncells))*var + isVec=True + elif type(var) is np.ndarray and var.shape[0] == self.ncells: + Vec = var + isVec=True + #Si el modelo es tipo ladera agrega la variable + if self.modelType[0] == 'h': + return 'El modelo por laderas no simula deslizamientos.' + #finalmente mete la variable en el modelo + N = self.ncells + if VarName is 'GammaSoil' : + models.sl_gammas = np.ones((1,N))*Vec + elif VarName is 'Cohesion': + models.sl_cohesion = np.ones((1,N))*Vec + elif VarName is 'FrictionAngle': + models.sl_frictionangle = np.ones((1,N))*np.deg2rad(Vec) + elif VarName is 'Zs': + models.sl_zs = np.ones((1,N))*Vec + elif VarName is 'FS': + models.sl_fs = var + elif VarName is 'Slope': + models.sl_radslope = np.ones((1,N))*np.arctan(Vec) + models.sl_radslope[models.sl_radslope == 0] = 0.01 + #------------------------------------------------------ + # Guardado y Cargado de modelos de cuencas preparados + #------------------------------------------------------ + def Save_SimuBasin(self,ruta,SimSlides = False, + ExtraVar = None): + 'Descripcion: guarda una cuenca previamente ejecutada\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'ruta : Ruta donde la cuenca sera guardada.\n'\ + 'ruta_dem : direccion donde se aloja el DEM (se recomienda absoluta).\n'\ + 'ruta_dir : direccion donde se aloja el DIR (se recomienda absoluta).\n'\ + 'SimSlides: indica a la funcion si va a guardar o no informacion para la simulacion.\n'\ + ' de deslizamientos.\n'\ + 'ExtraVar: Variables extras de simulacion deben ir en un diccionario.\n'\ + ' Forma del diccionario Dict = {"varName": {"Data": vector[ncells], "type": "tipo"}}.\n'\ + ' Los tipos de variables son: flotante: "f4", entero "i4".\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas.\n'\ + #Si esta o no set el Geomorphology, de acuerdo a eso lo estima por defecto + if self.isSetGeo is False: + self.set_Geomorphology() + print 'Aviso: SE ha estimado la geomorfologia con los umbrales por defecto umbral = [30, 500]' + #Guarda la cuenca + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + Dict = {'nombre':self.name, + 'modelType':self.modelType,'noData':cu.nodata,'umbral':self.umbral, + 'ncells':self.ncells,'nhills':self.nhills, + 'dt':models.dt,'Nelem':N,'dxp':cu.dxp,'retorno':models.retorno, + 'storageConst' :models.storage_constant, + 'ncols':cu.ncols, + 'nrows':cu.nrows, + 'xll':cu.xll, + 'yll':cu.yll, + 'dx':cu.dx, + 'dy':cu.dy, + 'epsg': self.epsg} + if SimSlides: + Dict.update({'sl_fs':models.sl_fs, 'sl_gullie':models.sl_gullienogullie, 'sl_gammaw':models.sl_gammaw}) + #abre el archivo + gr = netcdf.Dataset(ruta,'w',format='NETCDF4') + #Grupo base + GrupoBase = gr.createGroup('base') + GrupoSimHid = gr.createGroup('SimHidro') + GrupoSimSed = gr.createGroup('SimSediments') + GrupoSimSli = gr.createGroup('SimSlides') + GrupoHidro = gr.createGroup('Hidro') + GrupoGeo = gr.createGroup('Geomorfo') + GrupoCalib = gr.createGroup('Parametros') + #Variables grupo base + DimNcell = GrupoBase.createDimension('ncell',self.ncells) + DimNhill = GrupoBase.createDimension('nhills',self.nhills) + DimCol3 = GrupoBase.createDimension('col3',3) + DimCol2 = GrupoBase.createDimension('col2',2) + VarStruc = GrupoBase.createVariable('structure','i4',('col3','ncell'),zlib=True) + VarHills = GrupoBase.createVariable('hills','i4',('col2','nhills'),zlib=True) + VarHills_own = GrupoBase.createVariable('hills_own','i4',('ncell',),zlib=True) + VarStruc[:] = self.structure + VarHills[:] = self.hills + VarHills_own[:] = self.hills_own + #Variables de Simulacion hidrologica + DimNelem = GrupoSimHid.createDimension('Nelem',N) + DimCol3 = GrupoSimHid.createDimension('col3',3) + DimCol2 = GrupoSimHid.createDimension('col2',2) + DimCol4 = GrupoSimHid.createDimension('col4',4) + DimCol5 = GrupoSimHid.createDimension('col5',5) + VarH_coef = GrupoSimHid.createVariable('h_coef','f4',('col4','Nelem'),zlib=True) + VarV_coef = GrupoSimHid.createVariable('v_coef','f4',('col4','Nelem'),zlib=True) + VarH_exp = GrupoSimHid.createVariable('h_exp','f4',('col4','Nelem'),zlib=True) + VarV_exp = GrupoSimHid.createVariable('v_exp','f4',('col4','Nelem'),zlib=True) + Var_H1max = GrupoSimHid.createVariable('h1_max','f4',('Nelem',),zlib = True) + Var_H3max = GrupoSimHid.createVariable('h3_max','f4',('Nelem',),zlib = True) + Control = GrupoSimHid.createVariable('control','i4',('Nelem',),zlib = True) + ControlH = GrupoSimHid.createVariable('control_h','i4',('Nelem',),zlib = True) + if self.modelType[0] is 'c': + drena = GrupoSimHid.createVariable('drena','i4',('col3','Nelem'),zlib = True) + elif self.modelType[0] is 'h': + drena = GrupoSimHid.createVariable('drena','i4',('Nelem'),zlib = True) + unitType = GrupoSimHid.createVariable('unit_type','i4',('Nelem',),zlib = True) + hill_long = GrupoSimHid.createVariable('hill_long','f4',('Nelem',),zlib = True) + hill_slope = GrupoSimHid.createVariable('hill_slope','f4',('Nelem',),zlib = True) + stream_long = GrupoSimHid.createVariable('stream_long','f4',('Nelem',),zlib = True) + stream_slope = GrupoSimHid.createVariable('stream_slope','f4',('Nelem',),zlib = True) + stream_width = GrupoSimHid.createVariable('stream_width','f4',('Nelem',),zlib = True) + elem_area = GrupoSimHid.createVariable('elem_area','f4',('Nelem',),zlib = True) + speed_type = GrupoSimHid.createVariable('speed_type','i4',('col3',),zlib = True) + storage = GrupoSimHid.createVariable('storage','i4',('col5','Nelem'),zlib = True) + VarH_coef[:] = models.h_coef + VarV_coef[:] = models.v_coef + VarH_exp[:] = models.h_exp + VarV_exp[:] = models.v_exp + Var_H1max[:] = models.max_capilar + Var_H3max[:] = models.max_gravita + Control[:] = models.control + ControlH[:] = models.control_h + drena[:] = models.drena + unitType[:] = models.unit_type + hill_long[:] = models.hill_long + hill_slope[:] = models.hill_slope + stream_long[:] = models.stream_long + stream_slope[:] = models.stream_slope + stream_width[:] = models.stream_width + elem_area[:] = models.elem_area + speed_type[:] = models.speed_type + storage[:] = models.storage + #Variables grupo GEomorfologia + DimNcell = GrupoGeo.createDimension('ncell',self.ncells) + VarDEM = GrupoGeo.createVariable('DEM','f4',('ncell',),zlib = True) + VarDIR = GrupoGeo.createVariable('DIR','i4',('ncell',),zlib = True) + VarDEM[:] = self.DEMvec + VarDIR[:] = self.DIRvec + #Variables de deslizamientos + if SimSlides: + DimNelem = GrupoSimSli.createDimension('Nelem',N) + frictionAngle = GrupoSimSli.createVariable('friction_angle','f4',('Nelem',),zlib = True) + Cohesion = GrupoSimSli.createVariable('cohesion','f4',('Nelem',),zlib = True) + GammaSoil = GrupoSimSli.createVariable('gamma_soil','f4',('Nelem',),zlib = True) + ZSoil = GrupoSimSli.createVariable('z_soil','f4',('Nelem',),zlib = True) + RadSlope = GrupoSimSli.createVariable('rad_slope','f4',('Nelem',),zlib = True) + frictionAngle[:] = models.sl_frictionangle + Cohesion[:] = models.sl_cohesion + GammaSoil[:] = models.sl_gammas + ZSoil[:] = models.sl_zs + RadSlope[:] = models.sl_radslope + #Introduce variables extras en caso de que el usuario las incluyera + if type(ExtraVar) is dict: + for k in ExtraVar.keys(): + Var = gr.createVariable(k,ExtraVar[k]['type'],('ncell',),zlib=True) + Var[:] = ExtraVar[k]['Data'] + #asigna las prop a la cuenca + gr.setncatts(Dict) + #Cierra el archivo + gr.close() + #Sale del programa + return + + #------------------------------------------------------ + # Ejecucion del modelo + #------------------------------------------------------ + def run_shia(self,Calibracion, + rain_rute, N_intervals, start_point = 1, StorageLoc = None, HspeedLoc = None,ruta_storage = None, ruta_speed = None, + ruta_conv = None, ruta_stra = None, ruta_retorno = None,kinematicN = 5, QsimDataFrame = True, EvpVariable = False): + 'Descripcion: Ejecuta el modelo una ves este es preparado\n'\ + ' Antes de su ejecucion se deben tener listas todas las . \n'\ + ' variables requeridas . \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Cuenca a ejecutar con todo listo para ser ejecutada.\n'\ + 'Calibracion : Parametros de calibracion del modelo, orden:.\n'\ + ' - Evaporacion.\n'\ + ' - Infiltracion.\n'\ + ' - Percolacion.\n'\ + ' - Perdidas.\n'\ + ' - Vel Superficial .\n'\ + ' - Vel Sub-superficial.\n'\ + ' - Vel Subterranea.\n'\ + ' - Vel Cauce.\n'\ + ' - Max Capilar.\n'\ + ' - Max Gravitacional.\n'\ + 'rain_rute : Ruta donde se encuentra el archivo binario de lluvia:.\n'\ + ' generado por rain_interpolate_* o por rain_radar2basin.\n'\ + 'N_intervals : Numero de intervalos de tiempo.\n'\ + 'start_point : Punto donde comienza a usar registros de lluvia.\n'\ + ' los binarios generados por rain_* generan un archivo de texto.\n'\ + ' que contiene fechas par aayudar a ubicar el punto de inicio deseado.\n'\ + 'StorageLoc: Variable local de almacenamiento, esto es en el caso de que no se.\n'\ + ' desee usar la configuracion global de almacenamiento del modelo (5, N).\n'\ + 'HspeedLoc: Variable local para setear la velocidad horizontal inicial de ejecucion.\n'\ + 'ruta_storage : Ruta donde se guardan los estados del modelo en cada intervalo.\n'\ + ' de tiempo, esta es opcional, solo se guardan si esta variable es asignada.\n'\ + 'ruta_conv : Ruta al binario y hdr indicando las nubes que son convectivas.\n'\ + 'ruta_stra : Ruta al binario y hdr indicando las nubes que son estratiformes.\n'\ + 'ruta_retorno : Ruta al binario y hdr en donde escribe la serie con los milimetros retornados al tanque runoff.\n'\ + 'kinematicN: Cantidad de iteraciones para la solucion de la onda cinematica.\n'\ + ' De forma continua: 5 iteraciones, recomendado para cuando el modelo se\n'\ + ' ejecuta en forma continua Ej: cu.run_shia(Calib, rain_rute, 100)\n'\ + ' Por intervalos: 10 iteraciones, recomendado cuando el modelo se ejecuta\n'\ + ' por intervalos de un paso ej:\n'\ + ' for i in range(1,N)\n'\ + ' Results = cu.run_shia(Calib, ruta_rain, 1, i)\n'\ + ' for c,j in enumerate(Results[''Storage'']):\n'\ + ' cu.set_Storage(j,c)\n'\ + 'QsimDataFrame: Retorna un data frame con los caudales simulados indicando su id de acuerdo con el\n'\ + ' que guarda la funcion Save_Net2Map con la opcion NumTramo = True. \n'\ + 'EvpVariable: (False) Asume que la evp del modelo cambia en funcion o no de la radiacion\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Qsim : Caudal simulado en los puntos de control.\n'\ + 'Hsim : Humedad simulada en los puntos de control.\n'\ + #genera las rutas + rain_ruteBin,rain_ruteHdr = __Add_hdr_bin_2route__(rain_rute) + #Obtiene las fechas + Rain = read_mean_rain(rain_ruteHdr, N_intervals, start_point) + # De acuerdo al tipo de modelo determina la cantidad de elementos + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + #prepara variables globales + models.rain_first_point = start_point + models.calc_niter = kinematicN + #Prepara terminos para control + if np.count_nonzero(models.control) == 0 : + NcontrolQ = 1 + else: + NcontrolQ = np.count_nonzero(models.control)+1 + if np.count_nonzero(models.control_h) == 0 : + NcontrolH = 1 + else: + NcontrolH = np.count_nonzero(models.control_h) + #Prepara variables de guardado de almacenamiento + if ruta_storage is not None: + models.save_storage = 1 + ruta_sto_bin, ruta_sto_hdr = __Add_hdr_bin_2route__(ruta_storage, + storage = True) + else: + models.save_storage = 0 + ruta_sto_bin = 'no_guardo_nada.StObin' + ruta_sto_hdr = 'no_guardo_nada.StOhdr' + #prepara variable para guardado de velocidad + if ruta_speed is not None: + models.save_speed = 1 + ruta_speed_bin, ruta_speed_hdr = __Add_hdr_bin_2route__(ruta_speed, + storage = True) + else: + models.save_speed = 0 + ruta_speed_bin = 'no_guardo_nada.bin' + ruta_speed_hdr = 'no_guardo_nada.hdr' + #Prepara variables para el almacenamiento de retorno + if ruta_retorno is not None: + models.save_retorno = 1 + ruta_ret_bin, ruta_ret_hdr = __Add_hdr_bin_2route__(ruta_retorno) + else: + models.save_retorno = 0 + ruta_ret_bin = 'no_guardo_nada.bin' + ruta_ret_hdr = 'no_guardo_nada.hdr' + #Variables de separacion de flujo por tipo de lluvia + if ruta_conv is not None and ruta_stra is not None: + ruta_binConv,ruta_hdrConv = __Add_hdr_bin_2route__(ruta_conv) + ruta_binStra,ruta_hdrStra = __Add_hdr_bin_2route__(ruta_stra) + models.separate_rain = 1 + else: + models.separate_rain = 0 + ruta_binConv = 'none' + ruta_hdrConv = 'none' + ruta_binStra = 'none' + ruta_hdrStra = 'none' + #Prepara la variable de almacenamiento + if StorageLoc is not None: + if StorageLoc.shape <> (5, N): + print 'Error: almacenamiento debe ser: (5,'+str(N)+'), y es: ('+str(StorageLoc.shape[0])+','+str(StorageLoc.shape[1])+')' + StorageLoc = np.zeros((5,N))*-9999.0 + else: + StorageLoc = np.zeros((5,N))*-9999.0 + #Prepara la variable de velocidad horizontal inicial + if HspeedLoc is not None: + if HspeedLoc.shape <> (4, N): + print 'Error: velocidad debe ser: (4,'+str(N)+'), y es: ('+str(HspeedLoc.shape[0])+','+str(HspeedLoc.shape[1])+')' + HspeedLoc = np.zeros((4,N))*-9999.0 + else: + HspeedLoc = np.zeros((4,N))*-9999.0 + #Implementa o no la EVP variable en funcion de la radiacion + if EvpVariable: + Rad = self.__GetEVP_Serie__(Rain.index) + else: + models.evpserie = np.ones(N_intervals) + # Ejecuta el modelo + Qsim,Qsed,Qseparated,Humedad,St1,St3,Balance,Speed,Area,Alm,Qsep_byrain = models.shia_v1( + rain_ruteBin, + rain_ruteHdr, + Calibracion, + #N, + NcontrolQ, + NcontrolH, + N_intervals, + StorageLoc, + HspeedLoc, + N, + ruta_sto_bin, + ruta_speed_bin, + ruta_binConv, + ruta_binStra, + ruta_hdrConv, + ruta_hdrStra, + ruta_ret_bin) + #Retorno de variables de acuerdo a lo simulado + Retornos={'Qsim' : Qsim} + Retornos.update({'Balance' : Balance}) + Retornos.update({'Storage' : Alm}) + if np.count_nonzero(models.control_h)>0: + Retornos.update({'Humedad' : Humedad}) + Retornos.update({'Humedad_t1' : St1}) + Retornos.update({'Humedad_t2' : St3}) + if models.sim_sediments == 1: + Retornos.update({'Sediments' : Qsed}) + if models.separate_fluxes == 1: + Retornos.update({'Fluxes' : Qseparated}) + if models.separate_rain == 1: + Retornos.update({'Rain_sep' : Qsep_byrain}) + if models.show_storage == 1: + Retornos.update({'Mean_Storage' : np.copy(models.mean_storage)}) + if models.save_storage == 1: + rutaStorageHdr = __Add_hdr_bin_2route__(ruta_storage) + #Caso en el que se registra el alm medio + if models.show_storage == 1: + __Save_storage_hdr__(ruta_sto_hdr,rain_ruteHdr,N_intervals, + start_point,self,Mean_Storage = np.copy(models.mean_storage)) + #Caso en el que no hay alm medio para cada uno de los + else: + __Save_storage_hdr__(ruta_sto_hdr,rain_ruteHdr,N_intervals, + start_point,self,Mean_Storage=np.zeros((5,N))*-9999) + #Area de la seccion + if models.show_area == 1: + Retornos.update({'Sec_Area': Area}) + #Velocidades + if models.show_speed == 1: + Retornos.update({'Speed' : Speed}) + if models.show_mean_speed == 1: + Retornos.update({'Mean_Speed' : np.copy(models.mean_speed)}) + if models.save_speed == 1: + rutaSpeedHdr = __Add_hdr_bin_2route__(ruta_speed) + #Caso en el que hay velocidad media para todos los tanques + if models.show_mean_speed == 1: + __Save_speed_hdr__(ruta_speed_hdr,rain_ruteHdr,N_intervals, + start_point,self,Mean_Speed = np.copy(models.mean_speed)) + #Caso en el que no hay alm medio para cada uno de los + else: + __Save_speed_hdr__(ruta_speed_hdr,rain_ruteHdr,N_intervals, + start_point,self) + + if models.save_retorno == 1: + if models.show_mean_retorno == 1: + __Save_retorno_hdr__(ruta_ret_hdr, rain_ruteHdr, N_intervals, + start_point, self, Mean_retorno = models.mean_retorno) + else: + __Save_retorno_hdr__(ruta_ret_hdr, rain_ruteHdr, N_intervals, + start_point, self) + + #Campo de lluvia acumulado para el evento + Retornos.update({'Rain_Acum': models.acum_rain}) + Retornos.update({'Rain_hietogram': models.mean_rain}) + #Retornos en caso de simular deslizamientos + if models.sim_slides == 1: + Retornos.update({'Slides_Map': np.copy(models.sl_slideocurrence)}) + Retornos.update({'Slides_NCell_Serie': np.copy(models.sl_slidencelltime)}) + Retornos.update({'Slides_Acum':np.copy(models.sl_slideacumulate)}) + #Caudal simulado en un dataframe + if QsimDataFrame: + #Obtiene ids + ids = models.control[models.control<>0] + Qdict = {} + for i,j in zip(Retornos['Qsim'][1:], ids): + Qdict.update({str(j): i}) + Qdict = pd.DataFrame(Qdict, index=Rain.index) + #Si separa flujos, entrega el caudal tambien en data frame por flujos + if models.separate_fluxes == 1: + Qsep = [] + tupla = [] + for z,i,j in zip(Retornos['Qsim'][1:], Retornos['Fluxes'][1:], ids): + tupla.append((str(j),'run')) + tupla.append((str(j),'sub')) + tupla.append((str(j),'sup')) + Qsep.extend([i[0],i[1],z-i[0]-i[1]]) + index = pd.MultiIndex.from_tuples(tupla, names=['reach','flux']) + Qsep = np.array(Qsep) + QsepDict = pd.DataFrame(Qsep.T, index=Rain.index, columns=index) + #Si simula sedimentos, hace el dataframe + if models.sim_sediments == 1: + Qsedi = [] + tupla = [] + for z,i,j in zip(Retornos['Qsim'][1:], Retornos['Sediments'][1:], ids): + tupla.append((str(j),'Sand')) + tupla.append((str(j),'Lime')) + tupla.append((str(j),'Clay')) + Qsedi.extend([i[0],i[1],i[2]])# [i[0],i[1],z-i[0]-i[1]]) + index = pd.MultiIndex.from_tuples(tupla, names=['reach','Sediments']) + Qsedi = np.array(Qsedi) + QsediDict = pd.DataFrame(Qsedi.T, index=Rain.index, columns=index) + if models.separate_fluxes == 1 and models.sim_sediments == 0: + return Retornos, Qdict, QsepDict + if models.separate_fluxes == 1 and models.sim_sediments == 1: + return Retornos, Qdict, QsepDict, QsediDict + if models.separate_fluxes == 0 and models.sim_sediments == 1: + return Retornos, Qdict, QsediDict + return Retornos, Qdict + return Retornos + + def efficiencia(self, Qobs, Qsim): + 'Descripcion: Calcula diferentes indices de desempeno del modelo\n'\ + ' nash, qpico, rmse, rmseLog, t_pico\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'Qobs : Caudal observado.\n'\ + 'Qsim : Caudal simulado.\n'\ + 'Retornos\n'\ + '----------\n'\ + 'DicEff: diccionario con la eficiencia obtenida en cada param.\n'\ + #Comienza a evaluar cada parametro + DictEff = {'Nash': __eval_nash__(Qobs, Qsim)} + DictEff.update({'Qpico': __eval_q_pico__(Qobs, Qsim)}) + DictEff.update({'Tpico': __eval_t_pico__(Qobs, Qsim, models.dt)}) + DictEff.update({'RmseLog': __eval_rmse_log__(Qobs, Qsim)}) + DictEff.update({'Rmse': __eval_rmse__(Qobs, Qsim)}) + return DictEff + + def Calib_NSGAII(self, nsga_el, nodo_eval, pop_size = 40, process = 4, + NGEN = 6, MUTPB = 0.5, CXPB = 0.5): + 'Descripcion: Algoritmo para calibrar de forma automatica el modelo\n'\ + ' hidrologico utilizando DEAP y su funcion de seleccion NSGAII.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + ' - nsga_el : un objeto de la clase nsgaii_element, el cual determinara las reglas.\n'\ + ' para la generacion de calibraciones.\n'\ + ' - nodo_eval: nodo donde se evalua el modelo.\n'\ + ' - pop_size: tamano de la poblacion (cantidad de calibraciones a evaluar, multiplo de 4).\n'\ + ' - process: Cantidad de procesadores que se utilizaran en la generacion.\n'\ + ' - NGEN: Cantidad de generaciones para obtener la poblacion final.\n'\ + ' - MUTPB: Probabilidad generica de que un gen mute.\n'\ + ' - CXPB: Probabilidad generica de que dos genes se crucen.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + ' - pop: poblacion final.\n'\ + ' - Qsim: Caudales simulados en el punto evaluado.\n'\ + ' - fitness: desempeno de la poblacion obtenida.\n'\ + #Check de que la poblacion sea multiplo de 4 + Flag = True + while Flag: + if np.mod(pop_size,4) == 0: + Flag = False + else: + pop_size += 1 + #Inicia el elemento nsga con los parametros de el + nsga_el.set_nsgaII() + #Crea las poblaciones y las ejecuciones + pop = nsga_el.toolbox.population(pop_size) + Ejecs = map(nsga_el.__crea_ejec__, pop) + #Ejecuta a la poblacion + QsimPar = __ejec_parallel__(Ejecs, process, nodo_eval) + fitnesses = map(nsga_el.toolbox.evaluate, QsimPar) + for ind, fit in zip(pop, fitnesses): + ind.fitness.values = fit + #Itera la poblacion hasta encontrar a la mejor + #toolbox = base.Toolbox() + for g in range(NGEN): + offspring = tools.selTournamentDCD(pop, len(pop)) + offspring = map(nsga_el.toolbox.clone, offspring) + # Apply crossover and mutation on the offspring + for child1, child2 in zip(offspring[::2], offspring[1::2]): + if random.random() < CXPB: + nsga_el.toolbox.mate(child1[0], child2[0]) + del child1.fitness.values + del child2.fitness.values + #Muta a algunos de los genomas + for mutant in offspring: + if random.random() < MUTPB: + nsga_el.toolbox.mutate(mutant[0]) + del mutant.fitness.values + #Ejecuta a la nueva generacion + Ejecs = map(nsga_el.__crea_ejec__, offspring) + QsimPar = __ejec_parallel__(Ejecs, process, nodo_eval) + #Identifica a la gente que no cumple de la generacion + Qsim_invalid = [] + invalid_ind = [] + for i,q in zip(offspring, QsimPar): + if not i.fitness.valid: + Qsim_invalid.append(q) + invalid_ind.append(i) + #Evaluate the individuals with an invalid fitness + fitnesses = map(nsga_el.toolbox.evaluate, Qsim_invalid) + for ind, fit in zip(invalid_ind, fitnesses): + ind.fitness.values = fit + #Toma la siguiente generacion + pop = nsga_el.toolbox.select(pop + offspring, pop_size) + #Retorno + return pop, QsimPar, np.array(fitnesses).T + + +class nsgaii_element: + def __init__(self, rutaLluvia, Qobs, npasos, inicio, SimuBasinElem ,evp =[0,1], infil = [1,200], perco = [1, 40], + losses = [0,1],velRun = [0.1, 1], velSub = [0.1, 1], velSup =[0.1, 1], + velStream = [0.1, 1], Hu = [0.1, 1], Hg = [0.1, 1], + probCruce = np.ones(10)*0.5, probMutacion = np.ones(10)*0.5, + rangosMutacion = [[0,1], [1,200], [1,40], [0,1], [0.1,1], [0.1, 1], [0.1,1], [0.1,1], [0.1, 1], [0.1,1]], + MaxMinOptima = (1.0, -1.0), CrowDist = 0.5): + 'Descripcion: Inicia el objeto de calibracion genetica tipo NSGAII\n'\ + ' este objeto contiene las reglas principales para la implementacion\n'\ + ' de todo el algoritmo de calibracion genetico.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + ' -rutaLluvia : Ruta donde se encuentra el archivo de lluvia binario.\n'\ + ' -Qobs: Array numpy con el caudal observado [npasos].\n'\ + ' -npasos: Cantidad de pasos en simulacion.\n'\ + ' -inicio: Punto de inicio en la simulacion.\n'\ + ' -SimuBasinElem: Objeto de simulacion.\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas.\n'\ + #Rangos parametros + self.evp_range = evp + self.infil_range = infil + self.perco_range = perco + self.losses_range = losses + self.velRun_range = velRun + self.velSub_range = velSub + self.velSup_range = velSup + self.velStream_range = velStream + self.hu_range = Hu + self.hg_range = Hg + #Establece propiedades para ejecucion + self.npasos = npasos + self.inicio = inicio + self.ruta_lluvia = rutaLluvia + self.Qobs = Qobs + self.simelem = SimuBasinElem + #Propiedades de cruce y mutacion + self.prob_cruce = probCruce + self.prob_mutacion = probMutacion + self.rangos_mutacion = rangosMutacion + self.optimiza = MaxMinOptima + self.crowdist = CrowDist + + def __crea_calibracion__(self): + #Evp + if self.evp_range[0] <> self.evp_range[1]: + evp = np.random.uniform(self.evp_range[0], self.evp_range[1],1)[0] + else: + evp = self.evp_range[0] + #Infiltracion + if self.infil_range[0] <> self.infil_range[1]: + infil = np.random.uniform(self.infil_range[0], self.infil_range[1],1)[0] + else: + infil = self.infil_range[0] + #Percolacion + if self.perco_range[0] <> self.perco_range[1]: + perco = np.random.uniform(self.perco_range[0], self.perco_range[1],1)[0] + else: + perco = self.perco_range[0] + #Perdidas + if self.losses_range[0] <> self.losses_range[1]: + losses = np.random.uniform(self.losses_range[0], self.losses_range[1],1)[0] + else: + losses = self.losses_range[0] + #runoff + if self.velRun_range[0] <> self.velRun_range[1]: + velRun = np.random.uniform(self.velRun_range[0], self.velRun_range[1],1)[0] + else: + velRun = self.velRun_range[0] + #Vel subsuperficial + if self.velSub_range[0] <> self.velSub_range[1]: + velSub = np.random.uniform(self.velSub_range[0], self.velSub_range[1],1)[0] + else: + velSub = self.velSub_range[0] + #Vel acuifero + if self.velSup_range[0] <> self.velSup_range[1]: + velSup = np.random.uniform(self.velSup_range[0], self.velSup_range[1],1)[0] + else: + velSup = self.velSup_range[0] + #Vel cauce + if self.velStream_range[0] <> self.velStream_range[1]: + velStream = np.random.uniform(self.velStream_range[0], self.velStream_range[1],1)[0] + else: + velStream = self.velStream_range[0] + #almacenamiento hu + if self.hu_range[0] <> self.hu_range[1]: + hu = np.random.uniform(self.hu_range[0], self.hu_range[1],1)[0] + else: + hu = self.hu_range[0] + #almacenamiento hg + if self.hg_range[0] <> self.hg_range[1]: + hg = np.random.uniform(self.hg_range[0], self.hg_range[1],1)[0] + else: + hg = self.hg_range[0] + #Retorna una calibracion aleatoria + return [evp, infil, perco, losses, velRun, velSub, velSup, velStream, hu, hg] + + def __crea_ejec__(self, calibracion): + return [calibracion, self.ruta_lluvia, self.npasos, self.inicio, self.simelem] + + def __evalfunc__(self, Qsim, f1 = __eval_nash__, f2 = __eval_q_pico__): + E1 = f1(self.Qobs, Qsim) + E2 = f2(self.Qobs, Qsim) + return E1, E2 + + def __cruce__(self, indi1, indi2): + for i,u in zip(range(10), self.prob_cruce): + p = np.random.uniform(0,1,1) + if p>u: + a = indi1[i]; b = indi2[i] + indi1[i] = b + indi2[i] = a + return indi1, indi2 + + def __mutacion__(self, indi): + c = 0 + for i,u in zip(range(10), self.prob_mutacion): + p = np.random.uniform(0,1,1) + if p>u: + indi[i] = np.random.uniform(self.rangos_mutacion[c][0],self.rangos_mutacion[c][0],1)[0] + c+=1 + return indi + + def set_nsgaII(self): + self.toolbox = base.Toolbox() + creator.create("FitnessMin", base.Fitness, + weights = self.optimiza, + crowding_dist = self.crowdist) + creator.create("Individual", list, fitness=creator.FitnessMin) + self.toolbox.register("attr1", self.__crea_calibracion__) + self.toolbox.register("individual", tools.initRepeat, creator.Individual, + self.toolbox.attr1, n=1) + self.toolbox.register("population", tools.initRepeat, list, self.toolbox.individual) + self.toolbox.register("evaluate", self.__evalfunc__) + self.toolbox.register("mate", self.__cruce__) + self.toolbox.register("mutate", self.__mutacion__) + self.toolbox.register("select", tools.selNSGA2) + +class Stream: + #------------------------------------------------------ + # Subrutinas de trazado de corriente y obtencion de parametros + #------------------------------------------------------ + #Inicia la cuenca + def __init__(self,lat,lon,DEM,DIR,name='NaN'): + 'Descripcion: Traza un cauce e inicia la variable de este \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'lat : Coordenada en X del punto mas alto del cauce.\n'\ + 'lon : Coordenada en Y del punto mas alto del cauce.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas y estructura del cauce.\n'\ + #Realiza copia de los mapas y obtiene el cauce + self.DEM = DEM + self.DIR = DIR + self.ncells = cu.stream_find(lat,lon,self.DEM, + self.DIR,cu.ncols,cu.nrows) + self.structure = cu.stream_cut(self.ncells) + #------------------------------------------------------ + # Guardado shp de cauce + #------------------------------------------------------ + def Save_Stream2Map(self,ruta,DriverFormat='ESRI Shapefile', + EPSG=4326): + 'Descripcion: Guarda el cauce trazado en un mapa \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'ruta : Nombre del lugar donde se va a guardar el cauce.\n'\ + 'DriverFormat : Tipo de mapa vectorial.\n'\ + 'EPSG : Codigo de tipo de proyeccion usada (defecto 4326).\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el cauce en el formato especificado.\n'\ + #Escribe el shp del cauce + if ruta.endswith('.shp')==False: + ruta=ruta+'.shp' + spatialReference = osgeo.osr.SpatialReference() + spatialReference.ImportFromEPSG(EPSG) + driver = osgeo.ogr.GetDriverByName(DriverFormat) + if os.path.exists(ruta): + driver.DeleteDataSource(ruta) + shapeData = driver.CreateDataSource(ruta) + layer = shapeData.CreateLayer('layer1', + spatialReference, osgeo.ogr.wkbLineString) + layerDefinition = layer.GetLayerDefn() + line = osgeo.ogr.Geometry(osgeo.ogr.wkbLineString) + for x,y in zip(self.structure[0],self.structure[1]): + line.AddPoint_2D(float(x),float(y)) + feature = osgeo.ogr.Feature(layerDefinition) + feature.SetGeometry(line) + feature.SetFID(0) + layer.CreateFeature(feature) + line.Destroy() + feature.Destroy() + shapeData.Destroy() + #------------------------------------------------------ + # Plot de variables + #------------------------------------------------------ + def Plot_Profile(self,ruta=None): + 'Descripcion: Grafica el perfil del cauce trazado \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'ruta : Nombre de la imagen si se va a guardar la imagen del cauce.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el cauce en el formato especificado.\n'\ + #Escribe el shp del cauce + fig=pl.figure(facecolor='w',edgecolor='w') + ax=fig.add_subplot(111) + ax.plot(self.structure[3],self.structure[2],lw=2) + ax.set_xlabel('Distancia $[mts]$',size=14) + ax.set_ylabel('Elevacion $[m.s.n.m]$',size=14) + ax.grid(True) + if ruta is not None: + pl.savefig(ruta,bbox_inches='tight') + pl.show() + #def Plot_Map(self,ruta=None + From e90f70410ef62f89a52a63197fb60586dad65658 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 21 Aug 2018 11:04:46 -0500 Subject: [PATCH 105/142] evaluador de expresiones ya admite expresiones con el simbolo igual del tipo a = b+d --- qgisplugin/HydroSEDPluginUtils.py | 10 ++++++++-- qgisplugin/HydroSEDPlugin_dockwidget.py | 19 ++++++++++++++++--- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 11 +++++++---- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 7759625..7f0ccfa 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -253,7 +253,7 @@ def Basin_LoadBasin(self, PathNC, LoadSim = False, LoadSed = False): shape = g.groups[grupoKey].variables[k].shape MapaRaster = False for s in shape: - if s == self.cuenca.ncells: MapaRaster = True + if s == self.cuenca.ncells: MapaRaster = True #Actualiza el diccionario self.DicBasinNc.update({k: {'nombre':k, @@ -719,7 +719,13 @@ def ExpressionParser(self, expresion): except: pass #Formula la expresion - AA = eval(expresion) + try: + AA = eval(expresion) + except: + exec(expresion) + pos = expresion.index('=') + VarName = expresion[:pos].strip() + AA = eval(VarName) return AA diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 45a0904..cb5d9f5 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -194,7 +194,7 @@ def clickEventBasin2WMF(): self.segundaCarga = True #Cargado de la cuenca Area, self.EPSG, dxp, self.noData, self.umbral = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), - Simhidro, SimSed) + Simhidro, SimSed) #self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), Simhidro, SimSed) self.TableStart() #Actualiza tabla de Nc y comboBox @@ -203,7 +203,7 @@ def clickEventBasin2WMF(): self.TabNC.NewEntry(self.HSutils.DicBasinNc[k],k, self.Tabla_Prop_NC) self.VarFromNC.addItem(k) #Area, self.EPSG, dxp, self.noData, self.umbral = self.HSutils.Basin_LoadBasin(self.lineEditRutaCuenca.text().strip(), - # Simhidro, SimSed) + # Simhidro, SimSed) #print self.umbral #Habilita los botones de visualizacion de red hidrica y divisoria self.Boton_verDivisoria.setEnabled(True) @@ -683,6 +683,16 @@ def clickEventEvalString(): except: self.HSutils.DicBasinNc[VarDestinoName]['var'] = np.copy(Var) self.HSutils.DicBasinNc[VarDestinoName]['saved'] = False + #Mensaje de exito + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + u'La variable '+VarDestinoName+' ha sido actualizada en NC', + level=QgsMessageBar.INFO, duration=3) + #Si no es cuenca da un mensaje de alerta + else: + #Mensaje de exito o error + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + u'El cálculo arroja una variable que no contiene '+str(self.HSutils.cuenca.ncells)+' celdas. Favor enviar a WMF.', + level=QgsMessageBar.WARNING, duration=3) #si es una variable nueva la tira al WMF elif self.Radio2WMF.isChecked(): #Variable al diccionario @@ -700,7 +710,10 @@ def clickEventEvalString(): #Actualiza la tabla self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[VarDestinoName], VarDestinoName, self.Tabla_Prop_WMF) - + #Mensaje de exito o error + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + u'La variable '+VarDestinoName+' ha sido cargado a la tabla WMF', + level=QgsMessageBar.INFO, duration=3) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index ac52a11..58019ae 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -294,7 +294,7 @@ 0 - -875 + -878 443 2018 @@ -1340,8 +1340,11 @@ 70 + + Evaluar variables en una expresion del tipo A = f(B,C) o f(A,B,C) + - Nombre de la variable que contiene la conversión + Evaluar variables en una expresion del tipo A = f(B,C) o f(A,B,C) @@ -2711,7 +2714,7 @@ - + :/plugins/HydroSEDPlugin/icons/update.png:/plugins/HydroSEDPlugin/icons/update.png @@ -2761,7 +2764,7 @@ - + :/plugins/HydroSEDPlugin/icons/update.png:/plugins/HydroSEDPlugin/icons/update.png From 86ac50f7a7e541f06445e94c34811e42bfb22c02 Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Tue, 21 Aug 2018 11:12:34 -0500 Subject: [PATCH 106/142] Revert "Delete wmf.py" This reverts commit bed8f8cfa7970a7e8546eae6e154db682b7a40bf. --- wmf/wmf.py | 4600 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 4600 insertions(+) create mode 100644 wmf/wmf.py diff --git a/wmf/wmf.py b/wmf/wmf.py new file mode 100644 index 0000000..113ab48 --- /dev/null +++ b/wmf/wmf.py @@ -0,0 +1,4600 @@ +#!Modelos: acoplado con cuencas presenta una serie de modelos hidrologicos distribuidos +#!Copyright (C) <2016> + +#!This program is free software: you can redistribute it and/or modify +#!it under the terms of the GNU General Public License as published by +#!the Free Software Foundation, either version 3 of the License, or +#!(at your option) any later version. + +#!This program is distributed in the hope that it will be useful, +#!but WITHOUT ANY WARRANTY; without even the implied warranty of +#!MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#!GNU General Public License for more details. + +#!You should have received a copy of the GNU General Public License +#!along with this program. If not, see . +#Algo +import matplotlib +matplotlib.use('Agg') +from cu import * +from models import * +import numpy as np +import pylab as pl +import osgeo.ogr, osgeo.osr +import gdal +from scipy.spatial import Delaunay +from scipy.stats import norm +import os +import pandas as pd +import datetime as datetime +from multiprocessing import Pool +import matplotlib.path as mplPath +try: + import netcdf as netcdf +except: + try: + import netCDF4 as netcdf + except: + print 'No netcdf en esta maquina, se desabilita la funcion SimuBasin.save_SimuBasin' + pass +try: + from mpl_toolkits.basemap import Basemap, addcyclic, shiftgrid, cm + from matplotlib.patches import Polygon + from matplotlib.collections import PatchCollection +except: + print 'No se logra importar basemap, por lo tanto no funciona Plot_basin' + pass +try: + from deap import base, creator + from deap import tools + FlagCalib_NSGAII = True +except: + print 'No se logra importar deap tools, por lo tanto se deshabilita SimuBasin.Calib_NSGAII' + FlagCalib_NSGAII = False +try: + import rasterio.features as __fea__ + FlagBasinPolygon = True +except: + print 'No se logra importar rasterio, se deshabilita obtencion de poligono de cuenca' + FlagBasinPolygon = False + +import random +#Variable codigo EPSG +Global_EPSG = -9999 + +#----------------------------------------------------------------------- +#Ploteo de variables +#----------------------------------------------------------------------- +def plot_sim_single(Qs,Qo=None,mrain=None,Dates=None,ruta=None, + figsize=(8,4.5),ids=None,legend=True,ax1 = None,**kwargs): + '''ENTRADAS: + Qs = Caudal simulado, variable tipo lista + Qo = Caudal observado, variable tipo lista + mrain = Lluvia media observada,variable tipo lista + Dates = Indice de tiempo (Datetime), variable tipo lista + ids = Identificador de puntos de control + ax1 = axis o entorno para graficar + **kwargs = Argumentos por defecto, se pueden cambiar. + Estos argumentos son: + + ARGUMENTOS POR DEFECTO + rain_alpha': 0.4, Transparencia de la lluvia + rain_color': blue, Color de la lluvia + rain_lw : 0, Ancho de linea de lluvia + rain_ylabel: Precipitation [$mm$], Etiqueta del eje y de la lluvia + label_size: 14, Tamano de fuente + rain_ylim : Se ajusta, Limite del eje y + ColorSim : ['r','g','k','c','y'], Colores para simulacion de caudal + Qs_lw : 1.5, Ancho de linea de caudal simulado + Qo_lw : 2.0, Ancho de linea de caudal observado + Qs_color : red, Color de linea de caudal simulado + Qo_color : blue, Color de linea de caudal observado + Qo_label : Observed, Leyenda de caudal observado + Qs_label : Simulated, Leyenda de caudal simulado + xlabel : Time [$min$], Etiqueta del eje x + ylabel : Streamflow $[m^3/seg], Etiqueta del eje y + legend_loc : upper center, Ubicacion de la leyenda + bbox_to_anchor : (0.5,-0.12), Ajuste de la caja de la leyenda + legend_ncol : 4, Numero de columnas para la leyenda + ''' + #Argumentos kw + show = kwargs.get('show',True) + if ax1 == None: + fig=pl.figure(facecolor='w',edgecolor='w',figsize=figsize) + ax1=fig.add_subplot(111) + else: + show = False + #Fechas + if Dates==None: + if len(Qs.shape)>1: + ejeX=range(len(Qs[0])) + else: + ejeX = range(len(Qs)) + else: + ejeX=Dates + #Grafica la lluvia + if mrain is not None: + ax1AX=pl.gca() + ax2=ax1.twinx() + ax2AX=pl.gca() + alpha = kwargs.get('rain_alpha',0.4) + color = kwargs.get('rain_color','blue') + lw = kwargs.get('rain_lw',0) + ax2.fill_between(ejeX,0,mrain,alpha=alpha,color=color,lw=lw) + ylabel = kwargs.get('rain_ylabel','Precipitation [$mm$]') + label_size = kwargs.get('label_size',14) + ax2.set_ylabel(ylabel,size=label_size) + ylim = kwargs.get('rain_ylim',ax2AX.get_ylim() [::-1]) + ax2AX.set_ylim(ylim) + else: + ax2 = None + #grafica las hidrografas + ColorSim=kwargs.get('ColorSim',['r','g','k','c','y']) + Qs_lw = kwargs.get('Qs_lw',1.5) + Qo_lw = kwargs.get('Qo_lw',2.0) + Qs_color = kwargs.get('Qs_color','r') + Qo_color = kwargs.get('Qo_color','b') + Qo_label = kwargs.get('Qo_label','Observed') + Qs_label = kwargs.get('Qs_label','Simulated') + if len(Qs.shape)>1: + if ids is None: + ids = np.arange(1,Qs.shape[0]+1) + for i,c,d in zip(Qs,ColorSim,ids): + ax1.plot(ejeX,i,c,lw=Qs_lw,label=str(d)) + else: + ax1.plot(ejeX,Qs,Qs_color,lw=Qs_lw,label=Qs_label) + if Qo is not None: ax1.plot(ejeX,Qo,Qo_color,lw=Qo_lw,label=Qo_label) + #Pone elementos en la figura + xlabel = kwargs.get('xlabel','Time [$min$]') + ylabel = kwargs.get('ylabel','Streamflow $[m^3/seg]$') + label_size = kwargs.get('label_size', 16) + ax1.set_xlabel(xlabel,size=label_size) + ax1.set_ylabel(ylabel,size=label_size) + ax1.grid(True) + loc = kwargs.get('legend_loc','upper center') + bbox_to_anchor = kwargs.get('bbox_to_anchor',(0.5,-0.12)) + ncol = kwargs.get('legend_ncol',4) + if legend == True: + lgn1=ax1.legend(loc=loc, bbox_to_anchor=bbox_to_anchor, + fancybox=True, shadow=True, ncol=ncol) + if ruta is not None: + pl.savefig(ruta, bbox_inches='tight') + if show == True: + pl.show() + return ax1, ax2 + +def plot_mean_storage(Mean_Storage, Dates = None, mrain = None, + rute = None, **kwargs): + 'Funcion: plot_mean_storage\n'\ + 'Descripcion: Plotea como se encuentran los almacenamientos medios en la cuenca.\n'\ + 'Parametros Obligatorios:.\n'\ + ' -Mean_Storage: almacenamiento medio en cada uno de los tanques (5,Npasos).\n'\ + ' Esta es la variables obtenida por wmf.SimuBasin.run_shia como Mean_Storage.\n'\ + 'Parametros Opcionales:.\n'\ + ' -Dates: Fechas para el plot\n'\ + ' -marin: Lluvia promedio sobre la cuenca\n'\ + ' -rute: Ruta donde se va a guardar\n'\ + ' -kwargs: algunos argumentos de set del plot\n'\ + ' - figsize: tamano de la figura.\n'\ + ' - color: Color de los plot.\n'\ + ' - lw: ancho de la linea del plot.\n'\ + ' - labelsize: tamano de los label.\n'\ + ' - ysize: tamano de la fuente en el eje Y.\n'\ + 'Retorno:.\n'\ + ' Plot de los almacenamientos medios.\n'\ + #Argumentos kw + figsize = kwargs.get('figsize',(13,9)) + color = kwargs.get('color','k') + lw = kwargs.get('lw',4) + labelsize = kwargs.get('labelsize', 14) + ysize = kwargs.get('ysize', 16) + show = kwargs.get('show',True) + alpha = kwargs.get('alpha',0.5) + colorRain = kwargs.get('colorRain','b') + lwRain = kwargs.get('lwRain',0.1) + #Inicio de la funcion + if Dates==None: + ejeX=range(Mean_Storage.shape[1]) + else: + ejeX=Dates + #figura + fig = pl.figure(figsize = figsize) + nombres = ['Hu','Runoff','Hg','Sub','Stream'] + for c,i in enumerate(Mean_Storage): + ax = fig.add_subplot(5,1,c+1) + ax.plot(ejeX, i, color, lw = lw) + ax.grid() + # Deja el eje X solo en el ultimo plot + if c<4: + ax.set_xticklabels([]) + ax.tick_params(labelsize = labelsize) + #Pinta la lluvia en el primer plot + if c == 0 and mrain is not None: + ax2=ax.twinx() + ax2AX=pl.gca() + ax2.fill_between(ejeX,0,mrain,alpha=alpha,color=colorRain,lw=lwRain) + ylim = ax2AX.get_ylim()[::-1]; ylim = list(ylim); ylim[1] = 0 + ax2AX.set_ylim(ylim) + #Nombre de cada tanque + ax.set_ylabel(nombres[c], size = ysize) + if rute is not None: + pl.savefig(rute, bbox_inches='tight') + if show == True: + pl.show() + if c == 0 and mrain is not None: + return ax, ax2 + else: + return ax + +#----------------------------------------------------------------------- +#Lectura de informacion y mapas +#----------------------------------------------------------------------- +def read_map_raster(ruta_map,isDEMorDIR=False,dxp=None, noDataP = None,isDIR = False,DIRformat = 'r.watershed'): + 'Funcion: read_map\n'\ + 'Descripcion: Lee un mapa raster soportado por GDAL.\n'\ + 'Parametros Obligatorios:.\n'\ + ' -ruta_map: Ruta donde se encuentra el mapa.\n'\ + 'Parametros Opcionales:.\n'\ + ' -isDEMorDIR: Pasa las propiedades de los mapas al modulo cuencas \n'\ + ' escrito en fortran \n'\ + ' -dxp: tamano plano del mapa\n'\ + ' -noDataP: Valor para datos nulos en el mapa (-9999)\n'\ + ' -DIRformat: donde se ha conseguido el mapa dir (r.watershed) \n'\ + ' - r.watershed: mapa de direcciones obtenido por la funcion de GRASS\n'\ + ' - opentopo: mapa de direcciones de http://www.opentopography.org/\n'\ + ' -isDIR: (FALSE) es este un mapa de direcciones\n'\ + 'Retorno:.\n'\ + ' Si no es DEM o DIR retorna todas las propieades del elemento en un vector.\n'\ + ' En el siguiente orden: ncols,nrows,xll,yll,dx,nodata.\n'\ + ' Si es DEM o DIR le pasa las propieades a cuencas para el posterior trazado.\n'\ + ' de cuencas y tramos.\n' \ + #Abre el mapa + direction=gdal.Open(ruta_map) + #Proyecction + proj = osgeo.osr.SpatialReference(wkt=direction.GetProjection()) + EPSG_code = proj.GetAttrValue('AUTHORITY',1) + #lee la informacion del mapa + ncols=direction.RasterXSize + nrows=direction.RasterYSize + banda=direction.GetRasterBand(1) + noData=banda.GetNoDataValue() + geoT=direction.GetGeoTransform() + dx=geoT[1] + dy = np.abs(geoT[-1]) + xll=geoT[0]; yll=geoT[3]-nrows*dy + #lee el mapa + Mapa=direction.ReadAsArray() + direction.FlushCache() + del direction + if isDEMorDIR==True: + cu.ncols=ncols + cu.nrows=nrows + if noDataP is not None: + cu.nodata = noDataP + Mapa[Mapa<0] = cu.nodata + else: + cu.nodata=noData + cu.dx=dx + cu.dy = dy + cu.xll=xll + cu.yll=yll + if dxp==None: + cu.dxp=30.0 + else: + cu.dxp=dxp + #Guarda la variable para el proyecto + global Global_EPSG + Global_EPSG = EPSG_code + # si es un dir se fija si es de r.watershed + if isDIR: + if DIRformat == 'r.watershed': + Mapa[Mapa<=0] = cu.nodata.astype(int) + Mapa = cu.dir_reclass_rwatershed(Mapa.T,cu.ncols,cu.nrows) + return Mapa, EPSG_code + if DIRformat == 'opentopo': + Mapa[Mapa<=0] = cu.nodata.astype(int) + Mapa = cu.dir_reclass_opentopo(Mapa.T,cu.ncols,cu.nrows) + return Mapa, EPSG_code + #retorna el mapa + return Mapa.T,EPSG_code + else: + return Mapa.T,[ncols,nrows,xll,yll,dx,dy,noData],EPSG_code + +def read_map_points(ruta_map, ListAtr = None): + 'Funcion: read_map_points\n'\ + 'Descripcion: Lee un mapa vectorial de puntos soportado por GDAL.\n'\ + 'Parametros Obligatorios:.\n'\ + ' -ruta_map: Ruta donde se encuentra el mapa.\n'\ + 'Parametros Opcionales:.\n'\ + ' -ListAtr: Lista con los nombres de los atributos de las columnas\n'\ + ' que se quieren leer dentro de la variable Dict\n'\ + 'Retorno:.\n'\ + ' Si ListAtr == None: Retorna unicamente las coordenadas.\n'\ + ' Si ListAtr == [Nombre1, Nombre2, ...]: Retorna: Coord y diccionario con variables.\n'\ + #Obtiene el acceso + dr = osgeo.ogr.Open(ruta_map) + l = dr.GetLayer() + #Lee las coordenadas + Cord = [] + for i in range(l.GetFeatureCount()): + f = l.GetFeature(i) + g = f.GetGeometryRef() + pt = [g.GetX(),g.GetY()] + Cord.append(pt) + Cord = np.array(Cord).T + #Si hay atributos para buscar los lee y los m + if ListAtr is not None: + Dict = {} + for j in ListAtr: + #Busca si el atributo esta + pos = f.GetFieldIndex(j) + #Si esta lee la info del atributo + if pos is not -1: + vals = [] + for i in range(l.GetFeatureCount()): + f = l.GetFeature(i) + vals.append(f.GetField(pos)) + Dict.update({j:np.array(vals)}) + #Cierra el mapa + dr.Destroy() + return Cord, Dict + else: + #Cierra el mapa + dr.Destroy() + return Cord + +def Save_Array2Raster(Array, ArrayProp, ruta, EPSG = 4326, Format = 'GTiff'): + dst_filename = ruta + #Formato de condiciones del mapa + x_pixels = Array.shape[0] # number of pixels in x + y_pixels = Array.shape[1] # number of pixels in y + PIXEL_SIZE = ArrayProp[4] # size of the pixel... + x_min = ArrayProp[2] + y_max = ArrayProp[3] + ArrayProp[4] * ArrayProp[1] # x_min & y_max are like the "top left" corner. + driver = gdal.GetDriverByName(Format) + #Para encontrar el formato de GDAL + NP2GDAL_CONVERSION = { + "uint8": 1, + "int8": 1, + "uint16": 2, + "int16": 3, + "uint32": 4, + "int32": 5, + "float32": 6, + "float64": 7, + "complex64": 10, + "complex128": 11, + } + gdaltype = NP2GDAL_CONVERSION[Array.dtype.name] + # Crea el driver + dataset = driver.Create( + dst_filename, + x_pixels, + y_pixels, + 1, + gdaltype,) + #coloca la referencia espacial + dataset.SetGeoTransform(( + x_min, # 0 + PIXEL_SIZE, # 1 + 0, # 2 + y_max, # 3 + 0, # 4 + -PIXEL_SIZE)) + #coloca la proyeccion a partir de un EPSG + proj = osgeo.osr.SpatialReference() + texto = 'EPSG:' + str(EPSG) + proj.SetWellKnownGeogCS( texto ) + dataset.SetProjection(proj.ExportToWkt()) + #Coloca el nodata + band = dataset.GetRasterBand(1) + if ArrayProp[-1] == None: + band.SetNoDataValue(wmf.cu.nodata.astype(int).max()) + else: + band.SetNoDataValue(-9999) + #Guarda el mapa + dataset.GetRasterBand(1).WriteArray(Array.T) + dataset.FlushCache() + +def Save_Points2Map(XY,ids,ruta,EPSG = 4326, Dict = None, + DriverFormat='ESRI Shapefile'): + 'Funcion: Save_Points2Map\n'\ + 'Descripcion: Guarda coordenadas X,Y en un mapa tipo puntos.\n'\ + 'Parametros Opcionales:.\n'\ + 'XY: Coordenadas de los puntos X,Y.\n'\ + 'ids: Numero que representa a cada punto.\n'\ + 'ruta: Ruta de escritura de los puntos.\n'\ + 'Opcionales:.\n'\ + 'EPSG : Codigo del tipo de proyeccion usada, defecto 4326 de WGS84.\n'\ + 'Dict : Diccionario con prop de los puntos, Defecto: None.\n'\ + 'DriverFormat : Formato del archivo vectorial, Defecto: ESRI Shapefile.\n'\ + 'Retorno:.\n'\ + ' Escribe el mapa en la ruta especificada.\n'\ + #Genera el shapefile + spatialReference = osgeo.osr.SpatialReference() + spatialReference.ImportFromEPSG(EPSG) + driver = osgeo.ogr.GetDriverByName(DriverFormat) + if os.path.exists(ruta): + driver.DeleteDataSource(ruta) + shapeData = driver.CreateDataSource(ruta) + layer = shapeData.CreateLayer('layer1', spatialReference, osgeo.ogr.wkbPoint) + layerDefinition = layer.GetLayerDefn() + new_field=osgeo.ogr.FieldDefn('Estacion',osgeo.ogr.OFTReal) + layer.CreateField(new_field) + if Dict is not None: + for p in Dict.keys(): + tipo = type(Dict[p][0]) + if tipo is np.float64: + new_field=osgeo.ogr.FieldDefn(p[:10],osgeo.ogr.OFTReal) + elif tipo is np.int64: + new_field=osgeo.ogr.FieldDefn(p[:10],osgeo.ogr.OFTInteger) + elif tipo is str: + new_field=osgeo.ogr.FieldDefn(p[:10],osgeo.ogr.OFTString) + layer.CreateField(new_field) + #Mete todos los puntos + featureIndex=0 + contador=0 + #Calcula el tamano de la muestra + N=np.size(XY,axis=1) + if N>1: + for i in XY.T: + if i[0]<>-9999.0 and i[1]<>-9999.0: + #inserta el punto + point = osgeo.ogr.Geometry(osgeo.ogr.wkbPoint) + point.SetPoint(0, float(i[0]), float(i[1])) + feature = osgeo.ogr.Feature(layerDefinition) + feature.SetGeometry(point) + feature.SetFID(featureIndex) + feature.SetField('Estacion',ids[contador]) + #Le coloca lo del diccionario + if Dict is not None: + for p in Dict.keys(): + tipo = type(Dict[p][0]) + if tipo is np.float64: + feature.SetField(p[:10],float("%.2f" % Dict[p][contador])) + elif tipo is np.int64: + feature.SetField(p[:10],int("%d" % Dict[p][contador])) + elif tipo is str: + feature.SetField(p[:10],Dict[p][contador]) + #Actualiza contadores + contador+=1 + layer.CreateFeature(feature) + point.Destroy() + feature.Destroy() + else: + point = osgeo.ogr.Geometry(osgeo.ogr.wkbPoint) + point.SetPoint(0, float(XY[0,0]), float(XY[1,0])) + feature = osgeo.ogr.Feature(layerDefinition) + feature.SetGeometry(point) + feature.SetFID(featureIndex) + feature.SetField('Estacion',ids) + for p in Dict.keys(): + feature.SetField(p[:p.index('[')].strip()[:10],float("%.2f" % Param[p])) + contador+=1 + layer.CreateFeature(feature) + point.Destroy() + feature.Destroy() + shapeData.Destroy() + +def __ListaRadarNames__(ruta,FechaI,FechaF,fmt,exten,string,dt): + 'Funcion: OCG_param\n'\ + 'Descripcion: Obtiene una lista con los nombres para leer datos de radar.\n'\ + 'Parametros:.\n'\ + ' -FechaI, FechaF: Fechas inicial y final en formato datetime.\n'\ + ' -fmt : Formato en el que se pasa FechaI a texto, debe couincidir con.\n'\ + ' el del texto que se tenga en los archivos.\n'\ + ' -exten : Extension de los archivos .asc, .nc, .bin ...\n'\ + ' -string : texto antes de la fecha.\n'\ + ' -dt : Intervalos de tiempo entre los eventos.\n'\ + 'Retorno:.\n'\ + ' Lista : la lista de python con los nombres de los binarios.\n'\ + #Crea lista de fechas y mira que archivos estan en esas fechas + Dates=[FechaI]; date=FechaI + while datei: + Flag = True + c2 = c + c3 = 0 + while Flag: + if i= Y.size: Flag = False + else: + Flag=False + Pos.append(c2) + c+=1 + # Obtiene la segunda derivada de la corriente corregida + Y = pd.Series(Y) + Y = Y.rolling(window).mean() + l = Y[np.isnan(Y)].shape[0] + Y[:l]=Y[l+1] + slope = np.diff(Y,1) + slope = np.hstack([slope,slope[-1]]) + return Y,np.abs(slope) + +#----------------------------------------------------------------------- +#Clase de cuencas +#----------------------------------------------------------------------- + +class Basin: + + #------------------------------------------------------ + # Subrutinas de trazado de cuenca y obtencion de parametros + #------------------------------------------------------ + #Inicia la cuenca + def __init__(self,lat=0,lon=0,DEM=None,DIR=None,name='NaN',stream=None, + umbral=1000, ruta = None, useCauceMap = None): + 'Descripcion: Inicia la variable de la cuenca, y la traza \n'\ + ' obtiene las propiedades basicas de la cuenca. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'lat : Coordenada en X de la salida de la cuenca.\n'\ + 'lon : Coordenada en Y de la salida de la cuenca.\n'\ + 'name : Nombre con el que se va a conocer la cuenca.\n'\ + 'stream : Opcional, si se coloca, las coordenadas no tienen.\n'\ + ' que ser exactas, estas se van a corregir para ubicarse.\n'\ + ' en el punto mas cercano dentro de la corriente, este.\n'\ + ' debe ser un objeto del tipo stream.\n'\ + 'umbral : umbral minimo para la creacion de cauce (defecto =1000).\n'\ + 'ruta : Ruta donde se encuentra un archivo binario de la cuenca.\n'\ + 'useCauceMap : Si se asigna un mapa binario donde 1 es cauce y 0 es ladera.\n'\ + ' el trazador corregira las coordenadas para que estas lleguen a una celda.\n'\ + ' tipo cauce y se trace la cuenca de forma correcta (esta opcion deshabilita \n'\ + ' a stream)\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas.\n'\ + #Relaciona con el DEM y el DIR + self.DEM=DEM + self.DIR=DIR + #Si se da la opcion de que use el useCauceMap deshabilita stream + if useCauceMap is not None: + stream = None + #Si se entrega cauce corrige coordenadas + if ruta == None: + # Si se da el stream corrige por corriente + if stream is not None: + error=[] + for i in stream.structure.T: + error.append( np.sqrt((lat-i[0])**2+(lon-i[1])**2) ) + loc=np.argmin(error) + lat=stream.structure[0,loc] + lon=stream.structure[1,loc] + if useCauceMap is not None and useCauceMap.shape == DEM.shape: + lat,lon = cu.stream_find_to_corr(lat,lon,DEM,DIR,useCauceMap, + cu.ncols,cu.nrows) + #copia la direccion de los mapas de DEM y DIR, para no llamarlos mas + self.name=name + #Traza la cuenca + self.ncells = cu.basin_find(lat,lon,DIR, + cu.ncols,cu.nrows) + self.structure = cu.basin_cut(self.ncells) + self.umbral = umbral + else: + self.__Load_BasinNc(ruta) + #Genera el poligono de la cuenca + self.__GetBasinPolygon__() + #Cargador de cuenca + def __Load_BasinNc(self,ruta,Var2Search=None): + 'Descripcion: Lee una cuenca posteriormente guardada\n'\ + ' La cuenca debio ser guardada con Basin.Save_Basin2nc\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'ruta : ruta donde se encuentra ubicada la cuenca guardada\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : La cuenca con sus parametros ya cargada.\n'\ + #Abre el archivo binario de la cuenca + self.rutaNC = ruta + gr = netcdf.Dataset(ruta,'a') + #obtiene las prop de la cuenca + self.name = gr.nombre + self.ncells = gr.ncells + self.umbral = gr.umbral + #Obtiene las prop de los mapas + cu.ncols=gr.ncols + cu.nrows=gr.nrows + cu.nodata=gr.noData + cu.dx=gr.dx + cu.xll=gr.xll + cu.yll=gr.yll + cu.dxp=gr.dxp + #Obtiene las variables vectoriales + self.structure = gr.variables['structure'][:] + #Cierra el archivo + gr.close() + + def Load_BasinVar(self, varName): + 'Descripcion: Lee una variable especifica del netCDf de la cuenca\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'varName: nombre de la variable guardada\n'\ + 'Retornos\n'\ + '----------\n'\ + 'var : Retorna la variable como un numpy array.\n'\ + #Lectura del netCDf y lectura de variable + gr = netcdf.Dataset(self.rutaNC,'a') + Var = gr.variables[varName][:] + gr.close() + return Var + + #Guardado de de la cuenca en nc + def Save_Basin2nc(self,ruta,qmed=None,q233=None,q5=None, + ExtraVar=None): + 'Descripcion: guarda una cuenca previamente ejecutada\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'ruta : Ruta donde la cuenca sera guardada.\n'\ + 'qmed : Matriz con caudal medio estimado.\n'\ + 'q233 : Matriz con caudal minimo de 2.33.\n'\ + 'q5 : Matriz con caudal minimo de 5.\n'\ + 'ExtraVar: Diccionario con variables extras que se quieran guardar,.\n'\ + ' se guardan como flotantes.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas.\n'\ + #Diccionario con las propiedades + Dict = {'nombre':self.name, + 'noData':cu.nodata, + 'ncells':self.ncells, + 'umbral':self.umbral, + 'dxp':cu.dxp, + 'dx':cu.dx, + 'xll':cu.xll, + 'yll':cu.yll, + 'ncols':cu.ncols, + 'nrows':cu.nrows} + #abre el archivo + gr = netcdf.Dataset(ruta,'w',format='NETCDF4') + #Establece tamano de las variables + DimNcell = gr.createDimension('ncell',self.ncells) + DimCol3 = gr.createDimension('col3',3) + #Crea variables + VarStruc = gr.createVariable('structure','i4',('col3','ncell'),zlib=True) + VarQmed = gr.createVariable('q_med','f4',('ncell',),zlib=True) + VarQ233 = gr.createVariable('q_233','f4',('ncell',),zlib=True) + VarQ5 = gr.createVariable('q_5','f4',('ncell',),zlib=True) + #Variables opcionales + if type(ExtraVar) is dict: + for k in ExtraVar.keys(): + Var = gr.createVariable(k,'f4',('ncell',),zlib=True) + Var[:] = ExtraVar[k] + #Asigna valores a las variables + VarStruc[:] = self.structure + if qmed is not None: + VarQmed[:] = qmed + if q233 is not None: + VarQ233[:] = q233 + if q5 is not None: + VarQ5[:] = q5 + #asignlas prop a la cuenca + gr.setncatts(Dict) + #Cierra el archivo + gr.close() + #Sale del programa + return + #Parametros Geomorfologicos + def GetGeo_Parameters(self,rutaParamASC=None,plotTc=False, + rutaTcPlot = None, figsize=(8,5), GetPerim=True): + 'Descripcion: Obtiene los parametros geomorfologicos de la cuenca \n'\ + ' y los tiempos de concentracion calculados por diferentes metodologias. \n'\ + '\n'\ + 'Parametros\n'\ + ' rutaParamASC: ruta del ascii donde se escriben los param.\n'\ + ' plotTc: Plotea o no los tiempos de concentracion.\n'\ + ' rutaTcPlot: Si se da se guarda la figura de tiempos de concentracion.\n'\ + '----------\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'GeoParameters : Parametros de la cuenca calculados.\n'\ + 'Tc : Tiempo de concentracion calculado para la cuenca.\n'\ + #Calcula lo que se necesita para sacar los parametros + acum,longCeld,slope,Elev=cu.basin_basics(self.structure, + self.DEMvec,self.DIRvec,self.ncells) + Lpma,puntto=cu.basin_findlong(self.structure,self.ncells) + cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod(self.structure, + acum,self.umbral,self.ncells) + ppal_nceldas,punto = cu.basin_ppalstream_find(self.structure, + nodos,longCeld,Elev,self.ncells) + ppal = cu.basin_ppalstream_cut(ppal_nceldas,self.ncells) + self.hipso_main,self.hipso_basin=cu.basin_ppal_hipsometric( + self.structure,Elev,punto,30,ppal_nceldas,self.ncells) + self.main_stream=ppal + #Obtiene los parametros + Perim = self.Polygon.shape[1]*cu.dxp/1000. + Area=(self.ncells*cu.dxp**2)/1e6 + TotalCauces = self.CellCauce*self.CellLong + TotalCauces = TotalCauces.sum() / 1000. #[km] + Densidad = TotalCauces / Area #[km/km2] + Lcau=ppal[1,-1]/1000.0 + Scau=np.polyfit(ppal[1,::-1],ppal[0],1)[0]*100 + Scue=slope.mean()*100 + Hmin=Elev[-1]; Hmax=Elev[puntto]; Hmean=Elev.mean() + HCmax=Elev[punto] + x,y = cu.basin_coordxy(self.structure,self.ncells) + CentXY = [np.median(x),np.median(y)] + #Genera un diccionario con las propiedades de la cuenca + self.GeoParameters={'Area_[km2]': Area, + 'Pend_Cauce_[%]':Scau, + 'Long_Cauce_[km]': Lcau, + 'Pend_Cuenca_[%]': Scue, + 'Long_Cuenca_[km]': Lpma, + 'Hmax_[m]':Hmax, + 'Hmin_[m]':Hmin, + 'Hmean_[m]':Hmean, + 'H_Cauce_Max_[m]':HCmax, + 'Centro_[X]': CentXY[0], + 'Centro_[Y]': CentXY[1], + 'Long_tot_cauces_[km]': TotalCauces, + 'Densidad_drenaje_[km/km2]': Densidad} + if GetPerim: + self.GeoParameters.update({'Perimetro_[km]':Perim}) + #Calcula los tiempos de concentracion + Tiempos={} + Tc=0.3*(Lcau/(Scue**0.25))**0.75 + Tiempos.update({'US Army': Tc}) + Tc=0.3*(Lcau/((Hmax-Hmin)/Lcau)**0.25)**0.75 + Tiempos.update({'Direccion Carreteras Espana': Tc}) + Tc=(0.02*(Lpma*1000.0)**0.77)/((Scau/100.0)**0.385)/60.0 + Tiempos.update({'Kiprich': Tc}) + Tc=8.157*((Area**0.316)/(((Scau*100)**0.17)*Scue**0.565)) + Tiempos.update({'Campo y Munera': Tc}) + Tc=(4*np.sqrt(Area)+1.5*Lcau)/(0.8*np.sqrt(Hmean)) + Tiempos.update({'Giandotti':Tc}) + Tc=0.4623*(Lcau**0.5)*((Scue/100.0)**(-0.25)) + Tiempos.update({'John Stone': Tc}) + Tc=(Lcau/Area)*(np.sqrt(Area)/Scau) + Tiempos.update({'Ventura': Tc}) + Tc=0.3*(Lcau/(((HCmax-Hmin)/Lcau)*100)**0.25)**0.75 + Tiempos.update({'Temez': Tc}) + self.Tc=Tiempos + #Si se habilita la funcion para guardar el ascii de param lo hace + if rutaParamASC is not None: + self.__WriteGeoParam__(rutaParamASC) + # Grafica Tc si se habilita + if plotTc is True: + self.Plot_Tc(ruta = rutaTcPlot, figsize=figsize) + #Funcion para escribir los parametros de la cuenca en un ascii + def __WriteGeoParam__(self,ruta): + f=open(ruta,'w') + f.write('------------------------------------------------------------ \n') + f.write('Parametros Cuenca \n') + f.write('------------------------------------------------------------ \n') + k=self.GeoParameters.keys() + for i in k: + v=self.GeoParameters[i] + if type(v) is not list: + f.write('%s : %.4f \n' % (i,v)) + f.write('------------------------------------------------------------ \n') + f.write('Tiempos de concentracion \n') + f.write('------------------------------------------------------------ \n') + k=self.Tc.keys() + for i in k: + v=self.Tc[i] + f.write('%s : %.4f \n' % (i,v)) + f.close() + + #Obtiene la envolvente de la cuenca + def __GetBasinPolygon__(self): + 'Descripcion: obtiene la envolvente de la cuenca, en coordenadas \n'\ + ' x,y, esta informacion luego sirve para plot y para escribir el\n'\ + ' shpfile de la cuenca\n'\ + #Evalua si se cuenta con rasterio en el sistema o no. + if FlagBasinPolygon: + #Obtiene mapa raster, propiedades geo y formato para escribir + Map, Prop = self.Transform_Basin2Map(np.ones(self.ncells)) + tt = [Prop[2], Prop[4].tolist(), 0.0, + Prop[1]*Prop[-2] + Prop[3], 0.0, -1*Prop[5].tolist()] + #Obtiene los shps con la forma de la o las envolventes de cuenca + Map = Map.T + mask = Map != -9999. + shapes = __fea__.shapes(Map, mask=mask, transform=tt) + #Obtiene el poligono de la cuenca completo + Shtemp = [] + flag = True + while flag: + try: + Shtemp.append(shapes.next()) + except: + flag = False + DicPoly = {} + for Sh in Shtemp: + Coord = Sh[0]['coordinates'] + Value = int(Sh[1]) + DicPoly.update({str(Value):{}}) + for cont,co in enumerate(Coord): + DicPoly[str(Value)].update({str(cont):np.array(co).T}) + #Por si hay mas de un poligono al interior + Tam = 0 + for k in DicPoly['1'].keys(): + if DicPoly['1'][k].size > Tam: + Tam = DicPoly['1'][k].size + goodKey = k + self.Polygon = DicPoly['1'][goodKey] + return 0 + else: + return 1 + + #Parametros por mapas (distribuidos) + def GetGeo_Cell_Basics(self): + 'Descripcion: Obtiene: area acumulada, long de celdas, Pendiente \n'\ + ' y Elevacion en cada elemento de la cuenca. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'CellAcum : Cantidad de celdas acumuladas.\n'\ + 'CellLong : Longitud de cada una de las celdas [mts].\n'\ + 'CellSlope : Pendiente de cada una de las celdas [y/x].\n'\ + 'CellHeight : Elevacion de cada una de las celdas [m.s.n.m].\n'\ + #obtiene los parametros basicos por celdas + acum,longCeld,S0,Elev=cu.basin_basics(self.structure, + self.DEMvec,self.DIRvec,self.ncells) + self.CellAcum=acum; self.CellLong=longCeld + self.CellSlope=S0; self.CellHeight=Elev + #Obtiene el canal en la cuenca + self.CellCauce = np.zeros(self.ncells) + self.CellCauce[self.CellAcum>self.umbral]=1 + def GetGeo_StreamOrder(self, MajorBasins = False, umbral = 100, verbose = False, FirtsOrder = 1): + 'Descripcion: Obtiene el orden de horton para cada celda de \n'\ + ' cada ladera y para las celdas de cada cauce.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + 'MajorBasins : Obtiene binarios con las sub-cuencas drenando.\n'\ + ' unicamente a cuencas de orden mayor (ej: todas las orden 2 que \n'\ + ' drenan a orden 3 o major).\n'\ + 'umbral: Cantidad minima de celdas para considerar canal (aplica cuando\n'\ + ' se obtienen las sub-cuencas mayores.\n'\ + 'verbose: Muestra el paso de calculo de cuencas mayores.\n'\ + 'FirtsOrder: Primer orden a partir dle cual se analizan ordenes mayores.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'CellHorton_Hill : Orden de horton de cada ladera.\n'\ + 'CellHorton_Stream : Orden de horton de cada elemento de cauce.\n'\ + #obtiene los parametros basicos por celdas + cauce,nodos_fin,n_nodos = cu.basin_subbasin_nod(self.structure,self.CellAcum,self.umbral,self.ncells) + sub_pert,sub_basin = cu.basin_subbasin_find(self.structure,nodos_fin,n_nodos,self.ncells) + sub_basins = cu.basin_subbasin_cut(n_nodos) + sub_horton,nod_horton = cu.basin_subbasin_horton(sub_basins,self.ncells,n_nodos) + self.CellHorton_Hill,sub_basin = cu.basin_subbasin_find(self.structure,nod_horton,n_nodos,self.ncells) + #Obtiene el canal en la cuenca + self.CellHorton_Stream = self.CellCauce * self.CellHorton_Hill + #Obtiene las cuencas mayores + if MajorBasins: + pos = np.where(models.control>0)[1] + X,Y = cu.basin_coordxy(self.structure, self.ncells) + DictBasins = {} + for Orden in range(FirtsOrder,self.CellHorton_Hill[-1]): + #Encuentra cuencas de un orden que drenen a un orden mayor + pos2 = np.where(self.CellHorton_Stream[pos] == Orden)[0] + drena = self.ncells - self.structure[0] + pos3 = np.where(self.CellHorton_Stream[drena[pos[pos2]]] > Orden)[0] + #Las ubica en un mapa dentro d ela cuenca + SubCuencas = np.zeros(self.ncells) + cont = 1 + for x,y in zip(X[pos[pos2[pos3]]], Y[pos[pos2[pos3]]]): + #Traza la cuenca + cuTemp = SimuBasin(x,y, self.DEM, self.DIR, umbral=umbral) + #La pega en una mascara con las cub-cuencas + Map, prop = cuTemp.Transform_Basin2Map(np.ones(cuTemp.ncells),) + Map[Map == -9999] = 0 + Var = self.Transform_Map2Basin(Map, prop) + Var[Var == 0] = -9999 + Var[Var == 1] = cont + ptemp = np.where(Var == cont)[0] + #Lo pega en la mascara de sub-uencas + SubCuencas[ptemp] = SubCuencas[ptemp] + Var[ptemp] + cont+=1 + #Agrega al diccionario + DictBasins.update({str(Orden):SubCuencas}) + #Si es verbose muestra en que paso va + if verbose: + print 'Sub-cuencas orden '+str(Orden)+' calculadas' + #Traza la cuenca original para no danar la estructura de guardado + cuTemp = SimuBasin(X[-1], Y[-1], self.DEM, self.DIR, umbral = umbral) + #Retorna el diccionario con las sub-cuencas mayore + return DictBasins + def GetGeo_IsoChrones(self,Tc,Niter=4): + 'Descripcion: Obtiene el tiempo de viaje aproximado de cada \n'\ + ' celda a la salida de la cuenca, para eso usa el tiempo de . \n'\ + ' concentracion obtenido por la funcion GetGeo_Parameters . \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + ' self : no necesita nada es autocontenido.\n'\ + ' Tc : Valor escalar de tiempo de concentracion.\n'\ + ' Niter: Cantidad de iteraciones para aproximar vel, defecto 4.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'isochrones : Mapa de viaje de cada celda a la salida [hrs].\n'\ + #Calcula la velocidad adecuada para que el tiempo coincida + acum,longCeld,S0,Elev=cu.basin_basics(self.structure, + self.DEM,self.DIR,cu.ncols,cu.nrows,self.ncells) + rangos=[50,25,1] + for i in range(Niter): + times=[] + for r in rangos: + speed = r*S0**(0.5) + time = cu.basin_time_to_out(self.structure, + longCeld,speed,self.ncells)/3600.0 + times.append(time[np.isfinite(time)].mean()) + for j in range(2): + if Tc>times[j] and Tc=i) & (time0], bins = binsN) + #Variables del elemento + self.width_hits = hn + self.width_distances = bn[:-1]/1000. + #Estandariza en terminos de probabilidad + hc = hc.astype(float); hc = hc / hc.sum() + hn = hn.astype(float); hn = hn / hn.sum() + #Grafica + fig = pl.figure(figsize=figsize) + ax = fig.add_subplot(111) + ax.plot(bc[:-1]/1000.0, hc, ccolor, lw = 3, label = 'Basin Width') + ax.plot(bn[:-1]/1000.0, hn, ncolor,lw = 3, label = 'Network Width') + ax.grid(True) + ax.set_xlabel('Distance to Outlet [$km$]', size = 16) + ax.set_ylabel('PDF', size = 16) + ax.fill_between(bc[:-1]/1000.0, hc, color = ccolor, alpha = 0.3) + ax.fill_between(bn[:-1]/1000.0, hn, color = ncolor, alpha = 0.3) + ax.set_ylim(0, np.max([hc.max(), hn.max()])+0.01) + ax.tick_params(labelsize = 15) + ax.legend(loc = 0) + ax2 = ax.twinx() + ax2.plot(bc[:-1]/1000.0, hc.cumsum(), ccolor, lw = 3, ls = '--', label = 'Basin Width') + ax2.plot(bn[:-1]/1000.0, hn.cumsum(), ncolor, lw = 3, ls = '--',label = 'Network Width') + ax2.tick_params(labelsize = 15) + ax2.set_ylabel('CDF', size = 16) + #Guarda la figura + if ruta is not None: + pl.savefig(ruta, bbox_inches='tight',pad_inches = 0.25) + if show: + pl.show() + #Retorna ejes de manipulacion + return ax,ax2 + + def GetGeo_Ppal_Hipsometric(self,umbral=1000, + intervals = 30): + 'Descripcion: Calcula y grafica la curva hipsometrica de\n'\ + ' la cuenca.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'umbral : cantidad minima de celdas para el trazado.\n'\ + 'intervals: Cantidad de intervalos en los cuales se haran .\n'\ + ' los muestreos de la curva hipsometrica.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Hipso : Curva hipsometrica en formato vectorial, contiene.\n'\ + ' - Curva sobre cauce ppal.\n'\ + ' - Curva como histograma de la cuenca.\n'\ + 'Figura: Figura de ambas curvas.\n'\ + # Obtiene los nodos de la red hidrica + cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( + self.structure, + self.CellAcum, + umbral, + self.ncells) + # Obtiene el cauce ppal + ppal_nceldas,punto = cu.basin_ppalstream_find( + self.structure, + nodos, + self.CellLong, + self.CellHeight, + self.ncells) + self.ppal_stream = cu.basin_ppalstream_cut(ppal_nceldas, + self.ncells) + #Corrige el perfil del cauce ppal + self.ppal_stream[0],self.ppal_slope = __ModifyElevErode__(self.ppal_stream[0]) + # Obtiene la curva hipsometrica + self.hipso_ppal, self.hipso_basin = cu.basin_ppal_hipsometric( + self.structure, + self.CellHeight, + punto, + intervals, + ppal_nceldas) + self.hipso_ppal[1],self.hipso_ppal_slope = __ModifyElevErode__(self.hipso_ppal[1]) + def GetGeo_IT(self): + 'Descripcion: Calcula el indice topografico para cada celda (Beven)\n'\ + ' Internamente calcula el area para cada elemento y la pendiente en radianes.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'IT : Indice topografico adimensional, a mayor valor se supone un suelo mas humedo.\n'\ + #Obtiene el area + acum = cu.basin_acum(self.structure, self.ncells) + #Obtiene la pendiente en radianes + acum,longCeld,slope,Elev=cu.basin_basics(self.structure, + self.DEMvec,self.DIRvec,self.ncells) + slope = np.arctan(slope) + slope[slope == 0] = 0.0001 + return np.log((acum*cu.dxp) / np.tan(slope)) + + def GetGeo_HAND(self,umbral=1000): + 'Descripcion: Calcula Height Above the Nearest Drainage (HAND) \n'\ + ' y Horizontal Distance to the Nearest Drainage (HDND) (Renno, 2008). \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + 'umbral : cantidad minima de celdas para el trazado.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'HAND : Elevacion sobre la red de drenaje cercana [mts].\n'\ + 'HDND : Distancia horizontal a la red de drenaje cercana [mts].\n'\ + #obtiene los parametros basicos por celdas + acum,longCeld,S0,Elev=cu.basin_basics(self.structure, + self.DEMvec,self.DIRvec,self.ncells) + cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( + self.structure,acum,umbral,self.ncells) + hand,hdnd,hand_destiny = cu.geo_hand(self.structure,Elev,longCeld,cauce,self.ncells) + handC=np.zeros(self.ncells) + handC[hand<5.3]=1 + handC[(hand>=5.3) & (hand<=15.0)]=2 + handC[(hand>15.0) & (S0<0.076)]=4 + handC[(hand>15.0) & (S0>=0.076)]=3 + self.CellHAND=hand + self.CellHAND_class=handC + self.CellHDND=hdnd + self.CellHAND_drainCell=hand_destiny + + def GetGeo_Sections(self, NumCeldas = 6): + 'Descripcion: Obtiene secciones transversales a traves de todos.\n'\ + ' los elementos de la red de drenaje, las secciones se obtienen\n'\ + ' en la direccion perpendicular al flujo, es decir si el mapa de\n'\ + ' direcciones indica en una celda la direccion norte, las secciones\n'\ + ' se obtienen en lsa direcciones oriente, occidente, con NumCeldas\n'\ + ' a cada lado de la celda tipo cauce.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'NumCeldas: Cantidad de celdas para elaborar secciones a ambos lados.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self.Sections : Secciones a traves de los elementos del cauce.\n'\ + ' su tamano es [NumCeldas*2 + 1, self.ncells]\n'\ + #Obtiene mapa de cauces + self.GetGeo_Cell_Basics() + #Obtiene vector de direcciones + directions = self.Transform_Map2Basin(self.DIR, + [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy ,0.0]) + #Obtiene las secciones + self.Sections, self.Sections_Cells = cu.basin_stream_sections(self.structure, + self.CellCauce, directions, self.DEM, NumCeldas, + self.ncells, cu.ncols, cu.nrows) + + #------------------------------------------------------ + # Subrutinas para el calculo de extremos mediante hidrografa unitaria sintetica + #------------------------------------------------------ + def GetHU_Snyder(self,Area,Tc,Cp=0.8,Fc=2.9,pequena='si'): + 'Descripcion: Obtiene HU segun Snyder.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'Area: area de la cuenca en km2.\n'\ + 'Tc: Tiempo de concentracion en Horas.\n'\ + 'Cp : Factor de escalamiento [0.8].\n'\ + 'Fc : Factor de escalamiento [2.9].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Tiempo : Tiempo total de duracion [M].\n'\ + 'Q : Caudal unitario.\n'\ + 'HU : Reglas del hidrograma unitario.\n'\ + #Calcula parametros para la hidrografa + Tr=0.6*Tc # [h] + T=0.1*Tc # [h] + Ts=Tr/5.5 # [h] + up=Cp*640/(Tr+(T-Ts)/4) #pie3/s/mi2/Pulg + Up=up*0.386*Area + Up=Up*(0.3048)**3.0/25.4 + Tp=T/2+Tr # horas + Tb=3+3*Tr/24 # dias + W50=770/up**1.08 + W75=440/up**1.08 + # Factor de multiplicacion + tb=Tp*Fc #horas + #obtiene las coordenadas del hidrograma + HU=[[0,0]] + At=(Tp-W50/3)*60; Aq=0.5*Up; HU.append([At,Aq]) + Bt=(Tp-W75/3)*60; Bq=0.75*Up; HU.append([Bt,Bq]) + Tpt=Tp*60; Tpq=Up; HU.append([Tpt,Tpq]) + Dt=(Tp+2*W75/3)*60; Dq=0.75*Up; HU.append([Dt,Dq]) + Et=(Tp+2*W50/3)*60; Eq=0.5*Up; HU.append([Et,Eq]) + if pequena=='si': + Tbt=tb*60 + else: + Tbt=Tb*60 + HU.append([Tbt,0]) + HU=np.array(HU).T + #Obtiene los intervalod de tiempo + Dt=Tc*0.1*60 #min + Tiempo=np.arange(0,Tbt+Dt,Dt) + #Obtiene la HU para los intervalos de tiempo necesarios + Q=np.zeros(Tiempo.size) + for cont,t in enumerate(Tiempo): + for h1,h2 in zip(HU.T[:-1],HU.T[1:]): + if t>h1[0] and tt1: + Q[cont]=HU[1,2]*np.exp((t1-t[1])/(3*k)) + if t[1]to: + Q[cont]=HU[1,1]*np.exp((to-t[1])/k) + return Tiempo*60,Q,HU + def GetHU_SCS(self,AreaCuenca,Tc,N=25): + 'Descripcion: Obtiene HU segun SCS.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'AreaCuenca: area de la cuenca en km2.\n'\ + 'Tc: Tiempo de concentracion en Horas.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Tiempo : Tiempo total de duracion [M].\n'\ + 'Q : Caudal unitario.\n'\ + 'HU : Reglas del hidrograma unitario.\n'\ + #Parametros fijos + ttp=np.array([0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1, + 1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0,2.2,2.4,2.6,2.8,3.0,3.2, + 3.4,3.6,3.8,4.0,4.5,5.0]) + UUp=np.array([0.0,0.03,0.1,0.19,0.31,0.47,0.66,0.82,0.93,0.99,1.0,0.99,0.93,0.86, + 0.78,0.68,0.56,0.46,0.39,0.33,0.28,0.21,0.15,0.11,0.08,0.06,0.04,0.03,0.02,0.02,0.01, + 0.01,0.0]) + #Parametros de la hidrografa + Trezago=(3.0/5.0)*float(Tc) + Tlluvia=0.133*Tc + Tpico=Tlluvia/2.0+Trezago + Upa=484.0*AreaCuenca*0.386/Tpico + Upm=Upa*0.3048**3/25.4 + #Obtiene el HU + HU=[] + for t,u in zip(ttp,UUp): + uTemp=u*Upa + HU.append([t*Tpico,uTemp*0.3048**3/25.4]) + HU=np.array(HU) + #Obtiene los intervalod de tiempo + Dt=Tc*0.1*60 #min + #Obtiene la HU para los intervalos de tiempo necesarios + Q=[]; flag=True + Tiempo=[];t=0.0 + for i in range(N): + for h1,h2 in zip(HU[:-1],HU[1:]): + if t>=h1[0] and t0: + L.append(((i-Ia)**2)/(i-Ia+S)) + else: + L.append(0) + lluviaTrTemp.append(L) + lluviaTrTemp=np.array(lluviaTrTemp) + lluviaTrEfect=lluviaTrTemp[:,1:]-lluviaTrTemp[:,:-1] + lluviaTrEfect[lluviaTrEfect<0]=0 + lluviaTrEfect=np.insert(lluviaTrEfect,0,lluviaTrTemp[:,0],axis=1) + if plot=='si': + #if Tr==None or len(Tr)<>IntTr.size(): + # Lista=[2.33,5,10,25,50,100,500,1000] + # Tr=[l for l in Lista[:IntTr.size]] + fig=pl.figure(edgecolor='w',facecolor='w') + ax=fig.add_subplot(111) + X=np.linspace(0,Dur,lluviaTrEfect.shape[1]) + Grosor=np.arange(0.5,4,0.2) + for l,le,t,g in zip(lluviaTr,lluviaTrEfect,Tr,Grosor): + ax.plot(X,l,c='b',lw=g,label=str(t)) + if CN is not None: + for l,le,t,g in zip(lluviaTr,lluviaTrEfect,Tr,Grosor): + ax.plot(X,le,c='r',lw=g,label=str(t)) + ax.set_xlabel('Tiempo $[h]$',size=16) + ax.set_ylabel('Precipitacion $[mm]$',size=16) + ax.grid(True) + ax.tick_params(labelsize=15) + pl.legend(loc=0,ncol=2) + if ruta is not None: + pl.savefig(ruta,bbox_inches='tight') + pl.show() + if CN is not None: + return lluviaTr,np.array(lluviaTrEfect),S + else: + return lluviaTr + #Convolucion de la tormenta de diseno + def GetHU_Convolution(self,Tiempo,Qhu,lluvEfect): + 'Descripcion: Realia la convolucion de los hidrogramas unitarios \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'Tiempo : Vector de la duracion de la hidrografa unitaria [Nt].\n'\ + 'Qhu : Valores del caudal unitario de la hidrografa unitaria [Nt].\n'\ + 'lluvEfect : Lluvia efectiva en un evento de tormenta cualquiera [Nt, Tr].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Qtr : Hidrografa para cada periodo de retorno [M, Tr].\n'\ + 'QmaxTr : Caudal maximo para cada periodo de retorno [Tr].\n'\ + 'Tiempo : Tiempo total de duracion [M].\n'\ + #Calcula el caudal convulucionado + Qtr=[]; QmaxTr=[] + for le in lluvEfect: + Qi=np.array([i*Qhu for i in le]) + Qconv=np.zeros(Qhu.size+lluvEfect.shape[1]-1) + for cont,q in enumerate(Qi): + Qconv[cont:cont+Qhu.size]=Qconv[cont:cont+Qhu.size]+q + Qtr.append(Qconv) + QmaxTr.append(Qconv.max()) + #Calcula el tiempo para toda la hidrografa + Dt=Tiempo[1]-Tiempo[0]; Tlast=Tiempo[-1] + T=list(Tiempo) + for i in range(1,lluvEfect.shape[1]): + T.append(Tlast+i*Dt) + return np.array(Qtr), np.array(QmaxTr),np.array(T) + #Grafica los hidrogramas sinteticos + def PlotHU_Synthetic(self,DictHU,ruta = None): + fig=pl.figure(edgecolor='w',facecolor='w') + ax=fig.add_subplot(111) + colors = ['b','r','k','g','m'] + for co,k in enumerate(DictHU.keys()): + ax.plot(DictHU[k]['time'], + DictHU[k]['HU'], + c=colors[co],lw=1.5,label=k) + ax.grid(True) + ax.set_xlabel('Tiempo $[min]$',size=14) + ax.set_ylabel('HU $[m^3/seg/mm]$',size=14) + ax.legend(loc=0) + if ruta is not None: + pl.savefig(ruta,bbox_inches='tight') + pl.show() + + #------------------------------------------------------ + # Trabajo con mapas externos y variables fisicas + #------------------------------------------------------ + def Transform_Map2Basin(self,Map,MapProp): + 'Descripcion: A partir de un mapa leido obtiene un vector \n'\ + ' con la forma de la cuenca, el cual luego puede ser agregado a esta. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'Map : Matriz con la informacion del mapa.\n'\ + 'MapProp : Propiedades del mapa.\n'\ + ' 1. Ncols Mapa.\n'\ + ' 2. Nrows Mapa.\n'\ + ' 3. Xll Mapa.\n'\ + ' 4. Yll Mapa.\n'\ + ' 5. dx Mapa.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'vecMap : Vector conla informacion del mapa al interio de la cuenca.\n'\ + #Comienza le codifgo + vec = cu.basin_map2basin(self.structure, + Map,MapProp[2],MapProp[3],MapProp[4],MapProp[5], + cu.nodata, + self.ncells, + MapProp[0],MapProp[1]) + return vec + def Transform_Basin2Map(self, BasinVar, ruta = None, DriverFormat='GTiff', + EPSG=4326): + 'Descripcion: A partir de un vector con propiedades de la cuenca en celdas\n'\ + ' obtiene un mapa (matriz) con las propiedades del DEM, este puede ser escrito \n'\ + ' en algun formato legible por GDAL. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : la cuenca misma.\n'\ + 'BasinVar : Vector con la variable de la cuenca a escribir [ncells].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Map : Matriz con la variable de la cuenca, donde no hay cuenca es wmf.cu.nodata .\n'\ + ' el tamano de la matriz es igual a DEM.shape.\n'\ + # Convierte la variable a mapa + map_ncols,map_nrows = cu.basin_2map_find(self.structure,self.ncells) + M,mxll,myll = cu.basin_2map(self.structure, BasinVar, + map_ncols, map_nrows, self.ncells) + # Si exporta el mapa lo guarda si no simplemente devuelve la matriz + if ruta is not None: + Save_Array2Raster(M, [map_ncols,map_nrows,mxll,myll,cu.dx,cu.nodata], + ruta = ruta, EPSG = EPSG, Format = DriverFormat) + return M, [map_ncols,map_nrows,mxll,myll,cu.dx,cu.dy,cu.nodata] + + def Transform_Hills2Basin(self,HillsMap): + 'Descripcion: A partir de un vector con propiedades de las laderas\n'\ + ' obtiene un vector con las propiedades por celda, ojo estas \n'\ + ' quedan con las formas de las laderas y la variable queda agregada. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : la cuenca misma.\n'\ + 'MapHills : Vector con las variables por laderas [nhills].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'CellMap : Vector con la variable agregada por laderas, pero .\n'\ + ' pasada a celdas.\n'\ + #Genera el mapa de basin vacio + CellMap = np.ones(self.ncells) + #itera por la cantidad de elementos y les va asignando + for i,k in enumerate(HillsMap[::-1]): + CellMap[self.hills_own==i+1] = k + return CellMap + def Transform_Basin2Hills(self,CellMap,mask=None,SumMeanMax=0): + 'Descripcion: A partir de un vector tipo Basin obtiene un\n'\ + ' vector del tipo laderas, en donde las propiedades se \n'\ + ' agregan para cada ladera. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : la cuenca misma.\n'\ + 'CellMap : Vector con las propiedades por celdas [ncells].\n'\ + 'mask : Celdas sobre las cuales se agrega la variable (1), y\n'\ + ' sobre las que no (0).\n'\ + 'SumMeanMax : si la variable sera agregada como un promedio (0)\n'\ + ' o como una suma (1), o como el maximo valor (2).\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'HillsMap : Vector con las prop agregadas a laderas .\n'\ + #Si hay mascara la tiene en cuenta + if mask is not None: + Ma = np.zeros(self.ncells) + if type(mask) is float or type(mask) is int: + Ma[CellMap==mask] = 1 + elif type(mask) is np.ndarray: + Ma = np.copy(mask) + else: + Ma = np.ones(self.ncells) + #Pasa el mapa de celdas a mapa de laderas + HillsMap = cu.basin_subbasin_map2subbasin(self.hills_own, + CellMap, self.nhills, Ma, SumMeanMax, self.ncells) + return HillsMap + + def Transform_Basin2Polygon(self, Vector,): + 'Descripcion: convierte una variable de topologia de la cuenca en varios poligonos\n'\ + ' cada poligono corresponde al numero de esa variable\n'\ + 'parametros\n'\ + '----------\n'\ + 'Vector: Vector con la topologia de la cuenca que contiene los datos a transformar' + 'Retorna\n'\ + '----------\n'\ + 'DicPoly: Diccionario donde el key indica el poligono encontrado y contiene las coord'\ + #Obtiene mapa raster, propiedades geo y formato para escribir + Map, Prop = self.Transform_Basin2Map(Vector) + tt = [Prop[2], Prop[4].tolist(), 0.0, + Prop[1]*Prop[-2] + Prop[3], 0.0, -1*Prop[5].tolist()] + #Obtiene los shps con la forma de la o las envolventes de cuenca + Map = Map.T + mask = Map != -9999. + shapes = __fea__.shapes(Map, mask=mask, transform=tt) + #Obtiene el poligono de la cuenca completo + DicPoly = {} + for Sh in shapes: + Coord = Sh[0]['coordinates'] + Value = int(Sh[1]) + DicPoly.update({str(Value):{}}) + for cont,co in enumerate(Coord): + DicPoly[str(Value)].update({str(cont):np.array(co).T}) + return DicPoly + + #------------------------------------------------------ + # Trabajo con datos puntuales puntos + #------------------------------------------------------ + def Points_Points2Stream(self,coordXY,ids): + 'Descripcion: toma las coordenadas de puntos XY y las mueve\n'\ + ' hacia los cauces de la cuenca\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'coordXY : coordenadas de los puntos [2,Ncoord].\n'\ + 'ids : Identificacion de los puntos que se van a mover.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'coordXYNew : Coordenadas transportadas a los cauces.\n'\ + 'basin_pts : Vector con la forma de la cuenca con los puntos.\n'\ + ' donde quedaron localizadas las coordenadas.\n'\ + 'idsOrdered : El orden en que quedaron los Ids ingresados.\n'\ + 'Ver Tambien\n'\ + '----------\n'\ + 'Points_Point2Basin\n'\ + #Obtiene el cauce + self.GetGeo_Cell_Basics() + #modifica los puntos + res_coord,basin_pts,xy_new = cu.basin_stream_point2stream( + self.structure, + self.CellCauce, + ids, + coordXY, + coordXY.shape[1], + self.ncells) + return xy_new, basin_pts, basin_pts[basin_pts<>0] + def Points_Points2Basin(self,coordXY,ids): + 'Descripcion: toma las coordenadas de puntos XY y las pone\n'\ + ' en la cuenca, no las mueve hacia los cuaces\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'coordXY : coordenadas de los puntos [2,Ncoord].\n'\ + 'ids : Identificacion de los puntos que se van a mover.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'basin_pts : Vector con la forma de la cuenca con los puntos.\n'\ + ' donde quedaron localizadas las coordenadas.\n'\ + 'idsOrdered : El orden en que quedaron los Ids ingresados.\n'\ + 'Ver Tambien\n'\ + '----------\n'\ + 'Points_Point2Stream\n'\ + #Obtiene el cauce + self.GetGeo_Cell_Basics() + #modifica los puntos + res_coord,basin_pts = cu.basin_point2var( + self.structure, + ids, + coordXY, + coordXY.shape[1], + self.ncells) + return basin_pts,basin_pts[basin_pts<>0] + #------------------------------------------------------ + # Caudales de largo plazo y regionalizacion + #------------------------------------------------------ + #Caudal de largo plazo + def GetQ_Balance(self,Precipitation, Tipo_ETR = 1, mu_choud = 1.37): + 'Descripcion: Calcula el caudal medio por balance de largo plazo\n'\ + ' para ello requiere conocer la precipitacion y el metodo de\n'\ + ' estimacion de la evaporacion.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + 'Precipitation : Cantidad anual de lluvia, escalar o vector.\n'\ + 'Elevacion : Elevacion en cada punto de la cuenca.\n'\ + 'Tipo_ETR : Tipo de ecuacion para calcular la evaporacion.\n'\ + ' -1. Turc.\n'\ + ' -2. Cenicafe Budyko.\n'\ + ' -3. Choundry.\n'\ + ' Defecto: 1.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self.CellQmed : Caudal medio calculado para toda la cuenca.\n'\ + 'self.CellETR : ETR calculada para toda la cuenca.\n'\ + #Calcula las propiedades de la cuenca + self.GetGeo_Cell_Basics() + #Determina si la precipitacion es un vector o un escalar + if type(Precipitation) is int or type(Precipitation) is float: + precip = np.ones(self.ncells)*Precipitation + elif type(Precipitation) is np.ndarray: + precip = Precipitation + #Calcula el qmed + self.CellQmed,self.CellETR = cu.basin_qmed( + self.structure, + self.CellHeight, + precip, + Tipo_ETR, + mu_choud, + self.ncells,) + + #Caudales extremos + def GetQ_Max(self,Qmed,Coef=[6.71, 3.29], Expo= [0.82, 0.64], Cv = 0.5, + Tr = [2.33, 5, 10, 25, 50, 100], Dist = 'gumbel', metodo = 'poveda', + Expo2 = [0.7745, 0.4608]): + 'Descripcion: Calcula el caudal maximo para diferentes\n'\ + ' periodos de retorno. Recibe como entrada el caudal medio \n'\ + ' calculado con GetQ_Balance.\n'\ + ' el calculo se hace a partir de la ecuacion:.\n'\ + ' MedMax = Coef[0] * Qmed ** Exp[0] .\n'\ + ' DesMax = Coef[1] * Qmed ** Exp[1] .\n'\ + ' Qmax = MedMax + K(Tr) * DesMax.\n'\ + ' Donde K es un coeficiente que depende de Tr y f(x).\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'Qmed : Caudal medio calculado con GetQ_Balance.\n'\ + 'Coef : Coeficientes para media y desviacion [6.71, 3.29].\n'\ + 'Expo : Exponentes para media y desviacion [0.82, 0.64].\n'\ + 'Cv : Coeficiente de escalamiento [0.5].\n'\ + 'Tr : Periodo de retorno [2.33, 5, 10, 25, 50, 100].\n'\ + 'Dist : Distrbucion [gumbel/lognorm].\n'\ + 'metodo: Poveda (u = cQA^a) o atlas (u = C(P-E)^a A^b), en este segundo caso Qmed = P-E.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'CellQmax : Caudal maximo para los diferentes periodos.\n'\ + # Calcula la media y desviacion + if metodo == 'poveda': + MedMax = Coef[0] * Qmed ** Expo[0] + DesMax = Coef[1] * Qmed ** Expo[1] + elif metodo == 'atlas': + Acum = cu.basin_acum(self.structure, self.ncells) + Acum = Acum * (cu.dxp**2)/1e6 + MedMax = Coef[0] * (Qmed ** Expo[0]) * (Acum**Expo2[0]) + DesMax = Coef[1] * (Qmed ** Expo[1]) * (Acum**Expo2[1]) + #Itera para todos los periodos de retorno + Qmax=[] + for t in Tr: + #Calcula k + if Dist is 'gumbel': + k=-1*(0.45+0.78*np.log(-1*np.log(1-1/float(t)))) + elif Dist is 'lognorm': + Ztr=norm.ppf(1-1/float(t)) + k=(np.exp(Ztr*np.sqrt(np.log(1+Cv**2))-0.5*np.log(1-Cv**2))-1)/Cv + #Calcula el caudal maximo + Qmax.append(list(MedMax+k*DesMax)) + return np.array(Qmax) + + def GetQ_Min(self,Qmed,Coef=[0.4168, 0.2], Expo= [1.058, 0.98], Cv = 0.5, + Tr = [2.33, 5, 10, 25, 50, 100], Dist = 'gumbel'): + 'Descripcion: Calcula el caudal minimo para diferentes\n'\ + ' periodos de retorno. Recibe como entrada el caudal medio \n'\ + ' calculado con GetQ_Balance.\n'\ + ' el calculo se hace a partir de la ecuacion:.\n'\ + ' MedMin = Coef[0] * Qmed ** Exp[0] .\n'\ + ' DesMin = Coef[1] * Qmed ** Exp[1] .\n'\ + ' Qmin = MedMin + K(Tr) * DesMin.\n'\ + ' Donde K es un coeficiente que depende de Tr y f(x).\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'Qmed : Caudal medio calculado con GetQ_Balance.\n'\ + 'Coef : Coeficientes para media y desviacion [6.71, 3.29].\n'\ + 'Expo : Exponentes para media y desviacion [0.82, 0.64].\n'\ + 'Cv : Coeficiente de escalamiento [0.5].\n'\ + 'Tr : Periodo de retorno [2.33, 5, 10, 25, 50, 100].\n'\ + 'Dist : Distrbucion [gumbel/lognorm].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'CellQmax : Caudal maximo para los diferentes periodos.\n'\ + # Calcula la media y desviacion + MedMin = Coef[0] * Qmed ** Expo[0] + DesMin = Coef[1] * Qmed ** Expo[1] + #Itera para todos los periodos de retorno + Qmin=[] + for t in Tr: + #Calcula k + if Dist is 'gumbel': + k = (-1*np.sqrt(6)/np.pi)*(0.5772+np.log(-1*np.log(1/float(t)))) + elif Dist is 'lognorm': + Ztr=norm.ppf(1/float(t)) + k = 1*(np.exp(Ztr*np.sqrt(np.log(1+Cv**2))-0.5*np.log(1-Cv**2))-1)/Cv + #Calcula el caudal maximo + Qmin.append(list(MedMin+k*DesMin)) + return np.array(Qmin) + + #------------------------------------------------------ + # Guardado shp de cuencas y redes hidricas + #------------------------------------------------------ + def Save_Net2Map(self,ruta,dx=cu.dxp,umbral=None, + qmed=None,Dict=None,DriverFormat='ESRI Shapefile', + EPSG=4326, NumTramo = True, formato = '%.2f'): + 'Descripcion: Guarda la red hidrica simulada de la cuenca en .shp \n'\ + ' Puede contener un diccionario con propiedades de la red hidrica. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + 'ruta : Lugar y nombre donde se va a guardar la red hidrica.\n'\ + 'dx : Longitud de las celdas planas (Valor de Dx plano asignado a wmf.cu.dxp).\n'\ + 'umbral : cantidad de celdas necesarias para corriente (Valor del umbral asignado a self.umbral).\n'\ + 'qmed : caudal medio calculado por alguna metodologia.\n'\ + 'Dict : Diccionario con parametros de la red hidrica que se quieren imprimir.\n'\ + 'DriverFormat : nombre del tipo de archivo vectorial de salida (ver OsGeo).\n'\ + 'EPSG : Codigo de proyeccion utilizada para los datos, defecto WGS84.\n'\ + 'NumTramo: Poner o no el numero de tramo en cada elemento de la red.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Escribe un archivo vectorial con la estructura de la red hidrica y sus propiedades.\n'\ + #varia el umbral en funcion de self + if umbral == None: + umbral = self.umbral + #division de la cuenca + acum=cu.basin_acum(self.structure,self.ncells) + cauce,nod_f,n_nodos=cu.basin_subbasin_nod(self.structure,acum,umbral,self.ncells) + sub_pert,sub_basin=cu.basin_subbasin_find(self.structure,nod_f,n_nodos,self.ncells) + sub_basins=cu.basin_subbasin_cut(n_nodos) + sub_horton,nod_hort=cu.basin_subbasin_horton(sub_basins,self.ncells,n_nodos) + sub_hort=cu.basin_subbasin_find(self.structure,nod_hort,n_nodos,self.ncells)[0] + cauceHorton=sub_hort*cauce + #Obtiene la red en manera vectorial + nodos = cu.basin_stream_nod(self.structure,acum,umbral,self.ncells)[1] + netsize = cu.basin_netxy_find(self.structure,nodos,cauceHorton,self.ncells) + net=cu.basin_netxy_cut(netsize,self.ncells) + #Para net con caudal medio + if qmed is not None: + netsize = cu.basin_netxy_find(self.structure,nodos,cauce*qmed,self.ncells) + netQmed=cu.basin_netxy_cut(netsize,self.ncells) + #Para net con tramos + if NumTramo: + netsize2 = cu.basin_netxy_find(self.structure,nodos,sub_pert*cauce,self.ncells) + netTramo = cu.basin_netxy_cut(netsize2,self.ncells) + #Cortes + cortes=np.where(net[0,:]==-999) + cortes=cortes[0].tolist() + cortes.insert(0,0) + #Escribe el shp de la red hidrica + spatialReference = osgeo.osr.SpatialReference() + spatialReference.ImportFromEPSG(EPSG) + driver = osgeo.ogr.GetDriverByName(DriverFormat) + if os.path.exists(ruta): + driver.DeleteDataSource(ruta) + shapeData = driver.CreateDataSource(ruta) + layer = shapeData.CreateLayer('layer1', spatialReference, osgeo.ogr.wkbLineString) + layerDefinition = layer.GetLayerDefn() + new_field=osgeo.ogr.FieldDefn('Long[km]',osgeo.ogr.OFTReal) + layer.CreateField(new_field) + new_field=osgeo.ogr.FieldDefn('Horton',osgeo.ogr.OFTInteger) + layer.CreateField(new_field) + #coloca los nodos + if NumTramo: + new_field=osgeo.ogr.FieldDefn('Tramo',osgeo.ogr.OFTInteger) + layer.CreateField(new_field) + if qmed is not None: + new_field=osgeo.ogr.FieldDefn('Qmed[m3s]',osgeo.ogr.OFTReal) + layer.CreateField(new_field) + if Dict is not None: + if type(Dict==dict): + netDict=[] + for k in Dict.keys(): + new_field=osgeo.ogr.FieldDefn(k[:10],osgeo.ogr.OFTReal) + layer.CreateField(new_field) + netsizeT = cu.basin_netxy_find(self.structure,nodos,cauce*Dict[k],self.ncells) + netDict.append(cu.basin_netxy_cut(netsize,self.ncells)) + #Para cada tramo + featureFID=0 + for i,j in zip(cortes[:-1],cortes[1:]): + line = osgeo.ogr.Geometry(osgeo.ogr.wkbLineString) + for x,y in zip(net[1,i+1:j],net[2,i+1:j]): + line.AddPoint_2D(float(x),float(y)) + feature = osgeo.ogr.Feature(layerDefinition) + feature.SetGeometry(line) + feature.SetFID(0) + feature.SetField('Long[km]',(net[1,i+1:j].size*dx)/1000.0) + feature.SetField('Horton',int(net[0,i+1])) + if qmed is not None: + feature.SetField('Qmed[m3s]',float(netQmed[0,i+1])) + if NumTramo: + feature.SetField('Tramo',int(netTramo[0,i+1])) + if Dict is not None: + if type(Dict==dict): + for n,k in zip(netDict,Dict.keys()): + feature.SetField(k[:10],float(formato % n[0,i+1])) + #featureFID+=1 + layer.CreateFeature(feature) + line.Destroy() + feature.Destroy() + shapeData.Destroy() + def Save_Basin2Map(self,ruta,dx=30.0,Param={}, + DriverFormat='ESRI Shapefile',EPSG=4326, GeoParam = False): + 'Descripcion: Guarda un archivo vectorial de la cuenca en .shp \n'\ + ' Puede contener un diccionario con propiedades. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + 'ruta : Lugar y nombre donde se va a guardar la cuenca.\n'\ + 'dx : Longitud de las celdas planas.\n'\ + 'DriverFormat : nombre del tipo de archivo vectorial de salida (ver OsGeo).\n'\ + 'EPSG : Codigo de proyeccion utilizada para los datos, defecto WGS84.\n'\ + 'GeoParam: (False) determina si calcular de una los parametros geomorfo o no.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Escribe un archivo vectorial de la cuenca.\n'\ + #Obtiene el perimetro de la cuenca + #nperim = cu.basin_perim_find(self.structure,self.ncells) + #basinPerim=cu.basin_perim_cut(nperim) + + #Parametros geomorfo + if GeoParam: + self.GetGeo_Parameters() + DictParam = {} + for k in self.GeoParameters.keys(): + DictParam.update({k[:8]: self.GeoParameters[k]}) + #Genera el shapefile + spatialReference = osgeo.osr.SpatialReference() + spatialReference.ImportFromEPSG(EPSG) + driver = osgeo.ogr.GetDriverByName(DriverFormat) + if os.path.exists(ruta): + driver.DeleteDataSource(ruta) + shapeData = driver.CreateDataSource(ruta) + layer = shapeData.CreateLayer('layer1', spatialReference, osgeo.ogr.wkbPolygon) + layerDefinition = layer.GetLayerDefn() + for p in Param.keys(): + #new_field=osgeo.ogr.FieldDefn(p[:p.index('[')].strip()[:10],osgeo.ogr.OFTReal) + new_field=osgeo.ogr.FieldDefn(p,osgeo.ogr.OFTReal) + layer.CreateField(new_field) + if GeoParam: + for p in DictParam.keys(): + new_field=osgeo.ogr.FieldDefn(p,osgeo.ogr.OFTReal) + layer.CreateField(new_field) + #Calcula el tamano de la muestra + ring = osgeo.ogr.Geometry(osgeo.ogr.wkbLinearRing) + for i in self.Polygon.T: + ring.AddPoint(x=float(i[0]),y=float(i[1])) + poly=osgeo.ogr.Geometry(osgeo.ogr.wkbPolygon) + poly.AddGeometry(ring) + feature = osgeo.ogr.Feature(layerDefinition) + feature.SetGeometry(poly) + feature.SetFID(0) + for p in Param.keys(): + #feature.SetField(p[:p.index('[')].strip()[:10],float("%.2f" % Param[p])) + feature.SetField(p,float("%.2f" % Param[p])) + #Si calcula parametros geomorfo + if GeoParam: + for p in DictParam.keys(): + feature.SetField(p,float("%.2f" % DictParam[p])) + layer.CreateFeature(feature) + poly.Destroy() + ring.Destroy() + feature.Destroy() + shapeData.Destroy() + + #------------------------------------------------------ + # Graficas de la cuenca + #------------------------------------------------------ + def Plot_basin(self,vec=None,Min=None, + Max=None,ruta=None,figsize=(10,7), + ZeroAsNaN ='no',extra_lat=0.0,extra_long=0.0,lines_spaces='Default', + xy=None,xycolor='b',colorTable=None,alpha=1.0,vmin=None,vmax=None, + colorbar=True, colorbarLabel = None,axis=None,rutaShp=None,shpWidth = 0.7, + shpColor = 'r',axloc = 111, fig = None, EPSG = 4326,backMap = False, + **kwargs): + #Plotea en la terminal como mapa un vector de la cuenca + 'Funcion: Plot_basin\n'\ + 'Descripcion: Genera un plot del mapa entregado.\n'\ + 'del mismo en forma de mapa \n'\ + 'Parametros Obligatorios:.\n'\ + ' -basin: Vector con la forma de la cuenca.\n'\ + ' -vec: Vector con los valores a plotear.\n'\ + 'Parametros Opcionales:.\n'\ + ' -Min: Valor minimo del plot, determina el rango de colores.\n'\ + ' -Max: Valor maximo del plot, determina el rango de colores.\n'\ + ' -ruta: Ruta en la cual se guarda la grafica.\n'\ + ' -colorbar: Muestra o no la barra de colores, defecto: True.\n'\ + ' -figsize: tamano de la ventana donde se muestra la cuenca.\n'\ + ' -ZeroAsNaN: Convierte los valores de cero en NaN.\n'\ + ' -rutaShp: Ruta a un vectorial que se quiera mostrar en el mapa.\n'\ + ' -shpWidth: Ancho de las lineas del shp cargado.\n'\ + ' -shpColor: Color de las lineas del shp cargado.\n'\ + ' -backMap: Pone de fondo un mapa tipo arcGIS.\n'\ + 'Otros argumentos:.\n'\ + ' -axis = Entorno de grafica que contiene elementos de las figuras.\n'\ + ' -parallels = Grafica Paralelos, list-like.\n'\ + ' -parallels_labels = Etiquetas de los paralelos, list-like.\n'\ + ' labels = [left,right,top,bottom].\n'\ + ' Ejemplo:\n'\ + ' m.drawparallels(parallels,labels=[False,True,True,False]).\n'\ + ' -parallels_offset: desplazamiento de las coordenadas en X.\n'\ + ' -meridians = Grafica Meridianos, list-like.\n'\ + ' -meridians_labels = Etiquetas de los meridianos, list-like.\n'\ + ' -meridians_offset: desplazamiento de las coordeandas en Y.\n'\ + ' -per_color = Color del perimetro.\n'\ + ' -per_lw = Ancho de linea del perimetro.\n'\ + ' -colorbarLabel = Titulo del colorbar.\n'\ + ' -xy_edgecolor = Color de la linea exterior del scatter .\n'\ + ' -xy_lw = Ancho de linea del Scatter .\n'\ + ' -xy_s = Tamano del scatter.\n'\ + ' -xy_colorbar: Coloca o no barra de colores del scatter enviado (False).\n'\ + ' -show = boolean, si es True muestra la grafica.\n'\ + ' -cbar_ticks: (None) ubicacion de los ticks del cbar.\n'\ + ' -cbar_ticklabels: (None) Labels a poner sobre los ticks.\n'\ + ' -cbar_ticksize: (14) Tamano de los ticks.\n'\ + ' -ShpIsPolygon: Indica si ese shp cargado es poligono (True) o no (False).\n'\ + ' -shpAlpha: transparencia del shp (0.5).\n'\ + 'Retorno:.\n'\ + ' -Actualizacion del binario .int\n'\ + ' -m = Para continuar graficando encima del entorno creado en Basemap\n'\ + ' Ejemplo:.\n'\ + ' m = Plot_basin(**args).\n'\ + ' m.scatter(coordenada_x,coordenada_y).\n' + #Prop de la barra de colores + cbar_ticklabels = kwargs.get('cbar_ticklabels', None) + cbar_ticks = kwargs.get('cbar_ticks', None) + cbar_ticksize = kwargs.get('cbar_ticksize', 14) + show = kwargs.get('show', True) + ShpIsPolygon = kwargs.get('ShpIsPolygon',None) + shpAlpha = kwargs.get('shpAlpha',0.5) + xy_colorbar = kwargs.get('xy_colorbar', False) + if lines_spaces == 'Default': + lines_spaces = cu.dx*cu.ncols*0.05 + #El mapa + Mcols,Mrows=cu.basin_2map_find(self.structure,self.ncells) + Map,mxll,myll=cu.basin_2map(self.structure,self.structure[0] + ,Mcols,Mrows,self.ncells) + longs=np.array([mxll+0.5*cu.dx+i*cu.dx for i in range(Mcols)]) + lats=np.array([myll+0.5*cu.dy+i*cu.dy for i in range(Mrows)]) + X,Y=np.meshgrid(longs,lats) + Y=Y[::-1] + show = kwargs.get('show',True) + if fig is None: + fig = pl.figure(figsize = figsize) + if axis == None: + ax = fig.add_subplot(axloc) + else: + show = False + m = Basemap(projection='merc', + llcrnrlat=lats.min()-extra_lat, + urcrnrlat=lats.max()+extra_lat, + llcrnrlon=longs.min()-extra_long, + urcrnrlon=longs.max()+extra_long, + resolution='c', + epsg = EPSG) + parallels = kwargs.get('parallels',np.arange(lats.min(), + lats.max(),lines_spaces)) + parallels_labels = kwargs.get('parallels_labels',[1,0,0,0]) + parallel_offset = kwargs.get('parallels_offset', 0.001) + m.drawparallels(parallels, + labels = parallels_labels, + fmt="%.2f", + rotation='vertical', + xoffset=parallel_offset) + meridians = kwargs.get('meridians', np.arange(longs.min(), + longs.max(),lines_spaces)) + meridians_labels = kwargs.get('meridians_labels', [0,0,1,0]) + meridians_offset = kwargs.get('meridians_offset', 0.001) + m.drawmeridians(meridians, + labels=meridians_labels, + fmt="%.2f", + yoffset=meridians_offset) + Xm,Ym=m(X,Y) + #plotea el mapa de fondo de arcGIS + if backMap: + m.arcgisimage(server='http://server.arcgisonline.com/ArcGIS', service='World_Topo_Map', xpixels = 1500, verbose = True) + #Plotea el contorno de la cuenca y la red + xp,yp = m(self.Polygon[0], self.Polygon[1]) + per_color = kwargs.get('per_color','r') + per_lw = kwargs.get('per_lw',2) + m.plot(xp, yp, color=per_color,lw=per_lw) + #hay una variable la monta + if vec is not None: + if vmin is None: + vmin = vec.min() + if vmax is None: + vmax = vec.max() + MapVec,mxll,myll=cu.basin_2map(self.structure,vec,Mcols,Mrows, + self.ncells) + MapVec[MapVec==cu.nodata]=np.nan + if ZeroAsNaN is 'si': + MapVec[MapVec == 0] = np.nan + if colorTable is not None: + cs = m.contourf(Xm, Ym, MapVec.T, 25, alpha=alpha,cmap=colorTable, + vmin=vmin,vmax=vmax) + else: + cs = m.contourf(Xm, Ym, MapVec.T, 25, alpha=alpha, + vmin=vmin,vmax=vmax) + cbar_label_size = kwargs.get('cbar_label_size',16) + if colorbar: + cbar = m.colorbar(cs,location='bottom',pad="5%") + if colorbarLabel is not None: + cbar.set_label(colorbarLabel, size = cbar_label_size) + if cbar_ticks is not None: + cbar.set_ticks(cbar_ticks) + if cbar_ticklabels is not None: + cbar.ax.set_yticklabels(cbar_ticklabels, size = cbar_ticksize,) + cbar.ax.set_xticklabels(cbar_ticklabels, size = cbar_ticksize,) + #Si hay coordenadas de algo las plotea + xy_edgecolor = kwargs.get('xy_edgecolor','black') + xy_lw = kwargs.get('xy_lw',30) + xy_s = kwargs.get('xy_s',0.5) + if xy is not None: + xc,yc=m(xy[0],xy[1]) + sx = m.scatter(xc,yc,c=xycolor, + s=xy_s, + linewidth=xy_lw, + edgecolor=xy_edgecolor) + if xy_colorbar: + pl.colorbar(sx) + #Si hay una ruta a un shp lo plotea + if rutaShp is not None: + if type(rutaShp) == str: + m.readshapefile(rutaShp, 'mapashp', linewidth = shpWidth, color = shpColor) + elif type(rutaShp) == list: + for c,shape in enumerate(rutaShp): + m.readshapefile(shape, 'mapashp', linewidth = shpWidth[c], color = shpColor[c]) + if ShpIsPolygon[c]: + patches = [] + for shape in m.mapashp: + patches.append(Polygon(np.array(shape), True)) + ax.add_collection(PatchCollection(patches, facecolor= shpColor[c], + edgecolor=shpColor[c], linewidths=shpWidth[c], zorder=2, alpha = shpAlpha[c])) + #Guarda + if ruta is not None: + pl.savefig(ruta, bbox_inches='tight',pad_inches = 0.25) + if show is True: + pl.show() + if xy is None: + return m,ax + else: + return m, ax, sx + #Grafica de plot para montar en paginas web o presentaciones + def Plot_basinClean(self, vec, ruta = None, umbral = 0.0, + vmin = 0.0, vmax = None, show_cbar = False, **kwargs): + 'Funcion: Plot_basinClean\n'\ + 'Descripcion: Genera un plot del mapa entregado en un lienzo limpio.\n'\ + 'Parametros Obligatorios:.\n'\ + ' -vec: Vector con los valores a plotear.\n'\ + 'Parametros Opcionales:.\n'\ + ' -ruta: ruta donde se guarda el png.\n'\ + ' -umbral: Umbral a partir del cual se plotea variable.\n'\ + ' -vmin: Valor minimo de la variable.\n'\ + ' -vmax: valor maximo de la variable.\n'\ + ' -show_cbar: muestra o no el Cbar del plot.\n'\ + 'Otros argumentos:.\n'\ + ' -cmap: Esquema de colores.\n'\ + ' -figsize = Tamano de la figura.\n'\ + ' -cbar_aspect: (20) relacion largo ancho del cbar.\n'\ + ' -cbar_ticks: (None) ubicacion de los ticks del cbar.\n'\ + ' -cbar_ticklabels: (None) Labels a poner sobre los ticks.\n'\ + ' -cbar_ticksize: (14) Tamano de los ticks.\n'\ + ' -show: SE muestra por defecto la figura (True).\n'\ + ' -interpolation: Tipo de interpolacion utilizada por la funcion imshow (ver opciones en matplotlib).\n'\ + 'Retorno:.\n'\ + ' -Figura se muestra y se guarda.\n'\ + ' -Coordenadas de los bordes del mapa.\n'\ + #Argumentos kw + cmap = kwargs.get('cmap','Spectral') + figsize = kwargs.get('figsize', (10,8)) + cbar_aspect = kwargs.get('cbar_aspect', 20) + cbar_ticklabels = kwargs.get('cbar_ticklabels', None) + cbar_ticks = kwargs.get('cbar_ticks', None) + cbar_ticksize = kwargs.get('cbar_ticksize', 14) + interpolation = kwargs.get('None') + show = kwargs.get('show', True) + #Obtiene la matriz + M,p = self.Transform_Basin2Map(vec) + M[(M == -9999) | (Mumbral)[0] + elif type(umbral) == np.ndarray and umbral.shape[0] == self.ncells: + pos = np.where(umbral == 1)[0] + x,y = cu.basin_coordxy(self.structure, self.ncells) + #Vector para pintar si no tiene el vec_c usa vec + if vec_c is None: + vec_c = np.copy(vec) + #Compara o no + if q_compare is not None: + vec = vec/q_compare.astype(float) + #Figura + fig = pl.figure(figsize=figsize) + ax = fig.add_subplot(111) + sca = pl.scatter(x[pos],y[pos], + s = vec[pos]*escala, + c = vec_c[pos], + lw = 0, + vmin = vmin, + vmax = vmax, + cmap = cmap, + norm = norm) + ax.patch.set_facecolor('w') + ax.patch.set_alpha(0.0) + if grid: + pl.grid(True) + #colorca colorbar + if show_cbar: + cbar = pl.colorbar(sca, aspect = cbar_aspect, ) + if cbar_ticks is not None: + cbar.set_ticks(cbar_ticks) + if cbar_ticklabels is not None: + cbar.ax.set_yticklabels(cbar_ticklabels, size = cbar_ticksize,) + + ax.set_xlim(x[pos].min(),x[pos].max()) + ax.set_ylim(y[pos].min(),y[pos].max()) + #Quita ejes + if clean: + ax.set_xticklabels([]) + ax.set_yticklabels([]) + ax.axis('off') + if clean == False: + ax.set_xlabel('Latitud', size = size) + ax.set_ylabel('Longitud', size = size) + ax.tick_params(labelsize = ticksize) + #Guarda transparente y ajustando bordes + if ruta is not None: + pl.savefig(ruta, + bbox_inches = 'tight', + pad_inches = 0, + transparent = transparent, + edgecolor = 'none', + facecolor = 'none') + if show: + pl.show() + pl.close(fig) + #Retorna las 4 coordenadas de las esquinas + return [x[pos].min(), x[pos].max(), y[pos].min(), y[pos].max()] + + + # Grafica barras de tiempos de concentracion + def Plot_Tc(self,ruta=None,figsize=(8,6),**kwargs): + keys=self.Tc.keys() + keys[2]=u'Carr Espana' + Media=np.array(self.Tc.values()).mean() + Desv=np.array(self.Tc.values()).std() + Mediana=np.percentile(self.Tc.values(),50) + rango=[Media-Desv,Media+Desv] + color1 = kwargs.get('color1','b') + color2 = kwargs.get('color2','r') + colores=[] + for t in self.Tc.values(): + if t>rango[0] and tself.ncells: + Nsize = self.ncells + pos = np.random.choice(self.ncells,Nsize) + h,b=np.histogram(self.CellSlope[pos],bins=np.arange(bins[0],bins[1],bins[2])) + b=(b[:-1]+b[1:])/2.0 + h=h.astype(float)/h.astype(float).sum() + if fig is None: + fig=pl.figure(figsize = figsize, edgecolor='w',facecolor='w') + ax=fig.add_subplot(111) + ax.plot(b,h,lw=lw) + ax.grid(True) + ax.tick_params(labelsize = axissize) + ax.set_xlabel('Pendiente',size=labelsize) + ax.set_ylabel('$pdf [\%]$',size=labelsize) + if ruta is not None: + pl.savefig(ruta,bbox_inches='tight') + if show: + pl.show() + return ax + + #Plot de histograma de tiempos de viajes en la cuenca + def Plot_Travell_Hist(self,ruta=None,Nint=10.0): + #comparacion histogramas de tiempos de respuestas + bins=np.arange(0,np.ceil(self.CellTravelTime.max()), + np.ceil(self.CellTravelTime.max())/Nint) + h_lib,b_lib=np.histogram(self.CellTravelTime,bins=bins) + h_lib=h_lib.astype(float)/h_lib.sum() + b_lib=(b_lib[:-1]+b_lib[1:])/2.0 + hc_lib=np.cumsum(h_lib) + fig=pl.figure(facecolor='w',edgecolor='w') + ax=fig.add_subplot(111) + ax.plot(b_lib,h_lib,'b',lw=2,label='Tiempos') + ax2=ax.twinx() + ax2.plot(b_lib,hc_lib,'r',lw=2) + ax2.set_ylim(0,1.1) + ax.set_xlim(0,np.ceil(self.CellTravelTime.max())) + ax.grid(True) + ax.set_xlabel('Tiempo $t [hrs]$',size=14) + ax.set_ylabel('$pdf[\%]$',size=14) + ax2.set_ylabel('$cdf[\%]$',size=14) + ax.set_xticks(b_lib) + ax.legend(loc=4) + if ruta is not None: + pl.savefig(ruta,bbox_inches='tight') + pl.show() + #Plot de curva hipsometrica + def Plot_Hipsometric(self,ruta=None,ventana=10,normed=False, + figsize = (8,6)): + #Suaviza la elevacion en el cuace ppal + elevPpal=pd.Series(self.hipso_ppal[1]) + elevBasin=self.hipso_basin[1] + if normed==True: + elevPpal=elevPpal-elevPpal.min() + elevPpal=(elevPpal/elevPpal.max())*100.0 + elevBasin=elevBasin-elevBasin.min() + elevBasin=(elevBasin/elevBasin.max())*100.0 + elevPpal=pd.rolling_mean(elevPpal,ventana) + ppal_acum=(self.hipso_ppal[0]/self.hipso_ppal[0,-1])*100 + basin_acum=(self.hipso_basin[0]/self.hipso_basin[0,0])*100 + #Genera el plot + fig=pl.figure(edgecolor='w',facecolor='w',figsize = figsize) + ax=fig.add_subplot(111) + #box = ax.get_position() + #ax.set_position([box.x0, box.y0 + box.height * 0.1, + # box.width, box.height * 0.9]) + ax.plot(ppal_acum,elevPpal,c='b',lw=3,label='Cacuce Principal') + ax.plot(basin_acum,elevBasin,c='r',lw=3,label='Cuenca') + ax.tick_params(labelsize = 14) + ax.grid() + ax.set_xlabel('Porcentaje Area Acumulada $[\%]$',size=16) + if normed==False: + ax.set_ylabel('Elevacion $[m.s.n.m]$',size=16) + elif normed==True: + ax.set_ylabel('Elevacion $[\%]$',size=16) + lgn1=ax.legend(loc=0) + if ruta is not None: + pl.savefig(ruta, bbox_inches='tight') + pl.close('all') + else: + pl.show() +class SimuBasin(Basin): + + def __init__(self,lat=None,lon=None,DEM=None,DIR=None,rute = None, name='NaN',stream=None, + umbral=500,useCauceMap = None, + noData=-999,modelType='cells',SimSed=False,SimSlides=False,dt=60, + SaveStorage='no',SaveSpeed='no',retorno = 0, + SeparateFluxes = 'no',SeparateRain='no',ShowStorage='no', SimFloods = 'no', + controlNodos = True, storageConstant = 0.001): + 'Descripcion: Inicia un objeto para simulacion \n'\ + ' el objeto tiene las propieades de una cuenca con. \n'\ + ' la diferencia de que inicia las variables requeridas. \n'\ + ' para simular. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'lat : Coordenada en X de la salida de la cuenca.\n'\ + 'lon : Coordenada en Y de la salida de la cuenca.\n'\ + 'name : Nombre con el que se va a conocer la cuenca.\n'\ + ' (defecto = NaN).\n'\ + 'stream : Opcional, si se coloca, las coordenadas no tienen.\n'\ + ' que ser exactas, estas se van a corregir para ubicarse.\n'\ + ' en el punto mas cercano dentro de la corriente, este.\n'\ + ' debe ser un objeto del tipo stream.\n'\ + 'useCauceMap: Utiliza un mapa de 1 y 0 representando las celdas que.\n'\ + ' son canal, con este mapa corrige el punto de trazado de la cuenca.\n'\ + 'umbral : Cantidad minima de celdas para la creacion de cauces.\n'\ + ' (defecto = 500 ).\n'\ + 'noData : Valor correspondiente a valores sin dato (defecto = -999).\n'\ + 'modelType : Tipo de modelo, por celdas o por laderas (defecto = cells).\n'\ + ' opciones: .\n'\ + ' cells => modela por celdas.\n'\ + ' hills => modela por laderas.\n'\ + 'SimSed : Simula si, o no simula sedimentos no.\n'\ + 'SimSlides : Simula si, o no simula deslizamientos no.\n'\ + 'dt : Tamano del intervlao de tiempo en que trabaj el modelo (defecto=60seg) [secs].\n'\ + 'SaveStorage : Guarda o no el almacenamiento.\n'\ + 'SaveSpeed : Guarda o no mapas de velocidad.\n'\ + 'rute : por defecto es None, si se coloca la ruta, el programa no.\n'\ + ' hace una cuenca, si no que trata de leer una en el lugar especificado.\n'\ + ' Ojo: la cuenca debio ser guardada con la funcion: Save_SimuBasin().\n'\ + 'retorno : (defecto = 0), si es cero no se considera alm maximo en .\n'\ + ' el tanque 3, si es 1, si se considera.\n'\ + 'SeparateFluxes : Separa el flujo en base, sub-superficial y escorrentia.\n'\ + 'SeparateRain : Separa el flujo proveniente de convectivas y de estratiformes.\n'\ + 'ShowStorage : Muestra en la salida del modelo el alm promedio en cada uno de los tanques.\n'\ + 'controlNodos: Coloca por defecto puntos de control en todos los nodos (True) o no (False).\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas.\n'\ + #Variables de radar + self.radarDates = [] + self.radarPos = [] + self.radarMeanRain = [] + self.radarCont = 1 + #Si no hay ruta y el global del codigo EPSG existe, traza la cuenca + if rute is None and int(Global_EPSG) > 0: + #Si se entrega cauce corrige coordenadas + if stream is not None: + error=[] + for i in stream.structure.T: + error.append( np.sqrt((lat-i[0])**2+(lon-i[1])**2) ) + loc=np.argmin(error) + lat=stream.structure[0,loc] + lon=stream.structure[1,loc] + if useCauceMap is not None and useCauceMap.shape == DEM.shape: + lat,lon = cu.stream_find_to_corr(lat,lon,DEM,DIR,useCauceMap, + cu.ncols,cu.nrows) + #copia la direccion de los mapas de DEM y DIR, para no llamarlos mas + self.name=name + self.DEM=DEM + self.DIR=DIR + self.modelType=modelType + self.nodata=noData + self.umbral = umbral + self.epsg = Global_EPSG + #Traza la cuenca + self.ncells = cu.basin_find(lat,lon,DIR, + cu.ncols,cu.nrows) + self.structure = cu.basin_cut(self.ncells) + #Obtiene las propiedades para el tamano de la cuenca. + self.DEMvec = self.Transform_Map2Basin(DEM, + [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy]) + self.DIRvec = self.Transform_Map2Basin(DIR, + [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy]) + acum=cu.basin_acum(self.structure,self.ncells) + cauce,nodos,self.nhills = cu.basin_subbasin_nod(self.structure + ,acum,umbral,self.ncells) + self.hills_own,sub_basin = cu.basin_subbasin_find(self.structure, + nodos,self.nhills,self.ncells) + self.hills = cu.basin_subbasin_cut(self.nhills) + models.drena=self.structure + #Determina la cantidad de celdas para alojar + if modelType=='cells': + N=self.ncells + elif modelType=='hills': + N=self.nhills + #aloja variables + models.v_coef = np.ones((4,N)) + models.h_coef = np.ones((4,N)) + models.v_exp = np.ones((4,N)) + models.h_exp = np.ones((4,N)) + models.max_capilar = np.ones((1,N)) + models.max_gravita = np.ones((1,N)) + models.storage = np.zeros((5,N)) + models.dt = dt + models.calc_niter = 5 + models.retorno = 0 + models.verbose = 0 + #Define los puntos de control + models.control = np.zeros((1,N)) + #Si se da la opcion de puntos de control en toda la red lo hace + if controlNodos: + if modelType == 'cells': + self.GetGeo_Cell_Basics() + cauce,nodos,n_nodos = cu.basin_subbasin_nod( + self.structure, + self.CellAcum, + umbral, + self.ncells) + pos = np.where(nodos<>0)[0] + x,y = cu.basin_coordxy(self.structure,self.ncells) + idsOrd,xy = self.set_Control(np.vstack([x[pos],y[pos]]),nodos[pos]) + elif modelType == 'hills': + models.control = np.ones((1,self.nhills)) * nodos[nodos<>0] + #Puntos de control de humedad sin control por defecto + models.control_h = np.zeros((1,N)) + #Define las simulaciones que se van a hacer + models.sim_sediments=0 + if SimSed is 'si': + models.sim_sediments=1 + models.sim_slides=0 + if SimSlides: + models.sim_slides=1 + models.save_storage=0 + if SaveStorage is 'si': + models.save_storage=1 + models.save_speed=0 + if SaveSpeed is 'si': + models.save_speed=1 + models.separate_fluxes = 0 + if SeparateFluxes is 'si': + models.separate_fluxes = 1 + models.separate_rain = 0 + if SeparateRain is 'si': + models.separate_rain = 1 + models.show_storage = 0 + if ShowStorage is 'si': + models.show_storage = 1 + if SimFloods == 'si': + models.sim_floods = 1 + models.storage_constant = storageConstant + #Determina que la geomorfologia no se ha estimado + self.isSetGeo = False + # si hay tura lee todo lo de la cuenca + elif rute is not None: + self.__Load_SimuBasin(rute, SimSlides) + # Obtiene la envolvente de la cuenca + self.__GetBasinPolygon__() + + def __Load_SimuBasin(self,ruta, sim_slides = False): + 'Descripcion: Lee una cuenca posteriormente guardada\n'\ + ' La cuenca debio ser guardada con SimuBasin.save_SimuBasin\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'ruta : ruta donde se encuentra ubicada la cuenca guardada\n'\ + 'Opcionales\n'\ + '----------\n'\ + 'sim_slides : (False, True) Carga variables de modelos de deslizamientos previmaente guardadas.\n'\ + 'sim_sed : (False, True) Carga variables de modelo de sedimentos previamente guardadas\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : La cuenca con sus parametros ya cargada.\n'\ + #Abre el archivo binario de la cuenca + self.rutaNC = ruta + gr = netcdf.Dataset(ruta,'a') + #obtiene las prop de la cuenca + self.name = gr.nombre + self.modelType = gr.modelType.encode() + self.nodata = gr.noData + self.umbral = gr.umbral + self.ncells = gr.ncells + self.nhills = gr.nhills + self.epsg = gr.epsg + models.dt = gr.dt + models.dxp = gr.dxp + models.retorno = gr.retorno + try: + models.storage_constant = gr.storageConst + except: + models.storage_constant = 0.0 + #Si carga deslizamientos + if sim_slides: + models.sim_slides = 1 + models.sl_fs = gr.sl_fs + models.gullienogullie = gr.sl_gullie + models.sl_gammaw = gr.sl_gammaw + #Nueva metodologia de geoespacial de la cuenca + cu.ncols = gr.ncols + cu.nrows = gr.nrows + cu.xll = gr.xll + cu.yll = gr.yll + cu.dx = gr.dx + cu.dy = gr.dy + cu.dxp = gr.dxp + cu.nodata = gr.noData + #de acuerdo al tipo de modeloe stablece numero de elem + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + #Obtiene las variables base + GrupoBase = gr.groups['base'] + self.structure = GrupoBase.variables['structure'][:] + self.hills = GrupoBase.variables['hills'][:] + self.hills_own = GrupoBase.variables['hills_own'][:] + #Obtiene las geomorfologicas + GrupoGeo = gr.groups['Geomorfo'] + self.DEMvec = GrupoGeo.variables['DEM'][:] + self.DIRvec = GrupoGeo.variables['DIR'][:] + self.DEM = self.Transform_Basin2Map(self.DEMvec) + self.DIR = self.Transform_Basin2Map(self.DIRvec) + #obtiene las propieades del modelo + GrupoSimHid = gr.groups['SimHidro'] + models.h_coef = np.ones((4,N)) * GrupoSimHid.variables['h_coef'][:] + models.v_coef = np.ones((4,N)) * GrupoSimHid.variables['v_coef'][:] + models.h_exp = np.ones((4,N)) * GrupoSimHid.variables['h_exp'][:] + models.v_exp = np.ones((4,N)) * GrupoSimHid.variables['v_exp'][:] + models.max_capilar = np.ones((1,N)) * GrupoSimHid.variables['h1_max'][:] + models.max_gravita = np.ones((1,N)) * GrupoSimHid.variables['h3_max'][:] + #Variable de drena de acuerdo al tipo de modelo + if self.modelType[0] is 'c': + models.drena = np.ones((3,N)) *GrupoSimHid.variables['drena'][:] + elif self.modelType[0] is 'h': + models.drena = np.ones((1,N)) * GrupoSimHid.variables['drena'][:] + models.unit_type = np.ones((1,N)) * GrupoSimHid.variables['unit_type'][:] + models.hill_long = np.ones((1,N)) * GrupoSimHid.variables['hill_long'][:] + models.hill_slope = np.ones((1,N)) * GrupoSimHid.variables['hill_slope'][:] + models.stream_long = np.ones((1,N)) * GrupoSimHid.variables['stream_long'][:] + models.stream_slope = np.ones((1,N)) * GrupoSimHid.variables['stream_slope'][:] + models.stream_width = np.ones((1,N)) * GrupoSimHid.variables['stream_width'][:] + models.elem_area = np.ones((1,N)) * GrupoSimHid.variables['elem_area'][:] + models.speed_type = np.ones((3)) * GrupoSimHid.variables['speed_type'][:] + models.storage = np.ones((5,N)) * GrupoSimHid.variables['storage'][:] + models.control = np.ones((1,N)) * GrupoSimHid.variables['control'][:] + models.control_h = np.ones((1,N)) * GrupoSimHid.variables['control_h'][:] + + #Propiedades de deslizamientos + if sim_slides: + GrupoSlides = gr.groups['SimSlides'] + models.sl_gammas = np.ones((1,N)) * GrupoSlides.variables['gamma_soil'][:] + models.sl_cohesion = np.ones((1,N)) * GrupoSlides.variables['cohesion'][:] + models.sl_frictionangle = np.ones((1,N)) * GrupoSlides.variables['friction_angle'][:] + models.sl_radslope = np.ones((1,N)) * GrupoSlides.variables['rad_slope'][:] + models.sl_zs = np.ones((1,N)) * GrupoSlides.variables['z_soil'][:] + #Cierra el archivo + gr.close() + #Determina que por defecto debe estar set la geomorfologia + self.isSetGeo = True + + #------------------------------------------------------ + # Subrutinas de lluvia, interpolacion, lectura, escritura, agrega funcion para variar evp en + # el tiempo + #------------------------------------------------------ + def __GetEVP_Serie__(self, index): + '''Descripcion: Genera una serie que pondera la evp ''' + rng=index + rad=np.zeros(rng.size) + for pos,time in enumerate(rng): + Hora=time + # Dia del Ano + dn = Hora.timetuple().tm_yday + Theta_d = (2 * np.pi * (dn-1))/ 365. + # (d/d)2 + an = [1.000110, 0.034221, 0.000719] + bn = [0, 0.001280, 0.000077] + # + d = 0 + tmp = 0 + for i in range(3): + tmp = (an[i] * np.cos(i*Theta_d)) + (bn[i] * np.sin(i*Theta_d)) + d = d + tmp + # Delta + a_n = [0.006918, -0.399912, -0.006758, -0.002697] + b_n = [0, 0.070257, 0.000907, 0.001480] + # + Delta = 0 + tmp = 0 + for i in range(4): + tmp = (a_n[i] * np.cos(i*Theta_d)) + (b_n[i] * np.sin(i*Theta_d)) + Delta = Delta + tmp + #Angulo horario (cada minuto) + Minutos = (Hora.hour * 60) + Hora.minute + Horario = 180 - (0.25 * Minutos) + Horario = (Horario * np.pi)/180. + # Coseno de Theta + Latitud = (6.2593 * np.pi)/180. + Cos_Theta = (np.sin(Latitud)*np.sin(Delta)) + (np.cos(Latitud)*np.cos(Delta)*np.cos(Horario)) + # Radiacion Teorica + So = 1367 #w/m2 + Q = So * d * Cos_Theta + # Escala entre 0 y 1 + rad_max=1369.8721876806876 + Q=1*Q/rad_max + #Guarda + rad[pos]=Q + #Se vuelven cero los valores negativos. + rad[rad<0]=0 + #Serie + rad=pd.Series(rad,index=rng) + models.evpserie = np.copy(rad.values) + return rad + + def rain_interpolate_mit(self,coord,registers,ruta, umbral = 0.01): + 'Descripcion: Interpola la lluvia mediante una malla\n'\ + ' irregular de triangulos, genera campos que son. \n'\ + ' guardados en un binario para luego ser leido por el. \n'\ + ' modelo en el momento de simular. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : .\n'\ + 'coord : Array (2,Ncoord) con las coordenadas de estaciones.\n'\ + 'registers : Array (Nest,Nregisters) con los registros de lluvia.\n'\ + 'ruta : Ruta con nombre en donde se guardara el binario con.\n'\ + ' la informacion de lluvia.\n'\ + 'umbral: Umbral a partir del cual se considera que un campo contiene lluvia\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + 'meanRain : La serie de lluvia promedio interpolada para la cuenca\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ + 'rain_read_bin: Lee binario de registros para ver que tiene.\n'\ + 'rain_ncf2bin: Convierte ncf a binario en formato del modelo (para imagenes de radar).\n'\ + #Mira si los registros son un data frame de pandas + isPandas=False + if type(registers)==pd.core.frame.DataFrame: + reg=registers.values.T + isPandas=True + else: + reg=registers + #inventa estaciones en las esquinas del DEM + for i,j in zip([0,0,1,1],[0,1,1,0]): + x=cu.xll+cu.ncols*cu.dx*i + y=cu.yll+cu.nrows*cu.dx*j + d=np.sqrt((coord[0,:]-x)**2+(coord[1,:]-y)**2) + pos=np.argmin(d) + #Actualiza las coordenadas + coord=np.vstack((coord.T,np.array([x,y]))).T + #pone lluvia en ese registro + reg=np.vstack((reg,reg[pos])) + #Obtiene las coordenadas de cada celda de la cuenca + x,y = cu.basin_coordxy(self.structure,self.ncells) + xy_basin=np.vstack((x,y)) + #Obtiene la malla irregular + TIN_mesh=Delaunay(coord.T) + TIN_mesh=TIN_mesh.vertices.T+1 + #Obtiene las pertenencias en la cuenca a la malla + #TIN_perte = models.rain_pre_mit(xy_basin,TIN_mesh,coord,self.ncells, + # TIN_mesh.shape[1],coord.shape[1]) + c = 1 + TIN_perte = np.zeros((1,self.ncells)) + for t in TIN_mesh.T: + t = t-1 + t = np.append(t, t[0]) + Poly = np.vstack([coord[0][t], coord[1][t]]) + bbPath = mplPath.Path(Poly.T, closed=True) + Contiene = bbPath.contains_points(xy_basin.T) + TIN_perte[0][Contiene == True] = c + c+=1 + #Revisa si todas las celdas quedaron asignadas + if len(TIN_perte[TIN_perte == 0]) == 0: + #Selecciona si es por laderas o por celdas + if self.modelType[0] is 'h': + maskVector = np.copy(self.hills_own) + elif self.modelType[0] is 'c': + maskVector = np.ones(self.ncells) + #Interpola con tin + meanRain,posIds = models.rain_mit(xy_basin, + coord, + reg, + TIN_mesh, + TIN_perte, + self.nhills, + ruta, + umbral, + maskVector, + self.ncells, + coord.shape[1], + TIN_mesh.shape[1], + reg.shape[1]) + #Guarda un archivo con informacion de la lluvia + f=open(ruta[:-3]+'hdr','w') + f.write('Numero de celdas: %d \n' % self.ncells) + f.write('Numero de laderas: %d \n' % self.nhills) + f.write('Numero de registros: %d \n' % reg.shape[1]) + f.write('Numero de campos no cero: %d \n' % posIds.max()) + f.write('Tipo de interpolacion: TIN\n') + f.write('IDfecha, Record, Lluvia, Fecha \n') + if isPandas: + dates=registers.index.to_pydatetime() + c = 1 + for d,pos,m in zip(dates,posIds,meanRain): + f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) + c+=1 + f.close() + return meanRain, posIds + else: + print 'Error: Existen celdas de la cuenca sin asignacion de triangulos, se retornan las coordenadas no asignadas' + pos = np.where(TIN_perte == 0)[1] + return xy_basin[0,pos], xy_basin[1,pos] + + def rain_interpolate_idw(self,coord,registers,ruta,p=1,umbral=0.0): + 'Descripcion: Interpola la lluvia mediante la metodologia\n'\ + ' del inverso de la distancia ponderado. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : .\n'\ + 'coord : Array (2,Ncoord) con las coordenadas de estaciones.\n'\ + 'registers : DataFrame de pandas (Nest,Nregisters) con los registros de lluvia.\n'\ + 'p : exponente para la interpolacion de lluvia.\n'\ + 'ruta : Ruta con nombre en donde se guardara el binario con.\n'\ + ' la informacion de lluvia.\n'\ + 'umbral : Umbral de suma total de lluvia bajo el cual se considera\n'\ + ' que un intervalo tiene suficiente agua como para generar reaccion\n'\ + ' (umbral = 0.0) a medida que incremente se generaran archivos mas\n'\ + ' livianos, igualmente existe la posibilidad de borrar informacion.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + 'meanRain : La serie de lluvia promedio interpolada para la cuenca\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'rain_interpolate_mit: interpola campos mediante la metodologia idw.\n'\ + 'rain_read_bin: Lee binario de registros para ver que tiene.\n'\ + 'rain_ncf2bin: Convierte ncf a binario en formato del modelo (para imagenes de radar).\n'\ + #Mira si los registros son un data frame de pandas + isPandas=False + if type(registers)==pd.core.frame.DataFrame: + reg=registers.values.T + isPandas=True + else: + reg=registers + #Obtiene las coordenadas de cada celda de la cuenca + x,y = cu.basin_coordxy(self.structure,self.ncells) + xy_basin=np.vstack((x,y)) + #Interpola con idw + if self.modelType[0] is 'h': + meanRain,posIds = models.rain_idw(xy_basin, coord, reg, p, self.nhills, + ruta, umbral, self.hills_own, self.ncells, coord.shape[1],reg.shape[1]) + elif self.modelType[0] is 'c': + meanRain,posIds = models.rain_idw(xy_basin, coord, reg, p, self.nhills, + ruta, umbral, np.ones(self.ncells), self.ncells, coord.shape[1],reg.shape[1]) + #Guarda un archivo con informacion de la lluvia + f=open(ruta[:-3]+'hdr','w') + f.write('Numero de celdas: %d \n' % self.ncells) + f.write('Numero de laderas: %d \n' % self.nhills) + f.write('Numero de registros: %d \n' % reg.shape[1]) + f.write('Numero de campos no cero: %d \n' % posIds.max()) + f.write('Tipo de interpolacion: IDW, p= %.2f \n' % p) + f.write('IDfecha, Record, Lluvia, Fecha \n') + if isPandas: + dates=registers.index.to_pydatetime() + c = 1 + for d,pos,m in zip(dates,posIds,meanRain): + f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) + c+=1 + f.close() + return meanRain,posIds + + def rain_radar2basin_from_asc(self,ruta_in,ruta_out,fechaI,fechaF,dt, + pre_string,post_string,fmt = '%Y%m%d%H%M',conv_factor=1.0/12.0, + umbral = 0.0): + 'Descripcion: Genera campos de lluvia a partir de archivos asc. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : .\n'\ + 'ruta_in: Ruta donde se encuentran loas .asc.\n'\ + 'ruta_out: Ruta donde escribe el binario con la lluvia.\n'\ + 'fechaI: Fecha de inicio de registros.\n'\ + 'fechaF: Fecha de finalizacion de registros.\n'\ + 'dt: Intervalo de tiempo entre registros.\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + 'meanRain : La serie de lluvia promedio.\n'\ + 'meanRain : La serie de lluvia promedio.\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ + 'rain_radar2basin_from_array: Mete campos de lluvia mediante multiples arrays.\n'\ + #Edita la ruta de salida + if ruta_out.endswith('.hdr') or ruta_out.endswith('.bin'): + ruta_bin = ruta_out[:-3]+'.bin' + ruta_hdr = ruta_out[:-3]+'.hdr' + else: + ruta_bin = ruta_out+'.bin' + ruta_hdr = ruta_out+'.hdr' + #Establece la cantidad de elementos de acuerdo al tipo de cuenca + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + #Guarda la primera entrada como un mapa de ceros + models.write_int_basin(ruta_bin,np.zeros((1,N)),1,N,1) + #Genera la lista de las fechas. + ListDates,dates = __ListaRadarNames__(ruta_in, + fechaI,fechaF, + fmt,post_string,pre_string,dt) + #Lee los mapas y los transforma + cont = 1 + meanRain = [] + posIds = [] + for l in ListDates: + Map,p = read_map_raster(ruta_in + l) + vec = self.Transform_Map2Basin(Map,p) * conv_factor + #Si el mapa tiene mas agua de un umbral + if vec.sum() > umbral: + #Actualiza contador, lluvia media y pocisiones + cont +=1 + meanRain.append(vec.mean()) + posIds.append(cont) + #Guarda el vector + vec = vec*1000; vec = vec.astype(int) + models.write_int_basin(ruta_bin,np.zeros((1,N))+vec,cont,N,1) + else: + #lluvia media y pocisiones + meanRain.append(0.0) + posIds.append(1) + posIds = np.array(posIds) + meanRain = np.array(meanRain) + #Guarda un archivo con informacion de la lluvia + f=open(ruta_hdr[:-3]+'hdr','w') + f.write('Numero de celdas: %d \n' % self.ncells) + f.write('Numero de laderas: %d \n' % self.nhills) + f.write('Numero de registros: %d \n' % meanRain.shape[0]) + f.write('Numero de campos no cero: %d \n' % posIds.max()) + f.write('Tipo de interpolacion: radar \n') + f.write('IDfecha, Record, Lluvia, Fecha \n') + c = 1 + for d,pos,m in zip(dates,posIds,meanRain): + f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) + c+=1 + f.close() + return np.array(meanRain),np.array(posIds) + + def rain_radar2basin_from_array(self,vec=None,ruta_out=None,fecha=None,dt=None, + status='update',umbral = 0.01, doit = False): + 'Descripcion: Genera campos de lluvia a partir de archivos array\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : .\n'\ + 'vec: Array en forma de la cuenca con la informacion.\n'\ + 'ruta_out: Ruta donde escribe el binario con la lluvia.\n'\ + 'fecha: Fecha del registro actual.\n'\ + 'dt: Intervalo de tiempo entre registros.\n'\ + 'status: Estado en el cual se encuentra el binario que se va a pasar a campo.\n'\ + ' update: (Defecto) Con este estado se genera un binario y se agregan nuevos campos.\n'\ + ' old: Estado para abrir y tomar las propiedades de self.radar.. para la generacion de un binario.\n'\ + ' close: Cierra un binario que se ha generado mediante update.\n'\ + ' reset: Reinicia las condiciones de self.radar... para la creacion de un campo nuevo.\n'\ + 'doit: Independiente del umbral escribe el binario en la siguiente entrada.\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + 'meanRain : La serie de lluvia promedio.\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ + 'rain_radar2basin_from_asc: Mete campos de lluvia mediante multiples arrays.\n'\ + #Edita la ruta de salida + if ruta_out is not None: + if ruta_out.endswith('.hdr') or ruta_out.endswith('.bin'): + ruta_bin = ruta_out[:-3]+'.bin' + ruta_hdr = ruta_out[:-3]+'.hdr' + else: + ruta_bin = ruta_out+'.bin' + ruta_hdr = ruta_out+'.hdr' + #Establece la cantidad de elementos de acuerdo al tipo de cuenca + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + try: + if vec.shape[0] == self.ncells: + vec = self.Transform_Basin2Hills(vec,sumORmean=1) + except: + pass + # De acerudo al estado actualiza las variables o guarda el + # binario final + actualizo = 1 + if status == 'update': + #Entrada 1 es la entrada de campos sin lluvia + if len(self.radarDates) == 0: + models.write_int_basin(ruta_bin,np.zeros((1,N)),1,N,1) + if vec.mean() > umbral or doit: + #Actualiza contador, lluvia media y pocisiones + self.radarCont +=1 + self.radarMeanRain.append(vec.mean()) + self.radarPos.append(self.radarCont) + #Guarda el vector + vec = vec*1000; vec = vec.astype(int) + models.write_int_basin(ruta_bin,np.zeros((1,N))+vec, + self.radarCont,N,1) + actualizo = 0 + else: + #lluvia media y pocisiones + self.radarMeanRain.append(0.0) + self.radarPos.append(1) + self.radarDates.append(fecha) + #Si ya no va a agregar nada, no agrega mas campos y genera el .hdr + elif status == 'close': + self.radarMeanRain = np.array(self.radarMeanRain) + self.radarPos = np.array(self.radarPos) + #Guarda un archivo con informacion de la lluvia + f=open(ruta_hdr[:-3]+'hdr','w') + f.write('Numero de celdas: %d \n' % self.ncells) + f.write('Numero de laderas: %d \n' % self.nhills) + f.write('Numero de registros: %d \n' % self.radarMeanRain.shape[0]) + f.write('Numero de campos no cero: %d \n' % self.radarPos.max()) + f.write('Tipo de interpolacion: radar \n') + f.write('IDfecha, Record, Lluvia, Fecha \n') + c = 1 + for d,pos,m in zip(self.radarDates, + self.radarPos,self.radarMeanRain): + f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) + c+=1 + f.close() + #Vuelve las variables listas de nuevo + self.radarMeanRain = self.radarMeanRain.tolist() + self.radarPos = self.radarPos.tolist() + elif status == 'reset': + #Variables de radar + self.radarDates = [] + self.radarPos = [] + self.radarMeanRain = [] + self.radarCont = 1 + elif status == 'old': + #si es un archivo viejo, lo abre para tomar las variables y continuar en ese punto + f=open(ruta_hdr[:-3]+'hdr','r') + Lista = f.readlines() + self.radarCont = int(Lista[3].split()[-1]) + cantidadIds = int(Lista[2].split()[-1]) + f.close() + #Abre con numpy para simplificar las cosas + a = np.loadtxt(ruta_hdr,skiprows=6,dtype='str').T + if self.radarCont >= 1 and cantidadIds > 1: + self.radarPos = [int(i.split(',')[0]) for i in a[1]] + self.radarMeanRain = [float(i.split(',')[0]) for i in a[2]] + for i in a[3]: + d = datetime.datetime.strptime(i,'%Y-%m-%d-%H:%M') + self.radarDates.append(d) + else: + self.radarPos = [int(a[1].split(',')[0])] + self.radarMeanRain = [float(a[2].split(',')[0])] + self.radarDates = [datetime.datetime.strptime(a[-1], '%Y-%m-%d-%H:%M')] + return actualizo + + #------------------------------------------------------ + # Subrutinas para preparar modelo + #------------------------------------------------------ + def set_Geomorphology(self,umbrales=[30,500],stream_width=None): + 'Descripcion: calcula las propiedades geomorfologicas necesarias \n'\ + ' para la simulacion. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'umbrales : Lista con la cantidad de celdas necesarias .\n'\ + ' para que una celda sea: ladera, carcava o cauce .\n'\ + 'stream_width = Ancho del canal en cada tramo (opcional).\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables geomorfologicas de simulacion iniciadas.\n'\ + ' models.drena : Numero de celda o ladera destino. \n'\ + ' models.nceldas : Numero de celdas o laderas. \n'\ + ' models.unit_type : tipo de celda, en el caso de ladera no aplica.\n'\ + ' 1: Celda tipo ladera.\n'\ + ' 2: Celda tipo transitorio.\n'\ + ' 3: Celda tipo cauce.\n'\ + ' models.hill_long : Longitud promedio de la ladera (o celda). \n'\ + ' - Celdas: Longitud de cada elemento (cu.dxp) para ortogonal y 1.43*cu.dxp para diagonal. \n'\ + ' - Laderas: Promedio de las longitudes recorridas entre una celda y la corriente de la ladera. \n'\ + ' models.hill_slope : Pendiente de cada ladera (promedio) o celda.\n'\ + ' models.stream_long : Longitud de cada tramo de cuace. \n'\ + ' - Celdas: Es cu.dxp: ortogonal, 1.42*cu.dxp: Diagonal. \n'\ + ' - Laderas: Es la Longitud de los elementos del cauce que componen la ladera. \n'\ + ' models.stream_slope : Pendiente de cada tramo de cauce. \n'\ + ' - Celdas: Es la pendiente estimada por self.GetGeo_Cell_Basics(). \n'\ + ' - Laderas: Pendiente promedio de las laderas. \n'\ + ' models.stream_width : Ancho de cada tramo de cauce. \n'\ + ' - Celdas: No aplica y se hacen todos iguales a la unidad. \n'\ + ' - Laderas: Es el ancho del canal calculado a partir de geomrofologia o entregado. \n'\ + ' models.elem_area : Area de cada celda (cu.dxp**2) o ladera (nceldasLadera * cu.dxp**2). \n'\ + #Obtiene lo basico para luego pasar argumentos + acum,hill_long,pend,elev = cu.basin_basics(self.structure, + self.DEMvec,self.DIRvec,self.ncells) + #Obtiene la pendiente y la longitud de las corrientes + cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( + self.structure,acum,umbrales[1],self.ncells) + stream_s,stream_l = cu.basin_stream_slope( + self.structure,elev,hill_long,nodos,n_cauce,self.ncells) + stream_s[np.isnan(stream_s)]=self.nodata + #Obtiene para metros por subn cuencas + sub_horton,nod_horton = cu.basin_subbasin_horton(self.hills,self.ncells, + self.hills.shape[1]) + sub_basin_long,max_long,nodo_max_long = cu.basin_subbasin_long( + self.hills_own,cauce,hill_long,self.hills, + sub_horton,self.hills.shape[1],self.ncells) + #Obtiene las propiedades por laderas de los cauces + stream_slope,stream_long = cu.basin_subbasin_stream_prop( + self.hills_own,cauce,hill_long, + pend,self.hills.shape[1],self.ncells) + #opbtiene el ancho si noe s dado lo asume igual a uno + if stream_width is None: + stream_width=np.ones(self.ncells) + #De acuerdo a si el modelo es por laderas o por celdas agrega lass varaibeles + if self.modelType[0]=='c': + #Obtiene el tipo de celdas + unit_type = cu.basin_stream_type(self.structure, + acum,umbrales,len(umbrales),self.ncells) + #Asigna variables + models.drena = np.ones((1,self.ncells))*self.structure + models.nceldas = self.ncells + models.unit_type = np.ones((1,self.ncells))*unit_type + models.hill_long = np.ones((1,self.ncells))*hill_long + models.hill_slope = np.ones((1,self.ncells))*pend + models.stream_long = np.ones((1,self.ncells))*np.percentile(hill_long, 40) + models.stream_slope = np.ones((1,self.ncells))*pend + models.stream_width = np.ones((1,self.ncells))*stream_width + models.elem_area = np.ones((1,self.ncells))*cu.dxp**2.0 + elif self.modelType[0]=='h': + N=self.hills.shape[1] + models.drena = np.ones((1,N))*self.hills[1] + models.nceldas = self.hills.shape[1] + models.unit_type = np.ones((1,N))*np.ones(N)*3 + models.hill_long = np.ones((1,N))*sub_basin_long + models.hill_slope = np.ones((1,N))*self.Transform_Basin2Hills(pend) + models.stream_long = np.ones((1,N))*stream_long + models.stream_slope = np.ones((1,N))*stream_slope + models.stream_width = np.ones((1,N))*cu.basin_subbasin_map2subbasin( + self.hills_own,stream_width,self.nhills,cauce,0,self.ncells) + no0min = models.stream_width[models.stream_width<>0].min() + models.stream_width[models.stream_width==0] = no0min + models.elem_area = np.ones((1,N))*np.array([self.hills_own[self.hills_own==i].shape[0] for i in range(1,self.hills.shape[1]+1)])*cu.dxp**2.0 + #Ajusta variable de que la geomorfologia esta calculada + self.isSetGeo = True + + def set_Speed_type(self,types=np.ones(3)): + 'Descripcion: Especifica el tipo de velocidad a usar en cada \n'\ + ' nivel del modelo. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'types : tipos de velocidad .\n'\ + ' 1. Velocidad tipo embalse lineal, no se especifica h_exp.\n'\ + ' 2. Velocidad onda cinematica, se debe especificar h_exp.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con la variable models.speed_type especificada.\n'\ + #Especifica la ecuacion de velocidad a usar en cada nivel del modelo + for c,i in enumerate(types): + if i==1 or i==2: + models.speed_type[c]=i + else: + models.speed_type[c]=1 + + def set_Floods(self,var,VarName, umbral = 1000, NumCeldas = 6, Default = False): + 'Descripcion: Aloja las variables del sub modelo de inundaciones\n'\ + '\n'\ + 'Parametros\n'\ + 'Mierda PUTA\n'\ + '----------\n'\ + 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ + 'varName: Nombre de la variable a ingresar en el modelo.\n'\ + ' GammaWater : Densidad del agua (Defecto: 1000).\n'\ + ' GammaSoil : Densidad del sedimento (Defecto: 2600).\n'\ + ' VelArea: Factor conversion Velocidad - Area (Defecto: 1/200).\n'\ + ' Cmax: Maxima concentracion de sedimentos (Defecto 0.75).\n'\ + ' MaxIter: Cantidad maxima de iteraciones para obtener la mancha de inunudacion.\n'\ + ' VelUmbral: Velocidad minima para que se de el flujo de escombros ( Defecto: 3 m/s).\n'\ + ' Stream_W: Ancho del canal en cada celda (ncells).\n'\ + ' Stream_D50: Tamano de particula percentil 50 (ncells).\n'\ + ' HAND: Modelo de elevacion relativa de celda ladera a celda cauce (ncells), no se ponde nada.\n'\ + ' umbral: Umbral para determinar corriente segun HAND debe coincidir con el umbral del modelo.\n'\ + ' Slope: Pendiente del canal, (no se ponde variable)\n'\ + ' Default: Poner o no parametros por defecto (False)\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ + ' wmf.models.flood_dw.\n'\ + ' wmf.models.flood_dsed.\n'\ + ' wmf.models.flood_av.\n'\ + ' wmf.models.flood_cmax.\n'\ + ' wmf.models.flood_d50.\n'\ + ' wmf.models.flood_hand.\n'\ + ' wmf.models.flood_aquien.\n'\ + #Si el modelo es tipo ladera agrega la variable + if self.modelType[0] == 'h': + return 'El modelo por laderas no simula inundaciones.' + #Pone el gamma del agua por defecto + if Default: + models.flood_dw = 1000 + models.flood_dsed = 2600 + models.flood_av = 1./200.0 + models.flood_cmax = 0.75 + models.flood_umbral = 3.0 + models.flood_max_iter = 10 + models.flood_step = 1.0 + #Obtiene el vector que va a alojar en el modelo + if VarName <> 'GammaWater' and VarName <> 'GammaSoil' and VarName <> 'VelArea' and VarName <> 'Cmax' and VarName <> 'VelUmbral': + isVec=False + if type(var) is str: + #Si es un string lee el mapa alojado en esa ruta + Map,Pp = read_map_raster(var) + Vec = self.Transform_Map2Basin(Map,Pp) + isVec=True + elif type(var) is int or float: + Vec = np.ones((1,self.ncells))*var + isVec=True + elif type(var) is np.ndarray and var.shape[0] == self.ncells: + Vec = var + isVec=True + #finalmente mete la variable en el modelo + N = self.ncells + if VarName is 'Stream_W' : + models.flood_w = np.ones((1,N))*Vec + elif VarName is 'Stream_D50': + models.flood_d50 = np.ones((1,N))*Vec + elif VarName is 'HAND': + self.GetGeo_HAND(umbral = umbral) + models.flood_hand = np.ones((1,N))*np.copy(self.CellHAND) + models.flood_aquien = np.ones((1,N))*np.copy(self.CellHAND_drainCell) + elif VarName is 'Slope': + self.GetGeo_Cell_Basics() + models.flood_slope = np.ones((1,N))*np.sin(np.arctan(self.CellSlope)) + elif VarName is 'Sections': + self.GetGeo_Sections(NumCeldas = NumCeldas) + models.flood_sections = np.ones((NumCeldas*2+1,N)) * self.Sections + models.flood_sec_cells = np.ones((NumCeldas*2+1,N)) * self.Sections_Cells + elif VarName == 'GammaWater': + models.flood_dw = var + elif VarName == 'GammaSoil': + models.flood_dsed = var + elif VarName == 'VelArea': + models.flood_av = var + elif VarName == 'Cmax': + models.flood_cmax = var + elif VarName == 'VelUmbral': + models.flood_umbral = var + elif VarName == 'MaxIter': + models.flood_max_iter = var + + def set_PhysicVariables(self,modelVarName,var,pos,mask=None): + 'Descripcion: Coloca las variables fisicas en el modelo \n'\ + ' Se debe assignarel nombre del tipo de variable, la variable\n'\ + ' y la posicion en que esta va a ser insertada\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Objeto de la cuenca 2que luego se va a simular.\n'\ + 'modelVarName : Nombre de la variable del modelo que se va a incertar.\n'\ + ' - h_coef: coeficientes horizontales\n'\ + ' [0]: Flujo de Escorrentia.\n'\ + ' [1]: Flujo Sub-superficial.\n'\ + ' [2]: Flujo subterraneo.\n'\ + ' [3]: Flujo en cauces.\n'\ + ' - h_exp: exponentes del tipo v = h_coef*(A**h_exp)\n'\ + ' [0]: Escorrentia.\n'\ + ' [1]: sub-superficial.\n'\ + ' [2]: subterraneo.\n'\ + ' [3]: cauce.\n'\ + ' - v_coef.\n'\ + ' [0]: Tasa evaporacion.\n'\ + ' [1]: Infiltracion.\n'\ + ' [2]: Percolacion.\n'\ + ' [3]: Perdidas (0).\n'\ + ' - v_exp: procesos verticales no lineales\n'\ + ' (no implementado dentro del modelo)\n' + ' - capilar.\n'\ + ' - gravit.\n'\ + 'var : variable que ingresa en el modelo, esta puede ser:.\n'\ + ' - Ruta: una ruta del tipo string.\n'\ + ' - Escalar : Un valor escalar que se asignara a toda la cuenca.\n'\ + ' - Vector : Un vector con la informacion leida (1,ncells).\n'\ + 'pos : Posicion de insercion, aplica para : h_coef, v_coef,.\n'\ + ' h_exp, v_exp.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ + 'rain_read_bin: Lee binario de registros para ver que tiene.\n'\ + 'rain_ncf2bin: Convierte ncf a binario en formato del modelo (para imagenes de radar).\n'\ + + #Obtiene el vector que va a alojar en el modelo + isVec=False + if type(var) is str: + #Si es un string lee el mapa alojado en esa ruta + Map,Pp = read_map_raster(var) + Vec = self.Transform_Map2Basin(Map,Pp) + isVec=True + elif type(var) is int or float: + Vec = np.ones((1,self.ncells))*var + isVec=True + elif type(var) is np.ndarray and var.shape[0] == self.ncells: + Vec = var + isVec=True + #Si el modelo es tipo ladera agrega la variable + if self.modelType[0] is 'h': + Vec = self.Transform_Basin2Hills(Vec,mask=mask) + #finalmente mete la variable en el modelo + if modelVarName is 'h_coef': + models.h_coef[pos] = Vec + elif modelVarName is 'h_exp': + models.h_exp[pos] = Vec + elif modelVarName is 'v_coef': + models.v_coef[pos] = Vec + elif modelVarName is 'v_exp': + models.v_exp[pos] = Vec + elif modelVarName is 'capilar': + models.max_capilar[0] = Vec + elif modelVarName is 'gravit': + models.max_gravita[0] = Vec + + def set_Storage(self,var,pos,hour_scale=False): + 'Descripcion: \n'\ + ' Establece el almacenamiento inicial del modelo\n'\ + ' la variable puede ser un valor, una ruta o un vector.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'var : Variable con la cual se va a iniciar el almancenamiento.\n'\ + ' - ruta : es una ruta a un archivo binario de almacenamiento.\n'\ + ' - escalar : valor de almacenamiento constate para toda la cuenca.\n'\ + ' - vector : Vector con valores para cadda unidad de la cuenca.\n'\ + 'pos : Posicion de insercion,.\n'\ + ' - 0 : alm cpailar.\n'\ + ' - 1 : alm superficial.\n'\ + ' - 2 : alm sub-superficial.\n'\ + ' - 3 : alm subterraneo.\n'\ + ' - 4 : alm cauce.\n'\ + ' - fecha: en caso de que var sea la ruta a StOhdr:\n'\ + ' - valor: puede ser un entero con la posicion.\n'\ + ' - str fecha: puede ser un srint con la fecha: YYYY-MM-DD-HH:MM :\n'\ + 'hour_scale: Buscar fechas a escala horaria o minutos?.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'save_storage(slef,storage).\n'\ + #Determina el tipo de unidades del modelo + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + #Obtiene el vector que va a alojar en el modelo + isVec=False + if type(var) is str: + var_bin,var_hdr = __Add_hdr_bin_2route__(var,storage = True) + if type(pos) is not str: + #Si es un string lee el binario de almacenamiento alojado en esa ruta + Vec,res = models.read_float_basin_ncol(var_bin,pos+1,N,5) + if type(pos) == str: + # Lee las fechas + L = np.loadtxt(var_hdr,skiprows = 5, usecols = (0,6), dtype = str) + if hour_scale == False: + Fechas = [datetime.datetime.strptime(i[1], '%Y-%m-%d-%H:%M') for i in L] + else: + Fechas = [datetime.datetime.strptime(i[1][:-3], '%Y-%m-%d-%H') for i in L] + try: + if hour_scale == False: + posFecha = Fechas.index(datetime.datetime.strptime(pos, '%Y-%m-%d-%H:%M')) + else: + posFecha = Fechas.index(datetime.datetime.strptime(pos[:-3], '%Y-%m-%d-%H')) + except: + print 'Error: no se encuentra la fecha especificada en el archivo '+var + Vec,res = models.read_float_basin_ncol(var_bin,posFecha+1,N,5) + isVec=True + for p in range(5): + models.storage[p] = Vec[p] + elif type(var) is int or float: + Vec = np.ones((1,N))*var + isVec=True + models.storage[pos] = Vec + elif type(var) is np.ndarray and var.shape[0] == N: + Vec = var + isVec=True + models.storage[pos] = Vec + + def set_Control(self,coordXY,ids,tipo = 'Q'): + 'Descripcion: \n'\ + ' Establece los puntos deonde se va a realizar control del caudal\n'\ + ' y de la humedad simulada.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'coordXY : Coordenadas de los puntos de control [2,Ncontrol].\n'\ + 'ids : Identificacion de los puntos de control.\n'\ + 'tipo: Control para caudal [Q] o para humedad [H].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Define los puntos de control en las variables:\n'\ + ' - models.control : control de caudal y sedimentos.\n'\ + ' - models.control_h : control de la humedad del suelo.\n'\ + 'IdsControl : El orden en que quedaron los puntos de control al interior.\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'set_record, set_storage.\n'\ + #Obtiene los puntos donde hay coordenadas + if tipo is 'Q': + xyNew, basinPts, order = self.Points_Points2Stream(coordXY,ids) + if self.modelType[0] is 'c': + models.control[0] = basinPts + IdsConvert = basinPts[basinPts<>0] + elif self.modelType[0] is 'h': + unitario = basinPts / basinPts + pos = self.hills_own * self.CellCauce * unitario + posGrande = self.hills_own * self.CellCauce * basinPts + IdsConvert = posGrande[posGrande<>0] / pos[pos<>0] + models.control[0][pos[pos<>0].astype(int).tolist()] = IdsConvert + elif tipo is 'H': + xyNew = coordXY + basinPts, order = self.Points_Points2Basin(coordXY,ids) + if self.modelType[0] == 'c': + models.control_h[0] = basinPts + IdsConvert = basinPts[basinPts<>0] + elif self.modelType[0] == 'h': + unitario = basinPts / basinPts + pos = self.hills_own * unitario + posGrande = self.hills_own * basinPts + IdsConvert = posGrande[posGrande<>0] / pos[pos<>0] + models.control_h[0][pos[pos<>0].astype(int).tolist()] = IdsConvert + return IdsConvert,xyNew + + + def set_sediments(self,var,VarName, wi = [0.036, 2.2e-4, 8.6e-7], + diametro = [0.35, 0.016, 0.001], G = 9.8): + 'Descripcion: Alojas las variables requeridas para la ejecucion\n'\ + ' del modelo de sedimentos.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ + 'varName: Nombre de la variable a ingresar en el modelo.\n'\ + ' Krus : Erosividad del suelo (RUSLE).\n'\ + ' Crus : Cobertura del suelo (RUSLE).\n'\ + ' Prus : Practicas proteccion (RUSLE).\n'\ + ' PArLiAc : Porcentaje Arenas, Limos y Arcillas.\n'\ + ' wi : velocidad de caida de cada particula de sed [m/s].\n'\ + ' diametro : diametro de cada tipo de sedimento [mm].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ + ' wmf.models.krus.\n'\ + ' wmf.models.crus.\n'\ + ' wmf.models.prus.\n'\ + ' wmf.models.parliac.\n'\ + ' wmf.models.wi.\n'\ + ' wmf.models.diametro.\n'\ + #Determina el tipo de unidades del modelo + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + #Se fija que tipo de variable es + isVec=False + if type(var) is str: + #Si es un string lee el mapa alojado en esa ruta + Map,Pp = read_map_raster(var) + Vec = self.Transform_Map2Basin(Map,Pp) + isVec=True + elif type(var) is int or float: + Vec = np.ones((1,self.ncells))*var + isVec=True + elif type(var) is np.ndarray and var.shape[0] == self.ncells: + Vec = var + isVec=True + #Si el modelo es tipo ladera agrega la variable + if self.modelType[0] is 'h': + Vec = self.Transform_Basin2Hills(Vec,mask=mask) + #Inicia las variables + if VarName == 'Krus': + models.krus = np.ones((1,N))*Vec + if VarName == 'Prus': + models.prus = np.ones((1,N))*Vec + if VarName == 'Crus': + models.crus = np.ones((1,N))*Vec + if VarName == 'PArLiAc': + models.parliac = np.ones((3,N))*Vec + #Variables de diametro y velocidad de caida + models.wi = wi + models.diametro = diametro + models.g = G + + def set_Slides(self,var,VarName): + 'Descripcion: Alojas las variables requeridas para la ejecucion\n'\ + ' del modelo de deslizamientos.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ + 'varName: Nombre de la variable a ingresar en el modelo.\n'\ + ' Zs : Profundidad del suelo.\n'\ + ' GammaSoil: Densidad del suelo.\n'\ + ' Cohesion: Cohesion del suelo.\n'\ + ' FrictionAngle : Angulo de friccion del suelo.\n'\ + ' FS: Factor de Seguridad, en este caso se envia una constante.\n'\ + ' RadSlope : .\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ + ' wmf.models.sl_zs.\n'\ + ' wmf.models.sl_gammas.\n'\ + ' wmf.models.sl_cohesion.\n'\ + ' wmf.models.sl_frictionangle.\n'\ + ' wmf.models.sl_radslope.\n'\ + ' wmf.models.sl_fs.\n'\ + #Pone el gamma del agua por defecto + models.sl_gammaw = 9.8 + #Obtiene el vector que va a alojar en el modelo + if VarName <> 'FS': + isVec=False + if type(var) is str: + #Si es un string lee el mapa alojado en esa ruta + Map,Pp = read_map_raster(var) + Vec = self.Transform_Map2Basin(Map,Pp) + isVec=True + elif type(var) is int or float: + Vec = np.ones((1,self.ncells))*var + isVec=True + elif type(var) is np.ndarray and var.shape[0] == self.ncells: + Vec = var + isVec=True + #Si el modelo es tipo ladera agrega la variable + if self.modelType[0] == 'h': + return 'El modelo por laderas no simula deslizamientos.' + #finalmente mete la variable en el modelo + N = self.ncells + if VarName is 'GammaSoil' : + models.sl_gammas = np.ones((1,N))*Vec + elif VarName is 'Cohesion': + models.sl_cohesion = np.ones((1,N))*Vec + elif VarName is 'FrictionAngle': + models.sl_frictionangle = np.ones((1,N))*np.deg2rad(Vec) + elif VarName is 'Zs': + models.sl_zs = np.ones((1,N))*Vec + elif VarName is 'FS': + models.sl_fs = var + elif VarName is 'Slope': + models.sl_radslope = np.ones((1,N))*np.arctan(Vec) + models.sl_radslope[models.sl_radslope == 0] = 0.01 + #------------------------------------------------------ + # Guardado y Cargado de modelos de cuencas preparados + #------------------------------------------------------ + def Save_SimuBasin(self,ruta,SimSlides = False, + ExtraVar = None): + 'Descripcion: guarda una cuenca previamente ejecutada\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'ruta : Ruta donde la cuenca sera guardada.\n'\ + 'ruta_dem : direccion donde se aloja el DEM (se recomienda absoluta).\n'\ + 'ruta_dir : direccion donde se aloja el DIR (se recomienda absoluta).\n'\ + 'SimSlides: indica a la funcion si va a guardar o no informacion para la simulacion.\n'\ + ' de deslizamientos.\n'\ + 'ExtraVar: Variables extras de simulacion deben ir en un diccionario.\n'\ + ' Forma del diccionario Dict = {"varName": {"Data": vector[ncells], "type": "tipo"}}.\n'\ + ' Los tipos de variables son: flotante: "f4", entero "i4".\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas.\n'\ + #Si esta o no set el Geomorphology, de acuerdo a eso lo estima por defecto + if self.isSetGeo is False: + self.set_Geomorphology() + print 'Aviso: SE ha estimado la geomorfologia con los umbrales por defecto umbral = [30, 500]' + #Guarda la cuenca + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + Dict = {'nombre':self.name, + 'modelType':self.modelType,'noData':cu.nodata,'umbral':self.umbral, + 'ncells':self.ncells,'nhills':self.nhills, + 'dt':models.dt,'Nelem':N,'dxp':cu.dxp,'retorno':models.retorno, + 'storageConst' :models.storage_constant, + 'ncols':cu.ncols, + 'nrows':cu.nrows, + 'xll':cu.xll, + 'yll':cu.yll, + 'dx':cu.dx, + 'dy':cu.dy, + 'epsg': self.epsg} + if SimSlides: + Dict.update({'sl_fs':models.sl_fs, 'sl_gullie':models.sl_gullienogullie, 'sl_gammaw':models.sl_gammaw}) + #abre el archivo + gr = netcdf.Dataset(ruta,'w',format='NETCDF4') + #Grupo base + GrupoBase = gr.createGroup('base') + GrupoSimHid = gr.createGroup('SimHidro') + GrupoSimSed = gr.createGroup('SimSediments') + GrupoSimSli = gr.createGroup('SimSlides') + GrupoHidro = gr.createGroup('Hidro') + GrupoGeo = gr.createGroup('Geomorfo') + GrupoCalib = gr.createGroup('Parametros') + #Variables grupo base + DimNcell = GrupoBase.createDimension('ncell',self.ncells) + DimNhill = GrupoBase.createDimension('nhills',self.nhills) + DimCol3 = GrupoBase.createDimension('col3',3) + DimCol2 = GrupoBase.createDimension('col2',2) + VarStruc = GrupoBase.createVariable('structure','i4',('col3','ncell'),zlib=True) + VarHills = GrupoBase.createVariable('hills','i4',('col2','nhills'),zlib=True) + VarHills_own = GrupoBase.createVariable('hills_own','i4',('ncell',),zlib=True) + VarStruc[:] = self.structure + VarHills[:] = self.hills + VarHills_own[:] = self.hills_own + #Variables de Simulacion hidrologica + DimNelem = GrupoSimHid.createDimension('Nelem',N) + DimCol3 = GrupoSimHid.createDimension('col3',3) + DimCol2 = GrupoSimHid.createDimension('col2',2) + DimCol4 = GrupoSimHid.createDimension('col4',4) + DimCol5 = GrupoSimHid.createDimension('col5',5) + VarH_coef = GrupoSimHid.createVariable('h_coef','f4',('col4','Nelem'),zlib=True) + VarV_coef = GrupoSimHid.createVariable('v_coef','f4',('col4','Nelem'),zlib=True) + VarH_exp = GrupoSimHid.createVariable('h_exp','f4',('col4','Nelem'),zlib=True) + VarV_exp = GrupoSimHid.createVariable('v_exp','f4',('col4','Nelem'),zlib=True) + Var_H1max = GrupoSimHid.createVariable('h1_max','f4',('Nelem',),zlib = True) + Var_H3max = GrupoSimHid.createVariable('h3_max','f4',('Nelem',),zlib = True) + Control = GrupoSimHid.createVariable('control','i4',('Nelem',),zlib = True) + ControlH = GrupoSimHid.createVariable('control_h','i4',('Nelem',),zlib = True) + if self.modelType[0] is 'c': + drena = GrupoSimHid.createVariable('drena','i4',('col3','Nelem'),zlib = True) + elif self.modelType[0] is 'h': + drena = GrupoSimHid.createVariable('drena','i4',('Nelem'),zlib = True) + unitType = GrupoSimHid.createVariable('unit_type','i4',('Nelem',),zlib = True) + hill_long = GrupoSimHid.createVariable('hill_long','f4',('Nelem',),zlib = True) + hill_slope = GrupoSimHid.createVariable('hill_slope','f4',('Nelem',),zlib = True) + stream_long = GrupoSimHid.createVariable('stream_long','f4',('Nelem',),zlib = True) + stream_slope = GrupoSimHid.createVariable('stream_slope','f4',('Nelem',),zlib = True) + stream_width = GrupoSimHid.createVariable('stream_width','f4',('Nelem',),zlib = True) + elem_area = GrupoSimHid.createVariable('elem_area','f4',('Nelem',),zlib = True) + speed_type = GrupoSimHid.createVariable('speed_type','i4',('col3',),zlib = True) + storage = GrupoSimHid.createVariable('storage','i4',('col5','Nelem'),zlib = True) + VarH_coef[:] = models.h_coef + VarV_coef[:] = models.v_coef + VarH_exp[:] = models.h_exp + VarV_exp[:] = models.v_exp + Var_H1max[:] = models.max_capilar + Var_H3max[:] = models.max_gravita + Control[:] = models.control + ControlH[:] = models.control_h + drena[:] = models.drena + unitType[:] = models.unit_type + hill_long[:] = models.hill_long + hill_slope[:] = models.hill_slope + stream_long[:] = models.stream_long + stream_slope[:] = models.stream_slope + stream_width[:] = models.stream_width + elem_area[:] = models.elem_area + speed_type[:] = models.speed_type + storage[:] = models.storage + #Variables grupo GEomorfologia + DimNcell = GrupoGeo.createDimension('ncell',self.ncells) + VarDEM = GrupoGeo.createVariable('DEM','f4',('ncell',),zlib = True) + VarDIR = GrupoGeo.createVariable('DIR','i4',('ncell',),zlib = True) + VarDEM[:] = self.DEMvec + VarDIR[:] = self.DIRvec + #Variables de deslizamientos + if SimSlides: + DimNelem = GrupoSimSli.createDimension('Nelem',N) + frictionAngle = GrupoSimSli.createVariable('friction_angle','f4',('Nelem',),zlib = True) + Cohesion = GrupoSimSli.createVariable('cohesion','f4',('Nelem',),zlib = True) + GammaSoil = GrupoSimSli.createVariable('gamma_soil','f4',('Nelem',),zlib = True) + ZSoil = GrupoSimSli.createVariable('z_soil','f4',('Nelem',),zlib = True) + RadSlope = GrupoSimSli.createVariable('rad_slope','f4',('Nelem',),zlib = True) + frictionAngle[:] = models.sl_frictionangle + Cohesion[:] = models.sl_cohesion + GammaSoil[:] = models.sl_gammas + ZSoil[:] = models.sl_zs + RadSlope[:] = models.sl_radslope + #Introduce variables extras en caso de que el usuario las incluyera + if type(ExtraVar) is dict: + for k in ExtraVar.keys(): + Var = gr.createVariable(k,ExtraVar[k]['type'],('ncell',),zlib=True) + Var[:] = ExtraVar[k]['Data'] + #asigna las prop a la cuenca + gr.setncatts(Dict) + #Cierra el archivo + gr.close() + #Sale del programa + return + + #------------------------------------------------------ + # Ejecucion del modelo + #------------------------------------------------------ + def run_shia(self,Calibracion, + rain_rute, N_intervals, start_point = 1, StorageLoc = None, HspeedLoc = None,ruta_storage = None, ruta_speed = None, + ruta_conv = None, ruta_stra = None, ruta_retorno = None,kinematicN = 5, QsimDataFrame = True, EvpVariable = False): + 'Descripcion: Ejecuta el modelo una ves este es preparado\n'\ + ' Antes de su ejecucion se deben tener listas todas las . \n'\ + ' variables requeridas . \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Cuenca a ejecutar con todo listo para ser ejecutada.\n'\ + 'Calibracion : Parametros de calibracion del modelo, orden:.\n'\ + ' - Evaporacion.\n'\ + ' - Infiltracion.\n'\ + ' - Percolacion.\n'\ + ' - Perdidas.\n'\ + ' - Vel Superficial .\n'\ + ' - Vel Sub-superficial.\n'\ + ' - Vel Subterranea.\n'\ + ' - Vel Cauce.\n'\ + ' - Max Capilar.\n'\ + ' - Max Gravitacional.\n'\ + 'rain_rute : Ruta donde se encuentra el archivo binario de lluvia:.\n'\ + ' generado por rain_interpolate_* o por rain_radar2basin.\n'\ + 'N_intervals : Numero de intervalos de tiempo.\n'\ + 'start_point : Punto donde comienza a usar registros de lluvia.\n'\ + ' los binarios generados por rain_* generan un archivo de texto.\n'\ + ' que contiene fechas par aayudar a ubicar el punto de inicio deseado.\n'\ + 'StorageLoc: Variable local de almacenamiento, esto es en el caso de que no se.\n'\ + ' desee usar la configuracion global de almacenamiento del modelo (5, N).\n'\ + 'HspeedLoc: Variable local para setear la velocidad horizontal inicial de ejecucion.\n'\ + 'ruta_storage : Ruta donde se guardan los estados del modelo en cada intervalo.\n'\ + ' de tiempo, esta es opcional, solo se guardan si esta variable es asignada.\n'\ + 'ruta_conv : Ruta al binario y hdr indicando las nubes que son convectivas.\n'\ + 'ruta_stra : Ruta al binario y hdr indicando las nubes que son estratiformes.\n'\ + 'ruta_retorno : Ruta al binario y hdr en donde escribe la serie con los milimetros retornados al tanque runoff.\n'\ + 'kinematicN: Cantidad de iteraciones para la solucion de la onda cinematica.\n'\ + ' De forma continua: 5 iteraciones, recomendado para cuando el modelo se\n'\ + ' ejecuta en forma continua Ej: cu.run_shia(Calib, rain_rute, 100)\n'\ + ' Por intervalos: 10 iteraciones, recomendado cuando el modelo se ejecuta\n'\ + ' por intervalos de un paso ej:\n'\ + ' for i in range(1,N)\n'\ + ' Results = cu.run_shia(Calib, ruta_rain, 1, i)\n'\ + ' for c,j in enumerate(Results[''Storage'']):\n'\ + ' cu.set_Storage(j,c)\n'\ + 'QsimDataFrame: Retorna un data frame con los caudales simulados indicando su id de acuerdo con el\n'\ + ' que guarda la funcion Save_Net2Map con la opcion NumTramo = True. \n'\ + 'EvpVariable: (False) Asume que la evp del modelo cambia en funcion o no de la radiacion\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Qsim : Caudal simulado en los puntos de control.\n'\ + 'Hsim : Humedad simulada en los puntos de control.\n'\ + #genera las rutas + rain_ruteBin,rain_ruteHdr = __Add_hdr_bin_2route__(rain_rute) + #Obtiene las fechas + Rain = read_mean_rain(rain_ruteHdr, N_intervals, start_point) + # De acuerdo al tipo de modelo determina la cantidad de elementos + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + #prepara variables globales + models.rain_first_point = start_point + models.calc_niter = kinematicN + #Prepara terminos para control + if np.count_nonzero(models.control) == 0 : + NcontrolQ = 1 + else: + NcontrolQ = np.count_nonzero(models.control)+1 + if np.count_nonzero(models.control_h) == 0 : + NcontrolH = 1 + else: + NcontrolH = np.count_nonzero(models.control_h) + #Prepara variables de guardado de almacenamiento + if ruta_storage is not None: + models.save_storage = 1 + ruta_sto_bin, ruta_sto_hdr = __Add_hdr_bin_2route__(ruta_storage, + storage = True) + else: + models.save_storage = 0 + ruta_sto_bin = 'no_guardo_nada.StObin' + ruta_sto_hdr = 'no_guardo_nada.StOhdr' + #prepara variable para guardado de velocidad + if ruta_speed is not None: + models.save_speed = 1 + ruta_speed_bin, ruta_speed_hdr = __Add_hdr_bin_2route__(ruta_speed, + storage = True) + else: + models.save_speed = 0 + ruta_speed_bin = 'no_guardo_nada.bin' + ruta_speed_hdr = 'no_guardo_nada.hdr' + #Prepara variables para el almacenamiento de retorno + if ruta_retorno is not None: + models.save_retorno = 1 + ruta_ret_bin, ruta_ret_hdr = __Add_hdr_bin_2route__(ruta_retorno) + else: + models.save_retorno = 0 + ruta_ret_bin = 'no_guardo_nada.bin' + ruta_ret_hdr = 'no_guardo_nada.hdr' + #Variables de separacion de flujo por tipo de lluvia + if ruta_conv is not None and ruta_stra is not None: + ruta_binConv,ruta_hdrConv = __Add_hdr_bin_2route__(ruta_conv) + ruta_binStra,ruta_hdrStra = __Add_hdr_bin_2route__(ruta_stra) + models.separate_rain = 1 + else: + models.separate_rain = 0 + ruta_binConv = 'none' + ruta_hdrConv = 'none' + ruta_binStra = 'none' + ruta_hdrStra = 'none' + #Prepara la variable de almacenamiento + if StorageLoc is not None: + if StorageLoc.shape <> (5, N): + print 'Error: almacenamiento debe ser: (5,'+str(N)+'), y es: ('+str(StorageLoc.shape[0])+','+str(StorageLoc.shape[1])+')' + StorageLoc = np.zeros((5,N))*-9999.0 + else: + StorageLoc = np.zeros((5,N))*-9999.0 + #Prepara la variable de velocidad horizontal inicial + if HspeedLoc is not None: + if HspeedLoc.shape <> (4, N): + print 'Error: velocidad debe ser: (4,'+str(N)+'), y es: ('+str(HspeedLoc.shape[0])+','+str(HspeedLoc.shape[1])+')' + HspeedLoc = np.zeros((4,N))*-9999.0 + else: + HspeedLoc = np.zeros((4,N))*-9999.0 + #Implementa o no la EVP variable en funcion de la radiacion + if EvpVariable: + Rad = self.__GetEVP_Serie__(Rain.index) + else: + models.evpserie = np.ones(N_intervals) + # Ejecuta el modelo + Qsim,Qsed,Qseparated,Humedad,St1,St3,Balance,Speed,Area,Alm,Qsep_byrain = models.shia_v1( + rain_ruteBin, + rain_ruteHdr, + Calibracion, + #N, + NcontrolQ, + NcontrolH, + N_intervals, + StorageLoc, + HspeedLoc, + N, + ruta_sto_bin, + ruta_speed_bin, + ruta_binConv, + ruta_binStra, + ruta_hdrConv, + ruta_hdrStra, + ruta_ret_bin) + #Retorno de variables de acuerdo a lo simulado + Retornos={'Qsim' : Qsim} + Retornos.update({'Balance' : Balance}) + Retornos.update({'Storage' : Alm}) + if np.count_nonzero(models.control_h)>0: + Retornos.update({'Humedad' : Humedad}) + Retornos.update({'Humedad_t1' : St1}) + Retornos.update({'Humedad_t2' : St3}) + if models.sim_sediments == 1: + Retornos.update({'Sediments' : Qsed}) + if models.separate_fluxes == 1: + Retornos.update({'Fluxes' : Qseparated}) + if models.separate_rain == 1: + Retornos.update({'Rain_sep' : Qsep_byrain}) + if models.show_storage == 1: + Retornos.update({'Mean_Storage' : np.copy(models.mean_storage)}) + if models.save_storage == 1: + rutaStorageHdr = __Add_hdr_bin_2route__(ruta_storage) + #Caso en el que se registra el alm medio + if models.show_storage == 1: + __Save_storage_hdr__(ruta_sto_hdr,rain_ruteHdr,N_intervals, + start_point,self,Mean_Storage = np.copy(models.mean_storage)) + #Caso en el que no hay alm medio para cada uno de los + else: + __Save_storage_hdr__(ruta_sto_hdr,rain_ruteHdr,N_intervals, + start_point,self,Mean_Storage=np.zeros((5,N))*-9999) + #Area de la seccion + if models.show_area == 1: + Retornos.update({'Sec_Area': Area}) + #Velocidades + if models.show_speed == 1: + Retornos.update({'Speed' : Speed}) + if models.show_mean_speed == 1: + Retornos.update({'Mean_Speed' : np.copy(models.mean_speed)}) + if models.save_speed == 1: + rutaSpeedHdr = __Add_hdr_bin_2route__(ruta_speed) + #Caso en el que hay velocidad media para todos los tanques + if models.show_mean_speed == 1: + __Save_speed_hdr__(ruta_speed_hdr,rain_ruteHdr,N_intervals, + start_point,self,Mean_Speed = np.copy(models.mean_speed)) + #Caso en el que no hay alm medio para cada uno de los + else: + __Save_speed_hdr__(ruta_speed_hdr,rain_ruteHdr,N_intervals, + start_point,self) + + if models.save_retorno == 1: + if models.show_mean_retorno == 1: + __Save_retorno_hdr__(ruta_ret_hdr, rain_ruteHdr, N_intervals, + start_point, self, Mean_retorno = models.mean_retorno) + else: + __Save_retorno_hdr__(ruta_ret_hdr, rain_ruteHdr, N_intervals, + start_point, self) + + #Campo de lluvia acumulado para el evento + Retornos.update({'Rain_Acum': models.acum_rain}) + Retornos.update({'Rain_hietogram': models.mean_rain}) + #Retornos en caso de simular deslizamientos + if models.sim_slides == 1: + Retornos.update({'Slides_Map': np.copy(models.sl_slideocurrence)}) + Retornos.update({'Slides_NCell_Serie': np.copy(models.sl_slidencelltime)}) + Retornos.update({'Slides_Acum':np.copy(models.sl_slideacumulate)}) + #Caudal simulado en un dataframe + if QsimDataFrame: + #Obtiene ids + ids = models.control[models.control<>0] + Qdict = {} + for i,j in zip(Retornos['Qsim'][1:], ids): + Qdict.update({str(j): i}) + Qdict = pd.DataFrame(Qdict, index=Rain.index) + #Si separa flujos, entrega el caudal tambien en data frame por flujos + if models.separate_fluxes == 1: + Qsep = [] + tupla = [] + for z,i,j in zip(Retornos['Qsim'][1:], Retornos['Fluxes'][1:], ids): + tupla.append((str(j),'run')) + tupla.append((str(j),'sub')) + tupla.append((str(j),'sup')) + Qsep.extend([i[0],i[1],z-i[0]-i[1]]) + index = pd.MultiIndex.from_tuples(tupla, names=['reach','flux']) + Qsep = np.array(Qsep) + QsepDict = pd.DataFrame(Qsep.T, index=Rain.index, columns=index) + #Si simula sedimentos, hace el dataframe + if models.sim_sediments == 1: + Qsedi = [] + tupla = [] + for z,i,j in zip(Retornos['Qsim'][1:], Retornos['Sediments'][1:], ids): + tupla.append((str(j),'Sand')) + tupla.append((str(j),'Lime')) + tupla.append((str(j),'Clay')) + Qsedi.extend([i[0],i[1],i[2]])# [i[0],i[1],z-i[0]-i[1]]) + index = pd.MultiIndex.from_tuples(tupla, names=['reach','Sediments']) + Qsedi = np.array(Qsedi) + QsediDict = pd.DataFrame(Qsedi.T, index=Rain.index, columns=index) + if models.separate_fluxes == 1 and models.sim_sediments == 0: + return Retornos, Qdict, QsepDict + if models.separate_fluxes == 1 and models.sim_sediments == 1: + return Retornos, Qdict, QsepDict, QsediDict + if models.separate_fluxes == 0 and models.sim_sediments == 1: + return Retornos, Qdict, QsediDict + return Retornos, Qdict + return Retornos + + def efficiencia(self, Qobs, Qsim): + 'Descripcion: Calcula diferentes indices de desempeno del modelo\n'\ + ' nash, qpico, rmse, rmseLog, t_pico\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'Qobs : Caudal observado.\n'\ + 'Qsim : Caudal simulado.\n'\ + 'Retornos\n'\ + '----------\n'\ + 'DicEff: diccionario con la eficiencia obtenida en cada param.\n'\ + #Comienza a evaluar cada parametro + DictEff = {'Nash': __eval_nash__(Qobs, Qsim)} + DictEff.update({'Qpico': __eval_q_pico__(Qobs, Qsim)}) + DictEff.update({'Tpico': __eval_t_pico__(Qobs, Qsim, models.dt)}) + DictEff.update({'RmseLog': __eval_rmse_log__(Qobs, Qsim)}) + DictEff.update({'Rmse': __eval_rmse__(Qobs, Qsim)}) + return DictEff + + def Calib_NSGAII(self, nsga_el, nodo_eval, pop_size = 40, process = 4, + NGEN = 6, MUTPB = 0.5, CXPB = 0.5): + 'Descripcion: Algoritmo para calibrar de forma automatica el modelo\n'\ + ' hidrologico utilizando DEAP y su funcion de seleccion NSGAII.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + ' - nsga_el : un objeto de la clase nsgaii_element, el cual determinara las reglas.\n'\ + ' para la generacion de calibraciones.\n'\ + ' - nodo_eval: nodo donde se evalua el modelo.\n'\ + ' - pop_size: tamano de la poblacion (cantidad de calibraciones a evaluar, multiplo de 4).\n'\ + ' - process: Cantidad de procesadores que se utilizaran en la generacion.\n'\ + ' - NGEN: Cantidad de generaciones para obtener la poblacion final.\n'\ + ' - MUTPB: Probabilidad generica de que un gen mute.\n'\ + ' - CXPB: Probabilidad generica de que dos genes se crucen.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + ' - pop: poblacion final.\n'\ + ' - Qsim: Caudales simulados en el punto evaluado.\n'\ + ' - fitness: desempeno de la poblacion obtenida.\n'\ + #Check de que la poblacion sea multiplo de 4 + Flag = True + while Flag: + if np.mod(pop_size,4) == 0: + Flag = False + else: + pop_size += 1 + #Inicia el elemento nsga con los parametros de el + nsga_el.set_nsgaII() + #Crea las poblaciones y las ejecuciones + pop = nsga_el.toolbox.population(pop_size) + Ejecs = map(nsga_el.__crea_ejec__, pop) + #Ejecuta a la poblacion + QsimPar = __ejec_parallel__(Ejecs, process, nodo_eval) + fitnesses = map(nsga_el.toolbox.evaluate, QsimPar) + for ind, fit in zip(pop, fitnesses): + ind.fitness.values = fit + #Itera la poblacion hasta encontrar a la mejor + #toolbox = base.Toolbox() + for g in range(NGEN): + offspring = tools.selTournamentDCD(pop, len(pop)) + offspring = map(nsga_el.toolbox.clone, offspring) + # Apply crossover and mutation on the offspring + for child1, child2 in zip(offspring[::2], offspring[1::2]): + if random.random() < CXPB: + nsga_el.toolbox.mate(child1[0], child2[0]) + del child1.fitness.values + del child2.fitness.values + #Muta a algunos de los genomas + for mutant in offspring: + if random.random() < MUTPB: + nsga_el.toolbox.mutate(mutant[0]) + del mutant.fitness.values + #Ejecuta a la nueva generacion + Ejecs = map(nsga_el.__crea_ejec__, offspring) + QsimPar = __ejec_parallel__(Ejecs, process, nodo_eval) + #Identifica a la gente que no cumple de la generacion + Qsim_invalid = [] + invalid_ind = [] + for i,q in zip(offspring, QsimPar): + if not i.fitness.valid: + Qsim_invalid.append(q) + invalid_ind.append(i) + #Evaluate the individuals with an invalid fitness + fitnesses = map(nsga_el.toolbox.evaluate, Qsim_invalid) + for ind, fit in zip(invalid_ind, fitnesses): + ind.fitness.values = fit + #Toma la siguiente generacion + pop = nsga_el.toolbox.select(pop + offspring, pop_size) + #Retorno + return pop, QsimPar, np.array(fitnesses).T + + +class nsgaii_element: + def __init__(self, rutaLluvia, Qobs, npasos, inicio, SimuBasinElem ,evp =[0,1], infil = [1,200], perco = [1, 40], + losses = [0,1],velRun = [0.1, 1], velSub = [0.1, 1], velSup =[0.1, 1], + velStream = [0.1, 1], Hu = [0.1, 1], Hg = [0.1, 1], + probCruce = np.ones(10)*0.5, probMutacion = np.ones(10)*0.5, + rangosMutacion = [[0,1], [1,200], [1,40], [0,1], [0.1,1], [0.1, 1], [0.1,1], [0.1,1], [0.1, 1], [0.1,1]], + MaxMinOptima = (1.0, -1.0), CrowDist = 0.5): + 'Descripcion: Inicia el objeto de calibracion genetica tipo NSGAII\n'\ + ' este objeto contiene las reglas principales para la implementacion\n'\ + ' de todo el algoritmo de calibracion genetico.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + ' -rutaLluvia : Ruta donde se encuentra el archivo de lluvia binario.\n'\ + ' -Qobs: Array numpy con el caudal observado [npasos].\n'\ + ' -npasos: Cantidad de pasos en simulacion.\n'\ + ' -inicio: Punto de inicio en la simulacion.\n'\ + ' -SimuBasinElem: Objeto de simulacion.\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas.\n'\ + #Rangos parametros + self.evp_range = evp + self.infil_range = infil + self.perco_range = perco + self.losses_range = losses + self.velRun_range = velRun + self.velSub_range = velSub + self.velSup_range = velSup + self.velStream_range = velStream + self.hu_range = Hu + self.hg_range = Hg + #Establece propiedades para ejecucion + self.npasos = npasos + self.inicio = inicio + self.ruta_lluvia = rutaLluvia + self.Qobs = Qobs + self.simelem = SimuBasinElem + #Propiedades de cruce y mutacion + self.prob_cruce = probCruce + self.prob_mutacion = probMutacion + self.rangos_mutacion = rangosMutacion + self.optimiza = MaxMinOptima + self.crowdist = CrowDist + + def __crea_calibracion__(self): + #Evp + if self.evp_range[0] <> self.evp_range[1]: + evp = np.random.uniform(self.evp_range[0], self.evp_range[1],1)[0] + else: + evp = self.evp_range[0] + #Infiltracion + if self.infil_range[0] <> self.infil_range[1]: + infil = np.random.uniform(self.infil_range[0], self.infil_range[1],1)[0] + else: + infil = self.infil_range[0] + #Percolacion + if self.perco_range[0] <> self.perco_range[1]: + perco = np.random.uniform(self.perco_range[0], self.perco_range[1],1)[0] + else: + perco = self.perco_range[0] + #Perdidas + if self.losses_range[0] <> self.losses_range[1]: + losses = np.random.uniform(self.losses_range[0], self.losses_range[1],1)[0] + else: + losses = self.losses_range[0] + #runoff + if self.velRun_range[0] <> self.velRun_range[1]: + velRun = np.random.uniform(self.velRun_range[0], self.velRun_range[1],1)[0] + else: + velRun = self.velRun_range[0] + #Vel subsuperficial + if self.velSub_range[0] <> self.velSub_range[1]: + velSub = np.random.uniform(self.velSub_range[0], self.velSub_range[1],1)[0] + else: + velSub = self.velSub_range[0] + #Vel acuifero + if self.velSup_range[0] <> self.velSup_range[1]: + velSup = np.random.uniform(self.velSup_range[0], self.velSup_range[1],1)[0] + else: + velSup = self.velSup_range[0] + #Vel cauce + if self.velStream_range[0] <> self.velStream_range[1]: + velStream = np.random.uniform(self.velStream_range[0], self.velStream_range[1],1)[0] + else: + velStream = self.velStream_range[0] + #almacenamiento hu + if self.hu_range[0] <> self.hu_range[1]: + hu = np.random.uniform(self.hu_range[0], self.hu_range[1],1)[0] + else: + hu = self.hu_range[0] + #almacenamiento hg + if self.hg_range[0] <> self.hg_range[1]: + hg = np.random.uniform(self.hg_range[0], self.hg_range[1],1)[0] + else: + hg = self.hg_range[0] + #Retorna una calibracion aleatoria + return [evp, infil, perco, losses, velRun, velSub, velSup, velStream, hu, hg] + + def __crea_ejec__(self, calibracion): + return [calibracion, self.ruta_lluvia, self.npasos, self.inicio, self.simelem] + + def __evalfunc__(self, Qsim, f1 = __eval_nash__, f2 = __eval_q_pico__): + E1 = f1(self.Qobs, Qsim) + E2 = f2(self.Qobs, Qsim) + return E1, E2 + + def __cruce__(self, indi1, indi2): + for i,u in zip(range(10), self.prob_cruce): + p = np.random.uniform(0,1,1) + if p>u: + a = indi1[i]; b = indi2[i] + indi1[i] = b + indi2[i] = a + return indi1, indi2 + + def __mutacion__(self, indi): + c = 0 + for i,u in zip(range(10), self.prob_mutacion): + p = np.random.uniform(0,1,1) + if p>u: + indi[i] = np.random.uniform(self.rangos_mutacion[c][0],self.rangos_mutacion[c][0],1)[0] + c+=1 + return indi + + def set_nsgaII(self): + self.toolbox = base.Toolbox() + creator.create("FitnessMin", base.Fitness, + weights = self.optimiza, + crowding_dist = self.crowdist) + creator.create("Individual", list, fitness=creator.FitnessMin) + self.toolbox.register("attr1", self.__crea_calibracion__) + self.toolbox.register("individual", tools.initRepeat, creator.Individual, + self.toolbox.attr1, n=1) + self.toolbox.register("population", tools.initRepeat, list, self.toolbox.individual) + self.toolbox.register("evaluate", self.__evalfunc__) + self.toolbox.register("mate", self.__cruce__) + self.toolbox.register("mutate", self.__mutacion__) + self.toolbox.register("select", tools.selNSGA2) + +class Stream: + #------------------------------------------------------ + # Subrutinas de trazado de corriente y obtencion de parametros + #------------------------------------------------------ + #Inicia la cuenca + def __init__(self,lat,lon,DEM,DIR,name='NaN'): + 'Descripcion: Traza un cauce e inicia la variable de este \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'lat : Coordenada en X del punto mas alto del cauce.\n'\ + 'lon : Coordenada en Y del punto mas alto del cauce.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas y estructura del cauce.\n'\ + #Realiza copia de los mapas y obtiene el cauce + self.DEM = DEM + self.DIR = DIR + self.ncells = cu.stream_find(lat,lon,self.DEM, + self.DIR,cu.ncols,cu.nrows) + self.structure = cu.stream_cut(self.ncells) + #------------------------------------------------------ + # Guardado shp de cauce + #------------------------------------------------------ + def Save_Stream2Map(self,ruta,DriverFormat='ESRI Shapefile', + EPSG=4326): + 'Descripcion: Guarda el cauce trazado en un mapa \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'ruta : Nombre del lugar donde se va a guardar el cauce.\n'\ + 'DriverFormat : Tipo de mapa vectorial.\n'\ + 'EPSG : Codigo de tipo de proyeccion usada (defecto 4326).\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el cauce en el formato especificado.\n'\ + #Escribe el shp del cauce + if ruta.endswith('.shp')==False: + ruta=ruta+'.shp' + spatialReference = osgeo.osr.SpatialReference() + spatialReference.ImportFromEPSG(EPSG) + driver = osgeo.ogr.GetDriverByName(DriverFormat) + if os.path.exists(ruta): + driver.DeleteDataSource(ruta) + shapeData = driver.CreateDataSource(ruta) + layer = shapeData.CreateLayer('layer1', + spatialReference, osgeo.ogr.wkbLineString) + layerDefinition = layer.GetLayerDefn() + line = osgeo.ogr.Geometry(osgeo.ogr.wkbLineString) + for x,y in zip(self.structure[0],self.structure[1]): + line.AddPoint_2D(float(x),float(y)) + feature = osgeo.ogr.Feature(layerDefinition) + feature.SetGeometry(line) + feature.SetFID(0) + layer.CreateFeature(feature) + line.Destroy() + feature.Destroy() + shapeData.Destroy() + #------------------------------------------------------ + # Plot de variables + #------------------------------------------------------ + def Plot_Profile(self,ruta=None): + 'Descripcion: Grafica el perfil del cauce trazado \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'ruta : Nombre de la imagen si se va a guardar la imagen del cauce.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el cauce en el formato especificado.\n'\ + #Escribe el shp del cauce + fig=pl.figure(facecolor='w',edgecolor='w') + ax=fig.add_subplot(111) + ax.plot(self.structure[3],self.structure[2],lw=2) + ax.set_xlabel('Distancia $[mts]$',size=14) + ax.set_ylabel('Elevacion $[m.s.n.m]$',size=14) + ax.grid(True) + if ruta is not None: + pl.savefig(ruta,bbox_inches='tight') + pl.show() + #def Plot_Map(self,ruta=None + From bb28ce856594860cde5a041cd48ab198fba77ee6 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 21 Aug 2018 15:26:37 -0500 Subject: [PATCH 107/142] cuando se edita una variable de la Tabla NC esta queda con el * propio de una variable que no ha sido almacenada en el netCDF --- qgisplugin/HydroSEDPlugin_dockwidget.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index cb5d9f5..18dd376 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -678,11 +678,14 @@ def clickEventEvalString(): Capa = self.ObjectiveLayer.value() #Solo pasa al NC si el tamano es el de la cuenca if EsCuenca: + #Busca si la variable tiene una o mas dimensiones try: self.HSutils.DicBasinNc[VarDestinoName]['var'][Capa] = np.copy(Var) except: self.HSutils.DicBasinNc[VarDestinoName]['var'] = np.copy(Var) + #Establece a la variable nueva como no guardarda self.HSutils.DicBasinNc[VarDestinoName]['saved'] = False + self.TabNC.EditedEntry(VarDestinoName, self.Tabla_Prop_NC) #Mensaje de exito self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'La variable '+VarDestinoName+' ha sido actualizada en NC', @@ -1008,7 +1011,7 @@ def handleClickEventButton_Ver_Desde_NC(): #Nombre de la variable a observar selectedItems = self.Tabla_Prop_NC.currentRow () VarName = self.Tabla_Prop_NC.item(selectedItems,0).text() - if VarName[-1] == '*': VarName = varName[:-1] + if VarName[-1] == '*': VarName = VarName[:-1] #Capa de la variable if self.SpinBoxNCLayer.value() == 0: Capa = None @@ -1079,7 +1082,7 @@ def handleClickEventButton_WMF2NC(): self.HSutils.DicBasinWMF.pop(VarName) self.HSutils.Nc2Save.append(VarName) # Mensaje de exito - self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'La variable '+VarName+' ha sido movida de WMF a NC') + self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'La variable '+VarName+' ha sido movida de la Tabla WMF a NC') def clickEventBasinUpdateNC(): '''Actualiza el archivo .nc de la cuenca con las variables cargadas en la TablaNC''' @@ -1276,6 +1279,13 @@ def DelEntry(self, KeyToDel): pos = self.TabNames.index(KeyToDel) self.TabNames.pop(pos) self.NumRows -= 1 + + def EditedEntry(self, KeyEdited, TabElement, New_or_Edited = 'Edited'): + '''Establece en la tabla visual si una entrada ha sido editada''' + #Encuentra la pos + pos = self.TabNames.index(KeyEdited) + #Edita el nombre en la tabla + TabElement.setItem(pos, 0, QTableWidgetItem(KeyEdited+'*')) def SavedEntry(self, TabElement): '''Busca los elementos de la tabla que terminen con * y se los quita, solo para From 6e34f4dc25d13a166f8cb1149ea0329da09d5654 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 21 Aug 2018 15:40:45 -0500 Subject: [PATCH 108/142] en el cargado de las variable no todas son basicas, spinBox del edito de NC se setea a 0 despues de ser utilizado --- qgisplugin/HydroSEDPluginUtils.py | 7 +++++-- qgisplugin/HydroSEDPlugin_dockwidget.py | 10 ++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 7f0ccfa..9e1e654 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -239,12 +239,15 @@ def Basin_LoadBasin(self, PathNC, LoadSim = False, LoadSed = False): self.cuenca = wmf.SimuBasin(rute = PathNC) #Cargar las variables de la cuenca a un diccionario. g = netCDF4.Dataset(PathNC) + Basicas = [True, True, False] ListGrupos = ['base','Geomorfo','Hidro'] if LoadSim: ListGrupos.append('SimHidro') + Basicas.append(True) if LoadSed: ListGrupos.append('SimSediments') - for grupoKey in ListGrupos: + Basicas.append(True) + for grupoKey,basicas in zip(ListGrupos, Basicas): #Carga los grupos de variables en donde si se tengan variables if len(g.groups[grupoKey].variables.keys())>0: #itera @@ -260,7 +263,7 @@ def Basin_LoadBasin(self, PathNC, LoadSim = False, LoadSed = False): 'tipo':g.groups[grupoKey].variables[k].dtype.name, 'shape':g.groups[grupoKey].variables[k].shape, 'raster':MapaRaster, - 'basica': True, + 'basica': basicas, 'categoria': grupoKey, 'var': g.groups[grupoKey].variables[k][:], 'saved':True}}) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 18dd376..2333458 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -658,7 +658,8 @@ def setupNcVariables(self): ListaMetodos = ['No metodo','media','min','P10','P25','P50','P75','P90','max'] map(self.ComboMethod4Conversion.addItem,ListaMetodos) #Lista de grupos posibles para una variable - ListaGrupos = ['base','Geomorfo','SimHidro','Hidro'] + #ListaGrupos = ['base','Geomorfo','SimHidro','Hidro'] + ListaGrupos = ['Geomorfo','Hidro'] map(self.ComboBoxNewWMFVarGroup.addItem, ListaGrupos) #Lista de unidades de conversion ListaUnidades = ['Celdas','Laderas','Canales'] @@ -680,7 +681,7 @@ def clickEventEvalString(): if EsCuenca: #Busca si la variable tiene una o mas dimensiones try: - self.HSutils.DicBasinNc[VarDestinoName]['var'][Capa] = np.copy(Var) + self.HSutils.DicBasinNc[VarDestinoName]['var'][Capa-1] = np.copy(Var) except: self.HSutils.DicBasinNc[VarDestinoName]['var'] = np.copy(Var) #Establece a la variable nueva como no guardarda @@ -717,7 +718,8 @@ def clickEventEvalString(): self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'La variable '+VarDestinoName+' ha sido cargado a la tabla WMF', level=QgsMessageBar.INFO, duration=3) - + #Pone de nuevo la capa destino igual a 0 + self.ObjectiveLayer.setValue(0) @@ -987,7 +989,7 @@ def handleClickEventButton_Eliminar_Desde_NC (): selectedItems = self.Tabla_Prop_NC.currentRow () ItemName = str(self.Tabla_Prop_NC.item(selectedItems,0).text()) #Revisa que todavia no este guardado - if ItemName[-1] == '*' and self.HSutils.DicBasinNc[ItemName[:-1]]['saved'] is False: + if ItemName[-1] == '*' and self.HSutils.DicBasinNc[ItemName[:-1]]['saved'] is False or self.HSutils.DicBasinNc[ItemName[:-1]]['basica'] is False: ItemName = ItemName[:-1] #Remueve de la tabla visible y de los demas elementos. self.Tabla_Prop_NC.removeRow (selectedItems) From 6d4b38f98e409be90ff64d9043c47d338d36f5db Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 21 Aug 2018 15:46:51 -0500 Subject: [PATCH 109/142] se corrige error que salia cuando se trataba de borrar una variable del NC que ya esta guardada --- qgisplugin/HydroSEDPlugin_dockwidget.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 2333458..0e3ec43 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -988,8 +988,12 @@ def handleClickEventButton_Eliminar_Desde_NC (): #Selecciona el item y su nombre selectedItems = self.Tabla_Prop_NC.currentRow () ItemName = str(self.Tabla_Prop_NC.item(selectedItems,0).text()) + UnsavedInTable = False + if ItemName[-1] == '*': + ItemName = ItemName[:-1] + UnsavedInTable = True #Revisa que todavia no este guardado - if ItemName[-1] == '*' and self.HSutils.DicBasinNc[ItemName[:-1]]['saved'] is False or self.HSutils.DicBasinNc[ItemName[:-1]]['basica'] is False: + if UnsavedInTable and self.HSutils.DicBasinNc[ItemName]['saved'] is False or self.HSutils.DicBasinNc[ItemName]['basica'] is False: ItemName = ItemName[:-1] #Remueve de la tabla visible y de los demas elementos. self.Tabla_Prop_NC.removeRow (selectedItems) From 9aaa58c3cdb04dba593ffcb7a59296483b80ad01 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 22 Aug 2018 17:11:25 -0500 Subject: [PATCH 110/142] corrige bug de actualizacion de tabal nc cuando se ha movido una variable, bug de borrado de variables de la tabla Nc --- qgisplugin/HydroSEDPlugin_dockwidget.py | 8 ++++++-- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 0e3ec43..6a29262 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -994,17 +994,20 @@ def handleClickEventButton_Eliminar_Desde_NC (): UnsavedInTable = True #Revisa que todavia no este guardado if UnsavedInTable and self.HSutils.DicBasinNc[ItemName]['saved'] is False or self.HSutils.DicBasinNc[ItemName]['basica'] is False: - ItemName = ItemName[:-1] + #ItemName = ItemName[:-1] #Remueve de la tabla visible y de los demas elementos. self.Tabla_Prop_NC.removeRow (selectedItems) self.TabNC.DelEntry(ItemName) self.HSutils.DicBasinNc.pop(ItemName) + print self.HSutils.Nc2Save + self.HSutils.Nc2Save.remove(ItemName) + print self.HSutils.Nc2Save #self.HSutils.Nc2Erase.append(ItemName) #Mensaje de exito self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'La variable '+ItemName + ' ha sido borrada') else: #Mensaje de no exito - self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'La variable '+ItemName[:-1]+' no puede ser borrada del Nc (ya esta guardada)', + self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'La variable '+ItemName+' no puede ser borrada del Nc (ya esta guardada)', level=QgsMessageBar.WARNING, duration=5) def handleClickEventButton_Actualizar_WMF_Desde_NC (): @@ -1065,6 +1068,7 @@ def handleClickEventButton_NC2WMF(): self.Tabla_Prop_NC.removeRow (selectedItems) self.TabNC.DelEntry(VarName) self.HSutils.DicBasinNc.pop(VarName) + self.HSutils.Nc2Save.remove(VarName) #Mensaje de exito self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'La variable '+VarName+' ha sido movida de NC a WMF') else: diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 58019ae..5acfe77 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -2714,7 +2714,7 @@ - + :/plugins/HydroSEDPlugin/icons/update.png:/plugins/HydroSEDPlugin/icons/update.png @@ -2764,7 +2764,7 @@ - + :/plugins/HydroSEDPlugin/icons/update.png:/plugins/HydroSEDPlugin/icons/update.png From f67b4716e71be33fbc1ef69a3559b4b7cf6554d5 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 22 Aug 2018 18:47:10 -0500 Subject: [PATCH 111/142] ls funcion de gestion de variables de NC y editables, ya puede agregar las variables por canales o ladreas con diferentes funciones --- qgisplugin/HydroSEDPluginUtils.py | 104 +++++++++++++++++------- qgisplugin/HydroSEDPlugin_dockwidget.py | 13 ++- 2 files changed, 86 insertions(+), 31 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 9e1e654..8de2a9b 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -5,6 +5,7 @@ import netCDF4 from wmf import wmf import numpy as np +import scipy.stats as stat import pandas as pd import osgeo.ogr as ogr import HydroSEDPlots as HSplots @@ -192,35 +193,37 @@ def Basin_Update(self, PathNC): #Lectura del archivo g = netCDF4.Dataset(PathNC,'a') #Inclusion de nuevas variables - for l in self.Nc2Save: - #Selecciona el grupo del nc en donde va a meter la variable - Grupo = self.DicBasinNc[l]['categoria'] - Group = g.groups[Grupo] - #mira si el grupo tiene la dimension ncells en caso de que no, la crea - try: - pos = Group.dimensions.keys().index('ncell') - except: - DimNcell = Group.createDimension('ncell',self.cuenca.ncells) - #Obtiene el nombre, tipo y variable a actualizar - nombre = l - tipo = self.DicBasinNc[l]['tipo'] - if tipo == 'float32': - tipo = 'f4' - elif tipo == 'int64': - tipo = 'i4' - Var = np.copy(self.DicBasinNc[l]['var']) - #Trata de meter la variable como algo no existente - try: - #print 'variable nueva' - VarName = Group.createVariable(nombre,tipo,('ncell',),zlib=True) - #si ya existe la variable la sobre escribe - except: - #print 'variable vieja' - VarName = Group.variables[nombre] - #guarda la variable y la actualiza en estado a guardada - VarName[:] = Var - self.DicBasinNc[l]['saved'] = True - self.Nc2Save = [] + for l in self.DicBasinNc.keys():#self.Nc2Save: + #Si la variable no esta guradada la actualiza en el nc + if self.DicBasinNc[l]['saved'] is False: + #Selecciona el grupo del nc en donde va a meter la variable + Grupo = self.DicBasinNc[l]['categoria'] + Group = g.groups[Grupo] + #mira si el grupo tiene la dimension ncells en caso de que no, la crea + try: + pos = Group.dimensions.keys().index('ncell') + except: + DimNcell = Group.createDimension('ncell',self.cuenca.ncells) + #Obtiene el nombre, tipo y variable a actualizar + nombre = l + tipo = self.DicBasinNc[l]['tipo'] + if tipo == 'float32': + tipo = 'f4' + elif tipo == 'int64': + tipo = 'i4' + Var = np.copy(self.DicBasinNc[l]['var']) + #Trata de meter la variable como algo no existente + try: + #print 'variable nueva' + VarName = Group.createVariable(nombre,tipo,('ncell',),zlib=True) + #si ya existe la variable la sobre escribe + except: + #print 'variable vieja' + VarName = Group.variables[nombre] + #guarda la variable y la actualiza en estado a guardada + VarName[:] = Var + self.DicBasinNc[l]['saved'] = True + #self.Nc2Save = [] #Cerrado del archivo nc g.close() @@ -730,5 +733,48 @@ def ExpressionParser(self, expresion): VarName = expresion[:pos].strip() AA = eval(VarName) return AA + + def BasinConvert2HillsOrChannels(self, Var, Metodo, Agregado): + '''Agrega una variable por canales o laderas de acuerdo a una metodologia''' + #Funcion de metodologias + def __fx__(x, metodo = 'media'): + if metodo == 'media': + return np.nanmean(x) + elif metodo[0] == 'P': + percentil = int(metodo[1:]) + return np.nanpercentile(x, percentil) + elif metodo == 'min': + return np.nanmin(x) + elif metodo == 'max': + return np.nanmax(x) + elif metodo == 'moda': + res = stat.mode(x) + return res.mode[0] + #Variable vacia nula + VarAgregada = np.ones(self.cuenca.ncells)*wmf.cu.nodata + #Itera por las laderas del elemento cuenca + for i in range(1,self.cuenca.nhills+1): + #Define posiciones de acuerdo a la metodologia + hacer = True + pos = np.where(self.cuenca.hills_own == i)[0] + if Agregado == 'Canales': + pos2 = np.where((self.cuenca.hills_own == i) & (self.cuenca.CellCauce == 1))[0] + if len(pos2)==0: + hacer = False + else: + pos = pos2 + #Agrega la variable + if hacer: + VarTemporal = __fx__(Var[pos], Metodo) + VarAgregada[pos] = VarTemporal + #correccion no data de canales + #if Agregado == 'Canales': + #posMalos = np.where((self.cuenca.CellCauce == 1) & (VarAgregada == wmf.cu.nodata))[0] + #print posMalos + ##posBuenos = np.where((self.cuenca.CellCauce == 1) & (VarAgregada <> wmf.cu.nodata))[0] + #VarAgregada[posMalos] = VarAgregada[posBuenos].mean() + #print VarAgregada[posMalos].min() + return VarAgregada + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 6a29262..e99d95d 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -655,7 +655,7 @@ def setupNcVariables(self): '''Conjunto de herramientas para gestionar las variables del NC''' #Llena de datos los combobox - ListaMetodos = ['No metodo','media','min','P10','P25','P50','P75','P90','max'] + ListaMetodos = ['No metodo','moda','media','min','P10','P25','P50','P75','P90','max'] map(self.ComboMethod4Conversion.addItem,ListaMetodos) #Lista de grupos posibles para una variable #ListaGrupos = ['base','Geomorfo','SimHidro','Hidro'] @@ -670,9 +670,18 @@ def clickEventEvalString(): #toma la expresion y la evalua exp = self.LineaComando.text().strip() Var = self.HSutils.ExpressionParser(exp) - print self.HSutils.DicBasinNc.keys() EsCuenca = False if Var.size == self.HSutils.cuenca.ncells: EsCuenca = True + #conversion si solo si la nueva variable tiene el ncells de la cuenca + Agregado = self.ComboConversionUnits.currentText().strip() + if EsCuenca and Agregado <> 'Celdas': + #Revisar si es laderas o canales y metodo + Metodo = self.ComboMethod4Conversion.currentText().strip() + #Agrega + Var = self.HSutils.BasinConvert2HillsOrChannels(Var, Metodo, Agregado) + SiAgrego = True + else: + SiAgrego = False #Si es al nc sobre-escribe una entrada del diccionario if self.Radio2NcVar.isChecked(): VarDestinoName = self.VarFromNC.currentText().encode() From 7898a01a9dba54b9d4b89d120949eacc9912507f Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 23 Aug 2018 11:37:21 -0500 Subject: [PATCH 112/142] guarda ya carga sets de parametros de la cuenca. --- qgisplugin/HydroSEDPluginUtils.py | 11 ++++++++++ qgisplugin/HydroSEDPlugin_dockwidget.py | 23 ++++++++++++++++++-- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 4 ++-- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 8de2a9b..d6d5015 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -25,6 +25,7 @@ def __init__(self): self.StreamsCount = 0 self.DicBasinNc = {} self.DicBasinWMF = {} + self.DicParameters = {} self.Nc2Save = [] self.Interpol_Columnas = [] @@ -272,6 +273,16 @@ def Basin_LoadBasin(self, PathNC, LoadSim = False, LoadSed = False): 'saved':True}}) self.NumDicBasinNcVariables = self.NumDicBasinNcVariables + 1 self.NumDicBasinNcVariablesBasicas = self.NumDicBasinNcVariablesBasicas + 1 + #Carga parametros de calib del modelo + if LoadSim: + #Si tiene param + if len(g.groups['Parametros'].variables.keys())>0: + for k in g.groups['Parametros'].variables.keys(): + self.DicParameters.update({k:{ + 'nombre': k, + 'var': g.groups['Parametros'].variables[k][:]}}) + print self.DicParameters + #Cierra el archivo netCDF de la cuenca g.close() #Cargar la cuenca y sus variables base a WMF self.cuenca = wmf.SimuBasin(rute = PathNC) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index e99d95d..ca04106 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -219,6 +219,10 @@ def clickEventBasin2WMF(): #Actualiza comboBox de goemorfo for k in self.HSutils.DicBasinWMF.keys(): self.ComboGeoMaskVar.addItem(k) + #Actualiza Param de claibracion + if Simhidro: + for k in self.HSutils.DicParameters.keys(): + self.ParamNamesCombo.addItem(k) def clickEventBasinLoadDivisory(): '''Carga la divisoria de la cuenca cargada a WMF''' @@ -896,6 +900,18 @@ def clickEventGetAcumRainfall(): def setupSimulation(self): '''Herramientas para gestionar la simulacion hidrologica con la cuenca cargada''' + def changeEventUpdateScalarParameters(): + '''Actualiza los parametros escalares de las tablas de acuerdo al set seleccionado''' + #Obtiene el nombre de la param seleccionada + key = self.ParamNamesCombo.currentText().strip().encode() + #Itera en el diccionario de param de la cuenca + for c,values in enumerate(self.HSutils.DicParameters[key]['var'][:11]): + codigo = 'self.Param'+str(c+1)+'.setValue('+str(values)+')' + eval(codigo) + for c,values in enumerate(self.HSutils.DicParameters[key]['var'][11:]): + codigo = 'self.ParamExp'+str(c+1)+'.setValue('+str(values)+')' + eval(codigo) + def clickEventUpdateParamMapValues(): '''Muestra en los campos de simulacion el valor medio de los mapas de simulacion''' VarNames = ['h1_max','h3_max', 'v_coef','v_coef','v_coef','v_coef','h_coef', @@ -919,7 +935,7 @@ def clickEventAddNewParamSet(): '''Agrega un nuevo conjunto de parametros en el proyecto de cuenca''' #Obtiene los parametros PathNC = self.lineEditRutaCuenca.text().strip() - ParamName = self.ParamName.text().strip() + ParamName = self.ParamName.text().strip().encode() #Itera para los parametros escalares y de sedimentos ListaParam = [] for i in range(1,12): @@ -929,10 +945,13 @@ def clickEventAddNewParamSet(): ListaParam.append(getattr(self, 'ParamExp'+str(i)).value()) #Mete el set nuevo de calibracion self.HSutils.Sim_SaveParameters(PathNC, ParamName, ListaParam) - + #Actualiza la lista de parametros + for k in self.HSutils.DicParameters.keys(): + self.ParamNamesCombo.addItem(k) self.ButtonSimCalib2Nc.clicked.connect(clickEventAddNewParamSet) self.tabPanelDockOpciones.currentChanged.connect(clickEventUpdateParamMapValues) + self.ParamNamesCombo.currentIndexChanged.connect(changeEventUpdateScalarParameters) def setupUIInputsOutputs (self): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 5acfe77..9487953 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -250,7 +250,7 @@ - 0 + 4 @@ -5415,7 +5415,7 @@ - + From 60d73d5535e623157b64f89fd6b5f984c015daee Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 23 Aug 2018 11:45:10 -0500 Subject: [PATCH 113/142] corrige bug por el cual se recargaban las listas de parametrizaciones, aparece nuevo bug con el cual arroja error cuando se guarda una entrada nueva o se re-carga la cuenca --- qgisplugin/HydroSEDPluginUtils.py | 4 ++++ qgisplugin/HydroSEDPlugin_dockwidget.py | 3 +++ 2 files changed, 7 insertions(+) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index d6d5015..7c8463f 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -709,7 +709,11 @@ def Sim_SaveParameters(self, PathNC, ParamName, scalarParam): except: Var = GrupoParam.variables[ParamName] Var[:] = scalarParam + self.DicParameters.update({ParamName: + {'nombre': ParamName, + 'var':scalarParam}}) Ejecuto = 0 + #cierra el archivo g.close() return Ejecuto diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index ca04106..0e20b67 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -221,6 +221,7 @@ def clickEventBasin2WMF(): self.ComboGeoMaskVar.addItem(k) #Actualiza Param de claibracion if Simhidro: + self.ParamNamesCombo.clear() for k in self.HSutils.DicParameters.keys(): self.ParamNamesCombo.addItem(k) @@ -905,6 +906,7 @@ def changeEventUpdateScalarParameters(): #Obtiene el nombre de la param seleccionada key = self.ParamNamesCombo.currentText().strip().encode() #Itera en el diccionario de param de la cuenca + print key for c,values in enumerate(self.HSutils.DicParameters[key]['var'][:11]): codigo = 'self.Param'+str(c+1)+'.setValue('+str(values)+')' eval(codigo) @@ -946,6 +948,7 @@ def clickEventAddNewParamSet(): #Mete el set nuevo de calibracion self.HSutils.Sim_SaveParameters(PathNC, ParamName, ListaParam) #Actualiza la lista de parametros + self.ParamNamesCombo.clear() for k in self.HSutils.DicParameters.keys(): self.ParamNamesCombo.addItem(k) From e3ac3f9e0f33f1348b8d2ba2bd61ea31be46d435 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 23 Aug 2018 14:39:11 -0500 Subject: [PATCH 114/142] corrige bug que arroja error al cargar nueva param o cargar de nuevo la cuenca --- qgisplugin/HydroSEDPlugin_dockwidget.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 0e20b67..b30bb83 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -224,6 +224,8 @@ def clickEventBasin2WMF(): self.ParamNamesCombo.clear() for k in self.HSutils.DicParameters.keys(): self.ParamNamesCombo.addItem(k) + self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'El proyecto de cuenca ha sido cargado con exito', + level=QgsMessageBar.INFO, duration=3) def clickEventBasinLoadDivisory(): '''Carga la divisoria de la cuenca cargada a WMF''' @@ -907,12 +909,13 @@ def changeEventUpdateScalarParameters(): key = self.ParamNamesCombo.currentText().strip().encode() #Itera en el diccionario de param de la cuenca print key - for c,values in enumerate(self.HSutils.DicParameters[key]['var'][:11]): - codigo = 'self.Param'+str(c+1)+'.setValue('+str(values)+')' - eval(codigo) - for c,values in enumerate(self.HSutils.DicParameters[key]['var'][11:]): - codigo = 'self.ParamExp'+str(c+1)+'.setValue('+str(values)+')' - eval(codigo) + if key <> '': + for c,values in enumerate(self.HSutils.DicParameters[key]['var'][:11]): + codigo = 'self.Param'+str(c+1)+'.setValue('+str(values)+')' + eval(codigo) + for c,values in enumerate(self.HSutils.DicParameters[key]['var'][11:]): + codigo = 'self.ParamExp'+str(c+1)+'.setValue('+str(values)+')' + eval(codigo) def clickEventUpdateParamMapValues(): '''Muestra en los campos de simulacion el valor medio de los mapas de simulacion''' @@ -951,6 +954,9 @@ def clickEventAddNewParamSet(): self.ParamNamesCombo.clear() for k in self.HSutils.DicParameters.keys(): self.ParamNamesCombo.addItem(k) + #mensaje de exito + self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'La parametrización: ' + ParamName+' se ha guardado en el proyecto', + level=QgsMessageBar.INFO, duration=3) self.ButtonSimCalib2Nc.clicked.connect(clickEventAddNewParamSet) self.tabPanelDockOpciones.currentChanged.connect(clickEventUpdateParamMapValues) From fd52ffab99c7e648c75acb4c9871a55f3758a57d Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Fri, 24 Aug 2018 16:53:21 -0500 Subject: [PATCH 115/142] =?UTF-8?q?Ok=20calculos=20de=20geomorfolog=C3=ADa?= =?UTF-8?q?=20(Kubota=20y=20Runoff),=20Grafica=20histogramas=20de=20variab?= =?UTF-8?q?les=20con=20len=20menor=20a=20ncells?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPlots.py | 2 +- qgisplugin/HydroSEDPluginUtils.py | 51 ++++++++++++++------ qgisplugin/HydroSEDPlugin_dockwidget.py | 21 ++++++-- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 12 ++--- 4 files changed, 60 insertions(+), 26 deletions(-) diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py index 9765ce9..296a136 100644 --- a/qgisplugin/HydroSEDPlots.py +++ b/qgisplugin/HydroSEDPlots.py @@ -222,7 +222,7 @@ def VarHistogram(self, var, pathFigure, ncells): '''Hace el plot de un histograma de una variable seleccionada''' #Seleccion de datos if ncells > 10000: - pos = np.random.choice(ncells, 10000) + pos = np.random.choice(len(var), 10000) else: pos = range(10000) #Obtiene la pdf y cdf de la variable diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 7c8463f..127f115 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -526,14 +526,22 @@ def Basin_GeoGetKubota(self): para el correcto calculo el susuario debe tener definidas las variables: - Hu: almacenamiento capilar maximo [mm] DicBasinNc['h1_max'] - ks: conductividad saturada del suelo [mm/s] DicBasinNc['v_coef'][1]''' - #Copia parametros de la cuenca que deben estar definidos - Hu = np.copy(self.DicBasinNc['h1_max']['var']) - ks = np.copy(self.DicBasinNc['v_coef']['var'][0]) + #Busca si los parametros de la cuenca estan definidos, si no los reemplaza con constantes para Hu y ks + if u'h1_max' in self.DicBasinNc.keys(): + Hu = np.copy(self.DicBasinNc['h1_max']['var']) + else: + Hu = 100 + if u'v_coef' in self.DicBasinNc.keys(): + ks = np.copy(self.DicBasinNc['v_coef']['var'][1]) + else: + ks = 0.003 self.cuenca.GetGeo_Cell_Basics() So = np.copy(self.cuenca.CellSlope) Factor = (wmf.cu.dxp**2.)/1000. #[m3/mm] #Calculo del coeficiente de kubota Coef = (ks*So*(wmf.cu.dxp**2.))/(3*(Hu*Factor)**2.) + Coef[np.where(np.isinf(Coef))]=np.mean(Coef[np.where(np.isfinite(Coef))]) + print Coef #Actualiza el diccionario self.DicBasinWMF.update({'Kubota_coef': {'nombre':'Kubota_coef', @@ -550,9 +558,20 @@ def Basin_GeoGetRunoff(self, e1, Epsilon): #Obtiene pendiente y param requeridos self.cuenca.GetGeo_Cell_Basics() So = np.copy(self.cuenca.CellSlope) - Man = np.copy(self.DicBasinWMF['Manning']['var']) + #Busca si la variable esta guardada en los diccionarios, si no, la reemplaza con una constante. + if 'Manning' in self.DicBasinWMF.keys() or 'Manning' in self.DicBasinNc.keys(): + try: + Man = np.copy(self.DicBasinWMF['Manning']['var']) + except: + Man = np.copy(self.DicBasinNc['Manning']['var']) + Tipo_var = Man.dtype.name + else: + Man = np.ones([self.cuenca.ncells])*0.05 + Tipo_var = 'float' #Calcula - Coef = (Epsilon/Man)*(So**2.) + Coef = (float(Epsilon)/Man)*(So**2.) + Coef[np.where(np.isinf(Coef))]=np.mean(Coef[np.where(np.isfinite(Coef))]) + print Coef Expo = (2./3.)*e1 #Pone en los diccionarios self.DicBasinWMF.update({'Runoff_coef': @@ -564,15 +583,15 @@ def Basin_GeoGetRunoff(self, e1, Epsilon): 'categoria': 'Geomorfo', 'var': np.copy(Coef), 'saved':False}}) - self.DicBasinWMF.update({'Runoff_exp': - {'nombre':'Runoff_exp', - 'tipo':Expo.dtype.name, - 'shape':Expo.shape, - 'raster':True, - 'basica': False, - 'categoria': 'Geomorfo', - 'var': np.copy(Expo), - 'saved':False}}) + #self.DicBasinWMF.update({'Runoff_exp': + #{'nombre':'Runoff_exp', + #'tipo':'float', + #'shape':len(Expo), + #'raster':True, + #'basica': False, + #'categoria': 'Geomorfo', + #'var': np.copy(Expo), + #'saved':False}}) def Basin_GeoGetParameters(self): self.cuenca.GetGeo_Parameters() @@ -710,8 +729,8 @@ def Sim_SaveParameters(self, PathNC, ParamName, scalarParam): Var = GrupoParam.variables[ParamName] Var[:] = scalarParam self.DicParameters.update({ParamName: - {'nombre': ParamName, - 'var':scalarParam}}) + {'nombre': ParamName, + 'var':scalarParam}}) Ejecuto = 0 #cierra el archivo diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index b30bb83..7a2fb06 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -397,11 +397,26 @@ def clickEventGeoRasterProp(): ListaVar.extend(['OCG_coef']) if self.checkBoxKubota.isChecked(): self.HSutils.Basin_GeoGetKubota() - ListaVar.extend(['kubota_coef']) + ListaVar.extend(['Kubota_coef']) + #mensajes de advertencia por si no han sido cargadas las variables. + if 'h1_max' not in self.HSutils.DicBasinNc.keys(): + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + 'Como no se ha cargado h1_max al NC, se estima con h1_max = 100 mm ', + level=QgsMessageBar.WARNING, duration=5) + if 'v_coef' not in self.HSutils.DicBasinNc.keys(): + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + 'Como no se ha cargado Ks al NC, se estima con Ks = 0.003 mm/s ', + level=QgsMessageBar.WARNING, duration=5) if self.checkBoxRunoff.isChecked(): - self.HSutils.Basin_GeoGetRunoff() + E1 = self.RunoffE1.value() + Epsilon1 = self.RunoffEpsi.value() + self.HSutils.Basin_GeoGetRunoff(e1=E1,Epsilon=Epsilon1) ListaVar.extend(['Runoff_coef']) - + #Mensaje de advertencia por si no ha sido cargada la variable. + if 'Manning' not in self.HSutils.DicBasinWMF.keys() and 'Manning' not in self.HSutils.DicBasinNc.keys(): + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + 'Como no se ha cargado Manning al NC, se estima con n_manning = 0.05', + level=QgsMessageBar.WARNING, duration=5) #mensaje de caso de exito self.iface.messageBar().pushInfo(u'HidroSIG:',u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.') #Actualiza la tabla de variables temporales diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 9487953..93217b8 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -294,8 +294,8 @@ 0 - -878 - 443 + 0 + 446 2018 @@ -1639,7 +1639,7 @@ 0 0 - 443 + 446 2018 @@ -2371,7 +2371,7 @@ 0 0 - 443 + 446 1918 @@ -3194,7 +3194,7 @@ 0 0 - 443 + 446 1918 @@ -4560,7 +4560,7 @@ 0 0 - 433 + 436 1918 From fc00c453de42dd509609af136f119b041b09351f Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Sun, 26 Aug 2018 14:07:25 -0500 Subject: [PATCH 116/142] Guarda el .nc con las variables de Sedimentos. Carga las variables de sedimentos a la tabla --- qgisplugin/HydroSEDPluginUtils.py | 21 +- qgisplugin/HydroSEDPlugin_dockwidget.py | 35 +- wmf/wmf.py | 3995 ++++++++++++----------- 3 files changed, 2038 insertions(+), 2013 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 127f115..8797d3c 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -254,6 +254,7 @@ def Basin_LoadBasin(self, PathNC, LoadSim = False, LoadSed = False): for grupoKey,basicas in zip(ListGrupos, Basicas): #Carga los grupos de variables en donde si se tengan variables if len(g.groups[grupoKey].variables.keys())>0: + print g.groups[grupoKey].variables.keys() #itera for k in g.groups[grupoKey].variables.keys(): #Evalua si tiene la misma cantidad de celdas y puede ser un mapa @@ -572,7 +573,7 @@ def Basin_GeoGetRunoff(self, e1, Epsilon): Coef = (float(Epsilon)/Man)*(So**2.) Coef[np.where(np.isinf(Coef))]=np.mean(Coef[np.where(np.isfinite(Coef))]) print Coef - Expo = (2./3.)*e1 + Expo = (2./3.)*e1*np.ones([self.cuenca.ncells]) #Pone en los diccionarios self.DicBasinWMF.update({'Runoff_coef': {'nombre':'Runoff_coef', @@ -583,15 +584,15 @@ def Basin_GeoGetRunoff(self, e1, Epsilon): 'categoria': 'Geomorfo', 'var': np.copy(Coef), 'saved':False}}) - #self.DicBasinWMF.update({'Runoff_exp': - #{'nombre':'Runoff_exp', - #'tipo':'float', - #'shape':len(Expo), - #'raster':True, - #'basica': False, - #'categoria': 'Geomorfo', - #'var': np.copy(Expo), - #'saved':False}}) + self.DicBasinWMF.update({'Runoff_exp': + {'nombre':'Runoff_exp', + 'tipo':Coef.dtype.name, + 'shape':Coef.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geomorfo', + 'var': np.copy(Expo), + 'saved':False}}) def Basin_GeoGetParameters(self): self.cuenca.GetGeo_Parameters() diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 7a2fb06..f974711 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -406,19 +406,22 @@ def clickEventGeoRasterProp(): if 'v_coef' not in self.HSutils.DicBasinNc.keys(): self.iface.messageBar().pushMessage (u'Hydro-SIG:', 'Como no se ha cargado Ks al NC, se estima con Ks = 0.003 mm/s ', - level=QgsMessageBar.WARNING, duration=5) + level=QgsMessageBar.WARNING, duration=3) if self.checkBoxRunoff.isChecked(): E1 = self.RunoffE1.value() Epsilon1 = self.RunoffEpsi.value() self.HSutils.Basin_GeoGetRunoff(e1=E1,Epsilon=Epsilon1) ListaVar.extend(['Runoff_coef']) + ListaVar.extend(['Runoff_exp']) #Mensaje de advertencia por si no ha sido cargada la variable. if 'Manning' not in self.HSutils.DicBasinWMF.keys() and 'Manning' not in self.HSutils.DicBasinNc.keys(): self.iface.messageBar().pushMessage (u'Hydro-SIG:', 'Como no se ha cargado Manning al NC, se estima con n_manning = 0.05', - level=QgsMessageBar.WARNING, duration=5) + level=QgsMessageBar.WARNING, duration=3) #mensaje de caso de exito - self.iface.messageBar().pushInfo(u'HidroSIG:',u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.') + self.iface.messageBar().pushMessage(u'HidroSIG:', + u'Calculo de geomorfologia distribuida realizado, revisar la tabla Variables WMF.', + level=QgsMessageBar.INFO, duration=2) #Actualiza la tabla de variables temporales for k in ListaVar: self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[k],k, self.Tabla_Prop_WMF) @@ -513,7 +516,7 @@ def clickEventAcumVar(): else: self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'No se ha logrado acumular la variable '+ VarAcumName, - level=QgsMessageBar.WARNING, duration=5) + level=QgsMessageBar.WARNING, duration=3) #Botones de ejecucion @@ -591,7 +594,7 @@ def hadleClickEventEjecutarBalance(): else: self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'No se ha logrado realizar el balance hidrológico en la cuenca', - level=QgsMessageBar.WARNING, duration=5) + level=QgsMessageBar.WARNING, duration=3) #Habilita botones de visualizacion de variables if len(self.PathOutHydro_Qmed.text()) > 2: self.Button_HidroViewQmed.setEnabled(True) @@ -636,7 +639,7 @@ def handleClickConnectRaster2WMF(): Valor = -9 if len(self.NameRaster2WMF.text())<2: self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'Debe ingresar un nombre para el mapa raster a convertir.', - level=QgsMessageBar.WARNING, duration=5) + level=QgsMessageBar.WARNING, duration=3) return 1 try: Valor = float(self.PathRaster2WMF.text()) @@ -651,7 +654,7 @@ def handleClickConnectRaster2WMF(): print Valor except: self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'Debe seleccionar un mapa raster para ser convertido a la cuenca.', - level=QgsMessageBar.WARNING, duration=5) + level=QgsMessageBar.WARNING, duration=3) return 1 else: PathRaster = self.PathRaster2WMF.text() @@ -667,7 +670,7 @@ def handleClickConnectRaster2WMF(): else: self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'El mapa raster no ha ingresado a WMF.', - level=QgsMessageBar.WARNING, duration=5) + level=QgsMessageBar.WARNING, duration=3) #Habilita botones. self.ButtonPathRaster2WMF.clicked.connect(clickEventSelectorMapaRaster) @@ -1060,7 +1063,7 @@ def handleClickEventButton_Eliminar_Desde_NC (): else: #Mensaje de no exito self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'La variable '+ItemName+' no puede ser borrada del Nc (ya esta guardada)', - level=QgsMessageBar.WARNING, duration=5) + level=QgsMessageBar.WARNING, duration=3) def handleClickEventButton_Actualizar_WMF_Desde_NC (): rows = sorted (set (index.row () for index in self.Tabla_Prop_NC.selectedIndexes ())) @@ -1086,7 +1089,7 @@ def handleClickEventButton_Ver_Desde_NC(): self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'Se cargó la variable de forma exitosa') else: self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'No fue posible cargar la variable', - level=QgsMessageBar.WARNING, duration=5) + level=QgsMessageBar.WARNING, duration=3) #Hace que el spinbox vuelva a lo normal self.SpinBoxNCLayer.setValue(0) @@ -1102,7 +1105,7 @@ def handleClickEventButton_Ver_Desde_WMF(): self.iface.messageBar().pushInfo (u'Hydro-SIG:', u'Se cargó la variable de forma exitosa') else: self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'No fue posible cargar la variable', - level=QgsMessageBar.WARNING, duration=5) + level=QgsMessageBar.WARNING, duration=3) def handleClickEventButton_NC2WMF(): '''Mueve variables de NC a WMF en la tabla.''' @@ -1127,7 +1130,7 @@ def handleClickEventButton_NC2WMF(): #Mensaje de no exito self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'La variable '+VarName+' no ha podido ser movida a WMF, ya se encuentra guardada en NC', - level=QgsMessageBar.WARNING, duration=5) + level=QgsMessageBar.WARNING, duration=3) def handleClickEventButton_WMF2NC(): '''Mueve variables de NC a WMF en la tabla.''' @@ -1188,7 +1191,7 @@ def clickEventVisualizarMapaDEM (): else: self.iface.messageBar().pushMessage (u'Hydro-SED', u'No fue posible cargar el mapa MDE. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.', - level=QgsMessageBar.WARNING, duration=5) + level=QgsMessageBar.WARNING, duration=3) def clickEventVisualizarMapaDIR (): pathMapaDIR = self.lineEditMapaDIR.text ().strip () @@ -1198,7 +1201,7 @@ def clickEventVisualizarMapaDIR (): else: self.iface.messageBar().pushMessage (u'Hydro-SED', u'No fue posible cargar el mapa DIR. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.', - level=QgsMessageBar.WARNING, duration=5) + level=QgsMessageBar.WARNING, duration=3) def clickEventCargarWMFMapaDEM (): '''Carga el mapa dDM base para WMF''' @@ -1210,7 +1213,7 @@ def clickEventCargarWMFMapaDEM (): else: self.iface.messageBar().pushMessage (u'Hydro-SED', u'No fue posible cargar el mapa MDE al WMF. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.', - level=QgsMessageBar.WARNING, duration=5) + level=QgsMessageBar.WARNING, duration=3) #Pone el nombre del codigo EPSG en el dialogo. self.LineEditEPSG.setText(self.EPSG) t = '%.1f' % self.noData @@ -1226,7 +1229,7 @@ def clickEventCargarWMFMapaDIR(): else: self.iface.messageBar().pushMessage (u'Hydro-SED', u'No fue posible cargar el mapa DIR al WMF. Verifique su ruta. Verifique su formato. Y por favor intente de nuevo.', - level=QgsMessageBar.WARNING, duration=5) + level=QgsMessageBar.WARNING, duration=3) def clickEventSelectorBinarioNC (): setupLineEditButtonOpenFileDialog (self.lineEditSelectorBinarioNC, QFileDialog) diff --git a/wmf/wmf.py b/wmf/wmf.py index 90149cf..bc25eaa 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -968,7 +968,7 @@ def GetGeo_Parameters(self,rutaParamASC=None,plotTc=False, 'Tc : Tiempo de concentracion calculado para la cuenca.\n'\ #Calcula lo que se necesita para sacar los parametros acum,longCeld,slope,Elev=cu.basin_basics(self.structure, - self.DEMvec,self.DIRvec,self.ncells) + self.DEMvec,self.DIRvec,self.ncells) Lpma,puntto=cu.basin_findlong(self.structure,self.ncells) cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod(self.structure, acum,self.umbral,self.ncells) @@ -993,18 +993,18 @@ def GetGeo_Parameters(self,rutaParamASC=None,plotTc=False, CentXY = [np.median(x),np.median(y)] #Genera un diccionario con las propiedades de la cuenca self.GeoParameters={'Area_[km2]': Area, - 'Pend_Cauce_[%]':Scau, - 'Long_Cauce_[km]': Lcau, - 'Pend_Cuenca_[%]': Scue, - 'Long_Cuenca_[km]': Lpma, - 'Hmax_[m]':Hmax, - 'Hmin_[m]':Hmin, - 'Hmean_[m]':Hmean, - 'H_Cauce_Max_[m]':HCmax, - 'Centro_[X]': CentXY[0], - 'Centro_[Y]': CentXY[1], - 'Long_tot_cauces_[km]': TotalCauces, - 'Densidad_drenaje_[km/km2]': Densidad} + 'Pend_Cauce_[%]':Scau, + 'Long_Cauce_[km]': Lcau, + 'Pend_Cuenca_[%]': Scue, + 'Long_Cuenca_[km]': Lpma, + 'Hmax_[m]':Hmax, + 'Hmin_[m]':Hmin, + 'Hmean_[m]':Hmean, + 'H_Cauce_Max_[m]':HCmax, + 'Centro_[X]': CentXY[0], + 'Centro_[Y]': CentXY[1], + 'Long_tot_cauces_[km]': TotalCauces, + 'Densidad_drenaje_[km/km2]': Densidad} if GetPerim: self.GeoParameters.update({'Perimetro_[km]':Perim}) #Calcula los tiempos de concentracion @@ -1117,67 +1117,67 @@ def GetGeo_Cell_Basics(self): self.CellCauce = np.zeros(self.ncells) self.CellCauce[self.CellAcum>self.umbral]=1 def GetGeo_StreamOrder(self, MajorBasins = False, umbral = 100, verbose = False, FirtsOrder = 1): - 'Descripcion: Obtiene el orden de horton para cada celda de \n'\ - ' cada ladera y para las celdas de cada cauce.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : no necesita nada es autocontenido.\n'\ - 'MajorBasins : Obtiene binarios con las sub-cuencas drenando.\n'\ - ' unicamente a cuencas de orden mayor (ej: todas las orden 2 que \n'\ - ' drenan a orden 3 o major).\n'\ - 'umbral: Cantidad minima de celdas para considerar canal (aplica cuando\n'\ - ' se obtienen las sub-cuencas mayores.\n'\ - 'verbose: Muestra el paso de calculo de cuencas mayores.\n'\ - 'FirtsOrder: Primer orden a partir dle cual se analizan ordenes mayores.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'CellHorton_Hill : Orden de horton de cada ladera.\n'\ - 'CellHorton_Stream : Orden de horton de cada elemento de cauce.\n'\ - #obtiene los parametros basicos por celdas - cauce,nodos_fin,n_nodos = cu.basin_subbasin_nod(self.structure,self.CellAcum,self.umbral,self.ncells) - sub_pert,sub_basin = cu.basin_subbasin_find(self.structure,nodos_fin,n_nodos,self.ncells) - sub_basins = cu.basin_subbasin_cut(n_nodos) - sub_horton,nod_horton = cu.basin_subbasin_horton(sub_basins,self.ncells,n_nodos) - self.CellHorton_Hill,sub_basin = cu.basin_subbasin_find(self.structure,nod_horton,n_nodos,self.ncells) + 'Descripcion: Obtiene el orden de horton para cada celda de \n'\ + ' cada ladera y para las celdas de cada cauce.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : no necesita nada es autocontenido.\n'\ + 'MajorBasins : Obtiene binarios con las sub-cuencas drenando.\n'\ + ' unicamente a cuencas de orden mayor (ej: todas las orden 2 que \n'\ + ' drenan a orden 3 o major).\n'\ + 'umbral: Cantidad minima de celdas para considerar canal (aplica cuando\n'\ + ' se obtienen las sub-cuencas mayores.\n'\ + 'verbose: Muestra el paso de calculo de cuencas mayores.\n'\ + 'FirtsOrder: Primer orden a partir dle cual se analizan ordenes mayores.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'CellHorton_Hill : Orden de horton de cada ladera.\n'\ + 'CellHorton_Stream : Orden de horton de cada elemento de cauce.\n'\ + #obtiene los parametros basicos por celdas + cauce,nodos_fin,n_nodos = cu.basin_subbasin_nod(self.structure,self.CellAcum,self.umbral,self.ncells) + sub_pert,sub_basin = cu.basin_subbasin_find(self.structure,nodos_fin,n_nodos,self.ncells) + sub_basins = cu.basin_subbasin_cut(n_nodos) + sub_horton,nod_horton = cu.basin_subbasin_horton(sub_basins,self.ncells,n_nodos) + self.CellHorton_Hill,sub_basin = cu.basin_subbasin_find(self.structure,nod_horton,n_nodos,self.ncells) #Obtiene el canal en la cuenca - self.CellHorton_Stream = self.CellCauce * self.CellHorton_Hill - #Obtiene las cuencas mayores - if MajorBasins: - pos = np.where(models.control>0)[1] - X,Y = cu.basin_coordxy(self.structure, self.ncells) - DictBasins = {} - for Orden in range(FirtsOrder,self.CellHorton_Hill[-1]): - #Encuentra cuencas de un orden que drenen a un orden mayor - pos2 = np.where(self.CellHorton_Stream[pos] == Orden)[0] - drena = self.ncells - self.structure[0] - pos3 = np.where(self.CellHorton_Stream[drena[pos[pos2]]] > Orden)[0] - #Las ubica en un mapa dentro d ela cuenca - SubCuencas = np.zeros(self.ncells) - cont = 1 - for x,y in zip(X[pos[pos2[pos3]]], Y[pos[pos2[pos3]]]): - #Traza la cuenca - cuTemp = SimuBasin(x,y, self.DEM, self.DIR, umbral=umbral) - #La pega en una mascara con las cub-cuencas - Map, prop = cuTemp.Transform_Basin2Map(np.ones(cuTemp.ncells),) - Map[Map == -9999] = 0 - Var = self.Transform_Map2Basin(Map, prop) - Var[Var == 0] = -9999 - Var[Var == 1] = cont - ptemp = np.where(Var == cont)[0] - #Lo pega en la mascara de sub-uencas - SubCuencas[ptemp] = SubCuencas[ptemp] + Var[ptemp] - cont+=1 - #Agrega al diccionario - DictBasins.update({str(Orden):SubCuencas}) - #Si es verbose muestra en que paso va - if verbose: - print 'Sub-cuencas orden '+str(Orden)+' calculadas' - #Traza la cuenca original para no danar la estructura de guardado - cuTemp = SimuBasin(X[-1], Y[-1], self.DEM, self.DIR, umbral = umbral) - #Retorna el diccionario con las sub-cuencas mayore - return DictBasins + self.CellHorton_Stream = self.CellCauce * self.CellHorton_Hill + #Obtiene las cuencas mayores + if MajorBasins: + pos = np.where(models.control>0)[1] + X,Y = cu.basin_coordxy(self.structure, self.ncells) + DictBasins = {} + for Orden in range(FirtsOrder,self.CellHorton_Hill[-1]): + #Encuentra cuencas de un orden que drenen a un orden mayor + pos2 = np.where(self.CellHorton_Stream[pos] == Orden)[0] + drena = self.ncells - self.structure[0] + pos3 = np.where(self.CellHorton_Stream[drena[pos[pos2]]] > Orden)[0] + #Las ubica en un mapa dentro d ela cuenca + SubCuencas = np.zeros(self.ncells) + cont = 1 + for x,y in zip(X[pos[pos2[pos3]]], Y[pos[pos2[pos3]]]): + #Traza la cuenca + cuTemp = SimuBasin(x,y, self.DEM, self.DIR, umbral=umbral) + #La pega en una mascara con las cub-cuencas + Map, prop = cuTemp.Transform_Basin2Map(np.ones(cuTemp.ncells),) + Map[Map == -9999] = 0 + Var = self.Transform_Map2Basin(Map, prop) + Var[Var == 0] = -9999 + Var[Var == 1] = cont + ptemp = np.where(Var == cont)[0] + #Lo pega en la mascara de sub-uencas + SubCuencas[ptemp] = SubCuencas[ptemp] + Var[ptemp] + cont+=1 + #Agrega al diccionario + DictBasins.update({str(Orden):SubCuencas}) + #Si es verbose muestra en que paso va + if verbose: + print 'Sub-cuencas orden '+str(Orden)+' calculadas' + #Traza la cuenca original para no danar la estructura de guardado + cuTemp = SimuBasin(X[-1], Y[-1], self.DEM, self.DIR, umbral = umbral) + #Retorna el diccionario con las sub-cuencas mayore + return DictBasins def GetGeo_IsoChrones(self,Tc,Niter=4): 'Descripcion: Obtiene el tiempo de viaje aproximado de cada \n'\ ' celda a la salida de la cuenca, para eso usa el tiempo de . \n'\ @@ -1347,7 +1347,7 @@ def GetGeo_IT(self): acum = cu.basin_acum(self.structure, self.ncells) #Obtiene la pendiente en radianes acum,longCeld,slope,Elev=cu.basin_basics(self.structure, - self.DEMvec,self.DIRvec,self.ncells) + self.DEMvec,self.DIRvec,self.ncells) slope = np.arctan(slope) slope[slope == 0] = 0.0001 return np.log((acum*cu.dxp) / np.tan(slope)) @@ -1367,7 +1367,7 @@ def GetGeo_HAND(self,umbral=1000): 'HDND : Distancia horizontal a la red de drenaje cercana [mts].\n'\ #obtiene los parametros basicos por celdas acum,longCeld,S0,Elev=cu.basin_basics(self.structure, - self.DEMvec,self.DIRvec,self.ncells) + self.DEMvec,self.DIRvec,self.ncells) cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( self.structure,acum,umbral,self.ncells) hand,hdnd,hand_destiny = cu.geo_hand(self.structure,Elev,longCeld,cauce,self.ncells) @@ -1601,27 +1601,27 @@ def GetHU_DesingStorm(self,IntTr,Dur,CN=70,plot='no',ruta=None,Tr=None, #if Tr==None or len(Tr)<>IntTr.size(): # Lista=[2.33,5,10,25,50,100,500,1000] # Tr=[l for l in Lista[:IntTr.size]] - fig=pl.figure(edgecolor='w',facecolor='w') - ax=fig.add_subplot(111) - X=np.linspace(0,Dur,lluviaTrEfect.shape[1]) - Grosor=np.arange(0.5,4,0.2) - for l,le,t,g in zip(lluviaTr,lluviaTrEfect,Tr,Grosor): - ax.plot(X,l,c='b',lw=g,label=str(t)) - if CN is not None: - for l,le,t,g in zip(lluviaTr,lluviaTrEfect,Tr,Grosor): - ax.plot(X,le,c='r',lw=g,label=str(t)) - ax.set_xlabel('Tiempo $[h]$',size=16) - ax.set_ylabel('Precipitacion $[mm]$',size=16) - ax.grid(True) - ax.tick_params(labelsize=15) - pl.legend(loc=0,ncol=2) - if ruta is not None: - pl.savefig(ruta,bbox_inches='tight') - pl.show() - if CN is not None: - return lluviaTr,np.array(lluviaTrEfect),S - else: - return lluviaTr + fig=pl.figure(edgecolor='w',facecolor='w') + ax=fig.add_subplot(111) + X=np.linspace(0,Dur,lluviaTrEfect.shape[1]) + Grosor=np.arange(0.5,4,0.2) + for l,le,t,g in zip(lluviaTr,lluviaTrEfect,Tr,Grosor): + ax.plot(X,l,c='b',lw=g,label=str(t)) + if CN is not None: + for l,le,t,g in zip(lluviaTr,lluviaTrEfect,Tr,Grosor): + ax.plot(X,le,c='r',lw=g,label=str(t)) + ax.set_xlabel('Tiempo $[h]$',size=16) + ax.set_ylabel('Precipitacion $[mm]$',size=16) + ax.grid(True) + ax.tick_params(labelsize=15) + pl.legend(loc=0,ncol=2) + if ruta is not None: + pl.savefig(ruta,bbox_inches='tight') + pl.show() + if CN is not None: + return lluviaTr,np.array(lluviaTrEfect),S + else: + return lluviaTr #Convolucion de la tormenta de diseno def GetHU_Convolution(self,Tiempo,Qhu,lluvEfect): 'Descripcion: Realia la convolucion de los hidrogramas unitarios \n'\ @@ -2165,173 +2165,173 @@ def Plot_basin(self,vec=None,Min=None, colorbar=True, colorbarLabel = None,axis=None,rutaShp=None,shpWidth = 0.7, shpColor = 'r',axloc = 111, fig = None, EPSG = 4326,backMap = False, **kwargs): - #Plotea en la terminal como mapa un vector de la cuenca - 'Funcion: Plot_basin\n'\ - 'Descripcion: Genera un plot del mapa entregado.\n'\ - 'del mismo en forma de mapa \n'\ - 'Parametros Obligatorios:.\n'\ - ' -basin: Vector con la forma de la cuenca.\n'\ - ' -vec: Vector con los valores a plotear.\n'\ - 'Parametros Opcionales:.\n'\ - ' -Min: Valor minimo del plot, determina el rango de colores.\n'\ - ' -Max: Valor maximo del plot, determina el rango de colores.\n'\ - ' -ruta: Ruta en la cual se guarda la grafica.\n'\ - ' -colorbar: Muestra o no la barra de colores, defecto: True.\n'\ - ' -figsize: tamano de la ventana donde se muestra la cuenca.\n'\ - ' -ZeroAsNaN: Convierte los valores de cero en NaN.\n'\ - ' -rutaShp: Ruta a un vectorial que se quiera mostrar en el mapa.\n'\ - ' -shpWidth: Ancho de las lineas del shp cargado.\n'\ - ' -shpColor: Color de las lineas del shp cargado.\n'\ - ' -backMap: Pone de fondo un mapa tipo arcGIS.\n'\ - 'Otros argumentos:.\n'\ - ' -axis = Entorno de grafica que contiene elementos de las figuras.\n'\ - ' -parallels = Grafica Paralelos, list-like.\n'\ - ' -parallels_labels = Etiquetas de los paralelos, list-like.\n'\ - ' labels = [left,right,top,bottom].\n'\ - ' Ejemplo:\n'\ - ' m.drawparallels(parallels,labels=[False,True,True,False]).\n'\ - ' -parallels_offset: desplazamiento de las coordenadas en X.\n'\ - ' -meridians = Grafica Meridianos, list-like.\n'\ - ' -meridians_labels = Etiquetas de los meridianos, list-like.\n'\ - ' -meridians_offset: desplazamiento de las coordeandas en Y.\n'\ - ' -per_color = Color del perimetro.\n'\ - ' -per_lw = Ancho de linea del perimetro.\n'\ - ' -colorbarLabel = Titulo del colorbar.\n'\ - ' -xy_edgecolor = Color de la linea exterior del scatter .\n'\ - ' -xy_lw = Ancho de linea del Scatter .\n'\ - ' -xy_s = Tamano del scatter.\n'\ - ' -xy_colorbar: Coloca o no barra de colores del scatter enviado (False).\n'\ - ' -show = boolean, si es True muestra la grafica.\n'\ - ' -cbar_ticks: (None) ubicacion de los ticks del cbar.\n'\ - ' -cbar_ticklabels: (None) Labels a poner sobre los ticks.\n'\ - ' -cbar_ticksize: (14) Tamano de los ticks.\n'\ - ' -ShpIsPolygon: Indica si ese shp cargado es poligono (True) o no (False).\n'\ - ' -shpAlpha: transparencia del shp (0.5).\n'\ - 'Retorno:.\n'\ - ' -Actualizacion del binario .int\n'\ - ' -m = Para continuar graficando encima del entorno creado en Basemap\n'\ - ' Ejemplo:.\n'\ - ' m = Plot_basin(**args).\n'\ - ' m.scatter(coordenada_x,coordenada_y).\n' - #Prop de la barra de colores - cbar_ticklabels = kwargs.get('cbar_ticklabels', None) - cbar_ticks = kwargs.get('cbar_ticks', None) - cbar_ticksize = kwargs.get('cbar_ticksize', 14) - show = kwargs.get('show', True) - ShpIsPolygon = kwargs.get('ShpIsPolygon',None) - shpAlpha = kwargs.get('shpAlpha',0.5) - xy_colorbar = kwargs.get('xy_colorbar', False) - if lines_spaces == 'Default': - lines_spaces = cu.dx*cu.ncols*0.05 - #El mapa - Mcols,Mrows=cu.basin_2map_find(self.structure,self.ncells) - Map,mxll,myll=cu.basin_2map(self.structure,self.structure[0] - ,Mcols,Mrows,self.ncells) - longs=np.array([mxll+0.5*cu.dx+i*cu.dx for i in range(Mcols)]) - lats=np.array([myll+0.5*cu.dy+i*cu.dy for i in range(Mrows)]) - X,Y=np.meshgrid(longs,lats) - Y=Y[::-1] - show = kwargs.get('show',True) - if fig is None: - fig = pl.figure(figsize = figsize) - if axis == None: - ax = fig.add_subplot(axloc) - else: - show = False - m = Basemap(projection='merc', - llcrnrlat=lats.min()-extra_lat, - urcrnrlat=lats.max()+extra_lat, - llcrnrlon=longs.min()-extra_long, - urcrnrlon=longs.max()+extra_long, - resolution='c', - epsg = EPSG) - parallels = kwargs.get('parallels',np.arange(lats.min(), - lats.max(),lines_spaces)) - parallels_labels = kwargs.get('parallels_labels',[1,0,0,0]) - parallel_offset = kwargs.get('parallels_offset', 0.001) - m.drawparallels(parallels, - labels = parallels_labels, - fmt="%.2f", - rotation='vertical', - xoffset=parallel_offset) - meridians = kwargs.get('meridians', np.arange(longs.min(), - longs.max(),lines_spaces)) - meridians_labels = kwargs.get('meridians_labels', [0,0,1,0]) - meridians_offset = kwargs.get('meridians_offset', 0.001) - m.drawmeridians(meridians, - labels=meridians_labels, - fmt="%.2f", - yoffset=meridians_offset) - Xm,Ym=m(X,Y) + #Plotea en la terminal como mapa un vector de la cuenca + 'Funcion: Plot_basin\n'\ + 'Descripcion: Genera un plot del mapa entregado.\n'\ + 'del mismo en forma de mapa \n'\ + 'Parametros Obligatorios:.\n'\ + ' -basin: Vector con la forma de la cuenca.\n'\ + ' -vec: Vector con los valores a plotear.\n'\ + 'Parametros Opcionales:.\n'\ + ' -Min: Valor minimo del plot, determina el rango de colores.\n'\ + ' -Max: Valor maximo del plot, determina el rango de colores.\n'\ + ' -ruta: Ruta en la cual se guarda la grafica.\n'\ + ' -colorbar: Muestra o no la barra de colores, defecto: True.\n'\ + ' -figsize: tamano de la ventana donde se muestra la cuenca.\n'\ + ' -ZeroAsNaN: Convierte los valores de cero en NaN.\n'\ + ' -rutaShp: Ruta a un vectorial que se quiera mostrar en el mapa.\n'\ + ' -shpWidth: Ancho de las lineas del shp cargado.\n'\ + ' -shpColor: Color de las lineas del shp cargado.\n'\ + ' -backMap: Pone de fondo un mapa tipo arcGIS.\n'\ + 'Otros argumentos:.\n'\ + ' -axis = Entorno de grafica que contiene elementos de las figuras.\n'\ + ' -parallels = Grafica Paralelos, list-like.\n'\ + ' -parallels_labels = Etiquetas de los paralelos, list-like.\n'\ + ' labels = [left,right,top,bottom].\n'\ + ' Ejemplo:\n'\ + ' m.drawparallels(parallels,labels=[False,True,True,False]).\n'\ + ' -parallels_offset: desplazamiento de las coordenadas en X.\n'\ + ' -meridians = Grafica Meridianos, list-like.\n'\ + ' -meridians_labels = Etiquetas de los meridianos, list-like.\n'\ + ' -meridians_offset: desplazamiento de las coordeandas en Y.\n'\ + ' -per_color = Color del perimetro.\n'\ + ' -per_lw = Ancho de linea del perimetro.\n'\ + ' -colorbarLabel = Titulo del colorbar.\n'\ + ' -xy_edgecolor = Color de la linea exterior del scatter .\n'\ + ' -xy_lw = Ancho de linea del Scatter .\n'\ + ' -xy_s = Tamano del scatter.\n'\ + ' -xy_colorbar: Coloca o no barra de colores del scatter enviado (False).\n'\ + ' -show = boolean, si es True muestra la grafica.\n'\ + ' -cbar_ticks: (None) ubicacion de los ticks del cbar.\n'\ + ' -cbar_ticklabels: (None) Labels a poner sobre los ticks.\n'\ + ' -cbar_ticksize: (14) Tamano de los ticks.\n'\ + ' -ShpIsPolygon: Indica si ese shp cargado es poligono (True) o no (False).\n'\ + ' -shpAlpha: transparencia del shp (0.5).\n'\ + 'Retorno:.\n'\ + ' -Actualizacion del binario .int\n'\ + ' -m = Para continuar graficando encima del entorno creado en Basemap\n'\ + ' Ejemplo:.\n'\ + ' m = Plot_basin(**args).\n'\ + ' m.scatter(coordenada_x,coordenada_y).\n' + #Prop de la barra de colores + cbar_ticklabels = kwargs.get('cbar_ticklabels', None) + cbar_ticks = kwargs.get('cbar_ticks', None) + cbar_ticksize = kwargs.get('cbar_ticksize', 14) + show = kwargs.get('show', True) + ShpIsPolygon = kwargs.get('ShpIsPolygon',None) + shpAlpha = kwargs.get('shpAlpha',0.5) + xy_colorbar = kwargs.get('xy_colorbar', False) + if lines_spaces == 'Default': + lines_spaces = cu.dx*cu.ncols*0.05 + #El mapa + Mcols,Mrows=cu.basin_2map_find(self.structure,self.ncells) + Map,mxll,myll=cu.basin_2map(self.structure,self.structure[0] + ,Mcols,Mrows,self.ncells) + longs=np.array([mxll+0.5*cu.dx+i*cu.dx for i in range(Mcols)]) + lats=np.array([myll+0.5*cu.dy+i*cu.dy for i in range(Mrows)]) + X,Y=np.meshgrid(longs,lats) + Y=Y[::-1] + show = kwargs.get('show',True) + if fig is None: + fig = pl.figure(figsize = figsize) + if axis == None: + ax = fig.add_subplot(axloc) + else: + show = False + m = Basemap(projection='merc', + llcrnrlat=lats.min()-extra_lat, + urcrnrlat=lats.max()+extra_lat, + llcrnrlon=longs.min()-extra_long, + urcrnrlon=longs.max()+extra_long, + resolution='c', + epsg = EPSG) + parallels = kwargs.get('parallels',np.arange(lats.min(), + lats.max(),lines_spaces)) + parallels_labels = kwargs.get('parallels_labels',[1,0,0,0]) + parallel_offset = kwargs.get('parallels_offset', 0.001) + m.drawparallels(parallels, + labels = parallels_labels, + fmt="%.2f", + rotation='vertical', + xoffset=parallel_offset) + meridians = kwargs.get('meridians', np.arange(longs.min(), + longs.max(),lines_spaces)) + meridians_labels = kwargs.get('meridians_labels', [0,0,1,0]) + meridians_offset = kwargs.get('meridians_offset', 0.001) + m.drawmeridians(meridians, + labels=meridians_labels, + fmt="%.2f", + yoffset=meridians_offset) + Xm,Ym=m(X,Y) #plotea el mapa de fondo de arcGIS - if backMap: - m.arcgisimage(server='http://server.arcgisonline.com/ArcGIS', service='World_Topo_Map', xpixels = 1500, verbose = True) + if backMap: + m.arcgisimage(server='http://server.arcgisonline.com/ArcGIS', service='World_Topo_Map', xpixels = 1500, verbose = True) #Plotea el contorno de la cuenca y la red - xp,yp = m(self.Polygon[0], self.Polygon[1]) - per_color = kwargs.get('per_color','r') - per_lw = kwargs.get('per_lw',2) - m.plot(xp, yp, color=per_color,lw=per_lw) - #hay una variable la monta - if vec is not None: - if vmin is None: - vmin = vec.min() - if vmax is None: - vmax = vec.max() - MapVec,mxll,myll=cu.basin_2map(self.structure,vec,Mcols,Mrows, - self.ncells) - MapVec[MapVec==cu.nodata]=np.nan - if ZeroAsNaN is 'si': - MapVec[MapVec == 0] = np.nan - if colorTable is not None: - cs = m.contourf(Xm, Ym, MapVec.T, 25, alpha=alpha,cmap=colorTable, - vmin=vmin,vmax=vmax) - else: - cs = m.contourf(Xm, Ym, MapVec.T, 25, alpha=alpha, - vmin=vmin,vmax=vmax) - cbar_label_size = kwargs.get('cbar_label_size',16) - if colorbar: - cbar = m.colorbar(cs,location='bottom',pad="5%") - if colorbarLabel is not None: - cbar.set_label(colorbarLabel, size = cbar_label_size) - if cbar_ticks is not None: - cbar.set_ticks(cbar_ticks) - if cbar_ticklabels is not None: - cbar.ax.set_yticklabels(cbar_ticklabels, size = cbar_ticksize,) - cbar.ax.set_xticklabels(cbar_ticklabels, size = cbar_ticksize,) - #Si hay coordenadas de algo las plotea - xy_edgecolor = kwargs.get('xy_edgecolor','black') - xy_lw = kwargs.get('xy_lw',30) - xy_s = kwargs.get('xy_s',0.5) - if xy is not None: - xc,yc=m(xy[0],xy[1]) - sx = m.scatter(xc,yc,c=xycolor, - s=xy_s, - linewidth=xy_lw, - edgecolor=xy_edgecolor) - if xy_colorbar: - pl.colorbar(sx) - #Si hay una ruta a un shp lo plotea - if rutaShp is not None: - if type(rutaShp) == str: - m.readshapefile(rutaShp, 'mapashp', linewidth = shpWidth, color = shpColor) - elif type(rutaShp) == list: - for c,shape in enumerate(rutaShp): - m.readshapefile(shape, 'mapashp', linewidth = shpWidth[c], color = shpColor[c]) - if ShpIsPolygon[c]: - patches = [] - for shape in m.mapashp: - patches.append(Polygon(np.array(shape), True)) - ax.add_collection(PatchCollection(patches, facecolor= shpColor[c], - edgecolor=shpColor[c], linewidths=shpWidth[c], zorder=2, alpha = shpAlpha[c])) - #Guarda - if ruta is not None: - pl.savefig(ruta, bbox_inches='tight',pad_inches = 0.25) - if show is True: - pl.show() - if xy is None: - return m,ax - else: - return m, ax, sx + xp,yp = m(self.Polygon[0], self.Polygon[1]) + per_color = kwargs.get('per_color','r') + per_lw = kwargs.get('per_lw',2) + m.plot(xp, yp, color=per_color,lw=per_lw) + #hay una variable la monta + if vec is not None: + if vmin is None: + vmin = vec.min() + if vmax is None: + vmax = vec.max() + MapVec,mxll,myll=cu.basin_2map(self.structure,vec,Mcols,Mrows, + self.ncells) + MapVec[MapVec==cu.nodata]=np.nan + if ZeroAsNaN is 'si': + MapVec[MapVec == 0] = np.nan + if colorTable is not None: + cs = m.contourf(Xm, Ym, MapVec.T, 25, alpha=alpha,cmap=colorTable, + vmin=vmin,vmax=vmax) + else: + cs = m.contourf(Xm, Ym, MapVec.T, 25, alpha=alpha, + vmin=vmin,vmax=vmax) + cbar_label_size = kwargs.get('cbar_label_size',16) + if colorbar: + cbar = m.colorbar(cs,location='bottom',pad="5%") + if colorbarLabel is not None: + cbar.set_label(colorbarLabel, size = cbar_label_size) + if cbar_ticks is not None: + cbar.set_ticks(cbar_ticks) + if cbar_ticklabels is not None: + cbar.ax.set_yticklabels(cbar_ticklabels, size = cbar_ticksize,) + cbar.ax.set_xticklabels(cbar_ticklabels, size = cbar_ticksize,) + #Si hay coordenadas de algo las plotea + xy_edgecolor = kwargs.get('xy_edgecolor','black') + xy_lw = kwargs.get('xy_lw',30) + xy_s = kwargs.get('xy_s',0.5) + if xy is not None: + xc,yc=m(xy[0],xy[1]) + sx = m.scatter(xc,yc,c=xycolor, + s=xy_s, + linewidth=xy_lw, + edgecolor=xy_edgecolor) + if xy_colorbar: + pl.colorbar(sx) + #Si hay una ruta a un shp lo plotea + if rutaShp is not None: + if type(rutaShp) == str: + m.readshapefile(rutaShp, 'mapashp', linewidth = shpWidth, color = shpColor) + elif type(rutaShp) == list: + for c,shape in enumerate(rutaShp): + m.readshapefile(shape, 'mapashp', linewidth = shpWidth[c], color = shpColor[c]) + if ShpIsPolygon[c]: + patches = [] + for shape in m.mapashp: + patches.append(Polygon(np.array(shape), True)) + ax.add_collection(PatchCollection(patches, facecolor= shpColor[c], + edgecolor=shpColor[c], linewidths=shpWidth[c], zorder=2, alpha = shpAlpha[c])) + #Guarda + if ruta is not None: + pl.savefig(ruta, bbox_inches='tight',pad_inches = 0.25) + if show is True: + pl.show() + if xy is None: + return m,ax + else: + return m, ax, sx #Grafica de plot para montar en paginas web o presentaciones def Plot_basinClean(self, vec, ruta = None, umbral = 0.0, vmin = 0.0, vmax = None, show_cbar = False, **kwargs): @@ -2570,82 +2570,82 @@ def Plot_Tc(self,ruta=None,figsize=(8,6),**kwargs): pl.show() #Plot de cuace ppal def PlotPpalStream(self,ruta = None, figsize = (8,6),axis=None,**kwargs): - '''GRAFICA EL PERFIL DEL CAUCE PRINCIPAL - =================================================================================== - ARGUMENTO - DEFAULT - DESCRIPCIoN - TIPO - ruta - None - Ruta para guardar grafica - str - figsize - (8,6) - Tamano de la figura - tuple - axis - None - Axis o entorno para graficar - matplotlib.axes - show - True - Muestra grafica - bool - fontsize - 16 - Tamano de letra - int,float - ylabel - Elevacion $[m.s.n.m]$ - Etiqueta de la ordenada - str - cbar_label - None - Etiqueta del colorbar - str - =================================================================================== ''' - show = kwargs.get('show',True) - if axis == None: - fig = pl.figure(figsize = figsize, edgecolor = 'w',facecolor = 'w') - ax = fig.add_subplot(111) - else: - show=False - ax = axis - pl.scatter(self.ppal_stream[1]/1000.0, - self.ppal_stream[0], - c = self.ppal_slope, - linewidth = 0) - ax.grid(True) - fontsize = kwargs.get('fontsize',16) - ylabel = kwargs.get('ylabel','Elevacion $[m.s.n.m]$') - ax.set_xlabel('Distancia $[km]$',size = fontsize) - ax.set_ylabel(ylabel,size = fontsize) - ax.tick_params(labelsize = 14) - cb = pl.colorbar() - cbar_label = kwargs.get('cbar_label',None) - if cbar_label is not None: - cb.set_label(cbar_label,fontsize=fontsize) - if ruta is not None: - pl.savefig(ruta,bbox_inches='tight') - if show == True: - pl.show() - return ax,cb + '''GRAFICA EL PERFIL DEL CAUCE PRINCIPAL + =================================================================================== + ARGUMENTO - DEFAULT - DESCRIPCIoN - TIPO + ruta - None - Ruta para guardar grafica - str + figsize - (8,6) - Tamano de la figura - tuple + axis - None - Axis o entorno para graficar - matplotlib.axes + show - True - Muestra grafica - bool + fontsize - 16 - Tamano de letra - int,float + ylabel - Elevacion $[m.s.n.m]$ - Etiqueta de la ordenada - str + cbar_label - None - Etiqueta del colorbar - str + =================================================================================== ''' + show = kwargs.get('show',True) + if axis == None: + fig = pl.figure(figsize = figsize, edgecolor = 'w',facecolor = 'w') + ax = fig.add_subplot(111) + else: + show=False + ax = axis + pl.scatter(self.ppal_stream[1]/1000.0, + self.ppal_stream[0], + c = self.ppal_slope, + linewidth = 0) + ax.grid(True) + fontsize = kwargs.get('fontsize',16) + ylabel = kwargs.get('ylabel','Elevacion $[m.s.n.m]$') + ax.set_xlabel('Distancia $[km]$',size = fontsize) + ax.set_ylabel(ylabel,size = fontsize) + ax.tick_params(labelsize = 14) + cb = pl.colorbar() + cbar_label = kwargs.get('cbar_label',None) + if cbar_label is not None: + cb.set_label(cbar_label,fontsize=fontsize) + if ruta is not None: + pl.savefig(ruta,bbox_inches='tight') + if show == True: + pl.show() + return ax,cb #Plot de histograma de pendientes def PlotSlopeHist(self,ruta=None,bins=[0,2,0.2], - Nsize=1000, figsize = (8,6), fig = None, show = True,**kwargs): - '''Hace un plot del histograma de distribucion de - pendientes en la cuenca. - Requiere: - - ruta: ruta de guaradado de la imagen, - - bins: rango inferior, superior y paso para intervalos. - - Nsize: Cantidad de datos a usar para realizar el histograma. - Retorna: - - Plot. - - Eje del plot si se quiere continuar editando - **kwargs: - - lw: ancho de la linea. - - axissize: tamano de los ejes - - labelsize: tamano de los nombres''' - lw = kwargs.get('lw',3) - labelsize = kwargs.get('labelsize',16) - axissize = kwargs.get('axissize',15) - if Nsize>self.ncells: - Nsize = self.ncells - pos = np.random.choice(self.ncells,Nsize) - h,b=np.histogram(self.CellSlope[pos],bins=np.arange(bins[0],bins[1],bins[2])) - b=(b[:-1]+b[1:])/2.0 - h=h.astype(float)/h.astype(float).sum() - if fig is None: - fig=pl.figure(figsize = figsize, edgecolor='w',facecolor='w') - ax=fig.add_subplot(111) - ax.plot(b,h,lw=lw) - ax.grid(True) - ax.tick_params(labelsize = axissize) - ax.set_xlabel('Pendiente',size=labelsize) - ax.set_ylabel('$pdf [\%]$',size=labelsize) - if ruta is not None: - pl.savefig(ruta,bbox_inches='tight') - if show: - pl.show() - return ax - + Nsize=1000, figsize = (8,6), fig = None, show = True,**kwargs): + '''Hace un plot del histograma de distribucion de + pendientes en la cuenca. + Requiere: + - ruta: ruta de guaradado de la imagen, + - bins: rango inferior, superior y paso para intervalos. + - Nsize: Cantidad de datos a usar para realizar el histograma. + Retorna: + - Plot. + - Eje del plot si se quiere continuar editando + **kwargs: + - lw: ancho de la linea. + - axissize: tamano de los ejes + - labelsize: tamano de los nombres''' + lw = kwargs.get('lw',3) + labelsize = kwargs.get('labelsize',16) + axissize = kwargs.get('axissize',15) + if Nsize>self.ncells: + Nsize = self.ncells + pos = np.random.choice(self.ncells,Nsize) + h,b=np.histogram(self.CellSlope[pos],bins=np.arange(bins[0],bins[1],bins[2])) + b=(b[:-1]+b[1:])/2.0 + h=h.astype(float)/h.astype(float).sum() + if fig is None: + fig=pl.figure(figsize = figsize, edgecolor='w',facecolor='w') + ax=fig.add_subplot(111) + ax.plot(b,h,lw=lw) + ax.grid(True) + ax.tick_params(labelsize = axissize) + ax.set_xlabel('Pendiente',size=labelsize) + ax.set_ylabel('$pdf [\%]$',size=labelsize) + if ruta is not None: + pl.savefig(ruta,bbox_inches='tight') + if show: + pl.show() + return ax + #Plot de histograma de tiempos de viajes en la cuenca def Plot_Travell_Hist(self,ruta=None,Nint=10.0): #comparacion histogramas de tiempos de respuestas @@ -2708,1668 +2708,1689 @@ def Plot_Hipsometric(self,ruta=None,ventana=10,normed=False, pl.show() class SimuBasin(Basin): - def __init__(self,lat=None,lon=None,DEM=None,DIR=None,rute = None, name='NaN',stream=None, + def __init__(self,lat=None,lon=None,DEM=None,DIR=None,rute = None, name='NaN',stream=None, umbral=500,useCauceMap = None, noData=-999,modelType='cells',SimSed=False,SimSlides=False,dt=60, SaveStorage='no',SaveSpeed='no',retorno = 0, SeparateFluxes = 'no',SeparateRain='no',ShowStorage='no', SimFloods = 'no', controlNodos = True, storageConstant = 0.001): - 'Descripcion: Inicia un objeto para simulacion \n'\ - ' el objeto tiene las propieades de una cuenca con. \n'\ - ' la diferencia de que inicia las variables requeridas. \n'\ - ' para simular. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'lat : Coordenada en X de la salida de la cuenca.\n'\ - 'lon : Coordenada en Y de la salida de la cuenca.\n'\ - 'name : Nombre con el que se va a conocer la cuenca.\n'\ - ' (defecto = NaN).\n'\ - 'stream : Opcional, si se coloca, las coordenadas no tienen.\n'\ - ' que ser exactas, estas se van a corregir para ubicarse.\n'\ - ' en el punto mas cercano dentro de la corriente, este.\n'\ - ' debe ser un objeto del tipo stream.\n'\ - 'useCauceMap: Utiliza un mapa de 1 y 0 representando las celdas que.\n'\ - ' son canal, con este mapa corrige el punto de trazado de la cuenca.\n'\ - 'umbral : Cantidad minima de celdas para la creacion de cauces.\n'\ - ' (defecto = 500 ).\n'\ - 'noData : Valor correspondiente a valores sin dato (defecto = -999).\n'\ - 'modelType : Tipo de modelo, por celdas o por laderas (defecto = cells).\n'\ - ' opciones: .\n'\ - ' cells => modela por celdas.\n'\ - ' hills => modela por laderas.\n'\ - 'SimSed : Simula si, o no simula sedimentos no.\n'\ - 'SimSlides : Simula si, o no simula deslizamientos no.\n'\ - 'dt : Tamano del intervlao de tiempo en que trabaj el modelo (defecto=60seg) [secs].\n'\ - 'SaveStorage : Guarda o no el almacenamiento.\n'\ - 'SaveSpeed : Guarda o no mapas de velocidad.\n'\ - 'rute : por defecto es None, si se coloca la ruta, el programa no.\n'\ - ' hace una cuenca, si no que trata de leer una en el lugar especificado.\n'\ - ' Ojo: la cuenca debio ser guardada con la funcion: Save_SimuBasin().\n'\ - 'retorno : (defecto = 0), si es cero no se considera alm maximo en .\n'\ - ' el tanque 3, si es 1, si se considera.\n'\ - 'SeparateFluxes : Separa el flujo en base, sub-superficial y escorrentia.\n'\ - 'SeparateRain : Separa el flujo proveniente de convectivas y de estratiformes.\n'\ - 'ShowStorage : Muestra en la salida del modelo el alm promedio en cada uno de los tanques.\n'\ - 'controlNodos: Coloca por defecto puntos de control en todos los nodos (True) o no (False).\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con las variables iniciadas.\n'\ - #Variables de radar - self.radarDates = [] - self.radarPos = [] - self.radarMeanRain = [] - self.radarCont = 1 - #Si no hay ruta y el global del codigo EPSG existe, traza la cuenca - if rute is None and int(Global_EPSG) > 0: - #Si se entrega cauce corrige coordenadas - if stream is not None: - error=[] - for i in stream.structure.T: - error.append( np.sqrt((lat-i[0])**2+(lon-i[1])**2) ) - loc=np.argmin(error) - lat=stream.structure[0,loc] - lon=stream.structure[1,loc] - if useCauceMap is not None and useCauceMap.shape == DEM.shape: - lat,lon = cu.stream_find_to_corr(lat,lon,DEM,DIR,useCauceMap, - cu.ncols,cu.nrows) - #copia la direccion de los mapas de DEM y DIR, para no llamarlos mas - self.name=name - self.DEM=DEM - self.DIR=DIR - self.modelType=modelType - self.nodata=noData - self.umbral = umbral - self.epsg = Global_EPSG - #Traza la cuenca - self.ncells = cu.basin_find(lat,lon,DIR, - cu.ncols,cu.nrows) - self.structure = cu.basin_cut(self.ncells) - #Obtiene las propiedades para el tamano de la cuenca. - self.DEMvec = self.Transform_Map2Basin(DEM, - [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy]) - self.DIRvec = self.Transform_Map2Basin(DIR, - [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy]) - acum=cu.basin_acum(self.structure,self.ncells) - cauce,nodos,self.nhills = cu.basin_subbasin_nod(self.structure - ,acum,umbral,self.ncells) - self.hills_own,sub_basin = cu.basin_subbasin_find(self.structure, - nodos,self.nhills,self.ncells) - self.hills = cu.basin_subbasin_cut(self.nhills) - models.drena=self.structure - #Determina la cantidad de celdas para alojar - if modelType=='cells': - N=self.ncells - elif modelType=='hills': - N=self.nhills - #aloja variables - models.v_coef = np.ones((4,N)) - models.h_coef = np.ones((4,N)) - models.v_exp = np.ones((4,N)) - models.h_exp = np.ones((4,N)) - models.max_capilar = np.ones((1,N)) - models.max_gravita = np.ones((1,N)) - models.storage = np.zeros((5,N)) - models.dt = dt - models.calc_niter = 5 - models.retorno = 0 - models.verbose = 0 - #Define los puntos de control - models.control = np.zeros((1,N)) - #Si se da la opcion de puntos de control en toda la red lo hace - if controlNodos: - if modelType == 'cells': - self.GetGeo_Cell_Basics() - cauce,nodos,n_nodos = cu.basin_subbasin_nod( - self.structure, - self.CellAcum, - umbral, - self.ncells) - pos = np.where(nodos<>0)[0] - x,y = cu.basin_coordxy(self.structure,self.ncells) - idsOrd,xy = self.set_Control(np.vstack([x[pos],y[pos]]),nodos[pos]) - elif modelType == 'hills': - models.control = np.ones((1,self.nhills)) * nodos[nodos<>0] - #Puntos de control de humedad sin control por defecto - models.control_h = np.zeros((1,N)) - #Define las simulaciones que se van a hacer - models.sim_sediments=0 - if SimSed is 'si': - models.sim_sediments=1 - models.sim_slides=0 - if SimSlides: - models.sim_slides=1 - models.save_storage=0 - if SaveStorage is 'si': - models.save_storage=1 - models.save_speed=0 - if SaveSpeed is 'si': - models.save_speed=1 - models.separate_fluxes = 0 - if SeparateFluxes is 'si': - models.separate_fluxes = 1 - models.separate_rain = 0 - if SeparateRain is 'si': - models.separate_rain = 1 - models.show_storage = 0 - if ShowStorage is 'si': - models.show_storage = 1 - if SimFloods == 'si': - models.sim_floods = 1 - models.storage_constant = storageConstant - #Determina que la geomorfologia no se ha estimado - self.isSetGeo = False - # si hay tura lee todo lo de la cuenca - elif rute is not None: - self.__Load_SimuBasin(rute, SimSlides) - # Obtiene la envolvente de la cuenca - self.__GetBasinPolygon__() + 'Descripcion: Inicia un objeto para simulacion \n'\ + ' el objeto tiene las propieades de una cuenca con. \n'\ + ' la diferencia de que inicia las variables requeridas. \n'\ + ' para simular. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'lat : Coordenada en X de la salida de la cuenca.\n'\ + 'lon : Coordenada en Y de la salida de la cuenca.\n'\ + 'name : Nombre con el que se va a conocer la cuenca.\n'\ + ' (defecto = NaN).\n'\ + 'stream : Opcional, si se coloca, las coordenadas no tienen.\n'\ + ' que ser exactas, estas se van a corregir para ubicarse.\n'\ + ' en el punto mas cercano dentro de la corriente, este.\n'\ + ' debe ser un objeto del tipo stream.\n'\ + 'useCauceMap: Utiliza un mapa de 1 y 0 representando las celdas que.\n'\ + ' son canal, con este mapa corrige el punto de trazado de la cuenca.\n'\ + 'umbral : Cantidad minima de celdas para la creacion de cauces.\n'\ + ' (defecto = 500 ).\n'\ + 'noData : Valor correspondiente a valores sin dato (defecto = -999).\n'\ + 'modelType : Tipo de modelo, por celdas o por laderas (defecto = cells).\n'\ + ' opciones: .\n'\ + ' cells => modela por celdas.\n'\ + ' hills => modela por laderas.\n'\ + 'SimSed : Simula si, o no simula sedimentos no.\n'\ + 'SimSlides : Simula si, o no simula deslizamientos no.\n'\ + 'dt : Tamano del intervlao de tiempo en que trabaj el modelo (defecto=60seg) [secs].\n'\ + 'SaveStorage : Guarda o no el almacenamiento.\n'\ + 'SaveSpeed : Guarda o no mapas de velocidad.\n'\ + 'rute : por defecto es None, si se coloca la ruta, el programa no.\n'\ + ' hace una cuenca, si no que trata de leer una en el lugar especificado.\n'\ + ' Ojo: la cuenca debio ser guardada con la funcion: Save_SimuBasin().\n'\ + 'retorno : (defecto = 0), si es cero no se considera alm maximo en .\n'\ + ' el tanque 3, si es 1, si se considera.\n'\ + 'SeparateFluxes : Separa el flujo en base, sub-superficial y escorrentia.\n'\ + 'SeparateRain : Separa el flujo proveniente de convectivas y de estratiformes.\n'\ + 'ShowStorage : Muestra en la salida del modelo el alm promedio en cada uno de los tanques.\n'\ + 'controlNodos: Coloca por defecto puntos de control en todos los nodos (True) o no (False).\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas.\n'\ + #Variables de radar + self.radarDates = [] + self.radarPos = [] + self.radarMeanRain = [] + self.radarCont = 1 + #Si no hay ruta y el global del codigo EPSG existe, traza la cuenca + if rute is None and int(Global_EPSG) > 0: + #Si se entrega cauce corrige coordenadas + if stream is not None: + error=[] + for i in stream.structure.T: + error.append( np.sqrt((lat-i[0])**2+(lon-i[1])**2) ) + loc=np.argmin(error) + lat=stream.structure[0,loc] + lon=stream.structure[1,loc] + if useCauceMap is not None and useCauceMap.shape == DEM.shape: + lat,lon = cu.stream_find_to_corr(lat,lon,DEM,DIR,useCauceMap, + cu.ncols,cu.nrows) + #copia la direccion de los mapas de DEM y DIR, para no llamarlos mas + self.name=name + self.DEM=DEM + self.DIR=DIR + self.modelType=modelType + self.nodata=noData + self.umbral = umbral + self.epsg = Global_EPSG + #Traza la cuenca + self.ncells = cu.basin_find(lat,lon,DIR, + cu.ncols,cu.nrows) + self.structure = cu.basin_cut(self.ncells) + #Obtiene las propiedades para el tamano de la cuenca. + self.DEMvec = self.Transform_Map2Basin(DEM, + [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy]) + self.DIRvec = self.Transform_Map2Basin(DIR, + [cu.ncols, cu.nrows, cu.xll, cu.yll, cu.dx, cu.dy]) + acum=cu.basin_acum(self.structure,self.ncells) + cauce,nodos,self.nhills = cu.basin_subbasin_nod(self.structure + ,acum,umbral,self.ncells) + self.hills_own,sub_basin = cu.basin_subbasin_find(self.structure, + nodos,self.nhills,self.ncells) + self.hills = cu.basin_subbasin_cut(self.nhills) + models.drena=self.structure + #Determina la cantidad de celdas para alojar + if modelType=='cells': + N=self.ncells + elif modelType=='hills': + N=self.nhills + #aloja variables + models.v_coef = np.ones((4,N)) + models.h_coef = np.ones((4,N)) + models.v_exp = np.ones((4,N)) + models.h_exp = np.ones((4,N)) + models.max_capilar = np.ones((1,N)) + models.max_gravita = np.ones((1,N)) + models.storage = np.zeros((5,N)) + models.dt = dt + models.calc_niter = 5 + models.retorno = 0 + models.verbose = 0 + #Define los puntos de control + models.control = np.zeros((1,N)) + #Si se da la opcion de puntos de control en toda la red lo hace + if controlNodos: + if modelType == 'cells': + self.GetGeo_Cell_Basics() + cauce,nodos,n_nodos = cu.basin_subbasin_nod( + self.structure, + self.CellAcum, + umbral, + self.ncells) + pos = np.where(nodos<>0)[0] + x,y = cu.basin_coordxy(self.structure,self.ncells) + idsOrd,xy = self.set_Control(np.vstack([x[pos],y[pos]]),nodos[pos]) + elif modelType == 'hills': + models.control = np.ones((1,self.nhills)) * nodos[nodos<>0] + #Puntos de control de humedad sin control por defecto + models.control_h = np.zeros((1,N)) + #Define las simulaciones que se van a hacer + models.sim_sediments=0 + if SimSed is 'si': + models.sim_sediments=1 + models.sim_slides=0 + if SimSlides: + models.sim_slides=1 + models.save_storage=0 + if SaveStorage is 'si': + models.save_storage=1 + models.save_speed=0 + if SaveSpeed is 'si': + models.save_speed=1 + models.separate_fluxes = 0 + if SeparateFluxes is 'si': + models.separate_fluxes = 1 + models.separate_rain = 0 + if SeparateRain is 'si': + models.separate_rain = 1 + models.show_storage = 0 + if ShowStorage is 'si': + models.show_storage = 1 + if SimFloods == 'si': + models.sim_floods = 1 + models.storage_constant = storageConstant + #Determina que la geomorfologia no se ha estimado + self.isSetGeo = False + # si hay tura lee todo lo de la cuenca + elif rute is not None: + self.__Load_SimuBasin(rute, SimSlides) + # Obtiene la envolvente de la cuenca + self.__GetBasinPolygon__() - def __Load_SimuBasin(self,ruta, sim_slides = False): - 'Descripcion: Lee una cuenca posteriormente guardada\n'\ - ' La cuenca debio ser guardada con SimuBasin.save_SimuBasin\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'ruta : ruta donde se encuentra ubicada la cuenca guardada\n'\ - 'Opcionales\n'\ - '----------\n'\ - 'sim_slides : (False, True) Carga variables de modelos de deslizamientos previmaente guardadas.\n'\ - 'sim_sed : (False, True) Carga variables de modelo de sedimentos previamente guardadas\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : La cuenca con sus parametros ya cargada.\n'\ - #Abre el archivo binario de la cuenca - self.rutaNC = ruta - gr = netcdf.Dataset(ruta,'a') - #obtiene las prop de la cuenca - self.name = gr.nombre - self.modelType = gr.modelType.encode() - self.nodata = gr.noData - self.umbral = gr.umbral - self.ncells = gr.ncells - self.nhills = gr.nhills - self.epsg = gr.epsg - models.dt = gr.dt - models.dxp = gr.dxp - models.retorno = gr.retorno - try: - models.storage_constant = gr.storageConst - except: - models.storage_constant = 0.0 - #Si carga deslizamientos - if sim_slides: - models.sim_slides = 1 - models.sl_fs = gr.sl_fs - models.gullienogullie = gr.sl_gullie - models.sl_gammaw = gr.sl_gammaw - #Nueva metodologia de geoespacial de la cuenca - cu.ncols = gr.ncols - cu.nrows = gr.nrows - cu.xll = gr.xll - cu.yll = gr.yll - cu.dx = gr.dx - cu.dy = gr.dy - cu.dxp = gr.dxp - cu.nodata = gr.noData - #de acuerdo al tipo de modeloe stablece numero de elem - if self.modelType[0] is 'c': - N = self.ncells - elif self.modelType[0] is 'h': - N = self.nhills - #Obtiene las variables base - GrupoBase = gr.groups['base'] - self.structure = GrupoBase.variables['structure'][:] - self.hills = GrupoBase.variables['hills'][:] - self.hills_own = GrupoBase.variables['hills_own'][:] - #Obtiene las geomorfologicas - GrupoGeo = gr.groups['Geomorfo'] - self.DEMvec = GrupoGeo.variables['DEM'][:] - self.DIRvec = GrupoGeo.variables['DIR'][:] - self.DEM = self.Transform_Basin2Map(self.DEMvec) - self.DIR = self.Transform_Basin2Map(self.DIRvec) - #obtiene las propieades del modelo - GrupoSimHid = gr.groups['SimHidro'] - models.h_coef = np.ones((4,N)) * GrupoSimHid.variables['h_coef'][:] - models.v_coef = np.ones((4,N)) * GrupoSimHid.variables['v_coef'][:] - models.h_exp = np.ones((4,N)) * GrupoSimHid.variables['h_exp'][:] - models.v_exp = np.ones((4,N)) * GrupoSimHid.variables['v_exp'][:] - models.max_capilar = np.ones((1,N)) * GrupoSimHid.variables['h1_max'][:] - models.max_gravita = np.ones((1,N)) * GrupoSimHid.variables['h3_max'][:] - #Variable de drena de acuerdo al tipo de modelo - if self.modelType[0] is 'c': - models.drena = np.ones((3,N)) *GrupoSimHid.variables['drena'][:] - elif self.modelType[0] is 'h': - models.drena = np.ones((1,N)) * GrupoSimHid.variables['drena'][:] - models.unit_type = np.ones((1,N)) * GrupoSimHid.variables['unit_type'][:] - models.hill_long = np.ones((1,N)) * GrupoSimHid.variables['hill_long'][:] - models.hill_slope = np.ones((1,N)) * GrupoSimHid.variables['hill_slope'][:] - models.stream_long = np.ones((1,N)) * GrupoSimHid.variables['stream_long'][:] - models.stream_slope = np.ones((1,N)) * GrupoSimHid.variables['stream_slope'][:] - models.stream_width = np.ones((1,N)) * GrupoSimHid.variables['stream_width'][:] - models.elem_area = np.ones((1,N)) * GrupoSimHid.variables['elem_area'][:] - models.speed_type = np.ones((3)) * GrupoSimHid.variables['speed_type'][:] - models.storage = np.ones((5,N)) * GrupoSimHid.variables['storage'][:] - models.control = np.ones((1,N)) * GrupoSimHid.variables['control'][:] - models.control_h = np.ones((1,N)) * GrupoSimHid.variables['control_h'][:] - - #Propiedades de deslizamientos - if sim_slides: - GrupoSlides = gr.groups['SimSlides'] - models.sl_gammas = np.ones((1,N)) * GrupoSlides.variables['gamma_soil'][:] - models.sl_cohesion = np.ones((1,N)) * GrupoSlides.variables['cohesion'][:] - models.sl_frictionangle = np.ones((1,N)) * GrupoSlides.variables['friction_angle'][:] - models.sl_radslope = np.ones((1,N)) * GrupoSlides.variables['rad_slope'][:] - models.sl_zs = np.ones((1,N)) * GrupoSlides.variables['z_soil'][:] - #Cierra el archivo - gr.close() - #Determina que por defecto debe estar set la geomorfologia - self.isSetGeo = True + def __Load_SimuBasin(self,ruta, sim_slides = False): + 'Descripcion: Lee una cuenca posteriormente guardada\n'\ + ' La cuenca debio ser guardada con SimuBasin.save_SimuBasin\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'ruta : ruta donde se encuentra ubicada la cuenca guardada\n'\ + 'Opcionales\n'\ + '----------\n'\ + 'sim_slides : (False, True) Carga variables de modelos de deslizamientos previmaente guardadas.\n'\ + 'sim_sed : (False, True) Carga variables de modelo de sedimentos previamente guardadas\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : La cuenca con sus parametros ya cargada.\n'\ + #Abre el archivo binario de la cuenca + self.rutaNC = ruta + gr = netcdf.Dataset(ruta,'a') + #obtiene las prop de la cuenca + self.name = gr.nombre + self.modelType = gr.modelType.encode() + self.nodata = gr.noData + self.umbral = gr.umbral + self.ncells = gr.ncells + self.nhills = gr.nhills + self.epsg = gr.epsg + models.dt = gr.dt + models.dxp = gr.dxp + models.retorno = gr.retorno + try: + models.storage_constant = gr.storageConst + except: + models.storage_constant = 0.0 + #Si carga deslizamientos + if sim_slides: + models.sim_slides = 1 + models.sl_fs = gr.sl_fs + models.gullienogullie = gr.sl_gullie + models.sl_gammaw = gr.sl_gammaw + #Nueva metodologia de geoespacial de la cuenca + cu.ncols = gr.ncols + cu.nrows = gr.nrows + cu.xll = gr.xll + cu.yll = gr.yll + cu.dx = gr.dx + cu.dy = gr.dy + cu.dxp = gr.dxp + cu.nodata = gr.noData + #de acuerdo al tipo de modeloe stablece numero de elem + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + #Obtiene las variables base + GrupoBase = gr.groups['base'] + self.structure = GrupoBase.variables['structure'][:] + self.hills = GrupoBase.variables['hills'][:] + self.hills_own = GrupoBase.variables['hills_own'][:] + #Obtiene las geomorfologicas + GrupoGeo = gr.groups['Geomorfo'] + self.DEMvec = GrupoGeo.variables['DEM'][:] + self.DIRvec = GrupoGeo.variables['DIR'][:] + self.DEM = self.Transform_Basin2Map(self.DEMvec) + self.DIR = self.Transform_Basin2Map(self.DIRvec) + #obtiene las propieades del modelo + GrupoSimHid = gr.groups['SimHidro'] + models.h_coef = np.ones((4,N)) * GrupoSimHid.variables['h_coef'][:] + models.v_coef = np.ones((4,N)) * GrupoSimHid.variables['v_coef'][:] + models.h_exp = np.ones((4,N)) * GrupoSimHid.variables['h_exp'][:] + models.v_exp = np.ones((4,N)) * GrupoSimHid.variables['v_exp'][:] + models.max_capilar = np.ones((1,N)) * GrupoSimHid.variables['h1_max'][:] + models.max_gravita = np.ones((1,N)) * GrupoSimHid.variables['h3_max'][:] + + #Propiedades de Sedimentos + GrupoSimSed = gr.groups['SimSediments'] + models.krus = np.ones((1,N))*GrupoSimSed.variables['Krus'][:] + models.prus = np.ones((1,N))*GrupoSimSed.variables['Prus'][:] + models.crus = np.ones((1,N))*GrupoSimSed.variables['Crus'][:] + models.parliac = np.ones((3,N))*GrupoSimSed.variables['PArLiAc'][:] + + #Variable de drena de acuerdo al tipo de modelo + if self.modelType[0] is 'c': + models.drena = np.ones((3,N)) *GrupoSimHid.variables['drena'][:] + elif self.modelType[0] is 'h': + models.drena = np.ones((1,N)) * GrupoSimHid.variables['drena'][:] + models.unit_type = np.ones((1,N)) * GrupoSimHid.variables['unit_type'][:] + models.hill_long = np.ones((1,N)) * GrupoSimHid.variables['hill_long'][:] + models.hill_slope = np.ones((1,N)) * GrupoSimHid.variables['hill_slope'][:] + models.stream_long = np.ones((1,N)) * GrupoSimHid.variables['stream_long'][:] + models.stream_slope = np.ones((1,N)) * GrupoSimHid.variables['stream_slope'][:] + models.stream_width = np.ones((1,N)) * GrupoSimHid.variables['stream_width'][:] + models.elem_area = np.ones((1,N)) * GrupoSimHid.variables['elem_area'][:] + models.speed_type = np.ones((3)) * GrupoSimHid.variables['speed_type'][:] + models.storage = np.ones((5,N)) * GrupoSimHid.variables['storage'][:] + models.control = np.ones((1,N)) * GrupoSimHid.variables['control'][:] + models.control_h = np.ones((1,N)) * GrupoSimHid.variables['control_h'][:] + + #Propiedades de deslizamientos + if sim_slides: + GrupoSlides = gr.groups['SimSlides'] + models.sl_gammas = np.ones((1,N)) * GrupoSlides.variables['gamma_soil'][:] + models.sl_cohesion = np.ones((1,N)) * GrupoSlides.variables['cohesion'][:] + models.sl_frictionangle = np.ones((1,N)) * GrupoSlides.variables['friction_angle'][:] + models.sl_radslope = np.ones((1,N)) * GrupoSlides.variables['rad_slope'][:] + models.sl_zs = np.ones((1,N)) * GrupoSlides.variables['z_soil'][:] + #Cierra el archivo + gr.close() + #Determina que por defecto debe estar set la geomorfologia + self.isSetGeo = True - #------------------------------------------------------ - # Subrutinas de lluvia, interpolacion, lectura, escritura, agrega funcion para variar evp en - # el tiempo - #------------------------------------------------------ - def __GetEVP_Serie__(self, index): - '''Descripcion: Genera una serie que pondera la evp ''' - rng=index - rad=np.zeros(rng.size) - for pos,time in enumerate(rng): - Hora=time - # Dia del Ano - dn = Hora.timetuple().tm_yday - Theta_d = (2 * np.pi * (dn-1))/ 365. - # (d/d)2 - an = [1.000110, 0.034221, 0.000719] - bn = [0, 0.001280, 0.000077] - # - d = 0 - tmp = 0 - for i in range(3): - tmp = (an[i] * np.cos(i*Theta_d)) + (bn[i] * np.sin(i*Theta_d)) - d = d + tmp - # Delta - a_n = [0.006918, -0.399912, -0.006758, -0.002697] - b_n = [0, 0.070257, 0.000907, 0.001480] - # - Delta = 0 - tmp = 0 - for i in range(4): - tmp = (a_n[i] * np.cos(i*Theta_d)) + (b_n[i] * np.sin(i*Theta_d)) - Delta = Delta + tmp - #Angulo horario (cada minuto) - Minutos = (Hora.hour * 60) + Hora.minute - Horario = 180 - (0.25 * Minutos) - Horario = (Horario * np.pi)/180. - # Coseno de Theta - Latitud = (6.2593 * np.pi)/180. - Cos_Theta = (np.sin(Latitud)*np.sin(Delta)) + (np.cos(Latitud)*np.cos(Delta)*np.cos(Horario)) - # Radiacion Teorica - So = 1367 #w/m2 - Q = So * d * Cos_Theta - # Escala entre 0 y 1 - rad_max=1369.8721876806876 - Q=1*Q/rad_max - #Guarda - rad[pos]=Q - #Se vuelven cero los valores negativos. - rad[rad<0]=0 - #Serie - rad=pd.Series(rad,index=rng) - models.evpserie = np.copy(rad.values) - return rad + #------------------------------------------------------ + # Subrutinas de lluvia, interpolacion, lectura, escritura, agrega funcion para variar evp en + # el tiempo + #------------------------------------------------------ + def __GetEVP_Serie__(self, index): + '''Descripcion: Genera una serie que pondera la evp ''' + rng=index + rad=np.zeros(rng.size) + for pos,time in enumerate(rng): + Hora=time + # Dia del Ano + dn = Hora.timetuple().tm_yday + Theta_d = (2 * np.pi * (dn-1))/ 365. + # (d/d)2 + an = [1.000110, 0.034221, 0.000719] + bn = [0, 0.001280, 0.000077] + # + d = 0 + tmp = 0 + for i in range(3): + tmp = (an[i] * np.cos(i*Theta_d)) + (bn[i] * np.sin(i*Theta_d)) + d = d + tmp + # Delta + a_n = [0.006918, -0.399912, -0.006758, -0.002697] + b_n = [0, 0.070257, 0.000907, 0.001480] + # + Delta = 0 + tmp = 0 + for i in range(4): + tmp = (a_n[i] * np.cos(i*Theta_d)) + (b_n[i] * np.sin(i*Theta_d)) + Delta = Delta + tmp + #Angulo horario (cada minuto) + Minutos = (Hora.hour * 60) + Hora.minute + Horario = 180 - (0.25 * Minutos) + Horario = (Horario * np.pi)/180. + # Coseno de Theta + Latitud = (6.2593 * np.pi)/180. + Cos_Theta = (np.sin(Latitud)*np.sin(Delta)) + (np.cos(Latitud)*np.cos(Delta)*np.cos(Horario)) + # Radiacion Teorica + So = 1367 #w/m2 + Q = So * d * Cos_Theta + # Escala entre 0 y 1 + rad_max=1369.8721876806876 + Q=1*Q/rad_max + #Guarda + rad[pos]=Q + #Se vuelven cero los valores negativos. + rad[rad<0]=0 + #Serie + rad=pd.Series(rad,index=rng) + models.evpserie = np.copy(rad.values) + return rad - def rain_interpolate_mit(self,coord,registers,ruta, umbral = 0.01): - 'Descripcion: Interpola la lluvia mediante una malla\n'\ - ' irregular de triangulos, genera campos que son. \n'\ - ' guardados en un binario para luego ser leido por el. \n'\ - ' modelo en el momento de simular. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : .\n'\ - 'coord : Array (2,Ncoord) con las coordenadas de estaciones.\n'\ - 'registers : Array (Nest,Nregisters) con los registros de lluvia.\n'\ - 'ruta : Ruta con nombre en donde se guardara el binario con.\n'\ - ' la informacion de lluvia.\n'\ - 'umbral: Umbral a partir del cual se considera que un campo contiene lluvia\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Guarda el binario, no hay retorno\n'\ - 'meanRain : La serie de lluvia promedio interpolada para la cuenca\n'\ - '\n'\ - 'Mirar Tambien\n'\ - '----------\n'\ - 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ - 'rain_read_bin: Lee binario de registros para ver que tiene.\n'\ - 'rain_ncf2bin: Convierte ncf a binario en formato del modelo (para imagenes de radar).\n'\ - #Mira si los registros son un data frame de pandas - isPandas=False - if type(registers)==pd.core.frame.DataFrame: - reg=registers.values.T - isPandas=True - else: - reg=registers - #inventa estaciones en las esquinas del DEM - for i,j in zip([0,0,1,1],[0,1,1,0]): - x=cu.xll+cu.ncols*cu.dx*i - y=cu.yll+cu.nrows*cu.dx*j - d=np.sqrt((coord[0,:]-x)**2+(coord[1,:]-y)**2) - pos=np.argmin(d) - #Actualiza las coordenadas - coord=np.vstack((coord.T,np.array([x,y]))).T - #pone lluvia en ese registro - reg=np.vstack((reg,reg[pos])) - #Obtiene las coordenadas de cada celda de la cuenca - x,y = cu.basin_coordxy(self.structure,self.ncells) - xy_basin=np.vstack((x,y)) - #Obtiene la malla irregular - TIN_mesh=Delaunay(coord.T) - TIN_mesh=TIN_mesh.vertices.T+1 - #Obtiene las pertenencias en la cuenca a la malla - #TIN_perte = models.rain_pre_mit(xy_basin,TIN_mesh,coord,self.ncells, - # TIN_mesh.shape[1],coord.shape[1]) - c = 1 - TIN_perte = np.zeros((1,self.ncells)) - for t in TIN_mesh.T: - t = t-1 - t = np.append(t, t[0]) - Poly = np.vstack([coord[0][t], coord[1][t]]) - bbPath = mplPath.Path(Poly.T, closed=True) - Contiene = bbPath.contains_points(xy_basin.T) - TIN_perte[0][Contiene == True] = c - c+=1 - #Revisa si todas las celdas quedaron asignadas - if len(TIN_perte[TIN_perte == 0]) == 0: - #Selecciona si es por laderas o por celdas - if self.modelType[0] is 'h': - maskVector = np.copy(self.hills_own) - elif self.modelType[0] is 'c': - maskVector = np.ones(self.ncells) - #Interpola con tin - meanRain,posIds = models.rain_mit(xy_basin, - coord, - reg, - TIN_mesh, - TIN_perte, - self.nhills, - ruta, - umbral, - maskVector, - self.ncells, - coord.shape[1], - TIN_mesh.shape[1], - reg.shape[1]) - #Guarda un archivo con informacion de la lluvia - f=open(ruta[:-3]+'hdr','w') - f.write('Numero de celdas: %d \n' % self.ncells) - f.write('Numero de laderas: %d \n' % self.nhills) - f.write('Numero de registros: %d \n' % reg.shape[1]) - f.write('Numero de campos no cero: %d \n' % posIds.max()) - f.write('Tipo de interpolacion: TIN\n') - f.write('IDfecha, Record, Lluvia, Fecha \n') - if isPandas: - dates=registers.index.to_pydatetime() - c = 1 - for d,pos,m in zip(dates,posIds,meanRain): - f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) - c+=1 - f.close() - return meanRain, posIds - else: - print 'Error: Existen celdas de la cuenca sin asignacion de triangulos, se retornan las coordenadas no asignadas' - pos = np.where(TIN_perte == 0)[1] - return xy_basin[0,pos], xy_basin[1,pos] + def rain_interpolate_mit(self,coord,registers,ruta, umbral = 0.01): + 'Descripcion: Interpola la lluvia mediante una malla\n'\ + ' irregular de triangulos, genera campos que son. \n'\ + ' guardados en un binario para luego ser leido por el. \n'\ + ' modelo en el momento de simular. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : .\n'\ + 'coord : Array (2,Ncoord) con las coordenadas de estaciones.\n'\ + 'registers : Array (Nest,Nregisters) con los registros de lluvia.\n'\ + 'ruta : Ruta con nombre en donde se guardara el binario con.\n'\ + ' la informacion de lluvia.\n'\ + 'umbral: Umbral a partir del cual se considera que un campo contiene lluvia\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + 'meanRain : La serie de lluvia promedio interpolada para la cuenca\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ + 'rain_read_bin: Lee binario de registros para ver que tiene.\n'\ + 'rain_ncf2bin: Convierte ncf a binario en formato del modelo (para imagenes de radar).\n'\ + #Mira si los registros son un data frame de pandas + isPandas=False + if type(registers)==pd.core.frame.DataFrame: + reg=registers.values.T + isPandas=True + else: + reg=registers + #inventa estaciones en las esquinas del DEM + for i,j in zip([0,0,1,1],[0,1,1,0]): + x=cu.xll+cu.ncols*cu.dx*i + y=cu.yll+cu.nrows*cu.dx*j + d=np.sqrt((coord[0,:]-x)**2+(coord[1,:]-y)**2) + pos=np.argmin(d) + #Actualiza las coordenadas + coord=np.vstack((coord.T,np.array([x,y]))).T + #pone lluvia en ese registro + reg=np.vstack((reg,reg[pos])) + #Obtiene las coordenadas de cada celda de la cuenca + x,y = cu.basin_coordxy(self.structure,self.ncells) + xy_basin=np.vstack((x,y)) + #Obtiene la malla irregular + TIN_mesh=Delaunay(coord.T) + TIN_mesh=TIN_mesh.vertices.T+1 + #Obtiene las pertenencias en la cuenca a la malla + #TIN_perte = models.rain_pre_mit(xy_basin,TIN_mesh,coord,self.ncells, + # TIN_mesh.shape[1],coord.shape[1]) + c = 1 + TIN_perte = np.zeros((1,self.ncells)) + for t in TIN_mesh.T: + t = t-1 + t = np.append(t, t[0]) + Poly = np.vstack([coord[0][t], coord[1][t]]) + bbPath = mplPath.Path(Poly.T, closed=True) + Contiene = bbPath.contains_points(xy_basin.T) + TIN_perte[0][Contiene == True] = c + c+=1 + #Revisa si todas las celdas quedaron asignadas + if len(TIN_perte[TIN_perte == 0]) == 0: + #Selecciona si es por laderas o por celdas + if self.modelType[0] is 'h': + maskVector = np.copy(self.hills_own) + elif self.modelType[0] is 'c': + maskVector = np.ones(self.ncells) + #Interpola con tin + meanRain,posIds = models.rain_mit(xy_basin, + coord, + reg, + TIN_mesh, + TIN_perte, + self.nhills, + ruta, + umbral, + maskVector, + self.ncells, + coord.shape[1], + TIN_mesh.shape[1], + reg.shape[1]) + #Guarda un archivo con informacion de la lluvia + f=open(ruta[:-3]+'hdr','w') + f.write('Numero de celdas: %d \n' % self.ncells) + f.write('Numero de laderas: %d \n' % self.nhills) + f.write('Numero de registros: %d \n' % reg.shape[1]) + f.write('Numero de campos no cero: %d \n' % posIds.max()) + f.write('Tipo de interpolacion: TIN\n') + f.write('IDfecha, Record, Lluvia, Fecha \n') + if isPandas: + dates=registers.index.to_pydatetime() + c = 1 + for d,pos,m in zip(dates,posIds,meanRain): + f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) + c+=1 + f.close() + return meanRain, posIds + else: + print 'Error: Existen celdas de la cuenca sin asignacion de triangulos, se retornan las coordenadas no asignadas' + pos = np.where(TIN_perte == 0)[1] + return xy_basin[0,pos], xy_basin[1,pos] - def rain_interpolate_idw(self,coord,registers,ruta,p=1,umbral=0.0): - 'Descripcion: Interpola la lluvia mediante la metodologia\n'\ - ' del inverso de la distancia ponderado. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : .\n'\ - 'coord : Array (2,Ncoord) con las coordenadas de estaciones.\n'\ - 'registers : DataFrame de pandas (Nest,Nregisters) con los registros de lluvia.\n'\ - 'p : exponente para la interpolacion de lluvia.\n'\ - 'ruta : Ruta con nombre en donde se guardara el binario con.\n'\ - ' la informacion de lluvia.\n'\ - 'umbral : Umbral de suma total de lluvia bajo el cual se considera\n'\ - ' que un intervalo tiene suficiente agua como para generar reaccion\n'\ - ' (umbral = 0.0) a medida que incremente se generaran archivos mas\n'\ - ' livianos, igualmente existe la posibilidad de borrar informacion.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Guarda el binario, no hay retorno\n'\ - 'meanRain : La serie de lluvia promedio interpolada para la cuenca\n'\ - '\n'\ - 'Mirar Tambien\n'\ - '----------\n'\ - 'rain_interpolate_mit: interpola campos mediante la metodologia idw.\n'\ - 'rain_read_bin: Lee binario de registros para ver que tiene.\n'\ - 'rain_ncf2bin: Convierte ncf a binario en formato del modelo (para imagenes de radar).\n'\ - #Mira si los registros son un data frame de pandas - isPandas=False - if type(registers)==pd.core.frame.DataFrame: - reg=registers.values.T - isPandas=True - else: - reg=registers - #Obtiene las coordenadas de cada celda de la cuenca - x,y = cu.basin_coordxy(self.structure,self.ncells) - xy_basin=np.vstack((x,y)) - #Interpola con idw - if self.modelType[0] is 'h': - meanRain,posIds = models.rain_idw(xy_basin, coord, reg, p, self.nhills, - ruta, umbral, self.hills_own, self.ncells, coord.shape[1],reg.shape[1]) - elif self.modelType[0] is 'c': - meanRain,posIds = models.rain_idw(xy_basin, coord, reg, p, self.nhills, - ruta, umbral, np.ones(self.ncells), self.ncells, coord.shape[1],reg.shape[1]) - #Guarda un archivo con informacion de la lluvia - f=open(ruta[:-3]+'hdr','w') - f.write('Numero de celdas: %d \n' % self.ncells) - f.write('Numero de laderas: %d \n' % self.nhills) - f.write('Numero de registros: %d \n' % reg.shape[1]) - f.write('Numero de campos no cero: %d \n' % posIds.max()) - f.write('Tipo de interpolacion: IDW, p= %.2f \n' % p) - f.write('IDfecha, Record, Lluvia, Fecha \n') - if isPandas: - dates=registers.index.to_pydatetime() - c = 1 - for d,pos,m in zip(dates,posIds,meanRain): - f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) - c+=1 - f.close() - return meanRain,posIds + def rain_interpolate_idw(self,coord,registers,ruta,p=1,umbral=0.0): + 'Descripcion: Interpola la lluvia mediante la metodologia\n'\ + ' del inverso de la distancia ponderado. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : .\n'\ + 'coord : Array (2,Ncoord) con las coordenadas de estaciones.\n'\ + 'registers : DataFrame de pandas (Nest,Nregisters) con los registros de lluvia.\n'\ + 'p : exponente para la interpolacion de lluvia.\n'\ + 'ruta : Ruta con nombre en donde se guardara el binario con.\n'\ + ' la informacion de lluvia.\n'\ + 'umbral : Umbral de suma total de lluvia bajo el cual se considera\n'\ + ' que un intervalo tiene suficiente agua como para generar reaccion\n'\ + ' (umbral = 0.0) a medida que incremente se generaran archivos mas\n'\ + ' livianos, igualmente existe la posibilidad de borrar informacion.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + 'meanRain : La serie de lluvia promedio interpolada para la cuenca\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'rain_interpolate_mit: interpola campos mediante la metodologia idw.\n'\ + 'rain_read_bin: Lee binario de registros para ver que tiene.\n'\ + 'rain_ncf2bin: Convierte ncf a binario en formato del modelo (para imagenes de radar).\n'\ + #Mira si los registros son un data frame de pandas + isPandas=False + if type(registers)==pd.core.frame.DataFrame: + reg=registers.values.T + isPandas=True + else: + reg=registers + #Obtiene las coordenadas de cada celda de la cuenca + x,y = cu.basin_coordxy(self.structure,self.ncells) + xy_basin=np.vstack((x,y)) + #Interpola con idw + if self.modelType[0] is 'h': + meanRain,posIds = models.rain_idw(xy_basin, coord, reg, p, self.nhills, + ruta, umbral, self.hills_own, self.ncells, coord.shape[1],reg.shape[1]) + elif self.modelType[0] is 'c': + meanRain,posIds = models.rain_idw(xy_basin, coord, reg, p, self.nhills, + ruta, umbral, np.ones(self.ncells), self.ncells, coord.shape[1],reg.shape[1]) + #Guarda un archivo con informacion de la lluvia + f=open(ruta[:-3]+'hdr','w') + f.write('Numero de celdas: %d \n' % self.ncells) + f.write('Numero de laderas: %d \n' % self.nhills) + f.write('Numero de registros: %d \n' % reg.shape[1]) + f.write('Numero de campos no cero: %d \n' % posIds.max()) + f.write('Tipo de interpolacion: IDW, p= %.2f \n' % p) + f.write('IDfecha, Record, Lluvia, Fecha \n') + if isPandas: + dates=registers.index.to_pydatetime() + c = 1 + for d,pos,m in zip(dates,posIds,meanRain): + f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) + c+=1 + f.close() + return meanRain,posIds + + def rain_radar2basin_from_asc(self,ruta_in,ruta_out,fechaI,fechaF,dt, + pre_string,post_string,fmt = '%Y%m%d%H%M',conv_factor=1.0/12.0, + umbral = 0.0): + 'Descripcion: Genera campos de lluvia a partir de archivos asc. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : .\n'\ + 'ruta_in: Ruta donde se encuentran loas .asc.\n'\ + 'ruta_out: Ruta donde escribe el binario con la lluvia.\n'\ + 'fechaI: Fecha de inicio de registros.\n'\ + 'fechaF: Fecha de finalizacion de registros.\n'\ + 'dt: Intervalo de tiempo entre registros.\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + 'meanRain : La serie de lluvia promedio.\n'\ + 'meanRain : La serie de lluvia promedio.\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ + 'rain_radar2basin_from_array: Mete campos de lluvia mediante multiples arrays.\n'\ + #Edita la ruta de salida + if ruta_out.endswith('.hdr') or ruta_out.endswith('.bin'): + ruta_bin = ruta_out[:-3]+'.bin' + ruta_hdr = ruta_out[:-3]+'.hdr' + else: + ruta_bin = ruta_out+'.bin' + ruta_hdr = ruta_out+'.hdr' + #Establece la cantidad de elementos de acuerdo al tipo de cuenca + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + #Guarda la primera entrada como un mapa de ceros + models.write_int_basin(ruta_bin,np.zeros((1,N)),1,N,1) + #Genera la lista de las fechas. + ListDates,dates = __ListaRadarNames__(ruta_in, + fechaI,fechaF, + fmt,post_string,pre_string,dt) + #Lee los mapas y los transforma + cont = 1 + meanRain = [] + posIds = [] + for l in ListDates: + Map,p = read_map_raster(ruta_in + l) + vec = self.Transform_Map2Basin(Map,p) * conv_factor + #Si el mapa tiene mas agua de un umbral + if vec.sum() > umbral: + #Actualiza contador, lluvia media y pocisiones + cont +=1 + meanRain.append(vec.mean()) + posIds.append(cont) + #Guarda el vector + vec = vec*1000; vec = vec.astype(int) + models.write_int_basin(ruta_bin,np.zeros((1,N))+vec,cont,N,1) + else: + #lluvia media y pocisiones + meanRain.append(0.0) + posIds.append(1) + posIds = np.array(posIds) + meanRain = np.array(meanRain) + #Guarda un archivo con informacion de la lluvia + f=open(ruta_hdr[:-3]+'hdr','w') + f.write('Numero de celdas: %d \n' % self.ncells) + f.write('Numero de laderas: %d \n' % self.nhills) + f.write('Numero de registros: %d \n' % meanRain.shape[0]) + f.write('Numero de campos no cero: %d \n' % posIds.max()) + f.write('Tipo de interpolacion: radar \n') + f.write('IDfecha, Record, Lluvia, Fecha \n') + c = 1 + for d,pos,m in zip(dates,posIds,meanRain): + f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) + c+=1 + f.close() + return np.array(meanRain),np.array(posIds) + + def rain_radar2basin_from_array(self,vec=None,ruta_out=None,fecha=None,dt=None, + status='update',umbral = 0.01, doit = False): + 'Descripcion: Genera campos de lluvia a partir de archivos array\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : .\n'\ + 'vec: Array en forma de la cuenca con la informacion.\n'\ + 'ruta_out: Ruta donde escribe el binario con la lluvia.\n'\ + 'fecha: Fecha del registro actual.\n'\ + 'dt: Intervalo de tiempo entre registros.\n'\ + 'status: Estado en el cual se encuentra el binario que se va a pasar a campo.\n'\ + ' update: (Defecto) Con este estado se genera un binario y se agregan nuevos campos.\n'\ + ' old: Estado para abrir y tomar las propiedades de self.radar.. para la generacion de un binario.\n'\ + ' close: Cierra un binario que se ha generado mediante update.\n'\ + ' reset: Reinicia las condiciones de self.radar... para la creacion de un campo nuevo.\n'\ + 'doit: Independiente del umbral escribe el binario en la siguiente entrada.\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + 'meanRain : La serie de lluvia promedio.\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ + 'rain_radar2basin_from_asc: Mete campos de lluvia mediante multiples arrays.\n'\ + #Edita la ruta de salida + if ruta_out is not None: + if ruta_out.endswith('.hdr') or ruta_out.endswith('.bin'): + ruta_bin = ruta_out[:-3]+'.bin' + ruta_hdr = ruta_out[:-3]+'.hdr' + else: + ruta_bin = ruta_out+'.bin' + ruta_hdr = ruta_out+'.hdr' + #Establece la cantidad de elementos de acuerdo al tipo de cuenca + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + try: + if vec.shape[0] == self.ncells: + vec = self.Transform_Basin2Hills(vec,sumORmean=1) + except: + pass + # De acerudo al estado actualiza las variables o guarda el + # binario final + actualizo = 1 + if status == 'update': + #Entrada 1 es la entrada de campos sin lluvia + if len(self.radarDates) == 0: + models.write_int_basin(ruta_bin,np.zeros((1,N)),1,N,1) + if vec.mean() > umbral or doit: + #Actualiza contador, lluvia media y pocisiones + self.radarCont +=1 + self.radarMeanRain.append(vec.mean()) + self.radarPos.append(self.radarCont) + #Guarda el vector + vec = vec*1000; vec = vec.astype(int) + models.write_int_basin(ruta_bin,np.zeros((1,N))+vec, + self.radarCont,N,1) + actualizo = 0 + else: + #lluvia media y pocisiones + self.radarMeanRain.append(0.0) + self.radarPos.append(1) + self.radarDates.append(fecha) + #Si ya no va a agregar nada, no agrega mas campos y genera el .hdr + elif status == 'close': + self.radarMeanRain = np.array(self.radarMeanRain) + self.radarPos = np.array(self.radarPos) + #Guarda un archivo con informacion de la lluvia + f=open(ruta_hdr[:-3]+'hdr','w') + f.write('Numero de celdas: %d \n' % self.ncells) + f.write('Numero de laderas: %d \n' % self.nhills) + f.write('Numero de registros: %d \n' % self.radarMeanRain.shape[0]) + f.write('Numero de campos no cero: %d \n' % self.radarPos.max()) + f.write('Tipo de interpolacion: radar \n') + f.write('IDfecha, Record, Lluvia, Fecha \n') + c = 1 + for d,pos,m in zip(self.radarDates, + self.radarPos,self.radarMeanRain): + f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) + c+=1 + f.close() + #Vuelve las variables listas de nuevo + self.radarMeanRain = self.radarMeanRain.tolist() + self.radarPos = self.radarPos.tolist() + elif status == 'reset': + #Variables de radar + self.radarDates = [] + self.radarPos = [] + self.radarMeanRain = [] + self.radarCont = 1 + elif status == 'old': + #si es un archivo viejo, lo abre para tomar las variables y continuar en ese punto + f=open(ruta_hdr[:-3]+'hdr','r') + Lista = f.readlines() + self.radarCont = int(Lista[3].split()[-1]) + cantidadIds = int(Lista[2].split()[-1]) + f.close() + #Abre con numpy para simplificar las cosas + a = np.loadtxt(ruta_hdr,skiprows=6,dtype='str').T + if self.radarCont >= 1 and cantidadIds > 1: + self.radarPos = [int(i.split(',')[0]) for i in a[1]] + self.radarMeanRain = [float(i.split(',')[0]) for i in a[2]] + for i in a[3]: + d = datetime.datetime.strptime(i,'%Y-%m-%d-%H:%M') + self.radarDates.append(d) + else: + self.radarPos = [int(a[1].split(',')[0])] + self.radarMeanRain = [float(a[2].split(',')[0])] + self.radarDates = [datetime.datetime.strptime(a[-1], '%Y-%m-%d-%H:%M')] + return actualizo + + #------------------------------------------------------ + # Subrutinas para preparar modelo + #------------------------------------------------------ + def set_Geomorphology(self,umbrales=[30,500],stream_width=None): + 'Descripcion: calcula las propiedades geomorfologicas necesarias \n'\ + ' para la simulacion. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'umbrales : Lista con la cantidad de celdas necesarias .\n'\ + ' para que una celda sea: ladera, carcava o cauce .\n'\ + 'stream_width = Ancho del canal en cada tramo (opcional).\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables geomorfologicas de simulacion iniciadas.\n'\ + ' models.drena : Numero de celda o ladera destino. \n'\ + ' models.nceldas : Numero de celdas o laderas. \n'\ + ' models.unit_type : tipo de celda, en el caso de ladera no aplica.\n'\ + ' 1: Celda tipo ladera.\n'\ + ' 2: Celda tipo transitorio.\n'\ + ' 3: Celda tipo cauce.\n'\ + ' models.hill_long : Longitud promedio de la ladera (o celda). \n'\ + ' - Celdas: Longitud de cada elemento (cu.dxp) para ortogonal y 1.43*cu.dxp para diagonal. \n'\ + ' - Laderas: Promedio de las longitudes recorridas entre una celda y la corriente de la ladera. \n'\ + ' models.hill_slope : Pendiente de cada ladera (promedio) o celda.\n'\ + ' models.stream_long : Longitud de cada tramo de cuace. \n'\ + ' - Celdas: Es cu.dxp: ortogonal, 1.42*cu.dxp: Diagonal. \n'\ + ' - Laderas: Es la Longitud de los elementos del cauce que componen la ladera. \n'\ + ' models.stream_slope : Pendiente de cada tramo de cauce. \n'\ + ' - Celdas: Es la pendiente estimada por self.GetGeo_Cell_Basics(). \n'\ + ' - Laderas: Pendiente promedio de las laderas. \n'\ + ' models.stream_width : Ancho de cada tramo de cauce. \n'\ + ' - Celdas: No aplica y se hacen todos iguales a la unidad. \n'\ + ' - Laderas: Es el ancho del canal calculado a partir de geomrofologia o entregado. \n'\ + ' models.elem_area : Area de cada celda (cu.dxp**2) o ladera (nceldasLadera * cu.dxp**2). \n'\ + #Obtiene lo basico para luego pasar argumentos + acum,hill_long,pend,elev = cu.basin_basics(self.structure, + self.DEMvec,self.DIRvec,self.ncells) + #Obtiene la pendiente y la longitud de las corrientes + cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( + self.structure,acum,umbrales[1],self.ncells) + stream_s,stream_l = cu.basin_stream_slope( + self.structure,elev,hill_long,nodos,n_cauce,self.ncells) + stream_s[np.isnan(stream_s)]=self.nodata + #Obtiene para metros por subn cuencas + sub_horton,nod_horton = cu.basin_subbasin_horton(self.hills,self.ncells, + self.hills.shape[1]) + sub_basin_long,max_long,nodo_max_long = cu.basin_subbasin_long( + self.hills_own,cauce,hill_long,self.hills, + sub_horton,self.hills.shape[1],self.ncells) + #Obtiene las propiedades por laderas de los cauces + stream_slope,stream_long = cu.basin_subbasin_stream_prop( + self.hills_own,cauce,hill_long, + pend,self.hills.shape[1],self.ncells) + #opbtiene el ancho si noe s dado lo asume igual a uno + if stream_width is None: + stream_width=np.ones(self.ncells) + #De acuerdo a si el modelo es por laderas o por celdas agrega lass varaibeles + if self.modelType[0]=='c': + #Obtiene el tipo de celdas + unit_type = cu.basin_stream_type(self.structure, + acum,umbrales,len(umbrales),self.ncells) + #Asigna variables + models.drena = np.ones((1,self.ncells))*self.structure + models.nceldas = self.ncells + models.unit_type = np.ones((1,self.ncells))*unit_type + models.hill_long = np.ones((1,self.ncells))*hill_long + models.hill_slope = np.ones((1,self.ncells))*pend + models.stream_long = np.ones((1,self.ncells))*np.percentile(hill_long, 40) + models.stream_slope = np.ones((1,self.ncells))*pend + models.stream_width = np.ones((1,self.ncells))*stream_width + models.elem_area = np.ones((1,self.ncells))*cu.dxp**2.0 + elif self.modelType[0]=='h': + N=self.hills.shape[1] + models.drena = np.ones((1,N))*self.hills[1] + models.nceldas = self.hills.shape[1] + models.unit_type = np.ones((1,N))*np.ones(N)*3 + models.hill_long = np.ones((1,N))*sub_basin_long + models.hill_slope = np.ones((1,N))*self.Transform_Basin2Hills(pend) + models.stream_long = np.ones((1,N))*stream_long + models.stream_slope = np.ones((1,N))*stream_slope + models.stream_width = np.ones((1,N))*cu.basin_subbasin_map2subbasin( + self.hills_own,stream_width,self.nhills,cauce,0,self.ncells) + no0min = models.stream_width[models.stream_width<>0].min() + models.stream_width[models.stream_width==0] = no0min + models.elem_area = np.ones((1,N))*np.array([self.hills_own[self.hills_own==i].shape[0] for i in range(1,self.hills.shape[1]+1)])*cu.dxp**2.0 + #Ajusta variable de que la geomorfologia esta calculada + self.isSetGeo = True + + def set_Speed_type(self,types=np.ones(3)): + 'Descripcion: Especifica el tipo de velocidad a usar en cada \n'\ + ' nivel del modelo. \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Inicia las variables vacias.\n'\ + 'types : tipos de velocidad .\n'\ + ' 1. Velocidad tipo embalse lineal, no se especifica h_exp.\n'\ + ' 2. Velocidad onda cinematica, se debe especificar h_exp.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con la variable models.speed_type especificada.\n'\ + #Especifica la ecuacion de velocidad a usar en cada nivel del modelo + for c,i in enumerate(types): + if i==1 or i==2: + models.speed_type[c]=i + else: + models.speed_type[c]=1 + + def set_Floods(self,var,VarName, umbral = 1000, NumCeldas = 6, Default = False): + 'Descripcion: Aloja las variables del sub modelo de inundaciones\n'\ + '\n'\ + 'Parametros\n'\ + 'Mierda PUTA\n'\ + '----------\n'\ + 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ + 'varName: Nombre de la variable a ingresar en el modelo.\n'\ + ' GammaWater : Densidad del agua (Defecto: 1000).\n'\ + ' GammaSoil : Densidad del sedimento (Defecto: 2600).\n'\ + ' VelArea: Factor conversion Velocidad - Area (Defecto: 1/200).\n'\ + ' Cmax: Maxima concentracion de sedimentos (Defecto 0.75).\n'\ + ' MaxIter: Cantidad maxima de iteraciones para obtener la mancha de inunudacion.\n'\ + ' VelUmbral: Velocidad minima para que se de el flujo de escombros ( Defecto: 3 m/s).\n'\ + ' Stream_W: Ancho del canal en cada celda (ncells).\n'\ + ' Stream_D50: Tamano de particula percentil 50 (ncells).\n'\ + ' HAND: Modelo de elevacion relativa de celda ladera a celda cauce (ncells), no se ponde nada.\n'\ + ' umbral: Umbral para determinar corriente segun HAND debe coincidir con el umbral del modelo.\n'\ + ' Slope: Pendiente del canal, (no se ponde variable)\n'\ + ' Default: Poner o no parametros por defecto (False)\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ + ' wmf.models.flood_dw.\n'\ + ' wmf.models.flood_dsed.\n'\ + ' wmf.models.flood_av.\n'\ + ' wmf.models.flood_cmax.\n'\ + ' wmf.models.flood_d50.\n'\ + ' wmf.models.flood_hand.\n'\ + ' wmf.models.flood_aquien.\n'\ + #Si el modelo es tipo ladera agrega la variable + if self.modelType[0] == 'h': + return 'El modelo por laderas no simula inundaciones.' + #Pone el gamma del agua por defecto + if Default: + models.flood_dw = 1000 + models.flood_dsed = 2600 + models.flood_av = 1./200.0 + models.flood_cmax = 0.75 + models.flood_umbral = 3.0 + models.flood_max_iter = 10 + models.flood_step = 1.0 + #Obtiene el vector que va a alojar en el modelo + if VarName <> 'GammaWater' and VarName <> 'GammaSoil' and VarName <> 'VelArea' and VarName <> 'Cmax' and VarName <> 'VelUmbral': + isVec=False + if type(var) is str: + #Si es un string lee el mapa alojado en esa ruta + Map,Pp = read_map_raster(var) + Vec = self.Transform_Map2Basin(Map,Pp) + isVec=True + elif type(var) is int or float: + Vec = np.ones((1,self.ncells))*var + isVec=True + elif type(var) is np.ndarray and var.shape[0] == self.ncells: + Vec = var + isVec=True + #finalmente mete la variable en el modelo + N = self.ncells + if VarName is 'Stream_W' : + models.flood_w = np.ones((1,N))*Vec + elif VarName is 'Stream_D50': + models.flood_d50 = np.ones((1,N))*Vec + elif VarName is 'HAND': + self.GetGeo_HAND(umbral = umbral) + models.flood_hand = np.ones((1,N))*np.copy(self.CellHAND) + models.flood_aquien = np.ones((1,N))*np.copy(self.CellHAND_drainCell) + elif VarName is 'Slope': + self.GetGeo_Cell_Basics() + models.flood_slope = np.ones((1,N))*np.sin(np.arctan(self.CellSlope)) + elif VarName is 'Sections': + self.GetGeo_Sections(NumCeldas = NumCeldas) + models.flood_sections = np.ones((NumCeldas*2+1,N)) * self.Sections + models.flood_sec_cells = np.ones((NumCeldas*2+1,N)) * self.Sections_Cells + elif VarName == 'GammaWater': + models.flood_dw = var + elif VarName == 'GammaSoil': + models.flood_dsed = var + elif VarName == 'VelArea': + models.flood_av = var + elif VarName == 'Cmax': + models.flood_cmax = var + elif VarName == 'VelUmbral': + models.flood_umbral = var + elif VarName == 'MaxIter': + models.flood_max_iter = var + + def set_PhysicVariables(self,modelVarName,var,pos,mask=None): + 'Descripcion: Coloca las variables fisicas en el modelo \n'\ + ' Se debe assignarel nombre del tipo de variable, la variable\n'\ + ' y la posicion en que esta va a ser insertada\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Objeto de la cuenca 2que luego se va a simular.\n'\ + 'modelVarName : Nombre de la variable del modelo que se va a incertar.\n'\ + ' - h_coef: coeficientes horizontales\n'\ + ' [0]: Flujo de Escorrentia.\n'\ + ' [1]: Flujo Sub-superficial.\n'\ + ' [2]: Flujo subterraneo.\n'\ + ' [3]: Flujo en cauces.\n'\ + ' - h_exp: exponentes del tipo v = h_coef*(A**h_exp)\n'\ + ' [0]: Escorrentia.\n'\ + ' [1]: sub-superficial.\n'\ + ' [2]: subterraneo.\n'\ + ' [3]: cauce.\n'\ + ' - v_coef.\n'\ + ' [0]: Tasa evaporacion.\n'\ + ' [1]: Infiltracion.\n'\ + ' [2]: Percolacion.\n'\ + ' [3]: Perdidas (0).\n'\ + ' - v_exp: procesos verticales no lineales\n'\ + ' (no implementado dentro del modelo)\n' + ' - capilar.\n'\ + ' - gravit.\n'\ + 'var : variable que ingresa en el modelo, esta puede ser:.\n'\ + ' - Ruta: una ruta del tipo string.\n'\ + ' - Escalar : Un valor escalar que se asignara a toda la cuenca.\n'\ + ' - Vector : Un vector con la informacion leida (1,ncells).\n'\ + 'pos : Posicion de insercion, aplica para : h_coef, v_coef,.\n'\ + ' h_exp, v_exp.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ + 'rain_read_bin: Lee binario de registros para ver que tiene.\n'\ + 'rain_ncf2bin: Convierte ncf a binario en formato del modelo (para imagenes de radar).\n'\ + + #Obtiene el vector que va a alojar en el modelo + isVec=False + if type(var) is str: + #Si es un string lee el mapa alojado en esa ruta + Map,Pp = read_map_raster(var) + Vec = self.Transform_Map2Basin(Map,Pp) + isVec=True + elif type(var) is int or float: + Vec = np.ones((1,self.ncells))*var + isVec=True + elif type(var) is np.ndarray and var.shape[0] == self.ncells: + Vec = var + isVec=True + #Si el modelo es tipo ladera agrega la variable + if self.modelType[0] is 'h': + Vec = self.Transform_Basin2Hills(Vec,mask=mask) + #finalmente mete la variable en el modelo + if modelVarName is 'h_coef': + models.h_coef[pos] = Vec + elif modelVarName is 'h_exp': + models.h_exp[pos] = Vec + elif modelVarName is 'v_coef': + models.v_coef[pos] = Vec + elif modelVarName is 'v_exp': + models.v_exp[pos] = Vec + elif modelVarName is 'capilar': + models.max_capilar[0] = Vec + elif modelVarName is 'gravit': + models.max_gravita[0] = Vec - def rain_radar2basin_from_asc(self,ruta_in,ruta_out,fechaI,fechaF,dt, - pre_string,post_string,fmt = '%Y%m%d%H%M',conv_factor=1.0/12.0, - umbral = 0.0): - 'Descripcion: Genera campos de lluvia a partir de archivos asc. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : .\n'\ - 'ruta_in: Ruta donde se encuentran loas .asc.\n'\ - 'ruta_out: Ruta donde escribe el binario con la lluvia.\n'\ - 'fechaI: Fecha de inicio de registros.\n'\ - 'fechaF: Fecha de finalizacion de registros.\n'\ - 'dt: Intervalo de tiempo entre registros.\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Guarda el binario, no hay retorno\n'\ - 'meanRain : La serie de lluvia promedio.\n'\ - 'meanRain : La serie de lluvia promedio.\n'\ - '\n'\ - 'Mirar Tambien\n'\ - '----------\n'\ - 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ - 'rain_radar2basin_from_array: Mete campos de lluvia mediante multiples arrays.\n'\ - #Edita la ruta de salida - if ruta_out.endswith('.hdr') or ruta_out.endswith('.bin'): - ruta_bin = ruta_out[:-3]+'.bin' - ruta_hdr = ruta_out[:-3]+'.hdr' - else: - ruta_bin = ruta_out+'.bin' - ruta_hdr = ruta_out+'.hdr' - #Establece la cantidad de elementos de acuerdo al tipo de cuenca - if self.modelType[0] is 'c': - N = self.ncells - elif self.modelType[0] is 'h': - N = self.nhills - #Guarda la primera entrada como un mapa de ceros - models.write_int_basin(ruta_bin,np.zeros((1,N)),1,N,1) - #Genera la lista de las fechas. - ListDates,dates = __ListaRadarNames__(ruta_in, - fechaI,fechaF, - fmt,post_string,pre_string,dt) - #Lee los mapas y los transforma - cont = 1 - meanRain = [] - posIds = [] - for l in ListDates: - Map,p = read_map_raster(ruta_in + l) - vec = self.Transform_Map2Basin(Map,p) * conv_factor - #Si el mapa tiene mas agua de un umbral - if vec.sum() > umbral: - #Actualiza contador, lluvia media y pocisiones - cont +=1 - meanRain.append(vec.mean()) - posIds.append(cont) - #Guarda el vector - vec = vec*1000; vec = vec.astype(int) - models.write_int_basin(ruta_bin,np.zeros((1,N))+vec,cont,N,1) - else: - #lluvia media y pocisiones - meanRain.append(0.0) - posIds.append(1) - posIds = np.array(posIds) - meanRain = np.array(meanRain) - #Guarda un archivo con informacion de la lluvia - f=open(ruta_hdr[:-3]+'hdr','w') - f.write('Numero de celdas: %d \n' % self.ncells) - f.write('Numero de laderas: %d \n' % self.nhills) - f.write('Numero de registros: %d \n' % meanRain.shape[0]) - f.write('Numero de campos no cero: %d \n' % posIds.max()) - f.write('Tipo de interpolacion: radar \n') - f.write('IDfecha, Record, Lluvia, Fecha \n') - c = 1 - for d,pos,m in zip(dates,posIds,meanRain): - f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) - c+=1 - f.close() - return np.array(meanRain),np.array(posIds) - - def rain_radar2basin_from_array(self,vec=None,ruta_out=None,fecha=None,dt=None, - status='update',umbral = 0.01, doit = False): - 'Descripcion: Genera campos de lluvia a partir de archivos array\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : .\n'\ - 'vec: Array en forma de la cuenca con la informacion.\n'\ - 'ruta_out: Ruta donde escribe el binario con la lluvia.\n'\ - 'fecha: Fecha del registro actual.\n'\ - 'dt: Intervalo de tiempo entre registros.\n'\ - 'status: Estado en el cual se encuentra el binario que se va a pasar a campo.\n'\ - ' update: (Defecto) Con este estado se genera un binario y se agregan nuevos campos.\n'\ - ' old: Estado para abrir y tomar las propiedades de self.radar.. para la generacion de un binario.\n'\ - ' close: Cierra un binario que se ha generado mediante update.\n'\ - ' reset: Reinicia las condiciones de self.radar... para la creacion de un campo nuevo.\n'\ - 'doit: Independiente del umbral escribe el binario en la siguiente entrada.\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Guarda el binario, no hay retorno\n'\ - 'meanRain : La serie de lluvia promedio.\n'\ - '\n'\ - 'Mirar Tambien\n'\ - '----------\n'\ - 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ - 'rain_radar2basin_from_asc: Mete campos de lluvia mediante multiples arrays.\n'\ - #Edita la ruta de salida - if ruta_out is not None: - if ruta_out.endswith('.hdr') or ruta_out.endswith('.bin'): - ruta_bin = ruta_out[:-3]+'.bin' - ruta_hdr = ruta_out[:-3]+'.hdr' - else: - ruta_bin = ruta_out+'.bin' - ruta_hdr = ruta_out+'.hdr' - #Establece la cantidad de elementos de acuerdo al tipo de cuenca - if self.modelType[0] is 'c': - N = self.ncells - elif self.modelType[0] is 'h': - N = self.nhills - try: - if vec.shape[0] == self.ncells: - vec = self.Transform_Basin2Hills(vec,sumORmean=1) - except: - pass - # De acerudo al estado actualiza las variables o guarda el - # binario final - actualizo = 1 - if status == 'update': - #Entrada 1 es la entrada de campos sin lluvia - if len(self.radarDates) == 0: - models.write_int_basin(ruta_bin,np.zeros((1,N)),1,N,1) - if vec.mean() > umbral or doit: - #Actualiza contador, lluvia media y pocisiones - self.radarCont +=1 - self.radarMeanRain.append(vec.mean()) - self.radarPos.append(self.radarCont) - #Guarda el vector - vec = vec*1000; vec = vec.astype(int) - models.write_int_basin(ruta_bin,np.zeros((1,N))+vec, - self.radarCont,N,1) - actualizo = 0 - else: - #lluvia media y pocisiones - self.radarMeanRain.append(0.0) - self.radarPos.append(1) - self.radarDates.append(fecha) - #Si ya no va a agregar nada, no agrega mas campos y genera el .hdr - elif status == 'close': - self.radarMeanRain = np.array(self.radarMeanRain) - self.radarPos = np.array(self.radarPos) - #Guarda un archivo con informacion de la lluvia - f=open(ruta_hdr[:-3]+'hdr','w') - f.write('Numero de celdas: %d \n' % self.ncells) - f.write('Numero de laderas: %d \n' % self.nhills) - f.write('Numero de registros: %d \n' % self.radarMeanRain.shape[0]) - f.write('Numero de campos no cero: %d \n' % self.radarPos.max()) - f.write('Tipo de interpolacion: radar \n') - f.write('IDfecha, Record, Lluvia, Fecha \n') - c = 1 - for d,pos,m in zip(self.radarDates, - self.radarPos,self.radarMeanRain): - f.write('%d, \t %d, \t %.2f, %s \n' % (c,pos,m,d.strftime('%Y-%m-%d-%H:%M'))) - c+=1 - f.close() - #Vuelve las variables listas de nuevo - self.radarMeanRain = self.radarMeanRain.tolist() - self.radarPos = self.radarPos.tolist() - elif status == 'reset': - #Variables de radar - self.radarDates = [] - self.radarPos = [] - self.radarMeanRain = [] - self.radarCont = 1 - elif status == 'old': - #si es un archivo viejo, lo abre para tomar las variables y continuar en ese punto - f=open(ruta_hdr[:-3]+'hdr','r') - Lista = f.readlines() - self.radarCont = int(Lista[3].split()[-1]) - cantidadIds = int(Lista[2].split()[-1]) - f.close() - #Abre con numpy para simplificar las cosas - a = np.loadtxt(ruta_hdr,skiprows=6,dtype='str').T - if self.radarCont >= 1 and cantidadIds > 1: - self.radarPos = [int(i.split(',')[0]) for i in a[1]] - self.radarMeanRain = [float(i.split(',')[0]) for i in a[2]] - for i in a[3]: - d = datetime.datetime.strptime(i,'%Y-%m-%d-%H:%M') - self.radarDates.append(d) - else: - self.radarPos = [int(a[1].split(',')[0])] - self.radarMeanRain = [float(a[2].split(',')[0])] - self.radarDates = [datetime.datetime.strptime(a[-1], '%Y-%m-%d-%H:%M')] - return actualizo - - #------------------------------------------------------ - # Subrutinas para preparar modelo - #------------------------------------------------------ - def set_Geomorphology(self,umbrales=[30,500],stream_width=None): - 'Descripcion: calcula las propiedades geomorfologicas necesarias \n'\ - ' para la simulacion. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'umbrales : Lista con la cantidad de celdas necesarias .\n'\ - ' para que una celda sea: ladera, carcava o cauce .\n'\ - 'stream_width = Ancho del canal en cada tramo (opcional).\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con las variables geomorfologicas de simulacion iniciadas.\n'\ - ' models.drena : Numero de celda o ladera destino. \n'\ - ' models.nceldas : Numero de celdas o laderas. \n'\ - ' models.unit_type : tipo de celda, en el caso de ladera no aplica.\n'\ - ' 1: Celda tipo ladera.\n'\ - ' 2: Celda tipo transitorio.\n'\ - ' 3: Celda tipo cauce.\n'\ - ' models.hill_long : Longitud promedio de la ladera (o celda). \n'\ - ' - Celdas: Longitud de cada elemento (cu.dxp) para ortogonal y 1.43*cu.dxp para diagonal. \n'\ - ' - Laderas: Promedio de las longitudes recorridas entre una celda y la corriente de la ladera. \n'\ - ' models.hill_slope : Pendiente de cada ladera (promedio) o celda.\n'\ - ' models.stream_long : Longitud de cada tramo de cuace. \n'\ - ' - Celdas: Es cu.dxp: ortogonal, 1.42*cu.dxp: Diagonal. \n'\ - ' - Laderas: Es la Longitud de los elementos del cauce que componen la ladera. \n'\ - ' models.stream_slope : Pendiente de cada tramo de cauce. \n'\ - ' - Celdas: Es la pendiente estimada por self.GetGeo_Cell_Basics(). \n'\ - ' - Laderas: Pendiente promedio de las laderas. \n'\ - ' models.stream_width : Ancho de cada tramo de cauce. \n'\ - ' - Celdas: No aplica y se hacen todos iguales a la unidad. \n'\ - ' - Laderas: Es el ancho del canal calculado a partir de geomrofologia o entregado. \n'\ - ' models.elem_area : Area de cada celda (cu.dxp**2) o ladera (nceldasLadera * cu.dxp**2). \n'\ - #Obtiene lo basico para luego pasar argumentos - acum,hill_long,pend,elev = cu.basin_basics(self.structure, - self.DEMvec,self.DIRvec,self.ncells) - #Obtiene la pendiente y la longitud de las corrientes - cauce,nodos,trazado,n_nodos,n_cauce = cu.basin_stream_nod( - self.structure,acum,umbrales[1],self.ncells) - stream_s,stream_l = cu.basin_stream_slope( - self.structure,elev,hill_long,nodos,n_cauce,self.ncells) - stream_s[np.isnan(stream_s)]=self.nodata - #Obtiene para metros por subn cuencas - sub_horton,nod_horton = cu.basin_subbasin_horton(self.hills,self.ncells, - self.hills.shape[1]) - sub_basin_long,max_long,nodo_max_long = cu.basin_subbasin_long( - self.hills_own,cauce,hill_long,self.hills, - sub_horton,self.hills.shape[1],self.ncells) - #Obtiene las propiedades por laderas de los cauces - stream_slope,stream_long = cu.basin_subbasin_stream_prop( - self.hills_own,cauce,hill_long, - pend,self.hills.shape[1],self.ncells) - #opbtiene el ancho si noe s dado lo asume igual a uno - if stream_width is None: - stream_width=np.ones(self.ncells) - #De acuerdo a si el modelo es por laderas o por celdas agrega lass varaibeles - if self.modelType[0]=='c': - #Obtiene el tipo de celdas - unit_type = cu.basin_stream_type(self.structure, - acum,umbrales,len(umbrales),self.ncells) - #Asigna variables - models.drena = np.ones((1,self.ncells))*self.structure - models.nceldas = self.ncells - models.unit_type = np.ones((1,self.ncells))*unit_type - models.hill_long = np.ones((1,self.ncells))*hill_long - models.hill_slope = np.ones((1,self.ncells))*pend - models.stream_long = np.ones((1,self.ncells))*np.percentile(hill_long, 40) - models.stream_slope = np.ones((1,self.ncells))*pend - models.stream_width = np.ones((1,self.ncells))*stream_width - models.elem_area = np.ones((1,self.ncells))*cu.dxp**2.0 - elif self.modelType[0]=='h': - N=self.hills.shape[1] - models.drena = np.ones((1,N))*self.hills[1] - models.nceldas = self.hills.shape[1] - models.unit_type = np.ones((1,N))*np.ones(N)*3 - models.hill_long = np.ones((1,N))*sub_basin_long - models.hill_slope = np.ones((1,N))*self.Transform_Basin2Hills(pend) - models.stream_long = np.ones((1,N))*stream_long - models.stream_slope = np.ones((1,N))*stream_slope - models.stream_width = np.ones((1,N))*cu.basin_subbasin_map2subbasin( - self.hills_own,stream_width,self.nhills,cauce,0,self.ncells) - no0min = models.stream_width[models.stream_width<>0].min() - models.stream_width[models.stream_width==0] = no0min - models.elem_area = np.ones((1,N))*np.array([self.hills_own[self.hills_own==i].shape[0] for i in range(1,self.hills.shape[1]+1)])*cu.dxp**2.0 - #Ajusta variable de que la geomorfologia esta calculada - self.isSetGeo = True - - def set_Speed_type(self,types=np.ones(3)): - 'Descripcion: Especifica el tipo de velocidad a usar en cada \n'\ - ' nivel del modelo. \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Inicia las variables vacias.\n'\ - 'types : tipos de velocidad .\n'\ - ' 1. Velocidad tipo embalse lineal, no se especifica h_exp.\n'\ - ' 2. Velocidad onda cinematica, se debe especificar h_exp.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con la variable models.speed_type especificada.\n'\ - #Especifica la ecuacion de velocidad a usar en cada nivel del modelo - for c,i in enumerate(types): - if i==1 or i==2: - models.speed_type[c]=i - else: - models.speed_type[c]=1 - - def set_Floods(self,var,VarName, umbral = 1000, NumCeldas = 6, Default = False): - 'Descripcion: Aloja las variables del sub modelo de inundaciones\n'\ - '\n'\ - 'Parametros\n'\ - 'Mierda PUTA\n'\ - '----------\n'\ - 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ - 'varName: Nombre de la variable a ingresar en el modelo.\n'\ - ' GammaWater : Densidad del agua (Defecto: 1000).\n'\ - ' GammaSoil : Densidad del sedimento (Defecto: 2600).\n'\ - ' VelArea: Factor conversion Velocidad - Area (Defecto: 1/200).\n'\ - ' Cmax: Maxima concentracion de sedimentos (Defecto 0.75).\n'\ - ' MaxIter: Cantidad maxima de iteraciones para obtener la mancha de inunudacion.\n'\ - ' VelUmbral: Velocidad minima para que se de el flujo de escombros ( Defecto: 3 m/s).\n'\ - ' Stream_W: Ancho del canal en cada celda (ncells).\n'\ - ' Stream_D50: Tamano de particula percentil 50 (ncells).\n'\ - ' HAND: Modelo de elevacion relativa de celda ladera a celda cauce (ncells), no se ponde nada.\n'\ - ' umbral: Umbral para determinar corriente segun HAND debe coincidir con el umbral del modelo.\n'\ - ' Slope: Pendiente del canal, (no se ponde variable)\n'\ - ' Default: Poner o no parametros por defecto (False)\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ - ' wmf.models.flood_dw.\n'\ - ' wmf.models.flood_dsed.\n'\ - ' wmf.models.flood_av.\n'\ - ' wmf.models.flood_cmax.\n'\ - ' wmf.models.flood_d50.\n'\ - ' wmf.models.flood_hand.\n'\ - ' wmf.models.flood_aquien.\n'\ - #Si el modelo es tipo ladera agrega la variable - if self.modelType[0] == 'h': - return 'El modelo por laderas no simula inundaciones.' - #Pone el gamma del agua por defecto - if Default: - models.flood_dw = 1000 - models.flood_dsed = 2600 - models.flood_av = 1./200.0 - models.flood_cmax = 0.75 - models.flood_umbral = 3.0 - models.flood_max_iter = 10 - models.flood_step = 1.0 - #Obtiene el vector que va a alojar en el modelo - if VarName <> 'GammaWater' and VarName <> 'GammaSoil' and VarName <> 'VelArea' and VarName <> 'Cmax' and VarName <> 'VelUmbral': - isVec=False - if type(var) is str: - #Si es un string lee el mapa alojado en esa ruta - Map,Pp = read_map_raster(var) - Vec = self.Transform_Map2Basin(Map,Pp) - isVec=True - elif type(var) is int or float: - Vec = np.ones((1,self.ncells))*var - isVec=True - elif type(var) is np.ndarray and var.shape[0] == self.ncells: - Vec = var - isVec=True - #finalmente mete la variable en el modelo - N = self.ncells - if VarName is 'Stream_W' : - models.flood_w = np.ones((1,N))*Vec - elif VarName is 'Stream_D50': - models.flood_d50 = np.ones((1,N))*Vec - elif VarName is 'HAND': - self.GetGeo_HAND(umbral = umbral) - models.flood_hand = np.ones((1,N))*np.copy(self.CellHAND) - models.flood_aquien = np.ones((1,N))*np.copy(self.CellHAND_drainCell) - elif VarName is 'Slope': - self.GetGeo_Cell_Basics() - models.flood_slope = np.ones((1,N))*np.sin(np.arctan(self.CellSlope)) - elif VarName is 'Sections': - self.GetGeo_Sections(NumCeldas = NumCeldas) - models.flood_sections = np.ones((NumCeldas*2+1,N)) * self.Sections - models.flood_sec_cells = np.ones((NumCeldas*2+1,N)) * self.Sections_Cells - elif VarName == 'GammaWater': - models.flood_dw = var - elif VarName == 'GammaSoil': - models.flood_dsed = var - elif VarName == 'VelArea': - models.flood_av = var - elif VarName == 'Cmax': - models.flood_cmax = var - elif VarName == 'VelUmbral': - models.flood_umbral = var - elif VarName == 'MaxIter': - models.flood_max_iter = var - - def set_PhysicVariables(self,modelVarName,var,pos,mask=None): - 'Descripcion: Coloca las variables fisicas en el modelo \n'\ - ' Se debe assignarel nombre del tipo de variable, la variable\n'\ - ' y la posicion en que esta va a ser insertada\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Objeto de la cuenca 2que luego se va a simular.\n'\ - 'modelVarName : Nombre de la variable del modelo que se va a incertar.\n'\ - ' - h_coef: coeficientes horizontales\n'\ - ' [0]: Flujo de Escorrentia.\n'\ - ' [1]: Flujo Sub-superficial.\n'\ - ' [2]: Flujo subterraneo.\n'\ - ' [3]: Flujo en cauces.\n'\ - ' - h_exp: exponentes del tipo v = h_coef*(A**h_exp)\n'\ - ' [0]: Escorrentia.\n'\ - ' [1]: sub-superficial.\n'\ - ' [2]: subterraneo.\n'\ - ' [3]: cauce.\n'\ - ' - v_coef.\n'\ - ' [0]: Tasa evaporacion.\n'\ - ' [1]: Infiltracion.\n'\ - ' [2]: Percolacion.\n'\ - ' [3]: Perdidas (0).\n'\ - ' - v_exp: procesos verticales no lineales\n'\ - ' (no implementado dentro del modelo)\n' - ' - capilar.\n'\ - ' - gravit.\n'\ - 'var : variable que ingresa en el modelo, esta puede ser:.\n'\ - ' - Ruta: una ruta del tipo string.\n'\ - ' - Escalar : Un valor escalar que se asignara a toda la cuenca.\n'\ - ' - Vector : Un vector con la informacion leida (1,ncells).\n'\ - 'pos : Posicion de insercion, aplica para : h_coef, v_coef,.\n'\ - ' h_exp, v_exp.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Guarda el binario, no hay retorno\n'\ - '\n'\ - 'Mirar Tambien\n'\ - '----------\n'\ - 'rain_interpolate_idw: interpola campos mediante la metodologia idw.\n'\ - 'rain_read_bin: Lee binario de registros para ver que tiene.\n'\ - 'rain_ncf2bin: Convierte ncf a binario en formato del modelo (para imagenes de radar).\n'\ - - #Obtiene el vector que va a alojar en el modelo - isVec=False - if type(var) is str: - #Si es un string lee el mapa alojado en esa ruta - Map,Pp = read_map_raster(var) - Vec = self.Transform_Map2Basin(Map,Pp) - isVec=True - elif type(var) is int or float: - Vec = np.ones((1,self.ncells))*var - isVec=True - elif type(var) is np.ndarray and var.shape[0] == self.ncells: - Vec = var - isVec=True - #Si el modelo es tipo ladera agrega la variable - if self.modelType[0] is 'h': - Vec = self.Transform_Basin2Hills(Vec,mask=mask) - #finalmente mete la variable en el modelo - if modelVarName is 'h_coef': - models.h_coef[pos] = Vec - elif modelVarName is 'h_exp': - models.h_exp[pos] = Vec - elif modelVarName is 'v_coef': - models.v_coef[pos] = Vec - elif modelVarName is 'v_exp': - models.v_exp[pos] = Vec - elif modelVarName is 'capilar': - models.max_capilar[0] = Vec - elif modelVarName is 'gravit': - models.max_gravita[0] = Vec - - def set_Storage(self,var,pos,hour_scale=False): - 'Descripcion: \n'\ - ' Establece el almacenamiento inicial del modelo\n'\ - ' la variable puede ser un valor, una ruta o un vector.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'var : Variable con la cual se va a iniciar el almancenamiento.\n'\ - ' - ruta : es una ruta a un archivo binario de almacenamiento.\n'\ - ' - escalar : valor de almacenamiento constate para toda la cuenca.\n'\ - ' - vector : Vector con valores para cadda unidad de la cuenca.\n'\ - 'pos : Posicion de insercion,.\n'\ - ' - 0 : alm cpailar.\n'\ - ' - 1 : alm superficial.\n'\ - ' - 2 : alm sub-superficial.\n'\ - ' - 3 : alm subterraneo.\n'\ - ' - 4 : alm cauce.\n'\ - ' - fecha: en caso de que var sea la ruta a StOhdr:\n'\ - ' - valor: puede ser un entero con la posicion.\n'\ - ' - str fecha: puede ser un srint con la fecha: YYYY-MM-DD-HH:MM :\n'\ - 'hour_scale: Buscar fechas a escala horaria o minutos?.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Guarda el binario, no hay retorno\n'\ - '\n'\ - 'Mirar Tambien\n'\ - '----------\n'\ - 'save_storage(slef,storage).\n'\ - #Determina el tipo de unidades del modelo - if self.modelType[0] is 'c': - N = self.ncells - elif self.modelType[0] is 'h': - N = self.nhills - #Obtiene el vector que va a alojar en el modelo - isVec=False - if type(var) is str: - var_bin,var_hdr = __Add_hdr_bin_2route__(var,storage = True) - if type(pos) is not str: - #Si es un string lee el binario de almacenamiento alojado en esa ruta - Vec,res = models.read_float_basin_ncol(var_bin,pos+1,N,5) - if type(pos) == str: - # Lee las fechas - L = np.loadtxt(var_hdr,skiprows = 5, usecols = (0,6), dtype = str) - if hour_scale == False: - Fechas = [datetime.datetime.strptime(i[1], '%Y-%m-%d-%H:%M') for i in L] - else: - Fechas = [datetime.datetime.strptime(i[1][:-3], '%Y-%m-%d-%H') for i in L] - try: - if hour_scale == False: - posFecha = Fechas.index(datetime.datetime.strptime(pos, '%Y-%m-%d-%H:%M')) - else: - posFecha = Fechas.index(datetime.datetime.strptime(pos[:-3], '%Y-%m-%d-%H')) - except: - print 'Error: no se encuentra la fecha especificada en el archivo '+var - Vec,res = models.read_float_basin_ncol(var_bin,posFecha+1,N,5) - isVec=True - for p in range(5): - models.storage[p] = Vec[p] - elif type(var) is int or float: - Vec = np.ones((1,N))*var - isVec=True - models.storage[pos] = Vec - elif type(var) is np.ndarray and var.shape[0] == N: - Vec = var - isVec=True - models.storage[pos] = Vec - - def set_Control(self,coordXY,ids,tipo = 'Q'): - 'Descripcion: \n'\ - ' Establece los puntos deonde se va a realizar control del caudal\n'\ - ' y de la humedad simulada.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'coordXY : Coordenadas de los puntos de control [2,Ncontrol].\n'\ - 'ids : Identificacion de los puntos de control.\n'\ - 'tipo: Control para caudal [Q] o para humedad [H].\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Define los puntos de control en las variables:\n'\ - ' - models.control : control de caudal y sedimentos.\n'\ - ' - models.control_h : control de la humedad del suelo.\n'\ - 'IdsControl : El orden en que quedaron los puntos de control al interior.\n'\ - '\n'\ - 'Mirar Tambien\n'\ - '----------\n'\ - 'set_record, set_storage.\n'\ - #Obtiene los puntos donde hay coordenadas - if tipo is 'Q': - xyNew, basinPts, order = self.Points_Points2Stream(coordXY,ids) - if self.modelType[0] is 'c': - models.control[0] = basinPts - IdsConvert = basinPts[basinPts<>0] - elif self.modelType[0] is 'h': - unitario = basinPts / basinPts - pos = self.hills_own * self.CellCauce * unitario - posGrande = self.hills_own * self.CellCauce * basinPts - IdsConvert = posGrande[posGrande<>0] / pos[pos<>0] - models.control[0][pos[pos<>0].astype(int).tolist()] = IdsConvert - elif tipo is 'H': - xyNew = coordXY - basinPts, order = self.Points_Points2Basin(coordXY,ids) - if self.modelType[0] == 'c': - models.control_h[0] = basinPts - IdsConvert = basinPts[basinPts<>0] - elif self.modelType[0] == 'h': - unitario = basinPts / basinPts - pos = self.hills_own * unitario - posGrande = self.hills_own * basinPts - IdsConvert = posGrande[posGrande<>0] / pos[pos<>0] - models.control_h[0][pos[pos<>0].astype(int).tolist()] = IdsConvert - return IdsConvert,xyNew - - - def set_sediments(self,var,VarName, wi = [0.036, 2.2e-4, 8.6e-7], - diametro = [0.35, 0.016, 0.001], G = 9.8): - 'Descripcion: Alojas las variables requeridas para la ejecucion\n'\ - ' del modelo de sedimentos.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ - 'varName: Nombre de la variable a ingresar en el modelo.\n'\ - ' Krus : Erosividad del suelo (RUSLE).\n'\ - ' Crus : Cobertura del suelo (RUSLE).\n'\ - ' Prus : Practicas proteccion (RUSLE).\n'\ - ' PArLiAc : Porcentaje Arenas, Limos y Arcillas.\n'\ - ' wi : velocidad de caida de cada particula de sed [m/s].\n'\ - ' diametro : diametro de cada tipo de sedimento [mm].\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ - ' wmf.models.krus.\n'\ - ' wmf.models.crus.\n'\ - ' wmf.models.prus.\n'\ - ' wmf.models.parliac.\n'\ - ' wmf.models.wi.\n'\ - ' wmf.models.diametro.\n'\ - #Determina el tipo de unidades del modelo - if self.modelType[0] is 'c': - N = self.ncells - elif self.modelType[0] is 'h': - N = self.nhills - #Se fija que tipo de variable es - isVec=False - if type(var) is str: - #Si es un string lee el mapa alojado en esa ruta - Map,Pp = read_map_raster(var) - Vec = self.Transform_Map2Basin(Map,Pp) - isVec=True - elif type(var) is int or float: - Vec = np.ones((1,self.ncells))*var - isVec=True - elif type(var) is np.ndarray and var.shape[0] == self.ncells: - Vec = var - isVec=True - #Si el modelo es tipo ladera agrega la variable - if self.modelType[0] is 'h': - Vec = self.Transform_Basin2Hills(Vec,mask=mask) - #Inicia las variables - if VarName == 'Krus': - models.krus = np.ones((1,N))*Vec - if VarName == 'Prus': - models.prus = np.ones((1,N))*Vec - if VarName == 'Crus': - models.crus = np.ones((1,N))*Vec - if VarName == 'PArLiAc': - models.parliac = np.ones((3,N))*Vec - #Variables de diametro y velocidad de caida - models.wi = wi - models.diametro = diametro - models.g = G - - def set_Slides(self,var,VarName): - 'Descripcion: Alojas las variables requeridas para la ejecucion\n'\ - ' del modelo de deslizamientos.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ - 'varName: Nombre de la variable a ingresar en el modelo.\n'\ - ' Zs : Profundidad del suelo.\n'\ - ' GammaSoil: Densidad del suelo.\n'\ - ' Cohesion: Cohesion del suelo.\n'\ - ' FrictionAngle : Angulo de friccion del suelo.\n'\ - ' FS: Factor de Seguridad, en este caso se envia una constante.\n'\ - ' RadSlope : .\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ - ' wmf.models.sl_zs.\n'\ - ' wmf.models.sl_gammas.\n'\ - ' wmf.models.sl_cohesion.\n'\ - ' wmf.models.sl_frictionangle.\n'\ - ' wmf.models.sl_radslope.\n'\ - ' wmf.models.sl_fs.\n'\ - #Pone el gamma del agua por defecto - models.sl_gammaw = 9.8 - #Obtiene el vector que va a alojar en el modelo - if VarName <> 'FS': - isVec=False - if type(var) is str: - #Si es un string lee el mapa alojado en esa ruta - Map,Pp = read_map_raster(var) - Vec = self.Transform_Map2Basin(Map,Pp) - isVec=True - elif type(var) is int or float: - Vec = np.ones((1,self.ncells))*var - isVec=True - elif type(var) is np.ndarray and var.shape[0] == self.ncells: - Vec = var - isVec=True - #Si el modelo es tipo ladera agrega la variable - if self.modelType[0] == 'h': - return 'El modelo por laderas no simula deslizamientos.' - #finalmente mete la variable en el modelo - N = self.ncells - if VarName is 'GammaSoil' : - models.sl_gammas = np.ones((1,N))*Vec - elif VarName is 'Cohesion': - models.sl_cohesion = np.ones((1,N))*Vec - elif VarName is 'FrictionAngle': - models.sl_frictionangle = np.ones((1,N))*np.deg2rad(Vec) - elif VarName is 'Zs': - models.sl_zs = np.ones((1,N))*Vec - elif VarName is 'FS': - models.sl_fs = var - elif VarName is 'Slope': - models.sl_radslope = np.ones((1,N))*np.arctan(Vec) - models.sl_radslope[models.sl_radslope == 0] = 0.01 - #------------------------------------------------------ - # Guardado y Cargado de modelos de cuencas preparados - #------------------------------------------------------ - def Save_SimuBasin(self,ruta,SimSlides = False, - ExtraVar = None): - 'Descripcion: guarda una cuenca previamente ejecutada\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'ruta : Ruta donde la cuenca sera guardada.\n'\ - 'ruta_dem : direccion donde se aloja el DEM (se recomienda absoluta).\n'\ - 'ruta_dir : direccion donde se aloja el DIR (se recomienda absoluta).\n'\ - 'SimSlides: indica a la funcion si va a guardar o no informacion para la simulacion.\n'\ - ' de deslizamientos.\n'\ - 'ExtraVar: Variables extras de simulacion deben ir en un diccionario.\n'\ - ' Forma del diccionario Dict = {"varName": {"Data": vector[ncells], "type": "tipo"}}.\n'\ - ' Los tipos de variables son: flotante: "f4", entero "i4".\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'self : Con las variables iniciadas.\n'\ - #Si esta o no set el Geomorphology, de acuerdo a eso lo estima por defecto - if self.isSetGeo is False: - self.set_Geomorphology() - print 'Aviso: SE ha estimado la geomorfologia con los umbrales por defecto umbral = [30, 500]' - #Guarda la cuenca - if self.modelType[0] is 'c': - N = self.ncells - elif self.modelType[0] is 'h': - N = self.nhills - Dict = {'nombre':self.name, - 'modelType':self.modelType,'noData':cu.nodata,'umbral':self.umbral, - 'ncells':self.ncells,'nhills':self.nhills, - 'dt':models.dt,'Nelem':N,'dxp':cu.dxp,'retorno':models.retorno, - 'storageConst' :models.storage_constant, - 'ncols':cu.ncols, - 'nrows':cu.nrows, - 'xll':cu.xll, - 'yll':cu.yll, - 'dx':cu.dx, - 'dy':cu.dy, - 'epsg': self.epsg} - if SimSlides: - Dict.update({'sl_fs':models.sl_fs, 'sl_gullie':models.sl_gullienogullie, 'sl_gammaw':models.sl_gammaw}) - #abre el archivo - gr = netcdf.Dataset(ruta,'w',format='NETCDF4') - #Grupo base - GrupoBase = gr.createGroup('base') - GrupoSimHid = gr.createGroup('SimHidro') - GrupoSimSed = gr.createGroup('SimSediments') - GrupoSimSli = gr.createGroup('SimSlides') - GrupoHidro = gr.createGroup('Hidro') - GrupoGeo = gr.createGroup('Geomorfo') - GrupoCalib = gr.createGroup('Parametros') - #Variables grupo base - DimNcell = GrupoBase.createDimension('ncell',self.ncells) - DimNhill = GrupoBase.createDimension('nhills',self.nhills) - DimCol3 = GrupoBase.createDimension('col3',3) - DimCol2 = GrupoBase.createDimension('col2',2) - VarStruc = GrupoBase.createVariable('structure','i4',('col3','ncell'),zlib=True) - VarHills = GrupoBase.createVariable('hills','i4',('col2','nhills'),zlib=True) - VarHills_own = GrupoBase.createVariable('hills_own','i4',('ncell',),zlib=True) - VarStruc[:] = self.structure - VarHills[:] = self.hills - VarHills_own[:] = self.hills_own - #Variables de Simulacion hidrologica - DimNelem = GrupoSimHid.createDimension('Nelem',N) - DimCol3 = GrupoSimHid.createDimension('col3',3) - DimCol2 = GrupoSimHid.createDimension('col2',2) - DimCol4 = GrupoSimHid.createDimension('col4',4) - DimCol5 = GrupoSimHid.createDimension('col5',5) - VarH_coef = GrupoSimHid.createVariable('h_coef','f4',('col4','Nelem'),zlib=True) - VarV_coef = GrupoSimHid.createVariable('v_coef','f4',('col4','Nelem'),zlib=True) - VarH_exp = GrupoSimHid.createVariable('h_exp','f4',('col4','Nelem'),zlib=True) - VarV_exp = GrupoSimHid.createVariable('v_exp','f4',('col4','Nelem'),zlib=True) - Var_H1max = GrupoSimHid.createVariable('h1_max','f4',('Nelem',),zlib = True) - Var_H3max = GrupoSimHid.createVariable('h3_max','f4',('Nelem',),zlib = True) - Control = GrupoSimHid.createVariable('control','i4',('Nelem',),zlib = True) - ControlH = GrupoSimHid.createVariable('control_h','i4',('Nelem',),zlib = True) - if self.modelType[0] is 'c': - drena = GrupoSimHid.createVariable('drena','i4',('col3','Nelem'),zlib = True) - elif self.modelType[0] is 'h': - drena = GrupoSimHid.createVariable('drena','i4',('Nelem'),zlib = True) - unitType = GrupoSimHid.createVariable('unit_type','i4',('Nelem',),zlib = True) - hill_long = GrupoSimHid.createVariable('hill_long','f4',('Nelem',),zlib = True) - hill_slope = GrupoSimHid.createVariable('hill_slope','f4',('Nelem',),zlib = True) - stream_long = GrupoSimHid.createVariable('stream_long','f4',('Nelem',),zlib = True) - stream_slope = GrupoSimHid.createVariable('stream_slope','f4',('Nelem',),zlib = True) - stream_width = GrupoSimHid.createVariable('stream_width','f4',('Nelem',),zlib = True) - elem_area = GrupoSimHid.createVariable('elem_area','f4',('Nelem',),zlib = True) - speed_type = GrupoSimHid.createVariable('speed_type','i4',('col3',),zlib = True) - storage = GrupoSimHid.createVariable('storage','i4',('col5','Nelem'),zlib = True) - VarH_coef[:] = models.h_coef - VarV_coef[:] = models.v_coef - VarH_exp[:] = models.h_exp - VarV_exp[:] = models.v_exp - Var_H1max[:] = models.max_capilar - Var_H3max[:] = models.max_gravita - Control[:] = models.control - ControlH[:] = models.control_h - drena[:] = models.drena - unitType[:] = models.unit_type - hill_long[:] = models.hill_long - hill_slope[:] = models.hill_slope - stream_long[:] = models.stream_long - stream_slope[:] = models.stream_slope - stream_width[:] = models.stream_width - elem_area[:] = models.elem_area - speed_type[:] = models.speed_type - storage[:] = models.storage - #Variables grupo GEomorfologia - DimNcell = GrupoGeo.createDimension('ncell',self.ncells) - VarDEM = GrupoGeo.createVariable('DEM','f4',('ncell',),zlib = True) - VarDIR = GrupoGeo.createVariable('DIR','i4',('ncell',),zlib = True) - VarDEM[:] = self.DEMvec - VarDIR[:] = self.DIRvec - #Variables de deslizamientos - if SimSlides: - DimNelem = GrupoSimSli.createDimension('Nelem',N) - frictionAngle = GrupoSimSli.createVariable('friction_angle','f4',('Nelem',),zlib = True) - Cohesion = GrupoSimSli.createVariable('cohesion','f4',('Nelem',),zlib = True) - GammaSoil = GrupoSimSli.createVariable('gamma_soil','f4',('Nelem',),zlib = True) - ZSoil = GrupoSimSli.createVariable('z_soil','f4',('Nelem',),zlib = True) - RadSlope = GrupoSimSli.createVariable('rad_slope','f4',('Nelem',),zlib = True) - frictionAngle[:] = models.sl_frictionangle - Cohesion[:] = models.sl_cohesion - GammaSoil[:] = models.sl_gammas - ZSoil[:] = models.sl_zs - RadSlope[:] = models.sl_radslope - #Introduce variables extras en caso de que el usuario las incluyera - if type(ExtraVar) is dict: - for k in ExtraVar.keys(): - Var = gr.createVariable(k,ExtraVar[k]['type'],('ncell',),zlib=True) - Var[:] = ExtraVar[k]['Data'] - #asigna las prop a la cuenca - gr.setncatts(Dict) - #Cierra el archivo - gr.close() - #Sale del programa - return - - #------------------------------------------------------ - # Ejecucion del modelo - #------------------------------------------------------ - def run_shia(self,Calibracion, - rain_rute, N_intervals, start_point = 1, StorageLoc = None, HspeedLoc = None,ruta_storage = None, ruta_speed = None, - ruta_conv = None, ruta_stra = None, ruta_retorno = None,kinematicN = 5, QsimDataFrame = True, EvpVariable = False): - 'Descripcion: Ejecuta el modelo una ves este es preparado\n'\ - ' Antes de su ejecucion se deben tener listas todas las . \n'\ - ' variables requeridas . \n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'self : Cuenca a ejecutar con todo listo para ser ejecutada.\n'\ - 'Calibracion : Parametros de calibracion del modelo, orden:.\n'\ - ' - Evaporacion.\n'\ - ' - Infiltracion.\n'\ - ' - Percolacion.\n'\ - ' - Perdidas.\n'\ - ' - Vel Superficial .\n'\ - ' - Vel Sub-superficial.\n'\ - ' - Vel Subterranea.\n'\ - ' - Vel Cauce.\n'\ - ' - Max Capilar.\n'\ - ' - Max Gravitacional.\n'\ - 'rain_rute : Ruta donde se encuentra el archivo binario de lluvia:.\n'\ - ' generado por rain_interpolate_* o por rain_radar2basin.\n'\ - 'N_intervals : Numero de intervalos de tiempo.\n'\ - 'start_point : Punto donde comienza a usar registros de lluvia.\n'\ - ' los binarios generados por rain_* generan un archivo de texto.\n'\ - ' que contiene fechas par aayudar a ubicar el punto de inicio deseado.\n'\ - 'StorageLoc: Variable local de almacenamiento, esto es en el caso de que no se.\n'\ - ' desee usar la configuracion global de almacenamiento del modelo (5, N).\n'\ - 'HspeedLoc: Variable local para setear la velocidad horizontal inicial de ejecucion.\n'\ - 'ruta_storage : Ruta donde se guardan los estados del modelo en cada intervalo.\n'\ - ' de tiempo, esta es opcional, solo se guardan si esta variable es asignada.\n'\ - 'ruta_conv : Ruta al binario y hdr indicando las nubes que son convectivas.\n'\ - 'ruta_stra : Ruta al binario y hdr indicando las nubes que son estratiformes.\n'\ - 'ruta_retorno : Ruta al binario y hdr en donde escribe la serie con los milimetros retornados al tanque runoff.\n'\ - 'kinematicN: Cantidad de iteraciones para la solucion de la onda cinematica.\n'\ - ' De forma continua: 5 iteraciones, recomendado para cuando el modelo se\n'\ - ' ejecuta en forma continua Ej: cu.run_shia(Calib, rain_rute, 100)\n'\ - ' Por intervalos: 10 iteraciones, recomendado cuando el modelo se ejecuta\n'\ - ' por intervalos de un paso ej:\n'\ - ' for i in range(1,N)\n'\ - ' Results = cu.run_shia(Calib, ruta_rain, 1, i)\n'\ - ' for c,j in enumerate(Results[''Storage'']):\n'\ - ' cu.set_Storage(j,c)\n'\ - 'QsimDataFrame: Retorna un data frame con los caudales simulados indicando su id de acuerdo con el\n'\ - ' que guarda la funcion Save_Net2Map con la opcion NumTramo = True. \n'\ - 'EvpVariable: (False) Asume que la evp del modelo cambia en funcion o no de la radiacion\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - 'Qsim : Caudal simulado en los puntos de control.\n'\ - 'Hsim : Humedad simulada en los puntos de control.\n'\ - #genera las rutas - rain_ruteBin,rain_ruteHdr = __Add_hdr_bin_2route__(rain_rute) - #Obtiene las fechas - Rain = read_mean_rain(rain_ruteHdr, N_intervals, start_point) - # De acuerdo al tipo de modelo determina la cantidad de elementos - if self.modelType[0] is 'c': - N = self.ncells - elif self.modelType[0] is 'h': - N = self.nhills - #prepara variables globales - models.rain_first_point = start_point - models.calc_niter = kinematicN - #Prepara terminos para control - if np.count_nonzero(models.control) == 0 : - NcontrolQ = 1 - else: - NcontrolQ = np.count_nonzero(models.control)+1 - if np.count_nonzero(models.control_h) == 0 : - NcontrolH = 1 - else: - NcontrolH = np.count_nonzero(models.control_h) - #Prepara variables de guardado de almacenamiento - if ruta_storage is not None: - models.save_storage = 1 - ruta_sto_bin, ruta_sto_hdr = __Add_hdr_bin_2route__(ruta_storage, - storage = True) - else: - models.save_storage = 0 - ruta_sto_bin = 'no_guardo_nada.StObin' - ruta_sto_hdr = 'no_guardo_nada.StOhdr' - #prepara variable para guardado de velocidad - if ruta_speed is not None: - models.save_speed = 1 - ruta_speed_bin, ruta_speed_hdr = __Add_hdr_bin_2route__(ruta_speed, - storage = True) - else: - models.save_speed = 0 - ruta_speed_bin = 'no_guardo_nada.bin' - ruta_speed_hdr = 'no_guardo_nada.hdr' - #Prepara variables para el almacenamiento de retorno - if ruta_retorno is not None: - models.save_retorno = 1 - ruta_ret_bin, ruta_ret_hdr = __Add_hdr_bin_2route__(ruta_retorno) - else: - models.save_retorno = 0 - ruta_ret_bin = 'no_guardo_nada.bin' - ruta_ret_hdr = 'no_guardo_nada.hdr' - #Variables de separacion de flujo por tipo de lluvia - if ruta_conv is not None and ruta_stra is not None: - ruta_binConv,ruta_hdrConv = __Add_hdr_bin_2route__(ruta_conv) - ruta_binStra,ruta_hdrStra = __Add_hdr_bin_2route__(ruta_stra) - models.separate_rain = 1 - else: - models.separate_rain = 0 - ruta_binConv = 'none' - ruta_hdrConv = 'none' - ruta_binStra = 'none' - ruta_hdrStra = 'none' - #Prepara la variable de almacenamiento - if StorageLoc is not None: - if StorageLoc.shape <> (5, N): - print 'Error: almacenamiento debe ser: (5,'+str(N)+'), y es: ('+str(StorageLoc.shape[0])+','+str(StorageLoc.shape[1])+')' - StorageLoc = np.zeros((5,N))*-9999.0 - else: - StorageLoc = np.zeros((5,N))*-9999.0 - #Prepara la variable de velocidad horizontal inicial - if HspeedLoc is not None: - if HspeedLoc.shape <> (4, N): - print 'Error: velocidad debe ser: (4,'+str(N)+'), y es: ('+str(HspeedLoc.shape[0])+','+str(HspeedLoc.shape[1])+')' - HspeedLoc = np.zeros((4,N))*-9999.0 - else: - HspeedLoc = np.zeros((4,N))*-9999.0 - #Implementa o no la EVP variable en funcion de la radiacion - if EvpVariable: - Rad = self.__GetEVP_Serie__(Rain.index) - else: - models.evpserie = np.ones(N_intervals) - # Ejecuta el modelo - Qsim,Qsed,Qseparated,Humedad,St1,St3,Balance,Speed,Area,Alm,Qsep_byrain = models.shia_v1( - rain_ruteBin, - rain_ruteHdr, - Calibracion, - #N, - NcontrolQ, - NcontrolH, - N_intervals, - StorageLoc, - HspeedLoc, - N, - ruta_sto_bin, - ruta_speed_bin, - ruta_binConv, - ruta_binStra, - ruta_hdrConv, - ruta_hdrStra, - ruta_ret_bin) - #Retorno de variables de acuerdo a lo simulado - Retornos={'Qsim' : Qsim} - Retornos.update({'Balance' : Balance}) - Retornos.update({'Storage' : Alm}) - if np.count_nonzero(models.control_h)>0: - Retornos.update({'Humedad' : Humedad}) - Retornos.update({'Humedad_t1' : St1}) - Retornos.update({'Humedad_t2' : St3}) - if models.sim_sediments == 1: - Retornos.update({'Sediments' : Qsed}) - if models.separate_fluxes == 1: - Retornos.update({'Fluxes' : Qseparated}) - if models.separate_rain == 1: - Retornos.update({'Rain_sep' : Qsep_byrain}) - if models.show_storage == 1: - Retornos.update({'Mean_Storage' : np.copy(models.mean_storage)}) - if models.save_storage == 1: - rutaStorageHdr = __Add_hdr_bin_2route__(ruta_storage) - #Caso en el que se registra el alm medio - if models.show_storage == 1: - __Save_storage_hdr__(ruta_sto_hdr,rain_ruteHdr,N_intervals, - start_point,self,Mean_Storage = np.copy(models.mean_storage)) - #Caso en el que no hay alm medio para cada uno de los - else: - __Save_storage_hdr__(ruta_sto_hdr,rain_ruteHdr,N_intervals, - start_point,self,Mean_Storage=np.zeros((5,N))*-9999) - #Area de la seccion - if models.show_area == 1: - Retornos.update({'Sec_Area': Area}) - #Velocidades - if models.show_speed == 1: - Retornos.update({'Speed' : Speed}) - if models.show_mean_speed == 1: - Retornos.update({'Mean_Speed' : np.copy(models.mean_speed)}) - if models.save_speed == 1: - rutaSpeedHdr = __Add_hdr_bin_2route__(ruta_speed) - #Caso en el que hay velocidad media para todos los tanques - if models.show_mean_speed == 1: - __Save_speed_hdr__(ruta_speed_hdr,rain_ruteHdr,N_intervals, - start_point,self,Mean_Speed = np.copy(models.mean_speed)) - #Caso en el que no hay alm medio para cada uno de los - else: - __Save_speed_hdr__(ruta_speed_hdr,rain_ruteHdr,N_intervals, - start_point,self) - - if models.save_retorno == 1: - if models.show_mean_retorno == 1: - __Save_retorno_hdr__(ruta_ret_hdr, rain_ruteHdr, N_intervals, - start_point, self, Mean_retorno = models.mean_retorno) - else: - __Save_retorno_hdr__(ruta_ret_hdr, rain_ruteHdr, N_intervals, - start_point, self) - - #Campo de lluvia acumulado para el evento - Retornos.update({'Rain_Acum': models.acum_rain}) - Retornos.update({'Rain_hietogram': models.mean_rain}) - #Retornos en caso de simular deslizamientos - if models.sim_slides == 1: - Retornos.update({'Slides_Map': np.copy(models.sl_slideocurrence)}) - Retornos.update({'Slides_NCell_Serie': np.copy(models.sl_slidencelltime)}) - Retornos.update({'Slides_Acum':np.copy(models.sl_slideacumulate)}) - #Caudal simulado en un dataframe - if QsimDataFrame: - #Obtiene ids - ids = models.control[models.control<>0] - Qdict = {} - for i,j in zip(Retornos['Qsim'][1:], ids): - Qdict.update({str(j): i}) - Qdict = pd.DataFrame(Qdict, index=Rain.index) - #Si separa flujos, entrega el caudal tambien en data frame por flujos - if models.separate_fluxes == 1: - Qsep = [] - tupla = [] - for z,i,j in zip(Retornos['Qsim'][1:], Retornos['Fluxes'][1:], ids): - tupla.append((str(j),'run')) - tupla.append((str(j),'sub')) - tupla.append((str(j),'sup')) - Qsep.extend([i[0],i[1],z-i[0]-i[1]]) - index = pd.MultiIndex.from_tuples(tupla, names=['reach','flux']) - Qsep = np.array(Qsep) - QsepDict = pd.DataFrame(Qsep.T, index=Rain.index, columns=index) - #Si simula sedimentos, hace el dataframe - if models.sim_sediments == 1: - Qsedi = [] - tupla = [] - for z,i,j in zip(Retornos['Qsim'][1:], Retornos['Sediments'][1:], ids): - tupla.append((str(j),'Sand')) - tupla.append((str(j),'Lime')) - tupla.append((str(j),'Clay')) - Qsedi.extend([i[0],i[1],i[2]])# [i[0],i[1],z-i[0]-i[1]]) - index = pd.MultiIndex.from_tuples(tupla, names=['reach','Sediments']) - Qsedi = np.array(Qsedi) - QsediDict = pd.DataFrame(Qsedi.T, index=Rain.index, columns=index) - if models.separate_fluxes == 1 and models.sim_sediments == 0: - return Retornos, Qdict, QsepDict - if models.separate_fluxes == 1 and models.sim_sediments == 1: - return Retornos, Qdict, QsepDict, QsediDict - if models.separate_fluxes == 0 and models.sim_sediments == 1: - return Retornos, Qdict, QsediDict - return Retornos, Qdict - return Retornos - - def efficiencia(self, Qobs, Qsim): - 'Descripcion: Calcula diferentes indices de desempeno del modelo\n'\ - ' nash, qpico, rmse, rmseLog, t_pico\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - 'Qobs : Caudal observado.\n'\ - 'Qsim : Caudal simulado.\n'\ - 'Retornos\n'\ - '----------\n'\ - 'DicEff: diccionario con la eficiencia obtenida en cada param.\n'\ - #Comienza a evaluar cada parametro - DictEff = {'Nash': __eval_nash__(Qobs, Qsim)} - DictEff.update({'Qpico': __eval_q_pico__(Qobs, Qsim)}) - DictEff.update({'Tpico': __eval_t_pico__(Qobs, Qsim, models.dt)}) - DictEff.update({'RmseLog': __eval_rmse_log__(Qobs, Qsim)}) - DictEff.update({'Rmse': __eval_rmse__(Qobs, Qsim)}) - return DictEff - - def Calib_NSGAII(self, nsga_el, nodo_eval, pop_size = 40, process = 4, - NGEN = 6, MUTPB = 0.5, CXPB = 0.5): - 'Descripcion: Algoritmo para calibrar de forma automatica el modelo\n'\ - ' hidrologico utilizando DEAP y su funcion de seleccion NSGAII.\n'\ - '\n'\ - 'Parametros\n'\ - '----------\n'\ - ' - nsga_el : un objeto de la clase nsgaii_element, el cual determinara las reglas.\n'\ - ' para la generacion de calibraciones.\n'\ - ' - nodo_eval: nodo donde se evalua el modelo.\n'\ - ' - pop_size: tamano de la poblacion (cantidad de calibraciones a evaluar, multiplo de 4).\n'\ - ' - process: Cantidad de procesadores que se utilizaran en la generacion.\n'\ - ' - NGEN: Cantidad de generaciones para obtener la poblacion final.\n'\ - ' - MUTPB: Probabilidad generica de que un gen mute.\n'\ - ' - CXPB: Probabilidad generica de que dos genes se crucen.\n'\ - '\n'\ - 'Retornos\n'\ - '----------\n'\ - ' - pop: poblacion final.\n'\ - ' - Qsim: Caudales simulados en el punto evaluado.\n'\ - ' - fitness: desempeno de la poblacion obtenida.\n'\ - #Check de que la poblacion sea multiplo de 4 - Flag = True - while Flag: - if np.mod(pop_size,4) == 0: - Flag = False - else: - pop_size += 1 - #Inicia el elemento nsga con los parametros de el - nsga_el.set_nsgaII() - #Crea las poblaciones y las ejecuciones - pop = nsga_el.toolbox.population(pop_size) - Ejecs = map(nsga_el.__crea_ejec__, pop) - #Ejecuta a la poblacion - QsimPar = __ejec_parallel__(Ejecs, process, nodo_eval) - fitnesses = map(nsga_el.toolbox.evaluate, QsimPar) - for ind, fit in zip(pop, fitnesses): - ind.fitness.values = fit - #Itera la poblacion hasta encontrar a la mejor - #toolbox = base.Toolbox() - for g in range(NGEN): - offspring = tools.selTournamentDCD(pop, len(pop)) - offspring = map(nsga_el.toolbox.clone, offspring) - # Apply crossover and mutation on the offspring - for child1, child2 in zip(offspring[::2], offspring[1::2]): - if random.random() < CXPB: - nsga_el.toolbox.mate(child1[0], child2[0]) - del child1.fitness.values - del child2.fitness.values - #Muta a algunos de los genomas - for mutant in offspring: - if random.random() < MUTPB: - nsga_el.toolbox.mutate(mutant[0]) - del mutant.fitness.values - #Ejecuta a la nueva generacion - Ejecs = map(nsga_el.__crea_ejec__, offspring) - QsimPar = __ejec_parallel__(Ejecs, process, nodo_eval) - #Identifica a la gente que no cumple de la generacion - Qsim_invalid = [] - invalid_ind = [] - for i,q in zip(offspring, QsimPar): - if not i.fitness.valid: - Qsim_invalid.append(q) - invalid_ind.append(i) - #Evaluate the individuals with an invalid fitness - fitnesses = map(nsga_el.toolbox.evaluate, Qsim_invalid) - for ind, fit in zip(invalid_ind, fitnesses): - ind.fitness.values = fit - #Toma la siguiente generacion - pop = nsga_el.toolbox.select(pop + offspring, pop_size) - #Retorno - return pop, QsimPar, np.array(fitnesses).T + def set_Storage(self,var,pos,hour_scale=False): + 'Descripcion: \n'\ + ' Establece el almacenamiento inicial del modelo\n'\ + ' la variable puede ser un valor, una ruta o un vector.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'var : Variable con la cual se va a iniciar el almancenamiento.\n'\ + ' - ruta : es una ruta a un archivo binario de almacenamiento.\n'\ + ' - escalar : valor de almacenamiento constate para toda la cuenca.\n'\ + ' - vector : Vector con valores para cadda unidad de la cuenca.\n'\ + 'pos : Posicion de insercion,.\n'\ + ' - 0 : alm cpailar.\n'\ + ' - 1 : alm superficial.\n'\ + ' - 2 : alm sub-superficial.\n'\ + ' - 3 : alm subterraneo.\n'\ + ' - 4 : alm cauce.\n'\ + ' - fecha: en caso de que var sea la ruta a StOhdr:\n'\ + ' - valor: puede ser un entero con la posicion.\n'\ + ' - str fecha: puede ser un srint con la fecha: YYYY-MM-DD-HH:MM :\n'\ + 'hour_scale: Buscar fechas a escala horaria o minutos?.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Guarda el binario, no hay retorno\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'save_storage(slef,storage).\n'\ + #Determina el tipo de unidades del modelo + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + #Obtiene el vector que va a alojar en el modelo + isVec=False + if type(var) is str: + var_bin,var_hdr = __Add_hdr_bin_2route__(var,storage = True) + if type(pos) is not str: + #Si es un string lee el binario de almacenamiento alojado en esa ruta + Vec,res = models.read_float_basin_ncol(var_bin,pos+1,N,5) + if type(pos) == str: + # Lee las fechas + L = np.loadtxt(var_hdr,skiprows = 5, usecols = (0,6), dtype = str) + if hour_scale == False: + Fechas = [datetime.datetime.strptime(i[1], '%Y-%m-%d-%H:%M') for i in L] + else: + Fechas = [datetime.datetime.strptime(i[1][:-3], '%Y-%m-%d-%H') for i in L] + try: + if hour_scale == False: + posFecha = Fechas.index(datetime.datetime.strptime(pos, '%Y-%m-%d-%H:%M')) + else: + posFecha = Fechas.index(datetime.datetime.strptime(pos[:-3], '%Y-%m-%d-%H')) + except: + print 'Error: no se encuentra la fecha especificada en el archivo '+var + Vec,res = models.read_float_basin_ncol(var_bin,posFecha+1,N,5) + isVec=True + for p in range(5): + models.storage[p] = Vec[p] + elif type(var) is int or float: + Vec = np.ones((1,N))*var + isVec=True + models.storage[pos] = Vec + elif type(var) is np.ndarray and var.shape[0] == N: + Vec = var + isVec=True + models.storage[pos] = Vec + + def set_Control(self,coordXY,ids,tipo = 'Q'): + 'Descripcion: \n'\ + ' Establece los puntos deonde se va a realizar control del caudal\n'\ + ' y de la humedad simulada.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'coordXY : Coordenadas de los puntos de control [2,Ncontrol].\n'\ + 'ids : Identificacion de los puntos de control.\n'\ + 'tipo: Control para caudal [Q] o para humedad [H].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Define los puntos de control en las variables:\n'\ + ' - models.control : control de caudal y sedimentos.\n'\ + ' - models.control_h : control de la humedad del suelo.\n'\ + 'IdsControl : El orden en que quedaron los puntos de control al interior.\n'\ + '\n'\ + 'Mirar Tambien\n'\ + '----------\n'\ + 'set_record, set_storage.\n'\ + #Obtiene los puntos donde hay coordenadas + if tipo is 'Q': + xyNew, basinPts, order = self.Points_Points2Stream(coordXY,ids) + if self.modelType[0] is 'c': + models.control[0] = basinPts + IdsConvert = basinPts[basinPts<>0] + elif self.modelType[0] is 'h': + unitario = basinPts / basinPts + pos = self.hills_own * self.CellCauce * unitario + posGrande = self.hills_own * self.CellCauce * basinPts + IdsConvert = posGrande[posGrande<>0] / pos[pos<>0] + models.control[0][pos[pos<>0].astype(int).tolist()] = IdsConvert + elif tipo is 'H': + xyNew = coordXY + basinPts, order = self.Points_Points2Basin(coordXY,ids) + if self.modelType[0] == 'c': + models.control_h[0] = basinPts + IdsConvert = basinPts[basinPts<>0] + elif self.modelType[0] == 'h': + unitario = basinPts / basinPts + pos = self.hills_own * unitario + posGrande = self.hills_own * basinPts + IdsConvert = posGrande[posGrande<>0] / pos[pos<>0] + models.control_h[0][pos[pos<>0].astype(int).tolist()] = IdsConvert + return IdsConvert,xyNew + + + def set_sediments(self,var,VarName, wi = [0.036, 2.2e-4, 8.6e-7], + diametro = [0.35, 0.016, 0.001], G = 9.8): + 'Descripcion: Alojas las variables requeridas para la ejecucion\n'\ + ' del modelo de sedimentos.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ + 'varName: Nombre de la variable a ingresar en el modelo.\n'\ + ' Krus : Erosividad del suelo (RUSLE).\n'\ + ' Crus : Cobertura del suelo (RUSLE).\n'\ + ' Prus : Practicas proteccion (RUSLE).\n'\ + ' PArLiAc : Porcentaje Arenas, Limos y Arcillas.\n'\ + ' wi : velocidad de caida de cada particula de sed [m/s].\n'\ + ' diametro : diametro de cada tipo de sedimento [mm].\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ + ' wmf.models.krus.\n'\ + ' wmf.models.crus.\n'\ + ' wmf.models.prus.\n'\ + ' wmf.models.parliac.\n'\ + ' wmf.models.wi.\n'\ + ' wmf.models.diametro.\n'\ + #Determina el tipo de unidades del modelo + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + #Se fija que tipo de variable es + isVec=False + if type(var) is str: + #Si es un string lee el mapa alojado en esa ruta + Map,Pp = read_map_raster(var) + Vec = self.Transform_Map2Basin(Map,Pp) + isVec=True + elif type(var) is int or float: + Vec = np.ones((1,self.ncells))*var + isVec=True + elif type(var) is np.ndarray and var.shape[0] == self.ncells: + Vec = var + isVec=True + #Si el modelo es tipo ladera agrega la variable + if self.modelType[0] is 'h': + Vec = self.Transform_Basin2Hills(Vec,mask=mask) + #Inicia las variables + if VarName == 'Krus': + models.krus = np.ones((1,N))*Vec + if VarName == 'Prus': + models.prus = np.ones((1,N))*Vec + if VarName == 'Crus': + models.crus = np.ones((1,N))*Vec + if VarName == 'PArLiAc': + models.parliac = np.ones((3,N))*Vec + #Variables de diametro y velocidad de caida + models.wi = wi + models.diametro = diametro + models.g = G + + def set_Slides(self,var,VarName): + 'Descripcion: Alojas las variables requeridas para la ejecucion\n'\ + ' del modelo de deslizamientos.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'var : Variable que describe la propiedad (constante, ruta, mapa o vector).\n'\ + 'varName: Nombre de la variable a ingresar en el modelo.\n'\ + ' Zs : Profundidad del suelo.\n'\ + ' GammaSoil: Densidad del suelo.\n'\ + ' Cohesion: Cohesion del suelo.\n'\ + ' FrictionAngle : Angulo de friccion del suelo.\n'\ + ' FS: Factor de Seguridad, en este caso se envia una constante.\n'\ + ' RadSlope : .\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : variables iniciadas en el modelo bajo los nombres de:.\n'\ + ' wmf.models.sl_zs.\n'\ + ' wmf.models.sl_gammas.\n'\ + ' wmf.models.sl_cohesion.\n'\ + ' wmf.models.sl_frictionangle.\n'\ + ' wmf.models.sl_radslope.\n'\ + ' wmf.models.sl_fs.\n'\ + #Pone el gamma del agua por defecto + models.sl_gammaw = 9.8 + #Obtiene el vector que va a alojar en el modelo + if VarName <> 'FS': + isVec=False + if type(var) is str: + #Si es un string lee el mapa alojado en esa ruta + Map,Pp = read_map_raster(var) + Vec = self.Transform_Map2Basin(Map,Pp) + isVec=True + elif type(var) is int or float: + Vec = np.ones((1,self.ncells))*var + isVec=True + elif type(var) is np.ndarray and var.shape[0] == self.ncells: + Vec = var + isVec=True + #Si el modelo es tipo ladera agrega la variable + if self.modelType[0] == 'h': + return 'El modelo por laderas no simula deslizamientos.' + #finalmente mete la variable en el modelo + N = self.ncells + if VarName is 'GammaSoil' : + models.sl_gammas = np.ones((1,N))*Vec + elif VarName is 'Cohesion': + models.sl_cohesion = np.ones((1,N))*Vec + elif VarName is 'FrictionAngle': + models.sl_frictionangle = np.ones((1,N))*np.deg2rad(Vec) + elif VarName is 'Zs': + models.sl_zs = np.ones((1,N))*Vec + elif VarName is 'FS': + models.sl_fs = var + elif VarName is 'Slope': + models.sl_radslope = np.ones((1,N))*np.arctan(Vec) + models.sl_radslope[models.sl_radslope == 0] = 0.01 + #------------------------------------------------------ + # Guardado y Cargado de modelos de cuencas preparados + #------------------------------------------------------ + def Save_SimuBasin(self,ruta,SimSlides = False, + ExtraVar = None): + 'Descripcion: guarda una cuenca previamente ejecutada\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'ruta : Ruta donde la cuenca sera guardada.\n'\ + 'ruta_dem : direccion donde se aloja el DEM (se recomienda absoluta).\n'\ + 'ruta_dir : direccion donde se aloja el DIR (se recomienda absoluta).\n'\ + 'SimSlides: indica a la funcion si va a guardar o no informacion para la simulacion.\n'\ + ' de deslizamientos.\n'\ + 'ExtraVar: Variables extras de simulacion deben ir en un diccionario.\n'\ + ' Forma del diccionario Dict = {"varName": {"Data": vector[ncells], "type": "tipo"}}.\n'\ + ' Los tipos de variables son: flotante: "f4", entero "i4".\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'self : Con las variables iniciadas.\n'\ + #Si esta o no set el Geomorphology, de acuerdo a eso lo estima por defecto + if self.isSetGeo is False: + self.set_Geomorphology() + print 'Aviso: SE ha estimado la geomorfologia con los umbrales por defecto umbral = [30, 500]' + #Guarda la cuenca + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + Dict = {'nombre':self.name, + 'modelType':self.modelType,'noData':cu.nodata,'umbral':self.umbral, + 'ncells':self.ncells,'nhills':self.nhills, + 'dt':models.dt,'Nelem':N,'dxp':cu.dxp,'retorno':models.retorno, + 'storageConst' :models.storage_constant, + 'ncols':cu.ncols, + 'nrows':cu.nrows, + 'xll':cu.xll, + 'yll':cu.yll, + 'dx':cu.dx, + 'dy':cu.dy, + 'epsg': self.epsg} + if SimSlides: + Dict.update({'sl_fs':models.sl_fs, 'sl_gullie':models.sl_gullienogullie, 'sl_gammaw':models.sl_gammaw}) + #abre el archivo + gr = netcdf.Dataset(ruta,'w',format='NETCDF4') + #Grupo base + GrupoBase = gr.createGroup('base') + GrupoSimHid = gr.createGroup('SimHidro') + GrupoSimSed = gr.createGroup('SimSediments') + GrupoSimSli = gr.createGroup('SimSlides') + GrupoHidro = gr.createGroup('Hidro') + GrupoGeo = gr.createGroup('Geomorfo') + GrupoCalib = gr.createGroup('Parametros') + #Variables grupo base + DimNcell = GrupoBase.createDimension('ncell',self.ncells) + DimNhill = GrupoBase.createDimension('nhills',self.nhills) + DimCol3 = GrupoBase.createDimension('col3',3) + DimCol2 = GrupoBase.createDimension('col2',2) + VarStruc = GrupoBase.createVariable('structure','i4',('col3','ncell'),zlib=True) + VarHills = GrupoBase.createVariable('hills','i4',('col2','nhills'),zlib=True) + VarHills_own = GrupoBase.createVariable('hills_own','i4',('ncell',),zlib=True) + VarStruc[:] = self.structure + VarHills[:] = self.hills + VarHills_own[:] = self.hills_own + #Variables de Simulacion hidrologica + DimNelem = GrupoSimHid.createDimension('Nelem',N) + DimCol3 = GrupoSimHid.createDimension('col3',3) + DimCol2 = GrupoSimHid.createDimension('col2',2) + DimCol4 = GrupoSimHid.createDimension('col4',4) + DimCol5 = GrupoSimHid.createDimension('col5',5) + VarH_coef = GrupoSimHid.createVariable('h_coef','f4',('col4','Nelem'),zlib=True) + VarV_coef = GrupoSimHid.createVariable('v_coef','f4',('col4','Nelem'),zlib=True) + VarH_exp = GrupoSimHid.createVariable('h_exp','f4',('col4','Nelem'),zlib=True) + VarV_exp = GrupoSimHid.createVariable('v_exp','f4',('col4','Nelem'),zlib=True) + Var_H1max = GrupoSimHid.createVariable('h1_max','f4',('Nelem',),zlib = True) + Var_H3max = GrupoSimHid.createVariable('h3_max','f4',('Nelem',),zlib = True) + Control = GrupoSimHid.createVariable('control','i4',('Nelem',),zlib = True) + ControlH = GrupoSimHid.createVariable('control_h','i4',('Nelem',),zlib = True) + if self.modelType[0] is 'c': + drena = GrupoSimHid.createVariable('drena','i4',('col3','Nelem'),zlib = True) + elif self.modelType[0] is 'h': + drena = GrupoSimHid.createVariable('drena','i4',('Nelem'),zlib = True) + unitType = GrupoSimHid.createVariable('unit_type','i4',('Nelem',),zlib = True) + hill_long = GrupoSimHid.createVariable('hill_long','f4',('Nelem',),zlib = True) + hill_slope = GrupoSimHid.createVariable('hill_slope','f4',('Nelem',),zlib = True) + stream_long = GrupoSimHid.createVariable('stream_long','f4',('Nelem',),zlib = True) + stream_slope = GrupoSimHid.createVariable('stream_slope','f4',('Nelem',),zlib = True) + stream_width = GrupoSimHid.createVariable('stream_width','f4',('Nelem',),zlib = True) + elem_area = GrupoSimHid.createVariable('elem_area','f4',('Nelem',),zlib = True) + speed_type = GrupoSimHid.createVariable('speed_type','i4',('col3',),zlib = True) + storage = GrupoSimHid.createVariable('storage','i4',('col5','Nelem'),zlib = True) + VarH_coef[:] = models.h_coef + VarV_coef[:] = models.v_coef + VarH_exp[:] = models.h_exp + VarV_exp[:] = models.v_exp + Var_H1max[:] = models.max_capilar + Var_H3max[:] = models.max_gravita + Control[:] = models.control + ControlH[:] = models.control_h + drena[:] = models.drena + unitType[:] = models.unit_type + hill_long[:] = models.hill_long + hill_slope[:] = models.hill_slope + stream_long[:] = models.stream_long + stream_slope[:] = models.stream_slope + stream_width[:] = models.stream_width + elem_area[:] = models.elem_area + speed_type[:] = models.speed_type + storage[:] = models.storage + #Variables grupo GEomorfologia + DimNcell = GrupoGeo.createDimension('ncell',self.ncells) + VarDEM = GrupoGeo.createVariable('DEM','f4',('ncell',),zlib = True) + VarDIR = GrupoGeo.createVariable('DIR','i4',('ncell',),zlib = True) + VarDEM[:] = self.DEMvec + VarDIR[:] = self.DIRvec + + #Variables de sedimentos + DimNelem = GrupoSimSed.createDimension('Nelem',N) + DimCol3 = GrupoSimSed.createDimension('col3',3) + VarKrus = GrupoSimSed.createVariable('Krus','f4',('Nelem'),zlib=True) + VarPrus = GrupoSimSed.createVariable('Prus','f4',('Nelem'),zlib=True) + VarCrus = GrupoSimSed.createVariable('Crus','f4',('Nelem'),zlib=True) + VarParliac = GrupoSimSed.createVariable('PArLiAc','f4',('col3','Nelem'),zlib=True) + VarKrus[:]=models.krus + VarPrus[:]=models.prus + VarCrus[:]=models.crus + VarParliac[:]=models.parliac + + #Variables de deslizamientos + if SimSlides: + DimNelem = GrupoSimSli.createDimension('Nelem',N) + frictionAngle = GrupoSimSli.createVariable('friction_angle','f4',('Nelem',),zlib = True) + Cohesion = GrupoSimSli.createVariable('cohesion','f4',('Nelem',),zlib = True) + GammaSoil = GrupoSimSli.createVariable('gamma_soil','f4',('Nelem',),zlib = True) + ZSoil = GrupoSimSli.createVariable('z_soil','f4',('Nelem',),zlib = True) + RadSlope = GrupoSimSli.createVariable('rad_slope','f4',('Nelem',),zlib = True) + frictionAngle[:] = models.sl_frictionangle + Cohesion[:] = models.sl_cohesion + GammaSoil[:] = models.sl_gammas + ZSoil[:] = models.sl_zs + RadSlope[:] = models.sl_radslope + #Introduce variables extras en caso de que el usuario las incluyera + if type(ExtraVar) is dict: + for k in ExtraVar.keys(): + Var = gr.createVariable(k,ExtraVar[k]['type'],('ncell',),zlib=True) + Var[:] = ExtraVar[k]['Data'] + #asigna las prop a la cuenca + gr.setncatts(Dict) + #Cierra el archivo + gr.close() + #Sale del programa + return + + #------------------------------------------------------ + # Ejecucion del modelo + #------------------------------------------------------ + def run_shia(self,Calibracion, + rain_rute, N_intervals, start_point = 1, StorageLoc = None, HspeedLoc = None,ruta_storage = None, ruta_speed = None, + ruta_conv = None, ruta_stra = None, ruta_retorno = None,kinematicN = 5, QsimDataFrame = True, EvpVariable = False): + 'Descripcion: Ejecuta el modelo una ves este es preparado\n'\ + ' Antes de su ejecucion se deben tener listas todas las . \n'\ + ' variables requeridas . \n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'self : Cuenca a ejecutar con todo listo para ser ejecutada.\n'\ + 'Calibracion : Parametros de calibracion del modelo, orden:.\n'\ + ' - Evaporacion.\n'\ + ' - Infiltracion.\n'\ + ' - Percolacion.\n'\ + ' - Perdidas.\n'\ + ' - Vel Superficial .\n'\ + ' - Vel Sub-superficial.\n'\ + ' - Vel Subterranea.\n'\ + ' - Vel Cauce.\n'\ + ' - Max Capilar.\n'\ + ' - Max Gravitacional.\n'\ + 'rain_rute : Ruta donde se encuentra el archivo binario de lluvia:.\n'\ + ' generado por rain_interpolate_* o por rain_radar2basin.\n'\ + 'N_intervals : Numero de intervalos de tiempo.\n'\ + 'start_point : Punto donde comienza a usar registros de lluvia.\n'\ + ' los binarios generados por rain_* generan un archivo de texto.\n'\ + ' que contiene fechas par aayudar a ubicar el punto de inicio deseado.\n'\ + 'StorageLoc: Variable local de almacenamiento, esto es en el caso de que no se.\n'\ + ' desee usar la configuracion global de almacenamiento del modelo (5, N).\n'\ + 'HspeedLoc: Variable local para setear la velocidad horizontal inicial de ejecucion.\n'\ + 'ruta_storage : Ruta donde se guardan los estados del modelo en cada intervalo.\n'\ + ' de tiempo, esta es opcional, solo se guardan si esta variable es asignada.\n'\ + 'ruta_conv : Ruta al binario y hdr indicando las nubes que son convectivas.\n'\ + 'ruta_stra : Ruta al binario y hdr indicando las nubes que son estratiformes.\n'\ + 'ruta_retorno : Ruta al binario y hdr en donde escribe la serie con los milimetros retornados al tanque runoff.\n'\ + 'kinematicN: Cantidad de iteraciones para la solucion de la onda cinematica.\n'\ + ' De forma continua: 5 iteraciones, recomendado para cuando el modelo se\n'\ + ' ejecuta en forma continua Ej: cu.run_shia(Calib, rain_rute, 100)\n'\ + ' Por intervalos: 10 iteraciones, recomendado cuando el modelo se ejecuta\n'\ + ' por intervalos de un paso ej:\n'\ + ' for i in range(1,N)\n'\ + ' Results = cu.run_shia(Calib, ruta_rain, 1, i)\n'\ + ' for c,j in enumerate(Results[''Storage'']):\n'\ + ' cu.set_Storage(j,c)\n'\ + 'QsimDataFrame: Retorna un data frame con los caudales simulados indicando su id de acuerdo con el\n'\ + ' que guarda la funcion Save_Net2Map con la opcion NumTramo = True. \n'\ + 'EvpVariable: (False) Asume que la evp del modelo cambia en funcion o no de la radiacion\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + 'Qsim : Caudal simulado en los puntos de control.\n'\ + 'Hsim : Humedad simulada en los puntos de control.\n'\ + #genera las rutas + rain_ruteBin,rain_ruteHdr = __Add_hdr_bin_2route__(rain_rute) + #Obtiene las fechas + Rain = read_mean_rain(rain_ruteHdr, N_intervals, start_point) + # De acuerdo al tipo de modelo determina la cantidad de elementos + if self.modelType[0] is 'c': + N = self.ncells + elif self.modelType[0] is 'h': + N = self.nhills + #prepara variables globales + models.rain_first_point = start_point + models.calc_niter = kinematicN + #Prepara terminos para control + if np.count_nonzero(models.control) == 0 : + NcontrolQ = 1 + else: + NcontrolQ = np.count_nonzero(models.control)+1 + if np.count_nonzero(models.control_h) == 0 : + NcontrolH = 1 + else: + NcontrolH = np.count_nonzero(models.control_h) + #Prepara variables de guardado de almacenamiento + if ruta_storage is not None: + models.save_storage = 1 + ruta_sto_bin, ruta_sto_hdr = __Add_hdr_bin_2route__(ruta_storage, + storage = True) + else: + models.save_storage = 0 + ruta_sto_bin = 'no_guardo_nada.StObin' + ruta_sto_hdr = 'no_guardo_nada.StOhdr' + #prepara variable para guardado de velocidad + if ruta_speed is not None: + models.save_speed = 1 + ruta_speed_bin, ruta_speed_hdr = __Add_hdr_bin_2route__(ruta_speed, + storage = True) + else: + models.save_speed = 0 + ruta_speed_bin = 'no_guardo_nada.bin' + ruta_speed_hdr = 'no_guardo_nada.hdr' + #Prepara variables para el almacenamiento de retorno + if ruta_retorno is not None: + models.save_retorno = 1 + ruta_ret_bin, ruta_ret_hdr = __Add_hdr_bin_2route__(ruta_retorno) + else: + models.save_retorno = 0 + ruta_ret_bin = 'no_guardo_nada.bin' + ruta_ret_hdr = 'no_guardo_nada.hdr' + #Variables de separacion de flujo por tipo de lluvia + if ruta_conv is not None and ruta_stra is not None: + ruta_binConv,ruta_hdrConv = __Add_hdr_bin_2route__(ruta_conv) + ruta_binStra,ruta_hdrStra = __Add_hdr_bin_2route__(ruta_stra) + models.separate_rain = 1 + else: + models.separate_rain = 0 + ruta_binConv = 'none' + ruta_hdrConv = 'none' + ruta_binStra = 'none' + ruta_hdrStra = 'none' + #Prepara la variable de almacenamiento + if StorageLoc is not None: + if StorageLoc.shape <> (5, N): + print 'Error: almacenamiento debe ser: (5,'+str(N)+'), y es: ('+str(StorageLoc.shape[0])+','+str(StorageLoc.shape[1])+')' + StorageLoc = np.zeros((5,N))*-9999.0 + else: + StorageLoc = np.zeros((5,N))*-9999.0 + #Prepara la variable de velocidad horizontal inicial + if HspeedLoc is not None: + if HspeedLoc.shape <> (4, N): + print 'Error: velocidad debe ser: (4,'+str(N)+'), y es: ('+str(HspeedLoc.shape[0])+','+str(HspeedLoc.shape[1])+')' + HspeedLoc = np.zeros((4,N))*-9999.0 + else: + HspeedLoc = np.zeros((4,N))*-9999.0 + #Implementa o no la EVP variable en funcion de la radiacion + if EvpVariable: + Rad = self.__GetEVP_Serie__(Rain.index) + else: + models.evpserie = np.ones(N_intervals) + # Ejecuta el modelo + Qsim,Qsed,Qseparated,Humedad,St1,St3,Balance,Speed,Area,Alm,Qsep_byrain = models.shia_v1( + rain_ruteBin, + rain_ruteHdr, + Calibracion, + #N, + NcontrolQ, + NcontrolH, + N_intervals, + StorageLoc, + HspeedLoc, + N, + ruta_sto_bin, + ruta_speed_bin, + ruta_binConv, + ruta_binStra, + ruta_hdrConv, + ruta_hdrStra, + ruta_ret_bin) + #Retorno de variables de acuerdo a lo simulado + Retornos={'Qsim' : Qsim} + Retornos.update({'Balance' : Balance}) + Retornos.update({'Storage' : Alm}) + if np.count_nonzero(models.control_h)>0: + Retornos.update({'Humedad' : Humedad}) + Retornos.update({'Humedad_t1' : St1}) + Retornos.update({'Humedad_t2' : St3}) + if models.sim_sediments == 1: + Retornos.update({'Sediments' : Qsed}) + if models.separate_fluxes == 1: + Retornos.update({'Fluxes' : Qseparated}) + if models.separate_rain == 1: + Retornos.update({'Rain_sep' : Qsep_byrain}) + if models.show_storage == 1: + Retornos.update({'Mean_Storage' : np.copy(models.mean_storage)}) + if models.save_storage == 1: + rutaStorageHdr = __Add_hdr_bin_2route__(ruta_storage) + #Caso en el que se registra el alm medio + if models.show_storage == 1: + __Save_storage_hdr__(ruta_sto_hdr,rain_ruteHdr,N_intervals, + start_point,self,Mean_Storage = np.copy(models.mean_storage)) + #Caso en el que no hay alm medio para cada uno de los + else: + __Save_storage_hdr__(ruta_sto_hdr,rain_ruteHdr,N_intervals, + start_point,self,Mean_Storage=np.zeros((5,N))*-9999) + #Area de la seccion + if models.show_area == 1: + Retornos.update({'Sec_Area': Area}) + #Velocidades + if models.show_speed == 1: + Retornos.update({'Speed' : Speed}) + if models.show_mean_speed == 1: + Retornos.update({'Mean_Speed' : np.copy(models.mean_speed)}) + if models.save_speed == 1: + rutaSpeedHdr = __Add_hdr_bin_2route__(ruta_speed) + #Caso en el que hay velocidad media para todos los tanques + if models.show_mean_speed == 1: + __Save_speed_hdr__(ruta_speed_hdr,rain_ruteHdr,N_intervals, + start_point,self,Mean_Speed = np.copy(models.mean_speed)) + #Caso en el que no hay alm medio para cada uno de los + else: + __Save_speed_hdr__(ruta_speed_hdr,rain_ruteHdr,N_intervals, + start_point,self) + + if models.save_retorno == 1: + if models.show_mean_retorno == 1: + __Save_retorno_hdr__(ruta_ret_hdr, rain_ruteHdr, N_intervals, + start_point, self, Mean_retorno = models.mean_retorno) + else: + __Save_retorno_hdr__(ruta_ret_hdr, rain_ruteHdr, N_intervals, + start_point, self) + + #Campo de lluvia acumulado para el evento + Retornos.update({'Rain_Acum': models.acum_rain}) + Retornos.update({'Rain_hietogram': models.mean_rain}) + #Retornos en caso de simular deslizamientos + if models.sim_slides == 1: + Retornos.update({'Slides_Map': np.copy(models.sl_slideocurrence)}) + Retornos.update({'Slides_NCell_Serie': np.copy(models.sl_slidencelltime)}) + Retornos.update({'Slides_Acum':np.copy(models.sl_slideacumulate)}) + #Caudal simulado en un dataframe + if QsimDataFrame: + #Obtiene ids + ids = models.control[models.control<>0] + Qdict = {} + for i,j in zip(Retornos['Qsim'][1:], ids): + Qdict.update({str(j): i}) + Qdict = pd.DataFrame(Qdict, index=Rain.index) + #Si separa flujos, entrega el caudal tambien en data frame por flujos + if models.separate_fluxes == 1: + Qsep = [] + tupla = [] + for z,i,j in zip(Retornos['Qsim'][1:], Retornos['Fluxes'][1:], ids): + tupla.append((str(j),'run')) + tupla.append((str(j),'sub')) + tupla.append((str(j),'sup')) + Qsep.extend([i[0],i[1],z-i[0]-i[1]]) + index = pd.MultiIndex.from_tuples(tupla, names=['reach','flux']) + Qsep = np.array(Qsep) + QsepDict = pd.DataFrame(Qsep.T, index=Rain.index, columns=index) + #Si simula sedimentos, hace el dataframe + if models.sim_sediments == 1: + Qsedi = [] + tupla = [] + for z,i,j in zip(Retornos['Qsim'][1:], Retornos['Sediments'][1:], ids): + tupla.append((str(j),'Sand')) + tupla.append((str(j),'Lime')) + tupla.append((str(j),'Clay')) + Qsedi.extend([i[0],i[1],i[2]])# [i[0],i[1],z-i[0]-i[1]]) + index = pd.MultiIndex.from_tuples(tupla, names=['reach','Sediments']) + Qsedi = np.array(Qsedi) + QsediDict = pd.DataFrame(Qsedi.T, index=Rain.index, columns=index) + if models.separate_fluxes == 1 and models.sim_sediments == 0: + return Retornos, Qdict, QsepDict + if models.separate_fluxes == 1 and models.sim_sediments == 1: + return Retornos, Qdict, QsepDict, QsediDict + if models.separate_fluxes == 0 and models.sim_sediments == 1: + return Retornos, Qdict, QsediDict + return Retornos, Qdict + return Retornos + + def efficiencia(self, Qobs, Qsim): + 'Descripcion: Calcula diferentes indices de desempeno del modelo\n'\ + ' nash, qpico, rmse, rmseLog, t_pico\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + 'Qobs : Caudal observado.\n'\ + 'Qsim : Caudal simulado.\n'\ + 'Retornos\n'\ + '----------\n'\ + 'DicEff: diccionario con la eficiencia obtenida en cada param.\n'\ + #Comienza a evaluar cada parametro + DictEff = {'Nash': __eval_nash__(Qobs, Qsim)} + DictEff.update({'Qpico': __eval_q_pico__(Qobs, Qsim)}) + DictEff.update({'Tpico': __eval_t_pico__(Qobs, Qsim, models.dt)}) + DictEff.update({'RmseLog': __eval_rmse_log__(Qobs, Qsim)}) + DictEff.update({'Rmse': __eval_rmse__(Qobs, Qsim)}) + return DictEff + + def Calib_NSGAII(self, nsga_el, nodo_eval, pop_size = 40, process = 4, + NGEN = 6, MUTPB = 0.5, CXPB = 0.5): + 'Descripcion: Algoritmo para calibrar de forma automatica el modelo\n'\ + ' hidrologico utilizando DEAP y su funcion de seleccion NSGAII.\n'\ + '\n'\ + 'Parametros\n'\ + '----------\n'\ + ' - nsga_el : un objeto de la clase nsgaii_element, el cual determinara las reglas.\n'\ + ' para la generacion de calibraciones.\n'\ + ' - nodo_eval: nodo donde se evalua el modelo.\n'\ + ' - pop_size: tamano de la poblacion (cantidad de calibraciones a evaluar, multiplo de 4).\n'\ + ' - process: Cantidad de procesadores que se utilizaran en la generacion.\n'\ + ' - NGEN: Cantidad de generaciones para obtener la poblacion final.\n'\ + ' - MUTPB: Probabilidad generica de que un gen mute.\n'\ + ' - CXPB: Probabilidad generica de que dos genes se crucen.\n'\ + '\n'\ + 'Retornos\n'\ + '----------\n'\ + ' - pop: poblacion final.\n'\ + ' - Qsim: Caudales simulados en el punto evaluado.\n'\ + ' - fitness: desempeno de la poblacion obtenida.\n'\ + #Check de que la poblacion sea multiplo de 4 + Flag = True + while Flag: + if np.mod(pop_size,4) == 0: + Flag = False + else: + pop_size += 1 + #Inicia el elemento nsga con los parametros de el + nsga_el.set_nsgaII() + #Crea las poblaciones y las ejecuciones + pop = nsga_el.toolbox.population(pop_size) + Ejecs = map(nsga_el.__crea_ejec__, pop) + #Ejecuta a la poblacion + QsimPar = __ejec_parallel__(Ejecs, process, nodo_eval) + fitnesses = map(nsga_el.toolbox.evaluate, QsimPar) + for ind, fit in zip(pop, fitnesses): + ind.fitness.values = fit + #Itera la poblacion hasta encontrar a la mejor + #toolbox = base.Toolbox() + for g in range(NGEN): + offspring = tools.selTournamentDCD(pop, len(pop)) + offspring = map(nsga_el.toolbox.clone, offspring) + # Apply crossover and mutation on the offspring + for child1, child2 in zip(offspring[::2], offspring[1::2]): + if random.random() < CXPB: + nsga_el.toolbox.mate(child1[0], child2[0]) + del child1.fitness.values + del child2.fitness.values + #Muta a algunos de los genomas + for mutant in offspring: + if random.random() < MUTPB: + nsga_el.toolbox.mutate(mutant[0]) + del mutant.fitness.values + #Ejecuta a la nueva generacion + Ejecs = map(nsga_el.__crea_ejec__, offspring) + QsimPar = __ejec_parallel__(Ejecs, process, nodo_eval) + #Identifica a la gente que no cumple de la generacion + Qsim_invalid = [] + invalid_ind = [] + for i,q in zip(offspring, QsimPar): + if not i.fitness.valid: + Qsim_invalid.append(q) + invalid_ind.append(i) + #Evaluate the individuals with an invalid fitness + fitnesses = map(nsga_el.toolbox.evaluate, Qsim_invalid) + for ind, fit in zip(invalid_ind, fitnesses): + ind.fitness.values = fit + #Toma la siguiente generacion + pop = nsga_el.toolbox.select(pop + offspring, pop_size) + #Retorno + return pop, QsimPar, np.array(fitnesses).T class nsgaii_element: From 537c309c177679168f012f3e342cf58bf28ac018 Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Sun, 26 Aug 2018 14:38:58 -0500 Subject: [PATCH 117/142] =?UTF-8?q?Modificaci=C3=B3n=20algunos=20toolTips?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 158 +++++++++++-------- 1 file changed, 88 insertions(+), 70 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 93217b8..1c4d330 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -68,7 +68,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -254,7 +254,7 @@ - + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png @@ -434,7 +434,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -536,7 +536,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -761,7 +761,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -824,7 +824,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -900,7 +900,7 @@ - + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico @@ -941,7 +941,7 @@ - + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -976,7 +976,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -999,7 +999,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -1071,7 +1071,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png:/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png @@ -1094,7 +1094,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png:/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png @@ -1383,7 +1383,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1446,7 +1446,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -1481,7 +1481,7 @@ - + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -1538,7 +1538,7 @@ - + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico @@ -1564,7 +1564,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -1587,7 +1587,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -1732,7 +1732,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -1846,7 +1846,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1863,7 +1863,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1939,7 +1939,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -2122,7 +2122,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2216,7 +2216,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2264,7 +2264,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2312,7 +2312,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2370,7 +2370,7 @@ 0 - 0 + -362 446 1918 @@ -2540,7 +2540,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2714,7 +2714,7 @@ - + :/plugins/HydroSEDPlugin/icons/update.png:/plugins/HydroSEDPlugin/icons/update.png @@ -2764,7 +2764,7 @@ - + :/plugins/HydroSEDPlugin/icons/update.png:/plugins/HydroSEDPlugin/icons/update.png @@ -2850,7 +2850,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2962,7 +2962,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -2979,7 +2979,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3193,7 +3193,7 @@ 0 - 0 + -575 446 1918 @@ -3311,13 +3311,16 @@ - Establecer ruta donde se aloja el mapa de precipitación. + Establecer ruta donde se aloja el mapa de precipitación o un valor constante. + + + Establecer ruta donde se aloja el mapa de precipitación o un valor constante. - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3343,7 +3346,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3495,7 +3498,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3521,7 +3524,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3581,7 +3584,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3676,17 +3679,30 @@ + + Cargar el .shp con coordenadas de estaciones. + + + Cargar el .shp con coordenadas de estaciones + - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - + + + Definir el campo coincidente con el Excel + + + Definir el campo coincidente con el Excel + + @@ -3746,7 +3762,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3932,6 +3948,9 @@ + + Establecer ruta de guardado del binario de lluvia. + Establecer ruta de guardado del binario de lluvia. @@ -3939,7 +3958,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3956,7 +3975,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3994,10 +4013,10 @@ - Ejecuta la interpolación para la cuenca con los parámetros dados. + Calcula y grafica el ciclo anual de la precipitación media en la cuenca. - Ejecuta la interpolación para la cuenca con los parámetros dados. + Calcula y grafica el ciclo anual de la precipitación media en la cuenca. Ciclo Anual @@ -4013,10 +4032,10 @@ - Ejecuta la interpolación para la cuenca con los parámetros dados. + Calcula y grafica el histograma de la precipitación media en la cuenca. - Ejecuta la interpolación para la cuenca con los parámetros dados. + Calcula y grafica el histograma de la precipitación media en la cuenca. Histograma @@ -4038,10 +4057,10 @@ - Ejecuta la interpolación para la cuenca con los parámetros dados. + Grafica serie y acumulado de la precipitación media en la cuenca. - Ejecuta la interpolación para la cuenca con los parámetros dados. + Grafica serie y acumulado de la precipitación media en la cuenca. Serie @@ -4127,13 +4146,13 @@ - Visualiza una entrada del binario de lluvia interpolado. + Visualiza una entrada o un acumulado del binario de lluvia interpolado. - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4409,7 +4428,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4435,7 +4454,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4495,7 +4514,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4634,16 +4653,16 @@ - Seleccionar la ruta donde se va a guardar la corriente. + - Seleccionar la ruta donde se va a guardar la corriente. + - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4677,16 +4696,16 @@ - Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + - Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5379,7 +5398,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -5468,16 +5487,16 @@ - Seleccionar la ruta donde se va a guardar la corriente. + Seleccionar la ruta del binario de precipitación - Seleccionar la ruta donde se va a guardar la corriente. + Seleccionar la ruta del binario de precipitación. - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -5597,7 +5616,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5626,7 +5645,7 @@ - + :/plugins/HydroSEDPlugin/icons/toRaster.ico:/plugins/HydroSEDPlugin/icons/toRaster.ico @@ -5742,7 +5761,6 @@ - - + From eba6c17f87daa9e7b5aff16086f1d54eee6757f1 Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Sun, 26 Aug 2018 21:47:52 -0500 Subject: [PATCH 118/142] =?UTF-8?q?Actualiza=20la=20media=20de=20las=20var?= =?UTF-8?q?iables=20de=20Sedimentos=20en=20la=20pesta=C3=B1a=20Simulaci?= =?UTF-8?q?=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPlugin_dockwidget.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index f974711..8b47212 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -938,9 +938,9 @@ def changeEventUpdateScalarParameters(): def clickEventUpdateParamMapValues(): '''Muestra en los campos de simulacion el valor medio de los mapas de simulacion''' VarNames = ['h1_max','h3_max', 'v_coef','v_coef','v_coef','v_coef','h_coef', - 'h_coef','h_coef','h_coef', 'Krusle','Crusle','Prusle', - 'Arenas','Limos','Arcillas'] - Ejes = [0,0,0,1,2,3,0,1,2,3,0,0,0,0,0,0] + 'h_coef','h_coef','h_coef', 'Krus','Crus','Prus', + 'PArLiAc','PArLiAc','PArLiAc'] + Ejes = [0,0,0,1,2,3,0,1,2,3,0,0,0,0,1,2] for name, i, eje in zip(VarNames, range(1,17), Ejes): Campo = getattr(self, 'ParamVal'+str(i)) Campo.setMinimum(-99999) From f29d8d549e9a8eeb8b64b7de6183bc4d0a82d53e Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 27 Aug 2018 11:14:32 -0500 Subject: [PATCH 119/142] nuevas entradas en la interfaz grafica, para campos de radar y modificaciones en la simulacion --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 1543 ++++++++++++------ 1 file changed, 1052 insertions(+), 491 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 1c4d330..4b0ef9c 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -6,7 +6,7 @@ 0 0 - 493 + 495 936 @@ -68,7 +68,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -250,11 +250,11 @@ - 4 + 3 - + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png @@ -294,8 +294,8 @@ 0 - 0 - 446 + -878 + 443 2018 @@ -434,7 +434,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -536,7 +536,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -761,7 +761,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -824,7 +824,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -900,7 +900,7 @@ - + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico @@ -941,7 +941,7 @@ - + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -976,7 +976,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -999,7 +999,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -1071,7 +1071,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png:/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png @@ -1094,7 +1094,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png:/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png @@ -1383,7 +1383,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1446,7 +1446,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -1481,7 +1481,7 @@ - + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -1538,7 +1538,7 @@ - + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico @@ -1564,7 +1564,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -1587,7 +1587,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -1639,7 +1639,7 @@ 0 0 - 446 + 443 2018 @@ -1732,7 +1732,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -1846,7 +1846,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1863,7 +1863,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1939,7 +1939,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -2122,7 +2122,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2216,7 +2216,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2264,7 +2264,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2312,7 +2312,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2370,8 +2370,8 @@ 0 - -362 - 446 + 0 + 443 1918 @@ -2540,7 +2540,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2850,7 +2850,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2962,7 +2962,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -2979,7 +2979,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3193,8 +3193,8 @@ 0 - -575 - 446 + 0 + 443 1918 @@ -3229,7 +3229,7 @@ 0 - 440 + 820 421 241 @@ -3311,16 +3311,13 @@ - Establecer ruta donde se aloja el mapa de precipitación o un valor constante. - - - Establecer ruta donde se aloja el mapa de precipitación o un valor constante. + Establecer ruta donde se aloja el mapa de precipitación. - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3346,7 +3343,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3498,7 +3495,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3524,7 +3521,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3584,7 +3581,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3604,7 +3601,7 @@ - Generador campos de lluvia + Campos de lluvia interpolados @@ -3679,30 +3676,17 @@ - - Cargar el .shp con coordenadas de estaciones. - - - Cargar el .shp con coordenadas de estaciones - - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - Definir el campo coincidente con el Excel - - - Definir el campo coincidente con el Excel - - + @@ -3762,7 +3746,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3948,9 +3932,6 @@ - - Establecer ruta de guardado del binario de lluvia. - Establecer ruta de guardado del binario de lluvia. @@ -3958,7 +3939,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3975,7 +3956,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4013,10 +3994,10 @@ - Calcula y grafica el ciclo anual de la precipitación media en la cuenca. + Ejecuta la interpolación para la cuenca con los parámetros dados. - Calcula y grafica el ciclo anual de la precipitación media en la cuenca. + Ejecuta la interpolación para la cuenca con los parámetros dados. Ciclo Anual @@ -4032,10 +4013,10 @@ - Calcula y grafica el histograma de la precipitación media en la cuenca. + Ejecuta la interpolación para la cuenca con los parámetros dados. - Calcula y grafica el histograma de la precipitación media en la cuenca. + Ejecuta la interpolación para la cuenca con los parámetros dados. Histograma @@ -4057,10 +4038,10 @@ - Grafica serie y acumulado de la precipitación media en la cuenca. + Ejecuta la interpolación para la cuenca con los parámetros dados. - Grafica serie y acumulado de la precipitación media en la cuenca. + Ejecuta la interpolación para la cuenca con los parámetros dados. Serie @@ -4146,13 +4127,13 @@ - Visualiza una entrada o un acumulado del binario de lluvia interpolado. + Visualiza una entrada del binario de lluvia interpolado. - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4166,7 +4147,7 @@ -3 - 420 + 800 411 20 @@ -4179,7 +4160,7 @@ 0 - 710 + 1080 421 271 @@ -4428,7 +4409,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4454,7 +4435,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4514,7 +4495,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4528,7 +4509,7 @@ 0 - 680 + 1060 411 20 @@ -4537,132 +4518,124 @@ Qt::Horizontal - - - - - - - - - Simulación - - - - - 10 - 10 - 451 - 721 - - - - - 430 - 400 - - - - - 16777215 - 750 - - - - Qt::ScrollBarAlwaysOn - - - true - - - - - 0 - 0 - 436 - 1918 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - - - - 0 - 1900 - - - + 0 - 0 + 420 + 411 + 20 + + + + Qt::Horizontal + + + + + + 0 + 450 411 - 101 + 351 - Serie de Caudal Observado + Campos de lluvia de radar - + 0 - 20 - 401 - 81 + 30 + 411 + 311 - + - + + + Qt::Horizontal + + + + + + + + 0 + 10 + + + + + 75 + true + + + + Datos de entrada: + + + + + - + + + Archivo de excel con las series de tiempo de los puntos a interpolar. + - Ruta a la serie de caudales obsevada + Archivo de excel con las series de tiempo de los puntos a interpolar. - - false + + netCDF Radar - - + + + Qt::Horizontal + + - 30 - 0 + 10 + 20 + + + + + + false + + + + + + + true + - 30 + 100 16777215 - + Establecer archivo de excel a utilizar. - + Establecer archivo de excel a utilizar. - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4670,43 +4643,748 @@ - + - + - Selección estación + Fecha inicio conversión - - - - - - - 50 - 0 - - - - - 30 - 16777215 - + + + + 2015 + 1 + 1 + - - + + dd/MMM/yyyy HH:mm - - + + true + + + + + + + + - + Fecha fin conversión - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + 2015 + 1 + 1 + + + + dd/MMM/yyyy HH:mm + + + true + + + + + + + + + + + Intervalo de tiempo [seg] + + + + + + + 5.000000000000000 + + + 999999999.000000000000000 + + + + + + + + + Qt::Horizontal + + + + + + + + 75 + true + + + + Datos de salida: + + + Qt::AutoText + + + + + + + + + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + + + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + + + Binario de lluvia + + + + + + + Ruta de guardado + + + false + + + + + + + Establecer ruta de guardado del binario de lluvia. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + Qt::Horizontal + + + + + + + + + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + + + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + + + Gráficas tiempo + + + + + + + + 20 + 0 + + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Ciclo Anual + + + + + + + + 10 + 0 + + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Histograma + + + + + + + + 20 + 0 + + + + + 100 + 16777215 + + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Ejecuta la interpolación para la cuenca con los parámetros dados. + + + Serie + + + + + + + + + + + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + + + Ruta de guardado del binario de fortran con la serie de precipitación interpolada. + + + Gráficas espacio + + + + + + + + 20 + 0 + + + + Entrada del binario de lluvia a visualizar. + + + 0 + + + 0.000000000000000 + + + 10000000.000000000000000 + + + 1.000000000000000 + + + + + + + + 50 + 0 + + + + Entrada del binario de lluvia a visualizar. + + + 0 + + + 0.000000000000000 + + + 10000000.000000000000000 + + + 1.000000000000000 + + + + + + + true + + + + 40 + 16777215 + + + + Visualiza una entrada del binario de lluvia interpolado. + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + + + + + + + + + + + Simulación + + + + + 10 + 10 + 451 + 721 + + + + + 430 + 400 + + + + + 16777215 + 750 + + + + Qt::ScrollBarAlwaysOn + + + true + + + + + 0 + 0 + 433 + 1918 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + 0 + 1900 + + + + + + 0 + 0 + 411 + 141 + + + + Series + + + + + 0 + 20 + 411 + 111 + + + + + + + + + P [mm] + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 30 + 0 + + + + + 110 + 16777215 + + + + Ruta a la serie de caudales obsevada + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Seleccionar la ruta donde se va a guardar la corriente. + + + Seleccionar la ruta donde se va a guardar la corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + + + Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + + + + + Q [m3/s] + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 50 + 0 + + + + + 110 + 16777215 + + + + Ruta a la serie de caudales obsevada + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Seleccionar la ruta donde se va a guardar la corriente. + + + Seleccionar la ruta donde se va a guardar la corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + + + Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + + + + + + + Qsed [m3/s] + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 30 + 0 + + + + + 130 + 16777215 + + + + Ruta a la serie de caudales obsevada + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Seleccionar la ruta donde se va a guardar la corriente. + + + Seleccionar la ruta donde se va a guardar la corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + + + Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4732,7 +5410,7 @@ 0 - 330 + 160 411 711 @@ -4746,7 +5424,7 @@ 0 70 401 - 551 + 582 @@ -4755,6 +5433,16 @@ 4 + + + + Velocidad vertical evaporacion (v_coef[0]) + + + Vv0 [mm] + + + @@ -4801,19 +5489,6 @@ - - - - Exponente regional en caso de usar aproximación no lineal v = C A^e - - - Exponente aproximación no lineal al flujo sub-superficial - - - 1.000000000000000 - - - @@ -4907,16 +5582,6 @@ - - - - Velocidad vertical evaporacion (v_coef[0]) - - - Vv0 [mm] - - - @@ -5071,6 +5736,25 @@ + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 99999.000000000000000 + + + 0.000000000000000 + + + @@ -5091,25 +5775,6 @@ - - - - true - - - true - - - QAbstractSpinBox::NoButtons - - - 99999.000000000000000 - - - 0.000000000000000 - - - @@ -5148,8 +5813,8 @@ - - + + true @@ -5159,13 +5824,19 @@ QAbstractSpinBox::NoButtons + + -99999.000000000000000 + + + 99999.000000000000000 + 1.000000000000000 - - + + true @@ -5175,13 +5846,16 @@ QAbstractSpinBox::NoButtons + + 6 + 1.000000000000000 - - + + true @@ -5191,19 +5865,13 @@ QAbstractSpinBox::NoButtons - - -99999.000000000000000 - - - 99999.000000000000000 - 1.000000000000000 - - + + true @@ -5282,8 +5950,8 @@ - - + + true @@ -5298,8 +5966,8 @@ - - + + true @@ -5314,8 +5982,8 @@ - - + + true @@ -5330,8 +5998,8 @@ - - + + true @@ -5354,8 +6022,21 @@ true - - QAbstractSpinBox::NoButtons + + QAbstractSpinBox::NoButtons + + + 1.000000000000000 + + + + + + + Exponente regional en caso de usar aproximación no lineal v = C A^e + + + Exponente aproximación no lineal al flujo sub-superficial 1.000000000000000 @@ -5366,11 +6047,37 @@ + + + + 0 + 30 + 401 + 41 + + + + + + + + + Seleccionar calibración anterior + + + + + + + + + + 0 - 620 + 650 401 41 @@ -5398,7 +6105,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -5414,106 +6121,81 @@ - - - - 0 - 30 - 401 - 41 - - - - - - - - - Seleccionar calibración anterior - - - - - - - - - - - + 0 - 120 + 1430 411 - 191 + 20 + + + + Qt::Horizontal + + + + + + 0 + 870 + 401 + 301 - Serie de precipitación + Ejecución 0 - 20 + 30 401 - 171 + 241 - + - - - false + + + Fecha Inicio - - - - 30 - 0 - - - - - 30 - 16777215 - - - - Seleccionar la ruta del binario de precipitación - - - Seleccionar la ruta del binario de precipitación. + + + + 2015 + 1 + 1 + - - + + dd/MMM/yyyy HH:mm - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + true - + - + - Fecha inicio simulación + Fecha inicio interpolación - + 2015 @@ -5521,208 +6203,85 @@ 1 + + dd/MMM/yyyy HH:mm + + + true + - - - + + + - Fecha fin simulación + Separacion - - - - - 2015 - 12 - 31 - + + + + Retrono - - - - - - + + - Paso de tiempo (dt) + Sedimentos - - - - Paso del intervalo de tiempo en los campos cargados. - - - 0 - - - 0.000000000000000 - - - 100000.000000000000000 - - - 0.000000000000000 + + + + Deslizamientos - + - - - Qt::Horizontal - - - - 40 - 20 - + + + Figuras: - + + + + + - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Visualizar serie de precipitación entre las fechas seleccionadas. - - - Visualizar serie de precipitación. - + - - - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + Almacenamientos - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Visualizar acumulado de precipitación entre fecha inicial y final - - - Visualizar acumulado de precipitación entre fecha inicial y final - + - - - :/plugins/HydroSEDPlugin/icons/toRaster.ico:/plugins/HydroSEDPlugin/icons/toRaster.ico - - - - - 130 - 280 - 115 - 50 - - - - Nombre variable - - - - - - - 0 - 310 - 411 - 20 - - - - Qt::Horizontal - - - - - - 0 - 1050 - 411 - 20 - - - - Qt::Horizontal - - - - - - 0 - 1070 - 401 - 271 - - - - Ejecución - - - - - 0 - 30 - 401 - 221 - - - - 0 - 100 + 140 411 20 @@ -5761,6 +6320,8 @@ - + + + From 19c976870066dba3c1606c91edcea3feff4f1ed1 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 27 Aug 2018 17:14:16 -0500 Subject: [PATCH 120/142] Comienza a montarse el conversor de campos de radar a cuenca --- qgisplugin/HydroSEDPluginUtils.py | 103 ++++++++++++++++++- qgisplugin/HydroSEDPlugin_dockwidget.py | 53 +++++++++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 37 ++++--- 3 files changed, 173 insertions(+), 20 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 8797d3c..5f05277 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -811,5 +811,106 @@ def __fx__(x, metodo = 'media'): #print VarAgregada[posMalos].min() return VarAgregada - + def Radar_Conver2Basin(self, RadarFiles,fi,ff, TimeDelta, PathOut): + + +#si el binario el viejo, establece las variables para actualizar +if old: + self.cuenca.rain_radar2basin_from_array(status='old',ruta_out= args.rutaRes) + +#Itera sobre las fechas para actualizar el binario de campos +datesDt = datesDt.to_pydatetime() +for dates,pos in zip(datesDt[1:],PosDates): + rvec = np.zeros(cuAMVA.ncells) + if args.save_escenarios: + rhigh = np.zeros(cuAMVA.ncells) + rlow = np.zeros(cuAMVA.ncells) + Conv = np.zeros(cuAMVA.ncells, dtype = int) + Stra = np.zeros(cuAMVA.ncells, dtype = int) + try: + for c,p in enumerate(pos): + #Lee la imagen de radar para esa fecha + g = netCDF4.Dataset(ListRutas[p]) + print ListRutas[p] + RadProp = [g.ncols, g.nrows, g.xll, g.yll, g.dx, g.dx] + #Agrega la lluvia en el intervalo + rvec += cuAMVA.Transform_Map2Basin(g.variables['Rain'][:].T/ (12*1000.0),RadProp) + if args.save_escenarios: + rhigh += cuAMVA.Transform_Map2Basin(g.variables['Rhigh'][:].T / (12*1000.0), RadProp) + rlow += cuAMVA.Transform_Map2Basin(g.variables['Rlow'][:].T / (12*1000.0), RadProp) + #Agrega la clasificacion para la ultima imagen del intervalo + ConvStra = cuAMVA.Transform_Map2Basin(g.variables['Conv_Strat'][:].T, RadProp) + Conv = np.copy(ConvStra) + Conv[Conv == 1] = 0; Conv[Conv == 2] = 1 + Stra = np.copy(ConvStra) + Stra[Stra == 2] = 0 + #rvec[(Conv == 0) & (Stra == 0)] = 0 + if args.save_escenarios: + rhigh[(Conv == 0) & (Stra == 0)] = 0 + rlow[(Conv == 0) & (Stra == 0)] = 0 + Conv[rvec == 0] = 0 + Stra[rvec == 0] = 0 + #Cierra el netCDF + g.close() + except Exception, e: + print 'error' + rvec = np.zeros(cuAMVA.ncells) + if args.save_escenarios: + rhigh = np.zeros(cuAMVA.ncells) + rlow = np.zeros(cuAMVA.ncells) + Conv = np.zeros(cuAMVA.ncells) + Stra = np.zeros(cuAMVA.ncells) + #rvec[ConvStra==0] = 0 + #rhigh[ConvStra==0] = 0 + #rlow[ConvStra==0] = 0 + #Escribe el binario de lluvia + dentro = cuAMVA.rain_radar2basin_from_array(vec = rvec, + ruta_out = args.rutaRes, + fecha = dates-dt.timedelta(hours = 5), + dt = args.dt, + umbral = args.umbral) + if args.save_escenarios: + dentro = cuHigh.rain_radar2basin_from_array(vec = rhigh, + ruta_out = args.rutaRes+'_high', + fecha = dates-dt.timedelta(hours = 5), + dt = args.dt, + umbral = args.umbral) + dentro = cuLow.rain_radar2basin_from_array(vec = rlow, + ruta_out = args.rutaRes+'_low', + fecha = dates-dt.timedelta(hours = 5), + dt = args.dt, + umbral = args.umbral) + if dentro == 0: + hagalo = True + else: + hagalo = False + #mira si guarda o no los clasificados + if args.save_class: + #Escribe el binario convectivo + aa = cuConv.rain_radar2basin_from_array(vec = Conv, + ruta_out = args.rutaRes+'_conv', + fecha = dates-dt.timedelta(hours = 5), + dt = args.dt, + doit = hagalo) + #Escribe el binario estratiforme + aa = cuStra.rain_radar2basin_from_array(vec = Stra, + ruta_out = args.rutaRes+'_stra', + fecha = dates-dt.timedelta(hours = 5), + dt = args.dt, + doit = hagalo) + #Opcion Vervose + if args.verbose: + print dates.strftime('%Y%m%d-%H:%M'), pos + +#Cierrra el binario y escribe encabezado +cuAMVA.rain_radar2basin_from_array(status = 'close',ruta_out = args.rutaRes) +if args.save_class: + cuConv.rain_radar2basin_from_array(status = 'close',ruta_out = args.rutaRes+'_conv') + cuStra.rain_radar2basin_from_array(status = 'close',ruta_out = args.rutaRes+'_stra') +if args.save_escenarios: + cuHigh.rain_radar2basin_from_array(status = 'close',ruta_out = args.rutaRes+'_high') + cuLow.rain_radar2basin_from_array(status = 'close',ruta_out = args.rutaRes+'_low') +#Imprime en lo que va +if args.verbose: + print 'Encabezados de binarios de cuenca cerrados y listos' diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 8b47212..795f8c4 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -62,7 +62,7 @@ def __init__(self, iface = None, parent=None): self.setupBasinManager() self.setupGeomorfologia() #self.setupUIButtonEvents () - self.setupRainfallInterpolation() + self.setupRainfall() self.setupSimulation() self.setupNcVariables() @@ -70,6 +70,7 @@ def __init__(self, iface = None, parent=None): self.TablaFila_NC = 0 self.botonClicked = False self.segundaCarga = False + self.Path2Radar = '' self.GeoPlots = HSplots.PlotGeomorphology() @@ -770,9 +771,11 @@ def clickEventConvertVariable2NC(): self.Button_EditNcVariable.clicked.connect(clickEventEvalString) - def setupRainfallInterpolation(self): + def setupRainfall(self): '''Conjunto de herramientas dispuestas para interpolar campos de precipitacion''' + #self.PathInHydro_Radar.setText('/home/nicolas/Radar') + def setupLineEditButtonOpenShapeFileDialog (lineEditHolder, fileDialogHolder): '''Hace que cuando se busquen shapes solo se encuetren formatos vectoriales''' lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Shapefiles (*.shp);;")) @@ -786,7 +789,12 @@ def setupLineEditButtonSaveFileDialog (lineEditHolder, fileDialogHolder): def setupLineEditButtonOpenExcelFileDialog (lineEditHolder, fileDialogHolder): '''Hace que cuando se busquen shapes solo se encuetren formatos vectoriales''' lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Excel (*.xlsx);;")) - + + def setupLineEditButtonOpenRadarFileDialog (lineEditHolder, fileDialogHolder): + '''Para cambiar la carpeta por defecto donde se buscan las imagenes de radar''' + OutputFolder = fileDialogHolder.getExistingDirectory(QtGui.QDialog(), "Cargador de Cuencas", "/tmp/", QFileDialog.ShowDirsOnly) + lineEditHolder.setText (OutputFolder) + def clickEventSelectorMapaPuntosPluvio(): '''Evento de click: selecciona el shp con las estaciones''' #Reinicia el vector con los nombres de las variables y abre el archivo de puntos @@ -814,6 +822,12 @@ def clickEventSelectorArchivoExcel(): #Pone el intervalo de tiempo de interpolacion self.Interpol_SpinBox_delta.setValue(self.HSutils.Interpol_fd.total_seconds()) + def clickEventSelectorRadarFiles(): + '''Evento de seleccion de la carpeta contenedora de los archivos de radar''' + setupLineEditButtonOpenRadarFileDialog(self.PathInHydro_Radar, QFileDialog) + self.Path2Radar = self.PathInHydro_Radar + + def clickEventSelectorArchivoBinarioLluvia(): '''Selecciona la ruta en donde se guardara el binario de salida.''' #pone el camino del archivo con la lluvia de la cuenca @@ -825,6 +839,17 @@ def clickEventSelectorArchivoBinarioLluvia(): except: pass + def clickEventSelectorArchivoBinarioLluviaRadar(): + '''Selecciona la ruta en donde se guardara el binario de salida.''' + #pone el camino del archivo con la lluvia de la cuenca + setupLineEditButtonSaveFileDialog(self.PathOutHydro_Radar,QFileDialog) + #Trata de leer datos de lluvia en caso de que ya existan + try: + PathData = self.PathOutHydro_Radar.text().strip() + self.HSplots = HSplots.PlotRainfall(PathData) + except: + pass + def clickEventEjecutarInterpolacion(): '''Interpola los campos de precipitacion con los parametros ingresados.''' #Toma los parametros para la interpolacion @@ -846,6 +871,25 @@ def clickEventEjecutarInterpolacion(): #Aviso de existo self.iface.messageBar().pushInfo(u'HidroSIG:',u'Interpolacion de campos de precipitacion realizada con exito') + def clickEventEjecutarConversionRadar(): + '''Convierte campos de radar en la cuenca usando el archivo netCDF que se encuentran en la ruta especificada''' + #Toma los parametros para la interpolacion + PathRadar = self.PathInHydro_Radar.text().strip() + fi = self.Interpol_DateTimeStart_Radar.dateTime().toPyDateTime() + ff = self.Interpol_DateTimeEnd_Radar.dateTime().toPyDateTime() + fd = self.Interpol_SpinBox_delta_Radar.value() + PathOut = self.PathOutHydro_Radar.text().strip() + #Interpola para la cuenca seleccionada + self.HSutils.Radar_Conver2Basin(PathRadar,fi,ff,fd,PathOut) + #Trata de leer datos de lluvia en caso de que ya existan + try: + PathData = self.PathOutHydro_Radar.text().strip() + self.HSplots = HSplots.PlotRainfall(PathData) + except: + pass + #Aviso de existo + self.iface.messageBar().pushInfo(u'HidroSIG:',u'Conversión de campos de radar realizada con exito') + def clickEventViewSerieRainfall(): '''Genera y visualiza la grafica de lluvia interpolada para la cuenca''' #Hace la figura @@ -917,6 +961,9 @@ def clickEventGetAcumRainfall(): self.Button_InterpolHistogram.clicked.connect(clickEventViewHistogramRainfall) self.Button_InterpolCiclo.clicked.connect(clickEventViewMediaMensualRainfall) + #botones set de radar + self.Boton_HidroLoad_RadarData.clicked.connect(clickEventSelectorRadarFiles) + self.Button_HidroSaveRadar.clicked.connect(clickEventSelectorArchivoBinarioLluviaRadar) def setupSimulation(self): '''Herramientas para gestionar la simulacion hidrologica con la cuenca cargada''' diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 4b0ef9c..86db3c3 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -3193,7 +3193,7 @@ 0 - 0 + -33 443 1918 @@ -3878,6 +3878,9 @@ 999999999.000000000000000 + + 86400.000000000000000 + @@ -4608,14 +4611,14 @@ - + false - + true @@ -4652,7 +4655,7 @@ - + 2015 @@ -4680,7 +4683,7 @@ - + 2015 @@ -4708,13 +4711,16 @@ - + 5.000000000000000 999999999.000000000000000 + + 300.000000000000000 + @@ -4758,7 +4764,7 @@ - + Ruta de guardado @@ -4768,7 +4774,7 @@ - + Establecer ruta de guardado del binario de lluvia. @@ -4782,7 +4788,7 @@ - + Ejecuta la interpolación para la cuenca con los parámetros dados. @@ -4823,7 +4829,7 @@ - + 20 @@ -4842,7 +4848,7 @@ - + 10 @@ -4861,7 +4867,7 @@ - + 20 @@ -4903,7 +4909,7 @@ - + 20 @@ -4928,7 +4934,7 @@ - + 50 @@ -4953,7 +4959,7 @@ - + true @@ -6321,7 +6327,6 @@ - From 31c3bfd467029cb1b26e142a1b3a52db2f3071e5 Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Mon, 27 Aug 2018 18:52:27 -0500 Subject: [PATCH 121/142] =?UTF-8?q?Lee=20y=20grafica=20Series=20de=20Cauda?= =?UTF-8?q?les=20y=20serie=20de=20precipitaci=C3=B3n=20media,=20Pesta?= =?UTF-8?q?=C3=B1a=20de=20simulaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPlots.py | 53 ++++++ qgisplugin/HydroSEDPluginUtils.py | 10 ++ qgisplugin/HydroSEDPlugin_dockwidget.py | 112 +++++++++++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 173 ++++++++++--------- 4 files changed, 265 insertions(+), 83 deletions(-) diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py index 296a136..c394614 100644 --- a/qgisplugin/HydroSEDPlots.py +++ b/qgisplugin/HydroSEDPlots.py @@ -212,6 +212,59 @@ def Plot_MediaMensual(self, pathFigure): fig = dict(data=data, layout=layout) plot(fig,filename=pathFigure, auto_open = False) +class PlotCaudal(): + def __init__(self): + self.a = 0 + + def Plot_Caudal(self, pathFigure,DataQ,id_est,colorline): + '''Hace el plot de la serie de tiempo de lluvia e incluye en esta toda la info necesaria''' + #obtiene los records + Q = DataQ[id_est].copy() + #Datos de lluvia + trace1 = go.Scatter( + x = Q.index.to_pydatetime(), + y = Q.values, + name = 'Caudal Observado', + line = dict(color = (colorline),width=3), + fill='tozeroy' + ) + #Datos y formato de la figura + data = [trace1] + layout = dict( + width=1020, + height=400, + showlegend = False, + margin=dict( + l=50, + r=50, + b=50, + t=50, + pad=4 + ), + yaxis=dict( + title='Caudal Observado [m3/s]', + titlefont=dict( + color='black', + size = 15 + ), + tickangle=-90, + tickfont=dict( + color='black', + size = 16, + ), + ), + + xaxis = dict( + tickfont = dict( + size = 16 + ), + ), + ) + #Figura + fig = dict(data=data, layout=layout) + #Guarda el html + plot(fig,filename=pathFigure, auto_open = False) + class PlotGeomorphology(): diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 8797d3c..4fa8151 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -704,6 +704,16 @@ def Interpol_GetRainfallAcum(self, path2bin, inicio, fin): 'categoria': 'Hidro', 'var': Vsum, 'saved':False}}) + + def Sim_GetQobsInfo(self,PathExcelQobs): + DataQ = pd.read_excel(PathExcelQobs) + self.QobsData = DataQ.copy() + self.QobsData_fi = DataQ.index[0].to_pydatetime() + self.QobsData_ff = DataQ.index[-1].to_pydatetime() + self.QobsData_fd = DataQ.index[1] - DataQ.index[0] + idExcelQ = self.QobsData.columns.values.tolist() + return idExcelQ,DataQ + def Sim_SaveParameters(self, PathNC, ParamName, scalarParam): '''Actualiza el nc con un conjunto de parametros escalares nuevo''' diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 8b47212..348683d 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -70,6 +70,8 @@ def __init__(self, iface = None, parent=None): self.TablaFila_NC = 0 self.botonClicked = False self.segundaCarga = False + self.Segunda_carga_Qobs = False + self.Segunda_carga_Qobs_Sed = False self.GeoPlots = HSplots.PlotGeomorphology() @@ -921,6 +923,14 @@ def clickEventGetAcumRainfall(): def setupSimulation(self): '''Herramientas para gestionar la simulacion hidrologica con la cuenca cargada''' + def setupLineEditButtonOpenExcelCaudalFileDialog (lineEditHolder, fileDialogHolder): + '''Que solo busque los archivos con esa extension .xlsx''' + lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Excel (*.xlsx);;")) + + def setupLineEditButtonOpenBinFileDialog (lineEditHolder, fileDialogHolder): + '''Que solo busque los archivos con esa extension .bin''' + lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Binarios (*.bin);;")) + def changeEventUpdateScalarParameters(): '''Actualiza los parametros escalares de las tablas de acuerdo al set seleccionado''' #Obtiene el nombre de la param seleccionada @@ -975,11 +985,109 @@ def clickEventAddNewParamSet(): #mensaje de exito self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'La parametrización: ' + ParamName+' se ha guardado en el proyecto', level=QgsMessageBar.INFO, duration=3) + + def clickEventSelectorArchivoExcelCaudales(): + '''Evento de click: selecciona el archivo de excel con los datos caudal observado a utilizar''' + #Busca el archivo + setupLineEditButtonOpenExcelCaudalFileDialog (self.PathinSimu_Qobs, QFileDialog) + #vacia la lista desplegable + if self.Segunda_carga_Qobs == True: + self.comboBox_Selec_Qobs.clear() + + for l in self.HSutils.Sim_GetQobsInfo(self.PathinSimu_Qobs.text().strip())[0]: + self.comboBox_Selec_Qobs.addItem(str(l)) + + self.Segunda_carga_Qobs = True + def clickEventSelectorArchivoExcelCaudalesSed(): + '''Evento de click: selecciona el archivo de excel con los datos de Caudal solido a usar''' + #Busca el archivo + setupLineEditButtonOpenExcelCaudalFileDialog (self.PathinSimu_Qobs_Sed, QFileDialog) + + #vacia la lista desplegable + if self.Segunda_carga_Qobs_Sed == True: + self.comboBox_Selec_Qobs_Sed.clear() + + for l in self.HSutils.Sim_GetQobsInfo(self.PathinSimu_Qobs_Sed.text().strip())[0]: + self.comboBox_Selec_Qobs_Sed.addItem(str(l)) + + self.Segunda_carga_Qobs_Sed = True + def clickEventSelectorArchivoBinarioSimulacion(): + '''Evento de click: selecciona el archivo binario con la precipitacion para correr el modelo''' + #Busca el archivo + setupLineEditButtonOpenBinFileDialog (self.PathinSimu_Precipitacion,QFileDialog) + try: + PathData = self.PathinSimu_Precipitacion.text().strip() + self.HSplots = HSplots.PlotRainfall(PathData) + except: + pass + + def clickEventViewSerieSimuRainfall(): + '''Genera y visualiza la grafica de lluvia interpolada para la cuenca con la que se va a simular''' + #Hace la figura + PathFigure = '/tmp/HydroSED/Plots_Rainfall/RainfallPlotSimu.html' + self.HSplots.Plot_Rainfall(PathFigure) + #Set de la ventana que contiene la figura. + self.VistaRainWeb = QWebView(None) + self.VistaRainWeb.load(QUrl.fromLocalFile(PathFigure)) + self.VistaRainWeb.setWindowTitle('Precipitacion media en la cuenca') + self.VistaRainWeb.setMinimumWidth(1100) + self.VistaRainWeb.setMaximumWidth(3000) + self.VistaRainWeb.setMinimumHeight(100) + self.VistaRainWeb.setMaximumHeight(400) + self.VistaRainWeb.show() + + def clickEventViewSerieQobs(): + PathFigure = '/tmp/HydroSED/Plots_Rainfall/QobsPlotSimu.html' + PathQobs = self.PathinSimu_Qobs.text().strip() + #Obtiene el id de la estación + id_est = int(self.comboBox_Selec_Qobs.currentText().encode()) + #Obtiene la serie de caudales + DataQ = self.HSutils.Sim_GetQobsInfo(PathQobs)[1] + self.HSplots = HSplots.PlotCaudal() + self.HSplots.Plot_Caudal(PathFigure,DataQ,id_est,'blue') + #Set de la ventana que contiene la figura. + self.VistaQobsWeb = QWebView(None) + self.VistaQobsWeb.load(QUrl.fromLocalFile(PathFigure)) + self.VistaQobsWeb.setWindowTitle('Serie de Caudales medios') + self.VistaQobsWeb.setMinimumWidth(1100) + self.VistaQobsWeb.setMaximumWidth(3000) + self.VistaQobsWeb.setMinimumHeight(100) + self.VistaQobsWeb.setMaximumHeight(400) + self.VistaQobsWeb.show() + + + def clickEventViewSerieQobsSed(): + PathFigure = '/tmp/HydroSED/Plots_Rainfall/QobsSedPlotSimu.html' + PathQobs = self.PathinSimu_Qobs_Sed.text().strip() + #Obtiene el id de la estación + id_est = int(self.comboBox_Selec_Qobs_Sed.currentText().encode()) + #Obtiene la serie de caudales + DataQ = self.HSutils.Sim_GetQobsInfo(PathQobs)[1] + self.HSplots = HSplots.PlotCaudal() + self.HSplots.Plot_Caudal(PathFigure,DataQ,id_est,'goldenrod') + #Set de la ventana que contiene la figura. + self.VistaQobsWeb = QWebView(None) + self.VistaQobsWeb.load(QUrl.fromLocalFile(PathFigure)) + self.VistaQobsWeb.setWindowTitle('Serie de Caudales medios') + self.VistaQobsWeb.setMinimumWidth(1100) + self.VistaQobsWeb.setMaximumWidth(3000) + self.VistaQobsWeb.setMinimumHeight(100) + self.VistaQobsWeb.setMaximumHeight(400) + self.VistaQobsWeb.show() + self.ButtonSimCalib2Nc.clicked.connect(clickEventAddNewParamSet) self.tabPanelDockOpciones.currentChanged.connect(clickEventUpdateParamMapValues) - self.ParamNamesCombo.currentIndexChanged.connect(changeEventUpdateScalarParameters) - + self.ParamNamesCombo.currentIndexChanged.connect(changeEventUpdateScalarParameters) + + self.Boton_SimuSelec_Qobs.clicked.connect(clickEventSelectorArchivoExcelCaudales) + self.Boton_SimuSelec_Qobs_Sed.clicked.connect(clickEventSelectorArchivoExcelCaudalesSed) + self.Boton_SimuSelec_Binario.clicked.connect(clickEventSelectorArchivoBinarioSimulacion) + + self.Boton_Visualizar_Binario.clicked.connect(clickEventViewSerieSimuRainfall) + self.Boton_Visualizar_Qobs.clicked.connect(clickEventViewSerieQobs) + self.Boton_Visualizar_Qobs_Sed.clicked.connect(clickEventViewSerieQobsSed) + def setupUIInputsOutputs (self): def DrawClickEvent_histogram_WMF(): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 4b0ef9c..168bae1 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -68,7 +68,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -250,11 +250,11 @@ - 3 + 4 - + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png @@ -294,8 +294,8 @@ 0 - -878 - 443 + 0 + 446 2018 @@ -434,7 +434,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -536,7 +536,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -761,7 +761,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -824,7 +824,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -900,7 +900,7 @@ - + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico @@ -941,7 +941,7 @@ - + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -976,7 +976,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -999,7 +999,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -1071,7 +1071,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png:/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png @@ -1094,7 +1094,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png:/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png @@ -1383,7 +1383,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1446,7 +1446,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -1481,7 +1481,7 @@ - + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -1538,7 +1538,7 @@ - + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico @@ -1564,7 +1564,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -1587,7 +1587,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -1639,7 +1639,7 @@ 0 0 - 443 + 446 2018 @@ -1732,7 +1732,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -1846,7 +1846,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1863,7 +1863,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1939,7 +1939,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -2122,7 +2122,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2216,7 +2216,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2264,7 +2264,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2312,7 +2312,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2371,7 +2371,7 @@ 0 0 - 443 + 446 1918 @@ -2540,7 +2540,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2850,7 +2850,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2962,7 +2962,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -2979,7 +2979,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3194,7 +3194,7 @@ 0 0 - 443 + 446 1918 @@ -3317,7 +3317,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3343,7 +3343,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3495,7 +3495,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3521,7 +3521,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3581,7 +3581,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3680,7 +3680,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3746,7 +3746,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3939,7 +3939,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3956,7 +3956,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4133,7 +4133,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4409,7 +4409,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4435,7 +4435,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4495,7 +4495,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4635,7 +4635,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4776,7 +4776,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4793,7 +4793,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4970,7 +4970,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5022,7 +5022,7 @@ 0 0 - 433 + 436 1918 @@ -5079,20 +5079,23 @@ - + Qt::Horizontal + + QSizePolicy::Preferred + - 40 + 47 20 - + 30 @@ -5114,7 +5117,7 @@ - + 30 @@ -5137,16 +5140,13 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - + 50 @@ -5169,11 +5169,24 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -5199,7 +5212,7 @@ - + 50 @@ -5221,7 +5234,7 @@ - + 30 @@ -5244,16 +5257,16 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - + - + 50 @@ -5276,7 +5289,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5306,7 +5319,7 @@ - + 30 @@ -5328,7 +5341,7 @@ - + 30 @@ -5351,16 +5364,16 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - + - + 50 @@ -5383,7 +5396,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5409,7 +5422,7 @@ - 0 + -10 160 411 711 @@ -6105,7 +6118,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -6320,8 +6333,6 @@ - - - + From 5107ef34f2c8767d8624822e492d1462a6c30bf8 Mon Sep 17 00:00:00 2001 From: nicolas998 Date: Mon, 27 Aug 2018 23:51:43 -0500 Subject: [PATCH 122/142] se agregan las funciones para pasar las fechas de radar a las fechas seleccionadas para obtener campos de lluvia en las cuencas, falta juntar las funciones con la interfaz. --- qgisplugin/HydroSEDPluginUtils.py | 161 +++++++------------ qgisplugin/HydroSEDPlugin_dockwidget.py | 35 ++-- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 116 +++++++------ 3 files changed, 139 insertions(+), 173 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 3fbcde6..c755068 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -820,107 +820,62 @@ def __fx__(x, metodo = 'media'): #VarAgregada[posMalos] = VarAgregada[posBuenos].mean() #print VarAgregada[posMalos].min() return VarAgregada - - def Radar_Conver2Basin(self, RadarFiles,fi,ff, TimeDelta, PathOut): - - -#si el binario el viejo, establece las variables para actualizar -if old: - self.cuenca.rain_radar2basin_from_array(status='old',ruta_out= args.rutaRes) -#Itera sobre las fechas para actualizar el binario de campos -datesDt = datesDt.to_pydatetime() -for dates,pos in zip(datesDt[1:],PosDates): - rvec = np.zeros(cuAMVA.ncells) - if args.save_escenarios: - rhigh = np.zeros(cuAMVA.ncells) - rlow = np.zeros(cuAMVA.ncells) - Conv = np.zeros(cuAMVA.ncells, dtype = int) - Stra = np.zeros(cuAMVA.ncells, dtype = int) - try: - for c,p in enumerate(pos): - #Lee la imagen de radar para esa fecha - g = netCDF4.Dataset(ListRutas[p]) - print ListRutas[p] - RadProp = [g.ncols, g.nrows, g.xll, g.yll, g.dx, g.dx] - #Agrega la lluvia en el intervalo - rvec += cuAMVA.Transform_Map2Basin(g.variables['Rain'][:].T/ (12*1000.0),RadProp) - if args.save_escenarios: - rhigh += cuAMVA.Transform_Map2Basin(g.variables['Rhigh'][:].T / (12*1000.0), RadProp) - rlow += cuAMVA.Transform_Map2Basin(g.variables['Rlow'][:].T / (12*1000.0), RadProp) - #Agrega la clasificacion para la ultima imagen del intervalo - ConvStra = cuAMVA.Transform_Map2Basin(g.variables['Conv_Strat'][:].T, RadProp) - Conv = np.copy(ConvStra) - Conv[Conv == 1] = 0; Conv[Conv == 2] = 1 - Stra = np.copy(ConvStra) - Stra[Stra == 2] = 0 - #rvec[(Conv == 0) & (Stra == 0)] = 0 - if args.save_escenarios: - rhigh[(Conv == 0) & (Stra == 0)] = 0 - rlow[(Conv == 0) & (Stra == 0)] = 0 - Conv[rvec == 0] = 0 - Stra[rvec == 0] = 0 - #Cierra el netCDF - g.close() - except Exception, e: - print 'error' - rvec = np.zeros(cuAMVA.ncells) - if args.save_escenarios: - rhigh = np.zeros(cuAMVA.ncells) - rlow = np.zeros(cuAMVA.ncells) - Conv = np.zeros(cuAMVA.ncells) - Stra = np.zeros(cuAMVA.ncells) - #rvec[ConvStra==0] = 0 - #rhigh[ConvStra==0] = 0 - #rlow[ConvStra==0] = 0 - #Escribe el binario de lluvia - dentro = cuAMVA.rain_radar2basin_from_array(vec = rvec, - ruta_out = args.rutaRes, - fecha = dates-dt.timedelta(hours = 5), - dt = args.dt, - umbral = args.umbral) - if args.save_escenarios: - dentro = cuHigh.rain_radar2basin_from_array(vec = rhigh, - ruta_out = args.rutaRes+'_high', - fecha = dates-dt.timedelta(hours = 5), - dt = args.dt, - umbral = args.umbral) - dentro = cuLow.rain_radar2basin_from_array(vec = rlow, - ruta_out = args.rutaRes+'_low', - fecha = dates-dt.timedelta(hours = 5), - dt = args.dt, - umbral = args.umbral) - if dentro == 0: - hagalo = True - else: - hagalo = False - #mira si guarda o no los clasificados - if args.save_class: - #Escribe el binario convectivo - aa = cuConv.rain_radar2basin_from_array(vec = Conv, - ruta_out = args.rutaRes+'_conv', - fecha = dates-dt.timedelta(hours = 5), - dt = args.dt, - doit = hagalo) - #Escribe el binario estratiforme - aa = cuStra.rain_radar2basin_from_array(vec = Stra, - ruta_out = args.rutaRes+'_stra', - fecha = dates-dt.timedelta(hours = 5), - dt = args.dt, - doit = hagalo) - #Opcion Vervose - if args.verbose: - print dates.strftime('%Y%m%d-%H:%M'), pos - -#Cierrra el binario y escribe encabezado -cuAMVA.rain_radar2basin_from_array(status = 'close',ruta_out = args.rutaRes) -if args.save_class: - cuConv.rain_radar2basin_from_array(status = 'close',ruta_out = args.rutaRes+'_conv') - cuStra.rain_radar2basin_from_array(status = 'close',ruta_out = args.rutaRes+'_stra') -if args.save_escenarios: - cuHigh.rain_radar2basin_from_array(status = 'close',ruta_out = args.rutaRes+'_high') - cuLow.rain_radar2basin_from_array(status = 'close',ruta_out = args.rutaRes+'_low') -#Imprime en lo que va -if args.verbose: - print 'Encabezados de binarios de cuenca cerrados y listos' - + def Radar_FechasProcess(self, Fi, Ff, TimeStep, FechasRadar, ListaRadar): + '''Obtiene las fechas adecuadas y las posiciones para ls ttfmacion de radar a cuenca''' + #Rango de fechas a convertir + self.ConvertDates = pd.date_range(Fi,Ff,freq=TimeStep) + TextoFechas = [i.strftime('%Y-%m-%d-%H:%M') for i in self.ConvertDates.to_pydatetime()] + #Obtiene fechas equivalentes para las fechas a convertir + DatesRadar = pd.to_datetime(FechasRadar) + DatesRadar = DatesRadar.ceil(tr) + #Slice de analisis + Ini = DatesRadar.get_loc(TextoFechas[0]) + try: + Ini = Ini.start + except: + pass + Fin = DatesRadar.get_loc(TextoFechas[-1]) + try: + Fin = Fin.stop + except: + pass + #Corte en vectores + self.DatesRadar = DatesRadar[Ini:Fin] + FechasRadar = FechasRadar[Ini:Fin] + self.ListRadar = ListRadar[Ini:Fin] + self.TextoFechas = TextoFechas + + def Radar_Conver2Basin(self, PathRadarBasin, TimeStep, umbral = 0.01, + verbose = False, old = False): + '''Convierte barridos de radar a la cuenca''' + #Se fija si ya existia un binario con campos + if old: + self.cuenca.rain_radar2basin_from_array(status='old',ruta_out= PathRadarBasin) + #Convierte para las fechas + for ft,date in zip(self.TextoFechas, self.ConvertDates.to_pydatetime()): + #Posiciones de datos de radar + s = self.DatesRadar.get_loc(ft) + try: + ListaPos = range(s.start, s.stop) + except: + ListaPos = [s] + #Acumula para ese periodo + Rain = np.zeros(cu.ncells) + for l in ListaPos: + #Lee el netCDF y lo transforma + g = netCDF4.Dataset(self.ListRadar[l]) + RadProp = [g.ncols, g.nrows, g.xll, g.yll, g.dx, g.dx] + Rain += self.cuenca.Transform_Map2Basin(g.variables['Rain'][:].T/ (12*1000.0),RadProp) + g.close() + #Actualiza el binario con datos de radar + dentro = cu.rain_radar2basin_from_array(vec = Rain, + ruta_out = PathRadarBasin, + fecha = date-dt.timedelta(hours = 5), + dt = TimeStep, + umbral = umbral) + if verbose: + print date, Rain.mean() + #Cierra el binario y cea el encabezado + cu.rain_radar2basin_from_array(status = 'close',ruta_out = PathRadarBasin) + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 3d5676c..9ac3512 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -775,9 +775,10 @@ def clickEventConvertVariable2NC(): def setupRainfall(self): '''Conjunto de herramientas dispuestas para interpolar campos de precipitacion''' - - #self.PathInHydro_Radar.setText('/home/nicolas/Radar') - + + ListaRadarDates = [] + FechasRadar = [] + def setupLineEditButtonOpenShapeFileDialog (lineEditHolder, fileDialogHolder): '''Hace que cuando se busquen shapes solo se encuetren formatos vectoriales''' lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Shapefiles (*.shp);;")) @@ -794,6 +795,7 @@ def setupLineEditButtonOpenExcelFileDialog (lineEditHolder, fileDialogHolder): def setupLineEditButtonOpenRadarFileDialog (lineEditHolder, fileDialogHolder): '''Para cambiar la carpeta por defecto donde se buscan las imagenes de radar''' + #Obtiene la ruta donde esta lo de radar OutputFolder = fileDialogHolder.getExistingDirectory(QtGui.QDialog(), "Cargador de Cuencas", "/tmp/", QFileDialog.ShowDirsOnly) lineEditHolder.setText (OutputFolder) @@ -826,9 +828,18 @@ def clickEventSelectorArchivoExcel(): def clickEventSelectorRadarFiles(): '''Evento de seleccion de la carpeta contenedora de los archivos de radar''' + #Obtiene la ruta donde estan los archivos de radar setupLineEditButtonOpenRadarFileDialog(self.PathInHydro_Radar, QFileDialog) self.Path2Radar = self.PathInHydro_Radar - + #Actualiza lista con variables del radar + ListRadarDates = glob.glob(self.Path2Radar.text().strip()) + ListRadarDates.sort() + FechasRadar = [] + for L in ListRadarDates: + try: + self.FechasRadar.append(dt.datetime.strptime(L[-23:-11],'%Y%m%d%H%M')) + except: + pass def clickEventSelectorArchivoBinarioLluvia(): '''Selecciona la ruta en donde se guardara el binario de salida.''' @@ -874,16 +885,18 @@ def clickEventEjecutarInterpolacion(): self.iface.messageBar().pushInfo(u'HidroSIG:',u'Interpolacion de campos de precipitacion realizada con exito') def clickEventEjecutarConversionRadar(): - '''Convierte campos de radar en la cuenca usando el archivo netCDF que se encuentran en la ruta especificada''' - #Toma los parametros para la interpolacion + '''Convierte campos de radar en la cuenca usando el archivo netCDF que se encuentran en la ruta especificada''' + #Toma los parametros para la interpolacion PathRadar = self.PathInHydro_Radar.text().strip() fi = self.Interpol_DateTimeStart_Radar.dateTime().toPyDateTime() ff = self.Interpol_DateTimeEnd_Radar.dateTime().toPyDateTime() fd = self.Interpol_SpinBox_delta_Radar.value() PathOut = self.PathOutHydro_Radar.text().strip() + #Obtiene las fechas para conversion y la lista de valores + self.HSutils.Radar_FechasProcess(fi, ff, fd, FechasRadar, ListaRadarDates) #Interpola para la cuenca seleccionada - self.HSutils.Radar_Conver2Basin(PathRadar,fi,ff,fd,PathOut) - #Trata de leer datos de lluvia en caso de que ya existan + self.HSutils.Radar_Conver2Basin(PathOut) + #Trata de leer datos de lluvia en caso de que ya existan try: PathData = self.PathOutHydro_Radar.text().strip() self.HSplots = HSplots.PlotRainfall(PathData) @@ -1039,8 +1052,8 @@ def clickEventSelectorArchivoExcelCaudales(): setupLineEditButtonOpenExcelCaudalFileDialog (self.PathinSimu_Qobs, QFileDialog) #vacia la lista desplegable if self.Segunda_carga_Qobs == True: - self.comboBox_Selec_Qobs.clear() - + self.comboBox_Selec_Qobs.clear() + for l in self.HSutils.Sim_GetQobsInfo(self.PathinSimu_Qobs.text().strip())[0]: self.comboBox_Selec_Qobs.addItem(str(l)) @@ -1052,7 +1065,7 @@ def clickEventSelectorArchivoExcelCaudalesSed(): #vacia la lista desplegable if self.Segunda_carga_Qobs_Sed == True: - self.comboBox_Selec_Qobs_Sed.clear() + self.comboBox_Selec_Qobs_Sed.clear() for l in self.HSutils.Sim_GetQobsInfo(self.PathinSimu_Qobs_Sed.text().strip())[0]: self.comboBox_Selec_Qobs_Sed.addItem(str(l)) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index ac2dcde..a577021 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -68,7 +68,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -254,7 +254,7 @@ - + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png @@ -295,7 +295,7 @@ 0 0 - 446 + 443 2018 @@ -434,7 +434,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -536,7 +536,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -761,7 +761,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -824,7 +824,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -941,7 +941,7 @@ - + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -976,7 +976,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -999,7 +999,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -1071,7 +1071,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png:/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png @@ -1094,7 +1094,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png:/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png @@ -1383,7 +1383,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1446,7 +1446,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -1481,7 +1481,7 @@ - + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -1564,7 +1564,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -1587,7 +1587,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -1639,7 +1639,7 @@ 0 0 - 446 + 443 2018 @@ -1732,7 +1732,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -1846,7 +1846,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1863,7 +1863,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1939,7 +1939,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -2122,7 +2122,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2216,7 +2216,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2264,7 +2264,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2312,7 +2312,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2371,7 +2371,7 @@ 0 0 - 446 + 443 1918 @@ -2540,7 +2540,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2850,7 +2850,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2962,7 +2962,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -2979,7 +2979,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3194,8 +3194,6 @@ 0 0 - 446 - -33 443 1918 @@ -3319,7 +3317,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3345,7 +3343,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3497,7 +3495,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3523,7 +3521,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3583,7 +3581,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3682,7 +3680,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3748,7 +3746,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3944,7 +3942,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3961,7 +3959,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4138,7 +4136,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4414,7 +4412,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4440,7 +4438,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4500,7 +4498,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4640,7 +4638,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4784,7 +4782,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4801,7 +4799,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4978,7 +4976,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5030,7 +5028,7 @@ 0 0 - 436 + 433 1918 @@ -5148,7 +5146,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -5177,7 +5175,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5265,7 +5263,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -5297,7 +5295,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5372,7 +5370,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -5404,7 +5402,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5430,7 +5428,7 @@ - -10 + 0 160 411 711 @@ -6126,7 +6124,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg From c0b82481d66d3ae529a280da4714b84f77286a53 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 28 Aug 2018 09:54:53 -0500 Subject: [PATCH 123/142] conversor de radar a cuenca funciona de manera parcial, sigue teniendo problemas por fechas --- qgisplugin/HydroSEDPluginUtils.py | 15 +++++---- qgisplugin/HydroSEDPlugin_dockwidget.py | 44 +++++++++++++++++++------ wmf/wmf.py | 4 +-- 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index c755068..fe6dc7b 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -5,6 +5,7 @@ import netCDF4 from wmf import wmf import numpy as np +import datetime as dt import scipy.stats as stat import pandas as pd import osgeo.ogr as ogr @@ -689,11 +690,13 @@ def Interpol_GetRainfallAcum(self, path2bin, inicio, fin): '''Obtiene un campo acumulado de precipitacion para el periodo especifico''' #Lee el binario y los datos en el intervalo Vsum = np.zeros(self.cuenca.ncells) + print path2bin for i in range(inicio, fin+1): vect,res = wmf.models.read_int_basin(path2bin,i,self.cuenca.ncells) if res == 0: vect = vect.astype(float)/1000. Vsum+=vect + print 'salida' #Pasa el acumulado al diccionario de WMF self.DicBasinWMF.update({'Lluvia': {'nombre':'Lluvia', @@ -828,7 +831,7 @@ def Radar_FechasProcess(self, Fi, Ff, TimeStep, FechasRadar, ListaRadar): TextoFechas = [i.strftime('%Y-%m-%d-%H:%M') for i in self.ConvertDates.to_pydatetime()] #Obtiene fechas equivalentes para las fechas a convertir DatesRadar = pd.to_datetime(FechasRadar) - DatesRadar = DatesRadar.ceil(tr) + DatesRadar = DatesRadar.ceil(TimeStep) #Slice de analisis Ini = DatesRadar.get_loc(TextoFechas[0]) try: @@ -843,7 +846,7 @@ def Radar_FechasProcess(self, Fi, Ff, TimeStep, FechasRadar, ListaRadar): #Corte en vectores self.DatesRadar = DatesRadar[Ini:Fin] FechasRadar = FechasRadar[Ini:Fin] - self.ListRadar = ListRadar[Ini:Fin] + self.ListaRadar = ListaRadar[Ini:Fin] self.TextoFechas = TextoFechas def Radar_Conver2Basin(self, PathRadarBasin, TimeStep, umbral = 0.01, @@ -861,15 +864,15 @@ def Radar_Conver2Basin(self, PathRadarBasin, TimeStep, umbral = 0.01, except: ListaPos = [s] #Acumula para ese periodo - Rain = np.zeros(cu.ncells) + Rain = np.zeros(self.cuenca.ncells) for l in ListaPos: #Lee el netCDF y lo transforma - g = netCDF4.Dataset(self.ListRadar[l]) + g = netCDF4.Dataset(self.ListaRadar[l]) RadProp = [g.ncols, g.nrows, g.xll, g.yll, g.dx, g.dx] Rain += self.cuenca.Transform_Map2Basin(g.variables['Rain'][:].T/ (12*1000.0),RadProp) g.close() #Actualiza el binario con datos de radar - dentro = cu.rain_radar2basin_from_array(vec = Rain, + dentro = self.cuenca.rain_radar2basin_from_array(vec = Rain, ruta_out = PathRadarBasin, fecha = date-dt.timedelta(hours = 5), dt = TimeStep, @@ -877,5 +880,5 @@ def Radar_Conver2Basin(self, PathRadarBasin, TimeStep, umbral = 0.01, if verbose: print date, Rain.mean() #Cierra el binario y cea el encabezado - cu.rain_radar2basin_from_array(status = 'close',ruta_out = PathRadarBasin) + self.cuenca.rain_radar2basin_from_array(status = 'close',ruta_out = PathRadarBasin) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 9ac3512..9d91d0b 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -23,6 +23,8 @@ import os import numpy as np +import glob +import datetime as dt from PyQt4 import QtGui, uic, QtCore, Qt from PyQt4.QtCore import pyqtSignal, QUrl @@ -776,8 +778,8 @@ def clickEventConvertVariable2NC(): def setupRainfall(self): '''Conjunto de herramientas dispuestas para interpolar campos de precipitacion''' - ListaRadarDates = [] - FechasRadar = [] + #ListaRadarDates = [] + #FechasRadar = [] def setupLineEditButtonOpenShapeFileDialog (lineEditHolder, fileDialogHolder): '''Hace que cuando se busquen shapes solo se encuetren formatos vectoriales''' @@ -832,12 +834,12 @@ def clickEventSelectorRadarFiles(): setupLineEditButtonOpenRadarFileDialog(self.PathInHydro_Radar, QFileDialog) self.Path2Radar = self.PathInHydro_Radar #Actualiza lista con variables del radar - ListRadarDates = glob.glob(self.Path2Radar.text().strip()) - ListRadarDates.sort() - FechasRadar = [] - for L in ListRadarDates: + self.ListaRadarDates = glob.glob(self.Path2Radar.text().strip()+'/*.nc') + self.ListaRadarDates.sort() + self.FechasRadar = [] + for L in self.ListaRadarDates: try: - self.FechasRadar.append(dt.datetime.strptime(L[-23:-11],'%Y%m%d%H%M')) + self.FechasRadar.append(dt.datetime.strptime(L[-23:-11],'%Y%m%d%H%M')) except: pass @@ -890,12 +892,12 @@ def clickEventEjecutarConversionRadar(): PathRadar = self.PathInHydro_Radar.text().strip() fi = self.Interpol_DateTimeStart_Radar.dateTime().toPyDateTime() ff = self.Interpol_DateTimeEnd_Radar.dateTime().toPyDateTime() - fd = self.Interpol_SpinBox_delta_Radar.value() + Step = '%dS' % self.Interpol_SpinBox_delta_Radar.value() PathOut = self.PathOutHydro_Radar.text().strip() #Obtiene las fechas para conversion y la lista de valores - self.HSutils.Radar_FechasProcess(fi, ff, fd, FechasRadar, ListaRadarDates) + self.HSutils.Radar_FechasProcess(fi, ff, Step, self.FechasRadar, self.ListaRadarDates) #Interpola para la cuenca seleccionada - self.HSutils.Radar_Conver2Basin(PathOut) + self.HSutils.Radar_Conver2Basin(PathOut, Step) #Trata de leer datos de lluvia en caso de que ya existan try: PathData = self.PathOutHydro_Radar.text().strip() @@ -964,6 +966,21 @@ def clickEventGetAcumRainfall(): #Aviso de existo self.iface.messageBar().pushInfo(u'HidroSIG:',u'Los campos de han acumulado en la variable Lluvia de la tabla WMF') + def clickEventGetAcumRainfallRadar(): + '''Obtiene el acumulado de lluvia en el periodo especifico''' + #Punto inicial y final + Path = self.PathOutHydro_Radar.text().strip() + inicio = int(self.spinBoxCampoInicio_Radar.value()) + fin = int(self.spinBoxCampoFin_Radar.value()) + #Obtiene el campo acumulado para el periodo seleccionado + self.HSutils.Interpol_GetRainfallAcum(Path, inicio, fin) + #Actualiza la tabla WMF + k = 'Lluvia' + self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[k],k, self.Tabla_Prop_WMF) + #Aviso de existo + self.iface.messageBar().pushInfo(u'HidroSIG:',u'Los campos de han acumulado en la variable Lluvia de la tabla WMF') + + #Botones de set de interpolacion self.Boton_HidroLoad_Pluvios.clicked.connect(clickEventSelectorMapaPuntosPluvio) self.Boton_HidroLoad_Serie.clicked.connect(clickEventSelectorArchivoExcel) @@ -979,6 +996,13 @@ def clickEventGetAcumRainfall(): #botones set de radar self.Boton_HidroLoad_RadarData.clicked.connect(clickEventSelectorRadarFiles) self.Button_HidroSaveRadar.clicked.connect(clickEventSelectorArchivoBinarioLluviaRadar) + #Boton de ejecucion de radar + self.Button_Ejec_HidroRadar.clicked.connect(clickEventEjecutarConversionRadar) + #Botones de visualizacion + self.Button_InterpolCiclo_Radar.clicked.connect(clickEventViewMediaMensualRainfall) + self.Button_InterpolHistogram_Radar.clicked.connect(clickEventViewHistogramRainfall) + self.Button_InterpolSerieView_Radar.clicked.connect(clickEventViewSerieRainfall) + self.Button_InterpolViewRadar.clicked.connect(clickEventGetAcumRainfallRadar) def setupSimulation(self): '''Herramientas para gestionar la simulacion hidrologica con la cuenca cargada''' diff --git a/wmf/wmf.py b/wmf/wmf.py index bc25eaa..03143ea 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -3301,8 +3301,8 @@ def rain_radar2basin_from_array(self,vec=None,ruta_out=None,fecha=None,dt=None, #Edita la ruta de salida if ruta_out is not None: if ruta_out.endswith('.hdr') or ruta_out.endswith('.bin'): - ruta_bin = ruta_out[:-3]+'.bin' - ruta_hdr = ruta_out[:-3]+'.hdr' + ruta_bin = ruta_out[:-4]+'.bin' + ruta_hdr = ruta_out[:-4]+'.hdr' else: ruta_bin = ruta_out+'.bin' ruta_hdr = ruta_out+'.hdr' From 51fc455d48abb1530ffff770d2815df69817e70b Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Tue, 28 Aug 2018 12:17:06 -0500 Subject: [PATCH 124/142] conversor de radar a cuenca ya funciona relativamente bien --- qgisplugin/HydroSEDPluginUtils.py | 75 +++++++++++++++---------- qgisplugin/HydroSEDPlugin_dockwidget.py | 3 + 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index fe6dc7b..82716fc 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -828,57 +828,74 @@ def Radar_FechasProcess(self, Fi, Ff, TimeStep, FechasRadar, ListaRadar): '''Obtiene las fechas adecuadas y las posiciones para ls ttfmacion de radar a cuenca''' #Rango de fechas a convertir self.ConvertDates = pd.date_range(Fi,Ff,freq=TimeStep) - TextoFechas = [i.strftime('%Y-%m-%d-%H:%M') for i in self.ConvertDates.to_pydatetime()] + #TextoFechas = [i.strftime('%Y-%m-%d %H:%M') for i in self.ConvertDates.to_pydatetime()] #Obtiene fechas equivalentes para las fechas a convertir DatesRadar = pd.to_datetime(FechasRadar) DatesRadar = DatesRadar.ceil(TimeStep) + print DatesRadar[:5] + print DatesRadar[-5:] #Slice de analisis - Ini = DatesRadar.get_loc(TextoFechas[0]) - try: - Ini = Ini.start - except: - pass - Fin = DatesRadar.get_loc(TextoFechas[-1]) - try: - Fin = Fin.stop - except: - pass + Flag = True + pos = 0 + while Flag: + try: + Ini = np.where(DatesRadar == self.ConvertDates[pos])[0].tolist()[0] + Flag = False + print Ini, pos + except: + pos += 1 + if pos>DatesRadar.size: Flag = False + Flag = True + pos = -1 + while Flag: + try: + Fin = np.where(DatesRadar == self.ConvertDates[pos])[0].tolist()[0] + Flag = False + print Fin, pos + except: + pos -= 1 + if pos>DatesRadar.size: Flag = False #Corte en vectores self.DatesRadar = DatesRadar[Ini:Fin] FechasRadar = FechasRadar[Ini:Fin] self.ListaRadar = ListaRadar[Ini:Fin] - self.TextoFechas = TextoFechas + #self.TextoFechas = TextoFechas def Radar_Conver2Basin(self, PathRadarBasin, TimeStep, umbral = 0.01, - verbose = False, old = False): + verbose = True, old = False): '''Convierte barridos de radar a la cuenca''' #Se fija si ya existia un binario con campos if old: self.cuenca.rain_radar2basin_from_array(status='old',ruta_out= PathRadarBasin) #Convierte para las fechas - for ft,date in zip(self.TextoFechas, self.ConvertDates.to_pydatetime()): + Rain = np.zeros(self.cuenca.ncells) + for ft,date in zip(self.ConvertDates, self.ConvertDates.to_pydatetime()): #Posiciones de datos de radar - s = self.DatesRadar.get_loc(ft) - try: - ListaPos = range(s.start, s.stop) - except: - ListaPos = [s] + ListaPos = np.where(self.DatesRadar == ft)[0].tolist() + Entra = True + if Rain.mean()>umbral and len(ListaPos) == 0: + RainFin = np.copy(Rain) + Entra = False + elif len(ListaPos)>0: + Entra = True #Acumula para ese periodo - Rain = np.zeros(self.cuenca.ncells) - for l in ListaPos: - #Lee el netCDF y lo transforma - g = netCDF4.Dataset(self.ListaRadar[l]) - RadProp = [g.ncols, g.nrows, g.xll, g.yll, g.dx, g.dx] - Rain += self.cuenca.Transform_Map2Basin(g.variables['Rain'][:].T/ (12*1000.0),RadProp) - g.close() + if Entra: + Rain = np.zeros(self.cuenca.ncells) + for l in ListaPos: + #Lee el netCDF y lo transforma + g = netCDF4.Dataset(self.ListaRadar[l]) + RadProp = [g.ncols, g.nrows, g.xll, g.yll, g.dx, g.dx] + Rain += self.cuenca.Transform_Map2Basin(g.variables['Rain'][:].T/ (12*1000.0),RadProp) + g.close() + RainFin = np.copy(Rain) #Actualiza el binario con datos de radar - dentro = self.cuenca.rain_radar2basin_from_array(vec = Rain, + dentro = self.cuenca.rain_radar2basin_from_array(vec = RainFin, ruta_out = PathRadarBasin, fecha = date-dt.timedelta(hours = 5), dt = TimeStep, umbral = umbral) if verbose: - print date, Rain.mean() + print date, RainFin.mean(), ListaPos #Cierra el binario y cea el encabezado self.cuenca.rain_radar2basin_from_array(status = 'close',ruta_out = PathRadarBasin) - + self.cuenca.rain_radar2basin_from_array(status = 'reset') diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 9d91d0b..883dbca 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -842,6 +842,9 @@ def clickEventSelectorRadarFiles(): self.FechasRadar.append(dt.datetime.strptime(L[-23:-11],'%Y%m%d%H%M')) except: pass + #print len(self.ListaRadarDates) + #print self.ListaRadarDates[0] + #print self.ListaRadarDates[-1] def clickEventSelectorArchivoBinarioLluvia(): '''Selecciona la ruta en donde se guardara el binario de salida.''' From 16e69088826594a24025b7681ac28a464ff3421e Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Tue, 28 Aug 2018 12:39:06 -0500 Subject: [PATCH 125/142] Cambios en la interfaz de sedimentos, toolTips --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 1277 ++++++++++++++---- 1 file changed, 1035 insertions(+), 242 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index a577021..178a927 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -68,7 +68,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -238,7 +238,7 @@ 0 - 130 + 150 469 776 @@ -254,7 +254,7 @@ - + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png @@ -295,7 +295,7 @@ 0 0 - 443 + 318 2018 @@ -372,6 +372,12 @@ 16777215 + + Establecer el tamaño de pixel del MDE y DIR + + + Establecer el tamaño de pixel del MDE y DIR + 10000.000000000000000 @@ -411,6 +417,12 @@ 16777215 + + Ruta en la que se encuentra el .tif con el MDE + + + Ruta en la que se encuentra el .tif con el MDE + true @@ -430,11 +442,17 @@ 16777215 + + Establecer la ruta en la que se encuentra el .tif con el MDE + + + Establecer la ruta en la que se encuentra el .tif con el MDE + - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -448,7 +466,10 @@ - <html><head/><body><p>Establece el MDE y sus propiedades como el mapa base para WMF.</p></body></html> + Carga el mapa base MDE para WMF + + + Carga el mapa base MDE para WMF Cargar @@ -481,7 +502,10 @@ - <html><head/><body><p>Carga el MDE en el layout de mapas de Qgis.</p></body></html> + Visualizar el MDE que ha sido cargado + + + Visualizar el MDE que ha sido cargado Visualizar @@ -513,6 +537,12 @@ 16777215 + + Ruta en la que se encuentra el .tif con el DIR + + + Ruta en la que se encuentra el .tif con el DIR + true @@ -532,11 +562,17 @@ 16777215 + + Establecer la ruta en la que se encuentra el .tif con el DIR + + + Establecer la ruta en la que se encuentra el .tif con el DIR + - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -550,7 +586,10 @@ - <html><head/><body><p>Establece el DIR y sus propiedades como el mapa base para WMF.</p></body></html> + Carga el mapa base DIR para WMF + + + Carga el mapa base DIR para WMF Cargar @@ -583,7 +622,10 @@ - <html><head/><body><p>Carga el DIR en el layout de mapas de Qgis.</p></body></html> + Visualizar el DIR que ha sido cargado + + + Visualizar el DIR que ha sido cargado Visualizar @@ -738,6 +780,12 @@ 16777215 + + Establecer la ruta del mapa raster a convertir + + + Establecer la ruta del mapa raster a convertir + false @@ -757,11 +805,17 @@ 16777215 + + Establecer la ruta del mapa raster a convertir + + + Establecer la ruta del mapa raster a convertir + - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -791,6 +845,12 @@ 16777215 + + Nombre con el que será cargado el el mapa a la tabla de variables de WMF + + + Nombre con el que será cargado el el mapa a la tabla de variables de WMF + false @@ -810,21 +870,28 @@ - + + + Seleccionar la categoría del mapa a convertir + + + Seleccionar la categoría del mapa a convertir + + - Ejecutar la función de trazado de corriente. + Ejecutar la función para convertir el raster a cuenca - Ejecutar la función de trazado de corriente. + Ejecutar la función para convertir el raster a cuenca - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -941,7 +1008,7 @@ - + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -976,7 +1043,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -995,11 +1062,17 @@ 16777215 + + Eliminar variable de la tabla + + + Eliminar variable de la tabla + - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -1067,11 +1140,17 @@ 16777215 + + Envar variables del NC al WMF (Si no han sido guardadas en el NC) + + + Envar variables del NC al WMF (Si no han sido guardadas en el NC) + - + :/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png:/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png @@ -1090,11 +1169,17 @@ 16777215 + + Enviar variables del WMF al NC + + + Enviar variables del WMF al NC + - + :/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png:/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png @@ -1168,10 +1253,10 @@ - Tipo de conversión usada para agregar (promedio) + Tipo de conversión usada para agregar - Tipo de conversión usada para agregar (promedio) + Tipo de conversión usada para agregar @@ -1191,10 +1276,10 @@ - Tipo de conversión usada para agregar (promedio) + Metodología para llevar a cabo la conversión de variables - Tipo de conversión usada para agregar (promedio) + Metodología para llevar a cabo la conversión de variables @@ -1251,6 +1336,9 @@ 70 + + Selección de la variable del Nc sobre la cual se aplicará la conversión. + Selección de la variable del Nc sobre la cual se aplicará la conversión. @@ -1300,8 +1388,11 @@ 70 + + Nombre de la variable nueva calculada según la expresión + - Nombre de la variable que contiene la conversión + Nombre de la variable nueva calculada según la expresión @@ -1374,16 +1465,16 @@ - Ejecutar la función de trazado de corriente. + Evaluar la expresión definida. - Convertir variables. + Evaluar la expresión definida. - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1446,7 +1537,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -1481,7 +1572,7 @@ - + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -1564,7 +1655,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -1583,11 +1674,17 @@ 16777215 + + Eliminar variable de la tabla de variables de NC (Solo si no ha sido actualizada en el NC) + + + Eliminar variable de la tabla de variables de NC (Solo si no ha sido actualizada en el NC) + - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -1639,7 +1736,7 @@ 0 0 - 443 + 268 2018 @@ -1732,7 +1829,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -1846,7 +1943,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1863,7 +1960,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1935,11 +2032,17 @@ + + Seleccionar las coordenadas de la salida de la cuenca a trazar + + + Seleccionar las coordenadas de la salida de la cuenca a trazar + - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -2023,6 +2126,12 @@ + + Seleccionar umbral de área acumulada para estimar canales + + + Seleccionar umbral de área acumulada para estimar canales + 0 @@ -2118,11 +2227,17 @@ 16777215 + + Seleccionar la ruta para para guardar el .shp con la divisoria de aguas + + + Seleccionar la ruta para para guardar el .shp con la divisoria de aguas + - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2193,6 +2308,12 @@ + + Seleccionar la ruta para para guardar el .shp con la red hídrica + + + Seleccionar la ruta para para guardar el .shp con la red hídrica + false @@ -2216,7 +2337,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2241,6 +2362,12 @@ + + Seleccionar la ruta para guardar el .nc con el proyecto de cuenca + + + Seleccionar la ruta para guardar el .nc con el proyecto de cuenca + false @@ -2264,7 +2391,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2285,6 +2412,12 @@ + + Asignar un nombre a la cuenca trazada + + + Asignar un nombre a la cuenca trazada + Cuenca @@ -2312,7 +2445,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2371,7 +2504,7 @@ 0 0 - 443 + 318 1918 @@ -2503,10 +2636,10 @@ - Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + Calcula mapa raster con los canales - Calcula mapa raster con la distancia a la salida de cada celda (Dist2Out) + Calcula mapa raster con los canales Canales @@ -2540,7 +2673,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2576,7 +2709,7 @@ - + Calcular mapa de coeficiente de flujo sub-superficial (kubota, 1995), requiere: h1_max y v_coef[1] definidos en la tabla de Nc Calcular mapa de coeficiente de flujo sub-superficial (kubota, 1995), requiere: h1_max y v_coef[1] definidos en la tabla de Nc @@ -2589,7 +2722,7 @@ - + Calcular coeficiente y exp de escorrentía, requiere mapa Manning en WMF Calcular coeficiente y exp de escorrentía, requiere mapa Manning en WMF @@ -2850,7 +2983,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2962,7 +3095,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -2979,7 +3112,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3013,10 +3146,10 @@ - Ejecuta la interpolación para la cuenca con los parámetros dados. + Grafica de perfiles de elevación y distancia a la salida - Ejecuta la interpolación para la cuenca con los parámetros dados. + Grafica de perfiles de elevación y distancia a la salida Perfiles @@ -3041,10 +3174,10 @@ - Ejecuta la interpolación para la cuenca con los parámetros dados. + Visualizar gráfica de Tiempos de concentración - Ejecuta la interpolación para la cuenca con los parámetros dados. + Visualizar gráfica de Tiempos de concentración Tc @@ -3120,6 +3253,12 @@ + + Seleccionar umbral de área acumulada para estimar canales + + + Seleccionar umbral de área acumulada para estimar canales + 0 @@ -3194,7 +3333,7 @@ 0 0 - 443 + 318 1918 @@ -3317,7 +3456,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3343,7 +3482,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3495,7 +3634,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3521,7 +3660,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3581,7 +3720,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3676,17 +3815,30 @@ + + Establecer el archivo .shape con las coordenadas de las estaciones + + + Establecer el archivo .shape con las coordenadas de las estaciones + - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - + + + Seleccionar el campo dentro del shape que contiene los id de las estaciones + + + Seleccionar el campo dentro del shape que contiene los id de las estaciones + + @@ -3746,7 +3898,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3789,6 +3941,12 @@ 0 + + Exponente para la interpolación con IDW + + + Exponente para la interpolación con IDW + 2 @@ -3816,6 +3974,12 @@ + + Fecha inicial de la interpolación + + + Fecha inicial de la interpolación + 2015 @@ -3844,6 +4008,12 @@ + + Fecha final de la interpolación + + + Fecha final de la interpolación + 2015 @@ -3872,6 +4042,12 @@ + + Delta de tiempo para el campo que interpolado + + + Delta de tiempo para el campo que interpolado + 5.000000000000000 @@ -3925,8 +4101,11 @@ + + Ruta de guardado del binario de precipitación + - Ruta de guardado + Ruta de guardado del binario de precipitación false @@ -3935,6 +4114,9 @@ + + Establecer ruta de guardado del binario de lluvia. + Establecer ruta de guardado del binario de lluvia. @@ -3942,7 +4124,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3959,7 +4141,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3997,10 +4179,10 @@ - Ejecuta la interpolación para la cuenca con los parámetros dados. + Visualizar gráfica del ciclo anual de precipitación del campo interpolado. - Ejecuta la interpolación para la cuenca con los parámetros dados. + Visualizar gráfica del ciclo anual de precipitación del campo interpolado. Ciclo Anual @@ -4016,10 +4198,10 @@ - Ejecuta la interpolación para la cuenca con los parámetros dados. + Visualizar gráfica del histograma de precipitación del campo interpolado. - Ejecuta la interpolación para la cuenca con los parámetros dados. + Visualizar gráfica del histograma de precipitación del campo interpolado. Histograma @@ -4041,10 +4223,10 @@ - Ejecuta la interpolación para la cuenca con los parámetros dados. + Visualizar gráfica de la serie de precipitación media del campo interpolado. - Ejecuta la interpolación para la cuenca con los parámetros dados. + Visualizar gráfica de la serie de precipitación media del campo interpolado. Serie @@ -4129,14 +4311,17 @@ 16777215 + + Visualiza una entrada o acumulado del binario de lluvia interpolado. + - Visualiza una entrada del binario de lluvia interpolado. + Visualiza una entrada o acumulado del binario de lluvia interpolado. - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4412,7 +4597,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4438,7 +4623,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4498,7 +4683,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4638,7 +4823,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4782,7 +4967,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4799,7 +4984,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4976,7 +5161,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5000,9 +5185,9 @@ 10 - 10 + -10 451 - 721 + 581 @@ -5027,8 +5212,8 @@ 0 - 0 - 433 + -248 + 436 1918 @@ -5114,8 +5299,11 @@ 16777215 + + Ruta del binario de precipitación + - Ruta a la serie de caudales obsevada + Ruta del binario de precipitación false @@ -5137,16 +5325,16 @@ - Seleccionar la ruta donde se va a guardar la corriente. + Seleccionar la ruta del binario de precipitación - Seleccionar la ruta donde se va a guardar la corriente. + Seleccionar la ruta del binario de precipitación - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -5166,16 +5354,16 @@ - Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + Visualizar la serie de precipitación media del binario de precipitación cargado - Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + Visualizar la serie de precipitación media del binario de precipitación cargadoVisualizar la serie de precipitación media del binario de precipitación cargado - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5231,6 +5419,9 @@ 16777215 + + Ruta a la serie de caudales obsevada + Ruta a la serie de caudales obsevada @@ -5254,22 +5445,29 @@ - Seleccionar la ruta donde se va a guardar la corriente. + Seleccionar la ruta del Excel con el caudal observado - Seleccionar la ruta donde se va a guardar la corriente. + Seleccionar la ruta del Excel con el caudal observado - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - + + + Seleccionar el ID de la estaciónde caudal a utilizar + + + Seleccionar el ID de la estaciónde caudal sólido a utilizar + + @@ -5286,16 +5484,16 @@ - Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + Visualizar la serie de caudales líquidos seleccionada - Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + Visualizar la serie de caudales líquidos seleccionada - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5338,8 +5536,11 @@ 16777215 + + Ruta a la serie de caudales sólidos obsevada + - Ruta a la serie de caudales obsevada + Ruta a la serie de caudales sólidos obsevada false @@ -5361,22 +5562,29 @@ - Seleccionar la ruta donde se va a guardar la corriente. + Seleccionar la ruta del Excel con el caudal sólido observado - Seleccionar la ruta donde se va a guardar la corriente. + Seleccionar la ruta del Excel con el caudal sólido observado - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - + + + Seleccionar el ID de la estación a utilizar + + + Seleccionar el ID de la estación a utilizar + + @@ -5393,16 +5601,16 @@ - Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + Visualizar la serie de caudales sólidos seleccionada - Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) + Visualizar la serie de caudales sólidos seleccionada - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5442,7 +5650,7 @@ 0 70 - 401 + 412 582 @@ -5514,7 +5722,7 @@ Velocidad horizontal sub-superficial (h_coef[1]) - Vh2 [m/s] + Vh2 [mm/s] @@ -5534,7 +5742,7 @@ Velocidad horizontal subterranea (h_coef[2]) - Vh3 [m/s] + Vh3 [mm/s] @@ -5544,7 +5752,7 @@ Velocidad horizontal escorrentia (h_coef[0]) - Vh1 [m/s] + Vh1 [mm/s] @@ -5574,7 +5782,7 @@ Velocidad horizontal canales (h_coef[3]) - Vh4 [m/s] + Vh4 [mm/s] @@ -5670,6 +5878,12 @@ + + Parametro de calibración para la simulación de sedimentos + + + Parametro de calibración para la simulación de sedimentos + Sed Param @@ -5677,6 +5891,9 @@ + + 3 + 1.000000000000000 @@ -5694,6 +5911,9 @@ + + 3 + 1.000000000000000 @@ -5701,6 +5921,9 @@ + + 3 + 1.000000000000000 @@ -5708,6 +5931,9 @@ + + 3 + 1.000000000000000 @@ -5715,6 +5941,9 @@ + + 3 + 1.000000000000000 @@ -5722,6 +5951,9 @@ + + 3 + 1.000000000000000 @@ -5729,6 +5961,9 @@ + + 3 + 1.000000000000000 @@ -5736,20 +5971,9 @@ - - 1.000000000000000 - - - - - - - 1.000000000000000 + + 3 - - - - 1.000000000000000 @@ -5766,6 +5990,9 @@ QAbstractSpinBox::NoButtons + + 2 + 99999.000000000000000 @@ -5774,20 +6001,20 @@ - - - - 1.000000000000000 + + + + 3 + + + 1.000000000000000 - - - - Exponente regional en caso de usar aproximación no lineal v = C A^e - - - Exponente aproximación no lineal al flujo en canales + + + + 3 1.000000000000000 @@ -5805,6 +6032,9 @@ QAbstractSpinBox::NoButtons + + 2 + 99999.000000000000000 @@ -5813,27 +6043,31 @@ - - - - true + + + + 3 - - true + + 1.000000000000000 - - QAbstractSpinBox::NoButtons + + + + + + Exponente regional en caso de usar aproximación no lineal v = C A^e - - -1.000000000000000 + + Exponente aproximación no lineal al flujo en canales 1.000000000000000 - - + + true @@ -5843,19 +6077,19 @@ QAbstractSpinBox::NoButtons - - -99999.000000000000000 + + 5 - - 99999.000000000000000 + + -1.000000000000000 1.000000000000000 - - + + true @@ -5866,15 +6100,15 @@ QAbstractSpinBox::NoButtons - 6 + 5 1.000000000000000 - - + + true @@ -5884,13 +6118,16 @@ QAbstractSpinBox::NoButtons + + 5 + 1.000000000000000 - - + + true @@ -5900,13 +6137,16 @@ QAbstractSpinBox::NoButtons + + 5 + 1.000000000000000 - - + + true @@ -5916,6 +6156,9 @@ QAbstractSpinBox::NoButtons + + 5 + 1.000000000000000 @@ -5932,6 +6175,9 @@ QAbstractSpinBox::NoButtons + + 5 + 1.000000000000000 @@ -5948,6 +6194,9 @@ QAbstractSpinBox::NoButtons + + 5 + 1.000000000000000 @@ -5964,13 +6213,16 @@ QAbstractSpinBox::NoButtons + + 2 + 1.000000000000000 - - + + true @@ -5985,8 +6237,8 @@ - - + + true @@ -5996,13 +6248,16 @@ QAbstractSpinBox::NoButtons + + 2 + 1.000000000000000 - - + + true @@ -6012,13 +6267,16 @@ QAbstractSpinBox::NoButtons + + 2 + 1.000000000000000 - - + + true @@ -6028,6 +6286,9 @@ QAbstractSpinBox::NoButtons + + 2 + 1.000000000000000 @@ -6062,6 +6323,31 @@ + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 5 + + + -99999.000000000000000 + + + 99999.000000000000000 + + + 1.000000000000000 + + + @@ -6086,7 +6372,14 @@ - + + + Seleccionar una de las calibraciones que se tienen guardadas en el nc + + + Seleccionar una de las calibraciones que se tienen guardadas en el nc + + @@ -6113,6 +6406,15 @@ + + Definir el nombre de la parametrización actual + + + + + + Definir el nombre de la parametrización actual. + false @@ -6120,47 +6422,33 @@ + + Guarda o actualiza la parametrización actual en el nc + + + Guarda o actualiza la parametrización actual en el nc + - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg - - - - Establecer - - - - - - - 0 - 1430 - 411 - 20 - - - - Qt::Horizontal - - 0 - 870 + 880 401 - 301 + 901 @@ -6172,21 +6460,30 @@ 0 30 401 - 241 + 201 - + + + 0 + - Fecha Inicio + Fecha Inicio Simulación - + + + Seleccionar la fecha de inicio para correr la simulación + + + Seleccionar la fecha de inicio para correr la simulación + 2015 @@ -6209,12 +6506,18 @@ - Fecha inicio interpolación + Fecha Fin Simulación - + + + Seleccionar la fecha final de la simulación + + + Seleccionar la fecha final de la simulación + 2015 @@ -6234,66 +6537,560 @@ - - + + + + + 210 + 16777215 + + + + Configura para que se guarden las condiciones finales de la simulación para ejecutar la próxima corrida + + + Configura para que se guarden las condiciones finales de la simulación para ejecutar la próxima corrida + - Separacion + Guardar Almacenamientos + + + + 8 + 16 + - + + + + 120 + 16777215 + + + + Configura que la simulación entrege las salidas de caudal como Runoff, Superficial y Subterráneo + + + Exportar los indicadores básicos de desempeño de la simulación a Excel + - Retrono + Separacion + + + + 8 + 16 + - - + + + + Activa la simulación de Sedimentos en el modelo + + + Activa la simulación de Sedimentos en el modelo + Sedimentos - - + + + + Activa la simulación de Deslizamientos en el modelo + Deslizamientos - - - - - - + + + + Activa el retorno desde el tanque subsuperficial + + + Activa el retorno desde el tanque subsuperficial + - Figuras: + Retorno - - - + + + + + + 160 + 16777215 + + + + Ejecutar la simulación + + + Qt::LeftToRight + - Almacenamientos + Ejecutar Simulación + + + + + + + + 0 + 230 + 411 + 20 + + + + Qt::Horizontal + + + + + + 0 + 250 + 401 + 641 + + + + Resultados + + + + + 0 + 30 + 401 + 193 + + + + + 0 + + + + + + + + 16777215 + 20 + + + + Figuras: + + + + + + + + + + + + + + 118 + 16777215 + + + + Caudal Sólido + + + + 8 + 16 + + + + + + + + + 130 + 0 + + + + + 130 + 16777215 + + + + Graficar las series de caudales + + + Graficar las series de caudales + + + Series de Cadual + + + + 11 + 11 + + + + + + + + + 80 + 0 + + + + + 120 + 16777215 + + + + Graficar el ciclo anual de caudales + + + Graficar el ciclo anual de caudales + + + Ciclo Anual + + + + 11 + 11 + + + + + + + + + 110 + 0 + + + + + 20 + 16777215 + + + + Graficar las curvas de duración de Caudales + + + Graficar las curvas de duración de Caudales + + + CDC + + + + 11 + 11 + + + + + + + + + 130 + 0 + + + + + 130 + 16777215 + + + + Graficar la serie de almacenamientos en los tanques + + + Graficar la serie de almacenamientos en los tanques + + + Almacenamientos + + + + 11 + 11 + + + + + + + + + 130 + 16777215 + + + + Caudal Líquido + + + + 8 + 16 + + + + + + + + + + + + + + + + + 0 + 22 + + + + + 110 + 30 + + + + Exportar Series: + + + + + + + false + + + + 0 + 15 + + + + + 50 + 25 + + + + Exportar series de caudales a Excel + + + Exportar series de caudales a Excel + + + + + + + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png + + + + + + + + + + 0 + 10 + + + + Qt::Horizontal + + + + + + + + + + + 0 + 230 + 411 + 271 + + + + Calcula los indicadores básicos de desempeño de la simulación + + + Calcula los indicadores básicos de desempeño de la simulación + + + Indicadores de Desempeño + + + + + 0 + 330 + 411 + 21 + + + + Qt::Horizontal + + + + + + 10 + 30 + 391 + 181 + + + - - - + + + true + + + true + + + true + + 120 + + + 10 + + + 20 + + + 10 + + + true + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Exportar los indicadores básicos de desempeño de la simulación a Excel + + + Exportar los indicadores básicos de desempeño de la simulación a Excel + + + + + + + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png + + + + + + + Calcula los indicadores básicos de desempeño de la simulación + + + Calcula los indicadores básicos de desempeño de la simulación + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + - - + + + + + 200 + 270 + 411 + 21 + + + + Qt::Horizontal + + + @@ -6309,6 +7106,19 @@ Qt::Horizontal + + + + 0 + 860 + 401 + 20 + + + + Qt::Horizontal + + @@ -6318,28 +7128,11 @@ - - - - QFrame::Raised - - - 4 - - - 2 - - - Qt::Horizontal - - - - - + From 6472caa588a52abad0e25804a3eba0e575211526 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 29 Aug 2018 09:00:08 -0500 Subject: [PATCH 126/142] ya ejecuta simulaciones, se esta haciendo el set para mostrar de forma adecuada los resultados --- qgisplugin/HydroSEDPluginUtils.py | 42 +- qgisplugin/HydroSEDPlugin_dockwidget.py | 91 +- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 1333 +++++++++++------- 3 files changed, 951 insertions(+), 515 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 82716fc..0f3d5e2 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -503,6 +503,7 @@ def Basin_GeoGetOCG(self): Area = self.cuenca.CellAcum*wmf.cu.dxp**2/1e6 #Obtiene el coeficiente Coef, Expo = wmf.OCG_param(pend=self.cuenca.CellSlope, area=Area) + Expo = np.ones(self.cuenca.ncells)*Expo #Agrea los resultados al diccionario self.DicBasinWMF.update({'OCG_coef': {'nombre':'OCG_coef', @@ -515,8 +516,8 @@ def Basin_GeoGetOCG(self): 'saved':False}}) self.DicBasinWMF.update({'OCG_exp': {'nombre':'OCG_exp', - 'tipo':Coef.dtype.name, - 'shape':Coef.shape, + 'tipo':Expo.dtype.name, + 'shape':Expo.shape, 'raster':True, 'basica': False, 'categoria': 'Geomorfo', @@ -554,6 +555,16 @@ def Basin_GeoGetKubota(self): 'categoria': 'Geomorfo', 'var': np.copy(Coef), 'saved': False}}) + KubotaExpo = np.ones(self.cuenca.ncells)*2 + self.DicBasinWMF.update({'Kubota_exp': + {'nombre':'Kubota_exp', + 'tipo':KubotaExpo.dtype.name, + 'shape':KubotaExpo.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Geomorfo', + 'var': np.copy(KubotaExpo), + 'saved': False}}) def Basin_GeoGetRunoff(self, e1, Epsilon): '''Obtiene el coeficiente de escorrentia para carcavas''' @@ -899,3 +910,30 @@ def Radar_Conver2Basin(self, PathRadarBasin, TimeStep, umbral = 0.01, #Cierra el binario y cea el encabezado self.cuenca.rain_radar2basin_from_array(status = 'close',ruta_out = PathRadarBasin) self.cuenca.rain_radar2basin_from_array(status = 'reset') + + + def Sim_Basin(self, Start, Nsteps, Calibracion, PathRain, DeltaT, exponentes): + '''Hace la simulacion hidrologica de la cuenca''' + #Set de calibracion + wmf.models.sed_factor = Calibracion[-1] + Calibracion = Calibracion[:-1] + #Set del intervalo de tiempo de simulacion + wmf.models.dt = DeltaT + #SEtea el tipo de velocidad de acuerdo a los exponentes + for c,i in enumerate(exponentes): + if i<>1: + wmf.models.speed_type[c] = 2 + else: + wmf.models.speed_type[c] = 1 + #Simulacion de la cuenca + Results, Qsim = self.cuenca.run_shia(Calibracion, + PathRain, + Nsteps, + Start) + #Obtiene resultados como cosas genericas + self.Sim_index = Qsim.index + self.Sim_Streamflow = Qsim.copy() + self.Sim_Rainfall = pd.Series(Results['Rain_hietogram'][0], index = self.Sim_index) + self.Sim_Balance = pd.Series(Results['Balance'][0], index = self.Sim_index) + self.Sim_Storage = Results['Storage'] + self.Sim_RainfallField = np.copy(Results['Rain_Acum']) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 883dbca..ed667bc 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -399,15 +399,15 @@ def clickEventGeoRasterProp(): ListaVar.extend(['Channels']) if self.checkBoxOCG.isChecked(): self.HSutils.Basin_GeoGetOCG() - ListaVar.extend(['OCG_coef']) + ListaVar.extend(['OCG_coef','OCG_exp']) if self.checkBoxKubota.isChecked(): - self.HSutils.Basin_GeoGetKubota() - ListaVar.extend(['Kubota_coef']) + self.HSutils.Basin_GeoGetKubota() + ListaVar.extend(['Kubota_coef','Kubota_exp']) #mensajes de advertencia por si no han sido cargadas las variables. if 'h1_max' not in self.HSutils.DicBasinNc.keys(): self.iface.messageBar().pushMessage (u'Hydro-SIG:', 'Como no se ha cargado h1_max al NC, se estima con h1_max = 100 mm ', - level=QgsMessageBar.WARNING, duration=5) + level=QgsMessageBar.WARNING, duration=3) if 'v_coef' not in self.HSutils.DicBasinNc.keys(): self.iface.messageBar().pushMessage (u'Hydro-SIG:', 'Como no se ha cargado Ks al NC, se estima con Ks = 0.003 mm/s ', @@ -839,7 +839,7 @@ def clickEventSelectorRadarFiles(): self.FechasRadar = [] for L in self.ListaRadarDates: try: - self.FechasRadar.append(dt.datetime.strptime(L[-23:-11],'%Y%m%d%H%M')) + self.FechasRadar.append(dt.datetime.strptime(L[-23:-11],'%Y%m%d%H%M')) except: pass #print len(self.ListaRadarDates) @@ -1028,17 +1028,17 @@ def changeEventUpdateScalarParameters(): for c,values in enumerate(self.HSutils.DicParameters[key]['var'][:11]): codigo = 'self.Param'+str(c+1)+'.setValue('+str(values)+')' eval(codigo) - for c,values in enumerate(self.HSutils.DicParameters[key]['var'][11:]): - codigo = 'self.ParamExp'+str(c+1)+'.setValue('+str(values)+')' - eval(codigo) + #for c,values in enumerate(self.HSutils.DicParameters[key]['var'][11:]): + # codigo = 'self.ParamExp'+str(c+1)+'.setValue('+str(values)+')' + # eval(codigo) def clickEventUpdateParamMapValues(): '''Muestra en los campos de simulacion el valor medio de los mapas de simulacion''' VarNames = ['h1_max','h3_max', 'v_coef','v_coef','v_coef','v_coef','h_coef', 'h_coef','h_coef','h_coef', 'Krus','Crus','Prus', - 'PArLiAc','PArLiAc','PArLiAc'] - Ejes = [0,0,0,1,2,3,0,1,2,3,0,0,0,0,1,2] - for name, i, eje in zip(VarNames, range(1,17), Ejes): + 'PArLiAc','PArLiAc','PArLiAc','h_exp','h_exp','h_exp','h_exp'] + Ejes = [0,0,0,1,2,3,0,1,2,3,0,0,0,0,1,2,0,1,2,3] + for name, i, eje in zip(VarNames, range(1,21), Ejes): Campo = getattr(self, 'ParamVal'+str(i)) Campo.setMinimum(-99999) Campo.setValue(0) @@ -1103,6 +1103,14 @@ def clickEventSelectorArchivoBinarioSimulacion(): '''Evento de click: selecciona el archivo binario con la precipitacion para correr el modelo''' #Busca el archivo setupLineEditButtonOpenBinFileDialog (self.PathinSimu_Precipitacion,QFileDialog) + #Obtiene el Dt de modelacion a partir de la lluvia + PathRBin, PathRHdr = HSutils.wmf.__Add_hdr_bin_2route__(self.PathinSimu_Precipitacion.text().strip()) + RainStruct = HSutils.wmf.read_rain_struct(PathRHdr) + #Obtiene el Dt + Dt = RainStruct.index[1] - RainStruct.index[0] + Texto = '%d' % Dt.seconds + self.DtShowFrame.setText(Texto) + #SEt para la figura de lluvia try: PathData = self.PathinSimu_Precipitacion.text().strip() self.HSplots = HSplots.PlotRainfall(PathData) @@ -1163,6 +1171,65 @@ def clickEventViewSerieQobsSed(): self.VistaQobsWeb.setMaximumHeight(400) self.VistaQobsWeb.show() + def __ParseCalibValues__(): + '''Obtiene una lista de los param de calibracion a partir de los elem que estan en al interfaz''' + Calibracion = [] + for i in range(1,12): + Calibracion.append(getattr(self, 'Param'+str(i)).value()) + return Calibracion + + def __Dates2Start_Nsteps__(fi,ff,PathRain): + '''A partir de la fecha inicio y fin obtien el paso de inicio y la cantidad de pasos''' + #Obtiene el path para header y para el binario, lee la estructura de la lluvia + PathRBin, PathRHdr = HSutils.wmf.__Add_hdr_bin_2route__(PathRain) + RainStruct = HSutils.wmf.read_rain_struct(PathRHdr) + #Obtiene el Dt + Dt = RainStruct.index[1] - RainStruct.index[0] + Dt = Dt.seconds + #Obtiene punto de inicio + Start = RainStruct.index.get_loc(fi.strftime('%Y-%m-%d %H:%M')) + End = RainStruct.index.get_loc(ff.strftime('%Y-%m-%d %H:%M')) + Nsteps = End - Start + #Retorna + return Start, Nsteps, PathRBin, Dt + + def clickEventSimulationDeCuenca(): + '''Hace la simulacion hidrologica con el set de param seleccionados y los mapas propios de la cuenca''' + #Obtiene lo que se necesita para ejecutar + PathRain = self.PathinSimu_Precipitacion.text().strip() + Calib = __ParseCalibValues__() + #Obtiene pubnto de inicio y cantidad de pasos + Fi = self.Simulacion_DateTimeStart.dateTime().toPyDateTime() + Ff = self.Simulacion_DateTimeEnd.dateTime().toPyDateTime() + Inicio, Npasos, PathBin, TimeDelta = __Dates2Start_Nsteps__(Fi,Ff,PathRain) + #Exponenetes de funciones lineales o no lineales + Exponenetes = [] + for i in [17,18,19]: + Campo = getattr(self, 'ParamVal'+str(i)) + Exponenetes.append(Campo) + #Simulacion hidrologica + self.HSutils.Sim_Basin(Inicio, Npasos, Calib, PathBin, TimeDelta, Exponenetes) + #Pone estados de almacenamiento finales en el NC + self.HSutils.DicBasinNc['storage']['var'] = np.copy(self.HSutils.Sim_Storage) + self.HSutils.DicBasinNc['storage']['saved'] = False + self.TabNC.EditedEntry('storage', self.Tabla_Prop_NC) + #Pone el campo acumulado de lluvia usado en el WMF + self.HSutils.DicBasinWMF.update({'Sim_Rain': + {'nombre':'Sim_Rain', + 'tipo':self.HSutils.Sim_RainfallField.dtype.name, + 'shape':self.HSutils.Sim_RainfallField.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Hidro', + 'var': np.copy(self.HSutils.Sim_RainfallField), + 'saved':False}}) + self.TabWMF.NewEntry(self.HSutils.DicBasinWMF['Sim_Rain'], + 'Sim_Rain', self.Tabla_Prop_WMF) + #Mensaje de exito + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + u'El modelo se ha ejecutado con exito', + level=QgsMessageBar.INFO, duration=3) + self.ButtonSimCalib2Nc.clicked.connect(clickEventAddNewParamSet) self.tabPanelDockOpciones.currentChanged.connect(clickEventUpdateParamMapValues) self.ParamNamesCombo.currentIndexChanged.connect(changeEventUpdateScalarParameters) @@ -1174,6 +1241,8 @@ def clickEventViewSerieQobsSed(): self.Boton_Visualizar_Binario.clicked.connect(clickEventViewSerieSimuRainfall) self.Boton_Visualizar_Qobs.clicked.connect(clickEventViewSerieQobs) self.Boton_Visualizar_Qobs_Sed.clicked.connect(clickEventViewSerieQobsSed) + + self.ButtonSim_RunSimulacion.clicked.connect(clickEventSimulationDeCuenca) def setupUIInputsOutputs (self): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 178a927..ae5102d 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -68,7 +68,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -238,7 +238,7 @@ 0 - 150 + 130 469 776 @@ -254,7 +254,7 @@ - + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png @@ -295,7 +295,7 @@ 0 0 - 318 + 443 2018 @@ -452,7 +452,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -572,7 +572,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -815,7 +815,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -891,7 +891,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1008,7 +1008,7 @@ - + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -1043,7 +1043,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -1072,7 +1072,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -1150,7 +1150,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png:/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png @@ -1179,7 +1179,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png:/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png @@ -1474,7 +1474,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1537,7 +1537,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -1572,7 +1572,7 @@ - + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -1655,7 +1655,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -1684,7 +1684,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -1736,7 +1736,7 @@ 0 0 - 268 + 443 2018 @@ -1829,7 +1829,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -1943,7 +1943,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1960,7 +1960,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2042,7 +2042,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -2237,7 +2237,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2337,7 +2337,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2391,7 +2391,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2445,7 +2445,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2504,7 +2504,7 @@ 0 0 - 318 + 443 1918 @@ -2673,7 +2673,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2983,7 +2983,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3095,7 +3095,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -3112,7 +3112,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3333,7 +3333,7 @@ 0 0 - 318 + 443 1918 @@ -3456,7 +3456,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3482,7 +3482,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3634,7 +3634,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3660,7 +3660,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3720,7 +3720,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3825,7 +3825,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3898,7 +3898,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4124,7 +4124,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4141,7 +4141,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4321,7 +4321,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4597,7 +4597,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4623,7 +4623,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4683,7 +4683,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4823,7 +4823,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4967,7 +4967,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4984,7 +4984,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -5161,7 +5161,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5187,7 +5187,7 @@ 10 -10 451 - 581 + 741 @@ -5212,8 +5212,8 @@ 0 - -248 - 436 + -847 + 433 1918 @@ -5334,7 +5334,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -5363,7 +5363,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5454,7 +5454,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -5493,7 +5493,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5571,7 +5571,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -5610,7 +5610,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5656,7 +5656,7 @@ - + 4 @@ -5700,22 +5700,6 @@ - - - - Exponente regional en caso de usar aproximación no lineal v = C A^e - - - Exponente aproximación no lineal al flujo superficial - - - 99999.000000000000000 - - - 1.000000000000000 - - - @@ -5726,16 +5710,6 @@ - - - - Exponente aproximacion potencial (dejar en 1 para ecuaciones lineales) - - - Expo - - - @@ -5786,19 +5760,6 @@ - - - - Exponente regional en caso de usar aproximación no lineal v = C A^e - - - Exponente aproximación no lineal al flujo subterráneo - - - 1.000000000000000 - - - @@ -5822,7 +5783,7 @@ - Nombre variable + Nombre @@ -5949,16 +5910,6 @@ - - - - 3 - - - 1.000000000000000 - - - @@ -5969,8 +5920,8 @@ - - + + 3 @@ -6001,6 +5952,16 @@ + + + + 3 + + + 1.000000000000000 + + + @@ -6053,41 +6014,6 @@ - - - - Exponente regional en caso de usar aproximación no lineal v = C A^e - - - Exponente aproximación no lineal al flujo en canales - - - 1.000000000000000 - - - - - - - true - - - true - - - QAbstractSpinBox::NoButtons - - - 5 - - - -1.000000000000000 - - - 1.000000000000000 - - - @@ -6126,27 +6052,8 @@ - - - - true - - - true - - - QAbstractSpinBox::NoButtons - - - 5 - - - 1.000000000000000 - - - - - + + true @@ -6159,32 +6066,16 @@ 5 - - 1.000000000000000 - - - - - - - true - - - true - - - QAbstractSpinBox::NoButtons - - - 5 + + -1.000000000000000 1.000000000000000 - - + + true @@ -6195,7 +6086,7 @@ QAbstractSpinBox::NoButtons - 5 + 2 1.000000000000000 @@ -6221,24 +6112,8 @@ - - - - true - - - true - - - QAbstractSpinBox::NoButtons - - - 1.000000000000000 - - - - - + + true @@ -6256,8 +6131,8 @@ - - + + true @@ -6267,9 +6142,6 @@ QAbstractSpinBox::NoButtons - - 2 - 1.000000000000000 @@ -6310,19 +6182,6 @@ - - - - Exponente regional en caso de usar aproximación no lineal v = C A^e - - - Exponente aproximación no lineal al flujo sub-superficial - - - 1.000000000000000 - - - @@ -6348,32 +6207,200 @@ - - - - - - - - 0 - 30 - 401 - 41 - - - - - - - - - Seleccionar calibración anterior - - + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 5 + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 5 + + + 1.000000000000000 + + + + - - - + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 5 + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 5 + + + 1.000000000000000 + + + + + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 5 + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 5 + + + 1.000000000000000 + + + + + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 5 + + + 1.000000000000000 + + + + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 5 + + + 1.000000000000000 + + + + + + + + + + + + + 0 + 30 + 401 + 41 + + + + + + + + + Seleccionar calibración anterior + + + + + + Seleccionar una de las calibraciones que se tienen guardadas en el nc @@ -6432,7 +6459,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -6537,22 +6564,22 @@ - - + + - 210 + 120 16777215 - Configura para que se guarden las condiciones finales de la simulación para ejecutar la próxima corrida + Configura que la simulación entrege las salidas de caudal como Runoff, Superficial y Subterráneo - Configura para que se guarden las condiciones finales de la simulación para ejecutar la próxima corrida + Exportar los indicadores básicos de desempeño de la simulación a Excel - Guardar Almacenamientos + Separacion @@ -6562,22 +6589,22 @@ - - + + - 120 + 210 16777215 - Configura que la simulación entrege las salidas de caudal como Runoff, Superficial y Subterráneo + Configura para que se guarden las condiciones finales de la simulación para ejecutar la próxima corrida - Exportar los indicadores básicos de desempeño de la simulación a Excel + Configura para que se guarden las condiciones finales de la simulación para ejecutar la próxima corrida - Separacion + Velocidad media @@ -6587,7 +6614,20 @@ - + + + + Activa el retorno desde el tanque subsuperficial + + + Activa el retorno desde el tanque subsuperficial + + + Retorno + + + + Activa la simulación de Sedimentos en el modelo @@ -6600,26 +6640,38 @@ - - + + + + + 210 + 16777215 + + - Activa la simulación de Deslizamientos en el modelo + Configura para que se guarden las condiciones finales de la simulación para ejecutar la próxima corrida + + + Configura para que se guarden las condiciones finales de la simulación para ejecutar la próxima corrida - Deslizamientos + Guardar Almacenamientos + + + + 8 + 16 + - + - Activa el retorno desde el tanque subsuperficial - - - Activa el retorno desde el tanque subsuperficial + Activa la simulación de Deslizamientos en el modelo - Retorno + Deslizamientos @@ -6627,7 +6679,7 @@ - + @@ -6646,30 +6698,48 @@ + + + + + + Dt[seg] + + + + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + - - - - 0 - 230 - 411 - 20 - - - - Qt::Horizontal - - 0 - 250 + 240 401 - 641 + 281 @@ -6681,10 +6751,10 @@ 0 30 401 - 193 + 221 - + 0 @@ -6709,26 +6779,13 @@ - - - - - 118 - 16777215 - - - - Caudal Sólido - - - - 8 - 16 - - - - + + + + + + @@ -6759,28 +6816,28 @@ - - + + - 80 + 130 0 - 120 + 130 16777215 - Graficar el ciclo anual de caudales + Graficar las series de caudales - Graficar el ciclo anual de caudales + Graficar las series de caudales - Ciclo Anual + Curva duración @@ -6790,38 +6847,151 @@ - - - - - 110 - 0 - - + + - 20 + 118 16777215 - - Graficar las curvas de duración de Caudales - - - Graficar las curvas de duración de Caudales - - CDC + Observado - 11 - 11 - + 8 + 16 + - + + + + + + + + 118 + 16777215 + + + + Observado + + + + 8 + 16 + + + + + + + + + 130 + 0 + + + + + 130 + 16777215 + + + + Graficar las series de caudales + + + Graficar las series de caudales + + + Serie sedimentos + + + + 11 + 11 + + + + + + + + + 118 + 16777215 + + + + Observado + + + + 8 + 16 + + + + + + + + + + + + 118 + 16777215 + + + + Observado + + + + 8 + 16 + + + + + + + + + 130 + 0 + + + + + 130 + 16777215 + + + + Graficar las series de caudales + + + Graficar las series de caudales + + + Ciclo anual + + + + 11 + 11 + + + + + @@ -6852,54 +7022,135 @@ - - + + + + + 130 + 0 + + 130 16777215 + + Graficar la serie de almacenamientos en los tanques + + + Graficar la serie de almacenamientos en los tanques + - Caudal Líquido + Velocidad media - 8 - 16 + 11 + 11 - - - - - - - - - - + + + + false + 0 - 22 + 15 - 110 - 30 + 50 + 25 + + Exportar series de caudales a Excel + + + Exportar series de caudales a Excel + - Exportar Series: + + + + + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png - - + + + + false + + + + 0 + 15 + + + + + 50 + 25 + + + + Exportar series de caudales a Excel + + + Exportar series de caudales a Excel + + + + + + + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png + + + + + + + false + + + + 0 + 15 + + + + + 50 + 25 + + + + Exportar series de caudales a Excel + + + Exportar series de caudales a Excel + + + + + + + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png + + + + + false @@ -6925,23 +7176,216 @@ - + + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png + + + + + + + false + + + + 0 + 15 + + + + + 50 + 25 + + + + Exportar series de caudales a Excel + + + Exportar series de caudales a Excel + + + + + + + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png + + + + + + + false + + + + 0 + 15 + + + + + 50 + 25 + + + + Exportar series de caudales a Excel + + + Exportar series de caudales a Excel + + + + + + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png + + + + + + + + 0 + 260 + 411 + 20 + + + + Qt::Horizontal + + + + + + + 0 + 520 + 411 + 271 + + + + Calcula los indicadores básicos de desempeño de la simulación + + + Calcula los indicadores básicos de desempeño de la simulación + + + Indicadores de Desempeño + + + + + 0 + 330 + 411 + 21 + + + + Qt::Horizontal + + + + + + 10 + 30 + 391 + 181 + + + + + + + true + + + true + + + true + + + 120 + + + 10 + + + 20 + + + 10 + + + true + + + true + + + + + - - + + + Qt::Horizontal + + - 0 - 10 + 40 + 20 - - Qt::Horizontal + + + + + + false + + + Exportar los indicadores básicos de desempeño de la simulación a Excel + + + Exportar los indicadores básicos de desempeño de la simulación a Excel + + + + + + + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png + + + + + + + Calcula los indicadores básicos de desempeño de la simulación + + + Calcula los indicadores básicos de desempeño de la simulación + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -6949,149 +7393,33 @@ - + - 0 - 230 + 200 + 270 411 - 271 + 21 - - Calcula los indicadores básicos de desempeño de la simulación - - - Calcula los indicadores básicos de desempeño de la simulación + + Qt::Horizontal - - Indicadores de Desempeño - - - - - 0 - 330 - 411 - 21 - - - - Qt::Horizontal - - - - - - 10 - 30 - 391 - 181 - - - - - - - true - - - true - - - true - - - 120 - - - 10 - - - 20 - - - 10 - - - true - - - true - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - Exportar los indicadores básicos de desempeño de la simulación a Excel - - - Exportar los indicadores básicos de desempeño de la simulación a Excel - - - - - - - :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png - - - - - - - Calcula los indicadores básicos de desempeño de la simulación - - - Calcula los indicadores básicos de desempeño de la simulación - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - - - - - - - - - - 200 - 270 - 411 - 21 - - - - Qt::Horizontal - - + + + + 0 + 230 + 411 + 20 + + + + Qt::Horizontal + + @@ -7133,6 +7461,7 @@ - + + From b1901ae27a6b10d859f7387f42db795439c85d70 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 29 Aug 2018 09:44:40 -0500 Subject: [PATCH 127/142] simula y pasa las series al elemento de la cuenca --- qgisplugin/HydroSEDPluginUtils.py | 39 +++++++++-- qgisplugin/HydroSEDPlugin_dockwidget.py | 40 ++++++++--- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 74 ++++---------------- 3 files changed, 76 insertions(+), 77 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 0f3d5e2..3fb9f6f 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -926,10 +926,16 @@ def Sim_Basin(self, Start, Nsteps, Calibracion, PathRain, DeltaT, exponentes): else: wmf.models.speed_type[c] = 1 #Simulacion de la cuenca - Results, Qsim = self.cuenca.run_shia(Calibracion, - PathRain, - Nsteps, - Start) + if wmf.models.sim_sediments == 0: + Results, Qsim = self.cuenca.run_shia(Calibracion, + PathRain, + Nsteps, + Start) + elif wmf.models.sim_sediments == 1: + Results, Qsim, Qsed = self.cuenca.run_shia(Calibracion, + PathRain, + Nsteps, + Start) #Obtiene resultados como cosas genericas self.Sim_index = Qsim.index self.Sim_Streamflow = Qsim.copy() @@ -937,3 +943,28 @@ def Sim_Basin(self, Start, Nsteps, Calibracion, PathRain, DeltaT, exponentes): self.Sim_Balance = pd.Series(Results['Balance'][0], index = self.Sim_index) self.Sim_Storage = Results['Storage'] self.Sim_RainfallField = np.copy(Results['Rain_Acum']) + #Resultados opcionales + if wmf.models.show_storage == 1: + self.Sim_StorageSerie = pd.DataFrame(Results['Mean_Storage'].T, index = self.Sim_index) + print self.Sim_StorageSerie + if wmf.models.show_mean_speed == 1: + self.Sim_SpeedSerie = pd.DataFrame(Results['Mean_Speed'].T, index = self.Sim_index) + print self.Sim_SpeedSerie + if wmf.models.retorno == 1: + self.Sim_RetornoSerie = pd.DataFrame(wmf.models.mean_retorno, index = self.Sim_index) + self.Sim_RetornoMap = np.copy(wmf.models.retorned) + #Resultados de sedimentos + if wmf.models.sim_sediments == 1: + #Mapas de erosion y depositacion + self.Sim_ErosionMap = np.copy(wmf.models.volero) + self.Sim_DepositionMap = np.copy(wmf.models.voldepo) + #SErie de sedimentos simulada + self.Sim_Sediments = Qsed.copy() + + + + + + + + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index ed667bc..1329704 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -1193,6 +1193,20 @@ def __Dates2Start_Nsteps__(fi,ff,PathRain): #Retorna return Start, Nsteps, PathRBin, Dt + def __UpdateVar2WMFTable__(varName, varValue): + '''Agrega una variable a la tabla de WMF''' + self.HSutils.DicBasinWMF.update({varName: + {'nombre':varName, + 'tipo':varValue.dtype.name, + 'shape':varValue.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Hidro', + 'var': np.copy(varValue), + 'saved':False}}) + self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[varName], + varName, self.Tabla_Prop_WMF) + def clickEventSimulationDeCuenca(): '''Hace la simulacion hidrologica con el set de param seleccionados y los mapas propios de la cuenca''' #Obtiene lo que se necesita para ejecutar @@ -1207,6 +1221,16 @@ def clickEventSimulationDeCuenca(): for i in [17,18,19]: Campo = getattr(self, 'ParamVal'+str(i)) Exponenetes.append(Campo) + #Banderas de ejecucion + if self.checkBox_Simu_Sedimentos.isChecked(): + HSutils.wmf.models.sim_sediments = 1 + if self.checkBox_Simu_MeanSpeed.isChecked(): + HSutils.wmf.models.show_mean_speed = 1 + if self.checkBox_Simu_MeanStorage.isChecked(): + HSutils.wmf.models.show_mean_storage = 1 + if self.checkBox_Simu_Retorno.isChecked(): + HSutils.wmf.models.retorno = 1 + HSutils.wmf.models.show_mean_retorno = 1 #Simulacion hidrologica self.HSutils.Sim_Basin(Inicio, Npasos, Calib, PathBin, TimeDelta, Exponenetes) #Pone estados de almacenamiento finales en el NC @@ -1214,17 +1238,11 @@ def clickEventSimulationDeCuenca(): self.HSutils.DicBasinNc['storage']['saved'] = False self.TabNC.EditedEntry('storage', self.Tabla_Prop_NC) #Pone el campo acumulado de lluvia usado en el WMF - self.HSutils.DicBasinWMF.update({'Sim_Rain': - {'nombre':'Sim_Rain', - 'tipo':self.HSutils.Sim_RainfallField.dtype.name, - 'shape':self.HSutils.Sim_RainfallField.shape, - 'raster':True, - 'basica': False, - 'categoria': 'Hidro', - 'var': np.copy(self.HSutils.Sim_RainfallField), - 'saved':False}}) - self.TabWMF.NewEntry(self.HSutils.DicBasinWMF['Sim_Rain'], - 'Sim_Rain', self.Tabla_Prop_WMF) + __UpdateVar2WMFTable__('Sim_Rain',self.HSutils.Sim_RainfallField) + #Campos de erosion en caso de que este se simule + if self.checkBox_Simu_Sedimentos.isChecked(): + __UpdateVar2WMFTable__('Sim_Erosion',self.HSutils.Sim_ErosionMap) + __UpdateVar2WMFTable__('Sim_Deposit',self.HSutils.Sim_DepositionMap) #Mensaje de exito self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'El modelo se ha ejecutado con exito', diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index ae5102d..17be1a1 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -6564,33 +6564,8 @@ - - - - - 120 - 16777215 - - - - Configura que la simulación entrege las salidas de caudal como Runoff, Superficial y Subterráneo - - - Exportar los indicadores básicos de desempeño de la simulación a Excel - - - Separacion - - - - 8 - 16 - - - - - + 210 @@ -6614,19 +6589,6 @@ - - - - Activa el retorno desde el tanque subsuperficial - - - Activa el retorno desde el tanque subsuperficial - - - Retorno - - - @@ -6640,38 +6602,26 @@ - - - - - 210 - 16777215 - - + + - Configura para que se guarden las condiciones finales de la simulación para ejecutar la próxima corrida - - - Configura para que se guarden las condiciones finales de la simulación para ejecutar la próxima corrida + Activa la simulación de Deslizamientos en el modelo - Guardar Almacenamientos - - - - 8 - 16 - + Almacenamiento - - + + - Activa la simulación de Deslizamientos en el modelo + Activa el retorno desde el tanque subsuperficial + + + Activa el retorno desde el tanque subsuperficial - Deslizamientos + Retorno From eb6a5657df5b4948f43d58b9e4a0b87914ad5c29 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 29 Aug 2018 11:24:06 -0500 Subject: [PATCH 128/142] inclusion en la interfaz de cambios relacionados con el manejo de las variables de almacenamiento --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 926 ++++++++++++++++++- 1 file changed, 919 insertions(+), 7 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 17be1a1..a635ea7 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -5212,9 +5212,9 @@ 0 - -847 + -752 433 - 1918 + 2518 @@ -5235,7 +5235,7 @@ 0 - 1900 + 2500 @@ -5855,6 +5855,9 @@ 3 + + 9999999.000000000000000 + 1.000000000000000 @@ -6472,8 +6475,8 @@ - 0 - 880 + 10 + 1370 401 901 @@ -6579,7 +6582,7 @@ Configura para que se guarden las condiciones finales de la simulación para ejecutar la próxima corrida - Velocidad media + Guardar estados @@ -6608,7 +6611,7 @@ Activa la simulación de Deslizamientos en el modelo - Almacenamiento + Estados medios @@ -7397,6 +7400,915 @@ Qt::Horizontal + + + + 0 + 880 + 401 + 401 + + + + Estados de almacenamiento + + + + + 0 + 30 + 401 + 365 + + + + + + + + + + 100 + 16777215 + + + + Porcentaje de arenas (0-100) + + + VolSED depositados + + + + + + + Porcentaje de arenas (0-100) + + + Variable + + + + + + + Porcentaje de arenas (0-100) + + + S1, Capilar + + + + + + + Porcentaje de arenas (0-100) + + + S4, Subterráneo + + + + + + + Porcentaje de arenas (0-100) + + + S2, Escorrentía + + + + + + + Porcentaje de arenas (0-100) + + + S5, Canales + + + + + + + Porcentaje de arenas (0-100) + + + S3, Gravitacional + + + + + + + + 70 + 16777215 + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 2 + + + 1.000000000000000 + + + + + + + + 70 + 16777215 + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 2 + + + 1.000000000000000 + + + + + + + + 70 + 16777215 + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 2 + + + 1.000000000000000 + + + + + + + + 70 + 16777215 + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 2 + + + 1.000000000000000 + + + + + + + + 70 + 16777215 + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 2 + + + 1.000000000000000 + + + + + + + + 16777215 + 20 + + + + Porcentaje de arenas (0-100) + + + Valor [mm] + + + + + + + + + + 16777215 + 20 + + + + Porcentaje de arenas (0-100) + + + Valor + + + + + + + + 16777215 + 20 + + + + Porcentaje de arenas (0-100) + + + Archivo + + + + + + + + 16777215 + 20 + + + + Porcentaje de arenas (0-100) + + + Nc + + + + + + + + + + + + Qt::AlignJustify|Qt::AlignVCenter + + + false + + + false + + + + + 20 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + + + + 90 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + + + + 160 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + true + + + + + + + + + + + Qt::AlignJustify|Qt::AlignVCenter + + + false + + + false + + + + + 20 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + + + + 90 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + + + + 160 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + true + + + + + + + + + + + Qt::AlignJustify|Qt::AlignVCenter + + + false + + + false + + + + + 20 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + + + + 90 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + + + + 160 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + true + + + + + + + + + + + Qt::AlignJustify|Qt::AlignVCenter + + + false + + + false + + + + + 20 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + + + + 90 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + + + + 160 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + true + + + + + + + + + + + Qt::AlignJustify|Qt::AlignVCenter + + + false + + + false + + + + + 20 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + + + + 90 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + + + + 160 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + true + + + + + + + + + + + Qt::AlignJustify|Qt::AlignVCenter + + + false + + + false + + + + + 20 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + + + + 90 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + + + + 160 + 10 + 20 + 21 + + + + + 20 + 16777215 + + + + + + + true + + + + + + + + + 70 + 16777215 + + + + true + + + true + + + QAbstractSpinBox::NoButtons + + + 2 + + + 99999.000000000000000 + + + 1.000000000000000 + + + + + + + + + + + Archivo de estados + + + + + + + + 157 + 16777215 + + + + Definir el nombre de la parametrización actual + + + + + + Definir el nombre de la parametrización actual. + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + Fecha estados + + + + + + + Seleccionar la fecha de inicio para correr la simulación + + + Seleccionar la fecha de inicio para correr la simulación + + + + 2015 + 1 + 1 + + + + dd/MMM/yyyy HH:mm + + + true + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Establecer + + + + + + + + + + + + 20 + 1340 + 401 + 20 + + + + Qt::Horizontal + + From aa8b3ac0d68057edea671919d48a02ed76668628 Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Wed, 29 Aug 2018 11:25:48 -0500 Subject: [PATCH 129/142] Avances en plots simulacion --- qgisplugin/HydroSEDPlots.py | 77 +++++++++++++++++++++++++ qgisplugin/HydroSEDPluginUtils.py | 6 +- qgisplugin/HydroSEDPlugin_dockwidget.py | 49 +++++++++++++++- 3 files changed, 130 insertions(+), 2 deletions(-) diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py index c394614..af230c2 100644 --- a/qgisplugin/HydroSEDPlots.py +++ b/qgisplugin/HydroSEDPlots.py @@ -264,7 +264,84 @@ def Plot_Caudal(self, pathFigure,DataQ,id_est,colorline): fig = dict(data=data, layout=layout) #Guarda el html plot(fig,filename=pathFigure, auto_open = False) + + def Plot_Caudal_Simu(self,pathFigure,dfQobs,dfQsim): + + trace_high = go.Scatter( + x=dfQsim.index, + y=dfQsim.values, + name = "Q Simulado", + line = dict(color = 'red'), + opacity = 0.8) + + trace_low = go.Scatter( + x=dfQsim.index, + y=dfQobs.values, + name = "Q Observado", + line = dict(color = 'blue'), + opacity = 0.8) + + data = [trace_high,trace_low] + + layout = dict( + title = u"Series de caudal", + xaxis = dict( + title='Fechas', + range = [str(df.index[0]),str(df.index[-1])]), + yaxis=dict( + title="$Caudal [m^3/s]$") + + ) + + fig = dict(data=data, layout=layout) + #py.iplot(fig, filename = "Series") + #Guarda el html + plot(fig,filename=pathFigure, auto_open = False) + def Plot_CDC_caudal(self,pathFigure,dfQobs,dfQsim): + plt.close('all') + Qs=np.sort(np.array(dfQobs.values)) + Qo=np.sort(np.array(dfQobs.values)) + porcen_s=[] + porcen_o=[] + for i in range(len(Qo)): + porcen_s.append((len(Qs[Qs>Qs[i]]))/float(len(Qo))*100) + porcen_o.append((len(Qo[Qo>Qo[i]]))/float(len(Qo[np.isfinite(Qo)]))*100) + + trace_high = go.Scatter( + x=porcen_s, + y=Qs, + name = "Q simulado", + line = dict(color = 'red'), + opacity = 0.8) + + trace_low = go.Scatter( + x=porcen_o, + y=Qo, + name = "Q observado", + line = dict(color = 'blue'), + opacity = 0.8) + + data = [trace_high,trace_low] + + layout = dict( + width=670, + height=500, + title = "Curvas de duración de Caudal", + xaxis = dict( + title='Porcentaje de Excedencia', + range = [str(df.index[0]),str(df.index[-1])]), + yaxis=dict( + title='$Caudal [m^3/s]$') + + ) + + + fig = dict(data=data, layout=layout) + py.iplot(fig, filename = "Hidrografa") + #Guarda el html + plot(fig,filename=pathFigure, auto_open = False) + class PlotGeomorphology(): diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 3fb9f6f..0c13356 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -722,11 +722,13 @@ def Interpol_GetRainfallAcum(self, path2bin, inicio, fin): def Sim_GetQobsInfo(self,PathExcelQobs): DataQ = pd.read_excel(PathExcelQobs) self.QobsData = DataQ.copy() + self.DataQindex = DataQ.index self.QobsData_fi = DataQ.index[0].to_pydatetime() self.QobsData_ff = DataQ.index[-1].to_pydatetime() self.QobsData_fd = DataQ.index[1] - DataQ.index[0] idExcelQ = self.QobsData.columns.values.tolist() - return idExcelQ,DataQ + DataQdf = pd.Dataframe(Data={'Q':self.QobsData},index = self.DataQindex) + return idExcelQ,DataQ,DataQindex,DataQdf def Sim_SaveParameters(self, PathNC, ParamName, scalarParam): @@ -960,6 +962,8 @@ def Sim_Basin(self, Start, Nsteps, Calibracion, PathRain, DeltaT, exponentes): self.Sim_DepositionMap = np.copy(wmf.models.voldepo) #SErie de sedimentos simulada self.Sim_Sediments = Qsed.copy() + + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 1329704..6ac2cbf 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -1247,7 +1247,51 @@ def clickEventSimulationDeCuenca(): self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'El modelo se ha ejecutado con exito', level=QgsMessageBar.INFO, duration=3) - + + + def clickEventViewSerieQobsQsim(): + self.HSplots = HSplots.PlotCaudal() + PathFigure = '/tmp/HydroSED/Plots_Rainfall/QobsQsimPlotSimu.html' + PathQobs = self.PathinSimu_Qobs_Sed.text().strip() + #Obtiene el id de la estación + id_est = int(self.comboBox_Selec_Qobs_Sed.currentText().encode()) + #Obtiene la serie de caudales + dfDataQobs = self.HSutils.Sim_GetQobsInfo(PathQobs)[3] + dfDataQsim = self.HSutils.Sim_Streamflow + f_ini = self.Simulacion_DateTimeStart.dateTime().toPyDateTime() + f_fin = self.Simulacion_DateTimeEnd.dateTime().toPyDateTime() + self.dfDataQobs = dfDataQobs[id_est][f_ini:f_fin] + self.dfDataQsim = dfDataQsim[f_ini:f_fin] + self.HSplots.Plot_Caudal_Simu(PathFigure,self.dfDataQobs,self.dfDataQsim) + #Set de la ventana que contiene la figura + self.VistaQobsWeb = QWebView(None) + self.VistaQobsWeb.load(QUrl.fromLocalFile(PathFigure)) + self.VistaQobsWeb.setWindowTitle('Series de Caudales') + self.VistaQobsWeb.setMinimumWidth(1100) + self.VistaQobsWeb.setMaximumWidth(3000) + self.VistaQobsWeb.setMinimumHeight(100) + self.VistaQobsWeb.setMaximumHeight(400) + self.VistaQobsWeb.show() + + def clickEventViewCDCQobsQsim(): + self.HSplots = HSplots.PlotCaudal() + PathFigure = '/tmp/HydroSED/Plots_Rainfall/CDCQobsQsimuPlotSimu.html' + PathQobs = self.PathinSimu_Qobs_Sed.text().strip() + #Obtiene el id de la estación + id_est = int(self.comboBox_Selec_Qobs_Sed.currentText().encode()) + #Obtiene la serie de caudales + self.HSplots.Plot_CDC_caudal(PathFigure,self.dfDataQobs,self.dfDataQsim) + #Set de la ventana que contiene la figura + self.VistaQobsWeb = QWebView(None) + self.VistaQobsWeb.load(QUrl.fromLocalFile(PathFigure)) + self.VistaQobsWeb.setWindowTitle('Curvas de duración de Caudales') + self.VistaRainWeb.setMinimumWidth(200) + self.VistaRainWeb.setMaximumWidth(400) + self.VistaRainWeb.setMinimumHeight(400) + self.VistaRainWeb.setMaximumHeight(400) + self.VistaRainWeb.show() + + self.ButtonSimCalib2Nc.clicked.connect(clickEventAddNewParamSet) self.tabPanelDockOpciones.currentChanged.connect(clickEventUpdateParamMapValues) self.ParamNamesCombo.currentIndexChanged.connect(changeEventUpdateScalarParameters) @@ -1261,6 +1305,9 @@ def clickEventSimulationDeCuenca(): self.Boton_Visualizar_Qobs_Sed.clicked.connect(clickEventViewSerieQobsSed) self.ButtonSim_RunSimulacion.clicked.connect(clickEventSimulationDeCuenca) + #self.ButtonSim_ViewSeries.clicked.connect(clickEventViewSerieQobsQsim) + #self.ButtonSim_ViewSeries_2.clicked.connect(clickEventViewCDCQobsQsim) + def setupUIInputsOutputs (self): From b6b419dcf66988c6619bc775cddf8d81eec704f3 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 29 Aug 2018 11:31:14 -0500 Subject: [PATCH 130/142] cambios en nombres de botones para figuras de simulacion --- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index a635ea7..13eec81 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -5212,7 +5212,7 @@ 0 - -752 + -1301 433 2518 @@ -6739,7 +6739,7 @@ - + 130 @@ -6770,7 +6770,7 @@ - + 130 @@ -6842,7 +6842,7 @@ - + 130 @@ -6914,7 +6914,7 @@ - + 130 @@ -6976,7 +6976,7 @@ - + 130 @@ -7007,7 +7007,7 @@ - + false @@ -7039,7 +7039,7 @@ - + false @@ -7071,7 +7071,7 @@ - + false @@ -7103,7 +7103,7 @@ - + false @@ -7135,7 +7135,7 @@ - + false @@ -7167,7 +7167,7 @@ - + false From 98b365deb1ab2921f4db109a7488b68a0565b11d Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 29 Aug 2018 14:29:31 -0500 Subject: [PATCH 131/142] se agregan funciones para habilitar la opciond e setear condiciones de la cuenca como valor constante, desde NC o desde archivo de condiciones, tambien se agrega nueva funcion a wmf que permite leer el hdr de las condiciones de almacenamiento --- qgisplugin/HydroSEDPlots.py | 2 +- qgisplugin/HydroSEDPluginUtils.py | 35 ++++- qgisplugin/HydroSEDPlugin_dockwidget.py | 25 ++++ qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 147 +++++++++++-------- wmf/wmf.py | 11 ++ 5 files changed, 158 insertions(+), 62 deletions(-) diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py index af230c2..3f2b78f 100644 --- a/qgisplugin/HydroSEDPlots.py +++ b/qgisplugin/HydroSEDPlots.py @@ -327,7 +327,7 @@ def Plot_CDC_caudal(self,pathFigure,dfQobs,dfQsim): layout = dict( width=670, height=500, - title = "Curvas de duración de Caudal", + title = "Curvas de duracion de Caudal", xaxis = dict( title='Porcentaje de Excedencia', range = [str(df.index[0]),str(df.index[-1])]), diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 0c13356..8835217 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -963,7 +963,40 @@ def Sim_Basin(self, Start, Nsteps, Calibracion, PathRain, DeltaT, exponentes): #SErie de sedimentos simulada self.Sim_Sediments = Qsed.copy() - + def Sim_setStates_ConstValue(self, Tanque, Valor): + '''Establece condiciones de almacenamiento constantes basado en un valor constante para toda la cuenca''' + #Si es un almacenamiento del modelo + if Tanque < 6: + self.cuenca.set_Storage(Valor, Tanque - 1) + #Si es sedimentos de la cuenca. + else: + wmf.models.vd = np.ones(self.cuenca.ncells)*Valor + + def Sim_setStates_FileValue(self, Tanque, Path2Bin, Fecha): + '''Establece las condiciones de almacenamiento basado en un binario con datos de almacenamiento anteriores''' + #Si es un tanque del modelo + if Tanque < 6: + #Obtiene el record. + Fecha = Fecha.strftime('%Y-%m-%d %H:%M') + Data = wmf.read_storage_struct(Path2Bin) + record = Data.index.get_loc(Fecha) + #lee el archivo + Valor, res = wmf.read_float_basin_Ncol(Path2Bin, + record, self.cuenca.ncells, 5) + if res == 0: + self.cuenca.set_Storage(Valor, Tanque - 1) + + def Sim_setStates_NcValue(self, Tanque): + '''Establece condiciones de un tanque en funcion del estado que se tiene en la tabla NC''' + #Saca el valor del diccionario + if Tanque < 6: + Valor = self.DicBasinNc['storage']['var'][Tanque-1] + self.cuenca.set_Storage(Valor, Tanque -1) + + + + + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 6ac2cbf..36903cf 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -1207,6 +1207,30 @@ def __UpdateVar2WMFTable__(varName, varValue): self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[varName], varName, self.Tabla_Prop_WMF) + def clickEventSetAlmacenamientos(): + '''Establece que clase de almacenamientos se van a usar para la simulacion''' + #Itera por opciones y almacenamientos + self.DictStatesOptions = {} + for state in range(1,7): + for option in range(1,4): + #Determina en que opcion esta + boton = 'RadioO'+str(option)+'S'+str(state) + Estado = getattr(self, boton).isChecked() + #Si encontro el estado lo habilita + if Estado: + #Valor dado por el susuario + if option == 1: + Value = getattr(self, 'Storage'+str(state)+'Val').value() + self.HSutils.Sim_setStates_ConstValue(state, Value) + #Valor tomado de un archivo de estados de almacenamiento + if option == 2: + FilePath = self.StateFilePath.text().strip() + Date = self.StateDate.dateTime().toPyDateTime() + Return = self.HSutils.Sim_setStates_FileValue(state, FilePath, Date) + #Valor tomado de la variable storage del NC + if option == 3: + self.HSutils.Sim_setStates_NcValue(state) + def clickEventSimulationDeCuenca(): '''Hace la simulacion hidrologica con el set de param seleccionados y los mapas propios de la cuenca''' #Obtiene lo que se necesita para ejecutar @@ -1304,6 +1328,7 @@ def clickEventViewCDCQobsQsim(): self.Boton_Visualizar_Qobs.clicked.connect(clickEventViewSerieQobs) self.Boton_Visualizar_Qobs_Sed.clicked.connect(clickEventViewSerieQobsSed) + self.ButtonSimSetStates.clicked.connect(clickEventSetAlmacenamientos) self.ButtonSim_RunSimulacion.clicked.connect(clickEventSimulationDeCuenca) #self.ButtonSim_ViewSeries.clicked.connect(clickEventViewSerieQobsQsim) #self.ButtonSim_ViewSeries_2.clicked.connect(clickEventViewCDCQobsQsim) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 13eec81..1c165c7 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -967,7 +967,7 @@ - + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico @@ -1629,7 +1629,7 @@ - + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico @@ -5212,7 +5212,7 @@ 0 - -1301 + -833 433 2518 @@ -6475,8 +6475,8 @@ - 10 - 1370 + 0 + 1310 401 901 @@ -7512,7 +7512,7 @@ true - true + false QAbstractSpinBox::NoButtons @@ -7537,7 +7537,7 @@ true - true + false QAbstractSpinBox::NoButtons @@ -7562,7 +7562,7 @@ true - true + false QAbstractSpinBox::NoButtons @@ -7587,7 +7587,7 @@ true - true + false QAbstractSpinBox::NoButtons @@ -7612,7 +7612,7 @@ true - true + false QAbstractSpinBox::NoButtons @@ -7726,7 +7726,7 @@ - + 90 @@ -7745,7 +7745,7 @@ - + 160 @@ -7769,6 +7769,34 @@ + + + + + 70 + 16777215 + + + + true + + + false + + + QAbstractSpinBox::NoButtons + + + 2 + + + 99999.000000000000000 + + + 1.000000000000000 + + + @@ -7783,7 +7811,7 @@ false - + 20 @@ -7802,7 +7830,7 @@ - + 90 @@ -7821,7 +7849,7 @@ - + 160 @@ -7859,7 +7887,7 @@ false - + 20 @@ -7878,7 +7906,7 @@ - + 90 @@ -7897,7 +7925,7 @@ - + 160 @@ -7935,7 +7963,7 @@ false - + 20 @@ -7954,7 +7982,7 @@ - + 90 @@ -7973,7 +8001,7 @@ - + 160 @@ -8011,7 +8039,7 @@ false - + 20 @@ -8030,7 +8058,7 @@ - + 90 @@ -8049,7 +8077,7 @@ - + 160 @@ -8087,7 +8115,7 @@ false - + 20 @@ -8106,7 +8134,7 @@ - + 90 @@ -8125,7 +8153,7 @@ - + 160 @@ -8149,34 +8177,6 @@ - - - - - 70 - 16777215 - - - - true - - - true - - - QAbstractSpinBox::NoButtons - - - 2 - - - 99999.000000000000000 - - - 1.000000000000000 - - - @@ -8189,7 +8189,7 @@ - + 157 @@ -8245,7 +8245,7 @@ - + Seleccionar la fecha de inicio para correr la simulación @@ -8285,7 +8285,33 @@ - + + + true + + + + 40 + 16777215 + + + + Visualiza una entrada o acumulado del binario de lluvia interpolado. + + + Visualiza una entrada o acumulado del binario de lluvia interpolado. + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png + + + + + Establecer @@ -8299,8 +8325,8 @@ - 20 - 1340 + 0 + 1290 401 20 @@ -8324,6 +8350,7 @@ + diff --git a/wmf/wmf.py b/wmf/wmf.py index 03143ea..4da2c1f 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -558,6 +558,17 @@ def read_rain_struct(ruta): usecols = (1,2,3)) return D +def read_storage_struct(ruta): + '''Lee la estructura del archivo encabezado de almacenamiento''' + #Obtiene rutaHdr + PathBin, PathHdr = __Add_hdr_bin_2route__(ruta,storage=True) + #Lee el archivo + Data = pd.read_csv(PathHdr, + skiprows=4, + index_col=6, + parse_dates=True) + return Data + def __Save_storage_hdr__(rute,rute_rain,Nintervals,FirstInt,cuenca, Mean_Storage): #Lee fechas para el intervalo de tiempo From 3f5380e05cb85577a81e4256b43a28ee69db33aa Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Wed, 29 Aug 2018 16:02:13 -0500 Subject: [PATCH 132/142] =?UTF-8?q?Avance=20plots=20simulaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPlots.py | 26 +- qgisplugin/HydroSEDPluginUtils.py | 4 +- qgisplugin/HydroSEDPlugin_dockwidget.py | 49 ++-- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 281 ++++++++++--------- 4 files changed, 198 insertions(+), 162 deletions(-) diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py index af230c2..800e776 100644 --- a/qgisplugin/HydroSEDPlots.py +++ b/qgisplugin/HydroSEDPlots.py @@ -265,7 +265,7 @@ def Plot_Caudal(self, pathFigure,DataQ,id_est,colorline): #Guarda el html plot(fig,filename=pathFigure, auto_open = False) - def Plot_Caudal_Simu(self,pathFigure,dfQobs,dfQsim): + def Plot_Caudal_Simu(self,pathFigure,dfQobs,dfQsim,rain_mean): trace_high = go.Scatter( x=dfQsim.index, @@ -280,21 +280,30 @@ def Plot_Caudal_Simu(self,pathFigure,dfQobs,dfQsim): name = "Q Observado", line = dict(color = 'blue'), opacity = 0.8) + trace_inv = go.Scatter( + x=dfQsim.index, + y=rain_mean.values, + name = "Q Observado", + line = dict(color = 'blue'), + opacity = 0.8, + yaxis='y2') - data = [trace_high,trace_low] + data = [trace_high,trace_low,trace_inv] layout = dict( title = u"Series de caudal", xaxis = dict( - title='Fechas', - range = [str(df.index[0]),str(df.index[-1])]), + title='Fechas'), yaxis=dict( - title="$Caudal [m^3/s]$") + title="Caudal [m3/s]"), + yaxis2=dict(autorange="reversed", + title="Caudal [m3/s]", + overlaying ='y', + side='right') ) fig = dict(data=data, layout=layout) - #py.iplot(fig, filename = "Series") #Guarda el html plot(fig,filename=pathFigure, auto_open = False) @@ -327,10 +336,9 @@ def Plot_CDC_caudal(self,pathFigure,dfQobs,dfQsim): layout = dict( width=670, height=500, - title = "Curvas de duración de Caudal", + title = u'Curvas de duracion de Caudal', xaxis = dict( - title='Porcentaje de Excedencia', - range = [str(df.index[0]),str(df.index[-1])]), + title='Porcentaje de Excedencia'), yaxis=dict( title='$Caudal [m^3/s]$') diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 0c13356..8cba7fc 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -727,8 +727,7 @@ def Sim_GetQobsInfo(self,PathExcelQobs): self.QobsData_ff = DataQ.index[-1].to_pydatetime() self.QobsData_fd = DataQ.index[1] - DataQ.index[0] idExcelQ = self.QobsData.columns.values.tolist() - DataQdf = pd.Dataframe(Data={'Q':self.QobsData},index = self.DataQindex) - return idExcelQ,DataQ,DataQindex,DataQdf + return idExcelQ,DataQ,self.DataQindex def Sim_SaveParameters(self, PathNC, ParamName, scalarParam): @@ -941,6 +940,7 @@ def Sim_Basin(self, Start, Nsteps, Calibracion, PathRain, DeltaT, exponentes): #Obtiene resultados como cosas genericas self.Sim_index = Qsim.index self.Sim_Streamflow = Qsim.copy() + print 'qsim',self.Sim_Streamflow self.Sim_Rainfall = pd.Series(Results['Rain_hietogram'][0], index = self.Sim_index) self.Sim_Balance = pd.Series(Results['Balance'][0], index = self.Sim_index) self.Sim_Storage = Results['Storage'] diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 6ac2cbf..c95ddad 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -1134,13 +1134,13 @@ def clickEventViewSerieSimuRainfall(): def clickEventViewSerieQobs(): PathFigure = '/tmp/HydroSED/Plots_Rainfall/QobsPlotSimu.html' - PathQobs = self.PathinSimu_Qobs.text().strip() + self.PathQobs = self.PathinSimu_Qobs.text().strip() #Obtiene el id de la estación id_est = int(self.comboBox_Selec_Qobs.currentText().encode()) #Obtiene la serie de caudales - DataQ = self.HSutils.Sim_GetQobsInfo(PathQobs)[1] + self.DataQ = self.HSutils.Sim_GetQobsInfo(self.PathQobs)[1] self.HSplots = HSplots.PlotCaudal() - self.HSplots.Plot_Caudal(PathFigure,DataQ,id_est,'blue') + self.HSplots.Plot_Caudal(PathFigure,self.DataQ,id_est,'blue') #Set de la ventana que contiene la figura. self.VistaQobsWeb = QWebView(None) self.VistaQobsWeb.load(QUrl.fromLocalFile(PathFigure)) @@ -1158,9 +1158,9 @@ def clickEventViewSerieQobsSed(): #Obtiene el id de la estación id_est = int(self.comboBox_Selec_Qobs_Sed.currentText().encode()) #Obtiene la serie de caudales - DataQ = self.HSutils.Sim_GetQobsInfo(PathQobs)[1] + self.DataQsed = self.HSutils.Sim_GetQobsInfo(PathQobs)[1] self.HSplots = HSplots.PlotCaudal() - self.HSplots.Plot_Caudal(PathFigure,DataQ,id_est,'goldenrod') + self.HSplots.Plot_Caudal(PathFigure,self.DataQsed,id_est,'goldenrod') #Set de la ventana que contiene la figura. self.VistaQobsWeb = QWebView(None) self.VistaQobsWeb.load(QUrl.fromLocalFile(PathFigure)) @@ -1250,19 +1250,32 @@ def clickEventSimulationDeCuenca(): def clickEventViewSerieQobsQsim(): + #Fechas de inicio y fin de simulacion + self.f_ini = self.Simulacion_DateTimeStart.dateTime().toPyDateTime() + self.f_fin = self.Simulacion_DateTimeEnd.dateTime().toPyDateTime() + #llama el df de caudal observado + dfDataQsim = self.HSutils.Sim_Streamflow + #identifica el tramo para graficar + id_tramo = str(self.spinBox.value()) + #Llama el df en el id de tramo que puso el usuario + self.dfDataQsim = dfDataQsim[id_tramo] + #Llama la clase de plot caudal self.HSplots = HSplots.PlotCaudal() PathFigure = '/tmp/HydroSED/Plots_Rainfall/QobsQsimPlotSimu.html' - PathQobs = self.PathinSimu_Qobs_Sed.text().strip() - #Obtiene el id de la estación - id_est = int(self.comboBox_Selec_Qobs_Sed.currentText().encode()) - #Obtiene la serie de caudales - dfDataQobs = self.HSutils.Sim_GetQobsInfo(PathQobs)[3] - dfDataQsim = self.HSutils.Sim_Streamflow - f_ini = self.Simulacion_DateTimeStart.dateTime().toPyDateTime() - f_fin = self.Simulacion_DateTimeEnd.dateTime().toPyDateTime() - self.dfDataQobs = dfDataQobs[id_est][f_ini:f_fin] - self.dfDataQsim = dfDataQsim[f_ini:f_fin] - self.HSplots.Plot_Caudal_Simu(PathFigure,self.dfDataQobs,self.dfDataQsim) + + if self.checkBox_Simu_Qs.isChecked(): + #Selecciona el id que haya puesto el usuario + id_est = int(self.comboBox_Selec_Qobs.currentText().encode()) + #Obtiene la serie de caudales + self.PathQobs = self.PathinSimu_Qobs.text().strip() + #llama el df de caudal observado + self.DataQ = self.HSutils.Sim_GetQobsInfo(self.PathQobs)[1] + #Crea el dataframe + self.dfDataQobs = self.DataQ[id_est][self.f_ini:self.f_fin] + else: + self.dfDataQobs = self.dfDataQsim*np.nan + print self.HSutils.Sim_Rainfall + self.HSplots.Plot_Caudal_Simu(PathFigure,self.dfDataQobs,self.dfDataQsim,self.HSutils.Sim_Rainfall) #Set de la ventana que contiene la figura self.VistaQobsWeb = QWebView(None) self.VistaQobsWeb.load(QUrl.fromLocalFile(PathFigure)) @@ -1305,8 +1318,8 @@ def clickEventViewCDCQobsQsim(): self.Boton_Visualizar_Qobs_Sed.clicked.connect(clickEventViewSerieQobsSed) self.ButtonSim_RunSimulacion.clicked.connect(clickEventSimulationDeCuenca) - #self.ButtonSim_ViewSeries.clicked.connect(clickEventViewSerieQobsQsim) - #self.ButtonSim_ViewSeries_2.clicked.connect(clickEventViewCDCQobsQsim) + self.ButtonSim_ViewStreamflow.clicked.connect(clickEventViewSerieQobsQsim) + self.ButtonSim_ViewCDC.clicked.connect(clickEventViewCDCQobsQsim) def setupUIInputsOutputs (self): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 13eec81..eb25fec 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -68,7 +68,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -254,7 +254,7 @@ - + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png @@ -295,7 +295,7 @@ 0 0 - 443 + 446 2018 @@ -452,7 +452,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -572,7 +572,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -815,7 +815,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -891,7 +891,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1008,7 +1008,7 @@ - + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -1043,7 +1043,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -1072,7 +1072,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -1150,7 +1150,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png:/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png @@ -1179,7 +1179,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png:/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png @@ -1474,7 +1474,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1537,7 +1537,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -1572,7 +1572,7 @@ - + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -1655,7 +1655,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -1684,7 +1684,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -1736,7 +1736,7 @@ 0 0 - 443 + 446 2018 @@ -1829,7 +1829,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -1943,7 +1943,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1960,7 +1960,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2042,7 +2042,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -2237,7 +2237,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2337,7 +2337,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2391,7 +2391,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2445,7 +2445,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2504,7 +2504,7 @@ 0 0 - 443 + 446 1918 @@ -2673,7 +2673,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2983,7 +2983,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3095,7 +3095,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -3112,7 +3112,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3333,7 +3333,7 @@ 0 0 - 443 + 446 1918 @@ -3456,7 +3456,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3482,7 +3482,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3634,7 +3634,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3660,7 +3660,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3720,7 +3720,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3825,7 +3825,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3898,7 +3898,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4124,7 +4124,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4141,7 +4141,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4321,7 +4321,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4597,7 +4597,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4623,7 +4623,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4683,7 +4683,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4823,7 +4823,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4967,7 +4967,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4984,7 +4984,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -5161,7 +5161,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5212,8 +5212,8 @@ 0 - -1301 - 433 + -1526 + 436 2518 @@ -5334,7 +5334,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -5363,7 +5363,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5454,7 +5454,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -5493,7 +5493,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5571,7 +5571,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -5610,7 +5610,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -6462,7 +6462,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -6732,11 +6732,75 @@ - - + + + + + 130 + 0 + + + + + 130 + 16777215 + + + + Graficar las series de caudales + + + Graficar las series de caudales + + + Serie sedimentos + + + + 11 + 11 + + + + + + + + false + + + + 0 + 15 + + + + + 50 + 25 + + + + Exportar series de caudales a Excel + + + Exportar series de caudales a Excel + + + + + + + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png + + - + + + 100000 + + @@ -6820,7 +6884,11 @@ - + + + 100000 + + @@ -6841,37 +6909,6 @@ - - - - - 130 - 0 - - - - - 130 - 16777215 - - - - Graficar las series de caudales - - - Graficar las series de caudales - - - Serie sedimentos - - - - 11 - 11 - - - - @@ -6892,7 +6929,11 @@ - + + + 100000 + + @@ -7033,7 +7074,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -7065,7 +7106,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -7097,7 +7138,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -7129,7 +7170,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -7161,40 +7202,15 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png - - - - false - - - - 0 - 15 - - - - - 50 - 25 - - - - Exportar series de caudales a Excel - - - Exportar series de caudales a Excel - - - - - - - :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png + + + + 100000 @@ -7320,7 +7336,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -7337,7 +7353,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -8228,7 +8244,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -8323,7 +8339,6 @@ - - + From e272ff0362f4309cd60560e153f13e4e51692daa Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 29 Aug 2018 16:05:24 -0500 Subject: [PATCH 133/142] avances en el establecimientod e las condiciones inciales --- qgisplugin/HydroSEDPluginUtils.py | 11 +- qgisplugin/HydroSEDPlugin_dockwidget.py | 68 +++++++----- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 103 +++++++++++++++---- 3 files changed, 134 insertions(+), 48 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 8835217..fae60a5 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -914,11 +914,14 @@ def Radar_Conver2Basin(self, PathRadarBasin, TimeStep, umbral = 0.01, self.cuenca.rain_radar2basin_from_array(status = 'reset') - def Sim_Basin(self, Start, Nsteps, Calibracion, PathRain, DeltaT, exponentes): + def Sim_Basin(self, Start, Nsteps, Calibracion, PathRain, DeltaT, exponentes, PathStore): '''Hace la simulacion hidrologica de la cuenca''' #Set de calibracion wmf.models.sed_factor = Calibracion[-1] Calibracion = Calibracion[:-1] + print Calibracion + Calibracion = Calibracion[2:] + Calibracion[:2] + print Calibracion #Set del intervalo de tiempo de simulacion wmf.models.dt = DeltaT #SEtea el tipo de velocidad de acuerdo a los exponentes @@ -932,12 +935,14 @@ def Sim_Basin(self, Start, Nsteps, Calibracion, PathRain, DeltaT, exponentes): Results, Qsim = self.cuenca.run_shia(Calibracion, PathRain, Nsteps, - Start) + Start, + ruta_storage = PathStore) elif wmf.models.sim_sediments == 1: Results, Qsim, Qsed = self.cuenca.run_shia(Calibracion, PathRain, Nsteps, - Start) + Start, + ruta_storage = PathStore) #Obtiene resultados como cosas genericas self.Sim_index = Qsim.index self.Sim_Streamflow = Qsim.copy() diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 36903cf..d43b7cc 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -1018,6 +1018,12 @@ def setupLineEditButtonOpenBinFileDialog (lineEditHolder, fileDialogHolder): '''Que solo busque los archivos con esa extension .bin''' lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Binarios (*.bin);;")) + def setupLineEditButtonOpenBinStoFileDialog (lineEditHolder, fileDialogHolder): + '''Que solo busque los archivos con esa extension .bin''' + lineEditHolder.setText (fileDialogHolder.getSaveFileName (QtGui.QDialog (), "Guardar estados almacenamiento", "*", "Binario (*.StObin);;")) + + #getSaveFileName (QtGui.QDialog (), "Guardar parametros en un archivo de excel", "*", "Excel (*.xlsx);;") + def changeEventUpdateScalarParameters(): '''Actualiza los parametros escalares de las tablas de acuerdo al set seleccionado''' #Obtiene el nombre de la param seleccionada @@ -1207,29 +1213,40 @@ def __UpdateVar2WMFTable__(varName, varValue): self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[varName], varName, self.Tabla_Prop_WMF) + def clickEventSaveAlmacenamientos(): + '''Establece la ruta de guardado de los almacenamientos''' + #Establece el punto de guardado + setupLineEditButtonOpenBinStoFileDialog(self.Where2SaveStates, QFileDialog) + Path = self.Where2SaveStates.text().strip() + #Hace check del boton + self.checkBox_Simu_MeanSpeed.setChecked(True) + def clickEventSetAlmacenamientos(): - '''Establece que clase de almacenamientos se van a usar para la simulacion''' - #Itera por opciones y almacenamientos - self.DictStatesOptions = {} - for state in range(1,7): - for option in range(1,4): - #Determina en que opcion esta - boton = 'RadioO'+str(option)+'S'+str(state) - Estado = getattr(self, boton).isChecked() - #Si encontro el estado lo habilita - if Estado: - #Valor dado por el susuario - if option == 1: - Value = getattr(self, 'Storage'+str(state)+'Val').value() - self.HSutils.Sim_setStates_ConstValue(state, Value) - #Valor tomado de un archivo de estados de almacenamiento - if option == 2: - FilePath = self.StateFilePath.text().strip() - Date = self.StateDate.dateTime().toPyDateTime() - Return = self.HSutils.Sim_setStates_FileValue(state, FilePath, Date) - #Valor tomado de la variable storage del NC - if option == 3: - self.HSutils.Sim_setStates_NcValue(state) + '''Establece que clase de almacenamientos se van a usar para la simulacion''' + #Itera por opciones y almacenamientos + self.DictStatesOptions = {} + for state in range(1,7): + for option in range(1,4): + #Determina en que opcion esta + boton = 'RadioO'+str(option)+'S'+str(state) + Estado = getattr(self, boton).isChecked() + #Si encontro el estado lo habilita + if Estado: + #Valor dado por el susuario + if option == 1: + Value = getattr(self, 'Storage'+str(state)+'Val').value() + self.HSutils.Sim_setStates_ConstValue(state, Value) + #Valor tomado de un archivo de estados de almacenamiento + if option == 2: + FilePath = self.StateFilePath.text().strip() + Date = self.StateDate.dateTime().toPyDateTime() + Return = self.HSutils.Sim_setStates_FileValue(state, FilePath, Date) + #Valor tomado de la variable storage del NC + if option == 3: + self.HSutils.Sim_setStates_NcValue(state) + if state<6: + print HSutils.wmf.models.storage[state-1] + print '----' def clickEventSimulationDeCuenca(): '''Hace la simulacion hidrologica con el set de param seleccionados y los mapas propios de la cuenca''' @@ -1255,8 +1272,12 @@ def clickEventSimulationDeCuenca(): if self.checkBox_Simu_Retorno.isChecked(): HSutils.wmf.models.retorno = 1 HSutils.wmf.models.show_mean_retorno = 1 + #Guarda o no estados de almacenamiento + pathStorage = None + if self.checkBox_Simu_MeanSpeed.isChecked(): + pathStorage = self.Where2SaveStates.text().strip() #Simulacion hidrologica - self.HSutils.Sim_Basin(Inicio, Npasos, Calib, PathBin, TimeDelta, Exponenetes) + self.HSutils.Sim_Basin(Inicio, Npasos, Calib, PathBin, TimeDelta, Exponenetes, pathStorage) #Pone estados de almacenamiento finales en el NC self.HSutils.DicBasinNc['storage']['var'] = np.copy(self.HSutils.Sim_Storage) self.HSutils.DicBasinNc['storage']['saved'] = False @@ -1328,6 +1349,7 @@ def clickEventViewCDCQobsQsim(): self.Boton_Visualizar_Qobs.clicked.connect(clickEventViewSerieQobs) self.Boton_Visualizar_Qobs_Sed.clicked.connect(clickEventViewSerieQobsSed) + self.BotonSelectSaveStateRute.clicked.connect(clickEventSaveAlmacenamientos) self.ButtonSimSetStates.clicked.connect(clickEventSetAlmacenamientos) self.ButtonSim_RunSimulacion.clicked.connect(clickEventSimulationDeCuenca) #self.ButtonSim_ViewSeries.clicked.connect(clickEventViewSerieQobsQsim) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 1c165c7..67a2d09 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -5212,7 +5212,7 @@ 0 - -833 + -1083 433 2518 @@ -6476,7 +6476,7 @@ 0 - 1310 + 1280 401 901 @@ -6490,7 +6490,7 @@ 0 30 401 - 201 + 204 @@ -6567,7 +6567,33 @@ - + + + + Activa la simulación de Sedimentos en el modelo + + + Activa la simulación de Sedimentos en el modelo + + + Sedimentos + + + + + + + Activa el retorno desde el tanque subsuperficial + + + Activa el retorno desde el tanque subsuperficial + + + Retorno + + + + @@ -6592,20 +6618,29 @@ - - + + + + + 157 + 16777215 + + - Activa la simulación de Sedimentos en el modelo + Definir el nombre de la parametrización actual + + + - Activa la simulación de Sedimentos en el modelo + Definir el nombre de la parametrización actual. - - Sedimentos + + false - + Activa la simulación de Deslizamientos en el modelo @@ -6615,16 +6650,26 @@ - - - - Activa el retorno desde el tanque subsuperficial + + + + + 30 + 0 + - - Activa el retorno desde el tanque subsuperficial + + + 30 + 16777215 + - Retorno + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -7406,7 +7451,7 @@ 0 880 401 - 401 + 371 @@ -7418,7 +7463,7 @@ 0 30 401 - 365 + 341 @@ -7520,6 +7565,9 @@ 2 + + 99999.000000000000000 + 1.000000000000000 @@ -7545,6 +7593,9 @@ 2 + + 99999.000000000000000 + 1.000000000000000 @@ -7570,6 +7621,9 @@ 2 + + 99999.000000000000000 + 1.000000000000000 @@ -7595,6 +7649,9 @@ 2 + + 99999.000000000000000 + 1.000000000000000 @@ -7620,6 +7677,9 @@ 2 + + 99999.000000000000000 + 1.000000000000000 @@ -8326,7 +8386,7 @@ 0 - 1290 + 1260 401 20 @@ -8350,7 +8410,6 @@ - From 1a37e493aec9406b2808fc6a662b41d270623c75 Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Wed, 29 Aug 2018 18:21:05 -0500 Subject: [PATCH 134/142] grafica de serie de caudales y CDC --- qgisplugin/HydroSEDPlots.py | 24 +++++----- qgisplugin/HydroSEDPlugin_dockwidget.py | 60 ++++++++++++++++--------- 2 files changed, 49 insertions(+), 35 deletions(-) diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py index 800e776..3e172eb 100644 --- a/qgisplugin/HydroSEDPlots.py +++ b/qgisplugin/HydroSEDPlots.py @@ -286,12 +286,12 @@ def Plot_Caudal_Simu(self,pathFigure,dfQobs,dfQsim,rain_mean): name = "Q Observado", line = dict(color = 'blue'), opacity = 0.8, - yaxis='y2') + yaxis='y2', + fill='tozeroy') data = [trace_high,trace_low,trace_inv] - layout = dict( - title = u"Series de caudal", + layout = dict(showlegend = False, xaxis = dict( title='Fechas'), yaxis=dict( @@ -308,14 +308,14 @@ def Plot_Caudal_Simu(self,pathFigure,dfQobs,dfQsim,rain_mean): plot(fig,filename=pathFigure, auto_open = False) def Plot_CDC_caudal(self,pathFigure,dfQobs,dfQsim): - plt.close('all') - Qs=np.sort(np.array(dfQobs.values)) + + Qs=np.sort(np.array(dfQsim.values)) Qo=np.sort(np.array(dfQobs.values)) porcen_s=[] porcen_o=[] for i in range(len(Qo)): - porcen_s.append((len(Qs[Qs>Qs[i]]))/float(len(Qo))*100) - porcen_o.append((len(Qo[Qo>Qo[i]]))/float(len(Qo[np.isfinite(Qo)]))*100) + porcen_s.append((len(Qs[Qs>Qs[i]]))/float(len(Qs))*100) + porcen_o.append((len(Qo[Qo>Qo[i]]))/float(len(Qo))*100) trace_high = go.Scatter( x=porcen_s, @@ -333,20 +333,16 @@ def Plot_CDC_caudal(self,pathFigure,dfQobs,dfQsim): data = [trace_high,trace_low] - layout = dict( - width=670, - height=500, - title = u'Curvas de duracion de Caudal', + layout = dict(showlegend = False, + width=500, + height=400, xaxis = dict( title='Porcentaje de Excedencia'), yaxis=dict( title='$Caudal [m^3/s]$') ) - - fig = dict(data=data, layout=layout) - py.iplot(fig, filename = "Hidrografa") #Guarda el html plot(fig,filename=pathFigure, auto_open = False) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index b75347e..4de6811 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -1145,8 +1145,8 @@ def clickEventViewSerieQobs(): id_est = int(self.comboBox_Selec_Qobs.currentText().encode()) #Obtiene la serie de caudales self.DataQ = self.HSutils.Sim_GetQobsInfo(self.PathQobs)[1] - self.HSplots = HSplots.PlotCaudal() - self.HSplots.Plot_Caudal(PathFigure,self.DataQ,id_est,'blue') + self.HSplotsCaudal = HSplots.PlotCaudal() + self.HSplotsCaudal.Plot_Caudal(PathFigure,self.DataQ,id_est,'blue') #Set de la ventana que contiene la figura. self.VistaQobsWeb = QWebView(None) self.VistaQobsWeb.load(QUrl.fromLocalFile(PathFigure)) @@ -1165,8 +1165,8 @@ def clickEventViewSerieQobsSed(): id_est = int(self.comboBox_Selec_Qobs_Sed.currentText().encode()) #Obtiene la serie de caudales self.DataQsed = self.HSutils.Sim_GetQobsInfo(PathQobs)[1] - self.HSplots = HSplots.PlotCaudal() - self.HSplots.Plot_Caudal(PathFigure,self.DataQsed,id_est,'goldenrod') + self.HSplotsCaudal = HSplots.PlotCaudal() + self.HSplotsCaudal.Plot_Caudal(PathFigure,self.DataQsed,id_est,'goldenrod') #Set de la ventana que contiene la figura. self.VistaQobsWeb = QWebView(None) self.VistaQobsWeb.load(QUrl.fromLocalFile(PathFigure)) @@ -1305,7 +1305,7 @@ def clickEventViewSerieQobsQsim(): #Llama el df en el id de tramo que puso el usuario self.dfDataQsim = dfDataQsim[id_tramo] #Llama la clase de plot caudal - self.HSplots = HSplots.PlotCaudal() + self.HSplotsCaudal = HSplots.PlotCaudal() PathFigure = '/tmp/HydroSED/Plots_Rainfall/QobsQsimPlotSimu.html' if self.checkBox_Simu_Qs.isChecked(): @@ -1320,34 +1320,52 @@ def clickEventViewSerieQobsQsim(): else: self.dfDataQobs = self.dfDataQsim*np.nan print self.HSutils.Sim_Rainfall - self.HSplots.Plot_Caudal_Simu(PathFigure,self.dfDataQobs,self.dfDataQsim,self.HSutils.Sim_Rainfall) + self.HSplotsCaudal.Plot_Caudal_Simu(PathFigure,self.dfDataQobs,self.dfDataQsim,self.HSutils.Sim_Rainfall) #Set de la ventana que contiene la figura self.VistaQobsWeb = QWebView(None) self.VistaQobsWeb.load(QUrl.fromLocalFile(PathFigure)) self.VistaQobsWeb.setWindowTitle('Series de Caudales') self.VistaQobsWeb.setMinimumWidth(1100) self.VistaQobsWeb.setMaximumWidth(3000) - self.VistaQobsWeb.setMinimumHeight(100) - self.VistaQobsWeb.setMaximumHeight(400) + self.VistaQobsWeb.setMinimumHeight(200) + self.VistaQobsWeb.setMaximumHeight(500) self.VistaQobsWeb.show() def clickEventViewCDCQobsQsim(): - self.HSplots = HSplots.PlotCaudal() - PathFigure = '/tmp/HydroSED/Plots_Rainfall/CDCQobsQsimuPlotSimu.html' - PathQobs = self.PathinSimu_Qobs_Sed.text().strip() - #Obtiene el id de la estación - id_est = int(self.comboBox_Selec_Qobs_Sed.currentText().encode()) + self.f_ini = self.Simulacion_DateTimeStart.dateTime().toPyDateTime() + self.f_fin = self.Simulacion_DateTimeEnd.dateTime().toPyDateTime() + self.HSplotsCaudal = HSplots.PlotCaudal() + PathFigure1 = '/tmp/HydroSED/Plots_Rainfall/CDCQobsQsimuPlotSimu.html' + #llama el df de caudal observado + dfDataQsim = self.HSutils.Sim_Streamflow + #identifica el tramo para graficar + id_tramo = str(self.spinBox_2.value()) + #Llama el df en el id de tramo que puso el usuario + self.dfDataQsim = dfDataQsim[id_tramo] + + if self.checkBox_Simu_Qs_2.isChecked(): + #Selecciona el id que haya puesto el usuario + id_est = int(self.comboBox_Selec_Qobs.currentText().encode()) + #Obtiene la serie de caudales + self.PathQobs = self.PathinSimu_Qobs.text().strip() + #llama el df de caudal observado + self.DataQ = self.HSutils.Sim_GetQobsInfo(self.PathQobs)[1] + #Crea el dataframe + self.dfDataQobs = self.DataQ[id_est][self.f_ini:self.f_fin] + else: + self.dfDataQobs = self.dfDataQsim*np.nan + #Obtiene la serie de caudales - self.HSplots.Plot_CDC_caudal(PathFigure,self.dfDataQobs,self.dfDataQsim) + self.HSplotsCaudal.Plot_CDC_caudal(PathFigure1,self.dfDataQobs,self.dfDataQsim) #Set de la ventana que contiene la figura self.VistaQobsWeb = QWebView(None) - self.VistaQobsWeb.load(QUrl.fromLocalFile(PathFigure)) - self.VistaQobsWeb.setWindowTitle('Curvas de duración de Caudales') - self.VistaRainWeb.setMinimumWidth(200) - self.VistaRainWeb.setMaximumWidth(400) - self.VistaRainWeb.setMinimumHeight(400) - self.VistaRainWeb.setMaximumHeight(400) - self.VistaRainWeb.show() + self.VistaQobsWeb.load(QUrl.fromLocalFile(PathFigure1)) + self.VistaQobsWeb.setWindowTitle('Curvas de duracion de Caudales') + self.VistaQobsWeb.setMinimumWidth(400) + self.VistaQobsWeb.setMaximumWidth(500) + self.VistaQobsWeb.setMinimumHeight(400) + self.VistaQobsWeb.setMaximumHeight(400) + self.VistaQobsWeb.show() self.ButtonSimCalib2Nc.clicked.connect(clickEventAddNewParamSet) From b9b4966c2b23b3b859370d890c3765f08174055a Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 29 Aug 2018 18:34:49 -0500 Subject: [PATCH 135/142] ya deja cargar estados de un archivo binario y actualiza en la variable de tabla NC --- qgisplugin/HydroSEDPluginUtils.py | 13 +- qgisplugin/HydroSEDPlugin_dockwidget.py | 37 +++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 201 ++++++++++--------- 3 files changed, 146 insertions(+), 105 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 3cc744f..5d04a71 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -918,9 +918,7 @@ def Sim_Basin(self, Start, Nsteps, Calibracion, PathRain, DeltaT, exponentes, Pa #Set de calibracion wmf.models.sed_factor = Calibracion[-1] Calibracion = Calibracion[:-1] - print Calibracion Calibracion = Calibracion[2:] + Calibracion[:2] - print Calibracion #Set del intervalo de tiempo de simulacion wmf.models.dt = DeltaT #SEtea el tipo de velocidad de acuerdo a los exponentes @@ -945,7 +943,6 @@ def Sim_Basin(self, Start, Nsteps, Calibracion, PathRain, DeltaT, exponentes, Pa #Obtiene resultados como cosas genericas self.Sim_index = Qsim.index self.Sim_Streamflow = Qsim.copy() - print 'qsim',self.Sim_Streamflow self.Sim_Rainfall = pd.Series(Results['Rain_hietogram'][0], index = self.Sim_index) self.Sim_Balance = pd.Series(Results['Balance'][0], index = self.Sim_index) self.Sim_Storage = Results['Storage'] @@ -953,10 +950,8 @@ def Sim_Basin(self, Start, Nsteps, Calibracion, PathRain, DeltaT, exponentes, Pa #Resultados opcionales if wmf.models.show_storage == 1: self.Sim_StorageSerie = pd.DataFrame(Results['Mean_Storage'].T, index = self.Sim_index) - print self.Sim_StorageSerie if wmf.models.show_mean_speed == 1: self.Sim_SpeedSerie = pd.DataFrame(Results['Mean_Speed'].T, index = self.Sim_index) - print self.Sim_SpeedSerie if wmf.models.retorno == 1: self.Sim_RetornoSerie = pd.DataFrame(wmf.models.mean_retorno, index = self.Sim_index) self.Sim_RetornoMap = np.copy(wmf.models.retorned) @@ -986,10 +981,13 @@ def Sim_setStates_FileValue(self, Tanque, Path2Bin, Fecha): Data = wmf.read_storage_struct(Path2Bin) record = Data.index.get_loc(Fecha) #lee el archivo - Valor, res = wmf.read_float_basin_Ncol(Path2Bin, + Valor, res = wmf.models.read_float_basin_ncol(Path2Bin, record, self.cuenca.ncells, 5) if res == 0: - self.cuenca.set_Storage(Valor, Tanque - 1) + self.cuenca.set_Storage(Valor[Tanque-1], Tanque - 1) + return Valor[Tanque-1].mean(), Valor[Tanque-1] + else: + return 0.0 def Sim_setStates_NcValue(self, Tanque): '''Establece condiciones de un tanque en funcion del estado que se tiene en la tabla NC''' @@ -997,6 +995,7 @@ def Sim_setStates_NcValue(self, Tanque): if Tanque < 6: Valor = self.DicBasinNc['storage']['var'][Tanque-1] self.cuenca.set_Storage(Valor, Tanque -1) + return Valor.mean(), Valor diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index b75347e..34cf8c5 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -1018,11 +1018,13 @@ def setupLineEditButtonOpenBinFileDialog (lineEditHolder, fileDialogHolder): '''Que solo busque los archivos con esa extension .bin''' lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "", "*", "Binarios (*.bin);;")) - def setupLineEditButtonOpenBinStoFileDialog (lineEditHolder, fileDialogHolder): + def setupLineEditButtonSaveBinStoFileDialog (lineEditHolder, fileDialogHolder): '''Que solo busque los archivos con esa extension .bin''' lineEditHolder.setText (fileDialogHolder.getSaveFileName (QtGui.QDialog (), "Guardar estados almacenamiento", "*", "Binario (*.StObin);;")) - #getSaveFileName (QtGui.QDialog (), "Guardar parametros en un archivo de excel", "*", "Excel (*.xlsx);;") + def setupLineEditButtonOpenBinStoFileDialog (lineEditHolder, fileDialogHolder): + '''Que solo busque los archivos con esa extension .bin''' + lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), "Buscar estados de almacenamiento", "*", "Binarios (*.StObin);;")) def changeEventUpdateScalarParameters(): '''Actualiza los parametros escalares de las tablas de acuerdo al set seleccionado''' @@ -1038,6 +1040,10 @@ def changeEventUpdateScalarParameters(): # codigo = 'self.ParamExp'+str(c+1)+'.setValue('+str(values)+')' # eval(codigo) + def clickEventSetPath2States(): + '''Eventod e click para establecer el path de archivo binario con estados''' + setupLineEditButtonOpenBinStoFileDialog (self.StateFilePath, QFileDialog) + def clickEventUpdateParamMapValues(): '''Muestra en los campos de simulacion el valor medio de los mapas de simulacion''' VarNames = ['h1_max','h3_max', 'v_coef','v_coef','v_coef','v_coef','h_coef', @@ -1220,6 +1226,8 @@ def clickEventSaveAlmacenamientos(): Path = self.Where2SaveStates.text().strip() #Hace check del boton self.checkBox_Simu_MeanSpeed.setChecked(True) + self.checkBox_Simu_MeanStorage.setChecked(True) + HSutils.wmf.models.show_storage = 1 def clickEventSetAlmacenamientos(): '''Establece que clase de almacenamientos se van a usar para la simulacion''' @@ -1236,17 +1244,31 @@ def clickEventSetAlmacenamientos(): if option == 1: Value = getattr(self, 'Storage'+str(state)+'Val').value() self.HSutils.Sim_setStates_ConstValue(state, Value) + Valor = np.ones(self.HSutils.cuenca.ncells)*Value #Valor tomado de un archivo de estados de almacenamiento if option == 2: FilePath = self.StateFilePath.text().strip() Date = self.StateDate.dateTime().toPyDateTime() - Return = self.HSutils.Sim_setStates_FileValue(state, FilePath, Date) + Return, Valor = self.HSutils.Sim_setStates_FileValue(state, FilePath, Date) + Texto = '%.2f' % Return + Comando = 'self.Storage'+str(state)+'Val.setValue('+Texto+')' + eval(Comando) #Valor tomado de la variable storage del NC if option == 3: - self.HSutils.Sim_setStates_NcValue(state) + Return, Valor = self.HSutils.Sim_setStates_NcValue(state) + Texto = '%.2f' % Return + Comando = 'self.Storage'+str(state)+'Val.setValue('+Texto+')' + eval(Comando) if state<6: - print HSutils.wmf.models.storage[state-1] - print '----' + #Actualiza el diccionario NC de storage para visualizar variables + self.HSutils.DicBasinNc['storage']['var'][state-1] = Valor + #Establece las condiciones de esa entrada en la tabla de NC + self.HSutils.DicBasinNc['storage']['saved'] = False + self.TabNC.EditedEntry('storage', self.Tabla_Prop_NC) + #Mensaje de exito y cambio + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + u'Se han actualizado las condiciones de estado, mirar variable storage en Tabla NC', + level=QgsMessageBar.INFO, duration=3) def clickEventSimulationDeCuenca(): '''Hace la simulacion hidrologica con el set de param seleccionados y los mapas propios de la cuenca''' @@ -1268,7 +1290,7 @@ def clickEventSimulationDeCuenca(): if self.checkBox_Simu_MeanSpeed.isChecked(): HSutils.wmf.models.show_mean_speed = 1 if self.checkBox_Simu_MeanStorage.isChecked(): - HSutils.wmf.models.show_mean_storage = 1 + HSutils.wmf.models.show_storage = 1 if self.checkBox_Simu_Retorno.isChecked(): HSutils.wmf.models.retorno = 1 HSutils.wmf.models.show_mean_retorno = 1 @@ -1362,6 +1384,7 @@ def clickEventViewCDCQobsQsim(): self.Boton_Visualizar_Qobs.clicked.connect(clickEventViewSerieQobs) self.Boton_Visualizar_Qobs_Sed.clicked.connect(clickEventViewSerieQobsSed) + self.ButtonSelectPath2States.clicked.connect(clickEventSetPath2States) self.BotonSelectSaveStateRute.clicked.connect(clickEventSaveAlmacenamientos) self.ButtonSimSetStates.clicked.connect(clickEventSetAlmacenamientos) self.ButtonSim_RunSimulacion.clicked.connect(clickEventSimulationDeCuenca) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 06c08a1..d64a223 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -68,7 +68,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -254,7 +254,7 @@ - + :/plugins/HydroSEDPlugin/icons/config.png:/plugins/HydroSEDPlugin/icons/config.png @@ -295,7 +295,7 @@ 0 0 - 446 + 443 2018 @@ -452,7 +452,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -572,7 +572,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -815,7 +815,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -891,7 +891,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1008,7 +1008,7 @@ - + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -1043,7 +1043,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -1072,7 +1072,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -1150,7 +1150,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png:/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png @@ -1179,7 +1179,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png:/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png @@ -1474,7 +1474,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -1537,7 +1537,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -1572,7 +1572,7 @@ - + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico @@ -1655,7 +1655,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -1684,7 +1684,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png @@ -1736,7 +1736,7 @@ 0 0 - 446 + 443 2018 @@ -1829,7 +1829,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -1943,7 +1943,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -1960,7 +1960,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2042,7 +2042,7 @@ - + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png @@ -2237,7 +2237,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2337,7 +2337,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2391,7 +2391,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -2445,7 +2445,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2504,7 +2504,7 @@ 0 0 - 446 + 443 1918 @@ -2673,7 +2673,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -2983,7 +2983,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3095,7 +3095,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -3112,7 +3112,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3333,7 +3333,7 @@ 0 0 - 446 + 443 1918 @@ -3456,7 +3456,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3482,7 +3482,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3634,7 +3634,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3660,7 +3660,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -3720,7 +3720,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -3825,7 +3825,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -3898,7 +3898,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4124,7 +4124,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4141,7 +4141,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4321,7 +4321,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4597,7 +4597,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4623,7 +4623,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -4683,7 +4683,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -4823,7 +4823,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4967,7 +4967,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -4984,7 +4984,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -5161,7 +5161,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5212,7 +5212,7 @@ 0 - -1083 + -830 433 2518 @@ -5334,7 +5334,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -5363,7 +5363,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5454,7 +5454,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -5493,7 +5493,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -5571,7 +5571,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -5610,7 +5610,7 @@ - + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png @@ -6462,7 +6462,7 @@ - + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg @@ -6568,19 +6568,16 @@ - + - Activa la simulación de Sedimentos en el modelo - - - Activa la simulación de Sedimentos en el modelo + Activa la simulación de Deslizamientos en el modelo - Sedimentos + Estados medios - + Activa el retorno desde el tanque subsuperficial @@ -6640,16 +6637,6 @@ - - - - Activa la simulación de Deslizamientos en el modelo - - - Estados medios - - - @@ -6673,6 +6660,19 @@ + + + + Activa la simulación de Sedimentos en el modelo + + + Activa la simulación de Sedimentos en el modelo + + + Sedimentos + + + @@ -6835,7 +6835,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -7119,7 +7119,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -7151,7 +7151,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -7183,7 +7183,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -7215,7 +7215,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -7247,7 +7247,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -7381,7 +7381,7 @@ - + :/plugins/HydroSEDPlugin/icons/toexcel.png:/plugins/HydroSEDPlugin/icons/toexcel.png @@ -7398,7 +7398,7 @@ - + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png @@ -7801,6 +7801,9 @@ + + true + @@ -7840,7 +7843,7 @@ - true + false @@ -7905,6 +7908,9 @@ + + true + @@ -7944,7 +7950,7 @@ - true + false @@ -7981,6 +7987,9 @@ + + true + @@ -8020,7 +8029,7 @@ - true + false @@ -8057,6 +8066,9 @@ + + true + @@ -8096,7 +8108,7 @@ - true + false @@ -8133,6 +8145,9 @@ + + true + @@ -8172,7 +8187,7 @@ - true + false @@ -8209,6 +8224,9 @@ + + true + @@ -8248,7 +8266,7 @@ - true + false @@ -8287,7 +8305,7 @@ - + 30 @@ -8304,7 +8322,7 @@ - + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png @@ -8425,6 +8443,7 @@ - + + From 24c466fdc4b602c0362dfc20e59e55e53e25f631 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 29 Aug 2018 20:22:01 -0500 Subject: [PATCH 136/142] Figura de almacenamientos medio se despliega --- qgisplugin/HydroSEDPlots.py | 34 +++++++++++++++++++++++++ qgisplugin/HydroSEDPlugin_dockwidget.py | 21 +++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py index 3e172eb..ac663df 100644 --- a/qgisplugin/HydroSEDPlots.py +++ b/qgisplugin/HydroSEDPlots.py @@ -1,6 +1,8 @@ from wmf import wmf import numpy as np import plotly.graph_objs as go +import pandas as pd +from plotly import tools from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot class PlotRainfall(): @@ -562,3 +564,35 @@ def StreamProfileHipsometric(self, pathFigure, HipsoData, StreamData): fig = dict(data=data, layout=layout) plot(fig,filename=pathFigure, auto_open = False) +class PlotStorage(): + + def __init__(self): + self.foo = 1 + + def Plot_Storages(self, StoragePath, PathFigure): + '''Hace un plot del storage en el periodo de simulacion''' + #Lee los datos + Data = pd.read_csv(StoragePath, skiprows=4, index_col=6, parse_dates=True) + #Hace la figura + fig = tools.make_subplots(rows=5, cols=1) + for c,key in enumerate(Data.columns.values[1:].tolist()): + trace1 = go.Scatter( + x = Data.index.to_pydatetime(), + y = Data[key].values, + name = key, + line = {'width':3}, + fill='tozeroy', + ) + fig.append_trace(trace1, c+1, 1) + fig['layout'].update(height=600, width=600, + showlegend = False, + yaxis=dict(title='Estado [mm]',), + margin=dict( + l=50, + r=50, + b=50, + t=50, + pad=4 + )) + plot(fig,filename=PathFigure, auto_open = False) + diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 9f44fa0..869d9bb 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -77,6 +77,7 @@ def __init__(self, iface = None, parent=None): self.Path2Radar = '' self.GeoPlots = HSplots.PlotGeomorphology() + self.SimStoragePlots = HSplots.PlotStorage() #Inicia el comboBox de la seleccion de categoria para transformar raster a WMF for k in ['base','Geomorfo','SimHidro','Hidro']: @@ -1183,6 +1184,25 @@ def clickEventViewSerieQobsSed(): self.VistaQobsWeb.setMaximumHeight(400) self.VistaQobsWeb.show() + def clickEventViewSimStorageSeries(): + '''Hace plot de las condiciones medias de almacenamiento de la cuenca''' + #Path de la figura + PathFigure = '/tmp/HydroSED/Plots_Sim/SimStoredConditions.html' + #Obtiene el path de los datos + Path = self.Where2SaveStates.text().strip() + PathBin, PathHdr = HSutils.wmf.__Add_hdr_bin_2route__(Path, storage = True) + #Invoca la figura + self.SimStoragePlots.Plot_Storages(PathHdr, PathFigure) + #Set de la ventana que contiene la figura. + self.VistaQobsWeb = QWebView(None) + self.VistaQobsWeb.load(QUrl.fromLocalFile(PathFigure)) + self.VistaQobsWeb.setWindowTitle('Series de almacenamiento medio') + self.VistaQobsWeb.setMinimumWidth(600) + self.VistaQobsWeb.setMaximumWidth(600) + self.VistaQobsWeb.setMinimumHeight(500) + self.VistaQobsWeb.setMaximumHeight(700) + self.VistaQobsWeb.show() + def __ParseCalibValues__(): '''Obtiene una lista de los param de calibracion a partir de los elem que estan en al interfaz''' Calibracion = [] @@ -1401,6 +1421,7 @@ def clickEventViewCDCQobsQsim(): self.Boton_Visualizar_Binario.clicked.connect(clickEventViewSerieSimuRainfall) self.Boton_Visualizar_Qobs.clicked.connect(clickEventViewSerieQobs) self.Boton_Visualizar_Qobs_Sed.clicked.connect(clickEventViewSerieQobsSed) + self.ButtonSim_ViewStorage.clicked.connect(clickEventViewSimStorageSeries) self.ButtonSelectPath2States.clicked.connect(clickEventSetPath2States) self.BotonSelectSaveStateRute.clicked.connect(clickEventSaveAlmacenamientos) From 46e5a04f9616a2b8630d0abad7a5dde601805362 Mon Sep 17 00:00:00 2001 From: vanesalo10 Date: Wed, 29 Aug 2018 20:38:14 -0500 Subject: [PATCH 137/142] =?UTF-8?q?Plot=20de=20caudales=20solidos,=20pesta?= =?UTF-8?q?=C3=B1a=20de=20simulacion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPlots.py | 59 +++++++++++++++++++++++-- qgisplugin/HydroSEDPlugin_dockwidget.py | 44 ++++++++++++++++++ 2 files changed, 100 insertions(+), 3 deletions(-) diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py index 3e172eb..3e89a3b 100644 --- a/qgisplugin/HydroSEDPlots.py +++ b/qgisplugin/HydroSEDPlots.py @@ -287,7 +287,8 @@ def Plot_Caudal_Simu(self,pathFigure,dfQobs,dfQsim,rain_mean): line = dict(color = 'blue'), opacity = 0.8, yaxis='y2', - fill='tozeroy') + fill='tozeroy', + fillcolor='rgba(0, 102, 153,0.2)') data = [trace_high,trace_low,trace_inv] @@ -344,9 +345,61 @@ def Plot_CDC_caudal(self,pathFigure,dfQobs,dfQsim): ) fig = dict(data=data, layout=layout) #Guarda el html - plot(fig,filename=pathFigure, auto_open = False) - + plot(fig,filename=pathFigure, auto_open = False) + + def Plot_Series_Sedimentos(self,pathFigure,dfArenas,dfLimos,dfArcillas,dfSed_total,dfDataQobs): + + trace_high = go.Scatter( + x=dfArenas.index, + y=dfArenas.values, + name = "Arenas", + line = dict(color = 'rgb(255, 255, 0)',dash = 'dashdot'), + opacity = 0.8) + + trace_1 = go.Scatter( + x=dfArenas.index, + y=dfLimos.values, + name = "Limos", + line = dict(color = 'rgb(179, 143, 0)',dash = 'dash'), + opacity = 0.8) + + trace_2 = go.Scatter( + x=dfArenas.index, + y=dfArcillas.values, + name = "Arcillas", + line = dict(color = 'rgb(85, 128, 0)',dash = 'dot'), + opacity = 0.8) + + trace_3 = go.Scatter( + x=dfArenas.index, + y=dfSed_total.values, + name = "Qsed total", + line = dict(color = 'red',width=3), + opacity = 0.8) + + trace_4 = go.Scatter( + x=dfArenas.index, + y=dfDataQobs.values, + name = "Qsed Observado", + line = dict(color = ('rgb(255, 71, 26)'),width=3), + opacity = 0.8) + + + data = [trace_high,trace_1,trace_2,trace_3,trace_4] + + layout = dict(showlegend = False, + xaxis = dict( + title='Fechas'), + yaxis=dict( + title="Caudal Solido [m3/s]"), + + ) + fig = dict(data=data, layout=layout) + #Guarda el html + plot(fig,filename=pathFigure, auto_open = False) + + class PlotGeomorphology(): def __init__(self): diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 4de6811..aa93511 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -1366,6 +1366,49 @@ def clickEventViewCDCQobsQsim(): self.VistaQobsWeb.setMinimumHeight(400) self.VistaQobsWeb.setMaximumHeight(400) self.VistaQobsWeb.show() + + def clickEventViewSerieSedimentos(): + #Fechas de inicio y fin de simulacion + self.f_ini = self.Simulacion_DateTimeStart.dateTime().toPyDateTime() + self.f_fin = self.Simulacion_DateTimeEnd.dateTime().toPyDateTime() + #llama el df de caudal observado + dfDataQsim = self.HSutils.Sim_Sediments + #identifica el tramo para graficar + id_tramo = str(self.spinBox_3.value()) + #Llama el df en el id de tramo que puso el usuario + dfDataQsim = dfDataQsim[id_tramo] + #Llama la clase de plot caudal + self.HSplotsCaudal = HSplots.PlotCaudal() + self.Arenas=dfDataQsim['Sand'] + self.Limos=dfDataQsim['Lime'] + self.Arcillas= dfDataQsim['Clay'] + self.Sed_total = self.Arenas + self.Limos + self.Arcillas + + PathFigure = '/tmp/HydroSED/Plots_Rainfall/QSedPlotSimu.html' + + if self.checkBox_Simu_Qs_3.isChecked(): + #Selecciona el id que haya puesto el usuario + id_est = int(self.comboBox_Selec_Qobs_Sed.currentText().encode()) + #Obtiene la serie de caudales + self.PathQobs = self.PathinSimu_Qobs_Sed.text().strip() + #llama el df de caudal observado + self.DataQ = self.HSutils.Sim_GetQobsInfo(self.PathQobs)[1] + #Recorta el DF a las fechas + self.dfDataQobs = self.DataQ[id_est][self.f_ini:self.f_fin] + else: + self.dfDataQobs = self.Arenas*np.nan + #print self.HSutils.Sim_Rainfall + self.HSplotsCaudal.Plot_Series_Sedimentos(PathFigure,self.Arenas,self.Limos,self.Arcillas,self.Sed_total,self.dfDataQobs) + #Set de la ventana que contiene la figura + self.VistaQobsWeb = QWebView(None) + self.VistaQobsWeb.load(QUrl.fromLocalFile(PathFigure)) + self.VistaQobsWeb.setWindowTitle('Series de Caudales solidos') + self.VistaQobsWeb.setMinimumWidth(1100) + self.VistaQobsWeb.setMaximumWidth(3000) + self.VistaQobsWeb.setMinimumHeight(200) + self.VistaQobsWeb.setMaximumHeight(500) + self.VistaQobsWeb.show() + self.ButtonSimCalib2Nc.clicked.connect(clickEventAddNewParamSet) @@ -1385,6 +1428,7 @@ def clickEventViewCDCQobsQsim(): self.ButtonSim_RunSimulacion.clicked.connect(clickEventSimulationDeCuenca) self.ButtonSim_ViewStreamflow.clicked.connect(clickEventViewSerieQobsQsim) self.ButtonSim_ViewCDC.clicked.connect(clickEventViewCDCQobsQsim) + self.ButtonSim_ViewSediments.clicked.connect(clickEventViewSerieSedimentos) def setupUIInputsOutputs (self): From 9d9629bae9471318d1b756e6d0d3836962800c55 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Wed, 29 Aug 2018 21:22:54 -0500 Subject: [PATCH 138/142] toques adicionales para corregir pendejadas --- qgisplugin/HydroSEDPlots.py | 62 ++++++++++---------- qgisplugin/HydroSEDPluginUtils.py | 15 +++-- qgisplugin/HydroSEDPlugin_dockwidget.py | 7 ++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 32 +++++++++- 4 files changed, 75 insertions(+), 41 deletions(-) diff --git a/qgisplugin/HydroSEDPlots.py b/qgisplugin/HydroSEDPlots.py index ac663df..b951db7 100644 --- a/qgisplugin/HydroSEDPlots.py +++ b/qgisplugin/HydroSEDPlots.py @@ -565,34 +565,34 @@ def StreamProfileHipsometric(self, pathFigure, HipsoData, StreamData): plot(fig,filename=pathFigure, auto_open = False) class PlotStorage(): - - def __init__(self): - self.foo = 1 - - def Plot_Storages(self, StoragePath, PathFigure): - '''Hace un plot del storage en el periodo de simulacion''' - #Lee los datos - Data = pd.read_csv(StoragePath, skiprows=4, index_col=6, parse_dates=True) - #Hace la figura - fig = tools.make_subplots(rows=5, cols=1) - for c,key in enumerate(Data.columns.values[1:].tolist()): - trace1 = go.Scatter( - x = Data.index.to_pydatetime(), - y = Data[key].values, - name = key, - line = {'width':3}, - fill='tozeroy', - ) - fig.append_trace(trace1, c+1, 1) - fig['layout'].update(height=600, width=600, - showlegend = False, - yaxis=dict(title='Estado [mm]',), - margin=dict( - l=50, - r=50, - b=50, - t=50, - pad=4 - )) - plot(fig,filename=PathFigure, auto_open = False) - + + def __init__(self): + self.foo = 1 + + def Plot_Storages(self, StoragePath, PathFigure): + '''Hace un plot del storage en el periodo de simulacion''' + #Lee los datos + Data = pd.read_csv(StoragePath, skiprows=4, index_col=6, parse_dates=True) + #Hace la figura + fig = tools.make_subplots(rows=5, cols=1) + for c,key in enumerate(Data.columns.values[1:].tolist()): + trace1 = go.Scatter( + x = Data.index.to_pydatetime(), + y = Data[key].values, + name = key, + line = {'width':3}, + fill='tozeroy', + ) + fig.append_trace(trace1, c+1, 1) + fig['layout'].update(height=600, width=600, + showlegend = False, + yaxis=dict(title='Estado [mm]',), + margin=dict( + l=50, + r=50, + b=50, + t=50, + pad=4 + )) + plot(fig,filename=PathFigure, auto_open = False) + diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 5d04a71..d7e768b 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -530,19 +530,22 @@ def Basin_GeoGetKubota(self): - Hu: almacenamiento capilar maximo [mm] DicBasinNc['h1_max'] - ks: conductividad saturada del suelo [mm/s] DicBasinNc['v_coef'][1]''' #Busca si los parametros de la cuenca estan definidos, si no los reemplaza con constantes para Hu y ks - if u'h1_max' in self.DicBasinNc.keys(): - Hu = np.copy(self.DicBasinNc['h1_max']['var']) + if u'h3_max' in self.DicBasinNc.keys(): + Hg = np.copy(self.DicBasinNc['h3_max']['var']) + Hg[Hg<=0] = Hg.mean() else: - Hu = 100 + Hg = 250 if u'v_coef' in self.DicBasinNc.keys(): ks = np.copy(self.DicBasinNc['v_coef']['var'][1]) else: - ks = 0.003 + ks = 0.00128 self.cuenca.GetGeo_Cell_Basics() So = np.copy(self.cuenca.CellSlope) - Factor = (wmf.cu.dxp**2.)/1000. #[m3/mm] + Factor = (wmf.cu.dxp**2.)/1000./1000. #[m3/mm] #Calculo del coeficiente de kubota - Coef = (ks*So*(wmf.cu.dxp**2.))/(3*(Hu*Factor)**2.) + Coef = (ks*So*(wmf.cu.dxp**2.))/(3*(Hg*Factor)**2.) + Coef[Coef==0] = np.percentile(Coef, 50) + #ksh=(Ks*cuSalgar.CellSlope*(12.7**2.0))/(3*(Hg*0.9/1000.0)**2) Coef[np.where(np.isinf(Coef))]=np.mean(Coef[np.where(np.isfinite(Coef))]) print Coef #Actualiza el diccionario diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 869d9bb..dec177b 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -1074,9 +1074,10 @@ def clickEventAddNewParamSet(): for i in range(1,12): ListaParam.append(getattr(self, 'Param'+str(i)).value()) #Itera en los exponentes - for i in range(1,5): - ListaParam.append(getattr(self, 'ParamExp'+str(i)).value()) + #for i in range(1,5): + # ListaParam.append(getattr(self, 'ParamExp'+str(i)).value()) #Mete el set nuevo de calibracion + ListaParam.extend([0,0,0,0]) self.HSutils.Sim_SaveParameters(PathNC, ParamName, ListaParam) #Actualiza la lista de parametros self.ParamNamesCombo.clear() @@ -1242,7 +1243,7 @@ def __UpdateVar2WMFTable__(varName, varValue): def clickEventSaveAlmacenamientos(): '''Establece la ruta de guardado de los almacenamientos''' #Establece el punto de guardado - setupLineEditButtonOpenBinStoFileDialog(self.Where2SaveStates, QFileDialog) + setupLineEditButtonSaveBinStoFileDialog(self.Where2SaveStates, QFileDialog) Path = self.Where2SaveStates.text().strip() #Hace check del boton self.checkBox_Simu_MeanSpeed.setChecked(True) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index d64a223..639b8be 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -5212,7 +5212,7 @@ 0 - -830 + -137 433 2518 @@ -5878,6 +5878,9 @@ 3 + + 999999.000000000000000 + 1.000000000000000 @@ -5888,6 +5891,9 @@ 3 + + 999999.000000000000000 + 1.000000000000000 @@ -5898,6 +5904,9 @@ 3 + + 999999.000000000000000 + 1.000000000000000 @@ -5908,6 +5917,9 @@ 3 + + 999999.000000000000000 + 1.000000000000000 @@ -5918,6 +5930,9 @@ 3 + + 999999.000000000000000 + 1.000000000000000 @@ -5928,6 +5943,9 @@ 3 + + 999999.000000000000000 + 1.000000000000000 @@ -5960,6 +5978,9 @@ 3 + + 999999.000000000000000 + 1.000000000000000 @@ -5970,6 +5991,9 @@ 3 + + 999999.000000000000000 + 1.000000000000000 @@ -5980,6 +6004,9 @@ 3 + + 999999.000000000000000 + 1.000000000000000 @@ -6012,6 +6039,9 @@ 3 + + 999999.000000000000000 + 1.000000000000000 From b388d752600a38fdb9ea608e67973758ee5666bc Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Thu, 6 Sep 2018 09:50:46 -0500 Subject: [PATCH 139/142] =?UTF-8?q?cambia=20modo=20de=20interfaz=20para=20?= =?UTF-8?q?trazar=20cuencas=20y=20corrientes=20y=20se=20mueve=20el=20gesto?= =?UTF-8?q?r=20de=20variables=20a=20una=20pesta=C3=B1a=20propia,=20se=20ag?= =?UTF-8?q?rega=20posible=20icono=20del=20software?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPluginUtils.py | 1 + qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 3181 +++++++++--------- qgisplugin/icon.png | Bin 1034 -> 2017 bytes wmf/wmf.py | 2 +- 4 files changed, 1541 insertions(+), 1643 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index d7e768b..016766b 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -587,6 +587,7 @@ def Basin_GeoGetRunoff(self, e1, Epsilon): #Calcula Coef = (float(Epsilon)/Man)*(So**2.) Coef[np.where(np.isinf(Coef))]=np.mean(Coef[np.where(np.isfinite(Coef))]) + Coef[Coef<=0] = np.percentile(Coef, 50) print Coef Expo = (2./3.)*e1*np.ones([self.cuenca.ncells]) #Pone en los diccionarios diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 639b8be..e01fcaf 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -7,7 +7,7 @@ 0 0 495 - 936 + 937 @@ -250,7 +250,7 @@ - 4 + 0 @@ -294,7 +294,7 @@ 0 - 0 + -309 443 2018 @@ -317,7 +317,7 @@ 300 - 2000 + 1000 @@ -326,1370 +326,983 @@ 50000 - + 0 0 - 425 - 1151 + 421 + 361 - - - QLayout::SetMinimumSize + + Configuración mapas raster + + + + + 0 + 30 + 421 + 331 + - - - - - - Valor en metros del tamano de una celda en el mapa + + + QLayout::SetMinimumSize + + + + + + + Valor en metros del tamano de una celda en el mapa (establecer antes de cargar MDE). - - - Valor en metros del tamano de una celda en el mapa. - - - Qt::LeftToRight - - - Valor Dxp [m] - - - - - - - - 100 - 0 - - - - - 150 - 16777215 - - - - Establecer el tamaño de pixel del MDE y DIR - - - Establecer el tamaño de pixel del MDE y DIR - - - 10000.000000000000000 - - - 12.699999999999999 - - - - - - - - - <html><head/><body><p>Dirección al MDE (modelo digital de elevación), este se usa como base para un proyecto.</p></body></html> - - - <html><head/><body><p>Dirección al MDE (modelo digital de elevación), este se usa como base para un proyecto.</p></body></html> - - - Mapa MDE: - - - - - - - - - - 100 - 20 - - - - - 290 - 16777215 - - - - Ruta en la que se encuentra el .tif con el MDE - - - Ruta en la que se encuentra el .tif con el MDE - - - true - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - Establecer la ruta en la que se encuentra el .tif con el MDE - - - Establecer la ruta en la que se encuentra el .tif con el MDE - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - 100 - 16777215 - - - - Carga el mapa base MDE para WMF - - - Carga el mapa base MDE para WMF - - - Cargar - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 100 - 16777215 - - - - Visualizar el MDE que ha sido cargado - - - Visualizar el MDE que ha sido cargado - - - Visualizar - - - - - - - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - Mapa DIR: - - - - - - - - - - 290 - 16777215 - - - - Ruta en la que se encuentra el .tif con el DIR - - - Ruta en la que se encuentra el .tif con el DIR - - - true - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - Establecer la ruta en la que se encuentra el .tif con el DIR - - - Establecer la ruta en la que se encuentra el .tif con el DIR - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - 100 - 16777215 - - - - Carga el mapa base DIR para WMF - - - Carga el mapa base DIR para WMF - - - Cargar - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 100 - 16777215 - - - - Visualizar el DIR que ha sido cargado - - - Visualizar el DIR que ha sido cargado - - - Visualizar - - - - - - - - - - - - - - Código EPSG de los mapas DEM y DIR cargados para el proyecto. - - - Valor en metros del tamano de una celda en el mapa. - - - Qt::LeftToRight - - - Proyección EPSG - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 85 - 16777215 - - - - true - - - - - - - - - - - Código EPSG de los mapas DEM y DIR cargados para el proyecto. - - - Valor en metros del tamano de una celda en el mapa. - - - Qt::LeftToRight - - - Valor datos nulos - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 85 - 16777215 - - - - true - - - - - - - - - Qt::Horizontal - - - - - - - - 0 - 100 - - - - Convertir raster a cuenca. - - - - - 10 - 20 - 401 - 71 - + + + Valor en metros del tamano de una celda en el mapa. + + + Qt::LeftToRight + + + 1. Valor Dxp [m] + + + + + + + + 100 + 0 + + + + + 150 + 16777215 + + + + Establecer el tamaño de pixel del MDE y DIR + + + Establecer el tamaño de pixel del MDE y DIR + + + 10000.000000000000000 + + + 12.699999999999999 + + + + + + + + + <html><head/><body><p>Dirección al MDE (modelo digital de elevación), este se usa como base para un proyecto.</p></body></html> + + + <html><head/><body><p>Dirección al MDE (modelo digital de elevación), este se usa como base para un proyecto.</p></body></html> + + + 2. Mapa MDE: - - - - - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - Mapa raster - - - - - - - - 290 - 16777215 - - - - Establecer la ruta del mapa raster a convertir - - - Establecer la ruta del mapa raster a convertir - - - false - - - - - - - - 30 - 0 - - - - - 30 - 16777215 - - - - Establecer la ruta del mapa raster a convertir - - - Establecer la ruta del mapa raster a convertir - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - - - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - Nombre: - - - - - - - - 100 - 16777215 - - - - Nombre con el que será cargado el el mapa a la tabla de variables de WMF - - - Nombre con el que será cargado el el mapa a la tabla de variables de WMF - - - false - - - - - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - Categoría: - - - - - - - Seleccionar la categoría del mapa a convertir - - - Seleccionar la categoría del mapa a convertir - - - - - - - Ejecutar la función para convertir el raster a cuenca - - - Ejecutar la función para convertir el raster a cuenca - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - - - - - - - - - - - Qt::Horizontal - - - - - - - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - Variables WMF - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - true - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Qt::DefaultContextMenu - - - Grafica el histograma de la variable seleccionada - - - Grafica el histograma de la variable seleccionada - - - - - - - :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico - - - - 16 - 16 - - - - - - - - false - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Qt::DefaultContextMenu - - - Convertir variable a red hídrica (promedia celdas del tramo). - - - Convertir variable a red hídrica (promedia celdas del tramo). - - - - - - - :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico - - - - 16 - 16 - - - - - - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) - - - Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - - - - - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Eliminar variable de la tabla - - - Eliminar variable de la tabla - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png - - - - - - - - - - 0 - 200 - - - - QAbstractItemView::MultiSelection - - - QAbstractItemView::SelectRows - - - true - - - - - - - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - Variables NC - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Envar variables del NC al WMF (Si no han sido guardadas en el NC) - - - Envar variables del NC al WMF (Si no han sido guardadas en el NC) - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png:/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png - - - - - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Enviar variables del WMF al NC - - - Enviar variables del WMF al NC - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png:/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png - - - - - - - - - - 0 - 200 - - - - Qt::TargetMoveAction - - - true - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - true - - - - + + + + + + + + 100 + 20 + + + + + 290 + 16777215 + + + + Ruta en la que se encuentra el .tif con el MDE + + + Ruta en la que se encuentra el .tif con el MDE + + + true + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Establecer la ruta en la que se encuentra el .tif con el MDE + + + Establecer la ruta en la que se encuentra el .tif con el MDE + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + 100 + 16777215 + + + + Carga el mapa base MDE para WMF + + + Carga el mapa base MDE para WMF + + + Cargar + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 16777215 + + + + Visualizar el MDE que ha sido cargado + + + Visualizar el MDE que ha sido cargado + + + Visualizar + + + + + + + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + 3. Mapa DIR: + + + + + + + + + + 290 + 16777215 + + + + Ruta en la que se encuentra el .tif con el DIR + + + Ruta en la que se encuentra el .tif con el DIR + + + true + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Establecer la ruta en la que se encuentra el .tif con el DIR + + + Establecer la ruta en la que se encuentra el .tif con el DIR + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + 100 + 16777215 + + + + Carga el mapa base DIR para WMF + + + Carga el mapa base DIR para WMF + + + Cargar + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 16777215 + + + + Visualizar el DIR que ha sido cargado + + + Visualizar el DIR que ha sido cargado + + + Visualizar + + + + + + + + + + + Código EPSG de los mapas DEM y DIR cargados para el proyecto. + + + Valor en metros del tamano de una celda en el mapa. + + + Qt::LeftToRight + + + Propiedades espaciales. + + + + + + + + + + + Código EPSG de los mapas DEM y DIR cargados para el proyecto. + + + Valor en metros del tamano de una celda en el mapa. + + + Qt::LeftToRight + + + Proyección EPSG + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 85 + 16777215 + + + + true + + + + + + + + + + + Código EPSG de los mapas DEM y DIR cargados para el proyecto. + + + Valor en metros del tamano de una celda en el mapa. + + + Qt::LeftToRight + + + Valor datos nulos + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 85 + 16777215 + + + + true + + + + + + + + + + + + 0 + 370 + 419 + 3 + + + + Qt::Horizontal + - + 0 - 1200 + 380 421 - 311 + 391 - Gestión de variables Nc + Trazadores - + 0 20 421 - 184 + 141 - - - + + + + + + + Punto de inicio de trazado de la corriente + + + Punto de inicio de trazado de la corriente + + + 1. Corriente + + + + + + + + + + + Coordenada en Y del punto de inicio. + + + Coordenada en Y del punto de inicio. + + + Latitud: + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + Coordenada en X del punto de inicio. + + + Coordenada en X del punto de inicio. + + + Longitud + + + + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + + + + + Obtener coordenadas dando click sobre el mapa + + + Obtener coordenadas dando click sobre el mapa + + + + + + + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png + + + + + + + Ejecutar la función de trazado de corriente. + + + Ejecutar la función de trazado de corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + + + 120 + 0 + + + + Corriente (.shp) + + + + + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + Seleccionar la ruta donde se va a guardar la corriente. + + + Seleccionar la ruta donde se va a guardar la corriente. + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + + + + + + 0 + 180 + 421 + 171 + + + + + + + + + Punto de inicio de trazado de la corriente + + + Punto de inicio de trazado de la corriente + + + 2. Cuenca + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Umbral mínimo para determinar red de drenaje en la cuenca + + + Umbral mínimo para determinar red de drenaje en la cuenca + + + Umbral + + + + + + + Seleccionar umbral de área acumulada para estimar canales + + + Seleccionar umbral de área acumulada para estimar canales + + + 0 + + + 10.000000000000000 + + + 100000.000000000000000 + + + 100.000000000000000 + + + + + + + + + + + Coordenada en Y del punto de inicio. + + + Coordenada en Y del punto de inicio. + + + Latitud: + + + + + + + + 80 + 16777215 + + + + 6 + + + -200.000000000000000 + + + 200.000000000000000 + + + - + + + Coordenada en X del punto de inicio. + + + Coordenada en X del punto de inicio. + + + Longitud + + + + + - 16777215 - 20 + 80 + 16777215 - - Unidades + + 6 + + + -200.000000000000000 + + + 200.000000000000000 - + - Tipo de conversión usada para agregar + Seleccionar las coordenadas de la salida de la cuenca a trazar - Tipo de conversión usada para agregar + Seleccionar las coordenadas de la salida de la cuenca a trazar + + + + + + + :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png - + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + + + 120 + 0 + + - 16777215 - 20 + 150 + 16777215 - Método + Divisoria (.shp) - - - Metodología para llevar a cabo la conversión de variables - - - Metodología para llevar a cabo la conversión de variables + + + false - - - Qt::Vertical + + + + 30 + 0 + - + - 20 - 40 + 30 + 16777215 - + + Seleccionar la ruta para para guardar el .shp con la divisoria de aguas + + + Seleccionar la ruta para para guardar el .shp con la divisoria de aguas + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + - - - - - 16777215 - 20 - - - - Objetivo - - - - - + + - - - - - - 20 - 16777215 - - - - - - - - - - - - 16777215 - 70 - - - - Selección de la variable del Nc sobre la cual se aplicará la conversión. - - - Selección de la variable del Nc sobre la cual se aplicará la conversión. - - - - - - - - 82 - 16777215 - - - - Capa a ver (o editar) de la variable Nc. - - - Capa a ver (o editar) de la variable Nc. - - - 5 - - - - + + + Red Hídrica (.shp) + + - - - - - - 20 - 16777215 - - - - - - - - - - - - 16777215 - 70 - - - - Nombre de la variable nueva calculada según la expresión - - - Nombre de la variable nueva calculada según la expresión - - - - - - - Categoría de la nueva variable obtenida - - - Categoría de la nueva variable obtenida - - - - + + + Seleccionar la ruta para para guardar el .shp con la red hídrica + + + Seleccionar la ruta para para guardar el .shp con la red hídrica + + + false + + + + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + + + + + - - + + - 16777215 - 20 + 120 + 0 - Expresión + Topologia (.nc) - - - - - - 16777215 - 70 - - - - Evaluar variables en una expresion del tipo A = f(B,C) o f(A,B,C) - - - Evaluar variables en una expresion del tipo A = f(B,C) o f(A,B,C) - - - - + + + Seleccionar la ruta para guardar el .nc con el proyecto de cuenca + + + Seleccionar la ruta para guardar el .nc con el proyecto de cuenca + + + false + + - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 50 - 16777215 - - - - Evaluar la expresión definida. - - - Evaluar la expresión definida. - - - - - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png - - - - + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + + + + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + + - - - - - 16777215 - 20 - - - - Conversión - - - - - - - - 0 - 1150 - 423 - 41 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 50 - 16777215 - - - - Actualizar variables del Nc. - - - - - - - :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg - - - - - - - false - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Qt::DefaultContextMenu - - - Convertir variable a red hídrica (promedia celdas del tramo). - - - Convertir variable a red hídrica (promedia celdas del tramo). - - - - - - - :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico - - - - 16 - 16 - - - - - - - - - 50 - 16777215 - - - - Capa a ver (o editar) de la variable Nc. - - - 5 - - - - - - - true - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Qt::DefaultContextMenu - - - Grafica el histograma de la variable seleccionada - - - Grafica el histograma de la variable seleccionada - - - - - - - :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico - - - - 16 - 16 - - - - - - - - - 50 - 16777215 - - - - Visualizar una variable del Nc - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - - - - - - - - 50 - 0 - - - - - 30 - 16777215 - - - - Eliminar variable de la tabla de variables de NC (Solo si no ha sido actualizada en el NC) - - - Eliminar variable de la tabla de variables de NC (Solo si no ha sido actualizada en el NC) - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png - - - - + + + + 110 + 390 + 59 + 27 + + + + Divisoria + + @@ -1699,7 +1312,7 @@ - Trazadores + Gestor @@ -1767,194 +1380,163 @@ 50000 - + 0 0 - 421 - 231 + 423 + 100 + + + 0 + 100 + + - Corriente + Convertir raster a cuenca. - + - 0 + 10 20 - 421 - 211 + 401 + 71 - + - + - + - Punto de inicio de trazado de la corriente + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Punto de inicio de trazado de la corriente + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Ubicación + Mapa raster + + + + + + + + 290 + 16777215 + + + + Establecer la ruta del mapa raster a convertir + + + Establecer la ruta del mapa raster a convertir + + + false - - - Qt::Horizontal + + + + 30 + 0 + - + - 40 - 20 + 30 + 16777215 - - - - - Obtener coordenadas dando click sobre el mapa + Establecer la ruta del mapa raster a convertir - Obtener coordenadas dando click sobre el mapa + Establecer la ruta del mapa raster a convertir - :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png + :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - + - + - Coordenada en Y del punto de inicio. + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Coordenada en Y del punto de inicio. + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Latitud: + Nombre: - - - 6 - - - -200.000000000000000 - - - 200.000000000000000 + + + + 100 + 16777215 + - - - - - - - - - Coordenada en X del punto de inicio. + Nombre con el que será cargado el el mapa a la tabla de variables de WMF - Coordenada en X del punto de inicio. + Nombre con el que será cargado el el mapa a la tabla de variables de WMF - - Longitud + + false - - - 6 - - - -200.000000000000000 + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - 200.000000000000000 + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - - - - - - - - Qt::Horizontal - - - - - - - Ruta corriente trazada (*.shp): - - - - - - - - - false + + Categoría: - - - - 30 - 0 - - - - - 30 - 16777215 - - + - Seleccionar la ruta donde se va a guardar la corriente. + Seleccionar la categoría del mapa a convertir - Seleccionar la ruta donde se va a guardar la corriente. - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + Seleccionar la categoría del mapa a convertir - + - Ejecutar la función de trazado de corriente. + Ejecutar la función para convertir el raster a cuenca - Ejecutar la función de trazado de corriente. + Ejecutar la función para convertir el raster a cuenca @@ -1970,55 +1552,45 @@ - + 0 - 240 + 100 421 - 16 - - - - Qt::Horizontal - - - - - - 0 - 250 - 421 - 461 + 601 - Cuencas + Gestión de variables - + 0 - 20 + 30 421 - 436 + 571 - - - QLayout::SetMinimumSize - + - + - + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + + + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> + - Ubicación + Variables WMF - + Qt::Horizontal @@ -2031,123 +1603,183 @@ - + + + true + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Qt::DefaultContextMenu + - Seleccionar las coordenadas de la salida de la cuenca a trazar + Grafica el histograma de la variable seleccionada - Seleccionar las coordenadas de la salida de la cuenca a trazar + Grafica el histograma de la variable seleccionada - :/plugins/HydroSEDPlugin/icons/coordCapture.png:/plugins/HydroSEDPlugin/icons/coordCapture.png + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico + + + + 16 + 16 + - - - - - + + + false + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Qt::DefaultContextMenu + - Coordenada en X del punto de inicio. + Convertir variable a red hídrica (promedia celdas del tramo). - Coordenada en X del punto de inicio. + Convertir variable a red hídrica (promedia celdas del tramo). - Latitud: - - - - - - - 6 + - - -200.000000000000000 + + + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico - - 200.000000000000000 + + + 16 + 16 + - - - - - + + + + 50 + 0 + + + + + 30 + 16777215 + + - Coordenada en Y del punto de inicio. + Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) - Coordenada en Y del punto de inicio. + Visualizar variable (es convertida a raster y enviada a /tmp/Hidrosig/) - Longitud + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - - - 6 + + + + 50 + 0 + - - -200.000000000000000 + + + 30 + 16777215 + - - 200.000000000000000 + + Eliminar variable de la tabla + + + Eliminar variable de la tabla + + + + + + + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png - + + + + 0 + 200 + + + + QAbstractItemView::MultiSelection + + + QAbstractItemView::SelectRows + + + true + + + + + - + - Umbral mínimo para determinar red de drenaje en la cuenca + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Umbral mínimo para determinar red de drenaje en la cuenca + <html><head/><body><p>Mapa DIR (direcciones de flujo) obtenido a partir del MDE. Se debe obtener mediante la herramienta <span style=" font-style:italic;">r.watershed</span> de GRASS.</p></body></html> - Umbral - - - - - - - Seleccionar umbral de área acumulada para estimar canales - - - Seleccionar umbral de área acumulada para estimar canales - - - 0 - - - 10.000000000000000 - - - 100000.000000000000000 - - - 100.000000000000000 + Variables NC - + Qt::Horizontal @@ -2160,170 +1792,248 @@ - + + + + 50 + 0 + + + + + 30 + 16777215 + + - Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca + Envar variables del NC al WMF (Si no han sido guardadas en el NC) - Usar la ultima corriente trazada para corregir la coordenada de trazado de cuenca + Envar variables del NC al WMF (Si no han sido guardadas en el NC) - Ultima corriente + + + + + :/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png:/plugins/HydroSEDPlugin/icons/icono-flecha-arriba.png - + + + + 50 + 0 + + + + + 30 + 16777215 + + - Si usar o no usar ultima corriente + Enviar variables del WMF al NC - Si usar o no usar ultima corriente + Enviar variables del WMF al NC - - true + + + :/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png:/plugins/HydroSEDPlugin/icons/icono-flecha-abajo.png - - - Qt::Horizontal + + + + 0 + 200 + - - - - - - Ruta divisoria de aguas (*.shp): + + Qt::TargetMoveAction + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true - + - - - false + + + Qt::Horizontal - - - - - + - 30 - 0 + 40 + 20 + + + + - 30 + 50 16777215 - - Seleccionar la ruta para para guardar el .shp con la divisoria de aguas - - Seleccionar la ruta para para guardar el .shp con la divisoria de aguas + Actualizar variables del Nc. - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + :/plugins/HydroSEDPlugin/icons/save.svg:/plugins/HydroSEDPlugin/icons/save.svg - - - - - - Qt::Horizontal - - - - - - - Ruta red hidrica (*.shp): - - - - - - + false + + + 50 + 0 + + + + + 30 + 16777215 + + + + Qt::DefaultContextMenu + - Obtiene automaticamente los nodos topograficos. + Convertir variable a red hídrica (promedia celdas del tramo). - Obtiene automaticamente los nodos topograficos. + Convertir variable a red hídrica (promedia celdas del tramo). - Topo Nodes + + + + + :/plugins/HydroSEDPlugin/icons/RedHidrica.ico:/plugins/HydroSEDPlugin/icons/RedHidrica.ico + + + + 16 + 16 + - - - false + + + + 50 + 16777215 + - - Obtiene parametros geomorfologicos de la cuenca. + + Capa a ver (o editar) de la variable Nc. - - GetGeo + + 5 - + - false + true + + + + 50 + 0 + + + + + 30 + 16777215 + + + + Qt::DefaultContextMenu - Obtiene el ancho del canal en cada tramo. + Grafica el histograma de la variable seleccionada + + + Grafica el histograma de la variable seleccionada - Ancho canal + + + + + :/plugins/HydroSEDPlugin/icons/histograma.ico:/plugins/HydroSEDPlugin/icons/histograma.ico + + + + 16 + 16 + - - - - - - - Seleccionar la ruta para para guardar el .shp con la red hídrica + + + + 50 + 16777215 + - Seleccionar la ruta para para guardar el .shp con la red hídrica + Visualizar una variable del Nc - - false + + + + + + :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - + - 30 + 50 0 @@ -2333,128 +2043,315 @@ 16777215 + + Eliminar variable de la tabla de variables de NC (Solo si no ha sido actualizada en el NC) + + + Eliminar variable de la tabla de variables de NC (Solo si no ha sido actualizada en el NC) + - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + :/plugins/HydroSEDPlugin/icons/icono-borrar.png:/plugins/HydroSEDPlugin/icons/icono-borrar.png - - - - Qt::Horizontal - - - - - - - Path Salida (*.nc): - - - - - - - - - Seleccionar la ruta para guardar el .nc con el proyecto de cuenca - - - Seleccionar la ruta para guardar el .nc con el proyecto de cuenca - - - false - - - + + + + + + + 0 + 720 + 421 + 311 + + + + Gestión de variables Nc + + + + + 0 + 20 + 421 + 184 + + + + + - - - - 30 - 0 - - + - 30 - 16777215 + 16777215 + 20 - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + Unidades - - - - - + - Nombre interno que identifica a la cuenca trazada (Cuenca) + Tipo de conversión usada para agregar + + + Tipo de conversión usada para agregar + + + + + + + + 16777215 + 20 + - Nombre: + Método - + - Asignar un nombre a la cuenca trazada + Metodología para llevar a cabo la conversión de variables - Asignar un nombre a la cuenca trazada - - - Cuenca - - - false + Metodología para llevar a cabo la conversión de variables - + - Qt::Horizontal + Qt::Vertical - 40 - 20 + 20 + 40 + + + + + + + 16777215 + 20 + + + + Objetivo + + + + + - - - + + + + + + 20 + 16777215 + + + + + + + + + + + + 16777215 + 70 + + + + Selección de la variable del Nc sobre la cual se aplicará la conversión. + + + Selección de la variable del Nc sobre la cual se aplicará la conversión. + + + + + + + + 82 + 16777215 + + + + Capa a ver (o editar) de la variable Nc. + + + Capa a ver (o editar) de la variable Nc. + + + 5 + + + + + + + + + + + + 20 + 16777215 + + + + + + + + + + + + 16777215 + 70 + + + + Nombre de la variable nueva calculada según la expresión + + + Nombre de la variable nueva calculada según la expresión + + + + + + + Categoría de la nueva variable obtenida + + + Categoría de la nueva variable obtenida + + + + + + + + + + 16777215 + 20 + - - - :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + Expresión + + + + + + + 16777215 + 70 + + + + Evaluar variables en una expresion del tipo A = f(B,C) o f(A,B,C) + + + Evaluar variables en una expresion del tipo A = f(B,C) o f(A,B,C) + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 50 + 16777215 + + + + Evaluar la expresión definida. + + + Evaluar la expresión definida. + + + + + + + :/plugins/HydroSEDPlugin/icons/play.png:/plugins/HydroSEDPlugin/icons/play.png + + + + + + + + + + 16777215 + 20 + + + + Conversión + + + + groupBox_21 + groupBox_3 + groupBox_11 @@ -5212,7 +5109,7 @@ 0 - -137 + -914 433 2518 diff --git a/qgisplugin/icon.png b/qgisplugin/icon.png index f696c00303219cfcc2f0d57608d04e298fbf56c3..6cea22352322ed8f13833fdd1726bad5ba2e51d8 100644 GIT binary patch literal 2017 zcmV<72Oju|P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D2X;wBK~!i%?OA(l zQ&ku*Dv0`r_%<=VA2Eb%AjB1%cJ1hTZ#RW$I|P9#;JWc}A-wj071$WA9T}4NAi&DD zc29N6Q(i*bO<)=Fi2OkiUkC={bZoudhGWO?yZt(E+dIc*mn>wzWhamw_ypYP-;+c6ch)cF!zrY1duUYw#his`*|JS|ewKpI}Tgtk8#(OT3R!x4{RP z>36}EuE`nTC%n@Ezt)7!>`v-7xFE&`&bEyB07BfTOFfa)tzWRX`BfH|{;Ji;RyUt%b?cec#dla;`Y5UnAJk>SYv3-Ovce@qLu2gT zm#AB>SYgo3%b3QsX3ybSeieV+;*K{`Q}_V_bAtuT5e&T)TXOY2>eeH&3~?`J8g!kR zMvft~lDVI$X<(qTv5_E9HpK=LjMzxsWMMX&Z^<<3zV(YoW*E2=)I4y2tduP$IFz1i z+S0Zssaps#4RJH1;*nWK-P_bWa8TJjW90>h5>{a)bqhi8>;oHdRj7I3fIG09SUEyK zH&C|#WF>LRAn`2Iz^SNtV1XN!oY+{II@~{~TL3bQx{@FR8mTD&@4FMizstv#d&UI| z)s_n^ufCnFbhZc7V@joN-AG9pKO8cTS870(fuBvyA{bK)gLFE%y4o22!y}wl*Gfeq z)AqKpjSU?v>qw9RcF#HL)(tcuBZ(9I;xi1o-_1tj2x=Bl=#Eb@HztJtXaXnIhwwxy z6&YVGunosLSP>X7^;2(v0YC?J4Zs>JSDBp*Ge4bcfz%nWaar7YQ-L$#1uBLQa2FT> z;tvD~WXr#97iT~HKwCgPGPcZ zZLq+k&%L5}%h7hmRR+#Jyx*a+{WXe)=mxq57|;o4pWo2esaj#J*FFdbxrPt+aJN%c zco6Mqz6WN0zf>F&vknF>8j!p*boL=ucGD06D0FktIQ!r#wNxbn$~9oXOe%&4u@&vl zVIYQx1J2svoBbTfJhCaY%rl3E2>`grVxIy08mdwh)bZ0SF8-96g>fT;fYplkV;OPC zHE!SRPpb_HTy&q#=&F_nXs7^y0S=!5@rhVAA6AV7@jqEzoI!knkhX2YQ}oz(fQYI8 zbrX9XvJHw~4MxbdLtiHi6$0@66QTii+|yKE0_BTf$Zg^afE1fDHD&YoyQ$bW#5!6h zV*ttv^Kss8p8=*lGQN+rdzRC1ArNm|F1`f=xajbdQBZEen;11KOvTEDDcdK$LdCwp zcbONi$cmD1(LUeCHG7A=0eB6iAr)!G6DJv~M~fR3W*Q3MvtrrJFT}F7UjI0jO}40* z)Z(bE_}nkR(&uywf#bm{2+*v

ATLoj0YY71%C3LPILR74Ahbwo zl+P5pc`dC#aY0@D%f4scLhpQRvMGzj4*iAn;*PV6A{TpHCRrn1rLKL0x?ET!6|xeJ$7qDv1-mT-wY04_f)QuqD!h;4xG?(%(16@SaXV0W zfir%SXaMZKF#AQ=2EX%-*2qo3ouZij0D}+W;0M15eU-opj&_JfpwH`q4s5*<#`-nJ z;Z;EloJNtWztT2{!kzjGp8l{!()ig+ma#@OS+Yu8wBkYqUf(8mtkQ%x1;^ zKM%of{1)t{U49W$YP>AJ-nSBXaly=l*GQ?*9B?yiFMy-Yi$VLId9UWWp729R@5R3I8A9!)bUZ^9$g?eU={bWhNvZ=A;6(6#`pw@Za`K z*Z}dqAbkg!SaX^!+n3#p2IL;pUPc3^7e#u}0D~oB5q&;9(3A;@(!BwR8(bc^63)1^ z-p}bU`}yDaj6kk9B>&zUpEa`d-8miewkUDtMS=kweL8$lIa;2F)i@(3q9t2I({4iWxT0-$e5vF8&S{5H{MIn5L}Bp|*SbcM`o3Xv$hf z!}W5ntbi~QV($WcXC3}ykv=_yAq?T>fkN>QO%&g|^7&rk00000NkvXXu0mjf5Y@BA literal 1034 zcmV+l1oiugP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXD@ z77;9+NQ1io00W9iL_t(Y$E}r1Xk1ko$A9PCduQg(OlBrY(9Ks7iMEcmzAKc3;VzZCAM*45PN_;^e6>czpi>a)k;jWgn$XwX#(ffW0x= z+8`f&KFz}YS*DXYlF=gSn-KxzBG6N#o}Sbu5ylW$ifX;y!Gxcoccb7X?l*&Cg%BLp+upi(AsPbFBN>WXDC?; z&(>7p1`~%XZ)m0`uQ4(<$FhGH?|poXGiT2da3o4;)@nx9({OUBf@d^Etti_X6*QRt zM(yu64Vk}6JTN%G$V;!1TAbqGBW-lFx`bT|DMfv_l!BJF5c985o@kjA(}*tNFK{QCU>`#$u@1vR=}>qa5@&kCuGhvP`xkhN}@YN}=O zQj$Y2Uc!t58W8mdtiyG1gOY%=`Oqf#kFzPpKDdk-HFaxyemu%W41P&5^jJIh_B4=) zIRqS8AO73bJYStlGW|rdy4U))V9(wb+>k{~N-CaW{!Ycn!A{zChUn=E(`kQe>l33Is7?7;qutHE1STpm8YoYyRmhySVLwneD zILtlW(W=jJRx_{aH|L?0Ar`gK1}rHy^>Uk*mB7T>op^&oQzC$62^{-|!2sta za1=;y9wJfWb=kJ1ful09`}7PjxUqtpunAx=vHSGQzo6-Eu3FzqfdBvi07*qoM6N<$ Ef=x2zx&QzG diff --git a/wmf/wmf.py b/wmf/wmf.py index 4da2c1f..a4feb97 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -4228,7 +4228,7 @@ def run_shia(self,Calibracion, if models.save_storage == 1: rutaStorageHdr = __Add_hdr_bin_2route__(ruta_storage) #Caso en el que se registra el alm medio - if models.show_storage == 1: + if models.show_storage == 1: __Save_storage_hdr__(ruta_sto_hdr,rain_ruteHdr,N_intervals, start_point,self,Mean_Storage = np.copy(models.mean_storage)) #Caso en el que no hay alm medio para cada uno de los From 46ce51c15876d28bc0b03ce84c41f56fe6b34253 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Fri, 7 Sep 2018 16:22:47 -0500 Subject: [PATCH 140/142] se corrige error en el balance de largo plazo, se habilita boton para pasar variable a red hidrica en Nc y WMF, en WMF todavia no funciona por un problea aun no explorado --- qgisplugin/HydroSEDPluginUtils.py | 31 +- qgisplugin/HydroSEDPlugin_dockwidget.py | 58 ++- qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 397 +++++++------------ qgisplugin/icons/reload.png | Bin 0 -> 637 bytes qgisplugin/icons/table.png | Bin 0 -> 531 bytes 5 files changed, 207 insertions(+), 279 deletions(-) create mode 100644 qgisplugin/icons/reload.png create mode 100644 qgisplugin/icons/table.png diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 016766b..560f9a7 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -142,17 +142,33 @@ def BasinNc2Network(self,pathNetwork, names): umbral = self.cuenca.umbral, EPSG = int(self.cuenca.epsg), Dict = DicVar) + + def BasinWMF2Network(self,pathNetwork, names): + '''Guarda una red hidrica con las variables seleccionadas del diccionario NC''' + # genera el diccionario de las variables a guardar + DicVar = {} + for n in names: + DicVar.update({n.encode():self.DicBasinWMF[n]['var'].data}) + print DicVar + #Guarda la red hidrica + self.cuenca.Save_Net2Map(pathNetwork, wmf.cu.dxp, + umbral = self.cuenca.umbral, + EPSG = int(self.cuenca.epsg), + Dict = DicVar) - def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed): + def hidologia_balance(self, dxp, umbral, PathRain, PathETR): #Se fija si la lluvia es un path o un valor try: Rain = float(PathRain) except: - Rain, prop, epsg = wmf.read_map_raster(PathRain) - if epsg == self.cuenca.epsg: - Rain = self.cuenca.Transform_Map2Basin(Rain, prop) - else: - return 1, 1 + #Trata de sacarlo del WMF + try: + Rain = np.copy(self.DicBasinWMF[PathRain]['var']) + except: + try: + Rain = np.copy(self.DicBasinNc[PathRain]['var']) + except: + return 1 #Realiza el balance self.cuenca.GetQ_Balance(Rain, Tipo_ETR = PathETR) #Actualiza el diccionario de WMF @@ -184,9 +200,6 @@ def hidologia_balance(self, dxp, umbral, PathRain, PathETR, PathQmed): 'categoria': 'Hidro', 'var': Runoff, 'saved':False}}) - # Guarda el resultado - if len(PathQmed)>2: - self.cuenca.Save_Net2Map(PathQmed, dxp, umbral, qmed = self.cuenca.CellQmed) #Retorna el resultado a la salida return 0,self.cuenca.CellQmed[-1] diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 795c4a9..5af8b9c 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -19,6 +19,7 @@ * (at your option) any later version. * * * ***************************************************************************/ + comando para cargar todos los iconos: pyrcc4 -o resources.py resources.qrc """ import os @@ -70,7 +71,8 @@ def __init__(self, iface = None, parent=None): self.TablaFila_WMF = 0 self.TablaFila_NC = 0 - self.botonClicked = False + self.botonClicked_NC = False + self.botonClicked_WMF = False self.segundaCarga = False self.Segunda_carga_Qobs = False self.Segunda_carga_Qobs_Sed = False @@ -175,7 +177,7 @@ def clickEventSelectShape2SaveNc(): def SelectNetworkshapeDialog (fileDialogHolder): '''Hace que cuando se busquen shapes solo se encuetren formatos vectoriales''' - lineEditHolder = fileDialogHolder.getOpenFileName (QtGui.QDialog (), "Guardar en capa vectorial...", "*", "Shapefiles (*.shp);;") + lineEditHolder = fileDialogHolder.getSaveFileName (QtGui.QDialog (), "Guardar en capa vectorial...", "*", "Shapefiles (*.shp);;") return lineEditHolder #if ((os.path.exists (lineEditHolder.text ().strip ())) and (not (self.iface is None))): # self.iface.addVectorLayer (lineEditHolder.text ().strip (), os.path.basename (lineEditHolder.text ()).strip (), "ogr") @@ -252,25 +254,47 @@ def clickEventBasinLoadNetwork(): def clickEventBasinVarNC2Network(): '''Convierte un conjunto de variables a una red hidrica de la cuenca''' - if self.botonClicked is False: + if self.botonClicked_NC is False: #Hace que la seleccion sea multiple en la columna de NC self.Tabla_Prop_NC.setSelectionMode(QAbstractItemView.MultiSelection) self.ruta2Network = '' #imprime las variables seleccionadas self.Vars2Network = [] - self.botonClicked = True - self.ButtonVar2Net_NC.setText('Variables') + self.botonClicked_NC = True return - elif self.botonClicked is True: + elif self.botonClicked_NC is True: for i in self.Tabla_Prop_NC.selectedItems()[::4]: self.Vars2Network.append(i.text()) #En el segundo click selecciona el archivo y ejecuta self.ruta2Network = SelectNetworkshapeDialog(QFileDialog) self.Tabla_Prop_NC.setSelectionMode(QAbstractItemView.SingleSelection) - self.botonClicked = False + self.botonClicked_NC = False #Guardado de las variables en formato red hidrica self.HSutils.BasinNc2Network(self.ruta2Network,self.Vars2Network) - self.ButtonVar2Net_NC.setText('Var2Net') + self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'Las variables seleccionadas han sido convertidas a la red hidrica', + level=QgsMessageBar.INFO, duration=3) + + def clickEventBasinVarWMF2Network(): + '''Convierte un conjunto de variables a una red hidrica de la cuenca''' + if self.botonClicked_WMF is False: + #Hace que la seleccion sea multiple en la columna de NC + self.Tabla_Prop_WMF.setSelectionMode(QAbstractItemView.MultiSelection) + self.ruta2Network = '' + #imprime las variables seleccionadas + self.Vars2Network = [] + self.botonClicked_WMF = True + return + elif self.botonClicked_WMF is True: + for i in self.Tabla_Prop_WMF.selectedItems()[::4]: + self.Vars2Network.append(i.text()) + #En el segundo click selecciona el archivo y ejecuta + self.ruta2Network = SelectNetworkshapeDialog(QFileDialog) + self.Tabla_Prop_WMF.setSelectionMode(QAbstractItemView.SingleSelection) + self.botonClicked_WMF = False + #Guardado de las variables en formato red hidrica + self.HSutils.BasinWMF2Network(self.ruta2Network,self.Vars2Network) + self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'Las variables seleccionadas han sido convertidas a la red hidrica', + level=QgsMessageBar.INFO, duration=3) #Botones para variables de entrada self.botonSelectorProyectBasin.clicked.connect(clickEventSelectorBasin) @@ -280,6 +304,7 @@ def clickEventBasinVarNC2Network(): self.Boton_verRedHidrica.clicked.connect(clickEventBasinLoadNetwork) #boton para convertir variables a red hidrica self.ButtonVar2Net_NC.clicked.connect(clickEventBasinVarNC2Network) + self.ButtonVar2Net_WMF.clicked.connect(clickEventBasinVarWMF2Network) def setupGeomorfologia(self): @@ -589,32 +614,23 @@ def hadleClickEventEjecutarBalance(): Retorno, QSalida = self.HSutils.hidologia_balance(self.spinBox_dxPlano.value(), self.spinBoxUmbralRed.value(), self.PathInHydro_Rain.text(), - TipoETR, - self.PathOutHydro_Qmed.text()) + TipoETR) #Pone el valor de cadual medio en el cuadro textoCaudal = '%.3f' % QSalida self.ShowResultQmed.setText(textoCaudal) #Mensaje de exito if Retorno == 0: - self.iface.messageBar().pushInfo(u'HidroSIG:',u'Balance realizado: variables Caudal, ETR y Runoff cargadas a Tabla de propiedades WMF.') + self.iface.messageBar().pushMessage(u'HidroSIG:', + u'Balance realizado: variables Caudal, ETR y Runoff cargadas a Tabla de propiedades WMF.', + level=QgsMessageBar.INFO, duration=3) else: self.iface.messageBar().pushMessage (u'Hydro-SIG:', u'No se ha logrado realizar el balance hidrológico en la cuenca', level=QgsMessageBar.WARNING, duration=3) - #Habilita botones de visualizacion de variables - if len(self.PathOutHydro_Qmed.text()) > 2: - self.Button_HidroViewQmed.setEnabled(True) #Actualiza la tabla de variables temporales y actualiza comboBox de gomorfo for k in ['Caudal','ETR','Runoff']: self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[k],k, self.Tabla_Prop_WMF) - #Botones para variables de entrada - self.Boton_HidroLoadRain.clicked.connect(clickEventSelectorRaster) - #Botones para variables de salida - self.Button_HidroSaveQmed.clicked.connect(clickEventOutQmed) - #Botones para visualizar variables - self.Button_HidroViewRain.clicked.connect(clickEventViewRainfall) - self.Button_HidroViewQmed.clicked.connect(clickEventViewQmedNetwork) #Botones para ejecutar self.Butto_Ejec_HidroBalance.clicked.connect(hadleClickEventEjecutarBalance) diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index e01fcaf..9616ecb 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -250,7 +250,7 @@ - 0 + 3 @@ -294,7 +294,7 @@ 0 - -309 + -329 443 2018 @@ -314,6 +314,12 @@ + + + 1 + 0 + + 300 @@ -780,7 +786,7 @@ 0 380 421 - 391 + 321 @@ -792,7 +798,7 @@ 0 20 421 - 141 + 101 @@ -830,6 +836,12 @@ + + + 80 + 16777215 + + 6 @@ -856,6 +868,12 @@ + + + 80 + 16777215 + + 6 @@ -869,6 +887,12 @@ + + + 40 + 16777215 + + Obtener coordenadas dando click sobre el mapa @@ -886,6 +910,12 @@ + + + 40 + 16777215 + + Ejecutar la función de trazado de corriente. @@ -962,7 +992,7 @@ 0 - 180 + 140 421 171 @@ -1101,6 +1131,12 @@ + + + 40 + 16777215 + + Seleccionar las coordenadas de la salida de la cuenca a trazar @@ -1118,6 +1154,12 @@ + + + 40 + 16777215 + + @@ -1368,10 +1410,16 @@ + + + 0 + 0 + + 250 - 2000 + 1500 @@ -1646,7 +1694,7 @@ - false + true @@ -1914,7 +1962,7 @@ - false + true @@ -2400,7 +2448,7 @@ 0 - 0 + -74 443 1918 @@ -2744,8 +2792,14 @@ - - :/plugins/HydroSEDPlugin/icons/update.png:/plugins/HydroSEDPlugin/icons/update.png + + :/plugins/HydroSEDPlugin/icons/reload.png:/plugins/HydroSEDPlugin/icons/reload.png + + + + 20 + 20 + @@ -2794,8 +2848,14 @@ - - :/plugins/HydroSEDPlugin/icons/update.png:/plugins/HydroSEDPlugin/icons/update.png + + :/plugins/HydroSEDPlugin/icons/reload.png:/plugins/HydroSEDPlugin/icons/reload.png + + + + 20 + 20 + @@ -3229,7 +3289,7 @@ 0 - 0 + -615 443 1918 @@ -3279,7 +3339,7 @@ 0 30 411 - 203 + 161 @@ -3339,49 +3399,12 @@ - - false - - - - - - Establecer ruta donde se aloja el mapa de precipitación. - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png + Nombre del mapa con precipitacion media cargado en WMF o NC - - - - - + false - - - 40 - 16777215 - - - - Visualizar shp con el caudal calculado por tramos. - - - Visualizar shp con el caudal calculado por tramos. - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - @@ -3487,83 +3510,6 @@ - - - - - - El valor del caudal calculado en cada tramo hidrológico. - - - El valor del caudal calculado en cada tramo hidrológico. - - - Qmed*[m3/s] - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - Ruta de guardado - - - false - - - - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - false - - - - 40 - 16777215 - - - - Visualizar shp con el caudal calculado por tramos. - - - Visualizar shp con el caudal calculado por tramos. - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - - - - - @@ -4245,13 +4191,13 @@ 0 - 1080 + 1030 421 - 271 + 241 - Máximos regionalización + Extremos regionalización @@ -4259,7 +4205,7 @@ 0 30 411 - 236 + 226 @@ -4294,7 +4240,7 @@ - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + Nombre de la capa de WMF o NC que contenga el caudal medio estimado para la cuenca. Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] @@ -4318,7 +4264,10 @@ - + + + Colocar nombre d ela cpaa WMF o NC con el caudal medio + false @@ -4330,10 +4279,14 @@ - - + + + + Coeficiente caudal medio extremo (Poveda, 2007) + + - + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] @@ -4346,10 +4299,14 @@ - - + + + + Coeficiente desviacion caudal extremo (Poveda, 2007) + + - + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] @@ -4362,7 +4319,7 @@ - + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] @@ -4375,10 +4332,14 @@ - - + + + + Exponente caudal medio extremo (Poveda, 2007) + + - + Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] @@ -4391,32 +4352,47 @@ - - + + + + Exponente desviacion caudal extremo (Poveda, 2007) + + - - - Qt::Horizontal + + + Seleccionar calcular caudales máximos - - - 10 - 20 - + + Máximo - + - - + + - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + Calcular caudales mínimos - - Mapa raster (o valor) con la precipitación anual en la cuenca [mm/año] + + Mínimo + + + + + + + Periodo de retorno - + Tr + + + + + + + Periodo de retorno en años para la estimación de extremos @@ -4424,9 +4400,6 @@ - - - @@ -4450,83 +4423,6 @@ - - - - - - El valor del caudal calculado en cada tramo hidrológico. - - - El valor del caudal calculado en cada tramo hidrológico. - - - Qmax*[m3/s] - - - - - - - Qt::Horizontal - - - - 10 - 20 - - - - - - - - Ruta de guardado - - - false - - - - - - - - - - - :/plugins/HydroSEDPlugin/icons/folder.png:/plugins/HydroSEDPlugin/icons/folder.png - - - - - - - false - - - - 40 - 16777215 - - - - Visualizar shp con el caudal calculado por tramos. - - - Visualizar shp con el caudal calculado por tramos. - - - - - - - :/plugins/HydroSEDPlugin/icons/icono-ver.png:/plugins/HydroSEDPlugin/icons/icono-ver.png - - - - - @@ -4544,7 +4440,7 @@ El valor del caudal calculado solo a la salida de la cuenca. - Qmax salida [m3/s]: + Qextremo salida [m3/s]: @@ -4562,16 +4458,19 @@ - + + + Valor del caudal extremo calculado a la salida. + true - + - Ejecuta el balance de largo plazo con los parametros dados. + Ejecutar cálculo de caudales extremos resultado cargado a WMF como QmaxTr o QminTr donde Tr es el periodo de retorno seleccionado Ejecuta el balance de largo plazo con los parametros dados. @@ -4594,7 +4493,7 @@ 0 - 1060 + 1010 411 20 diff --git a/qgisplugin/icons/reload.png b/qgisplugin/icons/reload.png new file mode 100644 index 0000000000000000000000000000000000000000..f83de6df0cbcac8145e81f7444a378fe045673f3 GIT binary patch literal 637 zcmV-@0)qXCP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0uo6?K~zXf?bb_( zPGKC!@s}xuu)tQrWF>`cCG1cZGyP0xXT1}J{xh-6B zzkI)V>gnnKocEkTHuI}bGw(Ui<-F(opXa>2$#lrn-+%vkR^ce_;t9UtJs#l-MlcV5 zEh}&n-&=TxBbbdp%07HSG)WWh!ZJ)KXAlkA)*Gxvr}#~y!IH0d1qYALC(p11t+Eoe z+j|?EF%u~Z;e|d&)MpG+&^I>_4dBIC*(ny#tY82B%v{upa4Q}M}# z6q{gX;2z3;9&3zCq3rZAI975^?}S+nYoKhi0M*<<-q>}y9(%K6HJ>pEa~4|hoKy!;%~j-$br8lS<0B}~myV;HR2xyv zFv<=uF&}0ZtlqNCr{GxbEvBOyC$O5!j<=9HF2x~S#(C_3YcyXGrHkmBXcN(W)LwP2 zh|`GrS@Ee(8si=u6`5Ra*RUH~Fa&>>@}i+y6_?g&?#&10?~kNIO&9c z0{LuwpGE`M_)M*n&fm0*FY#^Yw}H4CE}-=XP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0jNntK~zXf-PJ!x zl~DkO@muLqX0=O%qYwlxL5^XnLd`2sp&ehtGoRdgf9SyaaFkwp(IJTr-}~Xbc^x}KS!nqFkg#ILoi>8OrvNN)z&UL!FF)T%srZ!J45pyk?AYU zk0R498b$7rr>hrtkb9I*?omFuNBR8MsmteFin{Oy-W1h}zN0^sA9U?AFQ@BWWEzLL zUm){IG>U3#7ahZ8E4&5Fe@3QFn7aa*e}K7LkogW8MSkE4obEkbj8o@ryNr2MD>}qL zC?D`IJM(gPZA7MWy4EAp6dFafwTph?Rd5N+y}L5^b~gVOnOsWqFOkU^Hj3OM|1&

3zw}JgSmT=`2@_jBGWX?-$tfqXcu|?_@bugXg$S?ikMBS?=MMa VuJx7?ZQTF>002ovPDHLkV1mCD>4E?N literal 0 HcmV?d00001 From 917b859eba148d9301fc10e67c65c644fcab2b16 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 10 Sep 2018 10:10:47 -0500 Subject: [PATCH 141/142] se corrige error para pasar variables de WMF a red hidrica --- qgisplugin/HydroSEDPluginUtils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index 560f9a7..a85638f 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -148,7 +148,7 @@ def BasinWMF2Network(self,pathNetwork, names): # genera el diccionario de las variables a guardar DicVar = {} for n in names: - DicVar.update({n.encode():self.DicBasinWMF[n]['var'].data}) + DicVar.update({n.encode():self.DicBasinWMF[n]['var']}) print DicVar #Guarda la red hidrica self.cuenca.Save_Net2Map(pathNetwork, wmf.cu.dxp, From 0b7b45a87d263f743a7c165584e3184485267f97 Mon Sep 17 00:00:00 2001 From: Nicolas998 Date: Mon, 10 Sep 2018 18:17:15 -0500 Subject: [PATCH 142/142] =?UTF-8?q?en=20desarrollo=20herramienta=20para=20?= =?UTF-8?q?obtener=20caudales=20extremos,=20falta=20que=20funcione=20al=20?= =?UTF-8?q?parecer=20tyiene=20problemas=20pasando=20el=20nombre=20de=20la?= =?UTF-8?q?=20funci=C3=B3n=20de=20distribuci=C3=B3n,=20hay=20problemas=20c?= =?UTF-8?q?on=20el=20trazador=20de=20cuencas=20cuando=20se=20va=20a=20guar?= =?UTF-8?q?dar=20un=20.nc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qgisplugin/HydroSEDPluginUtils.py | 33 ++++++++ qgisplugin/HydroSEDPlugin_dockwidget.py | 57 +++++++++++++ qgisplugin/HydroSEDPlugin_dockwidget_base.ui | 85 +++++--------------- wmf/wmf.py | 4 +- 4 files changed, 113 insertions(+), 66 deletions(-) diff --git a/qgisplugin/HydroSEDPluginUtils.py b/qgisplugin/HydroSEDPluginUtils.py index a85638f..f46ec14 100644 --- a/qgisplugin/HydroSEDPluginUtils.py +++ b/qgisplugin/HydroSEDPluginUtils.py @@ -203,6 +203,39 @@ def hidologia_balance(self, dxp, umbral, PathRain, PathETR): #Retorna el resultado a la salida return 0,self.cuenca.CellQmed[-1] + def hidrologia_extremos_regional(self, Qmed, CoefExpoList, Pdf2Use, MaxorMin): + '''Obtiene caudales maximos o minimos para los periodos de retorno + de 2.33, 5, 10, 25, 50, 100, 500''' + #Organiza cioeficientes y expo + Coef = [CoefExpoList[i] for i in [0, 2]] + Expo = [CoefExpoList[i] for i in [1, 3]] + #Trata de hacerlo + #try: + print Coef + print Expo + print Pdf2Use + #Hace de acuerdo a una cosa o la otra + if MaxorMin == 'QMax': + Qext = self.cuenca.GetQ_Max(Qmed, Coef, Expo, Dist = Pdf2Use) + elif MaxorMin == 'QMin': + Qext = self.cuenca.GetQ_Min(Qmed, Coef, Expo, Dist = Pdf2Use) + #Actualiza el diccionario + Nombre = MaxorMin + #Actualiza diccionarios + for Tr,Q in zip([2.33, 5, 10, 25, 50, 100], Qext): + nombre2 = Nombre + '_' + str(Tr) + self.DicBasinWMF.update({nombre2:{'nombre':nombre2, + 'tipo':'float32', + 'shape':Q.shape, + 'raster':True, + 'basica': False, + 'categoria': 'Hidro', + 'var': np.copy(Q), + 'saved':False}}) + # return 0 + #except: + # return 1 + def Basin_Update(self, PathNC): '''Actualiza el archivo nc de la cuenca con las variables agregadas o borradas de la misma''' #Lectura del archivo diff --git a/qgisplugin/HydroSEDPlugin_dockwidget.py b/qgisplugin/HydroSEDPlugin_dockwidget.py index 5af8b9c..0e91c0a 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget.py +++ b/qgisplugin/HydroSEDPlugin_dockwidget.py @@ -568,6 +568,12 @@ def clickEventAcumVar(): def setupHidro_Balance(self): + #Inicia Combo box de funciones de distribucion + self.ComboQmaxPDF.addItem('gumbel') + self.ComboQmaxPDF.addItem('lognorm') + self.ComboQmaxPDF.setCurrentIndex(self.ComboQmaxPDF.findData('Gumbel')) + + def setupLineEditButtonOpenRasterFileDialog (lineEditHolder, fileDialogHolder): '''Hace que solo se busquen formatos aceptados por GDAL''' lineEditHolder.setText (fileDialogHolder.getOpenFileName (QtGui.QDialog (), 'Open File',"", GdalTools_utils.FileFilter.allRastersFilter (), @@ -631,8 +637,59 @@ def hadleClickEventEjecutarBalance(): for k in ['Caudal','ETR','Runoff']: self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[k],k, self.Tabla_Prop_WMF) + def handleClickEventExtremeByRegionalization(): + '''Calcula caudales extremos a partir de regionalizacion''' + #Obtiene el caudal medio + NombreQmed = self.PathInHydro_Qmed4Qmax.text().strip() + try: + Qmed = np.copy(self.HSutils.DicBasinWMF[NombreQmed]['var']) + except: + try: + Qmed = np.copy(self.HSutils.DicBasinNc[NombreQmed]['var']) + except: + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + u'No se encuentra la variable '+NombreQmed+' en WMF o NC, no es posible estimar Qmax o Qmin', + level=QgsMessageBar.ERROR, duration=3) + return + #Si es maximo establece valores por defecto de coeifciente y exponentes + if self.RadButton_maximos.isChecked(): + CoefExpoList = [6.71, 0.82, 3.29, 0.64] + StrVal = ['%.4f' % i for i in CoefExpoList] + isMaxorMin = 'QMax' + elif self.RadButton_minimos.isChecked(): + CoefExpoList = [0.4168, 1.058, 0.2, 0.98] + StrVal = ['%.4f' % i for i in CoefExpoList] + isMaxorMin = 'QMin' + #Valores por defecto + for i in range(1,5): + val = getattr(self, 'SpinBox_C'+str(i)).value() + if val == 0.0: + comando = 'self.SpinBox_C'+str(i)+'.setValue('+StrVal[i-1]+')' + eval(comando) + #Obtiene la funcion de distribucion + Pdf2Use = self.ComboQmaxPDF.currentText().encode() + #Ejecuta el calculo de caudal a largo plazo + retorno = self.HSutils.hidrologia_extremos_regional(Qmed, CoefExpoList, Pdf2Use, isMaxorMin) + #Mensajes de exito o error + if retorno == 0: + #Actualiza la tabla de WMF + for Tr in [2.33, 5, 10, 25, 50, 100]: + nombre = isMaxorMin+'_'+str(Tr) + self.TabWMF.NewEntry(self.HSutils.DicBasinWMF[nombre],nombre, self.Tabla_Prop_WMF) + #Mensaje de exito + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + u'Caudales extremos calculados con exito', + level=QgsMessageBar.INFO, duration=3) + else: + self.iface.messageBar().pushMessage (u'Hydro-SIG:', + u'No ha sido posible determinar caudales extremos para esta cuenca', + level=QgsMessageBar.WARNING, duration=3) + + + #Botones para ejecutar self.Butto_Ejec_HidroBalance.clicked.connect(hadleClickEventEjecutarBalance) + self.Butto_Ejec_HidroExtremos.clicked.connect(handleClickEventExtremeByRegionalization) def TableStart (self): '''Arranca las tablas de NC y WMF''' diff --git a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui index 9616ecb..86764dc 100644 --- a/qgisplugin/HydroSEDPlugin_dockwidget_base.ui +++ b/qgisplugin/HydroSEDPlugin_dockwidget_base.ui @@ -3289,7 +3289,7 @@ 0 - -615 + -730 443 1918 @@ -4193,7 +4193,7 @@ 0 1030 421 - 241 + 261 @@ -4280,7 +4280,7 @@ - + Coeficiente caudal medio extremo (Poveda, 2007) @@ -4300,7 +4300,7 @@ - + Coeficiente desviacion caudal extremo (Poveda, 2007) @@ -4333,7 +4333,7 @@ - + Exponente caudal medio extremo (Poveda, 2007) @@ -4353,7 +4353,7 @@ - + Exponente desviacion caudal extremo (Poveda, 2007) @@ -4379,20 +4379,29 @@ - - + + Periodo de retorno - Tr + f(x) - - + + + + + 0 + 0 + + - Periodo de retorno en años para la estimación de extremos + Función de distribución usada para obtener la estimación de máximos. + + + Función de distribución usada para obtener la estimación de máximos. @@ -4400,50 +4409,8 @@ - - - - Qt::Horizontal - - - - - - - - 75 - true - - - - Datos de salida: - - - Qt::AutoText - - - - - - - - 75 - true - - - - El valor del caudal calculado solo a la salida de la cuenca. - - - El valor del caudal calculado solo a la salida de la cuenca. - - - Qextremo salida [m3/s]: - - - @@ -4457,16 +4424,6 @@ - - - - Valor del caudal extremo calculado a la salida. - - - true - - - diff --git a/wmf/wmf.py b/wmf/wmf.py index a4feb97..e98fc6a 100644 --- a/wmf/wmf.py +++ b/wmf/wmf.py @@ -1905,7 +1905,7 @@ def GetQ_Balance(self,Precipitation, Tipo_ETR = 1, mu_choud = 1.37): self.CellQmed,self.CellETR = cu.basin_qmed( self.structure, self.CellHeight, - precip, + precip, Tipo_ETR, mu_choud, self.ncells,) @@ -2075,7 +2075,7 @@ def Save_Net2Map(self,ruta,dx=cu.dxp,umbral=None, new_field=osgeo.ogr.FieldDefn(k[:10],osgeo.ogr.OFTReal) layer.CreateField(new_field) netsizeT = cu.basin_netxy_find(self.structure,nodos,cauce*Dict[k],self.ncells) - netDict.append(cu.basin_netxy_cut(netsize,self.ncells)) + netDict.append(cu.basin_netxy_cut(netsizeT,self.ncells)) #Para cada tramo featureFID=0 for i,j in zip(cortes[:-1],cortes[1:]):