示例#1
0
文件: join.py 项目: ImageCatInc/sidd
    def do_operation(self):
        """ perform create mapping scheme operation """
        
        # input/output verification already performed during set input/ouput
        zone_layer = self.inputs[0].value
        zone_field = self.inputs[1].value                
        fp_layer = self.inputs[2].value
        
        # merge with zone to get assignment
        tmp_join = 'joined_%s' % get_unique_filename()
        tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join)        
        analyzer = QgsOverlayAnalyzer()        
        try:
            analyzer.intersection(fp_layer, zone_layer, tmp_join_file)
            tmp_join_layer = load_shapefile_verify(tmp_join_file, tmp_join,[zone_field])
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)
        
        fields = {
            0 : QgsField(self._lon_field, QVariant.Double),
            1 : QgsField(self._lat_field, QVariant.Double),
            2 : QgsField(zone_field, QVariant.String),
        }
        zone_idx = layer_field_index(tmp_join_layer, zone_field)
        fp_layername = 'fpc_%s' % get_unique_filename()
        fp_file = '%s%s.shp' % (self._tmp_dir, fp_layername)
        try:
            writer = QgsVectorFileWriter(fp_file, "utf-8", fields, QGis.WKBPoint, self._crs, "ESRI Shapefile")
            f = QgsFeature()
            for _f in layer_features(tmp_join_layer):                
                centroid = _f.geometry().centroid().asPoint()
                lon = centroid.x()
                lat = centroid.y()
                zone_str = str(_f.attributeMap()[zone_idx].toString()).upper()

                f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat)))
                f.addAttribute(0, QVariant(lon))
                f.addAttribute(1, QVariant(lat))
                f.addAttribute(2, QVariant(zone_str))
                writer.addFeature(f)
            
            del writer
        except Exception as err:
            logAPICall.log(err, logAPICall.ERROR)
            remove_shapefile(fp_file)
            raise OperatorError("error creating joined grid: %s" % err, self.__class__)
        
        # load shapefile as layer
        fp_layer = load_shapefile(fp_file, fp_layername)
        if not fp_layer:
            raise OperatorError('Error loading footprint centroid file' % (fp_file), self.__class__)        
                
        # clean up
        del tmp_join_layer        
        remove_shapefile(tmp_join_file)
        
        self.outputs[0].value = fp_layer
        self.outputs[1].value = fp_file
示例#2
0
 def test_AddAttribute(self):
     feat = QgsFeature()
     feat.addAttribute(1, "text")
     myCount = len(feat.attributeMap())
     myExpectedCount = 1
     myMessage = '\nExpected: %s\nGot: %s' % (myExpectedCount, myCount)
     assert myCount == myExpectedCount, myMessage        
示例#3
0
    def _write_grid_shapefile(self, path, x_min, y_min, x_max, y_max, x_off,
                              y_off):
        x_off = self._x_off
        y_off = self._y_off
        x_min = floor(x_min / x_off) * x_off
        x_max = ceil(x_max / x_off) * x_off
        y_min = floor(y_min / y_off) * y_off
        y_max = ceil(y_max / y_off) * y_off

        xtotal = int((x_max - x_min) / x_off)
        ytotal = int((y_max - y_min) / y_off)

        logAPICall.log(
            'x_min %f x_max %f y_min %f y_max %f x_off %f y_off %f xtotal %d, ytotal %d'
            % (x_min, x_max, y_min, y_max, x_off, y_off, xtotal, ytotal),
            logAPICall.DEBUG_L2)

        writer = QgsVectorFileWriter(path, "utf-8", self._fields,
                                     QGis.WKBPoint, self._crs,
                                     "ESRI Shapefile")
        f = QgsFeature()
        for x in range(xtotal):
            for y in range(ytotal):
                lon = x_min + (x * x_off) + (x_off / 2.0)
                lat = y_min + (y * y_off) + (y_off / 2.0)
                f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat)))
                f.addAttribute(0, QVariant(lon))
                f.addAttribute(1, QVariant(lat))
                writer.addFeature(f)
        del writer
示例#4
0
 def test_AddAttribute(self):
     feat = QgsFeature()
     feat.addAttribute(1, "text")
     myCount = len(feat.attributeMap())
     myExpectedCount = 1
     myMessage = '\nExpected: %s\nGot: %s' % (myExpectedCount, myCount)
     assert myCount == myExpectedCount, myMessage
 def saveIntersectionResult(self, report, intersectedPoint):
     # save the intersection result (point) and its report
     # check first
     while True:
         if not self.settings.value("advancedIntersectionWritePoint"):
             break  # if we do not place any point, skip
         layerid = self.settings.value("advancedIntersectionLayer")
         message = QCoreApplication.translate("IntersectIt",
                                              "To place the intersection solution,"
                                              " you must select a layer in the settings.")
         status, intLayer = self.checkLayerExists(layerid, message)
         if status == 2:
             continue
         if status == 3:
             return
         if self.settings.value("advancedIntersectionWriteReport"):
             reportField = self.settings.value("reportField")
             message = QCoreApplication.translate("IntersectIt",
                                                  "To save the intersection report, please select a field for it.")
             status = self.checkFieldExists(intLayer, reportField, message)
             if status == 2:
                 continue
             if status == 3:
                 return
         break
     # save the intersection results
     if self.settings.value("advancedIntersectionWritePoint"):
         f = QgsFeature()
         f.setGeometry(QgsGeometry().fromPoint(intersectedPoint))
         if self.settings.value("advancedIntersectionWriteReport"):
             irep = intLayer.dataProvider().fieldNameIndex(reportField)
             f.addAttribute(irep, report)
         intLayer.dataProvider().addFeatures([f])
         intLayer.updateExtents()
         self.mapCanvas.refresh()
示例#6
0
文件: grids.py 项目: gem/sidd
    def _create_grid(self, grid_name, grid_file, x_min, y_min, x_max, y_max, x_off, y_off):
        x_off2, y_off2 = x_off / 2.0, y_off / 2.0
        x_min = floor(x_min / x_off) * x_off
        x_max = ceil(x_max / x_off) * x_off
        y_min = floor(y_min / y_off) * y_off
        y_max = ceil(y_max / y_off) * y_off

        xtotal = int((x_max - x_min) / x_off) + 1
        ytotal = int((y_max - y_min) / y_off) + 1

        logAPICall.log(
            "x_min %f x_max %f y_min %f y_max %f x_off %f y_off %f xtotal %d, ytotal %d"
            % (x_min, x_max, y_min, y_max, x_off, y_off, xtotal, ytotal),
            logAPICall.DEBUG_L2,
        )
        fields = {0: QgsField("GRID_GID", QVariant.String)}
        writer = QgsVectorFileWriter(grid_file, "utf-8", fields, QGis.WKBPolygon, self._crs, "ESRI Shapefile")
        f = QgsFeature()
        for x in range(xtotal):
            for y in range(ytotal):
                lon = x_min + (x * x_off) + (x_off2)
                lat = y_min + (y * y_off) + (y_off2)
                # out_geom = QgsGeometry.fromRect(QgsRectangle(lon-x_off2, lat-y_off2,
                #                                             lon+x_off2, lat+y_off2))
                f.setGeometry(self._outputGeometryFromLatLon(lat, lon))
                f.addAttribute(0, QVariant(latlon_to_grid(lat, lon)))
                writer.addFeature(f)
        del writer
        return load_shapefile(grid_file, grid_name)
示例#7
0
文件: grid.py 项目: ImageCatInc/sidd
 def _write_grid_shapefile(self, path, x_min, y_min, x_max, y_max, x_off, y_off):
     x_off = self._x_off        
     y_off = self._y_off        
     x_min = floor(x_min / x_off) * x_off
     x_max = ceil(x_max / x_off) * x_off
     y_min = floor(y_min / y_off) * y_off
     y_max = ceil(y_max / y_off) * y_off
     
     xtotal = int((x_max - x_min) / x_off)
     ytotal = int((y_max - y_min) / y_off)
     
     logAPICall.log('x_min %f x_max %f y_min %f y_max %f x_off %f y_off %f xtotal %d, ytotal %d'
                    % (x_min, x_max, y_min, y_max, x_off, y_off, xtotal, ytotal),
                    logAPICall.DEBUG_L2)
     
     writer = QgsVectorFileWriter(path, "utf-8", self._fields, QGis.WKBPoint, self._crs, "ESRI Shapefile")
     f = QgsFeature()
     for x in range(xtotal):
         for y in range(ytotal):
             lon = x_min + (x * x_off) + (x_off/2.0)
             lat = y_min + (y * y_off) + (y_off/2.0)
             f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat)))
             f.addAttribute(0, QVariant(lon))
             f.addAttribute(1, QVariant(lat))
             writer.addFeature(f)
     del writer
示例#8
0
文件: grids.py 项目: gem/sidd
    def _create_grid(self, grid_name, grid_file, x_min, y_min, x_max, y_max, x_off, y_off):
        x_off2, y_off2 = x_off / 2.0, y_off / 2.0
        x_min = floor(x_min / x_off) * x_off
        x_max = ceil(x_max / x_off) * x_off
        y_min = floor(y_min / y_off) * y_off
        y_max = ceil(y_max / y_off) * y_off
        
        xtotal = int((x_max - x_min) / x_off)+1
        ytotal = int((y_max - y_min) / y_off)+1

        logAPICall.log('x_min %f x_max %f y_min %f y_max %f x_off %f y_off %f xtotal %d, ytotal %d'
                       % (x_min, x_max, y_min, y_max, x_off, y_off, xtotal, ytotal),
                       logAPICall.DEBUG_L2)
        fields = {
            0 : QgsField('GRID_GID', QVariant.String),            
        }
        writer = QgsVectorFileWriter(grid_file, "utf-8", fields, QGis.WKBPolygon, self._crs, "ESRI Shapefile")
        f = QgsFeature()
        for x in range(xtotal):
            for y in range(ytotal):
                lon = x_min + (x * x_off) + (x_off2)
                lat = y_min + (y * y_off) + (y_off2)                
                #out_geom = QgsGeometry.fromRect(QgsRectangle(lon-x_off2, lat-y_off2,
                #                                             lon+x_off2, lat+y_off2))                                
                f.setGeometry(self._outputGeometryFromLatLon(lat, lon))                
                f.addAttribute(0, QVariant(latlon_to_grid(lat, lon)))                
                writer.addFeature(f)
        del writer 
        return load_shapefile(grid_file, grid_name)        
示例#9
0
 def test_CreateFeature(self):
     feat = QgsFeature()
     feat.addAttribute(1, "text")
     feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(123,456)))
     myId = feat.id()
     myExpectedId = 0
     myMessage = '\nExpected: %s\nGot: %s' % (myExpectedId, myId)
     assert myId == myExpectedId, myMessage
示例#10
0
 def test_CreateFeature(self):
     feat = QgsFeature()
     feat.addAttribute(1, "text")
     feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(123, 456)))
     myId = feat.id()
     myExpectedId = 0
     myMessage = '\nExpected: %s\nGot: %s' % (myExpectedId, myId)
     assert myId == myExpectedId, myMessage
示例#11
0
 def test_ChangeAttribute(self):
     feat = QgsFeature()
     feat.addAttribute(1, "text")
     feat.changeAttribute(1, "changed")
     myChangedAttribute = feat.attributeMap()[1].toString()
     myExpectedAttribute = "changed"
     myMessage = '\nExpected: %s\nGot: %s' % (myExpectedAttribute, 
         myChangedAttribute)
     assert myChangedAttribute == myExpectedAttribute, myMessage        
示例#12
0
 def test_ChangeAttribute(self):
     feat = QgsFeature()
     feat.addAttribute(1, "text")
     feat.changeAttribute(1, "changed")
     myChangedAttribute = feat.attributeMap()[1].toString()
     myExpectedAttribute = "changed"
     myMessage = '\nExpected: %s\nGot: %s' % (myExpectedAttribute,
                                              myChangedAttribute)
     assert myChangedAttribute == myExpectedAttribute, myMessage
示例#13
0
    def do_operation(self):
        """ perform export operation """        
        # input/output data checking already done during property set
        input_file = self.inputs[0].value
        output_file = self.inputs[1].value
        output_dbf = '%s_attr.dbf' % output_file[:-3]
        try:
            exp_layer = load_shapefile(input_file, 'exposure_%s' % get_unique_filename())
            
            # store id of distinct features            
            total_features = exp_layer.dataProvider().featureCount()
            if total_features > MAX_FEATURES_IN_MEMORY:
                # use bsddb to store id in case number of features is too large
                tmp_db_file = '%sdb_%s.db' % (self._tmp_dir, get_unique_filename())
                db = bsddb.btopen(tmp_db_file, 'c')
                use_db = True
            else:
                # in memory dictionary, should be much faster, but could fail
                # if memory is limited
                db = {}
                use_db = False
                        
            # get field index for GID
            gid_idx = layer_field_index(exp_layer, GID_FIELD_NAME)
            fields = {
                0: QgsField(GID_FIELD_NAME, QVariant.Int),
            }            
            writer = QgsVectorFileWriter(output_file, "utf-8", fields, 
                                         exp_layer.dataProvider().geometryType(), 
                                         exp_layer.crs(), "ESRI Shapefile")
            out_feature = QgsFeature()
            for feature in layer_features(exp_layer):
                gid = str(feature.attributeMap()[gid_idx].toString())
                # only write out once 
                if not db.has_key(gid):
                    db[gid]= '1'    # bsddb only accepts string 
                    out_feature.addAttribute(0, gid)
                    out_feature.setGeometry(feature.geometry())
                    writer.addFeature(out_feature)
                    
            # clean up
            del writer                
            if use_db:
                db.close()
                os.remove(tmp_db_file)

            # copy associated attribute file            
            copy_shapefile(input_file, output_dbf, extensions=['.dbf'])
        except Exception as err:
            raise OperatorError("error creating shapefile: %s" % err, self.__class__)
示例#14
0
    def addGeomToMemoryLayer(self, the_geom, origin=0, delete_when_done=False):
        """TO DO: Add doc string"""
        foi_type = self.foi_type.lower()
        print "got foi_type"
        if self.mem_layer_obj.featureCount() > 0:
            if origin == 1:  # is added by identify operation
                pass
            else:
                print self.mem_layer_obj.featureCount()
                print "there exists a feature, kill it!"
                self.mem_layer_obj.select()
                print "Feature count selcted for deletion:"
                print self.mem_layer_obj.selectedFeatureCount()
                self.mem_layer_obj.deleteSelectedFeatures()
                #self.mem_layer_obj.deleteFeature(0)
                self.mem_layer_obj.commitChanges()
                self.mem_layer_obj.triggerRepaint()

        ml_dp = self.mem_layer_obj.dataProvider()
        print "got DP"
        uuid_gid = QtCore.QUuid().createUuid().toString()
        print "got uuid"
        fet = QgsFeature()
        print "got feature with id"
        fet.setGeometry(the_geom)
        print "set geometry"
        fet.addAttribute(0, uuid_gid)
        print "set attr "
        ml_dp.addFeatures([fet])
        self.mem_layer_obj.commitChanges()
        print "added layers"
        #self.mem_layer_obj.updateFeatureAttributes(fet)
        #self.mem_layer_obj.updateFeatureGeometry(fet)
        self.mem_layer_obj.updateExtents()
        print "updated extents"
        #self.mem_layer_obj.drawFeature(fet)
        self.mem_layer_obj.triggerRepaint()
        print "trp"
        return fet.id()
示例#15
0
 def saveIntersectionResult(self, report, intersectedPoint):
     # save the intersection result (point) and its report
     # check first
     while True:
         if not self.settings.value("advancedIntersectionWritePoint"):
             break  # if we do not place any point, skip
         layerid = self.settings.value("advancedIntersectionLayer")
         message = QCoreApplication.translate(
             "IntersectIt", "To place the intersection solution,"
             " you must select a layer in the settings.")
         status, intLayer = self.checkLayerExists(layerid, message)
         if status == 2:
             continue
         if status == 3:
             return
         if self.settings.value("advancedIntersectionWriteReport"):
             reportField = self.settings.value("reportField")
             message = QCoreApplication.translate(
                 "IntersectIt",
                 "To save the intersection report, please select a field for it."
             )
             status = self.checkFieldExists(intLayer, reportField, message)
             if status == 2:
                 continue
             if status == 3:
                 return
         break
     # save the intersection results
     if self.settings.value("advancedIntersectionWritePoint"):
         f = QgsFeature()
         f.setGeometry(QgsGeometry().fromPoint(intersectedPoint))
         if self.settings.value("advancedIntersectionWriteReport"):
             irep = intLayer.dataProvider().fieldNameIndex(reportField)
             f.addAttribute(irep, report)
         intLayer.dataProvider().addFeatures([f])
         intLayer.updateExtents()
         self.mapCanvas.refresh()
示例#16
0
    def createFeature(self, geom):
        # pydevd.settrace()
        layer = self.canvas.currentLayer()
        provider = layer.dataProvider()
        f = QgsFeature()

        # if (geom.validateGeometry()):
        if (geom.isGeosValid()):
            f.setGeometry(geom)
        else:
            reply = QMessageBox.question(self.iface.mainWindow(), 'Feature not valid',
                                         "The geometry of the feature you just added isn't valid. Do you want to use it anyway?",
                                         QMessageBox.Yes, QMessageBox.No)
            if reply == QMessageBox.Yes:
                f.setGeometry(geom)
            else:
                return False

        ## Add attributefields to feature.
        fields = layer.pendingFields()

        try:  # API-Break 1.8 vs. 2.0 handling
            attr = f.initAttributes(len(fields))
            for i in range(len(fields)):
                f.setAttribute(i, provider.defaultValue(i))

        except AttributeError:  # <=1.8
            ## Add attributefields to feature.
            for i in fields:
                f.addAttribute(i, provider.defaultValue(i))

        layer.beginEditCommand("Feature added")
        layer.addFeature(f)
        layer.endEditCommand()

        self.canvas.refresh()
def insertShapeFileValues(layer, attributes, values, coords):
    # get the geometry type
    # todo: not working yet. attribute ids must match those from table.
    # use createShapeFileFullLayer instead
    res = False
    if layer:
        geom_type = layer.geometryType()
        provider = layer.dataProvider()
        caps = provider.capabilities()
        if caps & QgsVectorDataProvider.AddFeatures:
            # add features by iterating the values
            features = []
            for val in values:
                feat = QgsFeature()
                # add geometry
                try:
                    if geom_type in (0, 3):
                        feat.setGeometry(
                            QgsGeometry.fromPoint([QgsPoint(float(val[coords[0]]), float(val[coords[1]]))]))
                    elif geom_type in (1, 4):
                        feat.setGeometry(
                            QgsGeometry.fromPolyline([QgsPoint(float(val[coords[0]]), float(val[coords[1]])),
                                                      QgsPoint(float(val[coords[2]]), float(val[coords[3]]))]))
                except:
                    pass
                # add attributes
                for i, x in enumerate(val):
                    feat.addAttribute(i, x)
                features.append(feat)
            res, outFeats = provider.addFeatures(features)
            layer.updateFields()
        else:
            res = False
    else:
        res = False
    return res
示例#18
0
文件: survey.py 项目: gem/sidd
 def _loadSurvey(self, csvpath, shapefilepath):
     # load data
     data = csv.reader(open(csvpath, "r"), delimiter=",", quotechar='"')
     # skip header, there is probably a better way to accomplish this
     data.next()
     writer = QgsVectorFileWriter(shapefilepath, "utf-8", self._fields, QGis.WKBPoint, self._crs, "ESRI Shapefile")
     f = QgsFeature()
     gid = 0
     for row in data:
         lon = float(row[0])
         lat = float(row[1])
         f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat)))
         gid += 1
         f.addAttribute(0, QVariant(gid))
         f.addAttribute(1, QVariant(lon))
         f.addAttribute(2, QVariant(lat))
         f.addAttribute(3, QVariant(row[2]))
         writer.addFeature(f)
     del writer, f
示例#19
0
 def _loadSurvey(self, csvpath, shapefilepath):
     # load data
     data = csv.reader(open(csvpath, 'r'), delimiter=',', quotechar='"')
     # skip header, there is probably a better way to accomplish this
     data.next()
     writer = QgsVectorFileWriter(shapefilepath, "utf-8", self._fields,
                                  QGis.WKBPoint, self._crs,
                                  "ESRI Shapefile")
     f = QgsFeature()
     gid = 0
     for row in data:
         lon = float(row[0])
         lat = float(row[1])
         f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat)))
         gid += 1
         f.addAttribute(0, QVariant(gid))
         f.addAttribute(1, QVariant(lon))
         f.addAttribute(2, QVariant(lat))
         f.addAttribute(3, QVariant(row[2]))
         writer.addFeature(f)
     del writer, f
示例#20
0
文件: join.py 项目: gem/sidd
    def do_operation(self):
        """ perform create mapping scheme operation """

        # input/output verification already performed during set input/ouput
        zone_layer = self.inputs[0].value
        zone_field = self.inputs[1].value
        zone_count_field = self.inputs[2].value
        fp_layer = self.inputs[3].value

        # merge with zone
        tmp_join = 'joined_%s' % get_unique_filename()
        tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join)
        analyzer = QgsOverlayAnalyzer()
        try:
            analyzer.intersection(fp_layer, zone_layer, tmp_join_file)
            tmp_join_layer = load_shapefile(tmp_join_file, tmp_join)
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)

        # count footprint in each zone
        gid_idx = layer_field_index(tmp_join_layer, GID_FIELD_NAME + "_")
        area_idx = layer_field_index(tmp_join_layer, AREA_FIELD_NAME)
        ht_idx = layer_field_index(tmp_join_layer, HT_FIELD_NAME)
        stats = {}
        for _feature in layer_features(tmp_join_layer):
            gid = _feature.attributeMap()[gid_idx].toString()
            if ht_idx > 0:
                ht = _feature.attributeMap()[ht_idx].toDouble()[0]
            else:
                ht = 0
            # if height is not defined, it is set to 0
            # this will cause the system to ignore area generate without having to
            # remove the field
            area = _feature.attributeMap()[area_idx].toDouble()[0] * ht  #
            if not stats.has_key(gid):
                stats[gid] = (1, area)
            else:
                stat = stats[gid]
                stats[gid] = (stat[0] + 1, stat[1] + area)

        output_layername = 'zone_%s' % get_unique_filename()
        output_file = '%s%s.shp' % (self._tmp_dir, output_layername)
        logAPICall.log('create outputfile %s ... ' % output_file,
                       logAPICall.DEBUG)
        try:
            fields = {
                0: QgsField(GID_FIELD_NAME, QVariant.Int),
                1: QgsField(zone_field, QVariant.String),
                2: QgsField(CNT_FIELD_NAME, QVariant.Int),
                3: QgsField(AREA_FIELD_NAME, QVariant.Int),
            }
            writer = QgsVectorFileWriter(output_file, "utf-8", fields,
                                         QGis.WKBPolygon, self._crs,
                                         "ESRI Shapefile")
            f = QgsFeature()
            for _f in layer_features(zone_layer):

                # write to file
                f.setGeometry(_f.geometry())
                f.addAttribute(0, _f.attributeMap()[0])
                f.addAttribute(1, _f.attributeMap()[1])

                # retrieve count from statistic
                try:
                    gid = _f.attributeMap()[0].toString()
                    stat = stats[gid]
                    bldg_count = stat[0]
                    area = stat[1]
                except:
                    bldg_count, area = 0, 0
                f.addAttribute(2, QVariant(bldg_count))
                f.addAttribute(3, QVariant(area))
                writer.addFeature(f)

            del writer, f
        except Exception as err:
            remove_shapefile(output_file)
            raise OperatorError("error creating zone: %s" % err,
                                self.__class__)

        # clean up
        del tmp_join_layer
        remove_shapefile(tmp_join_file)

        # store data in output
        output_layer = load_shapefile(output_file, output_layername)
        if not output_layer:
            raise OperatorError(
                'Error loading footprint centroid file' % (output_file),
                self.__class__)
        self.outputs[0].value = output_layer
        self.outputs[1].value = output_file
示例#21
0
文件: grids.py 项目: gem/sidd
    def do_operation(self):
        """ perform create mappin """
        # validate inputs 
        popgrid_layer = self.inputs[0].value        
        zone_layer = self.inputs[1].value
        zone_field = self.inputs[2].value
        pop_to_bldg = float(self.inputs[3].value)

        # make sure input is correct
        # NOTE: these checks cannot be performed at set input time
        #       because the data layer maybe is not loaded yet
        self._test_layer_loaded(popgrid_layer)
        self._test_layer_field_exists(popgrid_layer, CNT_FIELD_NAME)
        self._test_layer_loaded(zone_layer)
        self._test_layer_field_exists(zone_layer, zone_field)        
        # count_field is not required        
        # if count field is not defined, then generate building count from footprints
        
        # local variables 
        analyzer = QgsOverlayAnalyzer()

        # intersect grids and zones to obtain polygons with 
        # - population and zone_id
        # - apply ratio to population to obtain building count                  
        tmp_join = 'joined_%s' % get_unique_filename()
        tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join)
        try:
            # do intersection
            analyzer.intersection(popgrid_layer, zone_layer, tmp_join_file)
            tmp_join_layer = load_shapefile(tmp_join_file, tmp_join)
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)

        # generate grid with  building counts
        fields = {
            0 : QgsField(GID_FIELD_NAME, QVariant.String),            
            1 : QgsField(zone_field, QVariant.String),
            2 : QgsField(CNT_FIELD_NAME, QVariant.Double),
        }
        output_layername = 'grid_%s' % get_unique_filename()
        output_file = '%s%s.shp' % (self._tmp_dir, output_layername)                
        writer = QgsVectorFileWriter(output_file, "utf-8", fields, QGis.WKBPolygon, self._crs, "ESRI Shapefile")
        f = QgsFeature()
        pop_idx = layer_field_index(tmp_join_layer, CNT_FIELD_NAME)
        zone_idx = layer_field_index(tmp_join_layer, zone_field) 
        for _f in layer_features(tmp_join_layer):
            pop_count = _f.attributeMap()[pop_idx].toDouble()[0]
            zone = _f.attributeMap()[zone_idx].toString()
            
            # 1. get geometry
            geom = _f.geometry()
            # 2. get original centroid point and project is required
            centroid  = geom.centroid().asPoint()
            grid_gid = latlon_to_grid(centroid.y(), centroid.x())
            f.setGeometry(self._outputGeometryFromGridId(grid_gid))
            f.addAttribute(0, grid_gid)
            f.addAttribute(1, zone)
            f.addAttribute(2, pop_count / pop_to_bldg)
            writer.addFeature(f)
        del writer
        
        # clean up
        del tmp_join_layer
        remove_shapefile(tmp_join_file)
                
        # store data in output
        self._load_output(output_file, output_layername)
示例#22
0
文件: grids.py 项目: gem/sidd
    def do_operation(self):
        # validate inputs        
        zone_layer = self.inputs[0].value
        zone_field = self.inputs[1].value
        count_field = self.inputs[2].value
        area_field = self.inputs[3].value
        
        # make sure input is correct
        # NOTE: these checks cannot be performed at set input time
        #       because the data layer maybe is not loaded yet
        self._test_layer_loaded(zone_layer)
        self._test_layer_field_exists(zone_layer, GID_FIELD_NAME)
        self._test_layer_field_exists(zone_layer, zone_field)        
        self._test_layer_field_exists(zone_layer, count_field)
        
        # local variables 
        analyzer = QgsOverlayAnalyzer()
        area_idx = ToGrid.STAT_AREA_IDX
        #cnt_idx = ToGrid.STAT_COUNT_IDX
        
        # 1. find building count and total area for each zone
        zone_names, zone_stat= {}, {}
        try:
            self._create_zone_statistics(zone_layer, zone_field, count_field, 
                                         zone_stat, zone_names)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)    
    
        # 2. create grids around extent of zone 
        tmp_grid1 = 'grid_' + get_unique_filename()
        tmp_grid1_file = self._tmp_dir + tmp_grid1 + '.shp'
        try:
            extent = zone_layer.extent()
            [x_min, y_min, x_max, y_max] = [extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum()]
            tmp_grid_lyr1 = self._create_grid(tmp_grid1, tmp_grid1_file, \
                                              x_min, y_min, x_max, y_max, \
                                              DEFAULT_GRID_SIZE, DEFAULT_GRID_SIZE)            
        except Exception as err:
            raise OperatorError(str(err), self.__class__)    
        
        # 3. intersect grids and zones to obtain polygons with 
        # - grid_id and zone_id
        # - ratio of grid covered by zone (polygon area / zone area) 
        # apply ratio to zone building count to obtain count assigned to polygon                  
        tmp_join = 'joined_%s' % get_unique_filename()
        tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join)
        try:
            # do intersection
            analyzer.intersection(tmp_grid_lyr1, zone_layer, tmp_join_file)
            tmp_join_layer = load_shapefile(tmp_join_file, tmp_join)
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)
        
        # do tally        
        zone_gid_idx = layer_field_index(tmp_join_layer, GID_FIELD_NAME)
        grid_gid_idx = layer_field_index(tmp_join_layer, "GRID_GID")
        bldg_cnt_idx = layer_field_index(tmp_join_layer, count_field)
        bldg_area_idx = layer_field_index(tmp_join_layer, area_field)
        mercator_transform = QgsCoordinateTransform(tmp_join_layer.crs(),
                                                    self.mercator_crs)          

        fields = {
            0 : QgsField(GID_FIELD_NAME, QVariant.String),            
            1 : QgsField(zone_field, QVariant.String),
            2 : QgsField(CNT_FIELD_NAME, QVariant.Double),
            3 : QgsField(AREA_FIELD_NAME, QVariant.Double),
        }    
        output_layername = 'grid_%s' % get_unique_filename()
        output_file = '%s%s.shp' % (self._tmp_dir, output_layername)                
        writer = QgsVectorFileWriter(output_file, "utf-8", fields, QGis.WKBPolygon, self._crs, "ESRI Shapefile")
        f = QgsFeature() 
        for _f in layer_features(tmp_join_layer):
            # get area of polygon            
            geom = _f.geometry()
            geom.transform(mercator_transform)
            area = geom.area()

            # generate all stats of interest
            zone_gid = _f.attributeMap()[zone_gid_idx].toString()
            grid_gid = _f.attributeMap()[grid_gid_idx].toString()
            stat = zone_stat[zone_gid]
            
            # calculate count/area as proportion of total zone area
            bldg_cnt = _f.attributeMap()[bldg_cnt_idx].toDouble()[0] * (area/stat[area_idx])
            if bldg_area_idx> 0:
                bldg_area = _f.attributeMap()[bldg_area_idx].toDouble()[0] * (area/stat[area_idx])                
            else:
                bldg_area = 0 

            # create output record
            f.setGeometry(self._outputGeometryFromGridId(grid_gid))
            f.addAttribute(0, grid_gid)
            f.addAttribute(1, zone_names[QString(zone_gid)])
            f.addAttribute(2, bldg_cnt)
            f.addAttribute(3, bldg_area)
            writer.addFeature(f)        
        del writer    

        # clean up
        del tmp_grid_lyr1
        del tmp_join_layer
        remove_shapefile(tmp_grid1_file)
        remove_shapefile(tmp_join_file)
                
        # store data in output
        self._load_output(output_file, output_layername)
示例#23
0
文件: grids.py 项目: gem/sidd
    def do_operation(self):
        """ perform create mappin """
        # validate inputs
        popgrid_layer = self.inputs[0].value
        zone_layer = self.inputs[1].value
        zone_field = self.inputs[2].value
        pop_to_bldg = float(self.inputs[3].value)

        # make sure input is correct
        # NOTE: these checks cannot be performed at set input time
        #       because the data layer maybe is not loaded yet
        self._test_layer_loaded(popgrid_layer)
        self._test_layer_field_exists(popgrid_layer, CNT_FIELD_NAME)
        self._test_layer_loaded(zone_layer)
        self._test_layer_field_exists(zone_layer, zone_field)
        # count_field is not required
        # if count field is not defined, then generate building count from footprints

        # local variables
        analyzer = QgsOverlayAnalyzer()

        # intersect grids and zones to obtain polygons with
        # - population and zone_id
        # - apply ratio to population to obtain building count
        tmp_join = "joined_%s" % get_unique_filename()
        tmp_join_file = "%s%s.shp" % (self._tmp_dir, tmp_join)
        try:
            # do intersection
            analyzer.intersection(popgrid_layer, zone_layer, tmp_join_file)
            tmp_join_layer = load_shapefile(tmp_join_file, tmp_join)
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)

        # generate grid with  building counts
        fields = {
            0: QgsField(GID_FIELD_NAME, QVariant.String),
            1: QgsField(zone_field, QVariant.String),
            2: QgsField(CNT_FIELD_NAME, QVariant.Double),
        }
        output_layername = "grid_%s" % get_unique_filename()
        output_file = "%s%s.shp" % (self._tmp_dir, output_layername)
        writer = QgsVectorFileWriter(output_file, "utf-8", fields, QGis.WKBPolygon, self._crs, "ESRI Shapefile")
        f = QgsFeature()
        pop_idx = layer_field_index(tmp_join_layer, CNT_FIELD_NAME)
        zone_idx = layer_field_index(tmp_join_layer, zone_field)
        for _f in layer_features(tmp_join_layer):
            pop_count = _f.attributeMap()[pop_idx].toDouble()[0]
            zone = _f.attributeMap()[zone_idx].toString()

            # 1. get geometry
            geom = _f.geometry()
            # 2. get original centroid point and project is required
            centroid = geom.centroid().asPoint()
            grid_gid = latlon_to_grid(centroid.y(), centroid.x())
            f.setGeometry(self._outputGeometryFromGridId(grid_gid))
            f.addAttribute(0, grid_gid)
            f.addAttribute(1, zone)
            f.addAttribute(2, pop_count / pop_to_bldg)
            writer.addFeature(f)
        del writer

        # clean up
        del tmp_join_layer
        remove_shapefile(tmp_join_file)

        # store data in output
        self._load_output(output_file, output_layername)
示例#24
0
文件: grids.py 项目: gem/sidd
    def do_operation(self):
        # validate inputs
        zone_layer = self.inputs[0].value
        zone_field = self.inputs[1].value
        count_field = self.inputs[2].value
        area_field = self.inputs[3].value

        # make sure input is correct
        # NOTE: these checks cannot be performed at set input time
        #       because the data layer maybe is not loaded yet
        self._test_layer_loaded(zone_layer)
        self._test_layer_field_exists(zone_layer, GID_FIELD_NAME)
        self._test_layer_field_exists(zone_layer, zone_field)
        self._test_layer_field_exists(zone_layer, count_field)

        # local variables
        analyzer = QgsOverlayAnalyzer()
        area_idx = ToGrid.STAT_AREA_IDX
        # cnt_idx = ToGrid.STAT_COUNT_IDX

        # 1. find building count and total area for each zone
        zone_names, zone_stat = {}, {}
        try:
            self._create_zone_statistics(zone_layer, zone_field, count_field, zone_stat, zone_names)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)

        # 2. create grids around extent of zone
        tmp_grid1 = "grid_" + get_unique_filename()
        tmp_grid1_file = self._tmp_dir + tmp_grid1 + ".shp"
        try:
            extent = zone_layer.extent()
            [x_min, y_min, x_max, y_max] = [extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum()]
            tmp_grid_lyr1 = self._create_grid(
                tmp_grid1, tmp_grid1_file, x_min, y_min, x_max, y_max, DEFAULT_GRID_SIZE, DEFAULT_GRID_SIZE
            )
        except Exception as err:
            raise OperatorError(str(err), self.__class__)

        # 3. intersect grids and zones to obtain polygons with
        # - grid_id and zone_id
        # - ratio of grid covered by zone (polygon area / zone area)
        # apply ratio to zone building count to obtain count assigned to polygon
        tmp_join = "joined_%s" % get_unique_filename()
        tmp_join_file = "%s%s.shp" % (self._tmp_dir, tmp_join)
        try:
            # do intersection
            analyzer.intersection(tmp_grid_lyr1, zone_layer, tmp_join_file)
            tmp_join_layer = load_shapefile(tmp_join_file, tmp_join)
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)

        # do tally
        zone_gid_idx = layer_field_index(tmp_join_layer, GID_FIELD_NAME)
        grid_gid_idx = layer_field_index(tmp_join_layer, "GRID_GID")
        bldg_cnt_idx = layer_field_index(tmp_join_layer, count_field)
        bldg_area_idx = layer_field_index(tmp_join_layer, area_field)
        mercator_transform = QgsCoordinateTransform(tmp_join_layer.crs(), self.mercator_crs)

        fields = {
            0: QgsField(GID_FIELD_NAME, QVariant.String),
            1: QgsField(zone_field, QVariant.String),
            2: QgsField(CNT_FIELD_NAME, QVariant.Double),
            3: QgsField(AREA_FIELD_NAME, QVariant.Double),
        }
        output_layername = "grid_%s" % get_unique_filename()
        output_file = "%s%s.shp" % (self._tmp_dir, output_layername)
        writer = QgsVectorFileWriter(output_file, "utf-8", fields, QGis.WKBPolygon, self._crs, "ESRI Shapefile")
        f = QgsFeature()
        for _f in layer_features(tmp_join_layer):
            # get area of polygon
            geom = _f.geometry()
            geom.transform(mercator_transform)
            area = geom.area()

            # generate all stats of interest
            zone_gid = _f.attributeMap()[zone_gid_idx].toString()
            grid_gid = _f.attributeMap()[grid_gid_idx].toString()
            stat = zone_stat[zone_gid]

            # calculate count/area as proportion of total zone area
            bldg_cnt = _f.attributeMap()[bldg_cnt_idx].toDouble()[0] * (area / stat[area_idx])
            if bldg_area_idx > 0:
                bldg_area = _f.attributeMap()[bldg_area_idx].toDouble()[0] * (area / stat[area_idx])
            else:
                bldg_area = 0

            # create output record
            f.setGeometry(self._outputGeometryFromGridId(grid_gid))
            f.addAttribute(0, grid_gid)
            f.addAttribute(1, zone_names[QString(zone_gid)])
            f.addAttribute(2, bldg_cnt)
            f.addAttribute(3, bldg_area)
            writer.addFeature(f)
        del writer

        # clean up
        del tmp_grid_lyr1
        del tmp_join_layer
        remove_shapefile(tmp_grid1_file)
        remove_shapefile(tmp_join_file)

        # store data in output
        self._load_output(output_file, output_layername)
示例#25
0
文件: footprint.py 项目: gem/sidd
    def do_operation(self):
        """ perform footprint load operation """

        # input/output data checking already done during property set
        # load and verify
        infile = self.inputs[0].value

        tmp_fp_layername = 'fp_%s' % get_unique_filename()
        tmp_fp_layer = load_shapefile(infile, tmp_fp_layername)
        if not tmp_fp_layer:
            raise OperatorError('Error loading footprint file' % (infile),
                                self.__class__)

        if self._fp_ht_field is not None:
            ht_idx = layer_field_index(tmp_fp_layer, self._fp_ht_field)
        else:
            ht_idx = -1
        logAPICall.log(
            'tmp_fp_layer.crs().epsg() %s ' % tmp_fp_layer.crs().epsg(),
            logAPICall.DEBUG)
        if tmp_fp_layer.crs().epsg() != self._crs.epsg():
            transform = QgsCoordinateTransform(tmp_fp_layer.crs(), self._crs)
            transform_required = True
        else:
            transform_required = False

        mercator_crs = QgsCoordinateReferenceSystem()
        #mercator_crs.createFromProj4("+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")
        mercator_crs.createFromEpsg(3395)
        mercator_transform = QgsCoordinateTransform(tmp_fp_layer.crs(),
                                                    mercator_crs)

        # output grid
        fields = {
            0: QgsField(GID_FIELD_NAME, QVariant.Int),
            1: QgsField(LON_FIELD_NAME, QVariant.Double),
            2: QgsField(LAT_FIELD_NAME, QVariant.Double),
            3: QgsField(AREA_FIELD_NAME, QVariant.Double),
            4: QgsField(HT_FIELD_NAME, QVariant.Int),
        }
        output_file = '%sfpc_%s.shp' % (self._tmp_dir, get_unique_filename())
        logAPICall.log('create outputfile %s ... ' % output_file,
                       logAPICall.DEBUG)
        try:
            writer = QgsVectorFileWriter(output_file, "utf-8", fields,
                                         QGis.WKBPoint, self._crs,
                                         "ESRI Shapefile")
            f = QgsFeature()
            gid = 0
            for _f in layer_features(tmp_fp_layer):
                # NOTE: geom.transform does projection in place to underlying
                #       C object, for some reason, multiple projection does not
                #       work correctly. following is a work-around

                # 1. get geometry
                geom = _f.geometry()
                # 2. get original centroid point and project is required
                centroid = geom.centroid().asPoint()
                if transform_required:
                    t_centroid = transform.transform(centroid)
                else:
                    t_centroid = centroid

                # 3. project into mercator and get area in m2
                geom.transform(mercator_transform)
                area = geom.area()

                # write to file
                gid += 1
                f.setGeometry(QgsGeometry.fromPoint(t_centroid))
                f.addAttribute(0, QVariant(gid))
                f.addAttribute(1, QVariant(t_centroid.x()))
                f.addAttribute(2, QVariant(t_centroid.y()))
                f.addAttribute(3, QVariant(area))
                if ht_idx != -1:
                    f.addAttribute(4, _f.attributeMap()[ht_idx])
                else:
                    f.addAttribute(4, QVariant(0))
                writer.addFeature(f)
            del writer, f
        except Exception as err:
            remove_shapefile(output_file)
            raise OperatorError("error creating footprint centroids: %s" % err,
                                self.__class__)

        fp_layer = load_shapefile(output_file, tmp_fp_layername)
        if not fp_layer:
            raise OperatorError(
                'Error loading footprint centroid file' % (output_file),
                self.__class__)

        # clean up
        del tmp_fp_layer

        # store data in output
        self.outputs[0].value = fp_layer
        self.outputs[1].value = output_file
示例#26
0
    def do_operation(self):
        """ perform apply mapping scheme operation """

        # input/output data checking already done during property set
        src_layer = self.inputs[0].value
        zone_field = self.inputs[1].value
        count_field = self.inputs[2].value
        ms = self.inputs[3].value

        # make sure input is correct
        # NOTE: these checks cannot be performed at set input time
        #       because the data layer maybe is not loaded yet
        self._test_layer_loaded(src_layer)
        self._test_layer_field_exists(src_layer, zone_field)
        self._test_layer_field_exists(src_layer, count_field)

        # loop through all zones and assign mapping scheme
        # outputs
        exposure_layername = 'exp_%s' % get_unique_filename()
        exposure_file = '%sexp_%s.shp' % (self._tmp_dir, exposure_layername)

        # loop through all input features
        provider = src_layer.dataProvider()
        if provider is None:
            raise OperatorError("input layer not correctly loaded",
                                self.__class__)
        zone_idx = layer_field_index(src_layer, zone_field)
        if zone_idx == -1:
            raise OperatorError(
                "field %s not found in input layer" % zone_field,
                self.__class__)
        count_idx = layer_field_index(src_layer, count_field)
        if count_idx == -1:
            raise OperatorError(
                "field %s not found in input layer" % count_field,
                self.__class__)
        gid_idx = layer_field_index(src_layer, GID_FIELD_NAME)
        if gid_idx == -1:
            raise OperatorError(
                "field %s not found in input layer" % GID_FIELD_NAME,
                self.__class__)
        area_idx = layer_field_index(src_layer, AREA_FIELD_NAME)

        provider.select(provider.attributeIndexes(), provider.extent())
        provider.rewind()

        try:
            writer = QgsVectorFileWriter(exposure_file, "utf-8", self._fields,
                                         provider.geometryType(), self._crs,
                                         "ESRI Shapefile")
            out_feature = QgsFeature()

            gid = 0
            for in_feature in layer_features(src_layer):
                geom = in_feature.geometry()
                centroid = geom.centroid().asPoint()
                gid = in_feature.attributeMap()[gid_idx]
                zone_str = str(in_feature.attributeMap()[zone_idx].toString())
                count = in_feature.attributeMap()[count_idx].toDouble()[0]
                if area_idx > 0:
                    area = in_feature.attributeMap()[area_idx].toDouble()[0]
                else:
                    area = 0

                count = int(count + 0.5)
                if count == 0:
                    continue

                stats = ms.get_assignment_by_name(zone_str)

                # use default stats if missing
                if stats is None:
                    raise Exception("no mapping scheme found for zone %s" %
                                    zone_str)

                for _sample in stats.get_samples(count,
                                                 self._extrapolationOption):
                    # write out if there are structures assigned
                    _type = _sample[0]
                    _cnt = _sample[1]

                    if area > 0:
                        # use area provided by footprint/zone if defined
                        _size = area * (float(_sample[1]) / count)
                        if _sample[3] > 0 and _sample[2] > 0:
                            _cost = (_sample[3] / _sample[2]) * area
                        else:
                            _cost = 0
                    else:
                        # use mapping scheme generic area otherwise
                        _size = _sample[2]
                        _cost = _sample[3]

                    if _cnt > 0:
                        out_feature.setGeometry(geom)
                        #out_feature.addAttribute(0, QVariant(gid))
                        out_feature.addAttribute(0, gid)
                        out_feature.addAttribute(1, QVariant(centroid.x()))
                        out_feature.addAttribute(2, QVariant(centroid.y()))
                        out_feature.addAttribute(3, QVariant(_type))
                        out_feature.addAttribute(4, QVariant(zone_str))
                        out_feature.addAttribute(5, QVariant(_cnt))
                        out_feature.addAttribute(6, QVariant(_size))
                        out_feature.addAttribute(7, QVariant(_cost))
                        writer.addFeature(out_feature)
            del writer, out_feature
        except Exception as err:
            remove_shapefile(exposure_file)
            raise OperatorError("error creating exposure file: %s" % err,
                                self.__class__)

        del src_layer

        # load shapefile as layer
        exposure_layer = load_shapefile(exposure_file, exposure_layername)
        if not exposure_layer:
            raise OperatorError(
                'Error loading exposure file' % (exposure_file),
                self.__class__)

        # store data in output
        self.outputs[0].value = exposure_layer
        self.outputs[1].value = exposure_file
示例#27
0
    def do_operation(self):
        """ perform create mapping scheme operation """

        # input/output verification already performed during set input/ouput
        svy_layer = self.inputs[0].value

        # make sure input is correct
        # NOTE: these checks cannot be performed at set input time
        #       because the data layer maybe is not loaded yet
        self._test_layer_loaded(svy_layer)

        total_features = svy_layer.dataProvider().featureCount()
        if total_features > MAX_FEATURES_IN_MEMORY:
            # use bsddb to store temporary lat/lon
            tmp_db_file = '%sdb_%s.db' % (self._tmp_dir, get_unique_filename())
            db = bsddb.btopen(tmp_db_file, 'c')
        else:
            db = {}

        # tally statistics for each grid_id/building type combination
        tax_idx = layer_field_index(svy_layer, TAX_FIELD_NAME)
        for f in layer_features(svy_layer):
            geom = f.geometry()
            centroid = geom.centroid().asPoint()
            grid_id = latlon_to_grid(centroid.y(), centroid.x())
            tax_str = str(f.attributeMap()[tax_idx].toString())

            key = '%s %s' % (tax_str, grid_id)
            if db.has_key(key):
                db[key] = str(int(db[key]) +
                              1)  # value as string required by bsddb
            else:
                db[key] = '1'  # value as string required by bsddb

        # loop through all zones and assign mapping scheme
        # outputs
        exposure_layername = 'exp_%s' % get_unique_filename()
        exposure_file = '%s%s.shp' % (self._tmp_dir, exposure_layername)

        try:
            writer = QgsVectorFileWriter(exposure_file, "utf-8", self._fields,
                                         self._outputGeometryType(), self._crs,
                                         "ESRI Shapefile")
            f = QgsFeature()
            gid = 0
            for key, val in db.iteritems():
                (tax_str, grid_id) = key.split(' ')
                lon, lat = grid_to_latlon(int(grid_id))

                f.setGeometry(self._outputGeometryFromGridId(grid_id))
                f.addAttribute(0, QVariant(grid_id))
                f.addAttribute(1, QVariant(lon))
                f.addAttribute(2, QVariant(lat))
                f.addAttribute(3, QVariant(tax_str))
                f.addAttribute(4, QVariant(''))
                f.addAttribute(5, QVariant(val))
                writer.addFeature(f)
                gid += 1
            del writer, f
        except Exception as err:
            remove_shapefile(exposure_file)
            raise OperatorError("error creating exposure file: %s" % err,
                                self.__class__)

        # load shapefile as layer
        exposure_layer = load_shapefile(exposure_file, exposure_layername)
        if not exposure_layer:
            raise OperatorError(
                'Error loading exposure file %s' % (exposure_file),
                self.__class__)

        # store data in output
        self.outputs[0].value = exposure_layer
        self.outputs[1].value = exposure_file
示例#28
0
    def do_operation(self):
        """ perform footprint load operation """
        
        # input/output data checking already done during property set        
        # load and verify
        infile = self.inputs[0].value
        
        tmp_fp_layername = 'fp_%s' % get_unique_filename()
        tmp_fp_layer = load_shapefile(infile, tmp_fp_layername)
        if not tmp_fp_layer:
            raise OperatorError('Error loading footprint file' % (infile), self.__class__)

        if self._fp_ht_field is not None:
            ht_idx = layer_field_index(tmp_fp_layer, self._fp_ht_field)
        else:
            ht_idx = -1
        logAPICall.log('tmp_fp_layer.crs().epsg() %s ' % tmp_fp_layer.crs().epsg(),
                       logAPICall.DEBUG)
        if tmp_fp_layer.crs().epsg() != self._crs.epsg():
            transform = QgsCoordinateTransform(tmp_fp_layer.crs(), self._crs)
            transform_required = True
        else:
            transform_required = False
        
        mercator_crs = QgsCoordinateReferenceSystem()
        #mercator_crs.createFromProj4("+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")
        mercator_crs.createFromEpsg(3395)        
        mercator_transform = QgsCoordinateTransform(tmp_fp_layer.crs(), mercator_crs)
        
        # output grid
        fields = {
            0 : QgsField(GID_FIELD_NAME, QVariant.Int),
            1 : QgsField(LON_FIELD_NAME, QVariant.Double),
            2 : QgsField(LAT_FIELD_NAME, QVariant.Double),
            3 : QgsField(AREA_FIELD_NAME, QVariant.Double),
            4 : QgsField(HT_FIELD_NAME, QVariant.Int),
        }
        output_file = '%sfpc_%s.shp' % (self._tmp_dir, get_unique_filename())
        logAPICall.log('create outputfile %s ... ' % output_file, logAPICall.DEBUG)        
        try:
            writer = QgsVectorFileWriter(output_file, "utf-8", fields, QGis.WKBPoint, self._crs, "ESRI Shapefile")
            f = QgsFeature()
            gid = 0
            for _f in layer_features(tmp_fp_layer):
                # NOTE: geom.transform does projection in place to underlying
                #       C object, for some reason, multiple projection does not
                #       work correctly. following is a work-around
                 
                # 1. get geometry
                geom = _f.geometry()
                # 2. get original centroid point and project is required
                centroid  = geom.centroid().asPoint()
                if transform_required:
                    t_centroid = transform.transform(centroid)
                else:
                    t_centroid = centroid
                
                # 3. project into mercator and get area in m2
                geom.transform(mercator_transform)
                area = geom.area()
                
                # write to file
                gid += 1
                f.setGeometry(QgsGeometry.fromPoint(t_centroid))
                f.addAttribute(0, QVariant(gid))
                f.addAttribute(1, QVariant(t_centroid.x()))
                f.addAttribute(2, QVariant(t_centroid.y()))
                f.addAttribute(3, QVariant(area))
                if ht_idx != -1:
                    f.addAttribute(4, _f.attributeMap()[ht_idx])
                else:
                    f.addAttribute(4, QVariant(0))
                writer.addFeature(f)            
            del writer, f
        except Exception as err:
            remove_shapefile(output_file)
            raise OperatorError("error creating footprint centroids: %s" % err, self.__class__)

        fp_layer = load_shapefile(output_file, tmp_fp_layername)
        if not fp_layer:
            raise OperatorError('Error loading footprint centroid file' % (output_file), self.__class__)        
        
        # clean up
        del tmp_fp_layer
        
        # store data in output
        self.outputs[0].value = fp_layer
        self.outputs[1].value = output_file
示例#29
0
文件: join.py 项目: gem/sidd
    def do_operation(self):
        """ perform create mapping scheme operation """

        # input/output verification already performed during set input/ouput
        zone_layer = self.inputs[0].value
        zone_field = self.inputs[1].value
        popgrid_layer = self.inputs[2].value
        pop_to_bldg = float(self.inputs[3].value)

        # merge with zone
        tmp_join = 'joined_%s' % get_unique_filename()
        tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join)
        analyzer = QgsOverlayAnalyzer()
        try:
            analyzer.intersection(popgrid_layer, zone_layer, tmp_join_file)
            tmp_join_layer = load_shapefile(tmp_join_file, tmp_join)
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)

        # count footprint in each zone
        stats = {}
        _gid_idx = layer_field_index(tmp_join_layer, GID_FIELD_NAME + "_")
        _cnt_idx = layer_field_index(tmp_join_layer, CNT_FIELD_NAME)
        for _f in layer_features(tmp_join_layer):
            # retrieve count from statistic
            _gid = _f.attributeMap()[_gid_idx].toString()
            _count = _f.attributeMap()[_cnt_idx].toString()
            if stats.has_key(_gid):
                stats[_gid] += float(_count) / pop_to_bldg
            else:
                stats[_gid] = float(_count) / pop_to_bldg

        output_layername = 'zone_%s' % get_unique_filename()
        output_file = '%s%s.shp' % (self._tmp_dir, output_layername)
        logAPICall.log('create outputfile %s ... ' % output_file,
                       logAPICall.DEBUG)
        try:
            fields = {
                0: QgsField(GID_FIELD_NAME, QVariant.Int),
                1: QgsField(zone_field, QVariant.String),
                2: QgsField(CNT_FIELD_NAME, QVariant.Int),
            }
            writer = QgsVectorFileWriter(output_file, "utf-8", fields,
                                         QGis.WKBPolygon, self._crs,
                                         "ESRI Shapefile")
            f = QgsFeature()
            for _f in layer_features(zone_layer):

                # write to file
                f.setGeometry(_f.geometry())
                f.addAttribute(0, _f.attributeMap()[0])
                f.addAttribute(1, _f.attributeMap()[1])

                # retrieve count from statistic
                try:
                    gid = _f.attributeMap()[0].toString()
                    bldg_count = stats[gid]
                except:
                    bldg_count = 0
                f.addAttribute(2, QVariant(bldg_count))
                writer.addFeature(f)

            del writer, f
        except Exception as err:
            remove_shapefile(output_file)
            raise OperatorError("error creating zone: %s" % err,
                                self.__class__)

        # clean up
        del tmp_join_layer
        remove_shapefile(tmp_join_file)

        # store data in output
        output_layer = load_shapefile(output_file, output_layername)
        if not output_layer:
            raise OperatorError(
                'Error loading footprint centroid file' % (output_file),
                self.__class__)
        self.outputs[0].value = output_layer
        self.outputs[1].value = output_file
示例#30
0
文件: join.py 项目: ImageCatInc/sidd
    def do_operation(self):
        """ perform create mapping scheme operation """
        
        # input/output verification already performed during set input/ouput
        zone_layer = self.inputs[0].value
        zone_field = self.inputs[1].value
        popgrid_layer = self.inputs[2].value
        pop_to_bldg = float(self.inputs[3].value)
        
        # merge with zone 
        tmp_join = 'joined_%s' % get_unique_filename()
        tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join)        
        analyzer = QgsOverlayAnalyzer()
        try:
            analyzer.intersection(popgrid_layer, zone_layer, tmp_join_file)
            tmp_join_layer = load_shapefile(tmp_join_file, tmp_join)
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)
        
        # count footprint in each zone
        stats = {}
        _gid_idx = layer_field_index(tmp_join_layer, GID_FIELD_NAME + "_")        
        _cnt_idx = layer_field_index(tmp_join_layer, CNT_FIELD_NAME)
        for _f in layer_features(tmp_join_layer):
            # retrieve count from statistic
            _gid = _f.attributeMap()[_gid_idx].toString()
            _count = _f.attributeMap()[_cnt_idx].toString()
            if stats.has_key(_gid):
                stats[_gid]+=float(_count) / pop_to_bldg
            else:
                stats[_gid]=float(_count)  / pop_to_bldg          
        
        output_layername = 'zone_%s' % get_unique_filename()
        output_file = '%s%s.shp' % (self._tmp_dir, output_layername)
        logAPICall.log('create outputfile %s ... ' % output_file, logAPICall.DEBUG)
        try:            
            fields ={
                0 : QgsField(GID_FIELD_NAME, QVariant.Int),
                1 : QgsField(zone_field, QVariant.String),
                2 : QgsField(CNT_FIELD_NAME, QVariant.Int),
            }
            writer = QgsVectorFileWriter(output_file, "utf-8", fields, QGis.WKBPolygon, self._crs, "ESRI Shapefile")                     
            f = QgsFeature()            
            for _f in layer_features(zone_layer):
                
                # write to file
                f.setGeometry(_f.geometry())
                f.addAttribute(0, _f.attributeMap()[0])
                f.addAttribute(1, _f.attributeMap()[1])                
                
                # retrieve count from statistic
                try:
                    gid = _f.attributeMap()[0].toString()
                    bldg_count = stats[gid]
                except:
                    bldg_count = 0
                f.addAttribute(2, QVariant(bldg_count))
                writer.addFeature(f)
            
            del writer, f
        except Exception as err:            
            remove_shapefile(output_file)
            raise OperatorError("error creating zone: %s" % err, self.__class__)

        # clean up
        del tmp_join_layer
        remove_shapefile(tmp_join_file)

        # store data in output
        output_layer = load_shapefile(output_file, output_layername)
        if not output_layer:
            raise OperatorError('Error loading footprint centroid file' % (output_file), self.__class__)        
        self.outputs[0].value = output_layer
        self.outputs[1].value = output_file
示例#31
0
    def _buildSurveyLayer(self, data, shapefilepath):
        writer = QgsVectorFileWriter(shapefilepath, "utf-8", self._fields,
                                     QGis.WKBPoint, self._crs,
                                     "ESRI Shapefile")
        f = QgsFeature()
        for row in data:
            obj_uid = str(row[0])
            lon = self._tofloat(row[1])
            lat = self._tofloat(row[2])
            sample_grp = str(row[3])
            plan_area = self._tofloat(row[4])
            rep_cost = self._tofloat(row[5])
            tax_string = self._make_gem_taxstring(row[6:])
            ht = self._get_height(row[6:])

            f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat)))
            f.addAttribute(0, QVariant(obj_uid))
            f.addAttribute(1, QVariant(lon))
            f.addAttribute(2, QVariant(lat))
            f.addAttribute(3, QVariant(tax_string))
            f.addAttribute(4, QVariant(sample_grp))
            f.addAttribute(5, QVariant(plan_area))
            f.addAttribute(6, QVariant(ht))
            f.addAttribute(7, QVariant(rep_cost))
            writer.addFeature(f)
        del writer, f
示例#32
0
    def do_operation(self):
        """ perform footprint load operation """
        
        # input/output data checking already done during property set        
        # load and verify
        popgrid_file = self.inputs[0].value
        pop_field = self.inputs[1].value
        
        popgrid_layername = 'zone_%s' % get_unique_filename()
        try:
            tmp_popgrid_layer = load_shapefile_verify(popgrid_file, popgrid_layername,
                                                   [pop_field])
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)
        
        logAPICall.log('tmp_fp_layer.crs().epsg() %s ' % tmp_popgrid_layer.crs().epsg(),
                       logAPICall.DEBUG)
        if tmp_popgrid_layer.crs().epsg() != self._crs.epsg():
            transform = QgsCoordinateTransform(tmp_popgrid_layer.crs(), self._crs)
            transform_required = True
        else:
            transform_required = False
        
        # output grid
        fields = {
            0 : QgsField(GID_FIELD_NAME, QVariant.Int),
            1 : QgsField(CNT_FIELD_NAME, QVariant.Double),
        }
        pop_idx = layer_field_index(tmp_popgrid_layer, pop_field)
        output_file = '%spop_grid_%s.shp' % (self._tmp_dir, get_unique_filename())
        logAPICall.log('create outputfile %s ... ' % output_file, logAPICall.DEBUG)        
        try:
            writer = QgsVectorFileWriter(output_file, "utf-8", fields, QGis.WKBPoint, self._crs, "ESRI Shapefile")
            f = QgsFeature()
            gid = 0
            for _f in layer_features(tmp_popgrid_layer):
                # NOTE: geom.transform does projection in place to underlying C object
                 
                # 1. get geometry
                geom = _f.geometry()                
                # 2. change project if required
                if transform_required:
                    geom = transform.transform(geom)
                
                # 3. write to file
                gid += 1
                f.setGeometry(geom)
                f.addAttribute(0, QVariant(gid))
                f.addAttribute(1, _f.attributeMap()[pop_idx])
                writer.addFeature(f)            
            del writer, f
        except Exception as err:
            remove_shapefile(output_file)
            raise OperatorError("error creating footprint centroids: %s" % err, self.__class__)

        popgrid_layername = 'popgrid_%s' % get_unique_filename()
        popgrid_layer = load_shapefile(output_file, popgrid_layername)
        if not popgrid_layer:
            raise OperatorError('Error loading footprint centroid file' % (output_file), self.__class__)        
        
        # clean up
        del tmp_popgrid_layer
        
        # store data in output
        self.outputs[0].value = popgrid_layer
        self.outputs[1].value = output_file
示例#33
0
文件: join.py 项目: ImageCatInc/sidd
    def do_operation(self):
        """ perform create mapping scheme operation """
        
        # input/output verification already performed during set input/ouput
        zone_layer = self.inputs[0].value
        zone_field = self.inputs[1].value
        zone_count_field = self.inputs[2].value
        fp_layer = self.inputs[3].value

        # merge with zone 
        tmp_join = 'joined_%s' % get_unique_filename()
        tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join)        
        analyzer = QgsOverlayAnalyzer()
        try:
            analyzer.intersection(fp_layer, zone_layer, tmp_join_file)
            tmp_join_layer = load_shapefile(tmp_join_file, tmp_join)
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)
        
        # count footprint in each zone
        gid_idx = layer_field_index(tmp_join_layer, GID_FIELD_NAME + "_")
        area_idx = layer_field_index(tmp_join_layer, AREA_FIELD_NAME)
        ht_idx = layer_field_index(tmp_join_layer, HT_FIELD_NAME)
        stats = {}
        for _feature in layer_features(tmp_join_layer):
            gid = _feature.attributeMap()[gid_idx].toString()
            if ht_idx > 0:      
                ht = _feature.attributeMap()[ht_idx].toDouble()[0]
            else:
                ht = 0                        
            # if height is not defined, it is set to 0
            # this will cause the system to ignore area generate without having to
            # remove the field
            area = _feature.attributeMap()[area_idx].toDouble()[0] * ht # 
            if not stats.has_key(gid):
                stats[gid] = (1, area)
            else:
                stat = stats[gid] 
                stats[gid] = (stat[0]+1, stat[1]+area)
            
        output_layername = 'zone_%s' % get_unique_filename()
        output_file = '%s%s.shp' % (self._tmp_dir, output_layername)
        logAPICall.log('create outputfile %s ... ' % output_file, logAPICall.DEBUG)
        try:            
            fields ={
                0 : QgsField(GID_FIELD_NAME, QVariant.Int),
                1 : QgsField(zone_field, QVariant.String),
                2 : QgsField(CNT_FIELD_NAME, QVariant.Int),
                3 : QgsField(AREA_FIELD_NAME, QVariant.Int),
            }
            writer = QgsVectorFileWriter(output_file, "utf-8", fields, QGis.WKBPolygon, self._crs, "ESRI Shapefile")                     
            f = QgsFeature()            
            for _f in layer_features(zone_layer):
                
                # write to file
                f.setGeometry(_f.geometry())
                f.addAttribute(0, _f.attributeMap()[0])
                f.addAttribute(1, _f.attributeMap()[1])
                
                # retrieve count from statistic
                try:
                    gid = _f.attributeMap()[0].toString()
                    stat = stats[gid]
                    bldg_count = stat[0]
                    area = stat[1]
                except:
                    bldg_count, area = 0, 0
                f.addAttribute(2, QVariant(bldg_count))
                f.addAttribute(3, QVariant(area))
                writer.addFeature(f)
            
            del writer, f
        except Exception as err:            
            remove_shapefile(output_file)
            raise OperatorError("error creating zone: %s" % err, self.__class__)

        # clean up
        del tmp_join_layer
        remove_shapefile(tmp_join_file)

        # store data in output
        output_layer = load_shapefile(output_file, output_layername)
        if not output_layer:
            raise OperatorError('Error loading footprint centroid file' % (output_file), self.__class__)        
        self.outputs[0].value = output_layer
        self.outputs[1].value = output_file
示例#34
0
    @logAPICall
    def do_operation(self):
        """ perform create mapping scheme operation """
        
        # input/output verification already performed during set input/ouput
        svy_layer = self.inputs[0].value

        # make sure input is correct
        # NOTE: these checks cannot be performed at set input time
        #       because the data layer maybe is not loaded yet
        self._test_layer_loaded(svy_layer)
        
        total_features = svy_layer.dataProvider().featureCount()
        if total_features > MAX_FEATURES_IN_MEMORY:
            # use bsddb to store temporary lat/lon
            tmp_db_file = '%sdb_%s.db' % (self._tmp_dir, get_unique_filename())
            db = bsddb.btopen(tmp_db_file, 'c')            
        else:
            db = {}

        # tally statistics for each grid_id/building type combination
        tax_idx = layer_field_index(svy_layer, TAX_FIELD_NAME)
        for f in layer_features(svy_layer):
            geom = f.geometry()
            centroid  = geom.centroid().asPoint()
            grid_id = latlon_to_grid(centroid.y(), centroid.x())                        
            tax_str = str(f.attributeMap()[tax_idx].toString())

            key = '%s %s' % (tax_str, grid_id)
            if db.has_key(key):
                db[key] = str(int(db[key]) + 1) # value as string required by bsddb
            else:
                db[key] = '1'                   # value as string required by bsddb

        # loop through all zones and assign mapping scheme
        # outputs
        exposure_layername = 'exp_%s' % get_unique_filename()
        exposure_file = '%s%s.shp' % (self._tmp_dir, exposure_layername)

        try:
            writer = QgsVectorFileWriter(exposure_file, "utf-8", 
                                         self._fields, self._outputGeometryType(), self._crs, 
                                         "ESRI Shapefile")
            f = QgsFeature()            
            gid = 0
            for key, val in db.iteritems():
                (tax_str, grid_id) = key.split(' ')
                lon, lat = grid_to_latlon(int(grid_id))
                
                f.setGeometry(self._outputGeometryFromGridId(grid_id))
                f.addAttribute(0, QVariant(grid_id))
                f.addAttribute(1, QVariant(lon))
                f.addAttribute(2, QVariant(lat))
                f.addAttribute(3, QVariant(tax_str))
                f.addAttribute(4, QVariant(''))
                f.addAttribute(5, QVariant(val))
                writer.addFeature(f)
                gid += 1
            del writer, f
        except Exception as err:
            remove_shapefile(exposure_file)
            raise OperatorError("error creating exposure file: %s" % err, self.__class__)
        
        # load shapefile as layer        
        exposure_layer = load_shapefile(exposure_file, exposure_layername)
        if not exposure_layer:            
            raise OperatorError('Error loading exposure file %s' % (exposure_file), self.__class__)
        
        # store data in output
        self.outputs[0].value = exposure_layer
示例#35
0
文件: grids.py 项目: gem/sidd
    def do_operation(self):
        """ perform create mapping scheme operation """

        # validate inputs
        fp_layer = self.inputs[0].value
        zone_layer = self.inputs[1].value
        zone_field = self.inputs[2].value
        count_field = self.inputs[3].value
        area_field = self.inputs[4].value

        # make sure input is correct
        # NOTE: these checks cannot be performed at set input time
        #       because the data layer maybe is not loaded yet
        self._test_layer_loaded(fp_layer)
        self._test_layer_loaded(zone_layer)
        self._test_layer_field_exists(zone_layer, GID_FIELD_NAME)
        self._test_layer_field_exists(zone_layer, zone_field)
        # count_field is not required
        # if count field is not defined, then generate building count from footprints
        # area_field is not required

        # local variables
        analyzer = QgsOverlayAnalyzer()
        area_idx = ToGrid.STAT_AREA_IDX
        cnt_idx = ToGrid.STAT_COUNT_IDX

        zone_names, zone_stat, zone_stat2, zone_totals = {}, {}, {}, {}

        # 1. find building count and total area for each zone
        # project geometry into mercator and get area in m2
        mercator_crs = QgsCoordinateReferenceSystem()
        mercator_crs.createFromEpsg(3395)
        mercator_transform = QgsCoordinateTransform(zone_layer.crs(), mercator_crs)

        try:
            # use zone geometry area
            self._create_zone_statistics(zone_layer, zone_field, count_field, zone_stat, zone_names)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)

        # 2. create grids around extent of zone
        tmp_grid1 = "grid_" + get_unique_filename()
        tmp_grid1_file = self._tmp_dir + tmp_grid1 + ".shp"
        extent = zone_layer.extent()
        [x_min, y_min, x_max, y_max] = [extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum()]
        tmp_grid_lyr1 = self._create_grid(
            tmp_grid1, tmp_grid1_file, x_min, y_min, x_max, y_max, DEFAULT_GRID_SIZE, DEFAULT_GRID_SIZE
        )

        # tally total building area if there is defined
        bldg_area_idx = layer_field_index(zone_layer, area_field)
        zone_area = {}
        zone_has_area = False
        if bldg_area_idx > 0:
            zone_has_area = True
            zone_gid_idx = layer_field_index(zone_layer, GID_FIELD_NAME)
            for _f in layer_features(zone_layer):
                gid = _f.attributeMap()[zone_gid_idx].toString()
                area = _f.attributeMap()[bldg_area_idx].toDouble()[0]
                if zone_area.has_key(gid):
                    zone_area[gid] = str(float(zone_area[gid])) + area
                else:
                    zone_area[gid] = area

        # 3. intersect grids and zones to obtain polygons with
        # - grid_id and zone_id
        # - ratio of grid covered by zone (polygon area / zone area)
        # apply ratio to zone building count to obtain count assigned to polygon
        tmp_join = "joined_%s" % get_unique_filename()
        tmp_join_file = "%s%s.shp" % (self._tmp_dir, tmp_join)
        try:
            # do intersection
            analyzer.intersection(tmp_grid_lyr1, zone_layer, tmp_join_file)
            tmp_join_layer = load_shapefile(tmp_join_file, tmp_join)
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)

        # do tally
        zone_gid_idx = layer_field_index(tmp_join_layer, GID_FIELD_NAME)
        grid_gid_idx = layer_field_index(tmp_join_layer, "GRID_GID")
        bldg_cnt_idx = layer_field_index(tmp_join_layer, count_field)
        for _f in layer_features(tmp_join_layer):
            geom = _f.geometry()
            geom.transform(mercator_transform)
            area = geom.area()

            # generate all stats of interest
            zone_gid = _f.attributeMap()[zone_gid_idx].toString()
            grid_gid = _f.attributeMap()[grid_gid_idx].toString()
            stat = zone_stat[zone_gid]
            # calculate count/area as proportion of total zone area
            area_ratio = area / stat[area_idx]
            if bldg_cnt_idx > 0:
                bldg_cnt = _f.attributeMap()[bldg_cnt_idx].toDouble()[0] * area_ratio
            else:
                bldg_cnt = 0
            if zone_has_area:
                area = zone_area[zone_gid] * area_ratio
            else:
                area = stat[area_idx] * area_ratio
            self._update_stat(zone_stat2, "%s|%s" % (grid_gid, zone_gid), bldg_cnt, area)

        # 4. find total buildings in each zone based on footprint
        # - simply join the files and tally count and total area
        tmp_join1 = "joined_%s" % get_unique_filename()
        tmp_join1_file = "%s%s.shp" % (self._tmp_dir, tmp_join1)
        try:
            # do intersection
            analyzer.intersection(fp_layer, tmp_join_layer, tmp_join1_file)
            tmp_join1_layer = load_shapefile(tmp_join1_file, tmp_join1)
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)

        # do tally
        zone_fp_stat = {}
        zone_gid_idx = layer_field_index(tmp_join1_layer, "%s_" % GID_FIELD_NAME)
        grid_gid_idx = layer_field_index(tmp_join1_layer, "GRID_GID")
        fp_area_idx = layer_field_index(tmp_join1_layer, AREA_FIELD_NAME)
        fp_ht_idx = layer_field_index(tmp_join1_layer, HT_FIELD_NAME)
        fp_has_height = False
        for _f in layer_features(tmp_join1_layer):
            zone_gid = _f.attributeMap()[zone_gid_idx].toString()
            grid_gid = _f.attributeMap()[grid_gid_idx].toString()
            area = _f.attributeMap()[fp_area_idx].toDouble()[0]  # area comes from geometry, always exists
            ht = _f.attributeMap()[fp_ht_idx].toDouble()[0]
            if ht > 0:
                fp_has_height = True
                area *= ht  # this is actual area to be aggregated at the end
            self._update_stat(zone_fp_stat, "%s|%s" % (grid_gid, zone_gid), 1, area)
            self._update_stat(zone_totals, zone_gid, 1, area)

        # 5. generate grid with adjusted building counts
        fields = {
            0: QgsField(GID_FIELD_NAME, QVariant.String),
            1: QgsField(zone_field, QVariant.String),
            2: QgsField(CNT_FIELD_NAME, QVariant.Double),
            3: QgsField(AREA_FIELD_NAME, QVariant.Double),
        }
        output_layername = "grid_%s" % get_unique_filename()
        output_file = "%s%s.shp" % (self._tmp_dir, output_layername)
        writer = QgsVectorFileWriter(output_file, "utf-8", fields, QGis.WKBPolygon, self._crs, "ESRI Shapefile")
        f = QgsFeature()
        for key in zone_stat2.keys():
            (grid_gid, zone_gid) = str(key).split("|")
            s_zone = zone_stat[QString(zone_gid)]  # overall statistics for the zone from zone file (always exists)
            s_zone_grid = zone_stat2[key]  # grid specific statistic from from zone file    (always exists)
            if zone_totals.has_key(QString(zone_gid)):  # overall statistics for the zone from footprints
                s_total = zone_totals[QString(zone_gid)]
            else:
                s_total = [0, 0]  # set to zero if missing
            if zone_fp_stat.has_key(key):  # grid specific statistic from from footprint
                s_fp = zone_fp_stat[key]
            else:
                s_fp = [0, 0]  # set to zero if missing

            zone_leftover_count = s_zone[cnt_idx] - s_total[cnt_idx]
            if zone_has_area:
                zone_leftover_area = zone_area[QString(zone_gid)] - s_total[area_idx]
            else:
                zone_leftover_area = s_zone[area_idx] - s_total[area_idx]
            if zone_leftover_count > 0:
                # there are still building not accounted for
                # distribute to grid based on ratio of grid leftover area over zone leftover area
                # (leftover area is area of zone after subtracting footprint areas
                grid_leftover_count = zone_leftover_count * (
                    (s_zone_grid[area_idx] - s_fp[area_idx]) / zone_leftover_area
                )
                grid_count = s_fp[cnt_idx] + grid_leftover_count
            else:
                grid_count = s_fp[cnt_idx]

            if fp_has_height:
                # area can be actual area based on footprint area * height
                area = s_fp[area_idx]
            elif zone_has_area:
                area = s_zone_grid[area_idx]
            else:
                # no area defined
                area = 0  # max(s_zone_grid[area_idx], s_fp[area_idx])

            f.setGeometry(self._outputGeometryFromGridId(grid_gid))
            f.addAttribute(0, grid_gid)
            f.addAttribute(1, zone_names[QString(zone_gid)])
            f.addAttribute(2, grid_count)
            f.addAttribute(3, area)
            writer.addFeature(f)
        del writer

        # clean up
        del tmp_grid_lyr1
        del tmp_join_layer
        del tmp_join1_layer
        remove_shapefile(tmp_grid1_file)
        remove_shapefile(tmp_join_file)
        remove_shapefile(tmp_join1_file)

        # store data in output
        self._load_output(output_file, output_layername)
示例#36
0
    @logAPICall
    def do_operation(self):
        """ perform apply mapping scheme operation """
        
        # input/output data checking already done during property set
        src_layer = self.inputs[0].value
        zone_field = self.inputs[1].value
        count_field = self.inputs[2].value
        ms = self.inputs[3].value
        
        # make sure input is correct
        # NOTE: these checks cannot be performed at set input time
        #       because the data layer maybe is not loaded yet
        self._test_layer_loaded(src_layer)
        self._test_layer_field_exists(src_layer, zone_field)
        self._test_layer_field_exists(src_layer, count_field)
        
        # loop through all zones and assign mapping scheme
        # outputs
        exposure_layername = 'exp_%s' % get_unique_filename()
        exposure_file = '%sexp_%s.shp' % (self._tmp_dir, exposure_layername)

        # loop through all input features
        provider = src_layer.dataProvider()
        if provider is None:
            raise OperatorError("input layer not correctly loaded", self.__class__)
        zone_idx = layer_field_index(src_layer, zone_field)
        if zone_idx == -1:
            raise OperatorError("field %s not found in input layer" % zone_field, self.__class__)
        count_idx = layer_field_index(src_layer, count_field)
        if count_idx == -1:
            raise OperatorError("field %s not found in input layer" % count_field, self.__class__)
        gid_idx = layer_field_index(src_layer, GID_FIELD_NAME)
        if gid_idx == -1:
            raise OperatorError("field %s not found in input layer" % GID_FIELD_NAME, self.__class__)
        area_idx = layer_field_index(src_layer, AREA_FIELD_NAME)
        
        provider.select(provider.attributeIndexes(), provider.extent())
        provider.rewind()

        try:
            writer = QgsVectorFileWriter(exposure_file, "utf-8", self._fields, provider.geometryType(), self._crs, "ESRI Shapefile")
            out_feature = QgsFeature()
            
            gid = 0
            for in_feature in layer_features(src_layer):
                geom = in_feature.geometry()
                centroid = geom.centroid().asPoint ()
                gid = in_feature.attributeMap()[gid_idx]
                zone_str = str(in_feature.attributeMap()[zone_idx].toString())
                count = in_feature.attributeMap()[count_idx].toDouble()[0]
                if area_idx > 0:
                    area = in_feature.attributeMap()[area_idx].toDouble()[0]
                else:
                    area = 0
                
                count = int(count+0.5)
                if count == 0:
                    continue                            
                
                stats = ms.get_assignment_by_name(zone_str)
                
                # use default stats if missing
                if stats is None:
                    raise Exception("no mapping scheme found for zone %s" % zone_str)
                
                for _sample in stats.get_samples(count, self._extrapolationOption):
                    # write out if there are structures assigned
                    _type = _sample[0]
                    _cnt = _sample[1]
                    
                    if area > 0:
                        # use area provided by footprint/zone if defined
                        _size = area * ( float(_sample[1]) / count )
                        if _sample[3] > 0 and _sample[2] > 0:
                            _cost = (_sample[3] / _sample[2]) * area
                        else:
                            _cost = 0
                    else:
                        # use mapping scheme generic area otherwise
                        _size = _sample[2]
                        _cost = _sample[3]
                    
                    if _cnt > 0:
                        out_feature.setGeometry(geom)
                        #out_feature.addAttribute(0, QVariant(gid))
                        out_feature.addAttribute(0, gid)
                        out_feature.addAttribute(1, QVariant(centroid.x()))
                        out_feature.addAttribute(2, QVariant(centroid.y()))
                        out_feature.addAttribute(3, QVariant(_type))
                        out_feature.addAttribute(4, QVariant(zone_str))
                        out_feature.addAttribute(5, QVariant(_cnt))
                        out_feature.addAttribute(6, QVariant(_size))
                        out_feature.addAttribute(7, QVariant(_cost))
                        writer.addFeature(out_feature)
            del writer, out_feature
        except Exception as err:
            remove_shapefile(exposure_file)
            raise OperatorError("error creating exposure file: %s" % err, self.__class__)
            
        del src_layer
        
        # load shapefile as layer        
        exposure_layer = load_shapefile(exposure_file, exposure_layername)
        if not exposure_layer:            
            raise OperatorError('Error loading exposure file' % (exposure_file), self.__class__)
        
        # store data in output
        self.outputs[0].value = exposure_layer
示例#37
0
    def do_operation(self):
        """ perform create mapping scheme operation """
        
        # input/output verification already performed during set input/ouput
        fp_layer = self.inputs[0].value
        zone_field = self.inputs[1].value

        # aggregate footprint into grids
        logAPICall.log('aggregate statistic for grid ...', logAPICall.DEBUG)
        total_features = fp_layer.dataProvider().featureCount()
        if total_features > MAX_FEATURES_IN_MEMORY:
            # use bsddb to store temporary lat/lon
            tmp_db_file = '%sdb_%s.db' % (self._tmp_dir, get_unique_filename())
            db = bsddb.btopen(tmp_db_file, 'c')
            use_db = True
        else:
            db = {}
            use_db = False

        zone_idx = layer_field_index(fp_layer, zone_field)
        for f in layer_features(fp_layer):
            geom = f.geometry()
            zone_str = str(f.attributeMap()[zone_idx].toString())
            centroid  = geom.centroid().asPoint()
            # use floor, this truncates all points within grid to grid's
            # bottom-left corner                        
            x = math.floor(centroid.x() / DEFAULT_GRID_SIZE)
            y = math.floor(centroid.y() / DEFAULT_GRID_SIZE)
            key = '%s %d %d' % (zone_str, x,y)
            if db.has_key(key):
                db[key] = str(int(db[key]) + 1)
            else:
                db[key] = '1'
        
        # output grid
        logAPICall.log('create grid ...', logAPICall.DEBUG)
        fields = {
            0 : QgsField(self._lon_field, QVariant.Double),
            1 : QgsField(self._lat_field, QVariant.Double),
            2 : QgsField(CNT_FIELD_NAME, QVariant.Double),
            3 : QgsField(zone_field, QVariant.String),
        }
        grid_layername = 'grid_%s' % get_unique_filename()
        grid_file = '%s%s.shp' % (self._tmp_dir, grid_layername)
        try:
            writer = QgsVectorFileWriter(grid_file, "utf-8", fields, QGis.WKBPoint , self._crs, "ESRI Shapefile")
            f = QgsFeature()
            for key, val in db.iteritems():
                (zone_str, x, y) = key.split(' ')
                # point were aggregated to grid's bottom-left corner
                # add half grid size to place point at center of grid
                point = QgsPoint(int(x)*DEFAULT_GRID_SIZE+(DEFAULT_GRID_SIZE/2.0), 
                                 int(y)*DEFAULT_GRID_SIZE+(DEFAULT_GRID_SIZE/2.0))
                f.setGeometry(QgsGeometry.fromPoint(point))
                f.addAttribute(0, QVariant(point.x()))
                f.addAttribute(1, QVariant(point.y()))
                f.addAttribute(2, QVariant(val))
                f.addAttribute(3, QVariant(zone_str))
                writer.addFeature(f)
            del writer
        except Exception as err:
            remove_shapefile(grid_file)
            raise OperatorError("error creating joined grid: " % err, self.__class__)
        
        grid_layer = load_shapefile(grid_file, grid_layername)
        if not grid_layer:
            raise OperatorError('Error loading created grid file' % (grid_file), self.__class__)
                
        # clean up                
        if use_db:
            db.close()
            os.remove(tmp_db_file)
            
        # done
        self.outputs[0].value = grid_layer
        self.outputs[1].value = grid_file
示例#38
0
    def createFeature(self, geom):

        # layer = self.canvas.currentLayer()
        layer = self.iface.activeLayer()        
        provider = layer.dataProvider()
        f = QgsFeature()
    	
        if (geom.isGeosValid()):
            f.setGeometry(geom)
        else:
            reply = QMessageBox.question(self.iface.mainWindow(), 'Feature not valid',
                "The geometry of the feature you just added isn't valid. Do you want to use it anyway?",
            QMessageBox.Yes, QMessageBox.No)
            if reply == QMessageBox.Yes:
                f.setGeometry(geom)
            else:
                return False
				
      
        # Add attribute fields to feature.
        fields = layer.pendingFields()
        
        try: #API-Break 1.8 vs. 2.0 handling
            attr = f.initAttributes(len(fields))    #@UnusedVariable
            for i in range(len(fields)):
                f.setAttribute(i, provider.defaultValue(i))
              
        except AttributeError: #<=1.8
            # Add attributefields to feature.
            for i in fields:
                f.addAttribute(i, provider.defaultValue(i))
        
        idx = layer.fieldNameIndex('epa_type')
        f[idx] = self.elem_type_type
        
        # Upload changes
        layer.startEditing()
        layer.addFeature(f)
        
        # Control PostgreSQL exceptions
        boolOk = layer.commitChanges()

        # Update canvas        
        self.canvas.refresh()
 
        # Capture edit exception
        if boolOk:
                        
            # Spatial query to retrieve last added line, start searchingcandidates
            cands = layer.getFeatures(QgsFeatureRequest().setFilterRect(f.geometry().boundingBox()))

            # Iterate on candidates
            for line_feature in cands:
                if line_feature.geometry().equals(f.geometry()):

                    # Highlight
                    layer.setSelectedFeatures([line_feature.id()])

                    # Open form
                    self.iface.openFeatureForm(layer, line_feature)
                    break
        
        else:
            
            # Delete
            layer.rollBack()
            
            # User error
            msg = "Error adding PIPE: Typically this occurs if\n the first point is not located in a existing\n node or feature is out of the defined sectors."
            QMessageBox.information(None, "PostgreSQL error:", msg)
示例#39
0
文件: grids.py 项目: gem/sidd
    def do_operation(self):
        """ perform create mapping scheme operation """    
        
        # validate inputs 
        fp_layer = self.inputs[0].value
        zone_layer = self.inputs[1].value
        zone_field = self.inputs[2].value
        count_field = self.inputs[3].value
        area_field = self.inputs[4].value 

        # make sure input is correct
        # NOTE: these checks cannot be performed at set input time
        #       because the data layer maybe is not loaded yet
        self._test_layer_loaded(fp_layer)
        self._test_layer_loaded(zone_layer)
        self._test_layer_field_exists(zone_layer, GID_FIELD_NAME)
        self._test_layer_field_exists(zone_layer, zone_field)
        # count_field is not required        
        # if count field is not defined, then generate building count from footprints        
        # area_field is not required
        
        # local variables 
        analyzer = QgsOverlayAnalyzer()
        area_idx = ToGrid.STAT_AREA_IDX
        cnt_idx = ToGrid.STAT_COUNT_IDX
        
        zone_names, zone_stat, zone_stat2, zone_totals = {}, {}, {}, {}
        
        # 1. find building count and total area for each zone
        # project geometry into mercator and get area in m2
        mercator_crs = QgsCoordinateReferenceSystem()        
        mercator_crs.createFromEpsg(3395)        
        mercator_transform = QgsCoordinateTransform(zone_layer.crs(), mercator_crs)
        
        try:
            # use zone geometry area 
            self._create_zone_statistics(zone_layer, zone_field, count_field, 
                     zone_stat, zone_names)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)

        # 2. create grids around extent of zone 
        tmp_grid1 = 'grid_' + get_unique_filename()
        tmp_grid1_file = self._tmp_dir + tmp_grid1 + '.shp'
        extent = zone_layer.extent()
        [x_min, y_min, x_max, y_max] = [extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum()]
        tmp_grid_lyr1 = self._create_grid(tmp_grid1, tmp_grid1_file, \
                                          x_min, y_min, x_max, y_max, \
                                          DEFAULT_GRID_SIZE, DEFAULT_GRID_SIZE)            

        # tally total building area if there is defined
        bldg_area_idx = layer_field_index(zone_layer, area_field)
        zone_area = {}
        zone_has_area = False        
        if bldg_area_idx > 0:
            zone_has_area = True
            zone_gid_idx = layer_field_index(zone_layer, GID_FIELD_NAME)
            for _f in layer_features(zone_layer):            
                gid = _f.attributeMap()[zone_gid_idx].toString()            
                area = _f.attributeMap()[bldg_area_idx].toDouble()[0]            
                if zone_area.has_key(gid):
                    zone_area[gid] = str(float(zone_area[gid]))+area
                else: 
                    zone_area[gid] = area
        
        # 3. intersect grids and zones to obtain polygons with 
        # - grid_id and zone_id
        # - ratio of grid covered by zone (polygon area / zone area) 
        # apply ratio to zone building count to obtain count assigned to polygon                  
        tmp_join = 'joined_%s' % get_unique_filename()
        tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join)
        try:
            # do intersection
            analyzer.intersection(tmp_grid_lyr1, zone_layer, tmp_join_file)
            tmp_join_layer = load_shapefile(tmp_join_file, tmp_join)
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)
        
        # do tally
        zone_gid_idx = layer_field_index(tmp_join_layer, GID_FIELD_NAME)
        grid_gid_idx = layer_field_index(tmp_join_layer, "GRID_GID")
        bldg_cnt_idx = layer_field_index(tmp_join_layer, count_field)
        for _f in layer_features(tmp_join_layer):
            geom = _f.geometry()
            geom.transform(mercator_transform)
            area = geom.area()
            
            # generate all stats of interest
            zone_gid = _f.attributeMap()[zone_gid_idx].toString()
            grid_gid = _f.attributeMap()[grid_gid_idx].toString()
            stat = zone_stat[zone_gid]            
            # calculate count/area as proportion of total zone area
            area_ratio = (area/stat[area_idx])
            if bldg_cnt_idx > 0:
                bldg_cnt = _f.attributeMap()[bldg_cnt_idx].toDouble()[0] * area_ratio
            else:
                bldg_cnt = 0
            if zone_has_area: 
                area = zone_area[zone_gid] * area_ratio
            else:
                area = stat[area_idx] * area_ratio                 
            self._update_stat(zone_stat2, '%s|%s'%(grid_gid, zone_gid), bldg_cnt, area)
        
        # 4. find total buildings in each zone based on footprint
        # - simply join the files and tally count and total area 
        tmp_join1 = 'joined_%s' % get_unique_filename()
        tmp_join1_file = '%s%s.shp' % (self._tmp_dir, tmp_join1)        
        try:
            # do intersection
            analyzer.intersection(fp_layer, tmp_join_layer, tmp_join1_file)
            tmp_join1_layer = load_shapefile(tmp_join1_file, tmp_join1)
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)
        
        # do tally
        zone_fp_stat = {}
        zone_gid_idx = layer_field_index(tmp_join1_layer, '%s_'% GID_FIELD_NAME)
        grid_gid_idx = layer_field_index(tmp_join1_layer, "GRID_GID")        
        fp_area_idx = layer_field_index(tmp_join1_layer, AREA_FIELD_NAME)
        fp_ht_idx = layer_field_index(tmp_join1_layer, HT_FIELD_NAME)
        fp_has_height = False
        for _f in layer_features(tmp_join1_layer):
            zone_gid = _f.attributeMap()[zone_gid_idx].toString()
            grid_gid = _f.attributeMap()[grid_gid_idx].toString()
            area = _f.attributeMap()[fp_area_idx].toDouble()[0] # area comes from geometry, always exists
            ht = _f.attributeMap()[fp_ht_idx].toDouble()[0]
            if ht > 0:
                fp_has_height = True
                area *= ht      # this is actual area to be aggregated at the end
            self._update_stat(zone_fp_stat, '%s|%s'%(grid_gid, zone_gid), 1, area)
            self._update_stat(zone_totals, zone_gid, 1, area)
        
        # 5. generate grid with adjusted building counts
        fields = {
            0 : QgsField(GID_FIELD_NAME, QVariant.String),            
            1 : QgsField(zone_field, QVariant.String),
            2 : QgsField(CNT_FIELD_NAME, QVariant.Double),
            3 : QgsField(AREA_FIELD_NAME, QVariant.Double),
        }
        output_layername = 'grid_%s' % get_unique_filename()
        output_file = '%s%s.shp' % (self._tmp_dir, output_layername)                
        writer = QgsVectorFileWriter(output_file, "utf-8", fields, QGis.WKBPolygon, self._crs, "ESRI Shapefile")
        f = QgsFeature()
        for key in zone_stat2.keys():
            (grid_gid, zone_gid) = str(key).split("|")
            s_zone = zone_stat[QString(zone_gid)]           # overall statistics for the zone from zone file (always exists)
            s_zone_grid = zone_stat2[key]                   # grid specific statistic from from zone file    (always exists)            
            if zone_totals.has_key(QString(zone_gid)):      # overall statistics for the zone from footprints
                s_total = zone_totals[QString(zone_gid)]       
            else:
                s_total = [0,0] # set to zero if missing
            if zone_fp_stat.has_key(key):                   # grid specific statistic from from footprint
                s_fp = zone_fp_stat[key]                        
            else:
                s_fp = [0, 0]   # set to zero if missing

            zone_leftover_count = s_zone[cnt_idx] - s_total[cnt_idx]   
            if zone_has_area:
                zone_leftover_area = zone_area[QString(zone_gid)] - s_total[area_idx]
            else:
                zone_leftover_area = s_zone[area_idx] - s_total[area_idx]
            if zone_leftover_count > 0:
                # there are still building not accounted for
                # distribute to grid based on ratio of grid leftover area over zone leftover area
                # (leftover area is area of zone after subtracting footprint areas                
                grid_leftover_count = zone_leftover_count * ((s_zone_grid[area_idx]-s_fp[area_idx])/zone_leftover_area)
                grid_count = s_fp[cnt_idx] + grid_leftover_count
            else:
                grid_count = s_fp[cnt_idx]
            
            if fp_has_height:
                # area can be actual area based on footprint area * height
                area = s_fp[area_idx]
            elif zone_has_area:
                area = s_zone_grid[area_idx]
            else:
                # no area defined
                area = 0 # max(s_zone_grid[area_idx], s_fp[area_idx])
                
            f.setGeometry(self._outputGeometryFromGridId(grid_gid))
            f.addAttribute(0, grid_gid)
            f.addAttribute(1, zone_names[QString(zone_gid)])
            f.addAttribute(2, grid_count)
            f.addAttribute(3, area)
            writer.addFeature(f)
        del writer
        
        # clean up
        del tmp_grid_lyr1
        del tmp_join_layer
        del tmp_join1_layer
        remove_shapefile(tmp_grid1_file)
        remove_shapefile(tmp_join_file)
        remove_shapefile(tmp_join1_file)
                
        # store data in output
        self._load_output(output_file, output_layername)
示例#40
0
    def do_operation(self):
        """ perform footprint load operation """

        # input/output data checking already done during property set
        zone_layer = self.inputs[0].value

        # make sure input is correct
        # NOTE: these checks cannot be performed at set input time
        #       because the data layer maybe is not loaded yet
        self._test_layer_loaded(zone_layer)

        x_off = self._x_off
        y_off = self._y_off

        extent = zone_layer.extent()
        [x_min, y_min, x_max, y_max] = [
            extent.xMinimum(),
            extent.yMinimum(),
            extent.xMaximum(),
            extent.yMaximum()
        ]

        # create grid based on extent of given region
        tmp_grid1 = 'grid_' + get_unique_filename()
        tmp_grid1_file = self._tmp_dir + tmp_grid1 + '.shp'

        try:
            self._write_grid_shapefile(tmp_grid1_file, x_min, y_min, x_max,
                                       y_max, x_off, y_off)
        except:
            remove_shapefile(tmp_grid1_file)
            raise OperatorError('error creating temporary grid',
                                self.__class__)

        tmp_grid1_layer = load_shapefile(tmp_grid1_file, tmp_grid1)

        # temporary grid for joined shape with all grid points not within region removed
        tmp_grid2 = 'grid_' + get_unique_filename()
        tmp_grid2_file = self._tmp_dir + tmp_grid2 + '.shp'
        tmp_grid2_layer = None
        try:
            analyzer = QgsOverlayAnalyzer()
            analyzer.intersection(tmp_grid1_layer, zone_layer, tmp_grid2_file)
            tmp_grid2_layer = load_shapefile(tmp_grid2_file, tmp_grid2)
        except:
            raise OperatorError('error creating grid', self.__class__)

        # create result layer
        grid_layername = 'grid_%s' % get_unique_filename()
        grid_file = self._tmp_dir + grid_layername + '.shp'
        try:
            writer = QgsVectorFileWriter(grid_file, "utf-8", self._fields,
                                         QGis.WKBPoint, self._crs,
                                         "ESRI Shapefile")
            f = QgsFeature()
            lon_idx = layer_field_index(tmp_grid2_layer, self._lon_field)
            lat_idx = layer_field_index(tmp_grid2_layer, self._lat_field)
            for _f in layer_features(tmp_grid2_layer):
                lon = _f.attributeMap()[lon_idx].toDouble()[0]
                lat = _f.attributeMap()[lat_idx].toDouble()[0]

                f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat)))
                f.addAttribute(0, QVariant(lon))
                f.addAttribute(1, QVariant(lat))
                writer.addFeature(f)
            del writer
        except Exception as err:
            logAPICall.log(str(err), logAPICall.ERROR)
            raise OperatorError('error writing out grid', self.__class__)

        grid_layer = load_shapefile(grid_file, grid_layername)
        if not grid_layer:
            raise OperatorError('Error loading result grid file' % (grid_file),
                                self.__class__)

        # clean up
        del analyzer, tmp_grid1_layer, tmp_grid2_layer
        remove_shapefile(tmp_grid1_file)
        remove_shapefile(tmp_grid2_file)

        self.outputs[0].value = grid_layer
        self.outputs[1].value = grid_file
示例#41
0
文件: survey.py 项目: gem/sidd
    def _buildSurveyLayer(self, data, shapefilepath):
        writer = QgsVectorFileWriter(shapefilepath, "utf-8", self._fields, QGis.WKBPoint, self._crs, "ESRI Shapefile")
        f = QgsFeature()
        for row in data:
            obj_uid = str(row[0])
            lon = self._tofloat(row[1])
            lat = self._tofloat(row[2])
            sample_grp = str(row[3])
            plan_area = self._tofloat(row[4])
            rep_cost = self._tofloat(row[5])
            tax_string = self._make_gem_taxstring(row[6:])
            ht = self._get_height(row[6:])

            f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat)))
            f.addAttribute(0, QVariant(obj_uid))
            f.addAttribute(1, QVariant(lon))
            f.addAttribute(2, QVariant(lat))
            f.addAttribute(3, QVariant(tax_string))
            f.addAttribute(4, QVariant(sample_grp))
            f.addAttribute(5, QVariant(plan_area))
            f.addAttribute(6, QVariant(ht))
            f.addAttribute(7, QVariant(rep_cost))
            writer.addFeature(f)
        del writer, f
示例#42
0
文件: join.py 项目: gem/sidd
    def do_operation(self):
        """ perform create mapping scheme operation """

        # input/output verification already performed during set input/ouput
        zone_layer = self.inputs[0].value
        zone_field = self.inputs[1].value
        fp_layer = self.inputs[2].value

        # merge with zone to get assignment
        tmp_join = 'joined_%s' % get_unique_filename()
        tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join)
        analyzer = QgsOverlayAnalyzer()
        try:
            analyzer.intersection(fp_layer, zone_layer, tmp_join_file)
            tmp_join_layer = load_shapefile_verify(tmp_join_file, tmp_join,
                                                   [zone_field])
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)
        except Exception as err:
            raise OperatorError(str(err), self.__class__)

        fields = {
            0: QgsField(self._lon_field, QVariant.Double),
            1: QgsField(self._lat_field, QVariant.Double),
            2: QgsField(zone_field, QVariant.String),
        }
        zone_idx = layer_field_index(tmp_join_layer, zone_field)
        fp_layername = 'fpc_%s' % get_unique_filename()
        fp_file = '%s%s.shp' % (self._tmp_dir, fp_layername)
        try:
            writer = QgsVectorFileWriter(fp_file, "utf-8", fields,
                                         QGis.WKBPoint, self._crs,
                                         "ESRI Shapefile")
            f = QgsFeature()
            for _f in layer_features(tmp_join_layer):
                centroid = _f.geometry().centroid().asPoint()
                lon = centroid.x()
                lat = centroid.y()
                zone_str = str(_f.attributeMap()[zone_idx].toString()).upper()

                f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat)))
                f.addAttribute(0, QVariant(lon))
                f.addAttribute(1, QVariant(lat))
                f.addAttribute(2, QVariant(zone_str))
                writer.addFeature(f)

            del writer
        except Exception as err:
            logAPICall.log(err, logAPICall.ERROR)
            remove_shapefile(fp_file)
            raise OperatorError("error creating joined grid: %s" % err,
                                self.__class__)

        # load shapefile as layer
        fp_layer = load_shapefile(fp_file, fp_layername)
        if not fp_layer:
            raise OperatorError(
                'Error loading footprint centroid file' % (fp_file),
                self.__class__)

        # clean up
        del tmp_join_layer
        remove_shapefile(tmp_join_file)

        self.outputs[0].value = fp_layer
        self.outputs[1].value = fp_file
示例#43
0
文件: grid.py 项目: ImageCatInc/sidd
    def do_operation(self):
        """ perform footprint load operation """
        
        # input/output data checking already done during property set         
        zone_layer = self.inputs[0].value        
        
        # make sure input is correct
        # NOTE: these checks cannot be performed at set input time
        #       because the data layer maybe is not loaded yet
        self._test_layer_loaded(zone_layer)
                
        x_off = self._x_off
        y_off = self._y_off

        extent = zone_layer.extent()
        [x_min, y_min, x_max, y_max] = [extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum()]

        # create grid based on extent of given region 
        tmp_grid1 = 'grid_' + get_unique_filename()
        tmp_grid1_file = self._tmp_dir + tmp_grid1 + '.shp'

        try:
            self._write_grid_shapefile(tmp_grid1_file,
                                       x_min, y_min, x_max, y_max,
                                       x_off, y_off)
        except:
            remove_shapefile(tmp_grid1_file)
            raise OperatorError('error creating temporary grid', self.__class__)        
        
        tmp_grid1_layer = load_shapefile(tmp_grid1_file, tmp_grid1)
        
        # temporary grid for joined shape with all grid points not within region removed 
        tmp_grid2 = 'grid_' + get_unique_filename()
        tmp_grid2_file = self._tmp_dir + tmp_grid2 + '.shp'
        tmp_grid2_layer = None
        try:
            analyzer = QgsOverlayAnalyzer()        
            analyzer.intersection(tmp_grid1_layer, zone_layer, tmp_grid2_file)
            tmp_grid2_layer = load_shapefile(tmp_grid2_file, tmp_grid2)
        except:
            raise OperatorError('error creating grid', self.__class__)

        # create result layer
        grid_layername = 'grid_%s' % get_unique_filename()
        grid_file = self._tmp_dir + grid_layername + '.shp'
        try:
            writer = QgsVectorFileWriter(grid_file, "utf-8", self._fields,
                                         QGis.WKBPoint, self._crs, "ESRI Shapefile")
            f = QgsFeature()
            lon_idx = layer_field_index(tmp_grid2_layer, self._lon_field)
            lat_idx = layer_field_index(tmp_grid2_layer, self._lat_field)        
            for _f in layer_features(tmp_grid2_layer):
                lon = _f.attributeMap()[lon_idx].toDouble()[0]
                lat = _f.attributeMap()[lat_idx].toDouble()[0]
                
                f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat)))
                f.addAttribute(0, QVariant(lon))
                f.addAttribute(1, QVariant(lat))
                writer.addFeature(f)                
            del writer
        except  Exception as err:
            logAPICall.log(str(err), logAPICall.ERROR)
            raise OperatorError('error writing out grid', self.__class__)

        grid_layer = load_shapefile(grid_file, grid_layername)
        if not grid_layer:
            raise OperatorError('Error loading result grid file' % (grid_file), self.__class__)        
        
        # clean up
        del analyzer, tmp_grid1_layer, tmp_grid2_layer
        remove_shapefile(tmp_grid1_file)
        remove_shapefile(tmp_grid2_file)
        
        self.outputs[0].value = grid_layer
        self.outputs[1].value = grid_file
示例#44
0
文件: popgrid.py 项目: gem/sidd
    def do_operation(self):
        """ perform footprint load operation """

        # input/output data checking already done during property set
        # load and verify
        popgrid_file = self.inputs[0].value
        pop_field = self.inputs[1].value

        popgrid_layername = 'zone_%s' % get_unique_filename()
        try:
            tmp_popgrid_layer = load_shapefile_verify(popgrid_file,
                                                      popgrid_layername,
                                                      [pop_field])
        except AssertionError as err:
            raise OperatorError(str(err), self.__class__)

        logAPICall.log(
            'tmp_fp_layer.crs().epsg() %s ' % tmp_popgrid_layer.crs().epsg(),
            logAPICall.DEBUG)
        if tmp_popgrid_layer.crs().epsg() != self._crs.epsg():
            transform = QgsCoordinateTransform(tmp_popgrid_layer.crs(),
                                               self._crs)
            transform_required = True
        else:
            transform_required = False

        # output grid
        fields = {
            0: QgsField(GID_FIELD_NAME, QVariant.Int),
            1: QgsField(CNT_FIELD_NAME, QVariant.Double),
        }
        pop_idx = layer_field_index(tmp_popgrid_layer, pop_field)
        output_file = '%spop_grid_%s.shp' % (self._tmp_dir,
                                             get_unique_filename())
        logAPICall.log('create outputfile %s ... ' % output_file,
                       logAPICall.DEBUG)
        try:
            writer = QgsVectorFileWriter(output_file, "utf-8", fields,
                                         QGis.WKBPoint, self._crs,
                                         "ESRI Shapefile")
            f = QgsFeature()
            gid = 0
            for _f in layer_features(tmp_popgrid_layer):
                # NOTE: geom.transform does projection in place to underlying C object

                # 1. get geometry
                geom = _f.geometry()
                # 2. change project if required
                if transform_required:
                    geom = transform.transform(geom)

                # 3. write to file
                gid += 1
                f.setGeometry(geom)
                f.addAttribute(0, QVariant(gid))
                f.addAttribute(1, _f.attributeMap()[pop_idx])
                writer.addFeature(f)
            del writer, f
        except Exception as err:
            remove_shapefile(output_file)
            raise OperatorError("error creating footprint centroids: %s" % err,
                                self.__class__)

        popgrid_layername = 'popgrid_%s' % get_unique_filename()
        popgrid_layer = load_shapefile(output_file, popgrid_layername)
        if not popgrid_layer:
            raise OperatorError(
                'Error loading footprint centroid file' % (output_file),
                self.__class__)

        # clean up
        del tmp_popgrid_layer

        # store data in output
        self.outputs[0].value = popgrid_layer
        self.outputs[1].value = output_file