Exemple #1
0
    def styles_to_attributes_finished(self, input_layer: QgsVectorLayer, context: QgsProcessingContext, id: uuid.UUID,
                                      succesful: bool, results: Dict[str, any]) -> None:
        row = self.layer_rows[id]
        if succesful:
            legends = [Legend.from_dict(legend) for legend in results["OUTPUT_LEGEND"].values()]
            LOGGER.info(tr('Exporting styles for {} finished successfully', input_layer.name()))

            output_layer: QgsVectorLayer = context.takeResultLayer(results['OUTPUT'])
            if output_layer and output_layer.isValid():
                with tempfile.TemporaryDirectory(dir=resources_path()) as tmpdirname:
                    style_file = os.path.join(tmpdirname, 'style.qml')
                    msg, succeeded = input_layer.saveNamedStyle(style_file)
                    if succeeded:
                        output_layer.loadNamedStyle(style_file)
                    else:
                        LOGGER.error(tr('Could not load style'), extra=bar_msg(msg))

                QgsProject.instance().addMapLayer(output_layer)
                row['styled_layer'] = StyledLayer(row['layer_name'], output_layer.id(), legends)

            row['finished'] = True
        else:
            feedback: LoggerProcessingFeedBack = row['feedback']
            error_msg = feedback.last_report_error
            LOGGER.error(tr('Exporting styles for {} finished with errors', input_layer.name()),
                         extra=bar_msg(details=tr(f'Details: {error_msg}. Check log file for more details')))
            self._enable_ui()
Exemple #2
0
    def post_process_value_relation_fields(self, e_layer: QgsVectorLayer,
                                           o_field: QgsField):
        project = QgsProject.instance()
        o_ews = o_field.editorWidgetSetup()
        o_widget_config = o_ews.config()
        o_referenced_layer_id = o_widget_config["Layer"]

        if o_referenced_layer_id not in self.__layer_data_by_id:
            e_referenced_layer = QgsValueRelationFieldFormatter.resolveLayer(
                o_widget_config, project)

            if e_referenced_layer:
                o_referenced_layer_id = e_referenced_layer.customProperty(
                    "remoteLayerId")

        # yet another check whether value relation resolver succeeded
        if o_referenced_layer_id not in self.__layer_data_by_id:
            self.warning.emit(
                self.tr("Bad attribute form configuration"),
                self.
                tr('Field "{}" in layer "{}" has no configured layer in the value relation widget.'
                   ).format(o_field.name(), e_layer.name()),
            )
            return

        e_referenced_layer_id = None
        for e_layer in project.mapLayers().values():
            o_layer_data = self.__layer_data_by_id[o_referenced_layer_id]

            if e_layer.customProperty(
                    "remoteSource") == o_layer_data["source"]:
                #  First try strict matching: the offline layer should have a "remoteSource" property
                e_referenced_layer_id = e_layer.id()
                break
            elif e_layer.name() == o_layer_data["name"]:
                #  If that did not work, go with loose matching
                e_referenced_layer_id = e_layer.id()
                break

        if not e_referenced_layer_id:
            self.warning.emit(
                self.tr("Bad attribute form configuration"),
                self.
                tr('Field "{}" in layer "{}" has no configured layer in the value relation widget.'
                   ).format(o_field.name(), e_layer.name()),
            )
            return

        e_widget_config = o_widget_config
        e_widget_config["Layer"] = e_referenced_layer_id
        e_layer.setEditorWidgetSetup(
            e_layer.fields().indexOf(o_field.name()),
            QgsEditorWidgetSetup(o_ews.type(), e_widget_config),
        )
Exemple #3
0
    def get_sql_layer(self, table, geom, pk, uri, feedback):
        sql_file = resources_path('sql', 'export',
                                  'export_{}.sql'.format(table))
        other = False
        if not os.path.exists(sql_file):
            sql_file = resources_path('sql', 'export', 'export_table.sql')
            other = True

        with open(sql_file, "r") as f:
            sql = f.read()
            if len(sql.strip()) == 0:
                feedback.reportError("Fichier SQL vide")
                return None
        sql = str(sql)
        if other:
            sql += table

        uri.setSchema('')
        uri.setTable('(' + sql + ')')
        uri.setGeometryColumn(geom)
        uri.setKeyColumn(pk)

        layer = QgsVectorLayer(uri.uri(False), table, "postgres")
        if not layer.isValid():
            feedback.reportError("Layer not valid " + layer.name())
            return None
        return layer
Exemple #4
0
    def from_line_layer(layer: QgsVectorLayer):
        reach = Reach(
            my_id=0,
            name=layer.name(),
            crs_id=layer.crs().authid(),
        )

        section = None
        for f in layer.getFeatures():

            section = Section(
                my_id=f.attribute("sec_id"),
                name=f.attribute("sec_name"),
                pk=f.attribute("abs_long"),
            )

            # Take only the first parts (QgsMultiLineString => QgsLineString)
            line = next(f.geometry().constParts()).clone()

            section.set_points([
                Point(
                    x=p[0].x(),
                    y=p[0].y(),
                    z=p[1],
                    d=p[2],
                ) for p in zip(
                    line.points(),
                    f.attribute("zfond").split(","),
                    f.attribute("abs_lat").split(","),
                )
            ])

            reach.add_section(section)

        return reach
Exemple #5
0
    def from_point_layer(layer: QgsVectorLayer):
        reach = Reach(
            my_id=0,
            name=layer.name(),
            crs_id=layer.crs().authid(),
        )

        section = None
        points = []
        for f in layer.getFeatures():
            if section is not None:
                if f.attribute("sec_id") != section.id:
                    reach.add_section(section.set_points(points))
                    section = None
                    points = []

            if section is None:
                section = Section(
                    my_id=f.attribute("sec_id"),
                    pk=f.attribute("abs_long"),
                    name=f.attribute("sec_name"),
                )

            points.append(
                Point(
                    x=f.geometry().constGet().x(),
                    y=f.geometry().constGet().y(),
                    z=f.attribute("zfond"),
                    d=f.attribute("abs_lat"),
                ))
        if section is not None:
            reach.add_section(section.set_points(points))

        return reach
Exemple #6
0
def export_layer_as(layer, layer_name, layer_format, to_dir):
    """Convertir un fichier sph en format donné
    :param layer: la couche
    :type layer: str ou QgsVectorLayer

    :param layer_name nom du fichier en sorti
    :type layer_name: str

    :param layer_format: le format final
    :type layer_format: str

    :param to_dir: le nouveau chemin
    :type to_dir: str

    """
    if layer_name is None:
        if isinstance(layer, str):
            layer_name = basename(layer).replace(".shp", "")
            layer = QgsVectorLayer(layer, layer_name, "ogr")
        else:
            layer_name = layer.name()

    layer_path = join(to_dir,
                      layer_name + '{}'.format(extension[layer_format]))

    options = QgsVectorFileWriter.SaveVectorOptions()
    options.driverName = layer_format
    options.layerName = layer_name
    options.fileEncoding = 'utf-8'
    QgsVectorFileWriter.writeAsVectorFormat(layer, layer_path, options)
    QgsMessageLog.logMessage(
        "Les fichiers {} sont bien enregistrés dans {}".format(
            layer_format, to_dir), 'UnderMap', Qgis.Info)
    def test_add_layer_to_registry(self):
        layer_name = layer_interaction.biuniquify_layer_name('this_layer_was_added_for_testing_purpose')

        layer = QgsVectorLayer('Polygon?crs=EPSG:3857', layer_name, 'memory', False)

        number_of_layers = len(QgsMapLayerRegistry.instance().mapLayers())
        layer_interaction.add_layer_to_registry(layer)
        self.layer_list.append(layer.name())

        map_layers = QgsMapLayerRegistry.instance().mapLayers()
        actual = len(map_layers)
        expected = number_of_layers + 1
        message = 'An error occured when adding a layer to the MapLayerRegistry. {} is not {}!'.format(actual, expected)
        self.assertEqual(actual, expected, message)

        layer_added = False
        for layer_key in map_layers:

            if map_layers[layer_key].name() == layer_name:
                layer_added = True
                break

        self.assertTrue(layer_added, 'An error occured when adding a layer to the MapLayerRegistry.')
        number_of_layers = len(map_layers)
        layer_interaction.add_layer_to_registry(None)
        self.assertEqual(len(QgsMapLayerRegistry.instance().mapLayers()), number_of_layers, 'An error occured when trying to add a none-type-layer to the MapLayerRegistry. The number of layers should not increase.')
Exemple #8
0
 def duplicateLayer(self, currentLayer: QgsVectorLayer, suffix: str,
                    scoreName: str):
     """Duplicate original Layer.
     
     :param currentLayer QgsVectorLayer:The layer will be duplicated
     :param suffix str: Suffix name
     :param scoreName str: Attribute name of score in attribute table
     
     """
     # print(currentLayer)
     # print(suffix)
     # print(scoreName)
     layername = str(currentLayer.name()) + "_" + str(suffix)
     layer = QgsVectorLayer("Polygon?crs=ESPG:4326", layername, 'memory')
     # print("layer created")
     layer.setCrs(currentLayer.sourceCrs())
     # print("crs set")
     layer.dataProvider().addAttributes(
         currentLayer.dataProvider().fields().toList())
     # print("add field")
     # adding score attributes info
     layer.dataProvider().addAttributes([
         QgsField(scoreName, QVariant.Double),
         QgsField('id', QVariant.Int),
         QgsField('match', QVariant.Int)
     ])
     # print("field updated")
     # update the fields
     layer.updateFields()
     # print("updated fields")
     layer.dataProvider().addFeatures(currentLayer.getFeatures())
     # print(layer.featureCount())
     # print("features updated")
     return layer
Exemple #9
0
def getSavePaths(fileName: str, domainLayer: QgsVectorLayer, typeDir: str):
    """Description: Processes a raster image into a vector polygon ocean/land mask.
		Get a standardized vector name from a Landsat raster file name.
		Input:  str fileName - Landsat raster file name.
				str glacierName - Root vector file name.
				str typeDir - name of the type subdirectory.
		Output: str path - file save paths.
	"""

    date = fileName.split('_')[2]
    year = date.split('-')[0]

    # if (rootGroup.parent().name().startswith('2') or rootGroup.parent().name().startswith('1')):
    # rootGroup = rootGroup.parent()

    path = resolve('CalvingFronts')
    if (not os.path.exists(path)):
        os.mkdir(path)
    path = os.path.join(path, typeDir)
    if (not os.path.exists(path)):
        os.mkdir(path)
    path = os.path.join(path, domainLayer.name())
    if (not os.path.exists(path)):
        os.mkdir(path)
    path = os.path.join(path, year)
    if (not os.path.exists(path)):
        os.mkdir(path)

    return path
Exemple #10
0
    def test_add_layer_to_registry(self):
        layer_name = layer_interaction.biuniquify_layer_name(
            'this_layer_was_added_for_testing_purpose')

        layer = QgsVectorLayer('Polygon?crs=EPSG:3857', layer_name, 'memory',
                               False)

        number_of_layers = len(QgsMapLayerRegistry.instance().mapLayers())
        layer_interaction.add_layer_to_registry(layer)
        self.layer_list.append(layer.name())

        map_layers = QgsMapLayerRegistry.instance().mapLayers()
        actual = len(map_layers)
        expected = number_of_layers + 1
        message = 'An error occured when adding a layer to the MapLayerRegistry. {} is not {}!'.format(
            actual, expected)
        self.assertEqual(actual, expected, message)

        layer_added = False
        for layer_key in map_layers:

            if map_layers[layer_key].name() == layer_name:
                layer_added = True
                break

        self.assertTrue(
            layer_added,
            'An error occured when adding a layer to the MapLayerRegistry.')
        number_of_layers = len(map_layers)
        layer_interaction.add_layer_to_registry(None)
        self.assertEqual(
            len(QgsMapLayerRegistry.instance().mapLayers()), number_of_layers,
            'An error occured when trying to add a none-type-layer to the MapLayerRegistry. The number of layers should not increase.'
        )
Exemple #11
0
    def _write_gpkg(self, csv_files, output_file):
        layer_names = []
        options = QgsVectorFileWriter.SaveVectorOptions()
        options.driverName = 'GPKG'

        for csv in csv_files:
            # build URI
            uri = 'file:///{}?delimiter=,'.format(csv)
            csv_name = Path(Path(csv).name).stem
            if csv_name == 'stops':
                uri += '&xField=stop_lon&yField=stop_lat&crs=epsg:4326'
            elif csv_name == 'shapes':
                uri += '&xField=shape_pt_lon&yField=shape_pt_lat&crs=epsg:4326'
                csv_name='shapes_point'

            # create CSV-based layer
            layer_names.append(csv_name)
            layer = QgsVectorLayer(uri, csv_name, 'delimitedtext')

            # save layer to GPKG
            options.layerName = layer.name().replace(' ', '_')
            code, msg = QgsVectorFileWriter.writeAsVectorFormat(layer, output_file, options)
            # if code != QgsVectorFileWriter.NoError:
            #         raise GtfsError("Unable to create output GPKG file {} (details: {}/{})".format(output_file, code, msg))

            # append layers into single GPKG
            options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer
        # Return all layers from geopackage
        return layer_names
Exemple #12
0
 def from_qgs_layer(layer: QgsVectorLayer, parent_layer: Optional['LayerWrapper'] = None,
                    foreign_field: Optional[FieldWrapper] = None) -> 'LayerWrapper':
     pk_idxs = layer.primaryKeyAttributes()
     if len(pk_idxs):
         pk_field = layer.fields().toList()[pk_idxs[0]].name()
     else:
         pk_field = None
     return LayerWrapper(layer.name(), pk_field, parent_layer=parent_layer, foreign_field=foreign_field)
Exemple #13
0
    def load_layers(
            self,  #load data to project (for console runs)
            rfp_l,
            finv_fp,
            providerLib='ogr'):
        """
        special input loader for standalone runs
        Im assuming for the plugin these layers will be loaded already"""
        log = self.logger.getChild('load_layers')
        #======================================================================
        # load rasters
        #======================================================================
        raster_d = dict()

        for fp in rfp_l:
            rlayer = self.load_rlay(fp)

            #add it in
            basefn = os.path.splitext(os.path.split(fp)[1])[0]
            raster_d[basefn] = rlayer

        #======================================================================
        # load finv vector layer
        #======================================================================
        fp = finv_fp
        assert os.path.exists(fp)
        basefn = os.path.splitext(os.path.split(fp)[1])[0]
        vlay_raw = QgsVectorLayer(fp, basefn, providerLib)

        # checks
        if not isinstance(vlay_raw, QgsVectorLayer):
            raise IOError

        #check if this is valid
        if not vlay_raw.isValid():
            raise Error(
                'loaded vlay \'%s\' is not valid. \n \n did you initilize?' %
                vlay_raw.name())

        #check if it has geometry
        if vlay_raw.wkbType() == 100:
            raise Error('loaded vlay has NoGeometry')

        self.mstore.addMapLayer(vlay_raw)

        vlay = vlay_raw
        dp = vlay.dataProvider()

        log.info(
            'loaded vlay \'%s\' as \'%s\' %s geo  with %i feats from file: \n     %s'
            % (vlay.name(), dp.storageType(), QgsWkbTypes().displayString(
                vlay.wkbType()), dp.featureCount(), fp))

        #======================================================================
        # wrap
        #======================================================================

        return list(raster_d.values()), vlay
    def save_track(self):
        """
        Save the track to disk
        """
        layer_name, selected_filter = QFileDialog.getSaveFileName(None, 'Save Track', "",
                                                                  'Shapefile (*.shp);;KML (*.kml);;GPX (*.gpx)')

        if layer_name != '':

            if self.geom_type == QgsWkbTypes.PointGeometry:
                geometric_object = "MultiPoint?crs=epsg:4326"
            else:
                geometric_object = "LineString?crs=epsg:4326"

            layer = QgsVectorLayer(
                geometric_object,
                layer_name,
                "memory")
            feature = QgsFeature()
            feature.setGeometry(self.band.asGeometry())
            layer.dataProvider().addFeatures([feature])

            if selected_filter == "Shapefile (*.shp)":

                if not layer_name.endswith('.shp'):
                    layer_name = layer_name + '.shp'
                ret = QgsVectorFileWriter.writeAsVectorFormat(layer, layer_name, "utf-8",
                                                              QgsCoordinateReferenceSystem(4326,
                                                                                           QgsCoordinateReferenceSystem.EpsgCrsId),
                                                              "ESRI Shapefile")
                if ret == QgsVectorFileWriter.NoError:
                    logger.info(layer.name() + " saved to " + layer_name)

            elif selected_filter == "KML (*.kml)":

                if not layer_name.endswith('.kml'):
                    layer_name = layer_name + '.kml'

                QgsVectorFileWriter.writeAsVectorFormat(layer, layer_name, "utf-8",
                                                        QgsCoordinateReferenceSystem(4326,
                                                                                     QgsCoordinateReferenceSystem.EpsgCrsId),
                                                        "KML")
            elif selected_filter == "GPX (*.gpx)":

                if not layer_name.endswith('.gpx'):
                    layer_name = layer_name + '.gpx'
                ds_options = list()
                ds_options.append("GPX_USE_EXTENSIONS=TRUE")
                QgsVectorFileWriter.writeAsVectorFormat(layer, layer_name, "utf-8",
                                                        QgsCoordinateReferenceSystem(4326,
                                                                                     QgsCoordinateReferenceSystem.EpsgCrsId),
                                                        "GPX",
                                                        datasourceOptions=ds_options)
Exemple #15
0
    def duplicateEmptyLayer(self, currentLayer: QgsVectorLayer):
        layer = QgsVectorLayer("Polygon?crs=ESPG:4326", currentLayer.name(),
                               'memory')
        # print("layer created")
        layer.setCrs(currentLayer.sourceCrs())
        # print("crs set")
        layer.dataProvider().addAttributes(
            currentLayer.dataProvider().fields().toList())

        layer.updateFields()

        return layer
Exemple #16
0
    def processAlgorithm(self, parameters, context, feedback):
        msg = ""
        table_without_geom = [
            'itineraire', 'element', 'poi_portion', 'poi_acces', 'poi_service',
            'poi_tourisme'
        ]
        feedback.pushInfo("## CONNEXION A LA BASE DE DONNEES ##")
        connection = self.parameterAsString(parameters, self.DATABASE, context)
        table_int = self.parameterAsEnum(parameters, self.TABLE, context)
        table_name = self.EXPORTABLES[table_int]
        if table_name in table_without_geom or "val" in table_name:
            geom = None
        else:
            geom = "geom"
        name = table_name
        uri = uri_from_name(connection)
        if table_name == 'portion':
            name = 'v_portion'
            uri.setKeyColumn('id_portion')
        uri.setTable(name)
        uri.setSchema(self.parameterAsString(parameters, self.SCHEMA, context))
        uri.setGeometryColumn(geom)
        layer = QgsVectorLayer(uri.uri(), table_name, "postgres")
        layer_name = layer.name()

        pk = layer.fields().field(layer.primaryKeyAttributes()[0])

        dpt = self.parameterAsString(parameters, self.DPT, context)
        dirname = self.parameterAsString(parameters, self.PROJECTS_FOLDER,
                                         context)

        charger = self.parameterAsBool(parameters, self.CHARGER, context)

        feedback.pushInfo("")
        feedback.pushInfo("## CHARGEMENT DE LA COUCHE ##")

        sql_layer = self.get_sql_layer(layer_name, geom, pk.name(), uri,
                                       feedback)
        result = self.export_layer_to_shape(context, sql_layer, dpt,
                                            layer_name, dirname, feedback)
        if charger:
            self.load_shapefile(result[0], result[1], layer_name, context,
                                feedback)

        if not result[0]:
            output_layer = ""
        else:
            output_layer = result[0]

        return {self.OUTPUT_MSG: msg, self.OUTPUT: output_layer}
    def layerPermissions(  # noqa: ignore=N802
        self, layer: QgsVectorLayer
    ) -> qgis.server.QgsAccessControlFilter.LayerPermissions:
        """
        Returns the layer rights.
        """

        LOG.debug("layerPermissions %s", layer.name())

        try:
            rights = QgsAccessControlFilter.LayerPermissions()
            rights.canRead = rights.canInsert = rights.canUpdate = rights.canDelete = False

            if self.ogcserver is None:
                parameters = self.serverInterface().requestHandler(
                ).parameterMap()
                LOG.warning(
                    "Call on uninitialized plugin, map: %s",
                    os.environ.get("QGIS_PROJECT_FILE", parameters.get("MAP")),
                )
                return rights

            session = self.DBSession()
            try:
                roles = self.get_roles(session)

                if roles == "ROOT":
                    rights.canRead = True

                layers = self.get_layers(session)
                ogc_layer_name = self.ogc_layer_name(layer)
                if ogc_layer_name not in layers:
                    return rights
                gmf_layers = self.get_layers(session)[ogc_layer_name]
            finally:
                session.close()
            access, _ = self.get_restriction_areas(gmf_layers, roles=roles)
            if access is not Access.NO:
                rights.canRead = True

            access, _ = self.get_restriction_areas(gmf_layers,
                                                   read_write=True,
                                                   roles=roles)
            rights.canInsert = rights.canUpdate = rights.canDelete = access is not Access.NO

            return rights
        except Exception:
            LOG.error("Cannot run layerPermissions", exc_info=True)
            raise
def get_field_index(layer: QgsVectorLayer, field_name: str) -> int:
    """
    Get field index if exists
    :param layer: QgsVectorLayer
    :param field_name: name of the field
    :return: index of the field
    """
    field_index = layer.fields().indexFromName(field_name)
    if field_index == -1:
        raise KeyError(
            tr(
                "Field name {} does not exist in layer {}",
                field_name,
                layer.name(),
            ))
    return field_index
Exemple #19
0
def layerResize(rasterLayer: QgsRasterLayer, domainLayer: QgsVectorLayer,
                name: str, resolution: (int, int)) -> None:
    """Description: Processes a raster image into a vector polygon ocean/land mask.
		Make sure to save the shapefile, as it will be deleted otherwise! 
		Input:  QgsRasterLayer rasterLayer - layer that contains the raster image to process
				QgsVectorLayer domainLayer - layer that contains a polygon specifying the bounds of the raster image to process
				QgsVectorLayer outputLayer - layer to save vector layer in. Warning: not supported yet. 
		Output: QgsRasterLayer, QgsVectorLayer - objects referencing the new mask layers
	"""

    path = resolve('landsat_raw/' + domainLayer.name() + '/' + name + '.png')
    img = imread(path)
    img = resize(img, resolution)
    print(img.shape, path)
    if not DRY_RUN:
        imsave(path, img)
def test_vector_layer():
    input_layer = QgsVectorLayer(
        r"C:\Users\diane.soares\Downloads\ne_10m_airports\ne_10m_airports.shp",
        "ne_10m_airports", "ogr")

    if not input_layer:
        print("Layer failed to load!")

    print(input_layer.name())
    print(input_layer.crs().isValid())
    print(input_layer.crs().authid())
    print(input_layer.crs().toWkt())

    source = unicode(input_layer.source())
    print(source)

    return input_layer
    def layerFilterSubsetString(
            self, layer: QgsVectorLayer) -> str:  # noqa: ignore=N802
        """ Returns an additional subset string (typically SQL) filter """

        LOG.debug("layerFilterSubsetString %s %s", layer.name(),
                  layer.dataProvider().storageType())

        if self.ogcserver is None:
            parameters = self.serverInterface().requestHandler().parameterMap()
            LOG.warning(
                "Call on uninitialized plugin, map: %s",
                os.environ.get("QGIS_PROJECT_FILE", parameters.get("MAP")),
            )
            return "FALSE"

        try:
            if layer.dataProvider().storageType(
            ) not in self.SUBSETSTRING_TYPE:
                LOG.debug("layerFilterSubsetString not in type")
                return None

            session = self.DBSession()
            try:
                access, area = self.get_area(layer, session)
            finally:
                session.close()
            if access is Access.FULL:
                LOG.debug("layerFilterSubsetString no area")
                return None
            if access is Access.NO:
                LOG.debug("layerFilterSubsetString not allowed")
                return "0"

            area = "ST_GeomFromText('{}', {})".format(area.wkt, self.srid)
            if self.srid != layer.crs().postgisSrid():
                area = "ST_transform({}, {})".format(area,
                                                     layer.crs().postgisSrid())
            result = "ST_intersects({}, {})".format(
                QgsDataSourceUri(
                    layer.dataProvider().dataSourceUri()).geometryColumn(),
                area)
            LOG.debug("layerFilterSubsetString filter: %s", result)
            return result
        except Exception:
            LOG.error("Cannot run layerFilterSubsetString", exc_info=True)
            raise
    def add_vector_layer(self):
        """ Add vector layer to project."""
        self.vector_filename = self.vector_file_lineEdit.text()
        self.vector_base_name = self.vector_name_lineEdit.text()

        if self.vector_file_extension is not None and self.vector_file_extension.lower() == "gpx":
            vlayer_routes = QgsVectorLayer(self.vector_filename + "?type=route", self.vector_base_name+"_route", "gpx")
            vlayer_tracks = QgsVectorLayer(self.vector_filename + "?type=track", self.vector_base_name+"_track", "gpx")
            vlayer_waypoints = QgsVectorLayer(self.vector_filename + "?type=waypoint", self.vector_base_name+" waypoints", "gpx")

            if not vlayer_routes.isValid() or not vlayer_waypoints.isValid() or not vlayer_tracks.isValid():
                logger.warning("Layer failed to load!")
                QMessageBox.critical(self,
                                     "Add Layer",
                                     "Layer format is not recognised as a supported file format",
                                     QMessageBox.Close)
                self.msglog.logMessage("Failed to load layer " + self.vector_filename, "LoadingLayer", 1)

                self.vector_file_lineEdit.setText('')
                self.vector_name_lineEdit.setText('')

            else:
                if vlayer_routes.dataProvider().featureCount() > 0:
                    self.proj.addMapLayer(vlayer_routes)
                if vlayer_tracks.dataProvider().featureCount() > 0:
                    self.proj.addMapLayer(vlayer_tracks)
                if vlayer_waypoints.dataProvider().featureCount() > 0:
                    self.proj.addMapLayer(vlayer_waypoints)

                self.accept()
        else:
            vlayer = QgsVectorLayer(self.vector_filename, self.vector_base_name, "ogr")
            if not vlayer.isValid():
                logger.warning("Layer failed to load!")
                QMessageBox.critical(self,
                                     "Add Layer",
                                     "Layer format is not recognised as a supported file format",
                                     QMessageBox.Close)
                self.msglog.logMessage("Failed to load layer " + vlayer.name(), "LoadingLayer", 1)

                self.vector_file_lineEdit.setText('')
                self.vector_name_lineEdit.setText('')
            else:
                self.proj.addMapLayer(vlayer)
                self.accept()
Exemple #23
0
 def exportGlobalSummary(settings_instance, targetFile=None):
     #settings_instance.getSummaryWidget().updateTotals()
     csvFileName = settings_instance.summaryWidget.globalSummaryToCSV()
     csvLayer = QgsVectorLayer(csvFileName, 'summary report', 'ogr')
     QgsMapLayerRegistry.instance().addMapLayer(csvLayer)
     print_context = {
         'type': 'map',
         'job': 'project summary report',
         'title': settings_instance.projectDescription.text(),
         'template': "global_map.qpt",
         'id': csvLayer.id(),
         'name': csvLayer.name(),
         'source': csvLayer.source(),
     }
     print_engine = fdtmPrint(settings_instance)
     result = print_engine.exportToPdf(print_context, targetFile=targetFile)
     QgsMapLayerRegistry.instance().removeMapLayer(csvLayer)
     return result
    def layerFilterExpression(
            self, layer: QgsVectorLayer) -> Optional[str]:  # noqa: ignore=N802
        """
        Returns an additional expression filter.
        """

        LOG.debug("layerFilterExpression %s %s", layer.name(),
                  layer.dataProvider().storageType())

        if self.ogcserver is None:
            parameters = self.serverInterface().requestHandler().parameterMap()
            LOG.warning(
                "Call on uninitialized plugin, map: %s",
                os.environ.get("QGIS_PROJECT_FILE", parameters.get("MAP")),
            )
            return "FALSE"

        try:
            if layer.dataProvider().storageType() in self.SUBSETSTRING_TYPE:
                LOG.debug("layerFilterExpression not in type")
                return None

            session = self.DBSession()
            try:
                access, area = self.get_area(layer, session)
            finally:
                session.close()
            if access is Access.FULL:
                LOG.debug("layerFilterExpression no area")
                return None
            if access is Access.NO:
                LOG.debug("layerFilterExpression not allowed")
                return "0"

            result = (
                f"intersects($geometry, transform(geom_from_wkt('{area.wkt}'), 'EPSG:{self.srid}', "
                f"'{layer.crs().authid()}'))")

            LOG.debug("layerFilterExpression filter: %s", result)
            return result
        except Exception:
            LOG.error("Cannot run layerFilterExpression", exc_info=True)
            raise
Exemple #25
0
    def __restore_geometries(self):

        src_file_name = self.backup_path + QDir.separator() + self.layer_id + '.shp'
        if not QFile.exists(src_file_name):
            self.report_message.emit(self.layer_id, 'no backup file')
            self.completed = True
            return

        self.report_message.emit(self.layer_id, 'preparing ...')

        orig_layer = QgsMapLayerRegistry.instance().mapLayer(self.layer_id)
        # create a copy of the layer just for editing
        layer = QgsVectorLayer(orig_layer.source(), orig_layer.name(), orig_layer.providerType())
        layer.startEditing()
        src_layer = QgsVectorLayer(src_file_name, layer.name(), 'ogr')
        total_features = src_layer.featureCount()

        QgsMessageLog.logMessage(self.plugin.tr('Features to be restored in layer <{0}>: {1}').
                                 format(orig_layer.name(), total_features), self.plugin.tr('Vertex Tools'),
                                 QgsMessageLog.INFO)
        if total_features == 0:
            self.report_message.emit(self.layer_id, 'no features to restore')

        count = 0
        for feature in src_layer.getFeatures():
            with QMutexLocker(self.mutex):
                if self.stopped:
                    layer.rollBack()
                    return

            layer.changeGeometry(feature.id(), feature.geometry())

            count += 1
            self.run_progressed.emit(self.layer_id, count, total_features)

        layer.commitChanges()

        self.completed = True
Exemple #26
0
    def _createPolygonLayer(self, crs=None, fields=None):
        """Creates an empty shape file layer"""

        if crs is None:
            crs = QgsCoordinateReferenceSystem()
            crs.createFromEpsg(4326)

        if fields is None:
            fields = {}

        myTempdir = temp_dir(sub_dir='preprocess')
        myOutFilename = unique_filename(suffix='.shp',
                                        dir=myTempdir)
        mySHPWriter = QgsVectorFileWriter(myOutFilename,
                                          'UTF-8',
                                          fields,
                                          QGis.WKBPolygon,
                                          crs)
        #flush the writer to write to file
        del mySHPWriter
        myName = self.tr('Entire area')
        myLayer = QgsVectorLayer(myOutFilename, myName, 'ogr')
        LOGGER.debug('created' + myLayer.name())
        return myLayer
    def newFrontageLayer(self):

        # always create a memory layer first

        if self.frontagedlg.createNewFileCheckBox.isChecked():
            building_layer = self.getSelectedLayer()
            crs = building_layer.crs()
            vl = QgsVectorLayer("LineString?crs=" + crs.authid(), "memory:frontages", "memory")

        else:
            vl = QgsVectorLayer("LineString?crs=", "memory:frontages", "memory")
        if vl.crs().toWkt() == "":
            vl.setCrs(QgsProject.instance().crs())
        provider = vl.dataProvider()
        provider.addAttributes([QgsField(FrontageTool.id_attribute, QVariant.Int),
                                QgsField(FrontageTool.group_attribute, QVariant.String),
                                QgsField(FrontageTool.type_attribute, QVariant.String),
                                QgsField(FrontageTool.length_attribute, QVariant.Double)])
        vl.updateFields()

        # use building layer - explode
        if self.frontagedlg.createNewFileCheckBox.isChecked():
            print('building layer')
            exploded_features = []
            i = 1
            for f in building_layer.getFeatures():
                points = f.geometry().asPolygon()[0]  # get list of points
                for (p1, p2) in zip(points[:-1], points[1:]):
                    i += 1
                    feat = QgsFeature()
                    line_geom = QgsGeometry.fromPolyline([p1, p2])
                    feat.setAttributes([i, NULL, NULL, line_geom.geometry().length()])
                    feat.setId(i)
                    feat.setGeometry(line_geom)
                    exploded_features.append(feat)
            print('building layer2')
            vl.updateFields()
            vl.startEditing()
            provider.addFeatures(exploded_features)
            vl.commitChanges()
            print('building layer3')

        if self.frontagedlg.f_shp_radioButton.isChecked():  # layer_type == 'shapefile':

            path = self.frontagedlg.lineEditFrontages.text()

            if path and path != '':
                filename = os.path.basename(path)
                location = os.path.abspath(path)

                shph.createShapeFile(vl, path, vl.crs())
                vl = self.iface.addVectorLayer(location, filename[:-4], "ogr")
            else:
                vl = 'invalid data source'

        elif self.frontagedlg.f_postgis_radioButton.isChecked():

            db_path = self.frontagedlg.lineEditFrontages.text()
            if db_path and db_path != '':

                (database, schema, table_name) = (self.frontagedlg.lineEditFrontages.text()).split(':')
                db_con_info = self.frontagedlg.dbsettings_dlg.available_dbs[database]
                uri = QgsDataSourceUri()
                # passwords, usernames need to be empty if not provided or else connection will fail
                if 'service' in list(db_con_info.keys()):
                    uri.setConnection(db_con_info['service'], '', '', '')  # db_con_info['dbname']
                elif 'password' in list(db_con_info.keys()):
                    uri.setConnection(db_con_info['host'], db_con_info['port'], db_con_info['dbname'],
                                      db_con_info['user'], db_con_info['password'])
                else:
                    print(db_con_info)  # db_con_info['host']
                    uri.setConnection('', db_con_info['port'], db_con_info['dbname'], '',
                                      '')  # , db_con_info['user'], '')
                uri.setDataSource(schema, table_name, "geom")
                error = QgsVectorLayerExporter.exportLayer(vl, uri.uri(), "postgres", QgsProject.instance().crs())
                if error[0] != QgsVectorLayerExporter.NoError:
                    print("Error when creating postgis layer: ", error[1])
                    vl = 'duplicate'
                else:
                    vl = QgsVectorLayer(uri.uri(), table_name, "postgres")

            else:
                vl = 'invalid data source'

        if vl == 'invalid data source':
            msgBar = self.iface.messageBar()
            msg = msgBar.createMessage(u'Specify  output path!')
            msgBar.pushWidget(msg, Qgis.Info, 10)
        elif vl == 'duplicate':
            msgBar = self.iface.messageBar()
            msg = msgBar.createMessage(u'Fronatges layer already exists!')
            msgBar.pushWidget(msg, Qgis.Info, 10)
        elif not vl:
            msgBar = self.iface.messageBar()
            msg = msgBar.createMessage(u'Frontages layer failed to load!')
            msgBar.pushWidget(msg, Qgis.Info, 10)
        else:
            QgsProject.instance().addMapLayer(vl)
            msgBar = self.iface.messageBar()
            msg = msgBar.createMessage(u'Frontages layer created!')
            msgBar.pushWidget(msg, Qgis.Info, 10)
            vl.startEditing()
            if self.isRequiredLayer(vl, type):
                self.dockwidget.useExistingcomboBox.addItem(vl.name(), vl)

        # self.updateFrontageLayer() This is creating problems with signals - REMOVE

        # TODO: updateLength function should receive a layer as input. It would be used earlier
        self.frontagedlg.closePopUp()
Exemple #28
0
class TestQgsLayerTreeView(unittest.TestCase):
    def __init__(self, methodName):
        """Run once on class initialization."""

        unittest.TestCase.__init__(self, methodName)

        # setup a dummy project
        self.project = QgsProject()
        self.layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1",
                                    "memory")
        self.layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2",
                                     "memory")
        self.layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3",
                                     "memory")
        self.layer4 = QgsVectorLayer("Point?field=fldtxt:string", "layer4",
                                     "memory")
        self.layer5 = QgsVectorLayer("Point?field=fldtxt:string", "layer5",
                                     "memory")
        self.project.addMapLayers([self.layer, self.layer2, self.layer3])
        self.model = QgsLayerTreeModel(self.project.layerTreeRoot())
        if USE_MODEL_TESTER:
            self.tester = QAbstractItemModelTester(self.model)

    def nodeOrder(self, group):

        nodeorder = []
        for node in group:
            if QgsLayerTree.isGroup(node):
                groupname = node.name()
                nodeorder.append(groupname)
                for child in self.nodeOrder(node.children()):
                    nodeorder.append(groupname + '-' + child)
            elif QgsLayerTree.isLayer(node):
                nodeorder.append(node.layer().name())
        return nodeorder

    def testSetModel(self):

        view = QgsLayerTreeView()

        # should not work
        string_list_model = QStringListModel()
        view.setModel(string_list_model)
        self.assertFalse(view.model())

        # should work
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        self.assertEqual(view.layerTreeModel(), self.model)

    def testSetCurrentLayer(self):

        view = QgsLayerTreeView()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        current_layer_changed_spy = QSignalSpy(view.currentLayerChanged)
        self.assertFalse(view.currentLayer())
        view.setCurrentLayer(self.layer3)
        self.assertEqual(view.currentLayer(), self.layer3)
        self.assertEqual(len(current_layer_changed_spy), 1)
        view.setCurrentLayer(self.layer)
        self.assertEqual(view.currentLayer(), self.layer)
        self.assertEqual(len(current_layer_changed_spy), 2)
        view.setCurrentLayer(None)
        self.assertFalse(view.currentLayer())
        self.assertEqual(len(current_layer_changed_spy), 3)

    def testDefaultActions(self):
        view = QgsLayerTreeView()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        actions = QgsLayerTreeViewDefaultActions(view)

        # show in overview action
        view.setCurrentLayer(self.layer)
        self.assertEqual(view.currentNode().customProperty('overview', 0),
                         False)
        show_in_overview = actions.actionShowInOverview()
        show_in_overview.trigger()
        self.assertEqual(view.currentNode().customProperty('overview', 0),
                         True)
        show_in_overview.trigger()
        self.assertEqual(view.currentNode().customProperty('overview', 0),
                         False)

    def testMoveOutOfGroupActionLayer(self):
        """Test move out of group action on layer"""

        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().addGroup("embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
            ])

        view.setCurrentLayer(self.layer5)
        moveOutOfGroup = actions.actionMoveOutOfGroup()
        moveOutOfGroup.trigger()
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                self.layer5.name(),
                groupname,
                groupname + '-' + self.layer4.name(),
            ])

    def testMoveToTopActionLayer(self):
        """Test move to top action on layer"""

        view = QgsLayerTreeView()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(self.project.layerTreeRoot().layerOrder(),
                         [self.layer, self.layer2, self.layer3])
        view.setCurrentLayer(self.layer3)
        movetotop = actions.actionMoveToTop()
        movetotop.trigger()
        self.assertEqual(self.project.layerTreeRoot().layerOrder(),
                         [self.layer3, self.layer, self.layer2])

    def testMoveToTopActionGroup(self):
        """Test move to top action on group"""

        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().addGroup("embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
            ])

        nodeLayerIndex = view.node2index(group)
        view.setCurrentIndex(nodeLayerIndex)
        movetotop = actions.actionMoveToTop()
        movetotop.trigger()
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
            ])

    def testMoveToTopActionEmbeddedGroup(self):
        """Test move to top action on embeddedgroup layer"""

        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().addGroup("embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
            ])

        view.setCurrentLayer(self.layer5)
        movetotop = actions.actionMoveToTop()
        movetotop.trigger()
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer5.name(),
                groupname + '-' + self.layer4.name(),
            ])

    def testMoveToTopActionLayerAndGroup(self):
        """Test move to top action for a group and it's layer simultaneously"""

        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().addGroup("embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
            ])

        selectionMode = view.selectionMode()
        view.setSelectionMode(QgsLayerTreeView.MultiSelection)
        nodeLayerIndex = view.node2index(group)
        view.setCurrentIndex(nodeLayerIndex)
        view.setCurrentLayer(self.layer5)
        view.setSelectionMode(selectionMode)
        movetotop = actions.actionMoveToTop()
        movetotop.trigger()
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                groupname,
                groupname + '-' + self.layer5.name(),
                groupname + '-' + self.layer4.name(),
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
            ])

    def testMoveToBottomActionLayer(self):
        """Test move to bottom action on layer"""

        view = QgsLayerTreeView()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(self.project.layerTreeRoot().layerOrder(),
                         [self.layer, self.layer2, self.layer3])
        view.setCurrentLayer(self.layer)
        movetobottom = actions.actionMoveToBottom()
        movetobottom.trigger()
        self.assertEqual(self.project.layerTreeRoot().layerOrder(),
                         [self.layer2, self.layer3, self.layer])

    def testMoveToBottomActionGroup(self):
        """Test move to bottom action on group"""

        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().insertGroup(0, "embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
            ])

        nodeLayerIndex = view.node2index(group)
        view.setCurrentIndex(nodeLayerIndex)
        movetobottom = actions.actionMoveToBottom()
        movetobottom.trigger()
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
            ])

    def testMoveToBottomActionEmbeddedGroup(self):
        """Test move to bottom action on embeddedgroup layer"""

        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().addGroup("embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
            ])

        view.setCurrentLayer(self.layer4)
        movetobottom = actions.actionMoveToBottom()
        movetobottom.trigger()
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer5.name(),
                groupname + '-' + self.layer4.name(),
            ])

    def testMoveToBottomActionLayerAndGroup(self):
        """Test move to top action for a group and it's layer simultaneously"""

        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().insertGroup(0, "embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
            ])

        selectionMode = view.selectionMode()
        view.setSelectionMode(QgsLayerTreeView.MultiSelection)
        nodeLayerIndex = view.node2index(group)
        view.setCurrentIndex(nodeLayerIndex)
        view.setCurrentLayer(self.layer4)
        view.setSelectionMode(selectionMode)
        movetobottom = actions.actionMoveToBottom()
        movetobottom.trigger()
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer5.name(),
                groupname + '-' + self.layer4.name(),
            ])

    def testSetLayerVisible(self):

        view = QgsLayerTreeView()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        self.project.layerTreeRoot().findLayer(
            self.layer).setItemVisibilityChecked(True)
        self.project.layerTreeRoot().findLayer(
            self.layer2).setItemVisibilityChecked(True)
        self.assertTrue(self.project.layerTreeRoot().findLayer(
            self.layer).itemVisibilityChecked())
        self.assertTrue(self.project.layerTreeRoot().findLayer(
            self.layer2).itemVisibilityChecked())

        view.setLayerVisible(None, True)
        view.setLayerVisible(self.layer, True)
        self.assertTrue(self.project.layerTreeRoot().findLayer(
            self.layer).itemVisibilityChecked())
        view.setLayerVisible(self.layer2, False)
        self.assertFalse(self.project.layerTreeRoot().findLayer(
            self.layer2).itemVisibilityChecked())
        view.setLayerVisible(self.layer2, True)
        self.assertTrue(self.project.layerTreeRoot().findLayer(
            self.layer2).itemVisibilityChecked())

    def testProxyModel(self):
        """Test proxy model filtering and private layers"""

        view = QgsLayerTreeView()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        tree_model = view.layerTreeModel()
        proxy_model = view.proxyModel()

        self.assertEqual(tree_model.rowCount(), 3)
        self.assertEqual(proxy_model.rowCount(), 3)

        items = []
        for r in range(tree_model.rowCount()):
            items.append(tree_model.data(tree_model.index(r, 0)))

        self.assertEqual(items, ['layer1', 'layer2', 'layer3'])

        proxy_items = []
        for r in range(proxy_model.rowCount()):
            proxy_items.append(proxy_model.data(proxy_model.index(r, 0)))

        self.assertEqual(proxy_items, ['layer1', 'layer2', 'layer3'])

        self.layer3.setFlags(self.layer.Private)
        self.assertEqual(tree_model.rowCount(), 3)
        self.assertEqual(proxy_model.rowCount(), 2)

        proxy_items = []
        for r in range(proxy_model.rowCount()):
            proxy_items.append(proxy_model.data(proxy_model.index(r, 0)))

        self.assertEqual(proxy_items, ['layer1', 'layer2'])

        view.setShowPrivateLayers(True)

        self.assertEqual(proxy_model.rowCount(), 3)

        proxy_items = []
        for r in range(proxy_model.rowCount()):
            proxy_items.append(proxy_model.data(proxy_model.index(r, 0)))

        self.assertEqual(proxy_items, ['layer1', 'layer2', 'layer3'])

        view.setShowPrivateLayers(False)

        self.assertEqual(proxy_model.rowCount(), 2)

        proxy_items = []
        for r in range(proxy_model.rowCount()):
            proxy_items.append(proxy_model.data(proxy_model.index(r, 0)))

        self.assertEqual(proxy_items, ['layer1', 'layer2'])

        # Test filters
        proxy_model.setFilterText('layer2')

        self.assertEqual(proxy_model.rowCount(), 1)

        proxy_items = []
        for r in range(proxy_model.rowCount()):
            proxy_items.append(proxy_model.data(proxy_model.index(r, 0)))

        self.assertEqual(proxy_items, ['layer2'])

    def testProxyModelCurrentIndex(self):
        """Test a crash spotted out while developing the proxy model"""

        view = QgsLayerTreeView()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
            tree_tester = QAbstractItemModelTester(view.layerTreeModel())

        view.setCurrentLayer(self.layer3)
        self.layer3.setFlags(self.layer.Private)

    def testNode2IndexMethods(self):
        """Test node2index and node2sourceIndex"""

        view = QgsLayerTreeView()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
            tree_tester = QAbstractItemModelTester(view.layerTreeModel())

        tree_model = view.layerTreeModel()
        proxy_model = view.proxyModel()

        proxy_index = proxy_model.index(1, 0)
        node2 = view.index2node(proxy_index)
        self.assertEqual(node2.name(), 'layer2')

        proxy_layer2_index = view.node2index(node2)
        self.assertEqual(proxy_layer2_index, view.node2index(node2))

        source_index = tree_model.index(1, 0)
        tree_layer2_index = view.node2sourceIndex(node2)
        self.assertEqual(tree_layer2_index, view.node2sourceIndex(node2))
class TestQgsLayerTreeView(unittest.TestCase):

    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)

        # setup a dummy project
        self.project = QgsProject()
        self.layer = QgsVectorLayer("Point?field=fldtxt:string",
                                    "layer1", "memory")
        self.layer2 = QgsVectorLayer("Point?field=fldtxt:string",
                                     "layer2", "memory")
        self.layer3 = QgsVectorLayer("Point?field=fldtxt:string",
                                     "layer3", "memory")
        self.layer4 = QgsVectorLayer("Point?field=fldtxt:string",
                                     "layer4", "memory")
        self.layer5 = QgsVectorLayer("Point?field=fldtxt:string",
                                     "layer5", "memory")
        self.project.addMapLayers([self.layer, self.layer2, self.layer3])
        self.model = QgsLayerTreeModel(self.project.layerTreeRoot())

    def nodeOrder(self, group):
        nodeorder = []
        layerTree = QgsLayerTree()
        for node in group:
            if QgsLayerTree.isGroup(node):
                groupname = node.name()
                nodeorder.append(groupname)
                for child in self.nodeOrder(node.children()):
                    nodeorder.append(groupname + '-' + child)
            elif QgsLayerTree.isLayer(node):
                nodeorder.append(node.layer().name())
        return nodeorder

    def testSetModel(self):
        view = QgsLayerTreeView()

        # should not work
        string_list_model = QStringListModel()
        view.setModel(string_list_model)
        self.assertFalse(view.model())

        # should work
        view.setModel(self.model)
        self.assertEqual(view.model(), self.model)

    def testSetCurrentLayer(self):
        view = QgsLayerTreeView()
        view.setModel(self.model)
        current_layer_changed_spy = QSignalSpy(view.currentLayerChanged)
        self.assertFalse(view.currentLayer())
        view.setCurrentLayer(self.layer3)
        self.assertEqual(view.currentLayer(), self.layer3)
        self.assertEqual(len(current_layer_changed_spy), 1)
        view.setCurrentLayer(self.layer)
        self.assertEqual(view.currentLayer(), self.layer)
        self.assertEqual(len(current_layer_changed_spy), 2)
        view.setCurrentLayer(None)
        self.assertFalse(view.currentLayer())
        self.assertEqual(len(current_layer_changed_spy), 3)

    def testDefaultActions(self):
        view = QgsLayerTreeView()
        view.setModel(self.model)
        actions = QgsLayerTreeViewDefaultActions(view)

        # show in overview action
        view.setCurrentLayer(self.layer)
        self.assertEqual(view.currentNode().customProperty('overview', 0), False)
        show_in_overview = actions.actionShowInOverview()
        show_in_overview.trigger()
        self.assertEqual(view.currentNode().customProperty('overview', 0), True)
        show_in_overview.trigger()
        self.assertEqual(view.currentNode().customProperty('overview', 0), False)

    def testMoveOutOfGroupActionLayer(self):
        """Test move out of group action on layer"""
        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().addGroup("embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(self.nodeOrder(self.project.layerTreeRoot().children()), [
            self.layer.name(),
            self.layer2.name(),
            self.layer3.name(),
            groupname,
            groupname + '-' + self.layer4.name(),
            groupname + '-' + self.layer5.name(),
        ])

        view.setCurrentLayer(self.layer5)
        moveOutOfGroup = actions.actionMoveOutOfGroup()
        moveOutOfGroup.trigger()
        self.assertEqual(self.nodeOrder(self.project.layerTreeRoot().children()), [
            self.layer.name(),
            self.layer2.name(),
            self.layer3.name(),
            self.layer5.name(),
            groupname,
            groupname + '-' + self.layer4.name(),
        ])

    def testMoveToTopActionLayer(self):
        """Test move to top action on layer"""
        view = QgsLayerTreeView()
        view.setModel(self.model)
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(self.project.layerTreeRoot().layerOrder(), [self.layer, self.layer2, self.layer3])
        view.setCurrentLayer(self.layer3)
        movetotop = actions.actionMoveToTop()
        movetotop.trigger()
        self.assertEqual(self.project.layerTreeRoot().layerOrder(), [self.layer3, self.layer, self.layer2])

    def testMoveToTopActionGroup(self):
        """Test move to top action on group"""
        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().addGroup("embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(self.nodeOrder(self.project.layerTreeRoot().children()), [
            self.layer.name(),
            self.layer2.name(),
            self.layer3.name(),
            groupname,
            groupname + '-' + self.layer4.name(),
            groupname + '-' + self.layer5.name(),
        ])

        nodeLayerIndex = self.model.node2index(group)
        view.setCurrentIndex(nodeLayerIndex)
        movetotop = actions.actionMoveToTop()
        movetotop.trigger()
        self.assertEqual(self.nodeOrder(self.project.layerTreeRoot().children()), [
            groupname,
            groupname + '-' + self.layer4.name(),
            groupname + '-' + self.layer5.name(),
            self.layer.name(),
            self.layer2.name(),
            self.layer3.name(),
        ])

    def testMoveToTopActionEmbeddedGroup(self):
        """Test move to top action on embeddedgroup layer"""
        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().addGroup("embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(self.nodeOrder(self.project.layerTreeRoot().children()), [
            self.layer.name(),
            self.layer2.name(),
            self.layer3.name(),
            groupname,
            groupname + '-' + self.layer4.name(),
            groupname + '-' + self.layer5.name(),
        ])

        view.setCurrentLayer(self.layer5)
        movetotop = actions.actionMoveToTop()
        movetotop.trigger()
        self.assertEqual(self.nodeOrder(self.project.layerTreeRoot().children()), [
            self.layer.name(),
            self.layer2.name(),
            self.layer3.name(),
            groupname,
            groupname + '-' + self.layer5.name(),
            groupname + '-' + self.layer4.name(),
        ])
Exemple #30
0
def SplitMeshLayer(mlayer, keycolum):
    #  InputLayer  メッシュテーブル
    #  output_table  出力メッシュテーブル
    #  SplitFlag     フラグが1のメッシュは分割しない
    #
    #  return new mesh layer
    #
    #outputlayer = QgsVectorLayer("Point?crs=EPSG:4326", "layer name you like", "memory")

    if type(mlayer) is str:

        mlayer = QgsVectorLayer(mlayer, "mesh", "ogr")

    if mlayer.isValid():
        print("dmesh Layer load OK")
    else:
        print("dmesh Layer load Fail")
        print("dmesh=" + mlayer.name())
        sys.exit()

    crsstr = mlayer.crs().authid()

    #   作業結果出力レイヤ

    vectL = 'Polygon?crs=' + crsstr

    vl1 = QgsVectorLayer(vectL, "temporary_mesh", "memory")

    if not vl1:
        print("Virtual Layer failed to load!")
        sys.exit()
    #else:
    #         print( out_tb )

    #vl1.setCrs( mlayer.crs()  )

    pr1 = vl1.dataProvider()

    #  フィールド定義
    pr1.addAttributes([QgsField(keycolum, QVariant.String)])
    #               QgsField(divcolumn,  QVariant.Int)])

    vl1.updateFields()  #

    vl1.beginEditCommand("Add Polygons")

    features = mlayer.getFeatures()

    for feature in features:

        code = feature[keycolum]
        #divide_f = feature[ divcolumn ]

        divide_f = 0

        #print( 'code =' + code+ ' divide=' + str(divide_f) )
        geom = feature.geometry()
        geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())

        if divide_f == 0:

            if geom.type() == QgsWkbTypes.PolygonGeometry:

                if geomSingleType:
                    x = geom.asPolygon()

                    #print("Polygon: ", x, "Area: ", geom.area())

                    for xp in x:
                        #print("xp:",xp )

                        #for xxp in xp:
                        #     print("xxp:",xxp)

                        #    座標の場所を判定して位置関係を正規化したほうがいいかも
                        #

                        p0_1 = GetCyuuten(xp[0], xp[1])
                        p1_2 = GetCyuuten(xp[1], xp[2])
                        p2_3 = GetCyuuten(xp[2], xp[3])
                        p3_4 = GetCyuuten(xp[3], xp[4])
                        pC_C = GetCyuuten(p0_1, p2_3)

                        #    新しいキーコード
                        ncode1 = code + '-01'

                        Polygon1 = QgsGeometry.fromPolygonXY([[
                            QgsPointXY(xp[0].x(), xp[0].y()),
                            QgsPointXY(p0_1.x(), p0_1.y()),
                            QgsPointXY(pC_C.x(), pC_C.y()),
                            QgsPointXY(p3_4.x(), p3_4.y())
                        ]])

                        # add a feature
                        fet = QgsFeature(pr1.fields())

                        fet.setGeometry(Polygon1)

                        fet[keycolum] = ncode1
                        #    fet[divcolumn] = divide_f
                        #  新しい feature を作って別レイヤに格納する
                        retc = pr1.addFeatures([fet])

                        #print("add new")
                        #print( retc )

                        #    新しいキーコード
                        ncode2 = code + '-02'
                        Polygon2 = QgsGeometry.fromPolygonXY([[
                            QgsPointXY(p0_1.x(), p0_1.y()),
                            QgsPointXY(xp[1].x(), xp[1].y()),
                            QgsPointXY(p1_2.x(), p1_2.y()),
                            QgsPointXY(pC_C.x(), pC_C.y())
                        ]])

                        fet2 = QgsFeature(pr1.fields())

                        fet2.setGeometry(Polygon2)

                        fet2[keycolum] = ncode2
                        #   fet2[divcolumn] = divide_f
                        #  新しい feature を作って別レイヤに格納する
                        retc = pr1.addFeatures([fet2])

                        #    新しいキーコード
                        ncode3 = code + '-03'
                        Polygon3 = QgsGeometry.fromPolygonXY([[
                            QgsPointXY(pC_C.x(), pC_C.y()),
                            QgsPointXY(p1_2.x(), p1_2.y()),
                            QgsPointXY(xp[2].x(), xp[2].y()),
                            QgsPointXY(p2_3.x(), p2_3.y())
                        ]])

                        fet3 = QgsFeature(pr1.fields())

                        fet3.setGeometry(Polygon3)

                        fet3[keycolum] = ncode3
                        #   fet3[divcolumn] = divide_f
                        #  新しい feature を作って別レイヤに格納する
                        retc = pr1.addFeatures([fet3])

                        #    新しいキーコード
                        ncode4 = code + '-04'
                        Polygon4 = QgsGeometry.fromPolygonXY([[
                            QgsPointXY(p3_4.x(), p3_4.y()),
                            QgsPointXY(pC_C.x(), pC_C.y()),
                            QgsPointXY(p2_3.x(), p2_3.y()),
                            QgsPointXY(xp[3].x(), xp[3].y())
                        ]])

                        fet4 = QgsFeature(pr1.fields())

                        fet4.setGeometry(Polygon4)

                        fet4[keycolum] = ncode4
                        #   fet4[divcolumn] = divide_f
                        #  新しい feature を作って別レイヤに格納する
                        retc = pr1.addFeatures([fet4])

                    #print(Polygon1)
                    # print(Polygon2)

                    #Poly

                    #feat.setGeometry( QgsGeometry.fromPolygonXY([QgsPointXY(546016, 4760165), p2, p3]))
                    #qPolygon1 = QgsGeometry.fromPolygonXY([ xp[0],p0_1, pC_C,xp[0]])

                    #print( qPolygon1 )

                #   一点目 2点目の中点を求める   2

                else:
                    x = geom.asMultiPolygon()
                #print("MultiPolygon: ", x, "Area: ", geom.area())
            else:
                print("geometry is not polygon!")

        #else:    #  分割不要ポリゴンはそのまま書き込む
        #    retc = pr1.addFeatures([feature])

    vl1.updateExtents()
    vl1.endEditCommand()
    vl1.commitChanges()

    return vl1
 def ogc_layer_name(self, layer: QgsVectorLayer) -> str:
     use_layer_id, _ = self.project().readBoolEntry("WMSUseLayerIDs", "/",
                                                    False)
     if use_layer_id:
         return layer.id()
     return layer.shortName() or layer.name()
Exemple #32
0
def nodeDuplicate(node,newname=None,position='bottom',target_node=None):
    import time
    if oeq_global.isStringOrUnicode(node):
        node = nodeByName(node)
        if len(node) == 0:
             return None
        node = node[0]

    if target_node == None:
         target_node = node.parent()
    else:
         if oeq_global.isStringOrUnicode(target_node):
             target_node = nodeByName(target_node)
             if len(target_node) == 0:
                return None
             target_node = target_node[0]
    #
    #print node.layer().name()
    #print newname
    layer = node.layer()
    # source of the layer
    provider = layer.dataProvider()
    #print "---------------------"
    #print provider.crs().authid()
    #print layer.crs().authid()
    #print "---------------------"
    # creation of the shapefiles:
    pathfile = os.path.join(oeq_global.OeQ_project_path(),newname+'.shp')
    ct_pathfile = os.path.join(oeq_global.OeQ_project_path(),newname+'.qml')
    writer = QgsVectorFileWriter(pathfile, "CP1250", provider.fields(), provider.geometryType(), layer.crs(), "ESRI Shapefile")
    #print writer
    outelem = QgsFeature()
    # iterating over the input layer
    for elem in layer.getFeatures():
             outelem.setGeometry(elem.geometry() )
             outelem.setAttributes(elem.attributes())
             writer.addFeature(outelem)
    del writer
    oeq_global.OeQ_wait_for_file(pathfile)
    #time.sleep(1)
    newlayer = QgsVectorLayer(pathfile, newname, "ogr")

    #print layer.isValid()
    QgsMapLayerRegistry.instance().addMapLayer(newlayer, True)
    newlayer.setCrs(layer.crs())
    #oeq_global.OeQ_wait_for_renderer(60000)
    #print newlayer.name()


    newnode = nodeByName(newlayer.name())
    if len(newnode) == 0:
        return None
    newnode = newnode[0]
   # oeq_global.OeQ_unlockQgis()
    #time.sleep(1)
    newlayer.loadNamedStyle(ct_pathfile)
    nodeCollapse(newnode)
    #time.sleep(1)
    #position = nodePosition(node,target_node)
    newnode=nodeMove(newnode,position,target_node)
    #time.sleep(1)
    #oeq_global.OeQ_unlockQgis()
    #oeq_global.OeQ_wait(0.5)
    #print "+++++++++++++++"
    return newnode
    def processAlgorithm(self, parameters, context, model_feedback):
        """
        Here is where the processing itself takes place.
        """
        results = {}

        csvfile = self.parameterAsFile(parameters, self.INPUT, context)
        if csvfile is None:
            raise QgsProcessingException(self.tr('csv file error'))

        #df = QgsVirtualLayerDefinition()

        enc = self.parameterAsInt(parameters, 'ENCODING', context)

        meshLayer = self.parameterAsVectorLayer(parameters, "meshlayer",
                                                context)
        if meshLayer is None:
            raise QgsProcessingException(self.tr('mesh layer missed'))

        meshidfields = self.parameterAsFields(parameters, 'meshid', context)

        limit_sample = self.parameterAsInt(parameters, 'limit_sample', context)

        maxdivide = self.parameterAsInt(parameters, 'maxdivide', context)

        uneven_div = self.parameterAsInt(parameters, 'uneven_div', context)

        popmeshLayer = self.parameterAsVectorLayer(parameters, "popmeshlayer",
                                                   context)
        if popmeshLayer is None:
            raise QgsProcessingException(self.tr('popmes  layer missed'))

        popmeshidfields = self.parameterAsFields(parameters, 'popmeshid',
                                                 context)

        popmeshpopfields = self.parameterAsFields(parameters, 'popmeshpop',
                                                  context)

        feedback = QgsProcessingMultiStepFeedback(9 + maxdivide,
                                                  model_feedback)

        feedback.setCurrentStep(1)
        if feedback.isCanceled():
            return {}

        # 住所別集計
        alg_params = {
            'addresslayer': parameters['addresslayer'],
            'addressfield': parameters['addressfield'],
            'INPUT': csvfile,
            'ENCODING': enc,
            'CRS': None,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }

        #Stat_CSVAddressPolygon

        outputs_statv = processing.run('QGIS_stat:Stat_CSVAddressPolygon',
                                       alg_params,
                                       context=context,
                                       feedback=feedback,
                                       is_child_algorithm=True)

        if feedback.isCanceled():
            return {}

        statv = outputs_statv["OUTPUT"]
        meshid = meshidfields[0]

        #   人口メッシュと行政界メッシュのUnion作成する

        new_popfield = 'pv'

        param_uni = {
            'addresslayer': statv,
            'addressfield': parameters['addressfield'][0],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT,
            'popmeshlayer': popmeshLayer,
            'popmeshid': popmeshidfields[0],
            'popmeshpop': popmeshpopfields[0],
            'POPCOLUMN': new_popfield
        }

        feedback.setCurrentStep(2)

        res_uni = processing.run('QGIS_stat:UnionAdmAndPopMeshAlgorithm',
                                 param_uni,
                                 context=context,
                                 feedback=feedback,
                                 is_child_algorithm=True)

        if feedback.isCanceled():
            return {}

        feedback.pushConsoleInfo("csvs 1 union ok  ")

        #     union pop polygon   res_unit["OUTPUT"]
        #   population     pv
        #      address   parameters['addressfield'][0]

        #    行政界別人口の算出

        feedback.setCurrentStep(3)

        param_pop = {
            'inputlayer': res_uni['OUTPUT'],
            'agfield': parameters['addressfield'],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT,
            # 'OUTPUT':parameters['OUTPUT'],
            'cfield': new_popfield
        }

        res_adpop = processing.run('QGIS_stat:AggreagteValueAlgorithm',
                                   param_pop,
                                   context=context,
                                   feedback=feedback,
                                   is_child_algorithm=True)

        if feedback.isCanceled():
            return {}

        feedback.pushConsoleInfo("csvs 1  caliculate pop adm ok  ")

        #   UNION mesh と 行政界別 人口の結合

        feedback.setCurrentStep(4)

        param_join = {
            'DISCARD_NONMATCHING': False,
            'FIELD': parameters['addressfield'],
            'FIELDS_TO_COPY': [],
            'FIELD_2': parameters['addressfield'],
            'INPUT': res_uni['OUTPUT'],
            'INPUT_2': res_adpop['OUTPUT'],
            'METHOD': 1,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT,
            #'OUTPUT':parameters['OUTPUT'],
            'PREFIX': 'op'
        }

        res_join = processing.run('qgis:joinattributestable',
                                  param_join,
                                  context=context,
                                  feedback=feedback,
                                  is_child_algorithm=True)

        if feedback.isCanceled():
            return {}

        feedback.pushConsoleInfo("csvs 1  join union mesh and popof adm  ok  ")

        #   UNION MESH  人口 と行政界人口の比率算出

        feedback.setCurrentStep(5)

        param_ratio = {
            'FIELD_LENGTH': 12,
            'FIELD_NAME': 'pvratio',
            'FIELD_PRECISION': 6,
            'FIELD_TYPE': 0,
            'FORMULA': ' \"pv\" / \"oppv\" ',
            'INPUT': res_join["OUTPUT"],
            #'OUTPUT':parameters['OUTPUT']
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT,
        }

        res_ratio = processing.run('qgis:fieldcalculator',
                                   param_ratio,
                                   context=context,
                                   feedback=feedback,
                                   is_child_algorithm=True)

        if feedback.isCanceled():
            return {}

        feedback.pushConsoleInfo(
            "csvs 1 calc ratio of adm pop and union polygon population  ok  ")

        #    Union mesh の想定集計値を算出する   住所別集計値 × ( UNION MESH  人口 と行政界人口の比率算出)

        feedback.setCurrentStep(6)

        param_ratio2 = {
            'FIELD_LENGTH': 12,
            'FIELD_NAME': 'pvsum',
            'FIELD_PRECISION': 6,
            'FIELD_TYPE': 0,
            'FORMULA': ' \"snum\" * \"pvratio\" ',
            'INPUT': res_ratio["OUTPUT"],
            #'OUTPUT':parameters['OUTPUT']
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }

        res_ratio2 = processing.run('qgis:fieldcalculator',
                                    param_ratio2,
                                    context=context,
                                    feedback=feedback,
                                    is_child_algorithm=True)

        if feedback.isCanceled():
            return {}

        feedback.pushConsoleInfo("csvs 1 calc ratio of research sample  ok  ")

        #results["OUTPUT"] = res_ratio2["OUTPUT"]
        #return results

        #    入力メッシュとUnionメッシュのUnion
        feedback.setCurrentStep(7)

        #results["OUTPUT"] = res_ratio['OUTPUT']
        #return results

        #    入力UNIONメッシュの保存

        # レイヤをGeoPackage化
        cnv_paramsg = {
            'LAYERS': res_ratio2["OUTPUT"],
            'OVERWRITE': True,
            'SAVE_STYLES': False,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
            #'OUTPUT':parameters['OUTPUT']
        }
        input_c = processing.run('native:package',
                                 cnv_paramsg,
                                 context=context,
                                 feedback=feedback,
                                 is_child_algorithm=True)

        feedback.pushConsoleInfo("csvs 1 cahnge to geopackage  ok  ")

        #results["OUTPUT"] = input_c["OUTPUT"]
        #return results

        #   集計用 人口+行政界  UNION
        input_union = input_c["OUTPUT"]

        feedback.setCurrentStep(8)
        #    create union  poplation mesh and input mesh

        param1 = {
            'INPUT': input_union,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT,
            'pareafield': 'div_area',
            'polsmpl': 'pvsum',
            'meshid': meshid,
            'meshlayer': meshLayer
        }

        #parameters['OUTPUT']
        #
        res1 = processing.run('QGIS_stat:AggregatePopMeshbyMeshAlgorithm',
                              param1,
                              context=context,
                              feedback=feedback,
                              is_child_algorithm=True)

        if feedback.isCanceled():
            return {}

        feedback.pushConsoleInfo(
            "csvs 1 AggregatePopMeshbyMeshAlgorithm  ok  ")
        numberof_under_limit = 0

        #numberof_under_limit = res1["LIMITPOL"]

        # レイヤをGeoPackage化
        alg_paramsg = {
            'LAYERS': res1["OUTPUT"],
            'OVERWRITE': True,
            'SAVE_STYLES': False,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        retg1 = processing.run('native:package',
                               alg_paramsg,
                               context=context,
                               feedback=feedback,
                               is_child_algorithm=True)
        last_output = retg1["OUTPUT"]

        new_mesh = retg1["OUTPUT"]

        mesh_layb = retg1["OUTPUT"]

        if type(mesh_layb) is str:
            mesh_layb = QgsVectorLayer(mesh_layb, "mesh", "ogr")

        numberof_under_limit = 0

        #    作業用レイヤの作成
        crs_str = mesh_layb.crs()

        layerURI = "Polygon?crs=" + crs_str.authid()
        #feedback.pushConsoleInfo( "work layer  " + layerURI  )
        resLayer = QgsVectorLayer(layerURI, "mesh_result", "memory")

        appended = {}

        adfields = []
        for field in mesh_layb.fields():
            #print(field.name(), field.typeName())
            adfields.append(field)
            #resLayer.addField(field)

        resLayer.dataProvider().addAttributes(adfields)
        resLayer.updateFields()

        lower_ids = []

        value_column = "snum"

        #    limit 値より小さい値のポリゴン数算出
        for f in mesh_layb.getFeatures():
            # feedback.pushConsoleInfo( "value  " +str( f["value"])  )
            if not f[value_column] is None:
                if f[value_column] > 0 and f[value_column] < limit_sample:
                    numberof_under_limit += 1
                    lower_ids.append(f[meshid])

        next_output = None

        stepi = 9

        #   集計結果が最小サンプルより小さいものがある場合
        if numberof_under_limit > 0:
            #  初回の場合は終了

            feedback.pushConsoleInfo("最初の集計で指定値以下の集計値がありましたので集計を中止しました")
            results["OUTPUT"] = None
            return results

            if uneven_div:

                rmid = []
                for tgid in (lower_ids):
                    feedback.pushConsoleInfo("lower id  " + str(tgid))

                    #  next_output   code   の下3桁 削除   C27210-02    -> C27210   が last_output の code 番号
                    #  next_output  では last_output  が同じ番号の最大4メッシュを削除する

                    # リミットより小さいレコードは旧レコードを退避
                    #  リミットにひっかかるレコードを再処理用リストから削除(同一親メッシュのものも削除)
                    #   不均等分割でリミット以下のデータがある場合は last_output -> 分割不能抽出   next_output  分割不能削除  next_output -> last_output 代入
                    parent_code = tgid[0:-3]

                    rmid.append(parent_code)

                addfeatures = []

                alg_paramsg_n = {
                    'LAYERS': last_output,
                    'OVERWRITE': False,
                    'SAVE_STYLES': False,
                    'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
                }
                lmesh = processing.run('native:package',
                                       alg_paramsg_n,
                                       context=context,
                                       feedback=feedback,
                                       is_child_algorithm=True)

                last_output = lmesh["OUTPUT"]

                if type(last_output) is str:
                    last_output = QgsVectorLayer(last_output, "mesh", "ogr")

                last_output.selectAll()

                for lf in last_output.getFeatures():

                    for pcode in (rmid):
                        #    feedback.pushConsoleInfo( "pcode  " + pcode+ " meshid =" + lf[meshid]  )
                        if lf[meshid] == pcode:
                            lf["fid"] = None
                            if not lf[value_column]:
                                lf[value_column] = 0.0

                            if lf[meshid] not in appended:

                                addfeatures.append(lf)
                                appended[lf[meshid]] = lf

                    #       feedback.pushConsoleInfo( "add feature   " + pcode  )

                resLayer.dataProvider().addFeatures(addfeatures)

                deleteFeatures = []

                if type(next_output) is str:
                    next_output = QgsVectorLayer(next_output, "mesh", "ogr")

                #   add check   20210310
                if next_output is None:
                    feedback.pushConsoleInfo("no next  array")
                else:
                    for nf in next_output.getFeatures():

                        for pcode in (rmid):
                            if nf[meshid][0:-3] == pcode:
                                deleteFeatures.append(nf.id())
                                feedback.pushConsoleInfo("delete id  " +
                                                         str(pcode))

                    next_output.dataProvider().deleteFeatures(deleteFeatures)

                last_output = next_output

        #  分割回数ループ
        for divide_c in range(1, maxdivide):
            feedback.setCurrentStep(stepi)

            stepi = stepi + 1

            if numberof_under_limit > 0:
                #  均等分割の場合は終了
                if not uneven_div:
                    break

            if last_output is None:
                feedback.pushConsoleInfo("last output  is none")
            else:
                if type(last_output) is str:
                    feedback.pushConsoleInfo("last output " + last_output)
                else:
                    feedback.pushConsoleInfo("last output " +
                                             last_output.name())

            alg_paramsg_m = {
                'LAYERS': last_output,
                'OVERWRITE': True,
                'SAVE_STYLES': False,
                'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
            }
            spmesh = processing.run('native:package',
                                    alg_paramsg_m,
                                    context=context,
                                    feedback=feedback,
                                    is_child_algorithm=True)

            new_mesh = agtools.SplitMeshLayer(spmesh["OUTPUT"], meshid)

            # statv  行政界別集計データ

            #  再度メッシュ集計
            param2 = {
                'INPUT': input_union,
                'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT,
                'pareafield': 'div_area',
                'polsmpl': 'pvsum',
                'meshid': meshid,
                'meshlayer': new_mesh
            }

            res2 = processing.run('QGIS_stat:AggregatePopMeshbyMeshAlgorithm',
                                  param2,
                                  context=context,
                                  feedback=feedback,
                                  is_child_algorithm=True)

            #numberof_under_limit = res2["LIMITPOL"]
            numberof_under_limit = 0
            # レイヤをGeoPackage化
            alg_paramsg2 = {
                'LAYERS': res2["OUTPUT"],
                'OVERWRITE': True,
                'SAVE_STYLES': False,
                'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
            }
            retg2 = processing.run('native:package',
                                   alg_paramsg2,
                                   context=context,
                                   feedback=feedback,
                                   is_child_algorithm=True)

            mesh_layb = retg2["OUTPUT"]

            if type(mesh_layb) is str:
                mesh_layb = QgsVectorLayer(mesh_layb, "mesh", "ogr")

                #features = mesh_layb.selectedFeatures()
                #feedback.pushConsoleInfo( "feature count  " +str( len(features))  )
            lower_ids = []
            for f in mesh_layb.getFeatures():
                #   feedback.pushConsoleInfo( "value  " +str( f["value"])  )
                if not f[value_column] is None:
                    if f[value_column] > 0 and f[value_column] < limit_sample:
                        numberof_under_limit += 1
                        lower_ids.append(f[meshid])

            if numberof_under_limit == 0:
                last_output = res2["OUTPUT"]
                next_output = retg2["OUTPUT"]
            else:
                #   不均等分割でリミット以下のデータがある場合は last_output -> 分割不能抽出   next_output  分割不能削除  next_output -> last_output 代入
                # last_output = res2["OUTPUT"]
                next_output = retg2["OUTPUT"]

            #   集計結果が最小サンプルより小さいものがある場合
            if numberof_under_limit > 0:
                #  均等分割の場合は終了
                if not uneven_div:

                    break

                #  不均等分割の場合は終了データを保全  それ以外のメッシュの分割
                else:
                    rmid = []
                    for tgid in (lower_ids):
                        feedback.pushConsoleInfo("lower id  " + str(tgid))

                        #  next_output   code   の下3桁 削除   C27210-02    -> C27210   が last_output の code 番号
                        #  next_output  では last_output  が同じ番号の最大4メッシュを削除する

                        # リミットより小さいレコードは旧レコードを退避
                        #  リミットにひっかかるレコードを再処理用リストから削除(同一親メッシュのものも削除)
                        #   不均等分割でリミット以下のデータがある場合は last_output -> 分割不能抽出   next_output  分割不能削除  next_output -> last_output 代入
                        parent_code = tgid[0:-3]

                        rmid.append(parent_code)

                    addfeatures = []

                    #if type(last_output) is str:
                    #    last_output =  QgsVectorLayer(last_output, "mesh", "ogr")

                    alg_paramsg_n = {
                        'LAYERS': last_output,
                        'OVERWRITE': False,
                        'SAVE_STYLES': False,
                        'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
                    }
                    lmesh = processing.run('native:package',
                                           alg_paramsg_n,
                                           context=context,
                                           feedback=feedback,
                                           is_child_algorithm=True)

                    #last_output.removeSelection()
                    last_output = lmesh["OUTPUT"]

                    if type(last_output) is str:
                        last_output = QgsVectorLayer(last_output, "mesh",
                                                     "ogr")

                    last_output.selectAll()

                    for lf in last_output.getFeatures():

                        for pcode in (rmid):
                            #    feedback.pushConsoleInfo( "pcode  " + pcode+ " meshid =" + lf[meshid]  )
                            if lf[meshid] == pcode:
                                lf["fid"] = None

                                if not lf[value_column]:
                                    lf[value_column] = 0.0

                                if lf[meshid] not in appended:

                                    addfeatures.append(lf)
                                    appended[lf[meshid]] = lf

                                    #addfeatures.append(lf)
                                    feedback.pushConsoleInfo("add feature   " +
                                                             pcode)

                    resLayer.dataProvider().addFeatures(addfeatures)

                    deleteFeatures = []

                    if type(next_output) is str:
                        next_output = QgsVectorLayer(next_output, "mesh",
                                                     "ogr")

                    for nf in next_output.getFeatures():

                        for pcode in (rmid):
                            if nf[meshid][0:-3] == pcode:
                                deleteFeatures.append(nf.id())
                                feedback.pushConsoleInfo("delete id  " +
                                                         str(pcode))

                    next_output.dataProvider().deleteFeatures(deleteFeatures)

                    last_output = next_output

        # Return the results of the algorithm. In this case our only result is
        # the feature sink which contains the processed features, but some
        # algorithms may return multiple feature sinks, calculated numeric
        # statistics, etc. These should all be included in the returned
        # dictionary, with keys matching the feature corresponding parameter
        # or output names.

        #  不均等分割の場合   最終作業レイヤの地物がはいってないかも
        if uneven_div:

            alg_paramsg_n = {
                'LAYERS': next_output,
                'OVERWRITE': False,
                'SAVE_STYLES': False,
                'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
            }
            lmesh = processing.run('native:package',
                                   alg_paramsg_n,
                                   context=context,
                                   feedback=feedback,
                                   is_child_algorithm=True)

            #last_output.removeSelection()
            last_output = lmesh["OUTPUT"]

            if type(last_output) is str:
                last_output = QgsVectorLayer(last_output, "mesh", "ogr")

                last_output.selectAll()

            addfeatures = []

            for lf in last_output.getFeatures():

                feedback.pushConsoleInfo("add features  meshid =" + lf[meshid])
                lf["fid"] = None
                if not lf[value_column]:
                    lf[value_column] = 0.0

                if lf[meshid] not in appended:

                    addfeatures.append(lf)
                    appended[lf[meshid]] = lf

                #addfeatures.append(lf)

            resLayer.dataProvider().addFeatures(addfeatures)

            # フォーマット変換(gdal_translate)
            alg_params = {
                'INPUT': resLayer,
                'OPTIONS': '',
                'OUTPUT': parameters['OUTPUT']
            }
            ocv = processing.run('gdal:convertformat',
                                 alg_params,
                                 context=context,
                                 feedback=feedback,
                                 is_child_algorithm=True)

            results["OUTPUT"] = ocv["OUTPUT"]
            return results

    #   均等分割の場合
        else:

            # フォーマット変換(gdal_translate)
            alg_params = {
                'INPUT': last_output,
                'OPTIONS': '',
                'OUTPUT': parameters['OUTPUT']
            }
            ocv = processing.run('gdal:convertformat',
                                 alg_params,
                                 context=context,
                                 feedback=feedback,
                                 is_child_algorithm=True)

            results["OUTPUT"] = ocv["OUTPUT"]
            return results
Exemple #34
0
destCrs = QgsCoordinateReferenceSystem(local_utm)
tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance())
droneLocation.transform(tr)
print("utm Lat", droneLocation.y())
print("utm Lon", droneLocation.x())

# create nadir layer
nadirGeometry = QgsGeometry.fromPointXY(
    QgsPointXY(droneLocation.x(), droneLocation.y()))
nadirLayer = QgsVectorLayer('Point?crs={}'.format(local_utm), 'nadir',
                            'memory')
provider = nadirLayer.dataProvider()
feature = QgsFeature()
feature.setGeometry(nadirGeometry)
provider.addFeatures([feature])
existingLayer = QgsProject.instance().mapLayersByShortName(nadirLayer.name())
if existingLayer:
    QgsProject.instance().removeMapLayer(existingLayer[0])
QgsProject.instance().addMapLayer(nadirLayer)

#altitude_from_sealevel = exifTags['GPS GPSAltitude'].values[0].num / exifTags['GPS GPSAltitude'].values[0].den
realFocalLength = exifTags['EXIF FocalLength'].values[0].num / exifTags[
    'EXIF FocalLength'].values[0].den
teoreticFocalLength = exifTags['EXIF FocalLengthIn35mmFilm'].values[0]
#print("GPSAltitude", GPSAltitude)
print("realFocalLength", realFocalLength)
print("35mmFocalLegth = ", teoreticFocalLength)

exifImageWidth = exifTags['EXIF ExifImageWidth'].values[0]
exifImageLength = exifTags['EXIF ExifImageLength'].values[0]
imageRatio = float(exifImageWidth) / float(exifImageLength)
Exemple #35
0
def geojson_to_memory(path, name):
    my_WkbType = {
        'Unknown': 0,
         'Point': 1,
         'LineString': 2,
         'Polygon': 3,
         'MultiPoint': 4,
         'MultiLineString': 5,
         'MultiPolygon': 6,
         'NoGeometry': 7,
         'Point25D': 8,
         'LineString25D': 9,
         'Polygon25D': 10,
         'MultiPoint25D': 11,
         'MultiLineString25D': 12,
         'MultiPolygon25D': 13}

    # for i,j in my_WkbType.items():
    #     #print i + " : " + str(j)
    my_rev_WkbType = {v: k for k, v in my_WkbType.items()}
    # for i,j in my_WkbType.items():
    #     #print i + " : " + str(j)
    #print 'Path to geojson: %s' % path
    input_layer=QgsVectorLayer(path,
                               "input_layer", "ogr")
    print 'path: %s' % path
    print 'input_layer %s' % input_layer.name()
    dp = input_layer.dataProvider()
    QGisWKBType = dp.geometryType()
    #print 'QGisWKBType: ' + str(QGisWKBType)
    EPSG_code = int(dp.crs().authid().split(":")[1])
    print str(EPSG_code)

    destination_layer = QgsVectorLayer(
        my_rev_WkbType[QGisWKBType] + '?crs=epsg:' + str(EPSG_code) + '&index=yes',
        name,
        'memory')
    destination_layer_data_provider = destination_layer.dataProvider()

    input_layer_attrib_names = input_layer.dataProvider().fields()

    oldattributeList = input_layer.dataProvider().fields().toList()
    newattributeList = []
    for attrib in oldattributeList:
        if destination_layer.fieldNameIndex(attrib.name()) == -1:
            newattributeList.append(QgsField(attrib.name(), attrib.type()))

    destination_layer_data_provider.addAttributes(newattributeList)
    destination_layer.updateFields()

    destination_layer.startEditing()
    # cfeature = QgsFeature()
    cfeatures = []
    xfeatures = input_layer.getFeatures()
    for xfeature in xfeatures:
        xgeometry = xfeature.geometry()
        cfeature_Attributes = []
        cfeature_Attributes.extend(xfeature.attributes())
        cfeature = QgsFeature()
        cfeature.setGeometry(xgeometry)
        cfeature.setAttributes(cfeature_Attributes)
        cfeatures.append(cfeature)

    destination_layer.addFeatures(cfeatures)
    destination_layer.commitChanges()
    return destination_layer
Exemple #36
0
class TestQgsLayerTreeView(unittest.TestCase):
    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)

        # setup a dummy project
        self.project = QgsProject()
        self.layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1",
                                    "memory")
        self.layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2",
                                     "memory")
        self.layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3",
                                     "memory")
        self.layer4 = QgsVectorLayer("Point?field=fldtxt:string", "layer4",
                                     "memory")
        self.layer5 = QgsVectorLayer("Point?field=fldtxt:string", "layer5",
                                     "memory")
        self.project.addMapLayers([self.layer, self.layer2, self.layer3])
        self.model = QgsLayerTreeModel(self.project.layerTreeRoot())

    def nodeOrder(self, group):
        nodeorder = []
        layerTree = QgsLayerTree()
        for node in group:
            if QgsLayerTree.isGroup(node):
                groupname = node.name()
                nodeorder.append(groupname)
                for child in self.nodeOrder(node.children()):
                    nodeorder.append(groupname + '-' + child)
            elif QgsLayerTree.isLayer(node):
                nodeorder.append(node.layer().name())
        return nodeorder

    def testSetModel(self):
        view = QgsLayerTreeView()

        # should not work
        string_list_model = QStringListModel()
        view.setModel(string_list_model)
        self.assertFalse(view.model())

        # should work
        view.setModel(self.model)
        self.assertEqual(view.model(), self.model)

    def testSetCurrentLayer(self):
        view = QgsLayerTreeView()
        view.setModel(self.model)
        current_layer_changed_spy = QSignalSpy(view.currentLayerChanged)
        self.assertFalse(view.currentLayer())
        view.setCurrentLayer(self.layer3)
        self.assertEqual(view.currentLayer(), self.layer3)
        self.assertEqual(len(current_layer_changed_spy), 1)
        view.setCurrentLayer(self.layer)
        self.assertEqual(view.currentLayer(), self.layer)
        self.assertEqual(len(current_layer_changed_spy), 2)
        view.setCurrentLayer(None)
        self.assertFalse(view.currentLayer())
        self.assertEqual(len(current_layer_changed_spy), 3)

    def testDefaultActions(self):
        view = QgsLayerTreeView()
        view.setModel(self.model)
        actions = QgsLayerTreeViewDefaultActions(view)

        # show in overview action
        view.setCurrentLayer(self.layer)
        self.assertEqual(view.currentNode().customProperty('overview', 0),
                         False)
        show_in_overview = actions.actionShowInOverview()
        show_in_overview.trigger()
        self.assertEqual(view.currentNode().customProperty('overview', 0),
                         True)
        show_in_overview.trigger()
        self.assertEqual(view.currentNode().customProperty('overview', 0),
                         False)

    def testMoveOutOfGroupActionLayer(self):
        """Test move out of group action on layer"""
        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().addGroup("embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
            ])

        view.setCurrentLayer(self.layer5)
        moveOutOfGroup = actions.actionMoveOutOfGroup()
        moveOutOfGroup.trigger()
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                self.layer5.name(),
                groupname,
                groupname + '-' + self.layer4.name(),
            ])

    def testMoveToTopActionLayer(self):
        """Test move to top action on layer"""
        view = QgsLayerTreeView()
        view.setModel(self.model)
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(self.project.layerTreeRoot().layerOrder(),
                         [self.layer, self.layer2, self.layer3])
        view.setCurrentLayer(self.layer3)
        movetotop = actions.actionMoveToTop()
        movetotop.trigger()
        self.assertEqual(self.project.layerTreeRoot().layerOrder(),
                         [self.layer3, self.layer, self.layer2])

    def testMoveToTopActionGroup(self):
        """Test move to top action on group"""
        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().addGroup("embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
            ])

        nodeLayerIndex = self.model.node2index(group)
        view.setCurrentIndex(nodeLayerIndex)
        movetotop = actions.actionMoveToTop()
        movetotop.trigger()
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
            ])

    def testMoveToTopActionEmbeddedGroup(self):
        """Test move to top action on embeddedgroup layer"""
        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().addGroup("embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
            ])

        view.setCurrentLayer(self.layer5)
        movetotop = actions.actionMoveToTop()
        movetotop.trigger()
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer5.name(),
                groupname + '-' + self.layer4.name(),
            ])
Exemple #37
0
class UgQgis(object):
    """
    interfaces an UnstructuredGrid object and Qgis layers
    """
    def __init__(self,g):
        self.g = self.extend_grid(g)
        self.install_edge_quality()

    def install_edge_quality(self):
        if 'edge_quality' not in self.g.edges.dtype.names:
            edge_q=np.zeros(self.g.Nedges(),'f8')
            self.g.add_edge_field('edge_quality',edge_q)
            self.update_edge_quality()

    def update_edge_quality(self,edges=None):
        # First part is calculating the values
        if edges is None:
            edges=slice(None)
        g=self.g
        vc=g.cells_center()
        ec=g.edges_center()
        g.edge_to_cells()

        c2c=dist( vc[g.edges['cells'][edges,0]] - vc[g.edges['cells'][edges,1]] )
        A=g.cells_area()
        Acc= A[g.edges['cells'][edges,:]].sum(axis=1)
        c2c=c2c / np.sqrt(Acc) # normalized
        c2c[ np.any(g.edges['cells'][edges,:]<0,axis=1) ] = np.inf
        g.edges['edge_quality'][edges]=c2c
        
    def extend_grid(self,g):
        g.add_node_field('feat_id',np.zeros(g.Nnodes(),'i4')-1)
        g.add_edge_field('feat_id',np.zeros(g.Nedges(),'i4')-1)
        g.add_cell_field('feat_id',np.zeros(g.Ncells(),'i4')-1)

        # install grid callbacks:
        if 1: # re-enabled. DBG - temp. disabled
            g.subscribe_after('modify_node',self.on_modify_node)
            g.subscribe_after('add_node',self.on_add_node)
            g.subscribe_after('add_edge',self.on_add_edge)

            g.subscribe_after('add_cell',self.on_add_cell)

            g.subscribe_before('delete_edge',self.on_delete_edge)
            g.subscribe_before('delete_node',self.on_delete_node)
            g.subscribe_before('delete_cell',self.on_delete_cell)

        return g

    def on_delete_node(self,g,func_name,n,**k):
        # self.log('got signal for delete node')
        self.nl.dataProvider().deleteFeatures([self.g.nodes['feat_id'][n]])
        self.nl.triggerRepaint()

    def on_delete_edge(self,g,func_name,j,**k):
        # self.log('got signal for delete edge')
        self.el.dataProvider().deleteFeatures([self.g.edges['feat_id'][j]])
        self.el.triggerRepaint()

    def on_delete_cell(self,g,func_name,c,**k):
        # this one isn't working, while the others are...
        feat_id=self.g.cells['feat_id'][c]
        self.log('got signal for delete cell %d, feat_id %s'%(c,feat_id))
        self.cl.dataProvider().deleteFeatures([feat_id])
        self.cl.triggerRepaint()

    # Callbacks installed on the grid
    # instrument the grid to propagate changes back to the UI
    def on_modify_node(self,g,func_name,n,**k):
        if 'x' in k:
            fid=self.g.nodes[n]['feat_id']
            geom=self.node_geometry(n)
            self.nl.dataProvider().changeGeometryValues({fid:geom})
            self.nl.triggerRepaint()

            # update cells first, so that edge_quality has fresh
            # cell center and area information
            cell_changes={}
            cells=self.g.node_to_cells(n)
            self.g.cells_center(refresh=cells)
            self.g.cells['_area'][cells]=np.nan # trigger recalc.
            cell_edges=set()
            for i in cells:
                # this was all sorts of messed up - don't understand how
                # it was working at all before...
                fid=self.g.cells[i]['feat_id']
                geom=self.cell_geometry(i)
                cell_changes[fid]=geom
                cell_edges.update(self.g.cell_to_edges(i))
            self.cl.dataProvider().changeGeometryValues(cell_changes)
            self.cl.triggerRepaint()
                
            edge_geom_changes={}
            # edge centers are not cached at this point, so don't
            # need to update them...
            for j in self.g.node_to_edges(n):
                fid=self.g.edges[j]['feat_id']
                geom=self.edge_geometry(j)
                edge_geom_changes[fid]=geom
            self.el.dataProvider().changeGeometryValues(edge_geom_changes)

            # Edges for which a node or cell has changed:
            # this doesn't seem to be working now.
            edge_attr_changes={}
            edge_quality_idx=[i
                              for i,attr in enumerate(self.e_attrs)
                              if attr.name()=='edge_quality'][0]
            js=list(cell_edges)
            self.update_edge_quality(js)
            for j in js:
                # and update edge quality field - would be nice
                # to come up with a nice abstraction here...
                fid=self.g.edges[j]['feat_id']
                edge_attr_changes[fid]={edge_quality_idx:float(self.g.edges[j]['edge_quality'])}
            self.el.dataProvider().changeAttributeValues(edge_attr_changes)

            self.el.triggerRepaint()

    def on_add_node(self,g,func_name,return_value,**k):
        n=return_value
        geom=self.node_geometry(n)
        feat = QgsFeature() # can't set feature_ids
        feat.setGeometry(geom)
        (res, outFeats) = self.nl.dataProvider().addFeatures([feat])

        self.g.nodes['feat_id'][n] = outFeats[0].id()
        self.nl.triggerRepaint()

    def on_add_edge(self,g,func_name,return_value,**k):
        j=return_value
        feat=QgsFeature()
        feat.setGeometry(self.edge_geometry(j))
        (res,outFeats) = self.el.dataProvider().addFeatures([feat])

        self.g.edges['feat_id'][j] = outFeats[0].id()
        self.el.triggerRepaint()

    def on_add_cell(self,g,func_name,return_value,**k):
        c=return_value
        self.log('got signal for add cell')
        geom=self.cell_geometry(c)
        feat = QgsFeature() # can't set feature_ids
        feat.setGeometry(geom)
        (res, outFeats) = self.cl.dataProvider().addFeatures([feat])

        self.g.cells['feat_id'][c] = outFeats[0].id()
        self.cl.triggerRepaint()
         
    def node_geometry(self,n):
        return QgsGeometry.fromPoint(QgsPoint(self.g.nodes['x'][n,0],
                                              self.g.nodes['x'][n,1]))
        
    def populate_nodes(self):
        layer=self.nl
        layer.dataProvider().deleteFeatures(layer.allFeatureIds())

        # takes an existing point memory layer, adds in nodes from g
        feats=[]
        valid=[]
        for n in range(self.g.Nnodes()):
            valid.append(n)
            geom = self.node_geometry(n)
            feat = QgsFeature() # can't set feature_ids
            feat.setGeometry(geom)
            feats.append(feat)
        (res, outFeats) = layer.dataProvider().addFeatures(feats)
        self.g.nodes['feat_id'][valid] = [f.id() for f in outFeats]

        return res

    # callbacks from Qgis layers
    def on_node_geometry_changed(self,feat_id,geom):
        xy=geom.asPoint()
        # this should be sped up with a hash table
        n=np.nonzero( self.g.nodes['feat_id']==feat_id )[0][0]
        self.g.modify_node(n,x=xy)

    def edge_geometry(self,j):
        seg=self.g.nodes['x'][self.g.edges['nodes'][j]]
        pnts=[QgsPoint(seg[0,0],seg[0,1]),
              QgsPoint(seg[1,0],seg[1,1])]
        return QgsGeometry.fromPolyline(pnts)

    def populate_edges(self):
        layer=self.el
        layer.dataProvider().deleteFeatures(layer.allFeatureIds())

        # takes an existing line memory layer, adds in nodes from g
        feats=[]
        valid=[]
        for j in self.g.valid_edge_iter():
            geom=self.edge_geometry(j)
            valid.append(j)
            feat = QgsFeature()
            feat.initAttributes(len(self.e_attrs))
            for idx,eattr in enumerate(self.e_attrs):
                name=eattr.name()
                typecode=eattr.type()
                if name=='edge_id':
                    feat.setAttribute(idx,j) 
                elif name=='c0':
                    feat.setAttribute(idx,int(self.g.edges['cells'][j,0]))
                elif name=='c1':
                    feat.setAttribute(idx,int(self.g.edges['cells'][j,1]))
                elif typecode==2: # integer
                    feat.setAttribute(idx,int(self.g.edges[name][j]))
                elif typecode==6: # double
                    feat.setAttribute(idx,float(self.g.edges[name][j]))
                else:
                    continue
                # QGIS doesn't know about numpy types
            
            # feat.setAttribute(3,int(self.g.edges['mark'][j]))
            feat.setGeometry(geom)
            feats.append(feat)
        (res, outFeats) = layer.dataProvider().addFeatures(feats)
        self.g.edges['feat_id'][valid]=[f.id() for f in outFeats]

        return res

    def cell_geometry(self,i):
        pnts=[QgsPoint(self.g.nodes['x'][n,0],
                       self.g.nodes['x'][n,1])
              for n in self.g.cell_to_nodes(i)]
        return QgsGeometry.fromPolygon([pnts])
        
    def populate_cells(self):
        layer=self.cl
        layer.dataProvider().deleteFeatures(layer.allFeatureIds())

        # takes an existing line memory layer, adds in nodes from g
        feats=[]
        valid=[]
        for i in self.g.valid_cell_iter():
            geom=self.cell_geometry(i)
            feat = QgsFeature()
            feat.setGeometry(geom)
            feats.append(feat)
            valid.append(i)
        (res, outFeats) = layer.dataProvider().addFeatures(feats)
        self.g.cells['feat_id'][valid]=[f.id() for f in outFeats]
        return res

    def clear_layers(self,canvas):
        # more for development - clear out old layers
        lr=QgsMapLayerRegistry.instance()
        layers=lr.mapLayers()
        to_remove=[]
        for layer_key in layers.keys():
            if ( layer_key.startswith('edges') or
                 layer_key.startswith('cells') or
                 layer_key.startswith('nodes') ):
                to_remove.append(layer_key)
        lr.removeMapLayers( to_remove )

    def on_node_layer_deleted(self):
        self.nl=None
        self.log("signal received: node layer deleted")
        # to avoid confusion, let the node layer removal trigger
        # everything, at least for now.  
        self.graceful_deactivate()
    def on_edge_layer_deleted(self):
        self.el=None
        self.log("signal received: edge layer deleted")
    def on_cell_layer_deleted(self):
        self.cl=None
        self.log("signal received: cell layer deleted")

    # create the memory layers and populate accordingly
    def populate_all(self,iface):
        canvas=iface.mapCanvas()
        self.iface=iface
        self.clear_layers(canvas)

        crs="?crs=epsg:26910" # was 4326
        # create layer
        self.nl = QgsVectorLayer("Point"+crs, "nodes", "memory")
        self.el = QgsVectorLayer("LineString"+crs,"edges","memory")
        self.cl = QgsVectorLayer("Polygon"+crs,"cells","memory")

        self.nl.layerDeleted.connect(self.on_node_layer_deleted)
        self.el.layerDeleted.connect(self.on_edge_layer_deleted)
        self.cl.layerDeleted.connect(self.on_cell_layer_deleted)

        pr = self.el.dataProvider()

        # add fields - eventually would be tied in with g.edge_dtype
        e_attrs=[QgsField("edge_id",QVariant.Int)]

        for fidx,fdesc in enumerate(self.g.edge_dtype.descr):
            # descr gives string reprs of the types, use dtype
            # to get back to an object.
            fname=fdesc[0] ; ftype=np.dtype(fdesc[1])
            if len(fdesc)>2:
                fshape=fdesc[2]
            else:
                fshape=None

            if fname=='nodes':
                continue
            elif fname=='cells':
                e_attrs += [QgsField("c0", QVariant.Int),
                            QgsField("c1", QVariant.Int)]
            else:
                if np.issubdtype(ftype,np.int):
                    e_attrs.append( QgsField(fname,QVariant.Int) )
                elif np.issubdtype(ftype,np.float):
                    e_attrs.append( QgsField(fname,QVariant.Double) )
                else:
                    self.log("Not read other datatypes")
        self.e_attrs=e_attrs            
        pr.addAttributes(e_attrs)
        self.el.updateFields() # tell the vector layer to fetch changes from the provider

        self.populate_nodes()
        self.populate_edges()
        self.populate_cells()

        # Create a group for the layers -
        li=iface.legendInterface()

        grp_name="grid001"
        for gidx,gname in enumerate(li.groups()):
            if gname==grp_name:
                li.removeGroup(gidx)
        
        group_index=li.addGroup("grid001")

        for layer in [self.cl,self.el,self.nl]:
            # add layer to the registry
            QgsMapLayerRegistry.instance().addMapLayer(layer)
            li.moveLayer(layer,group_index)

        # if this is omitted, be sure to also skip over
        # the disconnects.
        li.currentLayerChanged.connect(self.on_layer_changed)
            
        # set extent to the extent of our layer
        # skip while developing
        # canvas.setExtent(layer.extent())

        self.tool=UgEditTool(canvas,self)
        canvas.setMapTool(self.tool)

    def graceful_deactivate(self):
        self.log("UgQgis deactivating")
        li=self.iface.legendInterface()
        li.currentLayerChanged.disconnect(self.on_layer_changed)
        self.log("currentLayerChanged callback disconnected")
        # remove map tool from the canvas
        canvas=self.iface.mapCanvas()
        if canvas.mapTool() == self.tool:
            self.log("active map tool is ours - how to remove??")
            self.tool=None
        # remove callbacks from the grid:
        self.log("Not ready for removing callbacks from the grid")

    def on_layer_changed(self,layer):
        if layer is not None:
            # Not sure why, but using layer.id() was triggering an error
            # about the layer being deleted.  Hmm - this is still somehow
            # related to an error about the layer being deleted.
            self.log("About to check names")
            if layer.name()==self.nl.name():
                # this happens, but doesn't seem to succeed
                self.log("Setting map tool to ours")
                self.iface.mapCanvas().setMapTool(self.tool)
                self.log("Done with setting map tool to ours")
            else:
                self.log("on_layer_changed, but to id=%s"%layer.name())
                self.log("My node name=%s"%self.nl.name())

    def log(self,s):
        with open(os.path.join(os.path.dirname(__file__),'log'),'a') as fp:
            fp.write(s+"\n")
            fp.flush()