コード例 #1
0
ファイル: doSpatialJoin.py プロジェクト: afrigeo/Quantum-GIS
    def compute(self, inName, joinName, outName, summary, sumList, keep, progressBar):
        layer1 = ftools_utils.getVectorLayerByName(inName)
        provider1 = layer1.dataProvider()
        allAttrs = provider1.attributeIndexes()
        provider1.select(allAttrs)
        fieldList1 = ftools_utils.getFieldList(layer1).values()

        layer2 = ftools_utils.getVectorLayerByName(joinName)
        provider2 = layer2.dataProvider()
        allAttrs = provider2.attributeIndexes()
        provider2.select(allAttrs)
        fieldList2 = ftools_utils.getFieldList(layer2)
        fieldList = []
        if provider1.crs() != provider2.crs():
            QMessageBox.warning(self, self.tr("CRS warning!"), self.tr("Warning: Input layers have non-matching CRS.\nThis may cause unexpected results."))
        if not summary:
            fieldList2 = ftools_utils.testForUniqueness(fieldList1, fieldList2.values())
            seq = range(0, len(fieldList1) + len(fieldList2))
            fieldList1.extend(fieldList2)
            fieldList1 = dict(zip(seq, fieldList1))
        else:
            numFields = {}
            for j in fieldList2.keys():
                if fieldList2[j].type() == QVariant.Int or fieldList2[j].type() == QVariant.Double:
                    numFields[j] = []
                    for i in sumList:
                        field = QgsField(i + unicode(fieldList2[j].name()), QVariant.Double, "real", 24, 16, self.tr("Summary field") )
                        fieldList.append(field)
            field = QgsField("COUNT", QVariant.Double, "real", 24, 16, self.tr("Summary field") )
            fieldList.append(field)
            fieldList2 = ftools_utils.testForUniqueness(fieldList1, fieldList)
            fieldList1.extend(fieldList)
            seq = range(0, len(fieldList1))
            fieldList1 = dict(zip(seq, fieldList1))

        # check for correct field names
        longNames = ftools_utils.checkFieldNameLength( fieldList1 )
        if not longNames.isEmpty():
            QMessageBox.warning( self, self.tr( 'Incorrect field names' ),
                        self.tr( 'No output will be created.\nFollowing field names are longer than 10 characters:\n%1' )
                        .arg( longNames.join( '\n' ) ) )
            return False

        sRs = provider1.crs()
        progressBar.setValue(13)
        check = QFile(self.shapefileName)
        if check.exists():
            if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName):
                QMessageBox.warning( self, self.tr( 'Error deleting shapefile' ),
                            self.tr( "Can't delete existing shapefile\n%1" ).arg( self.shapefileName ) )
                return False
        writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fieldList1, provider1.geometryType(), sRs)
        #writer = QgsVectorFileWriter(outName, "UTF-8", fieldList1, provider1.geometryType(), sRs)
        inFeat = QgsFeature()
        outFeat = QgsFeature()
        inFeatB = QgsFeature()
        inGeom = QgsGeometry()
        progressBar.setValue(15)
        start = 15.00
        add = 85.00 / provider1.featureCount()
        provider1.rewind()
        index = ftools_utils.createIndex(provider2)
        while provider1.nextFeature(inFeat):
            inGeom = inFeat.geometry()
            atMap1 = inFeat.attributeMap()
            outFeat.setGeometry(inGeom)
            none = True
            joinList = []
            if inGeom.type() == QGis.Point:
                #(check, joinList) = layer2.featuresInRectangle(inGeom.buffer(10,2).boundingBox(), True, True)
                #layer2.select(inGeom.buffer(10,2).boundingBox(), False)
                #joinList = layer2.selectedFeatures()
                joinList = index.intersects( inGeom.buffer(10,2).boundingBox() )
                if len(joinList) > 0: check = 0
                else: check = 1
            else:
                #(check, joinList) = layer2.featuresInRectangle(inGeom.boundingBox(), True, True)
                #layer2.select(inGeom.boundingBox(), False)
                #joinList = layer2.selectedFeatures()
                joinList = index.intersects( inGeom.boundingBox() )
                if len(joinList) > 0: check = 0
                else: check = 1
            if check == 0:
                count = 0
                for i in joinList:
                    #tempGeom = i.geometry()
                    provider2.featureAtId(int(i), inFeatB , True, allAttrs)
                    tmpGeom = QgsGeometry( inFeatB.geometry() )
                    if inGeom.intersects(tmpGeom):
                        count = count + 1
                        none = False
                        atMap2 = inFeatB.attributeMap()
                        if not summary:
                            atMap = atMap1.values()
                            atMap2 = atMap2.values()
                            atMap.extend(atMap2)
                            atMap = dict(zip(seq, atMap))
                            break
                        else:
                            for j in numFields.keys():
                                numFields[j].append(atMap2[j].toDouble()[0])
                if summary and not none:
                    atMap = atMap1.values()
                    for j in numFields.keys():
                        for k in sumList:
                            if k == "SUM": atMap.append(QVariant(sum(numFields[j])))
                            elif k == "MEAN": atMap.append(QVariant(sum(numFields[j]) / count))
                            elif k == "MIN": atMap.append(QVariant(min(numFields[j])))
                            elif k == "MED": atMap.append(QVariant(myself(numFields[j])))
                            else: atMap.append(QVariant(max(numFields[j])))
                        numFields[j] = []
                    atMap.append(QVariant(count))
                    atMap = dict(zip(seq, atMap))
            if none:
                outFeat.setAttributeMap(atMap1)
            else:
                outFeat.setAttributeMap(atMap)
            if keep: # keep all records
                writer.addFeature(outFeat)
            else: # keep only matching records
                if not none:
                    writer.addFeature(outFeat)
            start = start + add
            progressBar.setValue(start)
        del writer
        return True
コード例 #2
0
 def compute(self, inName, inField, joinName, joinField, outName, keep, useTable, progressBar):
   layer1 = ftools_utils.getVectorLayerByName(inName)
   provider1 = layer1.dataProvider()
   allAttrs = provider1.attributeIndexes()
   provider1.select(allAttrs)
   fieldList1 = ftools_utils.getFieldList(layer1).values()
   index1 = provider1.fieldNameIndex(inField)
   if useTable:
     joinInfo = QFileInfo(joinName)
     joinPath = joinInfo.absoluteFilePath()
     joinName = joinInfo.completeBaseName()
     layer2 = QgsVectorLayer(joinPath, joinName, 'ogr')
     useTable = False
   else:
     layer2 = ftools_utils.getVectorLayerByName(joinName)
   provider2 = layer2.dataProvider()
   allAttrs = provider2.attributeIndexes()
   provider2.select(allAttrs, QgsRectangle(), False, False)
   fieldList2 = ftools_utils.getFieldList(layer2)
   index2 = provider2.fieldNameIndex(joinField)
   fieldList2 = ftools_utils.testForUniqueness(fieldList1, fieldList2.values())
   seq = range(0, len(fieldList1) + len(fieldList2))
   fieldList1.extend(fieldList2)
   fieldList1 = dict(zip(seq, fieldList1))
   # check for correct field names
   longNames = ftools_utils.checkFieldNameLength( fieldList1 )
   if not longNames.isEmpty():
     QMessageBox.warning( self, self.tr( 'Incorrect field names' ),
                 self.tr( 'No output will be created.\nFollowing field names are longer than 10 characters:\n%1' )
                 .arg( longNames.join( '\n' ) ) )
     return False
   sRs = provider1.crs()
   progressBar.setValue(13)
   check = QFile(self.shapefileName)
   if check.exists():
     if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName):
       QMessageBox.warning( self, self.tr( 'Error deleting shapefile' ),
                   self.tr( "Can't delete existing shapefile\n%1" ).arg( self.shapefileName ) )
       return False
   writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fieldList1, provider1.geometryType(), sRs)
   inFeat = QgsFeature()
   outFeat = QgsFeature()
   joinFeat = QgsFeature()
   inGeom = QgsGeometry()
   nElement = 0
   nFeats = provider1.featureCount()
   progressBar.setRange(nElement, nFeats)
   count = 0
   provider1.rewind()
   while provider1.nextFeature(inFeat):
     inGeom = QgsGeometry(inFeat.geometry())
     atMap1 = inFeat.attributeMap()
     outFeat.setAttributeMap(atMap1)
     outFeat.setGeometry(inGeom)
     none = True
     provider2.select(allAttrs, QgsRectangle(), False, False)
     while provider2.nextFeature(joinFeat):
         atMap2 = joinFeat.attributeMap()
         if atMap1[index1] == atMap2[index2]:
           none = False
           atMap = atMap1.values()
           atMap2 = atMap2.values()
           atMap.extend(atMap2)
           atMap = dict(zip(seq, atMap))
           break
     if none:
       outFeat.setAttributeMap(atMap1)
     else:
       outFeat.setAttributeMap(atMap)
     if keep: # keep all records
       writer.addFeature(outFeat)
     else: # keep only matching records
       if not none:
         writer.addFeature(outFeat)
     nElement += 1
     progressBar.setValue(nElement)
   del writer
   return True
コード例 #3
0
    def compute(self, inName, joinName, outName, summary, sumList, keep, progressBar):
        layer1 = ftools_utils.getVectorLayerByName(inName)
        provider1 = layer1.dataProvider()
        fieldList1 = ftools_utils.getFieldList(layer1)

        layer2 = ftools_utils.getVectorLayerByName(joinName)
        provider2 = layer2.dataProvider()

        fieldList2 = ftools_utils.getFieldList(layer2)
        fieldList = QgsFields()
        if provider1.crs() != provider2.crs():
            QMessageBox.warning(self, self.tr("CRS warning!"), self.tr("Warning: Input layers have non-matching CRS.\nThis may cause unexpected results."))
        if not summary:
            fieldList2 = ftools_utils.testForUniqueness(fieldList1, fieldList2)
            seq = range(0, len(fieldList1) + len(fieldList2))
            fieldList1.extend(fieldList2)
            fieldList1 = dict(zip(seq, fieldList1))
        else:
            numFields = {}
            for j in xrange(len(fieldList2)):
                if fieldList2[j].type() == QVariant.Int or fieldList2[j].type() == QVariant.Double:
                    numFields[j] = []
                    for i in sumList:
                        field = QgsField(i + unicode(fieldList2[j].name()), QVariant.Double, "real", 24, 16, self.tr("Summary field") )
                        fieldList.append(field)
            field = QgsField("COUNT", QVariant.Double, "real", 24, 16, self.tr("Summary field") )
            fieldList.append(field)
            fieldList2 = ftools_utils.testForUniqueness(fieldList1, fieldList)
            fieldList1.extend(fieldList)
            seq = range(0, len(fieldList1))
            fieldList1 = dict(zip(seq, fieldList1))

        sRs = provider1.crs()
        progressBar.setValue(13)
        check = QFile(self.shapefileName)
        if check.exists():
            if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName):
                QMessageBox.warning( self, self.tr( 'Error deleting shapefile' ),
                            self.tr( "Can't delete existing shapefile\n%s" ) % ( self.shapefileName ) )
                return False
        fields = QgsFields()
        for f in fieldList1.values():
          fields.append(f)
        writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fields, provider1.geometryType(), sRs)
        #writer = QgsVectorFileWriter(outName, "UTF-8", fieldList1, provider1.geometryType(), sRs)
        inFeat = QgsFeature()
        outFeat = QgsFeature()
        inFeatB = QgsFeature()
        inGeom = QgsGeometry()
        progressBar.setValue(15)
        start = 15.00
        add = 85.00 / provider1.featureCount()

        index = ftools_utils.createIndex(provider2)

        # cache all features from provider2 to avoid huge number of feature requests in the inner loop
        mapP2 = {}
        for f in provider2.getFeatures():
            mapP2[f.id()] = QgsFeature(f)

        fit1 = provider1.getFeatures()
        while fit1.nextFeature(inFeat):
            inGeom = inFeat.geometry()
            atMap1 = inFeat.attributes()
            outFeat.setGeometry(inGeom)
            none = True
            joinList = []
            if inGeom.type() == QGis.Point:
                #(check, joinList) = layer2.featuresInRectangle(inGeom.buffer(10,2).boundingBox(), True, True)
                #layer2.select(inGeom.buffer(10,2).boundingBox(), False)
                #joinList = layer2.selectedFeatures()
                joinList = index.intersects( inGeom.buffer(10,2).boundingBox() )
                if len(joinList) > 0: check = 0
                else: check = 1
            else:
                #(check, joinList) = layer2.featuresInRectangle(inGeom.boundingBox(), True, True)
                #layer2.select(inGeom.boundingBox(), False)
                #joinList = layer2.selectedFeatures()
                joinList = index.intersects( inGeom.boundingBox() )
                if len(joinList) > 0: check = 0
                else: check = 1
            if check == 0:
                count = 0
                for i in joinList:
                    inFeatB = mapP2[i]  # cached feature from provider2
                    if inGeom.intersects(inFeatB.geometry()):
                        count = count + 1
                        none = False
                        atMap2 = inFeatB.attributes()
                        if not summary:
                            atMap = atMap1
                            atMap2 = atMap2
                            atMap.extend(atMap2)
                            atMap = dict(zip(seq, atMap))
                            break
                        else:
                            for j in numFields.keys():
                                numFields[j].append(atMap2[j])
                if summary and not none:
                    atMap = atMap1
                    for j in numFields.keys():
                        for k in sumList:
                            if k == "SUM":
                                atMap.append(sum(filter_null(numFields[j])))
                            elif k == "MEAN":
                                try:
                                    nn_count = sum( 1 for _ in filter_null(numFields[j]) )
                                    atMap.append(sum(filter_null(numFields[j])) / nn_count)
                                except ZeroDivisionError:
                                    atMap.append(NULL)
                            elif k == "MIN":
                                try:
                                    atMap.append(min(filter_null(numFields[j])))
                                except ValueError:
                                    atMap.append(NULL)
                            elif k == "MED":
                                atMap.append(myself(numFields[j]))
                            else:
                                try:
                                    atMap.append(max(filter_null(numFields[j])))
                                except ValueError:
                                    atMap.append(NULL)

                        numFields[j] = []
                    atMap.append(count)
                    atMap = dict(zip(seq, atMap))
            if none:
                outFeat.setAttributes(atMap1)
            else:
                outFeat.setAttributes(atMap.values())
            if keep: # keep all records
                writer.addFeature(outFeat)
            else: # keep only matching records
                if not none:
                    writer.addFeature(outFeat)
            start = start + add
            progressBar.setValue(start)
        del writer
        return True
コード例 #4
0
ファイル: doSpatialJoin.py プロジェクト: vivzqs/Quantum-GIS
    def compute(self, inName, joinName, outName, summary, sumList, keep,
                progressBar):
        layer1 = ftools_utils.getVectorLayerByName(inName)
        provider1 = layer1.dataProvider()
        fieldList1 = ftools_utils.getFieldList(layer1).toList()

        layer2 = ftools_utils.getVectorLayerByName(joinName)
        provider2 = layer2.dataProvider()

        fieldList2 = ftools_utils.getFieldList(layer2).toList()
        fieldList = []
        if provider1.crs() != provider2.crs():
            QMessageBox.warning(
                self, self.tr("CRS warning!"),
                self.
                tr("Warning: Input layers have non-matching CRS.\nThis may cause unexpected results."
                   ))
        if not summary:
            fieldList2 = ftools_utils.testForUniqueness(fieldList1, fieldList2)
            seq = range(0, len(fieldList1) + len(fieldList2))
            fieldList1.extend(fieldList2)
            fieldList1 = dict(zip(seq, fieldList1))
        else:
            numFields = {}
            for j in xrange(len(fieldList2)):
                if fieldList2[j].type() == QVariant.Int or fieldList2[j].type(
                ) == QVariant.Double:
                    numFields[j] = []
                    for i in sumList:
                        field = QgsField(i + unicode(fieldList2[j].name()),
                                         QVariant.Double, "real", 24, 16,
                                         self.tr("Summary field"))
                        fieldList.append(field)
            field = QgsField("COUNT", QVariant.Double, "real", 24, 16,
                             self.tr("Summary field"))
            fieldList.append(field)
            fieldList2 = ftools_utils.testForUniqueness(fieldList1, fieldList)
            fieldList1.extend(fieldList)
            seq = range(0, len(fieldList1))
            fieldList1 = dict(zip(seq, fieldList1))

        # check for correct field names
        print fieldList1
        longNames = ftools_utils.checkFieldNameLength(fieldList1.values())
        if not longNames.isEmpty():
            QMessageBox.warning(
                self, self.tr('Incorrect field names'),
                self.
                tr('No output will be created.\nFollowing field names are longer than 10 characters:\n%1'
                   ).arg(longNames.join('\n')))
            return False

        sRs = provider1.crs()
        progressBar.setValue(13)
        check = QFile(self.shapefileName)
        if check.exists():
            if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName):
                QMessageBox.warning(
                    self, self.tr('Error deleting shapefile'),
                    self.tr("Can't delete existing shapefile\n%1").arg(
                        self.shapefileName))
                return False
        fields = QgsFields()
        for f in fieldList1.values():
            fields.append(f)
        writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fields,
                                     provider1.geometryType(), sRs)
        #writer = QgsVectorFileWriter(outName, "UTF-8", fieldList1, provider1.geometryType(), sRs)
        inFeat = QgsFeature()
        outFeat = QgsFeature()
        inFeatB = QgsFeature()
        inGeom = QgsGeometry()
        progressBar.setValue(15)
        start = 15.00
        add = 85.00 / provider1.featureCount()

        index = ftools_utils.createIndex(provider2)
        fit1 = provider1.getFeatures()
        while fit1.nextFeature(inFeat):
            inGeom = inFeat.geometry()
            atMap1 = inFeat.attributes()
            outFeat.setGeometry(inGeom)
            none = True
            joinList = []
            if inGeom.type() == QGis.Point:
                #(check, joinList) = layer2.featuresInRectangle(inGeom.buffer(10,2).boundingBox(), True, True)
                #layer2.select(inGeom.buffer(10,2).boundingBox(), False)
                #joinList = layer2.selectedFeatures()
                joinList = index.intersects(inGeom.buffer(10, 2).boundingBox())
                if len(joinList) > 0: check = 0
                else: check = 1
            else:
                #(check, joinList) = layer2.featuresInRectangle(inGeom.boundingBox(), True, True)
                #layer2.select(inGeom.boundingBox(), False)
                #joinList = layer2.selectedFeatures()
                joinList = index.intersects(inGeom.boundingBox())
                if len(joinList) > 0: check = 0
                else: check = 1
            if check == 0:
                count = 0
                for i in joinList:
                    #tempGeom = i.geometry()
                    provider2.getFeatures(QgsFeatureRequest().setFilterFid(
                        int(i))).nextFeature(inFeatB)
                    tmpGeom = QgsGeometry(inFeatB.geometry())
                    if inGeom.intersects(tmpGeom):
                        count = count + 1
                        none = False
                        atMap2 = inFeatB.attributes()
                        if not summary:
                            atMap = atMap1
                            atMap2 = atMap2
                            atMap.extend(atMap2)
                            atMap = dict(zip(seq, atMap))
                            break
                        else:
                            for j in numFields.keys():
                                numFields[j].append(atMap2[j].toDouble()[0])
                if summary and not none:
                    atMap = atMap1
                    for j in numFields.keys():
                        for k in sumList:
                            if k == "SUM":
                                atMap.append(QVariant(sum(numFields[j])))
                            elif k == "MEAN":
                                atMap.append(
                                    QVariant(sum(numFields[j]) / count))
                            elif k == "MIN":
                                atMap.append(QVariant(min(numFields[j])))
                            elif k == "MED":
                                atMap.append(QVariant(myself(numFields[j])))
                            else:
                                atMap.append(QVariant(max(numFields[j])))
                        numFields[j] = []
                    atMap.append(QVariant(count))
                    atMap = dict(zip(seq, atMap))
            if none:
                outFeat.setAttributes(atMap1)
            else:
                outFeat.setAttributes(atMap.values())
            if keep:  # keep all records
                writer.addFeature(outFeat)
            else:  # keep only matching records
                if not none:
                    writer.addFeature(outFeat)
            start = start + add
            progressBar.setValue(start)
        del writer
        return True