def test_create_layer(self):
        """Test create layer work"""

        # Lines
        line_layer = QgsVectorLayer(
            self.line_before + '.shp', 'test', 'ogr')
        new_layer = create_layer(line_layer)
        self.assertEquals(new_layer.geometryType(), line_layer.geometryType())
        self.assertEquals(new_layer.crs(), line_layer.crs())
        fields = line_layer.dataProvider().fields()
        new_fields = new_layer.dataProvider().fields()
        self.assertEquals(new_fields.toList(), fields.toList())

        # Polygon
        polygon_layer = QgsVectorLayer(
            self.polygon_base + '.shp', 'test', 'ogr')
        new_layer = create_layer(polygon_layer)
        self.assertEquals(
            new_layer.geometryType(),
            polygon_layer.geometryType()
        )
        self.assertEquals(new_layer.crs(), polygon_layer.crs())
        fields = polygon_layer.dataProvider().fields()
        new_fields = new_layer.dataProvider().fields()
        self.assertEquals(new_fields.toList(), fields.toList())
    def testLayerGeometry(self):
        layer = QgsVectorLayer("Point", "test", "memory")

        myMessage = "Expected: %s\nGot: %s\n" % (QGis.Point, layer.geometryType())
        assert layer.geometryType() == QGis.Point, myMessage

        myMessage = "Expected: %s\nGot: %s\n" % (QGis.WKBPoint, layer.wkbType())
        assert layer.wkbType() == QGis.WKBPoint, myMessage
def create_grid(size):
    """Create a polygonal grid using Processing.

    :param size: The cell size.
    :type size: int

    :return: The grid layer in memory.
    :rtype: QgsVectorLayer
    """
    output_filename = unique_filename(prefix='grid', suffix='.shp')

    result = processing.runalg(
        'qgis:vectorgrid',
        '336199.970553,352338.397991,7636164.67975,7648562.41208',
        size,  # X spacing
        size,  # Y spacing
        0,  # Output as polygons
        output_filename)

    layer = QgsVectorLayer(output_filename, 'grid', 'ogr')
    layer.setCrs(QgsCoordinateReferenceSystem(32740))

    remove_fields(layer, ['xmin', 'xmax', 'ymin', 'ymax'])

    # Make a copy in memory
    memory = create_memory_layer(
        'grid', layer.geometryType(), layer.crs(), layer.fields())
    copy_layer(layer, memory)

    print "NB cells : %s" % layer.featureCount()

    return memory
 def load_loss_layer(self, loss_layer_path):
     # Load loss layer
     if self.loss_layer_is_vector:
         loss_layer = QgsVectorLayer(loss_layer_path, tr('Loss map'), 'ogr')
         if not loss_layer.geometryType() == QGis.Point:
             msg = 'Loss map must contain points'
             self.iface.messageBar().pushMessage(
                 tr("Error"),
                 tr(msg),
                 level=QgsMessageBar.CRITICAL)
             return False
     else:
         loss_layer = QgsRasterLayer(loss_layer_path, tr('Loss map'))
     # Add loss layer to registry
     if loss_layer.isValid():
         QgsMapLayerRegistry.instance().addMapLayer(loss_layer)
     else:
         msg = 'Invalid loss map'
         self.iface.messageBar().pushMessage(
             tr("Error"),
             tr(msg),
             level=QgsMessageBar.CRITICAL)
         return None
     # Zoom depending on the zonal layer's extent
     return loss_layer
Exemple #5
0
def load(fileName, name=None, crs=None, style=None):
    """Loads a layer/table into the current project, given its file.
    """

    if fileName is None:
        return
    prjSetting = None
    settings = QSettings()
    if crs is not None:
        prjSetting = settings.value('/Projections/defaultBehaviour')
        settings.setValue('/Projections/defaultBehaviour', '')
    if name is None:
        name = os.path.split(fileName)[1]
    qgslayer = QgsVectorLayer(fileName, name, 'ogr')
    if qgslayer.isValid():
        if crs is not None and qgslayer.crs() is None:
            qgslayer.setCrs(crs, False)
        if style is None:
            if qgslayer.geometryType() == QGis.Point:
                style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POINT_STYLE)
            elif qgslayer.geometryType() == QGis.Line:
                style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_LINE_STYLE)
            else:
                style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POLYGON_STYLE)
        qgslayer.loadNamedStyle(style)
        QgsMapLayerRegistry.instance().addMapLayers([qgslayer])
    else:
        qgslayer = QgsRasterLayer(fileName, name)
        if qgslayer.isValid():
            if crs is not None and qgslayer.crs() is None:
                qgslayer.setCrs(crs, False)
            if style is None:
                style = ProcessingConfig.getSetting(ProcessingConfig.RASTER_STYLE)
            qgslayer.loadNamedStyle(style)
            QgsMapLayerRegistry.instance().addMapLayers([qgslayer])
            iface.legendInterface().refreshLayerSymbology(qgslayer)
        else:
            if prjSetting:
                settings.setValue('/Projections/defaultBehaviour', prjSetting)
            raise RuntimeError('Could not load layer: ' + unicode(fileName)
                               + '\nCheck the procesing framework log to look for errors')
    if prjSetting:
        settings.setValue('/Projections/defaultBehaviour', prjSetting)

    return qgslayer
    def testLayerGeometry(self):
        testVectors = [("Point", QGis.Point, QGis.WKBPoint),
                       ("LineString", QGis.Line, QGis.WKBLineString),
                       ("Polygon", QGis.Polygon, QGis.WKBPolygon),
                       ("MultiPoint", QGis.Point, QGis.WKBMultiPoint),
                       ("MultiLineString", QGis.Line, QGis.WKBMultiLineString),
                       ("MultiPolygon", QGis.Polygon, QGis.WKBMultiPolygon),
                       ("None", QGis.NoGeometry, QGis.WKBNoGeometry)]
        for v in testVectors:
            layer = QgsVectorLayer(v[0], "test", "memory")

            myMessage = ('Expected: %s\nGot: %s\n' %
                         (v[1], layer.geometryType()))
            assert layer.geometryType() == v[1], myMessage

            myMessage = ('Expected: %s\nGot: %s\n' %
                         (v[2], layer.wkbType()))
            assert layer.wkbType() == v[2], myMessage
    def testLayerGeometry(self):
        testVectors = [("Point", QgsWkbTypes.PointGeometry, QgsWkbTypes.Point),
                       ("LineString", QgsWkbTypes.LineGeometry, QgsWkbTypes.LineString),
                       ("Polygon", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.Polygon),
                       ("MultiPoint", QgsWkbTypes.PointGeometry, QgsWkbTypes.MultiPoint),
                       ("MultiLineString", QgsWkbTypes.LineGeometry, QgsWkbTypes.MultiLineString),
                       ("MultiPolygon", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.MultiPolygon),
                       ("PointZ", QgsWkbTypes.PointGeometry, QgsWkbTypes.PointZ),
                       ("LineStringZ", QgsWkbTypes.LineGeometry, QgsWkbTypes.LineStringZ),
                       ("PolygonZ", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.PolygonZ),
                       ("MultiPointZ", QgsWkbTypes.PointGeometry, QgsWkbTypes.MultiPointZ),
                       ("MultiLineStringZ", QgsWkbTypes.LineGeometry, QgsWkbTypes.MultiLineStringZ),
                       ("MultiPolygonZ", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.MultiPolygonZ),
                       ("PointM", QgsWkbTypes.PointGeometry, QgsWkbTypes.PointM),
                       ("LineStringM", QgsWkbTypes.LineGeometry, QgsWkbTypes.LineStringM),
                       ("PolygonM", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.PolygonM),
                       ("MultiPointM", QgsWkbTypes.PointGeometry, QgsWkbTypes.MultiPointM),
                       ("MultiLineStringM", QgsWkbTypes.LineGeometry, QgsWkbTypes.MultiLineStringM),
                       ("MultiPolygonM", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.MultiPolygonM),
                       ("PointZM", QgsWkbTypes.PointGeometry, QgsWkbTypes.PointZM),
                       ("LineStringZM", QgsWkbTypes.LineGeometry, QgsWkbTypes.LineStringZM),
                       ("PolygonZM", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.PolygonZM),
                       ("MultiPointZM", QgsWkbTypes.PointGeometry, QgsWkbTypes.MultiPointZM),
                       ("MultiLineStringZM", QgsWkbTypes.LineGeometry, QgsWkbTypes.MultiLineStringZM),
                       ("MultiPolygonZM", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.MultiPolygonZM),
                       ("Point25D", QgsWkbTypes.PointGeometry, QgsWkbTypes.Point25D),
                       ("LineString25D", QgsWkbTypes.LineGeometry, QgsWkbTypes.LineString25D),
                       ("Polygon25D", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.Polygon25D),
                       ("MultiPoint25D", QgsWkbTypes.PointGeometry, QgsWkbTypes.MultiPoint25D),
                       ("MultiLineString25D", QgsWkbTypes.LineGeometry, QgsWkbTypes.MultiLineString25D),
                       ("MultiPolygon25D", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.MultiPolygon25D),
                       ("None", QgsWkbTypes.NullGeometry, QgsWkbTypes.NoGeometry)]
        for v in testVectors:
            layer = QgsVectorLayer(v[0], "test", "pythonprovider")

            myMessage = ('Expected: %s\nGot: %s\n' %
                         (v[1], layer.geometryType()))
            assert layer.geometryType() == v[1], myMessage

            myMessage = ('Expected: %s\nGot: %s\n' %
                         (v[2], layer.wkbType()))
            assert layer.wkbType() == v[2], myMessage
    def loadData(self, resultFile, chunkId):
        """ Load data to the map """
        
        if isMimeTypeVector(self.mimeType, True) != None:                 
            # Memory layer:
            geometryTypes = ["Point","LineString","Polygon","Unknown", "NoGeometry"]
            vlayer = QgsVectorLayer(resultFile, "chunk", "ogr")

            if self.__bFirstChunk:    
                self.__bFirstChunk = False
                self.__geometryType = geometryTypes[vlayer.geometryType()]
                self.__bGeomMulti = vlayer.wkbType() in [4,5,6,11,12,13]
                self.__memoryLayer = QgsVectorLayer(self.__geometryType,"Streamed data","memory")
                self.__memoryLayer.dataProvider().addAttributes(vlayer.pendingFields().values())
                self.__memoryLayer.updateFieldMap()            

            provider = vlayer.dataProvider()
            allAttrs = provider.attributeIndexes()
            vlayer.select(allAttrs)  
            
            # Visualize temporal geometries during the downloading process
            # Don't add temporal geometries if last chunk
            if self.DEBUG: print "Loaded chunkId:",chunkId           
            res = self.__memoryLayer.dataProvider().addFeatures( [feat for feat in vlayer] )
            self.__deliveredChunks += 1      
            
            if not self.allChunksDelivered():
                inFeat = QgsFeature()
                inGeom = QgsGeometry()
                self.createTempGeometry(chunkId, self.__geometryType)
                while provider.nextFeature( inFeat ):
                    inGeom = inFeat.geometry()
                    featList = self.extractAsSingle(self.__geometryType, inGeom) if self.__bGeomMulti else [inGeom]
                    for geom in featList:
                        self.addTempGeometry(chunkId, self.__geometryType, geom)  
            else:
                self.finishLoading()
                                
        # Raster data
        elif isMimeTypeRaster(self.mimeType, True) != None:
            # We can directly attach the new layer
            if self.__bFirstChunk:    
                self.__bFirstChunk = False
                self.__groupIndex = self.__legend.addGroup("Streamed-raster")
                
            rLayer = QgsRasterLayer(resultFile, "raster_"+str(chunkId))
            bLoaded = QgsMapLayerRegistry.instance().addMapLayer(rLayer)
            self.stretchRaster(rLayer)
            self.__legend.moveLayer(rLayer, self.__groupIndex + 1)
            
            self.__deliveredChunks += 1
            
            if self.allChunksDelivered():
                self.finishLoading()
Exemple #9
0
    def __snap(self):

        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())
        geom_type = layer.geometryType()
        # layer.wkbType() does not return reliable results
        wkb_type = layer.wkbType()

        if self.create_backup:
            self.report_message.emit(self.layer_id, 'creating backup ...')
            self.__create_backup_file(orig_layer)

        self.report_message.emit(self.layer_id, 'preparing ...')
        layer.startEditing()
        request = QgsFeatureRequest().setFilterRect(self.snap_extent)
        total_features = 0
        for feature in layer.getFeatures(request):
            total_features += 1

        QgsMessageLog.logMessage(self.plugin.tr('Features to be snapped 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')

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

            if geom_type == QGis.Point:
                snapped_geom = self.__point_grid(feature, wkb_type)
            elif geom_type == QGis.Line:
                snapped_geom = self.__line_grid(feature, wkb_type)
            elif geom_type == QGis.Polygon:
                snapped_geom = self.__polygon_grid(feature, wkb_type)

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

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

        layer.commitChanges()

        self.completed = True
Exemple #10
0
    def _get_cursor_columns(self, c):
        tf = QTemporaryFile()
        tf.open()
        tmp = tf.fileName()
        tf.close()

        q = QUrl.toPercentEncoding(c.sql)
        p = QgsVectorLayer("%s?query=%s" % (QUrl.fromLocalFile(tmp).toString(), q), "vv", "virtual")
        if not p.isValid():
            return []
        f = [f.name() for f in p.fields()]
        if p.geometryType() != QGis.WKBNoGeometry:
            gn = getQueryGeometryName(tmp)
            if gn:
                f += [gn]
        return f
    def test_sql5(self):
        l2 = QgsVectorLayer( os.path.join(self.testDataDir_, "france_parts.shp"), "france_parts", "ogr", False )
        self.assertEqual( l2.isValid(), True )
        QgsMapLayerRegistry.instance().addMapLayer(l2)

        query = QUrl.toPercentEncoding( "SELECT st_union(geometry) as geom from france_parts" )
        l4 = QgsVectorLayer( "?query=%s" % query, "tt", "virtual", False )
        self.assertEqual( l4.isValid(), True )
        #        self.assertEqual( l4.dataProvider().geometryType(), 3 )
        #self.assertEqual( l4.geometryType(), 2 )

        query = QUrl.toPercentEncoding( "SELECT st_collect(geometry) as geom from france_parts" )
        l4 = QgsVectorLayer( "?query=%s" % query, "tt", "virtual", False )
        self.assertEqual( l4.isValid(), True )
        self.assertEqual( l4.dataProvider().geometryType(), 0 )
        self.assertEqual( l4.geometryType(), 3 ) # unknown geometry
Exemple #12
0
    def make_OD_markers(nb, xo, yo, xd, yd, list_coords=None):
        """
        Prepare the Origin (green), Destination (red) and Intalternative_geometriesermediates (grey)
        markers.
        """
        OD_layer = QgsVectorLayer(
            "Point?crs=epsg:4326&field=id_route:integer&field=role:string(80)",
            "markers_osrm{}".format(nb), "memory")
        features = []
        fet = QgsFeature()
        fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(float(xo), float(yo))))
        fet.setAttributes([nb, 'Origin'])
        features.append(fet)
        fet = QgsFeature()
        fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(float(xd), float(yd))))
        fet.setAttributes([nb, 'Destination'])
        features.append(fet)
        marker_rules = [
            ('Origin', '"role" LIKE \'Origin\'', '#50b56d', 4),
            ('Destination', '"role" LIKE \'Destination\'', '#d31115', 4),
        ]
        if list_coords:
            for i, pt in enumerate(list_coords):
                fet = QgsFeature()
                fet.setGeometry(
                    QgsGeometry.fromPoint(QgsPoint(float(pt[0]), float(pt[1])))
                    )
                fet.setAttributes([nb, 'Via point n°{}'.format(i)])
                features.append(fet)
            marker_rules.insert(
                1, ('Intermediate', '"role" LIKE \'Via point%\'', 'grey', 2))
        OD_layer.dataProvider().addFeatures(features)

        symbol = QgsSymbolV2.defaultSymbol(OD_layer.geometryType())
        renderer = QgsRuleBasedRendererV2(symbol)
        root_rule = renderer.rootRule()
        for label, expression, color_name, size in marker_rules:
            rule = root_rule.children()[0].clone()
            rule.setLabel(label)
            rule.setFilterExpression(expression)
            rule.symbol().setColor(QtGui.QColor(color_name))
            rule.symbol().setSize(size)
            root_rule.appendChild(rule)

        root_rule.removeChildAt(0)
        OD_layer.setRendererV2(renderer)
        return OD_layer
    def make_OD_markers(nb, xo, yo, xd, yd, list_coords=None):
        """
        Prepare the Origin (green), Destination (red) and Intermediates (grey)
        markers.
        """
        OD_layer = QgsVectorLayer(
            "Point?crs=epsg:4326&field=id_route:integer&field=role:string(80)",
            "markers_osrm{}".format(nb), "memory")
        features = []
        fet = QgsFeature()
        fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(float(xo), float(yo))))
        fet.setAttributes([nb, 'Origin'])
        features.append(fet)
        fet = QgsFeature()
        fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(float(xd), float(yd))))
        fet.setAttributes([nb, 'Destination'])
        features.append(fet)
        marker_rules = [
            ('Origin', '"role" LIKE \'Origin\'', '#50b56d', 4),
            ('Destination', '"role" LIKE \'Destination\'', '#d31115', 4),
        ]
        if list_coords:
            for i, pt in enumerate(list_coords):
                fet = QgsFeature()
                fet.setGeometry(
                    QgsGeometry.fromPoint(QgsPoint(float(pt[0]),
                                                   float(pt[1]))))
                fet.setAttributes([nb, 'Via point n°{}'.format(i)])
                features.append(fet)
            marker_rules.insert(
                1, ('Intermediate', '"role" LIKE \'Via point%\'', 'grey', 2))
        OD_layer.dataProvider().addFeatures(features)

        symbol = QgsSymbolV2.defaultSymbol(OD_layer.geometryType())
        renderer = QgsRuleBasedRendererV2(symbol)
        root_rule = renderer.rootRule()
        for label, expression, color_name, size in marker_rules:
            rule = root_rule.children()[0].clone()
            rule.setLabel(label)
            rule.setFilterExpression(expression)
            rule.symbol().setColor(QtGui.QColor(color_name))
            rule.symbol().setSize(size)
            root_rule.appendChild(rule)

        root_rule.removeChildAt(0)
        OD_layer.setRendererV2(renderer)
        return OD_layer
Exemple #14
0
def create_vtx_outofbbox_lyr():
    vtx_outofbbox_lyr = QgsVectorLayer(r"Point?crs=epsg:4326&index=yes",
                                  vtx_outofbbox_lname, r"memory")
    p_vtx_outofbbox_lyr = vtx_outofbbox_lyr.dataProvider()
    QgsProject.instance().addMapLayer(vtx_outofbbox_lyr, True)
    # Create a simple symbol
    rend_symb=QgsSymbol.defaultSymbol(vtx_outofbbox_lyr.geometryType())
    rend_symb.setSize(vtx_outofbbox_size)
    rend_symb.setColor(QColor(vtx_outofbbox_color))
    rend_symb.setOpacity(vtx_outofbbox_opc)
    rend_vtx_outofbbox = QgsSingleSymbolRenderer(rend_symb)
    vtx_outofbbox_lyr.setRenderer(rend_vtx_outofbbox)
    p_vtx_outofbbox_lyr.addAttributes(vtx_atts)
    vtx_outofbbox_lyr.updateFields()
    # Refresh the canvas
    vtx_outofbbox_lyr.triggerRepaint()
    return vtx_outofbbox_lyr
Exemple #15
0
def create_edge_outofbbox_lyr():
    edge_outofbbox_lyr = QgsVectorLayer(r"LineString?crs=epsg:4326&index=yes",
                                  edge_outofbbox_lname, r"memory")
    p_edge_outofbbox_lyr = edge_outofbbox_lyr.dataProvider()
    QgsProject.instance().addMapLayer(edge_outofbbox_lyr, True)
    # Create a simple symbol
    rend_symb=QgsSymbol.defaultSymbol(edge_outofbbox_lyr.geometryType())
    rend_symb.setWidth(edge_outofbbox_width)
    rend_symb.setColor(QColor(edge_outofbbox_color))
    rend_symb.setOpacity(edge_outofbbox_opc)
    rend_edge_outofbbox = QgsSingleSymbolRenderer(rend_symb)
    edge_outofbbox_lyr.setRenderer(rend_edge_outofbbox)
    p_edge_outofbbox_lyr.addAttributes(edge_atts)
    edge_outofbbox_lyr.updateFields()
    # Refresh the canvas
    edge_outofbbox_lyr.triggerRepaint()
    return edge_outofbbox_lyr
Exemple #16
0
def JSONGeometryFromLayer(qgsLayer: QgsVectorLayer)->str:
    features: QgsFeatureIterator = qgsLayer.getFeatures()
    geomType: QgsWkbTypes.GeometryType = qgsLayer.geometryType()
    ret_geom = None
    for feature in features:
        geom:QgsGeometry = QgsGeometry(feature.geometry())
        if ret_geom is None:
            if geomType == QgsWkbTypes.Polygon:
                ret_geom = geom.asMultiPolygon()
            if geomType == QgsWkbTypes.MultiPolygon:
                ret_geom = geom
        if geomType == QgsWkbTypes.Polygon:
            ret_geom.addPartGeometry(geom)
        elif geomType == QgsWkbTypes.MultiPolygon:
            for i in geom.parts():
                ret_geom.addPartGeometry(i)
    return geometry.QgsGeometrytoGeoJSON(ret_geom) 
Exemple #17
0
    def onValidationSetsLoadButtonClicked(self) -> None:
        assert self.contentItem
        assert self.contentItem['ContentID']

        self.contentItemFilename = tempfile.NamedTemporaryFile().name

        # TODO this lock is not working for some reason :/
        self.loginGroupBox.setEnabled(False)
        self.projectsGroupBox.setEnabled(False)
        self.validationSetsGroupBox.setEnabled(False)
        self.boundaryStringsGroupBox.setEnabled(False)

        try:
            self.service.download_content_item(self.contentItem['ContentID'],
                                               self.contentItemFilename)
            layer = QgsVectorLayer(self.contentItemFilename,
                                   self.validationSet['Name'], 'ogr')

            if layer.geometryType() != QgsWkbTypes.LineGeometry:
                utils.show_info(
                    __('Validation set file is not with line geometries'))
                return

            utils.add_layer(layer,
                            self.validationSet['Name'],
                            parent=utils.get_group(),
                            index=0)
            layer = self.plugin.setSegmentsLayer(
                layer, name=self.validationSet['Name'])

            if layer:
                # TODO the ugliest thing in the whole project
                self.plugin.dockWidget.segmentsLayerComboBox.setLayer(layer)
        except Its4landException as e:
            if e.code == 404:
                utils.show_info(
                    __('Unable to load the selected validation set, check the web interface for more information'
                       ))
                return
            else:
                raise e
        finally:
            self.loginGroupBox.setEnabled(True)
            self.projectsGroupBox.setEnabled(True)
            self.validationSetsGroupBox.setEnabled(True)
            self.boundaryStringsGroupBox.setEnabled(True)
Exemple #18
0
    def _get_cursor_columns(self, c):
        tf = QTemporaryFile()
        tf.open()
        tmp = tf.fileName()
        tf.close()

        q = QUrl.toPercentEncoding(c.sql)
        p = QgsVectorLayer(
            "%s?query=%s" % (QUrl.fromLocalFile(tmp).toString(), q), "vv",
            "virtual")
        if not p.isValid():
            return []
        f = [f.name() for f in p.fields()]
        if p.geometryType() != QgsWkbTypes.NullGeometry:
            gn = getQueryGeometryName(tmp)
            if gn:
                f += [gn]
        return f
Exemple #19
0
    def _get_cursor_columns(self, c):
        tf = QTemporaryFile()
        tf.open()
        tmp = tf.fileName()
        tf.close()

        df = QgsVirtualLayerDefinition()
        df.setFilePath(tmp)
        df.setQuery(c.sql)
        p = QgsVectorLayer(df.toString(), "vv", "virtual")
        if not p.isValid():
            return []
        f = [f.name() for f in p.fields()]
        if p.geometryType() != QgsWkbTypes.NullGeometry:
            gn = getQueryGeometryName(tmp)
            if gn:
                f += [gn]
        return f
Exemple #20
0
 def newDatasourceIsValid(self, layer, newDS):
     """
     Probe new datasource to prevent layer issues
     """
     ds, uri = self.splitSource(newDS)
     if not ds:
         # if datasource type is not specified uri is probed with current one
         ds = layer.dataProvider().name()
     nlayer = QgsVectorLayer(uri, "probe", ds)
     if not nlayer.isValid():
         self.iface.messageBar().pushMessage("Error", "incorrect source|uri string: " + newDS, level=Qgis.Critical, duration=4)
         self.updateLog("\nERROR: incorrect source|uri string: " + newDS)
         return None
     if nlayer.geometryType() != layer.geometryType():
         self.iface.messageBar().pushMessage("Error", "geometry type mismatch on new datasource: " + newDS, level=Qgis.Critical, duration=4)
         self.updateLog("\nERROR: geometry type mismatch on new datasource: " + newDS)
         return None
     return True
Exemple #21
0
    def _get_cursor_columns(self, c):
        tf = QTemporaryFile()
        tf.open()
        tmp = tf.fileName()
        tf.close()

        df = QgsVirtualLayerDefinition()
        df.setFilePath(tmp)
        df.setQuery(c.sql)
        p = QgsVectorLayer(df.toString(), "vv", "virtual")
        if not p.isValid():
            return []
        f = [f.name() for f in p.fields()]
        if p.geometryType() != QgsWkbTypes.NullGeometry:
            gn = getQueryGeometryName(tmp)
            if gn:
                f += [gn]
        return f
Exemple #22
0
def getShapesByGeometryType(baseDir, inShapes, geomType):
    outShapes = []
    for fileName in inShapes:
        layerPath = QFileInfo(baseDir + "/" + fileName).absoluteFilePath()
        vLayer = QgsVectorLayer(layerPath, QFileInfo(layerPath).baseName(), "ogr")
        if not vLayer.isValid():
            continue
        layerGeometry = vLayer.geometryType()
        if layerGeometry == QGis.Polygon and geomType == 0:
            outShapes.append(fileName)
        elif layerGeometry == QGis.Line and geomType == 1:
            outShapes.append(fileName)
        elif layerGeometry == QGis.Point and geomType == 2:
            outShapes.append(fileName)

    if len(outShapes) == 0:
        return None

    return outShapes
Exemple #23
0
    def __init__(self, db, sql, parent=None):
        # create a virtual layer with non-geometry results
        t = QTime()
        t.start()

        tf = QTemporaryFile()
        tf.open()
        tmp = tf.fileName()
        tf.close()

        df = QgsVirtualLayerDefinition()
        df.setFilePath(tmp)
        df.setQuery(sql)
        p = QgsVectorLayer(df.toString(), "vv", "virtual")
        self._secs = t.elapsed() / 1000.0

        if not p.isValid():
            data = []
            header = []
            raise DbError(p.dataProvider().error().summary(), sql)
        else:
            header = [f.name() for f in p.fields()]
            has_geometry = False
            if p.geometryType() != QgsWkbTypes.NullGeometry:
                gn = getQueryGeometryName(tmp)
                if gn:
                    has_geometry = True
                    header += [gn]

            data = []
            for f in p.getFeatures():
                a = f.attributes()
                if has_geometry:
                    if f.hasGeometry():
                        a += [f.geometry().exportToWkt()]
                    else:
                        a += [None]
                data += [a]

        self._secs = 0
        self._affectedRows = len(data)

        BaseTableModel.__init__(self, header, data, parent)
Exemple #24
0
    def __init__(self, db, sql, parent=None, layer=None, path=None):
        t = QTime()
        t.start()

        if not layer:
            tf = QTemporaryFile()
            tf.open()
            path = tf.fileName()
            tf.close()

            df = QgsVirtualLayerDefinition()
            df.setFilePath(path)
            df.setQuery(sql)
            layer = QgsVectorLayer(df.toString(), "vv", "virtual")
            self._secs = t.elapsed() / 1000.0

        data = []
        header = []

        if not layer.isValid():
            raise DbError(layer.dataProvider().error().summary(), sql)
        else:
            header = [f.name() for f in layer.fields()]
            has_geometry = False
            if layer.geometryType() != QgsWkbTypes.NullGeometry:
                gn = getQueryGeometryName(path)
                if gn:
                    has_geometry = True
                    header += [gn]

            for f in layer.getFeatures():
                a = f.attributes()
                if has_geometry:
                    if f.hasGeometry():
                        a += [f.geometry().asWkt()]
                    else:
                        a += [None]
                data += [a]

        self._secs = 0
        self._affectedRows = len(data)

        BaseTableModel.__init__(self, header, data, parent)
Exemple #25
0
    def __init__(self, db, sql, parent=None, layer=None, path=None):
        t = QTime()
        t.start()

        if not layer:
            tf = QTemporaryFile()
            tf.open()
            path = tf.fileName()
            tf.close()

            df = QgsVirtualLayerDefinition()
            df.setFilePath(path)
            df.setQuery(sql)
            layer = QgsVectorLayer(df.toString(), "vv", "virtual")
            self._secs = t.elapsed() / 1000.0

        data = []
        header = []

        if not layer.isValid():
            raise DbError(layer.dataProvider().error().summary(), sql)
        else:
            header = [f.name() for f in layer.fields()]
            has_geometry = False
            if layer.geometryType() != QgsWkbTypes.NullGeometry:
                gn = getQueryGeometryName(path)
                if gn:
                    has_geometry = True
                    header += [gn]

            for f in layer.getFeatures():
                a = f.attributes()
                if has_geometry:
                    if f.hasGeometry():
                        a += [f.geometry().asWkt()]
                    else:
                        a += [None]
                data += [a]

        self._secs = 0
        self._affectedRows = len(data)

        BaseTableModel.__init__(self, header, data, parent)
 def load_loss_layer(self, loss_layer_path):
     # Load loss layer
     if self.loss_layer_is_vector:
         loss_layer = QgsVectorLayer(loss_layer_path, tr('Loss map'), 'ogr')
         if not loss_layer.geometryType() == QGis.Point:
             msg = 'Loss map must contain points'
             log_msg(msg, level='C', message_bar=self.iface.messageBar())
             return False
     else:
         loss_layer = QgsRasterLayer(loss_layer_path, tr('Loss map'))
     # Add loss layer to registry
     if loss_layer.isValid():
         QgsMapLayerRegistry.instance().addMapLayer(loss_layer)
     else:
         msg = 'Invalid loss map'
         log_msg(msg, level='C', message_bar=self.iface.messageBar())
         return None
     # Zoom depending on the zonal layer's extent
     return loss_layer
Exemple #27
0
    def __init__(self, db, sql, parent=None):
        # create a virtual layer with non-geometry results
        t = QTime()
        t.start()

        tf = QTemporaryFile()
        tf.open()
        tmp = tf.fileName()
        tf.close()

        df = QgsVirtualLayerDefinition()
        df.setFilePath(tmp)
        df.setQuery(sql)
        p = QgsVectorLayer(df.toString(), "vv", "virtual")
        self._secs = t.elapsed() / 1000.0

        if not p.isValid():
            data = []
            header = []
            raise DbError(p.dataProvider().error().summary(), sql)
        else:
            header = [f.name() for f in p.fields()]
            has_geometry = False
            if p.geometryType() != QgsWkbTypes.NullGeometry:
                gn = getQueryGeometryName(tmp)
                if gn:
                    has_geometry = True
                    header += [gn]

            data = []
            for f in p.getFeatures():
                a = f.attributes()
                if has_geometry:
                    if f.hasGeometry():
                        a += [f.geometry().exportToWkt()]
                    else:
                        a += [None]
                data += [a]

        self._secs = 0
        self._affectedRows = len(data)

        BaseTableModel.__init__(self, header, data, parent)
Exemple #28
0
def getShapesByGeometryType(baseDir, inShapes, geomType):
    outShapes = []
    for fileName in inShapes:
        layerPath = QFileInfo(baseDir + "/" + fileName).absoluteFilePath()
        vLayer = QgsVectorLayer(layerPath, QFileInfo(layerPath).baseName(), "ogr")
        if not vLayer.isValid():
            continue
        layerGeometry = vLayer.geometryType()
        if layerGeometry == QGis.Polygon and geomType == 0:
            outShapes.append(fileName)
        elif layerGeometry == QGis.Line and geomType == 1:
            outShapes.append(fileName)
        elif layerGeometry == QGis.Point and geomType == 2:
            outShapes.append(fileName)

    if len(outShapes) == 0:
        return None

    return outShapes
Exemple #29
0
    def __init__(self, db, sql, parent=None):
        # create a virtual layer with non-geometry results
        q = QUrl.toPercentEncoding(sql)
        t = QTime()
        t.start()

        tf = QTemporaryFile()
        tf.open()
        tmp = tf.fileName()
        tf.close()

        p = QgsVectorLayer(
            "%s?query=%s" % (QUrl.fromLocalFile(tmp).toString(), q), "vv",
            "virtual")
        self._secs = t.elapsed() / 1000.0

        if not p.isValid():
            data = []
            header = []
            raise DbError(p.dataProvider().error().summary(), sql)
        else:
            header = [f.name() for f in p.fields()]
            has_geometry = False
            if p.geometryType() != QGis.WKBNoGeometry:
                gn = getQueryGeometryName(tmp)
                if gn:
                    has_geometry = True
                    header += [gn]

            data = []
            for f in p.getFeatures():
                a = f.attributes()
                if has_geometry:
                    if f.geometry():
                        a += [f.geometry().exportToWkt()]
                    else:
                        a += [None]
                data += [a]

        self._secs = 0
        self._affectedRows = len(data)

        BaseTableModel.__init__(self, header, data, parent)
Exemple #30
0
    def test_sql5(self):
        l2 = QgsVectorLayer(
            os.path.join(self.testDataDir_, "france_parts.shp"),
            "france_parts", "ogr", False)
        self.assertEqual(l2.isValid(), True)
        QgsMapLayerRegistry.instance().addMapLayer(l2)

        query = QUrl.toPercentEncoding(
            "SELECT st_union(geometry) as geom from france_parts")
        l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual", False)
        self.assertEqual(l4.isValid(), True)
        #        self.assertEqual( l4.dataProvider().geometryType(), 3 )
        #self.assertEqual( l4.geometryType(), 2 )

        query = QUrl.toPercentEncoding(
            "SELECT st_collect(geometry) as geom from france_parts")
        l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual", False)
        self.assertEqual(l4.isValid(), True)
        self.assertEqual(l4.dataProvider().geometryType(), 0)
        self.assertEqual(l4.geometryType(), 3)  # unknown geometry
 def is_valid_polygon_selection(layer: QgsVectorLayer) -> bool:
     """"Checks if the layer type is polygon and if anything is selected."""
     if layer.geometryType() != QgsWkbTypes.PolygonGeometry:
         msg = QMessageBox()
         msg.setIcon(QMessageBox.Information)
         msg.setText("Unsupported layer type!")
         msg.setInformativeText("Please select polygon layer.")
         msg.setWindowTitle("Info")
         msg.setStandardButtons(QMessageBox.Ok)
         msg.exec_()
         return False
     if not layer.selectedFeatures():
         msg = QMessageBox()
         msg.setIcon(QMessageBox.Information)
         msg.setText("Please select at least one feature!")
         msg.setWindowTitle("Info")
         msg.setStandardButtons(QMessageBox.Ok)
         msg.exec_()
         return False
     return True
Exemple #32
0
    def __init__(self, db, sql, parent=None):
        # create a virtual layer with non-geometry results
        q = QUrl.toPercentEncoding(sql)
        t = QTime()
        t.start()

        tf = QTemporaryFile()
        tf.open()
        tmp = tf.fileName()
        tf.close()

        p = QgsVectorLayer("%s?query=%s" % (QUrl.fromLocalFile(tmp).toString(), q), "vv", "virtual")
        self._secs = t.elapsed() / 1000.0

        if not p.isValid():
            data = []
            header = []
            raise DbError(p.dataProvider().error().summary(), sql)
        else:
            header = [f.name() for f in p.fields()]
            has_geometry = False
            if p.geometryType() != QGis.WKBNoGeometry:
                gn = getQueryGeometryName(tmp)
                if gn:
                    has_geometry = True
                    header += [gn]

            data = []
            for f in p.getFeatures():
                a = f.attributes()
                if has_geometry:
                    if f.geometry():
                        a += [f.geometry().exportToWkt()]
                    else:
                        a += [None]
                data += [a]

        self._secs = 0
        self._affectedRows = len(data)

        BaseTableModel.__init__(self, header, data, parent)
 def load_zonal_layer(self, zonal_layer_path):
     # Load zonal layer
     zonal_layer = QgsVectorLayer(zonal_layer_path, tr('Zonal data'), 'ogr')
     if not zonal_layer.geometryType() == QGis.Polygon:
         msg = 'Zonal layer must contain zone polygons'
         self.iface.messageBar().pushMessage(
             tr("Error"),
             tr(msg),
             level=QgsMessageBar.CRITICAL)
         return False
     # Add zonal layer to registry
     if zonal_layer.isValid():
         QgsMapLayerRegistry.instance().addMapLayer(zonal_layer)
     else:
         msg = 'Invalid zonal layer'
         self.iface.messageBar().pushMessage(
             tr("Error"),
             tr(msg),
             level=QgsMessageBar.CRITICAL)
         return None
     return zonal_layer
 def load_zonal_layer(self, zonal_layer_path, make_a_copy=False):
     # Load zonal layer
     zonal_layer = QgsVectorLayer(zonal_layer_path, tr('Zonal data'), 'ogr')
     if not zonal_layer.geometryType() == QGis.Polygon:
         msg = 'Zonal layer must contain zone polygons'
         log_msg(msg, level='C', message_bar=self.iface.messageBar())
         return False
     if make_a_copy:
         # Make a copy, where stats will be added
         zonal_layer_plus_stats = ProcessLayer(
             zonal_layer).duplicate_in_memory()
     else:
         zonal_layer_plus_stats = zonal_layer
     # Add zonal layer to registry
     if zonal_layer_plus_stats.isValid():
         QgsMapLayerRegistry.instance().addMapLayer(zonal_layer_plus_stats)
     else:
         msg = 'Invalid zonal layer'
         log_msg(msg, level='C', message_bar=self.iface.messageBar())
         return None
     return zonal_layer_plus_stats
Exemple #35
0
def load_unloaded_data(project_path):

    operators_path = join(project_path, PROJECT_GROUP[2])
    try:
        operators_content = get_elements_name(operators_path, True, None)
    except FileNotFoundError:
        return
    qgis_groups = get_group()
    for i_op, item in enumerate(operators_content):
        # load vectors
        shp_path = join(operators_path, item, 'SHP')
        for shp_file in glob.glob(join(shp_path, '*.shp')):

            layer_name = basename(shp_file).replace(".shp", "")
            layer = QgsVectorLayer(shp_file, layer_name, "ogr")
            if layer.geometryType() == 1:
                try:
                    if layer_name not in get_layers_in_group(PROJECT_GROUP[2]):
                        add_layer_in_group(
                            layer, qgis_groups.findGroup(PROJECT_GROUP[2]),
                            i_op, 'line_style.qml')
                except TypeError:
                    return
            else:
                try:
                    if layer_name not in get_layers_in_group('BUF'):
                        add_layer_in_group(layer, qgis_groups.findGroup('BUF'),
                                           i_op, 'buffer_style.qml')
                except TypeError:
                    return

        # load raster
        tif_path = join(operators_path, item, 'TIF')
        for i_tif, tif_file in enumerate(glob.glob(join(tif_path, '*.tif'))):
            raster_name = basename(tif_file).replace(".tif", "")
            raster = QgsRasterLayer(tif_file, raster_name, 'gdal')
            if raster_name not in get_layers_in_group(item):
                add_layer_in_group(raster, qgis_groups.findGroup(item), i_tif,
                                   None)
    def sample_layer(self):
        source_layer = QgsVectorLayer(
            os.path.join(self.plugin_dir, "data", "Austria_PopulationByNUTS2.gml"),
            ""
        )

        # (empty) memory layer
        sample_layer = QgsVectorLayer(
            QgsWkbTypes.geometryDisplayString(source_layer.geometryType())
            + "?crs=" + source_layer.crs().authid()
            + "&index=yes",
            "Austria_Population_NUTS2_20170101",
            "memory"
        )
        sample_layer_data_provider = sample_layer.dataProvider()
        sample_layer_data_provider.addAttributes(source_layer.fields().toList())
        sample_layer.updateFields()
        sample_layer_data_provider.addFeatures(list(source_layer.getFeatures()))

        sample_layer.loadNamedStyle(
            os.path.join(self.plugin_dir, "data", "Austria_PopulationByNUTS2.qml")
        )

        sample_layer.setTitle("Austria: Population by NUTS2 regions, 1 Jan 2017")
        sample_layer.setShortName("Austria_Population_NUTS2_20170101")
        sample_layer.setAbstract(
            "Austria’s population by NUTS2 region, as of 1 Jan 2017 \n"
            + "\n"
            + "Data sources: \n"
            + "    http://ec.europa.eu/eurostat/web/gisco/geodata/"
            + "reference-data/administrative-units-statistical-units/"
            + "nuts#nuts13 \n"
            + "    http://www.statistik.at/web_de/statistiken/"
            + "menschen_und_gesellschaft/bevoelkerung/"
            + "bevoelkerungsstand_und_veraenderung/"
            + "bevoelkerung_zu_jahres-_quartalsanfang/index.html"
        )

        return sample_layer
Exemple #37
0
def checkShapefile(createDialog):
    shapefileOKBool = True
    if createDialog.puLineEdit.text() == '':
        warningMessage('Shapefile error', 'No shapefile was specified.')
        shapefileOKBool = False

    if shapefileOKBool:
        puLayer = QgsVectorLayer(createDialog.puLineEdit.text(), 'Shapefile', 'ogr')
        layerGeomType = puLayer.geometryType()
        puProvider = puLayer.dataProvider()
        puIdFieldOrder = puProvider.fieldNameIndex('Unit_ID')
        puCostFieldOrder = puProvider.fieldNameIndex('Area')
        puAreaFieldOrder = puProvider.fieldNameIndex('Cost')
        puStatusFieldOrder = puProvider.fieldNameIndex('Status')

        if layerGeomType != 2:
            warningMessage('Incorrect format', 'The specified shapefile is not a polygon layer.')
            shapefileOKBool = False

        if puIdFieldOrder != -1 or puCostFieldOrder != -1 or puAreaFieldOrder != -1 or puStatusFieldOrder != -1:
            warningMessage('Incorrect format', 'The specified shapefile cannot contain fields named Unit_ID, Area, Cost or Status as these will be created here. Please remove/rename these fields and try again.')
            shapefileOKBool = False

    return shapefileOKBool
Exemple #38
0
def addDiffLayer(repo, layername, commit):
    
    styles = [diffStylePoints, diffStyleLines, diffStylePolygons]
    geomTypes = ["Point","LineString","Polygon"]
    beforeFilename = tempFilename("gpkg")
    repo.exportdiff(layername, commit.commitid, commit.parent.commitid, beforeFilename)
    beforeLayer = loadLayerNoCrsDialog(beforeFilename, layername, "ogr")
    afterFilename = tempFilename("gpkg")
    repo.exportdiff(layername, commit.parent.commitid, commit.commitid, afterFilename)
    afterLayer = loadLayerNoCrsDialog(afterFilename, layername, "ogr")

    beforeCon = sqlite3.connect(beforeFilename)
    beforeCursor = beforeCon.cursor()
    afterCon = sqlite3.connect(afterFilename)
    afterCursor = afterCon.cursor()

    attributes = [v[1] for v in beforeCursor.execute("PRAGMA table_info('%s');" % layername)]
    attrnames = [f.name() for f in beforeLayer.pendingFields()]

    layerFeatures = []

    beforeCursor.execute("SELECT * FROM %s_changes WHERE audit_op=2;" % layername)
    modified = beforeCursor.fetchall()
    for m in modified:
        geogigfid = m[0]
        beforeGpkgfid = gpkgfidFromGeogigfid(beforeCursor, layername, geogigfid)
        beforeCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername, beforeGpkgfid))
        featureRow = beforeCursor.fetchone()
        attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames}
        attrs["changetype"] = MODIFIED_BEFORE
        request = QgsFeatureRequest()
        request.setFilterFid(beforeGpkgfid)
        feature = next(beforeLayer.getFeatures(request))
        layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())})
        afterGpkgfid = gpkgfidFromGeogigfid(afterCursor, layername, geogigfid)
        afterCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername,afterGpkgfid))
        featureRow = afterCursor.fetchone()
        attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames}
        attrs["changetype"] = MODIFIED_AFTER
        request = QgsFeatureRequest()
        request.setFilterFid(beforeGpkgfid)
        feature = next(afterLayer.getFeatures(request))
        layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())})


    afterCursor.execute("SELECT * FROM %s_changes WHERE audit_op=1;" % layername)
    added = afterCursor.fetchall()
    for a in added:
        geogigfid = a[0]
        afterGpkgfid = gpkgfidFromGeogigfid(afterCursor, layername, geogigfid)
        afterCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername, afterGpkgfid))
        featureRow = afterCursor.fetchone()
        attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames}
        attrs["changetype"] = ADDED
        request = QgsFeatureRequest()
        request.setFilterFid(afterGpkgfid)
        feature = next(afterLayer.getFeatures(request))
        layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())})

    beforeCursor.execute("SELECT * FROM %s_changes WHERE audit_op=1;" % layername)
    removed = beforeCursor.fetchall()
    for r in removed:
        geogigfid = r[0]
        beforeGpkgfid = gpkgfidFromGeogigfid(beforeCursor, layername, geogigfid)
        beforeCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername, beforeGpkgfid))
        featureRow = beforeCursor.fetchone()
        attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames}
        attrs["changetype"] = REMOVED
        request = QgsFeatureRequest()
        request.setFilterFid(beforeGpkgfid)
        feature = next(beforeLayer.getFeatures(request))
        layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())})

    attrnames.append("changetype")
    uriFields = "&".join(["field=%s" % f for f in attrnames])
    uri = "%s?crs=%s&%s" % (geomTypes[beforeLayer.geometryType()], beforeLayer.crs().authid(), uriFields)
    layer = QgsVectorLayer(uri, "diff", "memory")
    featuresList = []
    for feature in layerFeatures:
        qgsfeature = QgsFeature()
        qgsfeature.setGeometry(feature["geom"])
        qgsfeature.setAttributes([feature["attrs"][attr] for attr in attrnames])
        featuresList.append(qgsfeature)

    layer.dataProvider().addFeatures(featuresList)
    layer.updateExtents()
    QgsMapLayerRegistry.instance().addMapLayers([layer])
    layer.loadNamedStyle(styles[layer.geometryType()])
def addDiffLayers(repo, commit, commit2, layernames):

    styles = [diffStylePoints, diffStyleLines, diffStylePolygons]
    geomTypes = ["Point","LineString","Polygon"]
    beforeFilename = tempFilename("gpkg")
    repo.exportdiff(commit.commitid, commit2.commitid, beforeFilename)
    afterFilename = tempFilename("gpkg")
    repo.exportdiff(commit2.commitid, commit.commitid, afterFilename)
    for layername in layernames:
        styles = [diffStylePoints, diffStyleLines, diffStylePolygons]
        geomTypes = ["Point","LineString","Polygon"]
        beforeLayer = loadLayerNoCrsDialog("%s|layername=%s" % (beforeFilename, layername), layername, "ogr")
        afterLayer = loadLayerNoCrsDialog("%s|layername=%s" % (afterFilename, layername), layername, "ogr")
        beforeCon = sqlite3.connect(beforeFilename)
        beforeCursor = beforeCon.cursor()
        afterCon = sqlite3.connect(afterFilename)
        afterCursor = afterCon.cursor()

        attributes = [v[1] for v in beforeCursor.execute("PRAGMA table_info('%s');" % layername)]
        attrnames = [f.name() for f in beforeLayer.pendingFields()]

        layerFeatures = []

        beforeCursor.execute("SELECT * FROM %s_changes WHERE audit_op=2;" % layername)
        modified = beforeCursor.fetchall()
        for m in modified:
            geogigfid = m[0]
            beforeGpkgfid = gpkgfidFromGeogigfid(beforeCursor, layername, geogigfid)
            beforeCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername, beforeGpkgfid))
            featureRow = beforeCursor.fetchone()
            attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames}
            attrs["changetype"] = MODIFIED_BEFORE
            request = QgsFeatureRequest()
            request.setFilterFid(beforeGpkgfid)
            feature = next(beforeLayer.getFeatures(request))
            layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())})
            afterGpkgfid = gpkgfidFromGeogigfid(afterCursor, layername, geogigfid)
            afterCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername,afterGpkgfid))
            featureRow = afterCursor.fetchone()
            attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames}
            attrs["changetype"] = MODIFIED_AFTER
            request = QgsFeatureRequest()
            request.setFilterFid(afterGpkgfid)
            feature = next(afterLayer.getFeatures(request))
            layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())})


        afterCursor.execute("SELECT * FROM %s_changes WHERE audit_op=1;" % layername)
        added = afterCursor.fetchall()
        for a in added:
            geogigfid = a[0]
            afterGpkgfid = gpkgfidFromGeogigfid(afterCursor, layername, geogigfid)
            afterCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername, afterGpkgfid))
            featureRow = afterCursor.fetchone()
            attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames}
            attrs["changetype"] = ADDED
            request = QgsFeatureRequest()
            request.setFilterFid(afterGpkgfid)
            feature = next(afterLayer.getFeatures(request))
            layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())})

        beforeCursor.execute("SELECT * FROM %s_changes WHERE audit_op=1;" % layername)
        removed = beforeCursor.fetchall()
        for r in removed:
            geogigfid = r[0]
            beforeGpkgfid = gpkgfidFromGeogigfid(beforeCursor, layername, geogigfid)
            beforeCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername, beforeGpkgfid))
            featureRow = beforeCursor.fetchone()
            attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames}
            attrs["changetype"] = REMOVED
            request = QgsFeatureRequest()
            request.setFilterFid(beforeGpkgfid)
            feature = next(beforeLayer.getFeatures(request))
            layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())})

        if layerFeatures:
            attrnames.append("changetype")
            uriFields = "&".join(["field=%s" % f for f in attrnames])
            uri = "%s?crs=%s&%s" % (geomTypes[beforeLayer.geometryType()], beforeLayer.crs().authid(), uriFields)
            layer = QgsVectorLayer(uri, "%s(diff)" % layername, "memory")
            featuresList = []
            for feature in layerFeatures:
                qgsfeature = QgsFeature()
                qgsfeature.setGeometry(feature["geom"])
                qgsfeature.setAttributes([feature["attrs"][attr] for attr in attrnames])
                featuresList.append(qgsfeature)

            layer.dataProvider().addFeatures(featuresList)
            layer.updateExtents()
            QgsMapLayerRegistry.instance().addMapLayers([layer])
            layer.loadNamedStyle(styles[layer.geometryType()])
    def cloneToMemory(self):
        curlayer = self.iface.mapCanvas().currentLayer()
        selectedFeatCount = curlayer.selectedFeatureCount()
        geo = QgsWkbTypes.displayString(
            curlayer.wkbType())  # wkbType string name of geometry

        targetLayer = QgsVectorLayer(geo, self.dlg.lineEdit_2.text(), "memory")
        targetLayer.setCrs(curlayer.sourceCrs())
        QgsProject.instance().addMapLayer(targetLayer, False)
        root = QgsProject.instance().layerTreeRoot()

        self.setStyleLayer(targetLayer)

        if self.dlg.checkBoxAtrib.isChecked():  #copy attributes
            curlayer_attribute_list = curlayer.fields().toList()
            targetLayer_attribute_list = []
            targetLayerpr = targetLayer.dataProvider()

            for attrib in curlayer_attribute_list:
                if targetLayer.fields().lookupField(attrib.name()) == -1:
                    targetLayer_attribute_list.append(
                        QgsField(attrib.name(), attrib.type()))
            with edit(targetLayer):
                for attr in targetLayer_attribute_list:
                    if attr.type(
                    ) == 1:  # иначе игнорируется поле с типом 1 (bool)
                        attr = QgsField(
                            attr.name(),
                            QVariant.String)  # конвертируем bool в string
                    res_add = targetLayer.addAttribute(attr)
                    if not res_add:
                        print(u'Не создано поле {}'.format(attr.name()))
            targetLayer.updateFields()

        # for feat in curlayer.selectedFeatures(): # not work more
        #     targetLayer.dataProvider().addFeatures([feat]) # not work more

        # ИЗ МОДУЛЯ Apend Features To layer -----------------------------------------------
        # В старом варианте в QGIS3 при добавлении объектов с отличающимся набором аттрибутов
        # происходила задержка с выводом сообщений в логи. Что затягивало процесс.
        mapping = dict()
        for target_idx in targetLayer.fields().allAttributesList():
            target_field = targetLayer.fields().field(target_idx)
            source_idx = curlayer.fields().indexOf(target_field.name())
            if source_idx != -1:
                mapping[target_idx] = source_idx

        features = curlayer.selectedFeatures()
        destType = targetLayer.geometryType()
        destIsMulti = QgsWkbTypes.isMultiType(targetLayer.wkbType())
        new_features = []

        for current, in_feature in enumerate(features):
            attrs = {
                target_idx: in_feature[source_idx]
                for target_idx, source_idx in mapping.items()
            }
            geom = QgsGeometry()
            if in_feature.hasGeometry() and targetLayer.isSpatial():
                # Convert geometry to match destination layer
                # Adapted from QGIS qgisapp.cpp, pasteFromClipboard()
                geom = in_feature.geometry()
                if destType != QgsWkbTypes.UnknownGeometry:
                    newGeometry = geom.convertToType(destType, destIsMulti)
                    if newGeometry.isNull():
                        continue
                    geom = newGeometry
                # Avoid intersection if enabled in digitize settings
                geom.avoidIntersections(
                    QgsProject.instance().avoidIntersectionsLayers())

            new_feature = QgsVectorLayerUtils().createFeature(
                targetLayer, geom, attrs)
            new_features.append(new_feature)

        with edit(targetLayer):
            res = targetLayer.addFeatures(new_features)
        # ИЗ МОДУЛЯ Apend Features To layer -----------------------------------------------end

        root.insertLayer(0, targetLayer)
        self.iface.messageBar().clearWidgets()
        self.iface.setActiveLayer(targetLayer)
        curlayer.selectByIds([])

        if res:
            self.iface.messageBar().pushMessage(
                u"Выполнено",
                u"Склонировано {0}/{1} объектов".format(
                    len(new_features), selectedFeatCount),
                duration=5,
                level=0)
Exemple #41
0
    def showRequestResult(self, items, append, last, message):
        # print("showRequestResult")
        if items is None or len(items) == 0:
            QApplication.restoreOverrideCursor()
            self.__show_status_label(StatusMessageType.LOAD_FINISHED)
            self.getDataButton.setEnabled(True)

            if message is None or len(message) == 0:
                message = "По указанным параметрам ничего не найдено"

            self._show_message(self, "Загузка завершена", message)
            return

        color = QColor(237, 28, 36, 200)
        pjt = QgsProject.instance()
        layersList = pjt.mapLayersByName(self.resultsLayerName)

        if not append:
            if layersList is not None and len(layersList) > 0:
                pjt.removeMapLayer(layersList[0])
                # print("remove results")
            layersList.clear()
        if not append or layersList is None or len(layersList) == 0:
            # print("create layer")
            layer = QgsVectorLayer("Point?crs=EPSG:4326"
                                   "&field=coordinatesWKT:string(255)&field=shootingDateTime:string(255)"
                                   "&field=temperature:double(7)&field=pixelSizeInDirection:double(5)"
                                   "&field=pixelSizeAcross:double(5)&field=thermalPower:double(5)"
                                   "&field=baseResourceId:string(255)&field=id:string(255)&field=updated:string(255)"
                                   "&field=satellite:string(10)",
                                   self.resultsLayerName, "memory")
        else:
            layer = layersList[0]

        symbol = QgsSymbol.defaultSymbol(layer.geometryType())
        svg_marker = QgsSvgMarkerSymbolLayer(":/plugins/thermal_anomaly/fire.svg")
        svg_marker.setSize(6.0)
        symbol.changeSymbolLayer(0, svg_marker)
        layer.renderer().setSymbol(symbol)

        layer.startEditing()
        print("all items=", len(items))
        poly = QgsGeometry.fromWkt(self.polygon)

        for point in items:
            symbols = layer.renderer().symbols(QgsRenderContext())  # todo which context ?
            symbols[0].setColor(color)
            feature = QgsFeature()
            coord = QgsGeometry.fromWkt(point["coordinatesWKT"])
            feature.setGeometry(coord)
            feature.setAttributes([point["coordinatesWKT"], point["shootingDateTime"], point["temperature"],
                                   point["pixelSizeInDirection"], point["pixelSizeAcross"], point["thermalPower"],
                                   point["baseResourceId"], point["id"], point["updated"], point["satellite"]])
            layer.dataProvider().addFeatures([feature])

            # if not poly.contains(coord):
            #     print("point out of poly: id =", point["id"], "coord =", point["coordinatesWKT"])
        layer.commitChanges()

        if not append:
            pjt.addMapLayer(layer, False)
            if pjt.layerTreeRoot().findGroup(self.tr(self.groupName)) is None:
                pjt.layerTreeRoot().insertChildNode(0, QgsLayerTreeGroup(self.tr(self.groupName)))
            group = pjt.layerTreeRoot().findGroup(self.tr(self.groupName))
            group.insertLayer(0, layer)
        self.iface.layerTreeView().refreshLayerSymbology(layer.id())
        self.iface.mapCanvas().refresh()
        if last:
            QApplication.restoreOverrideCursor()
            self.__show_status_label(StatusMessageType.LOAD_FINISHED)
            self.getDataButton.setEnabled(True)
        else:
            self.__show_status_label(StatusMessageType.LOAD_STARTED, message)
Exemple #42
0
    def delimitedTextData(self, testname, filename, requests, verbose, **params):
        # Retrieve the data for a delimited text url
        # Create a layer for the specified file and query parameters
        # and return the data for the layer (fields, data)

        filepath = os.path.join(unitTestDataPath("delimitedtext"), filename)
        url = MyUrl.fromLocalFile(filepath)
        if not requests:
            requests = [{}]
        for k in list(params.keys()):
            url.addQueryItem(k, params[k])
        urlstr = url.toString()
        log = []
        with MessageLogger('DelimitedText') as logger:
            if verbose:
                print(testname)
            layer = QgsVectorLayer(urlstr, 'test', 'delimitedtext')
            uri = layer.dataProvider().dataSourceUri()
            if verbose:
                print(uri)
            basename = os.path.basename(filepath)
            if not basename.startswith('test'):
                basename = 'file'
            uri = re.sub(r'^file\:\/\/[^\?]*', 'file://' + basename, uri)
            fields = []
            fieldTypes = []
            data = {}
            if layer.isValid():
                for nr, r in enumerate(requests):
                    if verbose:
                        print(("Processing request", nr + 1, repr(r)))
                    if isinstance(r, collections.Callable):
                        r(layer)
                        if verbose:
                            print("Request function executed")
                    if isinstance(r, collections.Callable):
                        continue
                    rfields, rtypes, rdata = self.layerData(layer, r, nr * 1000)
                    if len(rfields) > len(fields):
                        fields = rfields
                        fieldTypes = rtypes
                    data.update(rdata)
                    if not rdata:
                        log.append("Request " + str(nr) + " did not return any data")
                    if verbose:
                        print(("Request returned", len(list(rdata.keys())), "features"))
            for msg in logger.messages():
                filelogname = 'temp_file' if 'tmp' in filename.lower() else filename
                msg = re.sub(r'file\s+.*' + re.escape(filename), 'file ' + filelogname, msg)
                msg = msg.replace(filepath, filelogname)
                log.append(msg)
            return dict(fields=fields, fieldTypes=fieldTypes, data=data, log=log, uri=uri, geometryType=layer.geometryType())
class MissionTrack(QObject):
    mission_changed = pyqtSignal(int)
    step_removed = pyqtSignal(int)

    def __init__(self,
                 mission_name="Mission",
                 mission_filename=None,
                 mission_layer=None,
                 mission_renderer=None,
                 canvas=None):
        super(MissionTrack, self).__init__()
        self.mission_filename = mission_filename
        self.mission_name = mission_name
        self.mission_layer = mission_layer
        self.mission_renderer = mission_renderer
        self.mission = Mission()
        self.canvas = canvas
        self.start_end_marker = StartEndMarker(
            canvas, self.find_waypoints_in_mission(), QColor(200, 0, 0))

        self.saved = False
        self.modified = False

    def is_saved(self):
        """
        :return: return True if mission is saved,  otherwise False
        """
        return self.saved

    def is_modified(self):
        """
        :return: return True if mission is modified,  otherwise False
        """
        return self.modified

    def set_modified(self, modified):
        """ Set modified state"""
        self.modified = modified

    def load_mission(self, filename):
        """ Load mission with name 'filename'"""
        try:
            self.mission.load_mission(filename)
            self.mission_filename = filename
            self.update_start_end_markers()
            self.saved = True
            self.modifed = False
        except:
            logger.error("Invalid mission file")
            raise Exception("Invalid mission file")

    def set_mission(self, mission):
        """ Set Mission."""
        self.mission = mission

    def set_mission_filename(self, filename):
        """ Set Mission Filename"""
        self.mission_filename = filename

    def set_mission_name(self, name):
        """ Set Mission name."""
        self.mission_name = name

    def set_mission_layer(self, layer):
        """ Set mission layer."""
        self.mission_layer.name = self.mission_name
        self.mission_layer = layer

    def set_mission_renderer(self, renderer):
        """ Set mission renderer."""
        self.mission_renderer = renderer
        self.mission_layer.setRenderer(self.mission_renderer)

    def get_mission(self):
        """ Returns the mission"""
        return self.mission

    def get_step(self, step):
        """ Returns the step 'step' of the mission"""
        return self.mission.get_step(step)

    def get_mission_length(self):
        """ Returns mission length"""
        return self.mission.num_steps

    def get_mission_layer(self):
        """ Returns mission layer"""
        return self.mission_layer

    def get_mission_name(self):
        """ Returns mission name"""
        return self.mission_name

    def get_mission_filename(self):
        """ Returns mission filename"""
        return self.mission_filename

    def copy_mission(self):
        """ Returns a copy of the current mission"""
        return copy.deepcopy(self.mission)

    def change_position(self, wp_id, point):
        """
        Changes a position of the waypoint 'wp_id' with a new position 'point'
        :param wp_id: Current step
        :param point: Point position
        """
        position = self.mission.get_step(wp_id).get_maneuver().get_position()
        position.set_lat_lon(point.y(), point.x())
        if wp_id != self.mission.get_length() - 1:  # not last point
            if self.mission.get_step(
                    wp_id +
                    1).get_maneuver().get_maneuver_type() == SECTION_MANEUVER:
                logger.debug("Next step is a section")
                # if next step is a section change its initial position
                position_next = self.mission.get_step(
                    wp_id + 1).get_maneuver().get_initial_position()
                position_next.set_lat_lon(point.y(), point.x())
        self.mission_changed.emit(wp_id)
        self.update_start_end_markers()
        self.modified = True

    def remove_step(self, wp_id):
        """
        Remove step 'wp_id'
        :param wp_id: the step number to delete
        """
        initial_num_steps = self.mission.num_steps
        # if is first point and next waypoint is a Section, show warning message
        if (wp_id == 0 and initial_num_steps > 1 and
                self.mission.get_step(wp_id +
                                      1).get_maneuver().get_maneuver_type()
                == SECTION_MANEUVER):
            reply = QMessageBox.warning(
                None, "Mission Error",
                "Impossible to remove the point because the next point is a section"
            )

        else:

            if (initial_num_steps - 1 != wp_id
                    and self.mission.get_step(wp_id + 1).get_maneuver(
                    ).get_maneuver_type() == SECTION_MANEUVER):
                logger.debug("Next step is a section")
                # if it's not the last step
                # if next step is a section change its initial position to the one of the point before
                position_previous = self.mission.get_step(
                    wp_id - 1).get_maneuver().get_position()
                position_next = self.mission.get_step(
                    wp_id + 1).get_maneuver().get_initial_position()
                position_next.set_lat_lon(position_previous.latitude,
                                          position_previous.longitude)

            self.mission.remove_step(wp_id)
            self.step_removed.emit(wp_id)

            # When point is deleted, layer may need a geometry type change
            if initial_num_steps <= 2:
                self.update_layer_geometry()

            if wp_id == initial_num_steps - 1:
                # if last waypoint is removed show previous
                self.mission_changed.emit(wp_id - 1)
            else:
                self.mission_changed.emit(wp_id)

            self.update_start_end_markers()

            self.modified = True

    def update_steps(self, id_list, mission_step_list):
        """
        Update the number of the step 'wp_id' with new number 'step'
        :param id_list: list of step ids to update
        :param mission_step_list: list of mission steps to update
        :return:
        """
        if len(id_list) > 0:
            for i in range(0, len(id_list)):
                self.mission.update_step(id_list[i], mission_step_list[i])
            self.mission_changed.emit(id_list[0])
            self.update_start_end_markers()
            self.modified = True

    def add_step(self, wp_id, point):
        """ Add new step"""
        initial_num_steps = self.mission.num_steps
        logger.debug("Add step: Mission has {} steps and wp_id is {}".format(
            initial_num_steps, wp_id))
        step = MissionStep()
        position = MissionPosition()
        tolerance = MissionTolerance()
        # If more than one point, get maneuver from surrounding waypoint and copy data
        if initial_num_steps > 0:
            if wp_id != 0:

                # if point is at the end or in the middle copy from the previous
                manv_to_copy = self.mission.get_step(wp_id - 1).get_maneuver()

                if manv_to_copy.get_maneuver_type() == SECTION_MANEUVER:
                    # if section, initial pos will be the final pos of the previous
                    manv = MissionSection()
                    position.copy(manv_to_copy.get_position())
                    tolerance.copy(manv_to_copy.get_tolerance())
                    manv.set(manv_to_copy.get_final_position(), position,
                             manv_to_copy.get_speed(), tolerance)
                    manv.get_final_position().set_lat_lon(point.y(), point.x())

                if wp_id != initial_num_steps:
                    # if point in the middle check if next is also section, we need to modify it
                    manv_next = self.mission.get_step(wp_id).get_maneuver()
                    if manv_next.get_maneuver_type() == SECTION_MANEUVER:
                        manv_next.get_initial_position().set_lat_lon(
                            point.y(), point.x())

            else:  # wp_id == 0
                # copy from the next wp, next cannot be a section if was first waypoint until now, so no need to check
                manv_to_copy = self.mission.get_step(wp_id).get_maneuver()

            if manv_to_copy.get_maneuver_type() == WAYPOINT_MANEUVER:
                manv = MissionWaypoint()
                position.copy(manv_to_copy.get_position())
                tolerance.copy(manv_to_copy.get_tolerance())
                manv.set(position, manv_to_copy.get_speed(), tolerance)
                manv.get_position().set_lat_lon(point.y(), point.x())

            elif manv_to_copy.get_maneuver_type() == PARK_MANEUVER:
                manv = MissionPark()
                position.copy(manv_to_copy.get_position())
                tolerance.copy(manv_to_copy.get_tolerance())
                manv.set(position, manv_to_copy.get_speed(),
                         manv_to_copy.get_time(), tolerance)
                manv.get_position().set_lat_lon(point.y(), point.x())

        else:
            # is first point of the mission, fill maneuver by default type waypoint with clicked position
            manv = MissionWaypoint(
                MissionPosition(point.y(), point.x(), 0.0, False), 0.5,
                MissionTolerance(
                    2.0, 2.0,
                    1.0))  # todo: define default z, mode, speed and tolerance

        step.add_maneuver(manv)

        self.mission.insert_step(wp_id, step)
        logger.debug("Mission has now {} steps".format(self.mission.num_steps))

        # When point is added, layer may need a geometry type change
        if initial_num_steps <= 1:
            self.update_layer_geometry()

        self.mission_changed.emit(wp_id)
        self.update_start_end_markers()
        self.modified = True

    def save_mission(self):
        """ Saves a mission"""
        if self.mission.num_steps == 0:
            reply = QMessageBox.question(
                None, "Save Mission",
                "You are about to save an empty mission. Do you want to proceed?",
                QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
            if reply == QMessageBox.No:
                return False
        elif float(
                self.mission.get_step(self.mission.get_length() - 1).
                get_maneuver().get_position().get_z()) != 0.0:
            # vehicle last waypoint is not at zero depth.
            reply = QMessageBox.question(
                None, "Save Mission",
                "You are about to save and the last waypoint is not at zero depth. "
                "Do you want to proceed?", QMessageBox.Yes | QMessageBox.No,
                QMessageBox.Yes)
            if reply == QMessageBox.No:
                return False

        logger.info("Saving mission to {}".format(self.mission_filename))
        self.mission.write_mission(self.mission_filename)
        self.mission_layer.setCustomProperty("mission_xml",
                                             self.mission_filename)
        self.saved = True
        self.modified = False
        return True

    def saveas_mission(self):
        """ Save a mission with new name"""
        if self.mission.num_steps == 0:
            reply = QMessageBox.question(
                None, "Save Mission",
                "You are about to save an empty mission. Do you want to proceed?",
                QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
            if reply == QMessageBox.No:
                return False, None
        elif float(
                self.mission.get_step(self.mission.get_length() - 1).
                get_maneuver().get_position().get_z()) != 0.0:
            # vehicle last waypoint is not at zero depth.
            reply = QMessageBox.question(
                None, "Save Mission",
                "You are about to save and the last waypoint is not at zero depth. "
                "Do you want to proceed?", QMessageBox.Yes | QMessageBox.No,
                QMessageBox.Yes)
            if reply == QMessageBox.No:
                return False, None

        mission_filename, selected_filter = QFileDialog.getSaveFileName(
            None, 'Save mission', self.mission_filename, 'XML (*.xml)')

        if mission_filename != '':
            if selected_filter == "XML (*.xml)":
                file_info = QFileInfo(mission_filename)

                self.mission.write_mission(mission_filename)

                logger.debug(file_info.fileName())
                self.set_mission_name(file_info.fileName())
                self.set_mission_filename(mission_filename)
                self.mission_layer.setName(file_info.baseName())
                self.mission_layer.setCustomProperty("mission_xml",
                                                     self.mission_filename)

                self.saved = True
                self.modified = False

            return True, mission_filename

        else:
            return False, None

    def render_mission(self):
        """
        Render the mission, it will render the mission layer with Point geometry if it has only 1 point
        oterwise it will be with LineString geometry.
        """
        waypoints = self.find_waypoints_in_mission()
        if self.mission_layer is None:
            if len(waypoints) == 1:
                self.mission_layer = QgsVectorLayer("Point?crs=epsg:4326",
                                                    self.mission_name,
                                                    "memory")
                self.mission_layer.setCustomProperty("mission_xml",
                                                     self.mission_filename)
                feature = QgsFeature()
                feature.setGeometry(QgsGeometry(waypoints[0]))
                self.mission_layer.dataProvider().addFeatures([feature])
            else:
                self.mission_layer = QgsVectorLayer("LineString?crs=epsg:4326",
                                                    self.mission_name,
                                                    "memory")
                self.mission_layer.setCustomProperty("mission_xml",
                                                     self.mission_filename)
                feature = QgsFeature()
                feature.setGeometry(QgsGeometry.fromPolyline(waypoints))
                self.mission_layer.dataProvider().addFeatures([feature])

        else:
            # mission layer exists, now check if it has already a feature or not
            feats = self.mission_layer.getFeatures()
            logger.debug("layer feature count {}".format(
                self.mission_layer.featureCount()))
            if self.mission_layer.featureCount() == 0:
                feature = QgsFeature()
                if len(waypoints) == 1:
                    feature.setGeometry(QgsGeometry(waypoints[0]))
                else:
                    feature.setGeometry(QgsGeometry.fromPolyline(waypoints))
                self.mission_layer.dataProvider().addFeatures([feature])
            else:
                logger.debug("layer has feature mission already, updating...")
                for f in feats:
                    self.mission_layer.dataProvider().deleteFeatures([f.id()])
                    feature = QgsFeature()
                    if len(waypoints) == 1:
                        feature.setGeometry(QgsGeometry(waypoints[0]))
                    else:
                        feature.setGeometry(
                            QgsGeometry.fromPolyline(waypoints))
                    self.mission_layer.dataProvider().addFeatures([feature])

        self.set_mission_renderer(self.get_default_track_renderer())

    def find_waypoints_in_mission(self, indexes=None):
        """
        Gets all waypoints from a mission structure
        """
        waypoints = []
        if indexes is None:
            step_indexes = range(0, self.mission.size())
        else:
            step_indexes = indexes

        for stepindex in step_indexes:
            step = self.mission.get_step(stepindex)
            maneuver = step.get_maneuver()

            if maneuver.get_maneuver_type(
            ) == SECTION_MANEUVER:  # for a Section
                position = maneuver.get_final_position()
            else:
                position = maneuver.get_position()  # for Waypoint and Park

            waypoints.append(
                QgsPoint(float(position.longitude), float(position.latitude)))
        return waypoints

    def get_default_track_renderer(self):
        # Renderer for track lines
        registry = QgsSymbolLayerRegistry()
        line_meta = registry.symbolLayerMetadata("SimpleLine")
        marker_meta = registry.symbolLayerMetadata("MarkerLine")

        symbol = QgsSymbol.defaultSymbol(self.mission_layer.geometryType())

        # Line layer
        line_layer = line_meta.createSymbolLayer({
            'width': '0.5',
            'color': '255,0,0',
            'offset': '0.0',
            'penstyle': 'solid',
            'use_custom_dash': '0',
            'joinstyle': 'bevel',
            'capstyle': 'square'
        })

        # Marker layer
        marker_layer = marker_meta.createSymbolLayer({
            'width': '1.5',
            'color': '255,0,0',
            'placement': 'vertex',
            'offset': '0.0'
        })
        sub_symbol = marker_layer.subSymbol()

        # Replace the default layer with our own SimpleMarker
        sub_symbol.deleteSymbolLayer(0)
        cross = registry.symbolLayerMetadata("SimpleMarker").createSymbolLayer(
            {
                'name': 'circle',
                'color': '255,0,0',
                'color_border': '0,0,0',
                'offset': '0,0',
                'size': '2.5',
                'angle': '0'
            })
        sub_symbol.appendSymbolLayer(cross)

        # Replace the default layer with our two custom layers
        symbol.deleteSymbolLayer(0)
        symbol.appendSymbolLayer(line_layer)
        symbol.appendSymbolLayer(marker_layer)

        # Replace the renderer of the current layer
        renderer = QgsSingleSymbolRenderer(symbol)
        return renderer

    def update_start_end_markers(self):
        """ Updates start_end_markers"""
        self.start_end_marker.update_markers(self.find_waypoints_in_mission())

    def hide_start_end_markers(self):
        """ Hide start_end_markers"""
        self.start_end_marker.hide_markers()

    def remove_start_end_markers(self):
        """ Removes start end markers"""
        self.start_end_marker.close_markers()

    def update_layer_geometry(self):
        """
        This function needs to be called every time a point is added or deleted from the layer
        If needed, a new layer is created with the apropiate geometry
        Point if only one point, LineString otherwise
        """
        options = QgsDataProvider.ProviderOptions()
        waypoints = self.find_waypoints_in_mission()
        if (len(waypoints) != 1) and self.mission_layer.geometryType(
        ) == QgsWkbTypes.PointGeometry:
            self.mission_layer.setDataSource("LineString?crs=epsg:4326",
                                             self.mission_name, "memory",
                                             options)
            self.set_mission_renderer(self.get_default_track_renderer())
        elif len(waypoints) == 1 and self.mission_layer.geometryType(
        ) == QgsWkbTypes.LineGeometry:
            self.mission_layer.setDataSource("Point?crs=epsg:4326",
                                             self.mission_name, "memory",
                                             options)
            self.set_mission_renderer(self.get_default_track_renderer())
 def post_process_layer(self, layer: QgsVectorLayer, position: int):
     if layer.geometryType() == QgsWkbTypes.PointGeometry:
         for symbol in layer.renderer().symbols(self.layer_context(layer)):
             symbol.symbolLayer(0).setShape(
                 MARKER_SHAPE[position % (len(MARKER_SHAPE) - 1)])
Exemple #45
0
class CommonAutocorrelationDialog(QDialog):

    signalAskCloseWindow = pyqtSignal(int, name='signalAskCloseWindow')
    signalStatus = pyqtSignal(int, str, name='signalStatus')

    def __init__(self, parent=None):
        """Constructor.

        Base class for Incidence and Density dialogs.

        use_area : If you use the area of the polygon or the population field.
        use_point_layer : If you a point a layer, or a field in the polygon
         layer.
        """
        self.parent = parent
        QDialog.__init__(self, parent)
        self.name_field = None
        self.admin_layer = None
        self.figure = None
        self.canvas = None
        self.toolbar = None
        self.output_file_path = None
        self.output_layer = None

        # Settings
        self.use_area = None

    def setup_ui(self):
        # Connect slot.
        # noinspection PyUnresolvedReferences
        self.button_browse.clicked.connect(self.open_file_browser)

        self.button_box_ok.button(QDialogButtonBox.Ok).clicked.connect(
            self.run_stats)
        self.button_box_ok.button(QDialogButtonBox.Cancel).clicked.connect(
            self.hide)
        self.button_box_ok.button(QDialogButtonBox.Cancel).clicked.connect(
            self.signalAskCloseWindow.emit)

        self.cbx_aggregation_layer.setFilters(
            QgsMapLayerProxyModel.PolygonLayer)

        self.cbx_indicator_field.setFilters(QgsFieldProxyModel.Numeric)
        self.cbx_indicator_field.setLayer(
            self.cbx_aggregation_layer.currentLayer())
        self.cbx_aggregation_layer.layerChanged.connect(
            self.cbx_indicator_field.setLayer)

        self.lisa = {
            1: ("#b92815", "High - High"),
            2: ("#3f70df", "Low - High"),
            3: ("#aecbdd", "Low - Low"),
            4: ("#e79e2c", "High - Low")
        }

    def open_file_browser(self):
        output_file, __ = QFileDialog.getSaveFileName(self.parent,
                                                      tr('Save shapefile'),
                                                      filter='SHP (*.shp)')
        #Fix the filename bug
        self.le_output_filepath.setText(output_file)

    def run_stats(self):
        """Main function which do the process."""

        # Get the common fields..currentField()
        self.admin_layer = self.cbx_aggregation_layer.currentLayer()
        input_name = self.admin_layer.name()
        field = self.cbx_indicator_field.currentField()

        self.layer = QgsProject.instance().mapLayersByName(input_name)[0]
        # Output.
        self.output_file_path = self.le_output_filepath.text()

        try:
            self.button_box_ok.setDisabled(True)
            # noinspection PyArgumentList
            QApplication.setOverrideCursor(Qt.WaitCursor)
            # noinspection PyArgumentList
            QApplication.processEvents()

            if not self.admin_layer:
                raise NoLayerProvidedException

            if not self.admin_layer and self.use_point_layer:
                raise NoLayerProvidedException

            crs_admin_layer = self.admin_layer.crs()

            # Output
            if not self.output_file_path:
                temp_file = NamedTemporaryFile(delete=False,
                                               suffix='-geopublichealth.shp')
                self.output_file_path = temp_file.name
                temp_file.flush()
                temp_file.close()
            else:
                with open(self.output_file_path, 'w') as document:
                    pass

            admin_layer_provider = self.layer.dataProvider()
            fields = admin_layer_provider.fields()

            if admin_layer_provider.fields().indexFromName(
                    self.name_field) != -1:
                raise FieldExistingException(field=self.name_field)

            fields.append(QgsField('LISA_P', QVariant.Double))
            fields.append(QgsField('LISA_Z', QVariant.Double))
            fields.append(QgsField('LISA_Q', QVariant.Int))
            fields.append(QgsField('LISA_I', QVariant.Double))
            fields.append(QgsField('LISA_C', QVariant.Double))

            # The QgsVectorFileWriter was Deprecated since 3.10 However,.......
            #The create() function DOEST NOT Flush the feature unless QGIS close.
            #options = QgsVectorFileWriter.SaveVectorOptions()
            #options.driverName = "ESRI Shapefile"
            #file_writer=QgsVectorFileWriter.create(self.output_file_path,fields,QgsWkbTypes.Polygon,self.admin_layer.crs(),QgsCoordinateTransformContext(),options)

            #It's currently a bug https://github.com/qgis/QGIS/issues/35021
            # So I will keep it for now

            file_writer = QgsVectorFileWriter(self.output_file_path, 'utf-8',
                                              fields, QgsWkbTypes.Polygon,
                                              self.admin_layer.crs(),
                                              'ESRI Shapefile')

            if self.cbx_contiguity.currentIndex() == 0:  # queen
                # fix_print_with_import

                print('Info: Local Moran\'s using queen contiguity')
                #Pysal 2.0 change
                #https://github.com/pysal/pysal/blob/master/MIGRATING.md

                w = Queen.from_shapefile(self.admin_layer.source())
            else:  # 1 for rook
                # fix_print_with_import
                print('Info: Local Moran\'s using rook contiguity')
                w = Rook.from_shapefile(self.admin_layer.source())

            #Pysal 2.0
            #https://stackoverflow.com/questions/59455383/pysal-does-not-have-attribute-open
            import geopandas

            f = geopandas.read_file(self.admin_layer.source().replace(
                '.shp', '.dbf'))

            y = f[str(field)]
            lm = Moran_Local(y, w, transformation="r", permutations=999)

            sig_q = lm.q * (lm.p_sim <= 0.05
                            )  # could make significance level an option
            outFeat = QgsFeature()
            i = 0

            count = self.admin_layer.featureCount()

            for i, feature in enumerate(self.admin_layer.getFeatures()):
                attributes = feature.attributes()
                attributes.append(float(lm.p_sim[i]))
                attributes.append(float(lm.z_sim[i]))
                attributes.append(int(lm.q[i]))
                attributes.append(float(lm.Is[i]))
                attributes.append(int(sig_q[i]))

                new_feature = QgsFeature()
                new_geom = QgsGeometry(feature.geometry())
                new_feature.setAttributes(attributes)
                new_feature.setGeometry(new_geom)
                file_writer.addFeature(new_feature)

            del file_writer

            self.output_layer = QgsVectorLayer(self.output_file_path,
                                               "LISA Moran's I - " + field,
                                               'ogr')
            QgsProject.instance().addMapLayer(self.output_layer)

            self.add_symbology()

            self.signalStatus.emit(3, tr('Successful process'))

        except GeoPublicHealthException as e:
            display_message_bar(msg=e.msg, level=e.level, duration=e.duration)

        finally:
            self.button_box_ok.setDisabled(False)
            # noinspection PyArgumentList
            QApplication.restoreOverrideCursor()
            # noinspection PyArgumentList
            QApplication.processEvents()

    def add_symbology(self):
        categories = []
        for lisaCategory, (color, label) in list(self.lisa.items()):
            sym = QgsSymbol.defaultSymbol(self.output_layer.geometryType())
            sym.setColor(QColor(color))
            category = QgsRendererCategory(lisaCategory, sym, label)
            categories.append(category)

        self.newlayer = QgsVectorLayer(
            self.output_layer.source(),
            self.output_layer.name() + " significance test",
            self.output_layer.providerType())
        self.output_layer.setOpacity(0.4)
        QgsProject.instance().addMapLayer(self.newlayer)

        # noinspection PyArgumentList
        renderer = QgsCategorizedSymbolRenderer('LISA_Q', categories)

        self.output_layer.setRenderer(renderer)

        symbol = QgsSymbol.defaultSymbol(
            QgsWkbTypes.geometryType(QgsWkbTypes.Polygon))

        color_ramp = QgsGradientColorRamp(QColor(0, 0, 0), QColor(255, 0, 0))
        # noinspection PyArgumentList

        renderer = QgsGraduatedSymbolRenderer.createRenderer(
            self.newlayer, 'LISA_C', 4, QgsGraduatedSymbolRenderer.Jenks,
            symbol, color_ramp)

        self.newlayer.setRenderer(renderer)
        #The input val of seOPacity is 0-1 not 0-100 as setLyerTransvarency
        #https://gis.stackexchange.com/questions/150858/setting-transparency-of-layer-group-with-python-in-qgis
        self.newlayer.setOpacity(0.4)
Exemple #46
0
def load_path_vector_layer(path, **kwargs):
    """Return the test vector layer.

    :param path: Path to the vector layer.
    :type path: str

    :param kwargs: It can be :
        clone=True if you want to copy the layer first to a temporary file.

        clone_to_memory=True if you want to create a memory layer.

        with_keywords=False if you do not want keywords. "clone_to_memory" is
            required.

    :type kwargs: dict

    :return: The vector layer.
    :rtype: QgsVectorLayer

    .. versionadded:: 4.0
    """
    if not exists(path):
        raise Exception('%s do not exist.' % path)

    path = os.path.normcase(os.path.abspath(path))
    name = splitext(basename(path))[0]
    extension = splitext(path)[1]

    extensions = [
        '.shp', '.shx', '.dbf', '.prj', '.gpkg', '.geojson', '.xml', '.qml'
    ]

    if kwargs.get('with_keywords'):
        if not kwargs.get('clone_to_memory'):
            raise Exception('with_keywords needs a clone_to_memory')

    if kwargs.get('clone', False):
        target_directory = mkdtemp()
        current_path = splitext(path)[0]
        path = join(target_directory, name + extension)

        for ext in extensions:
            src_path = current_path + ext
            if exists(src_path):
                target_path = join(target_directory, name + ext)
                shutil.copy2(src_path, target_path)

    if path.endswith('.csv'):
        # Explicitly use URI with delimiter or tests fail in Windows. TS.
        uri = 'file:///%s?delimiter=%s' % (path, ',')
        layer = QgsVectorLayer(uri, name, 'delimitedtext')
    else:
        layer = QgsVectorLayer(path, name, 'ogr')

    if not layer.isValid():
        raise Exception('%s is not a valid layer.' % name)

    monkey_patch_keywords(layer)

    if kwargs.get('clone_to_memory', False):
        keywords = layer.keywords.copy()
        memory_layer = create_memory_layer(name, layer.geometryType(),
                                           layer.crs(), layer.fields())
        copy_layer(layer, memory_layer)
        if kwargs.get('with_keywords', True):
            memory_layer.keywords = keywords
        return memory_layer
    else:
        return layer
    def delimitedTextData(self, testname, filename, requests, verbose, **params):
        # Retrieve the data for a delimited text url
        # Create a layer for the specified file and query parameters
        # and return the data for the layer (fields, data)

        filepath = os.path.join(unitTestDataPath("delimitedtext"), filename)
        url = MyUrl.fromLocalFile(filepath)
        if not requests:
            requests = [{}]
        for k in list(params.keys()):
            url.addQueryItem(k, params[k])
        urlstr = url.toString()
        log = []
        with MessageLogger('DelimitedText') as logger:
            if verbose:
                print(testname)
            layer = QgsVectorLayer(urlstr, 'test', 'delimitedtext')
            uri = layer.dataProvider().dataSourceUri()
            if verbose:
                print(uri)
            basename = os.path.basename(filepath)
            if not basename.startswith('test'):
                basename = 'file'
            uri = re.sub(r'^file\:\/\/[^\?]*', 'file://' + basename, uri)
            fields = []
            fieldTypes = []
            data = {}
            if layer.isValid():
                for nr, r in enumerate(requests):
                    if verbose:
                        print(("Processing request", nr + 1, repr(r)))
                    if isinstance(r, collections.Callable):
                        r(layer)
                        if verbose:
                            print("Request function executed")
                    if isinstance(r, collections.Callable):
                        continue
                    rfields, rtypes, rdata = self.layerData(layer, r, nr * 1000)
                    if len(rfields) > len(fields):
                        fields = rfields
                        fieldTypes = rtypes
                    data.update(rdata)
                    if not rdata:
                        log.append("Request " + str(nr) + " did not return any data")
                    if verbose:
                        print(("Request returned", len(list(rdata.keys())), "features"))
            for msg in logger.messages():
                filelogname = 'temp_file' if 'tmp' in filename.lower() else filename
                msg = re.sub(r'file\s+.*' + re.escape(filename), 'file ' + filelogname, msg)
                msg = msg.replace(filepath, filelogname)
                log.append(msg)
            return dict(fields=fields, fieldTypes=fieldTypes, data=data, log=log, uri=uri, geometryType=layer.geometryType())
class LoadOutputAsLayerDialog(QDialog, FORM_CLASS):
    """
    Modal dialog to load an oq-engine output as layer
    """
    def __init__(self,
                 iface,
                 viewer_dock,
                 session,
                 hostname,
                 calc_id,
                 output_type=None,
                 path=None,
                 mode=None,
                 zonal_layer_path=None,
                 engine_version=None):
        # sanity check
        if output_type not in OQ_TO_LAYER_TYPES:
            raise NotImplementedError(output_type)
        self.iface = iface
        self.viewer_dock = viewer_dock
        self.path = path
        self.session = session
        self.hostname = hostname
        self.calc_id = calc_id
        self.output_type = output_type
        self.mode = mode  # if 'testing' it will avoid some user interaction
        self.zonal_layer_path = zonal_layer_path
        self.engine_version = engine_version
        QDialog.__init__(self)
        # Set up the user interface from Designer.
        self.setupUi(self)
        # Disable ok_button until all user options are set
        self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok)
        self.ok_button.setDisabled(True)

    def create_file_hlayout(self):
        self.file_hlayout = QHBoxLayout()
        self.file_lbl = QLabel('File to load')
        self.file_browser_tbn = QToolButton()
        self.file_browser_tbn.setText('...')
        self.file_browser_tbn.clicked.connect(self.on_file_browser_tbn_clicked)
        self.path_le = QLineEdit()
        self.path_le.setEnabled(False)
        self.file_hlayout.addWidget(self.file_lbl)
        self.file_hlayout.addWidget(self.file_browser_tbn)
        self.file_hlayout.addWidget(self.path_le)
        self.vlayout.addLayout(self.file_hlayout)

    def create_num_sites_indicator(self):
        self.num_sites_msg = 'Number of sites: %s'
        self.num_sites_lbl = QLabel(self.num_sites_msg % '')
        self.vlayout.addWidget(self.num_sites_lbl)

    def create_file_size_indicator(self):
        self.file_size_msg = 'File size: %s'
        self.file_size_lbl = QLabel(self.file_size_msg % '')
        self.vlayout.addWidget(self.file_size_lbl)

    def create_rlz_or_stat_selector(self, label='Realization'):
        self.rlz_or_stat_lbl = QLabel(label)
        self.rlz_or_stat_cbx = QComboBox()
        self.rlz_or_stat_cbx.setEnabled(False)
        self.rlz_or_stat_cbx.currentIndexChanged['QString'].connect(
            self.on_rlz_or_stat_changed)
        self.vlayout.addWidget(self.rlz_or_stat_lbl)
        self.vlayout.addWidget(self.rlz_or_stat_cbx)

    def create_imt_selector(self):
        self.imt_lbl = QLabel('Intensity Measure Type')
        self.imt_cbx = QComboBox()
        self.imt_cbx.setEnabled(False)
        self.imt_cbx.currentIndexChanged['QString'].connect(
            self.on_imt_changed)
        self.vlayout.addWidget(self.imt_lbl)
        self.vlayout.addWidget(self.imt_cbx)

    def create_poe_selector(self):
        self.poe_lbl = QLabel('Probability of Exceedance')
        self.poe_cbx = QComboBox()
        self.poe_cbx.setEnabled(False)
        self.poe_cbx.currentIndexChanged['QString'].connect(
            self.on_poe_changed)
        self.vlayout.addWidget(self.poe_lbl)
        self.vlayout.addWidget(self.poe_cbx)

    def create_loss_type_selector(self):
        self.loss_type_lbl = QLabel('Loss Type')
        self.loss_type_cbx = QComboBox()
        self.loss_type_cbx.setEnabled(False)
        self.loss_type_cbx.currentIndexChanged['QString'].connect(
            self.on_loss_type_changed)
        self.vlayout.addWidget(self.loss_type_lbl)
        self.vlayout.addWidget(self.loss_type_cbx)

    def create_eid_selector(self):
        self.eid_lbl = QLabel('Event ID')
        self.eid_sbx = QSpinBox()
        self.eid_sbx.setEnabled(False)
        self.vlayout.addWidget(self.eid_lbl)
        self.vlayout.addWidget(self.eid_sbx)

    def create_dmg_state_selector(self):
        self.dmg_state_lbl = QLabel('Damage state')
        self.dmg_state_cbx = QComboBox()
        self.dmg_state_cbx.setEnabled(False)
        self.dmg_state_cbx.currentIndexChanged['QString'].connect(
            self.on_dmg_state_changed)
        self.vlayout.addWidget(self.dmg_state_lbl)
        self.vlayout.addWidget(self.dmg_state_cbx)

    def create_taxonomy_selector(self):
        self.taxonomy_lbl = QLabel('Taxonomy')
        self.taxonomy_cbx = QComboBox()
        self.taxonomy_cbx.setEnabled(False)
        self.vlayout.addWidget(self.taxonomy_lbl)
        self.vlayout.addWidget(self.taxonomy_cbx)

    def create_style_by_selector(self):
        self.style_by_lbl = QLabel('Style by')
        self.style_by_cbx = QComboBox()
        self.vlayout.addWidget(self.style_by_lbl)
        self.vlayout.addWidget(self.style_by_cbx)

    def create_load_selected_only_ckb(self):
        self.load_selected_only_ckb = QCheckBox("Load only the selected items")
        self.load_selected_only_ckb.setChecked(True)
        self.vlayout.addWidget(self.load_selected_only_ckb)

    def create_save_as_shp_ckb(self):
        self.save_as_shp_ckb = QCheckBox("Save the loaded layer as shapefile")
        self.save_as_shp_ckb.setChecked(False)
        self.vlayout.addWidget(self.save_as_shp_ckb)

    def create_zonal_layer_selector(self):
        self.zonal_layer_gbx = QGroupBox()
        self.zonal_layer_gbx.setTitle('Aggregate by zone (optional)')
        self.zonal_layer_gbx.setCheckable(True)
        self.zonal_layer_gbx.setChecked(False)
        self.zonal_layer_gbx_v_layout = QVBoxLayout()
        self.zonal_layer_gbx.setLayout(self.zonal_layer_gbx_v_layout)
        self.zonal_layer_cbx = QComboBox()
        self.zonal_layer_cbx.addItem('')
        self.zonal_layer_lbl = QLabel('Zonal layer')
        self.zonal_layer_tbn = QToolButton()
        self.zonal_layer_tbn.setText('...')
        self.zonal_layer_h_layout = QHBoxLayout()
        self.zonal_layer_h_layout.addWidget(self.zonal_layer_cbx)
        self.zonal_layer_h_layout.addWidget(self.zonal_layer_tbn)
        self.zonal_layer_gbx_v_layout.addWidget(self.zonal_layer_lbl)
        self.zonal_layer_gbx_v_layout.addLayout(self.zonal_layer_h_layout)
        self.zone_id_field_lbl = QLabel('Field containing zone ids')
        self.zone_id_field_cbx = QComboBox()
        self.zonal_layer_gbx_v_layout.addWidget(self.zone_id_field_lbl)
        self.zonal_layer_gbx_v_layout.addWidget(self.zone_id_field_cbx)
        self.vlayout.addWidget(self.zonal_layer_gbx)
        self.zonal_layer_tbn.clicked.connect(self.on_zonal_layer_tbn_clicked)
        self.zonal_layer_cbx.currentIndexChanged[int].connect(
            self.on_zonal_layer_cbx_currentIndexChanged)
        self.zonal_layer_gbx.toggled[bool].connect(
            self.on_zonal_layer_gbx_toggled)

    def pre_populate_zonal_layer_cbx(self):
        for key, layer in \
                QgsMapLayerRegistry.instance().mapLayers().iteritems():
            # populate loss cbx only with layers containing points
            if layer.type() != QgsMapLayer.VectorLayer:
                continue
            if layer.geometryType() == QGis.Polygon:
                self.zonal_layer_cbx.addItem(layer.name())
                self.zonal_layer_cbx.setItemData(
                    self.zonal_layer_cbx.count() - 1, layer.id())

    def on_zonal_layer_cbx_currentIndexChanged(self, new_index):
        self.zone_id_field_cbx.clear()
        zonal_layer = None
        if not self.zonal_layer_cbx.currentText():
            if self.zonal_layer_gbx.isChecked():
                self.ok_button.setEnabled(False)
            return
        zonal_layer_id = self.zonal_layer_cbx.itemData(new_index)
        zonal_layer = QgsMapLayerRegistry.instance().mapLayer(zonal_layer_id)
        # if the zonal_layer doesn't have a field containing a unique zone id,
        # the user can choose to add such unique id
        self.zone_id_field_cbx.addItem("Add field with unique zone id")
        for field in zonal_layer.fields():
            # for the zone id accept both numeric or textual fields
            self.zone_id_field_cbx.addItem(field.name())
            # by default, set the selection to the first textual field
        self.set_ok_button()

    def on_zonal_layer_gbx_toggled(self, on):
        if on and not self.zonal_layer_cbx.currentText():
            self.ok_button.setEnabled(False)
        else:
            self.set_ok_button()

    def on_output_type_changed(self):
        if self.output_type in OQ_TO_LAYER_TYPES:
            self.create_load_selected_only_ckb()
        elif self.output_type in OQ_COMPLEX_CSV_TO_LAYER_TYPES:
            self.create_save_as_shp_ckb()
        self.set_ok_button()

    @pyqtSlot()
    def on_file_browser_tbn_clicked(self):
        path = self.open_file_dialog()
        if path:
            self.populate_out_dep_widgets()
        self.set_ok_button()

    def on_rlz_or_stat_changed(self):
        self.dataset = self.npz_file[self.rlz_or_stat_cbx.currentText()]
        self.set_ok_button()

    def on_loss_type_changed(self):
        self.set_ok_button()

    def on_imt_changed(self):
        self.set_ok_button()

    def on_poe_changed(self):
        self.set_ok_button()

    def on_eid_changed(self):
        self.set_ok_button()

    def on_dmg_state_changed(self):
        self.set_ok_button()

    def open_file_dialog(self):
        """
        Open a file dialog to select the data file to be loaded
        """
        text = self.tr('Select the OQ-Engine output file to import')
        if self.output_type in OQ_CSV_TO_LAYER_TYPES:
            filters = self.tr('CSV files (*.csv)')
        else:
            raise NotImplementedError(self.output_type)
        default_dir = QSettings().value('irmt/load_as_layer_dir',
                                        QDir.homePath())
        path = QFileDialog.getOpenFileName(self, text, default_dir, filters)
        if not path:
            return
        selected_dir = QFileInfo(path).dir().path()
        QSettings().setValue('irmt/load_as_layer_dir', selected_dir)
        self.path = path
        self.path_le.setText(self.path)
        return path

    def populate_out_dep_widgets(self):
        self.populate_rlz_or_stat_cbx()
        self.show_num_sites()

    def get_taxonomies(self):
        raise NotImplementedError()

    def populate_rlz_or_stat_cbx(self):
        self.rlzs_or_stats = [
            key for key in sorted(self.npz_file)
            if key not in ('imtls', 'array')
        ]
        self.rlz_or_stat_cbx.clear()
        self.rlz_or_stat_cbx.setEnabled(True)
        self.rlz_or_stat_cbx.addItems(self.rlzs_or_stats)

    def populate_loss_type_cbx(self, loss_types):
        self.loss_type_cbx.clear()
        self.loss_type_cbx.setEnabled(True)
        self.loss_type_cbx.addItems(loss_types)

    def show_num_sites(self):
        # NOTE: we are assuming all realizations have the same number of sites,
        #       which currently is always true.
        #       If different realizations have a different number of sites, we
        #       need to move this block of code inside on_rlz_or_stat_changed()
        rlz_or_stat_data = self.npz_file[self.rlz_or_stat_cbx.currentText()]
        self.num_sites_lbl.setText(self.num_sites_msg % rlz_or_stat_data.shape)

    def set_ok_button(self):
        raise NotImplementedError()

    def build_layer_name(self, *args, **kwargs):
        raise NotImplementedError()

    def get_field_names(self, **kwargs):
        raise NotImplementedError()

    def add_field_to_layer(self, field_name):
        raise NotImplementedError()

    def read_npz_into_layer(self, field_names, **kwargs):
        raise NotImplementedError()

    def load_from_npz(self):
        raise NotImplementedError()

    def get_investigation_time(self):
        if self.output_type in ('hcurves', 'uhs', 'hmaps'):
            try:
                investigation_time = self.npz_file['investigation_time']
            except KeyError:
                msg = ('investigation_time not found. It is mandatory for %s.'
                       ' Please check if the ouptut was produced by an'
                       ' obsolete version of the OpenQuake Engine'
                       ' Server.') % self.output_type
                log_msg(msg, level='C', message_bar=self.iface.messageBar())
            else:
                return investigation_time
        else:
            # some outputs do not need the investigation time
            return None

    def build_layer(self,
                    rlz_or_stat=None,
                    taxonomy=None,
                    poe=None,
                    loss_type=None,
                    dmg_state=None,
                    gsim=None):
        layer_name = self.build_layer_name(rlz_or_stat=rlz_or_stat,
                                           taxonomy=taxonomy,
                                           poe=poe,
                                           loss_type=loss_type,
                                           dmg_state=dmg_state,
                                           gsim=gsim)
        field_names = self.get_field_names(rlz_or_stat=rlz_or_stat,
                                           taxonomy=taxonomy,
                                           poe=poe,
                                           loss_type=loss_type,
                                           dmg_state=dmg_state)

        # create layer
        self.layer = QgsVectorLayer("Point?crs=epsg:4326", layer_name,
                                    "memory")
        for field_name in field_names:
            if field_name in ['lon', 'lat']:
                continue
            added_field_name = self.add_field_to_layer(field_name)
            if field_name != added_field_name:
                if field_name == self.default_field_name:
                    self.default_field_name = added_field_name
                # replace field_name with the actual added_field_name
                field_name_idx = field_names.index(field_name)
                field_names.remove(field_name)
                field_names.insert(field_name_idx, added_field_name)

        self.read_npz_into_layer(field_names,
                                 rlz_or_stat=rlz_or_stat,
                                 taxonomy=taxonomy,
                                 poe=poe,
                                 loss_type=loss_type,
                                 dmg_state=dmg_state)
        self.layer.setCustomProperty('output_type', self.output_type)
        investigation_time = self.get_investigation_time()
        if investigation_time is not None:
            self.layer.setCustomProperty('investigation_time',
                                         investigation_time)
        if self.engine_version is not None:
            self.layer.setCustomProperty('engine_version', self.engine_version)
        irmt_version = get_irmt_version()
        self.layer.setCustomProperty('irmt_version', irmt_version)
        self.layer.setCustomProperty('calc_id', self.calc_id)
        QgsMapLayerRegistry.instance().addMapLayer(self.layer)
        self.iface.setActiveLayer(self.layer)
        self.iface.zoomToActiveLayer()

    def _set_symbol_size(self, symbol):
        if self.iface.mapCanvas().mapUnits() == QGis.Degrees:
            point_size = 0.05
        elif self.iface.mapCanvas().mapUnits() == QGis.Meters:
            point_size = 4000
        else:
            # it is not obvious how to choose the point size in the other
            # cases, so we conservatively keep the default sizing
            return
        symbol.symbolLayer(0).setSizeUnit(symbol.MapUnit)
        symbol.symbolLayer(0).setSize(point_size)
        map_unit_scale = QgsMapUnitScale()
        map_unit_scale.maxSizeMMEnabled = True
        map_unit_scale.minSizeMMEnabled = True
        map_unit_scale.minSizeMM = 0.5
        map_unit_scale.maxSizeMM = 10
        symbol.symbolLayer(0).setSizeMapUnitScale(map_unit_scale)

    def style_maps(self, layer=None, style_by=None):
        if layer is None:
            layer = self.layer
        if style_by is None:
            style_by = self.default_field_name
        symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())
        # see properties at:
        # https://qgis.org/api/qgsmarkersymbollayerv2_8cpp_source.html#l01073
        symbol.setAlpha(1)  # opacity
        if isinstance(symbol, QgsMarkerSymbolV2):
            # do it only for the layer with points
            self._set_symbol_size(symbol)
            symbol.symbolLayer(0).setOutlineStyle(Qt.PenStyle(Qt.NoPen))

        style = get_style(layer, self.iface.messageBar())

        # this is the default, as specified in the user settings
        ramp = QgsVectorGradientColorRampV2(style['color_from'],
                                            style['color_to'])
        mode = style['mode']

        # in most cases, we override the user-specified setting, and use
        # instead a setting that was required by scientists
        if self.output_type in OQ_TO_LAYER_TYPES:
            default_qgs_style = QgsStyleV2().defaultStyle()
            default_color_ramp_names = default_qgs_style.colorRampNames()
            if self.output_type in ('dmg_by_asset', 'losses_by_asset',
                                    'avg_losses-stats'):
                # options are EqualInterval, Quantile, Jenks, StdDev, Pretty
                # jenks = natural breaks
                mode = QgsGraduatedSymbolRendererV2.Jenks
                ramp_type_idx = default_color_ramp_names.index('Reds')
                inverted = False
            elif self.output_type in ('hmaps', 'gmf_data', 'ruptures'):
                # options are EqualInterval, Quantile, Jenks, StdDev, Pretty
                if self.output_type == 'ruptures':
                    mode = QgsGraduatedSymbolRendererV2.Pretty
                else:
                    mode = QgsGraduatedSymbolRendererV2.EqualInterval
                ramp_type_idx = default_color_ramp_names.index('Spectral')
                inverted = True
            ramp = default_qgs_style.colorRamp(
                default_color_ramp_names[ramp_type_idx])
        graduated_renderer = QgsGraduatedSymbolRendererV2.createRenderer(
            layer,
            style_by,
            style['classes'],
            mode,
            symbol,
            ramp,
            inverted=inverted)
        label_format = graduated_renderer.labelFormat()
        # label_format.setTrimTrailingZeroes(True)  # it might be useful
        label_format.setPrecision(2)
        graduated_renderer.setLabelFormat(label_format, updateRanges=True)
        # add a class for 0 values, unless while styling ruptures
        if self.output_type != 'ruptures':
            VERY_SMALL_VALUE = 1e-20
            graduated_renderer.updateRangeLowerValue(0, VERY_SMALL_VALUE)
            symbol_zeros = QgsSymbolV2.defaultSymbol(layer.geometryType())
            symbol_zeros.setColor(QColor(240, 240, 240))  # very light grey
            if isinstance(symbol, QgsMarkerSymbolV2):
                # do it only for the layer with points
                self._set_symbol_size(symbol_zeros)
                symbol_zeros.symbolLayer(0).setOutlineStyle(
                    Qt.PenStyle(Qt.NoPen))
            zeros_min = 0.0
            zeros_max = VERY_SMALL_VALUE
            range_zeros = QgsRendererRangeV2(
                zeros_min, zeros_max, symbol_zeros,
                " %.2f - %.2f" % (zeros_min, zeros_max), True)
            graduated_renderer.addClassRange(range_zeros)
            graduated_renderer.moveClass(
                len(graduated_renderer.ranges()) - 1, 0)
        layer.setRendererV2(graduated_renderer)
        layer.setLayerTransparency(30)  # percent
        layer.triggerRepaint()
        self.iface.legendInterface().refreshLayerSymbology(layer)
        self.iface.mapCanvas().refresh()

    def style_categorized(self, layer, style_by):
        # get unique values
        fni = layer.fieldNameIndex(style_by)
        unique_values = layer.dataProvider().uniqueValues(fni)
        # define categories
        categories = []
        for unique_value in unique_values:
            # initialize the default symbol for this geometry type
            symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())
            # configure a symbol layer
            layer_style = {}
            layer_style['color'] = '%d, %d, %d' % (randrange(
                0, 256), randrange(0, 256), randrange(0, 256))
            layer_style['outline'] = '#000000'
            symbol_layer = QgsSimpleFillSymbolLayerV2.create(layer_style)
            # replace default symbol layer with the configured one
            if symbol_layer is not None:
                symbol.changeSymbolLayer(0, symbol_layer)
            # create renderer object
            category = QgsRendererCategoryV2(unique_value, symbol,
                                             str(unique_value))
            # entry for the list of category items
            categories.append(category)
        # create renderer object
        renderer = QgsCategorizedSymbolRendererV2(style_by, categories)
        # assign the created renderer to the layer
        if renderer is not None:
            layer.setRendererV2(renderer)
        layer.triggerRepaint()
        self.iface.legendInterface().refreshLayerSymbology(layer)
        self.iface.mapCanvas().refresh()

    def style_curves(self):
        registry = QgsSymbolLayerV2Registry.instance()
        cross = registry.symbolLayerMetadata("SimpleMarker").createSymbolLayer(
            {
                'name': 'cross2',
                'color': '0,0,0',
                'color_border': '0,0,0',
                'offset': '0,0',
                'size': '1.5',
                'angle': '0'
            })
        symbol = QgsSymbolV2.defaultSymbol(self.layer.geometryType())
        symbol.deleteSymbolLayer(0)
        symbol.appendSymbolLayer(cross)
        self._set_symbol_size(symbol)
        renderer = QgsSingleSymbolRendererV2(symbol)
        effect = QgsOuterGlowEffect()
        effect.setSpread(0.5)
        effect.setTransparency(0)
        effect.setColor(QColor(255, 255, 255))
        effect.setBlurLevel(1)
        renderer.paintEffect().appendEffect(effect)
        renderer.paintEffect().setEnabled(True)
        self.layer.setRendererV2(renderer)
        self.layer.setLayerTransparency(30)  # percent
        self.layer.triggerRepaint()
        self.iface.legendInterface().refreshLayerSymbology(self.layer)
        self.iface.mapCanvas().refresh()

    def open_zonal_layer_dialog(self):
        """
        Open a file dialog to select the zonal layer to be loaded
        :returns: the zonal layer
        """
        text = self.tr('Select zonal layer to import')
        filters = self.tr('Vector shapefiles (*.shp);;SQLite (*.sqlite);;'
                          'All files (*.*)')
        default_dir = QSettings().value('irmt/select_layer_dir',
                                        QDir.homePath())
        file_name, file_type = QFileDialog.getOpenFileNameAndFilter(
            self, text, default_dir, filters)
        if not file_name:
            return None
        selected_dir = QFileInfo(file_name).dir().path()
        QSettings().setValue('irmt/select_layer_dir', selected_dir)
        zonal_layer_plus_stats = self.load_zonal_layer(file_name)
        return zonal_layer_plus_stats

    def load_zonal_layer(self, zonal_layer_path, make_a_copy=False):
        # Load zonal layer
        zonal_layer = QgsVectorLayer(zonal_layer_path, tr('Zonal data'), 'ogr')
        if not zonal_layer.geometryType() == QGis.Polygon:
            msg = 'Zonal layer must contain zone polygons'
            log_msg(msg, level='C', message_bar=self.iface.messageBar())
            return False
        if make_a_copy:
            # Make a copy, where stats will be added
            zonal_layer_plus_stats = ProcessLayer(
                zonal_layer).duplicate_in_memory()
        else:
            zonal_layer_plus_stats = zonal_layer
        # Add zonal layer to registry
        if zonal_layer_plus_stats.isValid():
            QgsMapLayerRegistry.instance().addMapLayer(zonal_layer_plus_stats)
        else:
            msg = 'Invalid zonal layer'
            log_msg(msg, level='C', message_bar=self.iface.messageBar())
            return None
        return zonal_layer_plus_stats

    def on_zonal_layer_tbn_clicked(self):
        zonal_layer_plus_stats = self.open_zonal_layer_dialog()
        if (zonal_layer_plus_stats
                and zonal_layer_plus_stats.geometryType() == QGis.Polygon):
            self.populate_zonal_layer_cbx(zonal_layer_plus_stats)

    def populate_zonal_layer_cbx(self, zonal_layer_plus_stats):
        cbx = self.zonal_layer_cbx
        cbx.addItem(zonal_layer_plus_stats.name())
        last_index = cbx.count() - 1
        cbx.setItemData(last_index, zonal_layer_plus_stats.id())
        cbx.setCurrentIndex(last_index)

    def show_file_size(self):
        file_size = get_file_size(self.path)
        self.file_size_lbl.setText(self.file_size_msg % file_size)

    def accept(self):
        if self.output_type in OQ_EXTRACT_TO_LAYER_TYPES:
            self.load_from_npz()
            if self.output_type in ('losses_by_asset', 'dmg_by_asset',
                                    'avg_losses-stats'):
                # check if also aggregating by zone or not
                if (not self.zonal_layer_cbx.currentText()
                        or not self.zonal_layer_gbx.isChecked()):
                    super(LoadOutputAsLayerDialog, self).accept()
                    return
                loss_layer = self.layer
                self.iface.legendInterface().setLayerVisible(loss_layer, False)
                zonal_layer_id = self.zonal_layer_cbx.itemData(
                    self.zonal_layer_cbx.currentIndex())
                zonal_layer = QgsMapLayerRegistry.instance().mapLayer(
                    zonal_layer_id)
                # if the two layers have different projections, display an
                # error message and return
                have_same_projection, check_projection_msg = ProcessLayer(
                    loss_layer).has_same_projection_as(zonal_layer)
                if not have_same_projection:
                    log_msg(check_projection_msg,
                            level='C',
                            message_bar=self.iface.messageBar())
                    # TODO: load only loss layer
                    super(LoadOutputAsLayerDialog, self).accept()
                    return
                loss_attr_names = [
                    field.name() for field in loss_layer.fields()
                ]
                zone_id_in_losses_attr_name = None
                # index 0 is for "Add field with unique zone id"
                if self.zone_id_field_cbx.currentIndex() == 0:
                    zone_id_in_zones_attr_name = None
                else:
                    zone_id_in_zones_attr_name = \
                        self.zone_id_field_cbx.currentText()
                # aggregate losses by zone (calculate count of points in the
                # zone, sum and average loss values for the same zone)
                loss_layer_is_vector = True
                try:
                    res = calculate_zonal_stats(loss_layer,
                                                zonal_layer,
                                                loss_attr_names,
                                                loss_layer_is_vector,
                                                zone_id_in_losses_attr_name,
                                                zone_id_in_zones_attr_name,
                                                self.iface,
                                                extra=False)
                except TypeError as exc:
                    log_msg(str(exc),
                            level='C',
                            message_bar=self.iface.messageBar())
                    return
                (loss_layer, zonal_layer, loss_attrs_dict) = res
                # sanity check
                assert len(loss_attrs_dict) == 1, (
                    "Only one attribute should be added to the zonal layer."
                    " %s were added insted" % len(loss_attrs_dict))
                # NOTE: in scenario damage, keys are like
                #       u'structural_no_damage_mean', and not just
                #       u'structural', therefore we can't just use the selected
                #       loss type, but we must use the actual only key in the
                #       dict
                [added_loss_attr] = loss_attrs_dict
                style_by = loss_attrs_dict[added_loss_attr]['sum']
                self.style_maps(layer=zonal_layer, style_by=style_by)
        elif self.output_type in OQ_CSV_TO_LAYER_TYPES:
            self.load_from_csv()
        super(LoadOutputAsLayerDialog, self).accept()

    def reject(self):
        if (hasattr(self, 'npz_file') and self.npz_file is not None
                and self.output_type in OQ_TO_LAYER_TYPES):
            self.npz_file.close()
        super(LoadOutputAsLayerDialog, self).reject()
Exemple #49
0
def load_path_vector_layer(path, **kwargs):
    """Return the test vector layer.

    :param path: Path to the vector layer.
    :type path: str

    :param kwargs: It can be :
        clone=True if you want to copy the layer first to a temporary file.

        clone_to_memory=True if you want to create a memory layer.

        with_keywords=False if you do not want keywords. "clone_to_memory" is
            required.

    :type kwargs: dict

    :return: The vector layer.
    :rtype: QgsVectorLayer

    .. versionadded:: 4.0
    """
    if not exists(path):
        raise Exception('%s do not exist.' % path)

    path = os.path.normcase(os.path.abspath(path))
    name = splitext(basename(path))[0]
    extension = splitext(path)[1]

    extensions = [
        '.shp', '.shx', '.dbf', '.prj', '.gpkg', '.geojson', '.xml', '.qml']

    if kwargs.get('with_keywords'):
        if not kwargs.get('clone_to_memory'):
            raise Exception('with_keywords needs a clone_to_memory')

    if kwargs.get('clone', False):
        target_directory = mkdtemp()
        current_path = splitext(path)[0]
        path = join(target_directory, name + extension)

        for ext in extensions:
            src_path = current_path + ext
            if exists(src_path):
                target_path = join(target_directory, name + ext)
                shutil.copy2(src_path, target_path)

    if path.endswith('.csv'):
        # Explicitly use URI with delimiter or tests fail in Windows. TS.
        uri = 'file:///%s?delimiter=%s' % (path, ',')
        layer = QgsVectorLayer(uri, name, 'delimitedtext')
    else:
        layer = QgsVectorLayer(path, name, 'ogr')

    if not layer.isValid():
        raise Exception('%s is not a valid layer.' % name)

    monkey_patch_keywords(layer)

    if kwargs.get('clone_to_memory', False):
        keywords = layer.keywords.copy()
        memory_layer = create_memory_layer(
            name, layer.geometryType(), layer.crs(), layer.fields())
        copy_layer(layer, memory_layer)
        if kwargs.get('with_keywords', True):
            memory_layer.keywords = keywords
        return memory_layer
    else:
        return layer
def addRowInLayer(row, errTable, table_codif):
    """
    Rows will be converted in a geometry thanks to codification.
    All attributes will be added thanks to QgsExpressionContext.

    Parameters
    ----------
    row: list of list
        A row contains one or many list of points.
    errTable: list of list
        Contains points in error.
        Some points can be added after the end of this function.
    table_codif: dictionnary
        The codification file. See the information about qlsc format.
    """

    #  TODO: assert?
    code = row[CODE_POSITION][0]
    parameters = row[PARAM_POSITION]

    codif = table_codif['Codification'][code]
    layerName = codif['Layer']

    layer = QgsVectorLayer(layerName)

    dim = 4 if QgsWkbTypes.hasZ(layer.dataProvider().wkbType()) else 3
    geom = geomFromType(list(zip(*row[1:dim])), parameters,
                        codif['GeometryType'], layer.geometryType())

    if geom:
        layer.startEditing()

        fields = layer.fields()
        newFeature = QgsFeature(fields)

        newFeature.setGeometry(geom)

        for e in codif['Attributes']:
            # print(e, e[1], e[1].startswith('_att'))
            if e[1].startswith('_att'):
                # len('_att') == 4
                try:
                    nb = int(e[1][4:]) - 1
                    assert(nb >= 0)
                    val = row[ATTRS_POSITION + nb][0]
                    newFeature[e[0]] = val
                except:
                    # print("attributes error")
                    pass
            else:
                context = QgsExpressionContext()
                scope = QgsExpressionContextScope()
                try:
                    exp = QgsExpression(e[1])
                    scope.setFeature(newFeature)
                    context.appendScope(scope)
                    newFeature[e[0]] = exp.evaluate(context)
                except:
                    # print('key error')
                    pass

        ret = layer.addFeature(newFeature)
        # if not ret:
         #   print(ret)

        layer.commitChanges()
        layer.updateExtents()
    else:
        # can it happen?
        errTable.append(row)
Exemple #51
0
	def run(self):
		# layer base name and dir path
		base_name = QFileInfo(self._fn).baseName()
		dir_path = QFileInfo(self._fn).absoluteDir()

		# create the uri for the delimitedtext provider
		from .settings_dlg import Settings
		csvUrl = QUrl.fromLocalFile( self._fn )
		csvUrl.setQueryItems( [
			( "delimiter", Settings.delimiter() ),
			( "delimiterType", "plain"),
			( "xField", Settings.longitudeField() ),
			( "yField", Settings.latitudeField() )
		] )

		# load the layer
		from qgis.core import QgsVectorLayer
		csvVl = QgsVectorLayer(csvUrl.toString(), base_name, "delimitedtext")
		if not csvVl.isValid():	# invalid layer
			csvVl.deleteLater()
			QMessageBox.warning( self.parent(), "Invalid layer", 
								u"Unable to load the layer %s" % self._fn )
			return (self.INVALID_INPUT, None)

		# check the layer geometry type
		from qgis.core import QGis
		if csvVl.geometryType() != QGis.Point:
			csvVl.deleteLater()
			QMessageBox.warning( self.parent(), "Invalid layer", 
								u"Unable to get data from the selected file. \nSetup Lat/Long field names and delimiter from the Settings dialog, \nthen try again." )
			return (self.INVALID_LATLON, None)

		# check whether the CSV file has to be imported to SL db
		if not Settings.importCsvToSl():
			return (self.OK, csvVl)

		# uri pointing to the new SL database
		from qgis.core import QgsDataSourceURI
		sqlite_path = dir_path.absoluteFilePath( u"%s.sqlite" % base_name )
		slUri = QgsDataSourceURI()
		slUri.setDatabase( sqlite_path )
		slUri.setDataSource( "", base_name, "GEOMETRY" )

		importer = Ogr2ogrImporter(csvVl, slUri, self.parent())
		#importer = QGisLayerImporter(csvVl, slUri, self.parent())
		ret = importer.start()

		# get the importer exit code
		if not ret:
			if importer.wasCanceled():
				ret = self.CANCELED
			else:
				ret = self.ERROR
				QMessageBox.warning( self.parent(), "Error", importer.errorMessage() )
		else:
			ret = self.OK

		# cleanup
		importer.deleteLater()
		importer = None

		csvVl.deleteLater()
		csvVl = None

		if ret != self.OK:
			return (ret, None)

		# load the layer from the SL database
		slVl = QgsVectorLayer(slUri.uri(), slUri.table(), "spatialite")
		if not slVl.isValid():	# invalid layer
			slVl.deleteLater()
			QMessageBox.warning( self.parent(),	"Invalid layer",
								u"Unable to load the layer %s" % slUri.database() )
			return (self.ERROR, None)

		# check the layer geometry type
		if slVl.geometryType() != QGis.Point:
			slVl.deleteLater()
			return (self.ERROR, None)

		return (self.OK, slVl)
Exemple #52
0
class OSRM_DialogTSP(QtGui.QDialog, FORM_CLASS_tsp, TemplateOsrm):
    def __init__(self, iface, parent=None):
        """ Constructor"""
        super(OSRM_DialogTSP, self).__init__(parent)
        self.setupUi(self)
        self.iface = iface
        self.pushButton_display.clicked.connect(self.run_tsp)
        self.pushButton_clear.clicked.connect(self.clear_results)
        self.comboBox_layer.setFilters(QgsMapLayerProxyModel.PointLayer)
        self.nb_route = 0

    def clear_results(self):
        """
        Clear previous result and set back counter to 0.
        """
        for layer in QgsMapLayerRegistry.instance().mapLayers():
            if 'tsp_solution_osrm' in layer:
                QgsMapLayerRegistry.instance().removeMapLayer(layer)
        self.nb_route = 0

    def run_tsp(self):
        """
        Main method, preparing the query and displaying the result on
        the canvas.
        """
        layer = self.comboBox_layer.currentLayer()
        coords, _ = get_coords_ids(
            layer, '', on_selected=self.checkBox_selec_features.isChecked())

        if len(coords) < 2:
            return -1

        try:
            self.host = check_host(self.lineEdit_host.text())
            profile = check_profile_name(self.lineEdit_profileName.text())
        except (ValueError, AssertionError) as err:
            print(err)
            self.iface.messageBar().pushMessage(
                "Error", "Please provide a valid non-empty URL and profile name", duration=10)
            return

        query = ''.join(
            ["http://", self.host,
            "/trip/", profile, "/",
            ";".join(["{},{}".format(coord[0], coord[1]) for coord in coords])])

        try:
            self.parsed = self.query_url(query)
        except Exception as err:
            self.iface.messageBar().pushMessage(
                "Error", "An error occured when trying to contact the OSRM "
                "instance (see QGis log for error traceback)",
                duration=10)
            QgsMessageLog.logMessage(
                'OSRM-plugin error report :\n {}'.format(err),
                level=QgsMessageLog.WARNING)
            return

        try:
            line_geoms = \
                [decode_geom(self.parsed['trips'][i]['geometry'])
                 for i in range(len(self.parsed['trips']))]
        except KeyError:
            self.iface.messageBar().pushMessage(
                "Error",
                "?...",
                duration=5)
            return

        tsp_route_layer = QgsVectorLayer(
            "Linestring?crs=epsg:4326&field=id:integer"
            "&field=total_time:integer(20)&field=distance:integer(20)",
            "tsp_solution_osrm{}".format(self.nb_route), "memory")
        my_symb = prepare_route_symbol(self.nb_route)
        tsp_route_layer.setRendererV2(QgsSingleSymbolRendererV2(my_symb))
        features = []
        for idx, feature in enumerate(self.parsed['trips']):
            ft = QgsFeature()
            ft.setGeometry(line_geoms[idx])
            ft.setAttributes([idx,
                              feature['distance'],
                              feature['duration']])
            features.append(ft)
            self.prepare_ordered_marker(coords, idx)
        tsp_route_layer.dataProvider().addFeatures(features)
        tsp_route_layer.updateExtents()
        QgsMapLayerRegistry.instance().addMapLayer(tsp_route_layer)
        self.iface.setActiveLayer(tsp_route_layer)
        self.iface.zoomToActiveLayer()
        put_on_top(self.tsp_marker_lr.id(), tsp_route_layer.id())
        self.nb_route += 1

#        if self.checkBox_instructions.isChecked():
#            pr_instruct, instruct_layer = self.prep_instruction()
#            QgsMapLayerRegistry.instance().addMapLayer(instruct_layer)
#            self.iface.setActiveLayer(instruct_layer)


    def prepare_ordered_marker(self, coords, idx):
        """
        Try to display nice marker on a point layer, showing the order of
        the path computed by OSRM.
        """
        self.tsp_marker_lr = QgsVectorLayer(
            "Point?crs=epsg:4326&field=id:integer"
            "&field=TSP_nb:integer(20)&field=Origin_nb:integer(20)",
            "tsp_markers_osrm{}".format(self.nb_route), "memory")
        symbol = QgsSymbolV2.defaultSymbol(self.tsp_marker_lr.geometryType())
        symbol.setSize(4.5)
        symbol.setColor(QtGui.QColor("yellow"))

        ordered_pts = \
            [coords[i["waypoint_index"]] for i in self.parsed['waypoints']]
        print("ordered_pts : ", ordered_pts)

        features = []
        for nb, pt in enumerate(ordered_pts):
            ft = QgsFeature()
            ft.setGeometry(QgsGeometry.fromPoint(QgsPoint(pt)))
            ft.setAttributes([nb, nb + 1, coords.index(pt)])
            features.append(ft)
        self.tsp_marker_lr.dataProvider().addFeatures(features)

        pal_lyr = QgsPalLayerSettings()
        pal_lyr.readFromLayer(self.tsp_marker_lr)
        pal_lyr.enabled = True
        pal_lyr.fieldName = 'TSP_nb'
        pal_lyr.placement= QgsPalLayerSettings.OverPoint
        pal_lyr.setDataDefinedProperty(QgsPalLayerSettings.Size,True,True,'12','')
        pal_lyr.writeToLayer(self.tsp_marker_lr)

        self.tsp_marker_lr.setRendererV2(QgsSingleSymbolRendererV2(symbol))
        QgsMapLayerRegistry.instance().addMapLayer(self.tsp_marker_lr)
 def run(self):
     """Run method that performs all the real work"""
     self.dlg.layerComboBox.clear()
     self.dlg.sheetTypeComboBox.clear()
     self.dlg.scaleComboBox.clear()  
     #self.dlg.label_2.setText('')        
     Alllayers = self.iface.legendInterface().layers()
     #layer_list = []
     lcount=0
     for layer in Alllayers:
         xyCrs = layer.crs()
         if xyCrs.projectionAcronym()=='longlat':
             lcount=lcount+1
             self.dlg.layerComboBox.addItem(layer.name(),layer)
             
     self.dlg.sheetTypeComboBox.addItem('Indian and Adjoining Countries Series Maps')    
     self.dlg.sheetTypeComboBox.addItem('Open Series Maps')    
     
     scale_list=['1:1M','1:250,000','1:125,000','1:50,000','1:25,000']
     self.dlg.scaleComboBox.addItems(scale_list)
     # show the dialog
     self.dlg.show()
     # Run the dialog event loop
     result = self.dlg.exec_()
     # See if OK was pressed
     if result:
         global scaleID
         global sheetw
         global sheeth
         if lcount>0:
             scaleID=self.dlg.scaleComboBox.currentIndex()+1
             maptype= self.dlg.sheetTypeComboBox.currentIndex()+1
             if maptype==1:                
                 sheetw,sheeth=setFactor1(scaleID)
             if maptype==2:
                 sheetw,sheeth=setFactor2(scaleID)               
             index = self.dlg.layerComboBox.currentIndex()
             clayer = self.dlg.layerComboBox.itemData(index)
             e=clayer.extent()
             a,b,c=degDec2dms(e.xMinimum())
             slongs=dmstosec(a,b,c)
             a,b,c=degDec2dms(e.xMaximum())
             elongs=dmstosec(a,b,c)
             a,b,c=degDec2dms(e.yMinimum())
             slats=dmstosec(a,b,c)
             a,b,c=degDec2dms(e.yMaximum())
             elats=dmstosec(a,b,c)
             slongs,elongs,slats,elats=CalculateExtentInTermsOfSheet(slongs,elongs,slats,elats)
             Xgrids=int(elongs-slongs)//sheetw # // is used for modular division
             Ygrids=int(elats-slats)//sheeth
             layer = QgsVectorLayer("Polygon?crs=EPSG:4326", "TopoSheets", "memory")
             global poly
             global pr
             pr = layer.dataProvider() 
             pr.addAttributes([QgsField("id",QVariant.Int),QgsField("SheetNo",QVariant.String),QgsField("Inside",QVariant.String)])
             layer.updateFields()
            
             poly = QgsFeature()
             CalculateSheet(maptype,slats,slongs,Xgrids,Ygrids)
             n=0
             # check intersection of selected layer feature with sheets
             fieldIdx = pr.fields().indexFromName('Inside' )
             updateMap = {}
             for f in clayer.getFeatures():
                 for a in layer.getFeatures():
                     if a.geometry().intersects(f.geometry()):
                         n=n+1
                         updateMap[a.id()] = { fieldIdx:1 }
             pr.changeAttributeValues(updateMap)
             
             # set the layer symbology
             values = (
             ('In', True,True,QColor.fromRgb(95,254,99)),
             ('Out', False,False,'yellow'),
             )
             # create a category for each item in values
             ranges=[]
             for label, lower, upper, color in values:
                 symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())
                 symbol.setColor(QColor(color))
                 rng = QgsRendererRangeV2(lower, upper, symbol, label)
                 ranges.append(rng)
             expression = 'Inside' # field name
             renderer = QgsGraduatedSymbolRendererV2(expression, ranges)
             layer.setRendererV2(renderer)
             
             # set layer transparence and dolabelling
             layer.setLayerTransparency(65)              
             layer.updateExtents()
             QgsMapLayerRegistry.instance().addMapLayers([layer])
             layer.setCustomProperty("labeling", "pal")
             layer.setCustomProperty("labeling/enabled", "true")
             layer.setCustomProperty("labeling/fontFamily", "Arial")
             layer.setCustomProperty("labeling/fontSize", "10")
             layer.setCustomProperty("labeling/fieldName", "SheetNo")
             layer.setCustomProperty("labeling/placement", "1")
             iface.mapCanvas().refresh()
         else:
             iface.messageBar().pushMessage("Error", "No layers loaded, Load layer with Geographic Corrdinates", level=QgsMessageBar.CRITICAL)
         pass
    def WPT2Layer(self):
        mapUnits = define._canvas.mapUnits()
        if define._mapCrs == None:
            if mapUnits == QGis.Meters:
                resultLayer = QgsVectorLayer(
                    "Point?crs=EPSG:32633", "WPT_" +
                    self.surfaceType.replace(" ", "_").replace("-", "_"),
                    "memory")
            else:
                resultLayer = QgsVectorLayer(
                    "Point?crs=EPSG:4326", "WPT_" +
                    self.surfaceType.replace(" ", "_").replace("-", "_"),
                    "memory")
        else:
            resultLayer = QgsVectorLayer(
                "Point?crs=%s" % define._mapCrs.authid(),
                "WPT_" + self.surfaceType.replace(" ", "_").replace("-", "_"),
                "memory")
        shpPath = ""
        if define.obstaclePath != None:
            shpPath = define.obstaclePath
        elif define.xmlPath != None:
            shpPath = define.xmlPath
        else:
            shpPath = define.appPath
        er = QgsVectorFileWriter.writeAsVectorFormat(
            resultLayer,
            shpPath + "/" + "RnavTurningSegmentAnalyserWpt" + ".shp", "utf-8",
            resultLayer.crs())
        resultLayer = QgsVectorLayer(
            shpPath + "/" + "RnavTurningSegmentAnalyserWpt" + ".shp",
            "WPT_RnavTurningSegmentAnalyser", "ogr")

        fieldName = "CATEGORY"
        resultLayer.dataProvider().addAttributes(
            [QgsField(fieldName, QVariant.String)])
        resultLayer.startEditing()
        fields = resultLayer.pendingFields()
        i = 1
        feature = QgsFeature()
        feature.setFields(fields)

        feature.setGeometry(
            QgsGeometry.fromPoint(self.parametersPanel.pnlWaypoint1.Point3d))
        feature.setAttribute(fieldName, "Waypoint1")
        pr = resultLayer.dataProvider()
        pr.addFeatures([feature])
        # resultLayer.addFeature(feature)
        feature.setGeometry(
            QgsGeometry.fromPoint(self.parametersPanel.pnlWaypoint2.Point3d))
        feature.setAttribute(fieldName, "Waypoint2")
        pr = resultLayer.dataProvider()
        pr.addFeatures([feature])
        # resultLayer.addFeature(feature)
        resultLayer.commitChanges()

        renderCatFly = None
        if self.parametersPanel.cmbType1.SelectedIndex == 1:
            '''FlyOver'''

            symbolFlyOver = QgsSymbolV2.defaultSymbol(
                resultLayer.geometryType())
            symbolFlyOver.deleteSymbolLayer(0)
            svgSymLayer = QgsSvgMarkerSymbolLayerV2("Resource/flyover.svg",
                                                    10.0, 0.0)
            symbolFlyOver.appendSymbolLayer(svgSymLayer)
            renderCatFly = QgsRendererCategoryV2(0, symbolFlyOver, "Fly Over")
        elif self.parametersPanel.cmbType1.SelectedIndex == 0:
            '''FlyBy'''
            symbolFlyBy = QgsSymbolV2.defaultSymbol(resultLayer.geometryType())
            symbolFlyBy.deleteSymbolLayer(0)
            svgSymLayer = QgsSvgMarkerSymbolLayerV2("Resource/flyby.svg", 10.0,
                                                    0.0)
            symbolFlyBy.appendSymbolLayer(svgSymLayer)
            renderCatFly = QgsRendererCategoryV2(0, symbolFlyBy, "Fly By")
        else:
            return None
        WPT_EXPRESION = "CASE WHEN  \"CATEGORY\" = 'Waypoint1'  THEN 0 " + \
                                        "END"
        symRenderer = QgsCategorizedSymbolRendererV2(WPT_EXPRESION,
                                                     [renderCatFly])

        resultLayer.setRendererV2(symRenderer)
        return resultLayer