7 changes: 4 additions & 3 deletions python/plugins/sextante/algs/ftools/FToolsUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,11 @@ def getUniqueValuesCount(layer, fieldIndex):

# From two input field maps, create single field map
def combineVectorFields( layerA, layerB ):
fieldsA = layerA.fields()
fieldsB = layerB.fields()
fieldsA = layerA.dataProvider().fields()
fieldsB = layerB.dataProvider().fields()
fieldsB = testForUniqueness( fieldsA, fieldsB )
fieldsA.extend( fieldsB )
for field in fieldsB:
fieldsA.append(field)
return fieldsA

# Check if two input field maps are unique, and resolve name issues if they aren't
Expand Down
34 changes: 9 additions & 25 deletions python/plugins/sextante/algs/ftools/Intersection.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* *
***************************************************************************
"""
from sextante.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
__author__ = 'Victor Olaya'
__date__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'
Expand Down Expand Up @@ -46,25 +47,9 @@ class Intersection(GeoAlgorithm):
def processAlgorithm(self, progress):
vlayerA = QGisLayers.getObjectFromUri(self.getParameterValue(Intersection.INPUT))
vlayerB = QGisLayers.getObjectFromUri(self.getParameterValue(Intersection.INPUT2))
GEOS_EXCEPT = True
FEATURE_EXCEPT = True
vproviderA = vlayerA.dataProvider()
vproviderB = vlayerB.dataProvider()

# check for crs compatibility
crsA = vproviderA.crs()
crsB = vproviderB.crs()
if not crsA.isValid() or not crsB.isValid():
SextanteLog.addToLog(SextanteLog.LOG_WARNING, "Intersection. Invalid CRS. Results might be unexpected")
else:
if not crsA != crsB:
SextanteLog.addToLog(SextanteLog.LOG_WARNING, "Intersection. Non-matching CRSs. Results might be unexpected")
fields = utils.combineVectorFields(vlayerA, vlayerB)
#=======================================================================
# longNames = ftools_utils.checkFieldNameLength( fields )
# if not longNames.isEmpty():
# raise GeoAlgorithmExecutionException("Following field names are longer than 10 characters:\n" + longNames.join('\n') )
#=======================================================================
writer = self.getOutputFromName(Intersection.OUTPUT).getVectorWriter(fields, vproviderA.geometryType(), vproviderA.crs() )
inFeatA = QgsFeature()
inFeatB = QgsFeature()
Expand Down Expand Up @@ -92,20 +77,19 @@ def processAlgorithm(self, progress):
int_geom = QgsGeometry( int_com.difference( int_sym ) )
try:
outFeat.setGeometry( int_geom )
outFeat.setAttributes( atMapA.extend( atMapB ) )
attrs = []
attrs.extend(atMapA)
attrs.extend(atMapB)
outFeat.setAttributes(attrs)
writer.addFeature( outFeat )
except:
FEATURE_EXCEPT = False
continue
raise GeoAlgorithmExecutionException("Feature exception while computing intersection")
except:
GEOS_EXCEPT = False
break
raise GeoAlgorithmExecutionException("Geometry exception while computing intersection")


del writer
if not GEOS_EXCEPT:
SextanteLog.addToLog(SextanteLog.LOG_WARNING, "Geometry exception while computing intersection")
if not FEATURE_EXCEPT:
SextanteLog.addToLog(SextanteLog.LOG_WARNING, "Feature exception while computing intersection")


def defineCharacteristics(self):
self.name = "Intersection"
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/sextante/algs/ftools/SelectByLocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def processAlgorithm(self, progress):
geom = QgsGeometry(feat.geometry())
intersects = index.intersects(geom.boundingBox())
for i in intersects:
inputProvider.featureAtId(i, infeat, True)
inputLayer.featureAtId(i, infeat, True)
tmpGeom = QgsGeometry( infeat.geometry() )
if geom.intersects(tmpGeom):
selectedSet.append(infeat.id())
Expand Down
73 changes: 30 additions & 43 deletions python/plugins/sextante/algs/ftools/Union.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* *
***************************************************************************
"""
from sextante.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException

__author__ = 'Victor Olaya'
__date__ = 'August 2012'
Expand Down Expand Up @@ -50,20 +51,7 @@ def processAlgorithm(self, progress):
GEOS_EXCEPT = True
FEATURE_EXCEPT = True
vproviderA = vlayerA.dataProvider()
allAttrsA = vproviderA.attributeIndexes()
vproviderA.select( allAttrsA )
vproviderB = vlayerB.dataProvider()
allAttrsB = vproviderB.attributeIndexes()
vproviderB.select( allAttrsB )

# check for crs compatibility
crsA = vproviderA.crs()
crsB = vproviderB.crs()
if not crsA.isValid() or not crsB.isValid():
SextanteLog.addToLog(SextanteLog.LOG_WARNING, "Union. Invalid CRS. Results might be unexpected")
else:
if not crsA != crsB:
SextanteLog.addToLog(SextanteLog.LOG_WARNING, "Union. Non-matching CRSs. Results might be unexpected")

fields = utils.combineVectorFields(vlayerA, vlayerB )
#longNames = ftools_utils.checkFieldNameLength( fields )
#if not longNames.isEmpty():
Expand All @@ -74,10 +62,9 @@ def processAlgorithm(self, progress):
outFeat = QgsFeature()
indexA = utils.createSpatialIndex(vlayerB)
indexB = utils.createSpatialIndex(vlayerA)
vproviderA.rewind()

count = 0
nElement = 0

featuresA = QGisLayers.features(vlayerA)
nFeat = len(featuresA)
for inFeatA in featuresA:
Expand All @@ -99,30 +86,29 @@ def processAlgorithm(self, progress):
FEATURE_EXCEPT = False
else:
for id in intersects:
count += 1
vproviderB.featureAtId( int( id ), inFeatB , True, allAttrsB )
atMapB = inFeatB.attributes()
tmpGeom = QgsGeometry( inFeatB.geometry() )
try:
count += 1
vlayerB.featureAtId( int( id ), inFeatB , True)
atMapB = inFeatB.attributes()
tmpGeom = QgsGeometry( inFeatB.geometry() )

if geom.intersects( tmpGeom ):
found = True
int_geom = geom.intersection( tmpGeom )

if int_geom is None:
# There was a problem creating the intersection
GEOS_EXCEPT = False
int_geom = QgsGeometry()
raise GeoAlgorithmExecutionException("Geometry exception while computing intersection")
else:
int_geom = QgsGeometry(int_geom)

if diff_geom.intersects( tmpGeom ):
diff_geom = diff_geom.difference( tmpGeom )
if diff_geom is None:
# It's possible there was an error here?
diff_geom = QgsGeometry()
else:
diff_geom = QgsGeometry(diff_geom)

if int_geom.wkbType() == 0:
# intersection produced different geomety types
temp_list = int_geom.asGeometryCollection()
Expand All @@ -131,10 +117,13 @@ def processAlgorithm(self, progress):
int_geom = QgsGeometry( i )
try:
outFeat.setGeometry( int_geom )
outFeat.setAttributes( atMapA.extend( atMapB ) )
attrs = []
attrs.extend(atMapA)
attrs.extend(atMapB)
outFeat.setAttributes(attrs)
writer.addFeature( outFeat )
except Exception, err:
FEATURE_EXCEPT = False
raise GeoAlgorithmExecutionException("Feature exception while computing union")
else:
# this only happends if the bounding box
# intersects, but the geometry doesn't
Expand All @@ -144,10 +133,8 @@ def processAlgorithm(self, progress):
writer.addFeature( outFeat )
except:
# also shoudn't ever happen
FEATURE_EXCEPT = False
except Exception, err:
GEOS_EXCEPT = False
found = False
raise GeoAlgorithmExecutionException("Feature exception while computing union")


if found:
try:
Expand All @@ -160,10 +147,9 @@ def processAlgorithm(self, progress):
outFeat.setAttributes( atMapA )
writer.addFeature( outFeat )
except Exception, err:
FEATURE_EXCEPT = False
raise GeoAlgorithmExecutionException("Feature exception while computing union")

length = len( vproviderA.fields().values() )
vproviderB.rewind()
length = len(vproviderA.fields())

featuresA = QGisLayers.features(vlayerB)
nFeat = len(featuresA)
Expand All @@ -172,8 +158,9 @@ def processAlgorithm(self, progress):
add = False
geom = QgsGeometry( inFeatA.geometry() )
diff_geom = QgsGeometry( geom )
atMap = inFeatA.attributes()
atMap = dict( zip( range( length, length + len( atMap ) ), atMap ) )
atMap = [None] * length
atMap.extend(inFeatA.attributes())
#atMap = dict( zip( range( length, length + len( atMap ) ), atMap ) )
intersects = indexB.intersects( geom.boundingBox() )

if len(intersects) < 1:
Expand All @@ -182,10 +169,10 @@ def processAlgorithm(self, progress):
outFeat.setAttributes( atMap )
writer.addFeature( outFeat )
except Exception, err:
FEATURE_EXCEPT = False
raise GeoAlgorithmExecutionException("Feature exception while computing union")
else:
for id in intersects:
vlayerA.featureAtId( int( id ), inFeatB , True, allAttrsA )
vlayerA.featureAtId( int( id ), inFeatB , True)
atMapB = inFeatB.attributes()
tmpGeom = QgsGeometry( inFeatB.geometry() )
try:
Expand All @@ -199,15 +186,15 @@ def processAlgorithm(self, progress):
outFeat.setAttributes( atMap )
writer.addFeature( outFeat )
except Exception, err:
add = False
GEOS_EXCEPT = False
raise GeoAlgorithmExecutionException("Geometry exception while computing intersection")

if add:
try:
outFeat.setGeometry( diff_geom )
outFeat.setAttributes( atMapB )
writer.addFeature( outFeat )
except Exception, err:
except Exception, err:
raise err
FEATURE_EXCEPT = False
nElement += 1

Expand All @@ -223,4 +210,4 @@ def defineCharacteristics(self):
self.group = "Vector overlay tools"
self.addParameter(ParameterVector(Union.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY))
self.addParameter(ParameterVector(Union.INPUT2, "Input layer 2", ParameterVector.VECTOR_TYPE_ANY))
self.addOutput(OutputVector(Union.OUTPUT, "Intersection"))
self.addOutput(OutputVector(Union.OUTPUT, "Union"))
4 changes: 1 addition & 3 deletions python/plugins/sextante/algs/mmqgisx/MMQGISXAlgorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@
from sextante.parameters.ParameterNumber import ParameterNumber
from sextante.parameters.ParameterSelection import ParameterSelection
from sextante.parameters.ParameterString import ParameterString
from sextante.parameters.ParameterTable import ParameterTable
from sextante.parameters.ParameterTableField import ParameterTableField
from sextante.parameters.ParameterVector import ParameterVector
from sextante.outputs.OutputTable import OutputTable
from sextante.outputs.OutputVector import OutputVector
from sextante.algs.mmqgisx.mmqgisx_library import *
from sextante.core.QGisLayers import QGisLayers


class mmqgisx_delete_columns_algorithm(GeoAlgorithm):
Expand Down
18 changes: 18 additions & 0 deletions python/plugins/sextante/core/GeoAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,24 @@ def setOutputCRS(self):
return
qgis = QGisLayers.iface
self.crs = qgis.mapCanvas().mapRenderer().destinationCrs()

def checkInputCRS(self):
'''it checks that all input layers use the same CRS. If so, returns True. False otherwise'''
crs = None;
layers = QGisLayers.getAllLayers()
for param in self.parameters:
if isinstance(param, (ParameterRaster, ParameterVector, ParameterMultipleInput)):
if param.value:
inputlayers = param.value.split(";")
for inputlayer in inputlayers:
for layer in layers:
if layer.source() == inputlayer:
if crs is None:
crs = layer.crs()
else:
if crs != layer.crs():
return False
return True

def addOutput(self, output):
#TODO: check that name does not exist
Expand Down
17 changes: 13 additions & 4 deletions python/plugins/sextante/core/Sextante.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def loadAlgorithms():
for alg in providerAlgs:
algs[alg.commandLineName()] = alg
Sextante.algs[provider.getName()] = algs

#this is a special provider, since it depends on others
#TODO Fix circular imports, so this provider can be incorporated
#as a normal one
Expand Down Expand Up @@ -287,9 +287,13 @@ def runAlgorithm(algOrName, onFinish, *args):

msg = alg.checkParameterValuesBeforeExecuting()
if msg:
print ("Unable to execute algorithm\n" + msg)
return
print ("Unable to execute algorithm\n" + msg)
return

if not alg.checkInputCRS():
print ("Warning: Not all input layers use the same CRS.\n" +
"This can cause unexpected results.")

SextanteLog.addToLog(SextanteLog.LOG_ALGORITHM, alg.getAsCommand())

# don't set the wait cursor twice, because then when you restore it
Expand All @@ -300,7 +304,12 @@ def runAlgorithm(algOrName, onFinish, *args):
elif cursor.shape() != Qt.WaitCursor:
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

if SextanteConfig.getSetting(SextanteConfig.USE_THREADS):
useThreads = SextanteConfig.getSetting(SextanteConfig.USE_THREADS)

#this is doing strange things, so temporarily the thread execution is disabled from the console
useThreads = False

if useThreads:
algEx = AlgorithmExecutor(alg)
progress = QProgressDialog()
progress.setWindowTitle(alg.name)
Expand Down
7 changes: 5 additions & 2 deletions python/plugins/sextante/core/SextanteConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class SextanteConfig():
RECENT_ALGORITHMS = "RECENT_ALGORITHMS"
PRE_EXECUTION_SCRIPT = "PRE_EXECUTION_SCRIPT"
POST_EXECUTION_SCRIPT = "POST_EXECUTION_SCRIPT"
SHOW_CRS_DEF = "SHOW_CRS_DEF"
WARN_UNMATCHING_CRS = "WARN_UNMATCHING_CRS"

settings = {}
settingIcons= {}
Expand All @@ -61,8 +63,9 @@ def initialize():
SextanteConfig.addSetting(Setting("General", SextanteConfig.USE_FILENAME_AS_LAYER_NAME, "Use filename as layer name", True))
SextanteConfig.addSetting(Setting("General", SextanteConfig.SHOW_RECENT_ALGORITHMS, "Show recently executed algorithms", True))
SextanteConfig.addSetting(Setting("General", SextanteConfig.USE_CATEGORIES, "Use categories to classify algorithms, instead of providers", False))
SextanteConfig.addSetting(Setting("General", SextanteConfig.OUTPUT_FOLDER,
"Output folder", SextanteUtils.tempFolder()))
SextanteConfig.addSetting(Setting("General", SextanteConfig.OUTPUT_FOLDER, "Output folder", SextanteUtils.tempFolder()))
SextanteConfig.addSetting(Setting("General", SextanteConfig.SHOW_CRS_DEF, "Show layer CRS definition in selection boxes", True))
SextanteConfig.addSetting(Setting("General", SextanteConfig.WARN_UNMATCHING_CRS, "Warn before executing if layer CRS's do not match", True))
SextanteConfig.addSetting(Setting("General", SextanteConfig.RASTER_STYLE,"Style for raster layers",""))
SextanteConfig.addSetting(Setting("General", SextanteConfig.VECTOR_POINT_STYLE,"Style for point layers",""))
SextanteConfig.addSetting(Setting("General", SextanteConfig.VECTOR_LINE_STYLE,"Style for line layers",""))
Expand Down
10 changes: 9 additions & 1 deletion python/plugins/sextante/gui/AlgorithmExecutionDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
from sextante.parameters.ParameterCrs import ParameterCrs
from sextante.core.SextanteConfig import SextanteConfig
from sextante.parameters.ParameterExtent import ParameterExtent
from sextante.outputs.OutputHTML import OutputHTML
from sextante.outputs.OutputRaster import OutputRaster
from sextante.outputs.OutputVector import OutputVector
from sextante.outputs.OutputTable import OutputTable
Expand Down Expand Up @@ -202,10 +201,19 @@ def setParamValue(self, param, widget):

@pyqtSlot()
def accept(self):
checkCRS = SextanteConfig.getSetting(SextanteConfig.WARN_UNMATCHING_CRS)
keepOpen = SextanteConfig.getSetting(SextanteConfig.KEEP_DIALOG_OPEN)
useThread = SextanteConfig.getSetting(SextanteConfig.USE_THREADS)
try:
self.setParamValues()
if checkCRS and not self.alg.checkInputCRS():
reply = QMessageBox.question(self, "Unmatching CRS's",
"Layers do not all use the same CRS.\n" +
"This can cause unexpected results.\n" +
"Do you want to continue?",
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.No:
return
msg = self.alg.checkParameterValuesBeforeExecuting()
if msg:
if keepOpen or useThread:
Expand Down
Loading