Skip to content

Commit

Permalink
Version 3.0.2: all undefined soils listed
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisWGeorge committed Oct 3, 2024
1 parent 9db0fb1 commit 1d32f51
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 34 deletions.
2 changes: 1 addition & 1 deletion QSWATPlus.iss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#define MyAppName "QSWATPlus"
#define MyAppVersion "3.0"
#define MyAppSubVersion "0"
#define MyAppSubVersion "2"
#define MyAppPublisher "SWAT"
#define MyAppURL "https://swat.tamu.edu/"

Expand Down
37 changes: 24 additions & 13 deletions QSWATPlus/DBUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,7 @@ def writeSoilsTable(self) -> bool:
# so cannot use sqlite3.Row which returns rows as dictionaries with arbitrary order
conn.row_factory = lambda _,row : row
usersoilTable = self.getUsersoilTable()
errorReported = False
try:
# single usersoil table has 152 columns, one with separate layer table has 11:
# we leave room for expansion by using 20 as limit
Expand Down Expand Up @@ -1028,14 +1029,19 @@ def writeSoilsTable(self) -> bool:
if not row:
if self.isHUC:
continue # assume already reported
QSWATUtils.error('SSURGO soil {0} (and perhaps others) not defined in {1} table in database {2}. {3} table not written.'.
format(ssurgoId, usersoilTable, database, DBUtils._SOILS_SOL_NAME), self.isBatch)
return False
sid += 1
if hasSeparateLayerTable:
lid = self.writeUsedSoilRowSeparate(sid, lid, str(ssurgoId), row, writeCursor, insert, insertLayer, readCursor, sqlLayer)
if not errorReported:
QSWATUtils.error("""
SSURGO soil {0} (and perhaps others) not defined in {1} table in database {2}. {3} table incomplete.
See QSWAT+ log messages for full list of undefined soils.""".
format(ssurgoId, usersoilTable, database, DBUtils._SOILS_SOL_NAME), self.isBatch)
errorReported = True
QSWATUtils.logerror('SSURGO soil {0} not defined'.format(ssurgoId))
else:
lid = self.writeUsedSoilRow(sid, lid, str(ssurgoId), row, writeCursor, insert, insertLayer)
sid += 1
if hasSeparateLayerTable:
lid = self.writeUsedSoilRowSeparate(sid, lid, str(ssurgoId), row, writeCursor, insert, insertLayer, readCursor, sqlLayer)
else:
lid = self.writeUsedSoilRow(sid, lid, str(ssurgoId), row, writeCursor, insert, insertLayer)
else:
for name in self.usedSoilNames.values():
if self.useSTATSGO:
Expand All @@ -1049,14 +1055,19 @@ def writeSoilsTable(self) -> bool:
args = (name,)
row = readCursor.execute(sql, args).fetchone()
if not row:
QSWATUtils.error('Soil name {0} (and perhaps others) not defined in {1} table in database {2}. {3} table not written.'.
if not errorReported:
QSWATUtils.error(
"""Soil name {0} (and perhaps others) not defined in {1} table in database {2}. {3} table incomplete.
See QSWAT+ log messages for full list of undefined soils.""".
format(name, usersoilTable, database, DBUtils._SOILS_SOL_NAME), self.isBatch)
return False
sid += 1
if hasSeparateLayerTable:
lid = self.writeUsedSoilRowSeparate(sid, lid, name, row, writeCursor, insert, insertLayer, readCursor, sqlLayer)
errorReported = True
QSWATUtils.logerror('Soil name {0} not defined'.format(ssurgoId))
else:
lid = self.writeUsedSoilRow(sid, lid, name, row, writeCursor, insert, insertLayer)
sid += 1
if hasSeparateLayerTable:
lid = self.writeUsedSoilRowSeparate(sid, lid, name, row, writeCursor, insert, insertLayer, readCursor, sqlLayer)
else:
lid = self.writeUsedSoilRow(sid, lid, name, row, writeCursor, insert, insertLayer)
return True
except Exception:
QSWATUtils.exceptionError('Could not create {2} and {3} tables from {0} table in soil database {1}'.
Expand Down
4 changes: 2 additions & 2 deletions QSWATPlus/QSWATPlusMain.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
class QSWATPlus(QObject):
"""QGIS plugin to prepare geographic data for SWAT+ Editor."""

__version__ = '3.0.1'
__version__ = '3.0.2'

def __init__(self, iface):
"""Constructor."""
Expand Down Expand Up @@ -345,7 +345,7 @@ def setupProject(self, proj, isBatch, isHUC=False, isHAWQS=False, logFile=None):
proj.writeEntryBool(attTitle, 'delin/isHAWQS', isHAWQS)
else:
isHAWQS = isHAWQSFromProjfile
QSWATUtils.loginfo('isHAWQS is {0}'.format(isHAWQS))
#QSWATUtils.loginfo('isHAWQS is {0}'.format(isHAWQS))
# now have project so initiate global vars
# if we do this earlier we cannot for example find the project database
self._gv = GlobalVars(self._iface, QSWATPlus.__version__, self.plugin_dir, isBatch, isHUC, isHAWQS, logFile)
Expand Down
17 changes: 11 additions & 6 deletions QSWATPlus/QSWATTopology.py
Original file line number Diff line number Diff line change
Expand Up @@ -4321,15 +4321,15 @@ def reachableFrom(a: int, b: int, mapp: Dict[int, int]):
streamLayer = QgsVectorLayer(streamFile, 'streams', 'ogr')
linkIndex = self.getIndex(streamLayer, 'LINKNO')
dsLinkIndex = self.getIndex(streamLayer, 'DSLINKNO1')
# outlets of merged streams are unreliable
#outXIndex = self.getIndex(streamLayer, 'OutletX')
#outYIndex = self.getIndex(streamLayer, 'OutletY')
#subOutlets = dict()
# outlets of merged streams are unreliable but can be used to disambiguate multiple channel outlets
outXIndex = self.getIndex(streamLayer, 'OutletX')
outYIndex = self.getIndex(streamLayer, 'OutletY')
subOutlets = dict()
for stream in streamLayer.getFeatures():
subbasin = stream[linkIndex]
dsSubbasin = stream[dsLinkIndex]
self.downSubbasins[subbasin] = dsSubbasin
#subOutlets[subbasin] = QgsPointXY(stream[outXIndex], stream[outYIndex])
subOutlets[subbasin] = QgsPointXY(stream[outXIndex], stream[outYIndex])
# replace subbasins in other HUC12s with -1
for subbasin in self.downSubbasins:
if self.downSubbasins[subbasin] not in self.downSubbasins:
Expand Down Expand Up @@ -4365,9 +4365,14 @@ def reachableFrom(a: int, b: int, mapp: Dict[int, int]):
if not QSWATTopology.coincidentPoints(outletPt0, outletPt, self.xThreshold, self.yThreshold):
if self.isHUC:
projRef = ' in ' + self.projName
if QSWATTopology.coincidentPoints(outletPt, subOutlets[subbasin], self.xThreshold, self.yThreshold):
# choose outletPt as coincident with stream outlet
outletId0 = outletId
outletPt0 = outletPt
# else stick with original
else:
projRef = ''
QSWATUtils.error('Polygon {0} has separate outlets at ({1}, {2}) and ({3}, {4}): ignoring second{5}'.
QSWATUtils.information('WARNIING: Polygon {0} has separate outlets at ({1}, {2}) and ({3}, {4}): ignoring second{5}'.
format(subbasin, outletPt0.x(), outletPt0.y(), outletPt.x(), outletPt.y(), projRef), self.isBatch)
#else:
self.chOutlets[chLink] = outletid0, outletPt0
Expand Down
8 changes: 4 additions & 4 deletions QSWATPlus/convertFromArc.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ def copyESRIGrid(inFile: str, outFile: str) -> bool:
return True

def createOutletShapefiles(self, isFull: bool) -> bool:
"""Create inlets\outlets file and extra inlets\outlets file. Return true if OK.
r"""Create inlets\outlets file and extra inlets\outlets file. Return true if OK.
The inlets/outlets shapefile is created even if not isFull, although it is not recorded in the project file,
as it might be useful to users if they decide to delineate again.
Expand All @@ -486,7 +486,7 @@ def createOutletShapefiles(self, isFull: bool) -> bool:
if not self.makeOutletFile(qOutlets, fields, prjFile):
return False
# add main outlets and inlets to outlets file
qOutletsLayer = QgsVectorLayer(qOutlets, 'Inlets\outlets', 'ogr')
qOutletsLayer = QgsVectorLayer(qOutlets, 'Inlets-outlets', 'ogr')
provider = qOutletsLayer.dataProvider()
idIndex = provider.fieldNameIndex('ID')
inletIndex = provider.fieldNameIndex('INLET')
Expand Down Expand Up @@ -2494,7 +2494,7 @@ def insertSort(percent: float, x: Any, result: List[Tuple[float, Any]]) -> None:

@staticmethod
def getMaxFileOrDir(direc: str, base: str, suffix: str) -> str:
"""Find and return the maximum file of the form 'direc\basensuffix' or 'direc\basen if suffix is empty."""
"""Find and return the maximum file of the form 'direc/basensuffix' or 'direc/basen if suffix is empty."""
num = 1
current = os.path.join(direc, base + str(num) + suffix)
while True:
Expand Down Expand Up @@ -2549,7 +2549,7 @@ def writeCsvFile(cursor: Any, table: str, outFile: str) -> None:
def copyAllFiles(inDir: str, outDir: str) -> None:
"""Copy files (containing at least one .) from inDir to OutDir."""
if os.path.exists(inDir):
patt = inDir + '\*.*'
patt = inDir + r'\*.*'
for f in glob.iglob(patt):
shutil.copy(f, outDir)

Expand Down
18 changes: 16 additions & 2 deletions QSWATPlus/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
# Import the PyQt and QGIS libraries
from qgis.PyQt.QtCore import QFileInfo, QPoint, QSettings # @UnresolvedImport
#from qgis.PyQt.QtGui import * # @UnusedWildImport type: ignore
from qgis.PyQt.QtWidgets import QComboBox # @UnresolvedImport
from qgis.PyQt.QtWidgets import QComboBox, QMessageBox # @UnresolvedImport
from qgis.core import QgsProject, QgsCoordinateReferenceSystem, QgsVectorFileWriter, Qgis, QgsProcessingContext, QgsFeatureRequest # @UnresolvedImport
from qgis.gui import QgisInterface # @UnresolvedImport
import os.path
Expand Down Expand Up @@ -52,7 +52,21 @@ def __init__(self, iface: QgisInterface, version: str, plugin_dir: str, isBatch:
"""Initialise class variables."""
settings = QSettings()
if settings.contains('/QSWATPlus/SWATPlusDir'):
SWATPlusDir = settings.value('/QSWATPlus/SWATPlusDir')
if Parameters._ISWIN:
SWATPlusDir = settings.value('/QSWATPlus/SWATPlusDir')
# choice to update to latest SWATPlus location if exists and not current setting
newSWATPlusDir = Parameters._HOMEDIR + r'\SWATPlus'
if not isBatch and os.path.isdir(newSWATPlusDir) and os.path.normcase(SWATPlusDir) == 'c:\\swat\\swatplus':
if QSWATUtils.question("""
It looks like you recently upgraded QSWAT+. The SWATPlus directory has moved to
{0}.
Change your settings to use the new directory?
if {0} is used for some other purpose you might want to rename it to stop this question being repeated.""".
format(newSWATPlusDir), isBatch, False) == QMessageBox.Yes:
SWATPlusDir = newSWATPlusDir
else:
SWATPlusDir = settings.value('/QSWATPlus/SWATPlusDir')
if not os.path.isdir(SWATPlusDir):
SWATPlusDir = Parameters._SWATPLUSDEFAULTDIR
else:
Expand Down
12 changes: 8 additions & 4 deletions QSWATPlus/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,13 @@ class Parameters:
_ISLINUX = platform.system() == 'Linux'
_ISMAC = platform.system() == 'Darwin'
_MACQGISDIR = '/Applications/QGIS-LTR.app'
_SWATPLUSDEFAULTDIR = r'C:\SWAT\SWATPlus' if _ISWIN else os.path.expanduser('~') + '/.local/share/SWATPlus' if _ISLINUX else os.path.expanduser('~') + '/SWATPlus'
if not os.path.isdir(_SWATPLUSDEFAULTDIR) and (_ISLINUX or _ISMAC):
_SWATPLUSDEFAULTDIR = '/usr/local/share/SWATPlus' if _ISLINUX else '/usr/local/share/SWATPlus'
_HOMEDIR = os.path.expanduser('~')
_SWATPLUSDEFAULTDIR = _HOMEDIR + r'\SWATPlus' if _ISWIN else _HOMEDIR + '/.local/share/SWATPlus' if _ISLINUX else _HOMEDIR + '/SWATPlus'
if not os.path.isdir(_SWATPLUSDEFAULTDIR):
if _ISWIN:
_SWATPLUSDEFAULTDIR = r'C:\SWAT\SWATPlus'
elif (_ISLINUX or _ISMAC):
_SWATPLUSDEFAULTDIR = '/usr/local/share/SWATPlus' if _ISLINUX else '/usr/local/share/SWATPlus'
_SWATEDITOR = 'SWATPlusEditor.exe' if _ISWIN else 'SWATPlusEditor' if _ISLINUX else 'SWATPlusEditor.app/Contents/MacOS/SWATPlusEditor'
_SWATEDITORDIR = 'SWATPlusEditor'
_MPIEXEC = 'mpiexec.exe' if _ISWIN else 'mpiexec' if _ISLINUX else 'mpiexec'
Expand Down Expand Up @@ -192,7 +196,7 @@ def __init__(self, gv: Any) -> None:
if self.mpiexecDir == '':
self.mpiexecDir = Parameters._MPIEXECDEFAULTDIR
elif not os.path.isdir(self.mpiexecDir):
settings.remove('/QSWATPlus/SWATPlusDir')
settings.remove('/QSWATPlus/mpiexecDir')
self.mpiexecDir = Parameters._MPIEXECDEFAULTDIR
## number of MPI processes
self.numProcesses = settings.value('/QSWATPlus/NumProcesses', '')
Expand Down
Binary file modified QSWATPlus/testdata/sj_demwshed.dbf
Binary file not shown.
5 changes: 3 additions & 2 deletions runHUC.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,10 @@ def runProject(d, dataDir, scale, minHRUha):
#for arg in sys.argv:
# print('Argument: {0}'.format(arg))
# set True for debugging, normally false
debugging = False
debugging = True
if debugging:
direc = r"K:\HUCModels\Models4\SWATPlus\Fields_CDL\HUC14\020503040404\huc020503040404\huc020503040404.qgs"
direc = r'K:\HUCModels\Models4\SWATPlus\Fields_CDL\HUC12\0202000206\huc0202000206\huc0202000206.qgs'
#direc = r"K:\HUCModels\Models4\SWATPlus\Fields_CDL\HUC14\020503040404\huc020503040404\huc020503040404.qgs"
#direc = r"K:\HUCModels\Models4\SWATPlus\Fields_CDL\HUC14\020801020403\huc020801020403\huc020801020403.qgs"
dataDir = "K:/Data"
scale = 14
Expand Down

0 comments on commit 1d32f51

Please sign in to comment.