def test_value_date(self):
        test_property = DateProperty(
            'test name',
            QDate.currentDate(),
            'gco:Date'
        )

        test_property.value = QDate.fromString('2015-06-07')

        with self.assertRaises(TypeError):
            test_property.value = 20150607
	def _getXYvalues(self, ts_layer, dateField, valueField):
		# utility function used to get the X and Y values
		x, y = [], []

		# get indexes of date (x) and value (y) fields
		dateIdx, valueIdx = None, None
		for idx, fld in enumerate(ts_layer.dataProvider().fields()):
			if fld.name().lower() == dateField:
				dateIdx = idx
			elif fld.name().lower() == valueField:
				valueIdx = idx

		if dateIdx is None or valueIdx is None:
			QgsMessageLog.logMessage("field %s -> index %s, field %s -> index %s. Exiting" % (dateField, dateIdx, valueField, valueIdx), "PSTimeSeriesViewer")
			return

		# fetch and loop through all the features
		request = QgsFeatureRequest()
		request.setSubsetOfAttributes([dateIdx, valueIdx])
		for f in ts_layer.getFeatures( request ):
			# get x and y values
			a = f.attributes()
			x.append( QDate.fromString( a[ dateIdx ], "yyyyMMdd" ).toPyDate() )
			y.append( float(a[ valueIdx ]) )

		return x, y
Beispiel #3
0
    def evaluation_test(self, layout, label):
        # $CURRENT_DATE evaluation
        label.setText("__$CURRENT_DATE__")
        assert label.currentText() == ("__" + QDate.currentDate().toString() + "__")

        # $CURRENT_DATE() evaluation
        label.setText("__$CURRENT_DATE(dd)(ok)__")
        expected = "__" + QDateTime.currentDateTime().toString("dd") + "(ok)__"
        assert label.currentText() == expected

        # $CURRENT_DATE() evaluation (inside an expression)
        label.setText("__[%$CURRENT_DATE(dd) + 1%](ok)__")
        dd = QDate.currentDate().day()
        expected = "__%d(ok)__" % (dd + 1)
        assert label.currentText() == expected

        # expression evaluation (without associated feature)
        label.setText("__[%\"NAME_1\"%][%21*2%]__")
        assert label.currentText() == "__[NAME_1]42__"
Beispiel #4
0
    def testDefaultValues(self):
        """ test detection of defaults on OGR layer """

        tmpfile = os.path.join(self.basetestpath, 'testDefaults.sqlite')
        ds = ogr.GetDriverByName('SQLite').CreateDataSource(tmpfile)
        lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint, options=['FID=fid'])
        lyr.CreateField(ogr.FieldDefn('field1', ogr.OFTInteger))
        fld2 = ogr.FieldDefn('field2', ogr.OFTInteger)
        fld2.SetDefault('5')
        lyr.CreateField(fld2)
        fld3 = ogr.FieldDefn('field3', ogr.OFTString)
        fld3.SetDefault("'some ''default'")
        lyr.CreateField(fld3)
        fld4 = ogr.FieldDefn('field4', ogr.OFTDate)
        fld4.SetDefault("CURRENT_DATE")
        lyr.CreateField(fld4)
        fld5 = ogr.FieldDefn('field5', ogr.OFTTime)
        fld5.SetDefault("CURRENT_TIME")
        lyr.CreateField(fld5)
        fld6 = ogr.FieldDefn('field6', ogr.OFTDateTime)
        fld6.SetDefault("CURRENT_TIMESTAMP")
        lyr.CreateField(fld6)

        ds = None

        vl = QgsVectorLayer('{}'.format(tmpfile), 'test', 'ogr')
        self.assertTrue(vl.isValid())

        # test some bad indexes
        self.assertFalse(vl.dataProvider().defaultValue(-1))
        self.assertFalse(vl.dataProvider().defaultValue(1001))

        # test default
        self.assertEqual(vl.dataProvider().defaultValue(1), NULL)
        self.assertEqual(vl.dataProvider().defaultValue(2), 5)
        self.assertEqual(vl.dataProvider().defaultValue(3), "some 'default")
        self.assertEqual(vl.dataProvider().defaultValue(4), QDate.currentDate())
        # time may pass, so we allow 1 second difference here
        self.assertTrue(vl.dataProvider().defaultValue(5).secsTo(QTime.currentTime()) < 1)
        self.assertTrue(vl.dataProvider().defaultValue(6).secsTo(QDateTime.currentDateTime()) < 1)
 def testDates(self):
     """ test with date values """
     s = QgsDateTimeStatisticalSummary()
     self.assertEqual(s.statistics(), QgsDateTimeStatisticalSummary.All)
     s.calculate([
         QDate(2015, 3, 4),
         QDate(2015, 3, 4),
         QDate(2019, 12, 28),
         QDate(),
         QDate(1998, 1, 2),
         QDate(),
         QDate(2011, 1, 5)
     ])
     self.assertEqual(s.count(), 7)
     self.assertEqual(
         set(s.distinctValues()),
         set([
             QDateTime(QDate(2015, 3, 4), QTime()),
             QDateTime(QDate(2019, 12, 28), QTime()),
             QDateTime(QDate(1998, 1, 2), QTime()),
             QDateTime(),
             QDateTime(QDate(2011, 1, 5), QTime())
         ]))
     self.assertEqual(s.countMissing(), 2)
     self.assertEqual(s.min(), QDateTime(QDate(1998, 1, 2), QTime()))
     self.assertEqual(s.max(), QDateTime(QDate(2019, 12, 28), QTime()))
     self.assertEqual(s.range(), QgsInterval(693792000))
Beispiel #6
0
    def agregacio(self,
                  llegenda,
                  nomCapa: str,
                  zona: str,
                  tipusAgregacio: str,
                  renderParams: QvMapRendererParams,
                  campAgregat: str = '',
                  simple=True,
                  tipusDistribucio: str = "Total",
                  campExtensio: str = mv.MAP_EXTENSIO,
                  filtre: str = '',
                  veure: bool = True,
                  form: QDialog = None) -> bool:
        """ Realiza la agragación de los datos por zona, la generación del mapa y su simbología.
        
        Arguments:
            llegenda {QvLlegenda} -- Leyenda
            nomCapa {str} -- Nombre de la capa del mapa a generar
            zona {str} -- Zona de agregación
            tipusAgregacio {str} -- Tipo de agregación
            renderParams {QvMapRendererParams} -- Parámetros de simbología
        
        Keyword Arguments:
            campAgregat {str} -- Campo que se utiliza en el cálculo de la agragación (default: {''})
            tipusDistribucio {str} -- Tipo de distribución (default: {"Total"})
            campExtensio {str} -- Nombre del campo que indica la extensión del mapa (default: {''})
            filtre {str} -- Expresión para filtrar los datos (default: {''})
            veure {bool} -- Si es True, añade la nueva capa con el mapa en la leyenda (default: {True})
            form {QDialog} -- Formulario desde donde se invoca la función (default: {None})
        
        Returns:
            bool -- False si hubo errores (mensaje de error en self.msgError)
        """

        if not PANDAS_ENABLED:
            self.msgError = PANDAS_ERROR
            return False

        self.fMapa = ''
        self.fSQL = ''
        self.llegenda = llegenda
        self.msgError = ''
        self.form = form
        self.descripcio = "Arxiu de dades: " + self.fZones + '\n' + \
            "Data: " +  QDate.currentDate().toString(QvApp().locale.dateFormat(QvApp().locale.ShortFormat)) + '\n' + \
            "Zona: " + zona + '\n' + \
            "Tipus d'agregació: " + tipusAgregacio + '\n' + \
            "Camp de càlcul: " + campAgregat
        if not simple:
            self.descripcio += '\n' + \
                "Filtre: " + filtre + '\n' + \
                "Distribució: " + tipusDistribucio

        if not self.verifZona(zona):
            self.msgError = "Error en zona"
            return False

        if campAgregat is not None and campAgregat != '':
            self.campAgregat = campAgregat
        elif tipusAgregacio == 'Recompte' and campAgregat == '':
            self.campAgregat = '*'
        else:
            self.msgError = "Error en campAgregat"
            return False

        if tipusAgregacio is None or tipusAgregacio not in mv.MAP_AGREGACIO.keys(
        ):
            self.msgError = "Error en tipusAgregacio"
            return False
        self.tipusAgregacio = mv.MAP_AGREGACIO[tipusAgregacio].format(
            self.campAgregat)

        if tipusDistribucio is None or tipusDistribucio not in mv.MAP_DISTRIBUCIO.keys(
        ):
            self.msgError = "Error en tipusDistribucio"
            return False
        self.tipusDistribucio = mv.MAP_DISTRIBUCIO[tipusDistribucio]

        self.filtre = filtre
        self.nomCapa = self.netejaString(nomCapa, True)

        # if not self.generaCapaQgis(nomCapa):
        #     return False

        if not self.generaCapaGpd(self.nomCapa, tipusAgregacio,
                                  tipusDistribucio, renderParams,
                                  campExtensio):
            return False

        # Carga capa de agregación
        mapLyr = QgsVectorLayer(self.fSQL, nomCapa, "ogr")
        mapLyr.setProviderEncoding("UTF-8")
        if not mapLyr.isValid():
            self.msgError = "No s'ha pogut carregar capa de agregació: " + self.fSQL
            return False

        # Renderer para mapificar
        mapRenderer = renderParams.mapRenderer(self.llegenda)
        self.renderer = mapRenderer.calcRender(mapLyr)
        if self.renderer is None:
            self.msgError = "No s'ha pogut elaborar el mapa"
            return False
        else:
            mapLyr.setRenderer(self.renderer)

        # Identificador de mapificación para qVista
        QgsExpressionContextUtils.setLayerVariable(mapLyr, mv.MAP_ID,
                                                   self.descripcio)
        mapLyr.setDisplayExpression(renderParams.campCalculat)

        # Guarda simbología en GPKG
        err = self.llegenda.saveStyleToGeoPackage(mapLyr, mv.MAP_ID)
        if err != '':
            self.msgError = "Hi ha hagut problemes al desar la simbologia\n({})".format(
                err)
            return False

        # Fin correcto
        self.fMapa = self.fSQL
        if veure:
            self.llegenda.project.addMapLayer(mapLyr)
        return True
Beispiel #7
0
    def testEquality(self):
        # spatial extent
        extent = QgsLayerMetadata.SpatialExtent()
        extent.extentCrs = QgsCoordinateReferenceSystem.fromEpsgId(3111)
        extent.bounds = QgsBox3d(5.0, 6.0, 7.0, 11.0, 13.0, 15.0)
        extent2 = QgsLayerMetadata.SpatialExtent()
        extent2.extentCrs = QgsCoordinateReferenceSystem.fromEpsgId(3111)
        extent2.bounds = QgsBox3d(5.0, 6.0, 7.0, 11.0, 13.0, 15.0)
        self.assertEqual(extent, extent2)
        extent2.extentCrs = QgsCoordinateReferenceSystem.fromEpsgId(3113)
        self.assertNotEqual(extent, extent2)
        extent2.extentCrs = QgsCoordinateReferenceSystem.fromEpsgId(3111)
        extent2.bounds = QgsBox3d(5.0, 6.0, 7.0, 11.0, 13.0, 16.0)
        self.assertNotEqual(extent, extent2)

        # extent
        extent = QgsLayerMetadata.Extent()
        extent1 = QgsLayerMetadata.SpatialExtent()
        extent1.extentCrs = QgsCoordinateReferenceSystem.fromEpsgId(3111)
        extent1.bounds = QgsBox3d(5.0, 6.0, 7.0, 11.0, 13.0, 15.0)
        extent2 = QgsLayerMetadata.SpatialExtent()
        extent2.extentCrs = QgsCoordinateReferenceSystem.fromEpsgId(3113)
        extent2.bounds = QgsBox3d(5.0, 6.0, 7.0, 11.0, 13.0, 16.0)
        extent.setSpatialExtents([extent1, extent2])
        dates = [
            QgsDateTimeRange(
                QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47)),
                QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47))),
            QgsDateTimeRange(
                QDateTime(QDate(2010, 12, 17), QTime(9, 30, 47)),
                QDateTime(QDate(2020, 12, 17), QTime(9, 30, 47)))
        ]
        extent.setTemporalExtents(dates)
        extent_copy = QgsLayerMetadata.Extent(extent)
        self.assertEqual(extent, extent_copy)
        extent_copy.setTemporalExtents([
            QgsDateTimeRange(
                QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47)),
                QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47))),
            QgsDateTimeRange(
                QDateTime(QDate(2010, 12, 17), QTime(9, 30, 48)),
                QDateTime(QDate(2020, 12, 17), QTime(9, 30, 49)))
        ])
        self.assertNotEqual(extent, extent_copy)
        extent_copy = QgsLayerMetadata.Extent(extent)
        extent3 = QgsLayerMetadata.SpatialExtent()
        extent3.extentCrs = QgsCoordinateReferenceSystem.fromEpsgId(3113)
        extent3.bounds = QgsBox3d(5.0, 6.0, 7.0, 11.0, 13.0, 19.0)
        extent_copy.setSpatialExtents([extent1, extent3])
        self.assertNotEqual(extent, extent_copy)

        constraint = QgsLayerMetadata.Constraint('c', 'type1')
        self.assertEqual(constraint, QgsLayerMetadata.Constraint('c', 'type1'))
        self.assertNotEqual(constraint, QgsLayerMetadata.Constraint('c2', 'type1'))
        self.assertNotEqual(constraint, QgsLayerMetadata.Constraint('c', 'type2'))

        a = QgsLayerMetadata.Address()
        a.type = 'postal'
        a.address = '13 north rd'
        a.city = 'huxleys haven'
        a.administrativeArea = 'land of the queens'
        a.postalCode = '4123'
        a.country = 'straya!'
        a2 = QgsLayerMetadata.Address(a)
        self.assertEqual(a, a2)
        a2.type = 'postal2'
        self.assertNotEqual(a, a2)
        a2 = QgsLayerMetadata.Address(a)
        a2.address = 'address2'
        self.assertNotEqual(a, a2)
        a2 = QgsLayerMetadata.Address(a)
        a2.city = 'city'
        self.assertNotEqual(a, a2)
        a2 = QgsLayerMetadata.Address(a)
        a2.administrativeArea = 'area2'
        self.assertNotEqual(a, a2)
        a2 = QgsLayerMetadata.Address(a)
        a2.postalCode = 'postal2'
        self.assertNotEqual(a, a2)
        a2 = QgsLayerMetadata.Address(a)
        a2.country = 'country2'
        self.assertNotEqual(a, a2)

        c = QgsLayerMetadata.Contact()
        c.name = 'name'
        c.organization = 'org'
        c.position = 'pos'
        c.voice = '1500 515 555'
        c.fax = 'fax'
        c.email = 'email'
        c.role = 'role'
        a = QgsLayerMetadata.Address()
        a.type = 'postal'
        a2 = QgsLayerMetadata.Address()
        a2.type = 'street'
        c.addresses = [a, a2]
        c2 = QgsLayerMetadata.Contact(c)
        self.assertEqual(c, c2)
        c2.name = 'name2'
        self.assertNotEqual(c, c2)
        c2 = QgsLayerMetadata.Contact(c)
        c2.organization = 'org2'
        self.assertNotEqual(c, c2)
        c2 = QgsLayerMetadata.Contact(c)
        c2.position = 'pos2'
        self.assertNotEqual(c, c2)
        c2 = QgsLayerMetadata.Contact(c)
        c2.voice = 'voice2'
        self.assertNotEqual(c, c2)
        c2 = QgsLayerMetadata.Contact(c)
        c2.fax = 'fax2'
        self.assertNotEqual(c, c2)
        c2 = QgsLayerMetadata.Contact(c)
        c2.email = 'email2'
        self.assertNotEqual(c, c2)
        c2 = QgsLayerMetadata.Contact(c)
        c2.role = 'role2'
        self.assertNotEqual(c, c2)
        c2 = QgsLayerMetadata.Contact(c)
        c2.addresses = [a2]
        self.assertNotEqual(c, c2)

        # link
        l = QgsLayerMetadata.Link()
        l.name = 'name'
        l.type = 'type'
        l.description = 'desc'
        l.url = 'url'
        l.format = 'format'
        l.mimeType = 'mime'
        l.size = '112'
        l2 = QgsLayerMetadata.Link(l)
        self.assertEqual(l, l2)
        l2 = QgsLayerMetadata.Link(l)
        l2.name = 'name2'
        self.assertNotEqual(l, l2)
        l2 = QgsLayerMetadata.Link(l)
        l2.type = 'type2'
        self.assertNotEqual(l, l2)
        l2 = QgsLayerMetadata.Link(l)
        l2.description = 'desc2'
        self.assertNotEqual(l, l2)
        l2 = QgsLayerMetadata.Link(l)
        l2.url = 'url2'
        self.assertNotEqual(l, l2)
        l2 = QgsLayerMetadata.Link(l)
        l2.format = 'format2'
        self.assertNotEqual(l, l2)
        l2 = QgsLayerMetadata.Link(l)
        l2.mimeType = 'mime2'
        self.assertNotEqual(l, l2)
        l2 = QgsLayerMetadata.Link(l)
        l2.size = '113'
        self.assertNotEqual(l, l2)
    def testDateTimeWriteShapefile(self):
        """Check writing date and time fields to an ESRI shapefile."""
        ml = QgsVectorLayer(
            ('Point?crs=epsg:4326&field=id:int&'
             'field=date_f:date&field=time_f:time&field=dt_f:datetime'),
            'test', 'memory')

        self.assertTrue(ml.isValid())
        provider = ml.dataProvider()
        self.assertIsNotNone(provider)

        ft = QgsFeature()
        ft.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 10)))
        ft.setAttributes([
            1,
            QDate(2014, 3, 5),
            QTime(13, 45, 22),
            QDateTime(QDate(2014, 3, 5), QTime(13, 45, 22))
        ])
        res, features = provider.addFeatures([ft])
        self.assertTrue(res)
        self.assertTrue(features)

        dest_file_name = os.path.join(str(QDir.tempPath()), 'datetime.shp')
        crs = QgsCoordinateReferenceSystem()
        crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
        write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat(
            ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile')
        self.assertEqual(write_result, QgsVectorFileWriter.NoError,
                         error_message)

        # Open result and check
        created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name),
                                       'test', 'ogr')

        fields = created_layer.dataProvider().fields()
        self.assertEqual(
            fields.at(fields.indexFromName('date_f')).type(), QVariant.Date)
        # shapefiles do not support time types, result should be string
        self.assertEqual(
            fields.at(fields.indexFromName('time_f')).type(), QVariant.String)
        # shapefiles do not support datetime types, result should be string
        self.assertEqual(
            fields.at(fields.indexFromName('dt_f')).type(), QVariant.String)

        f = next(created_layer.getFeatures(QgsFeatureRequest()))

        date_idx = created_layer.fields().lookupField('date_f')
        self.assertIsInstance(f.attributes()[date_idx], QDate)
        self.assertEqual(f.attributes()[date_idx], QDate(2014, 3, 5))
        time_idx = created_layer.fields().lookupField('time_f')
        # shapefiles do not support time types
        self.assertIsInstance(f.attributes()[time_idx], str)
        self.assertEqual(f.attributes()[time_idx], '13:45:22')
        # shapefiles do not support datetime types
        datetime_idx = created_layer.fields().lookupField('dt_f')
        self.assertIsInstance(f.attributes()[datetime_idx], str)
        self.assertEqual(
            f.attributes()[datetime_idx],
            QDateTime(QDate(2014, 3, 5),
                      QTime(13, 45, 22)).toString("yyyy/MM/dd hh:mm:ss.zzz"))
    def testExpression(self):
        """ test aggregate calculation using an expression """

        # numeric
        layer = QgsVectorLayer("Point?field=fldint:integer", "layer", "memory")
        pr = layer.dataProvider()

        int_values = [4, 2, 3, 2, 5, None, 8]

        features = []
        for v in int_values:
            f = QgsFeature()
            f.setFields(layer.fields())
            f.setAttributes([v])
            features.append(f)
        assert pr.addFeatures(features)

        #int
        agg = QgsAggregateCalculator(layer)
        val, ok = agg.calculate(QgsAggregateCalculator.Sum, 'fldint * 2')
        self.assertTrue(ok)
        self.assertEqual(val, 48)

        # double
        val, ok = agg.calculate(QgsAggregateCalculator.Sum, 'fldint * 1.5')
        self.assertTrue(ok)
        self.assertEqual(val, 36)

        # datetime
        val, ok = agg.calculate(QgsAggregateCalculator.Max, "to_date('2012-05-04') + to_interval( fldint || ' day' )")
        self.assertTrue(ok)
        self.assertEqual(val, QDateTime(QDate(2012, 5, 12), QTime(0, 0, 0)))

        # date
        val, ok = agg.calculate(QgsAggregateCalculator.Min, "to_date(to_date('2012-05-04') + to_interval( fldint || ' day' ))")
        self.assertTrue(ok)
        self.assertEqual(val, QDateTime(QDate(2012, 5, 6), QTime(0, 0, 0)))

        # string
        val, ok = agg.calculate(QgsAggregateCalculator.Max, "fldint || ' oranges'")
        self.assertTrue(ok)
        self.assertEqual(val, '8 oranges')

        # geometry
        val, ok = agg.calculate(QgsAggregateCalculator.GeometryCollect, "make_point( coalesce(fldint,0), 2 )")
        self.assertTrue(ok)
        self.assertTrue(val.exportToWkt(), 'MultiPoint((4 2, 2 2, 3 2, 2 2,5 2, 0 2,8 2))')

        # try a bad expression
        val, ok = agg.calculate(QgsAggregateCalculator.Max, "not_a_field || ' oranges'")
        self.assertFalse(ok)
        val, ok = agg.calculate(QgsAggregateCalculator.Max, "5+")
        self.assertFalse(ok)

        # test expression context

        # check default context first
        # should have layer variables:
        val, ok = agg.calculate(QgsAggregateCalculator.Min, "@layer_name")
        self.assertTrue(ok)
        self.assertEqual(val, 'layer')
        # but not custom variables:
        val, ok = agg.calculate(QgsAggregateCalculator.Min, "@my_var")
        self.assertTrue(ok)
        self.assertEqual(val, NULL)

        # test with manual expression context
        scope = QgsExpressionContextScope()
        scope.setVariable('my_var', 5)
        context = QgsExpressionContext()
        context.appendScope(scope)
        val, ok = agg.calculate(QgsAggregateCalculator.Min, "@my_var", context)
        self.assertTrue(ok)
        self.assertEqual(val, 5)
Beispiel #10
0
    def createTestMetadata(self):
        """
        Returns a standard metadata which can be tested with checkExpectedMetadata
        """
        m = QgsLayerMetadata()
        m.setIdentifier('1234')
        m.setParentIdentifier('xyz')
        m.setLanguage('en-CA')
        m.setType('dataset')
        m.setTitle('roads')
        m.setAbstract('my roads')
        m.setFees('None')
        m.setConstraints([QgsLayerMetadata.Constraint('None', 'access')])
        m.setRights(['Copyright foo 2017'])
        m.setLicenses(['WTFPL'])
        m.setHistory(['history a', 'history b'])
        m.setKeywords({
            'GEMET': ['kw1', 'kw2'],
            'gmd:topicCategory': ['natural'],
        })
        m.setEncoding('utf-8')
        m.setCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4326'))

        e = QgsLayerMetadata.Extent()
        se = QgsLayerMetadata.SpatialExtent()
        se.extentCrs = QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4326')
        se.bounds = QgsBox3d(-180, -90, 0, 180, 90, 0)
        e.setSpatialExtents([se])
        dates = [
            QgsDateTimeRange(
                QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47)),
                QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47))),
            QgsDateTimeRange(
                QDateTime(QDate(2010, 12, 17), QTime(9, 30, 47)),
                QDateTime(QDate(2020, 12, 17), QTime(9, 30, 47)))
        ]
        e.setTemporalExtents(dates)
        m.setExtent(e)

        c = QgsLayerMetadata.Contact()
        c.name = 'John Smith'
        c.organization = 'ACME'
        c.position = 'staff'
        c.voice = '1500 515 555'
        c.fax = 'xx.xxx.xxx.xxxx'
        c.email = '*****@*****.**'
        c.role = 'pointOfContact'
        address = QgsLayerMetadata.Address()
        address.type = 'postal'
        address.address = '123 Main Street'
        address.city = 'anycity'
        address.administrativeArea = 'anyprovince'
        address.postalCode = '90210'
        address.country = 'Canada'
        c.addresses = [address]
        m.setContacts([c])

        l = QgsLayerMetadata.Link()
        l.name = 'geonode:roads'
        l.type = 'OGC:WMS'
        l.description = 'my GeoNode road layer'
        l.url = 'http://example.org/wms'

        l2 = QgsLayerMetadata.Link()
        l2.name = 'geonode:roads'
        l2.type = 'OGC:WFS'
        l2.description = 'my GeoNode road layer'
        l2.url = 'http://example.org/wfs'

        l3 = QgsLayerMetadata.Link()
        l3.name = 'roads'
        l3.type = 'WWW:LINK'
        l3.description = 'full dataset download'
        l3.url = 'http://example.org/roads.tgz'
        l3.format = 'ESRI Shapefile'
        l3.mimeType = 'application/gzip'
        l3.size = '283676'

        m.setLinks([l, l2, l3])

        return m
    def testExportToSvg(self):
        md = QgsProject.instance().metadata()
        md.setTitle('proj title')
        md.setAuthor('proj author')
        md.setCreationDateTime(QDateTime(QDate(2011, 5, 3), QTime(9, 4, 5), QTimeZone(36000)))
        md.setIdentifier('proj identifier')
        md.setAbstract('proj abstract')
        md.setKeywords({'kw': ['kw1', 'kw2']})
        QgsProject.instance().setMetadata(md)
        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()

        # add a second page
        page2 = QgsLayoutItemPage(l)
        page2.setPageSize('A5')
        l.pageCollection().addPage(page2)

        # add some items
        item1 = QgsLayoutItemShape(l)
        item1.attemptSetSceneRect(QRectF(10, 20, 100, 150))
        fill = QgsSimpleFillSymbolLayer()
        fill_symbol = QgsFillSymbol()
        fill_symbol.changeSymbolLayer(0, fill)
        fill.setColor(Qt.green)
        fill.setStrokeStyle(Qt.NoPen)
        item1.setSymbol(fill_symbol)
        l.addItem(item1)

        item2 = QgsLayoutItemShape(l)
        item2.attemptSetSceneRect(QRectF(10, 20, 100, 150))
        item2.attemptMove(QgsLayoutPoint(10, 20), page=1)
        fill = QgsSimpleFillSymbolLayer()
        fill_symbol = QgsFillSymbol()
        fill_symbol.changeSymbolLayer(0, fill)
        fill.setColor(Qt.cyan)
        fill.setStrokeStyle(Qt.NoPen)
        item2.setSymbol(fill_symbol)
        l.addItem(item2)

        exporter = QgsLayoutExporter(l)
        # setup settings
        settings = QgsLayoutExporter.SvgExportSettings()
        settings.dpi = 80
        settings.forceVectorOutput = False
        settings.exportMetadata = True

        svg_file_path = os.path.join(self.basetestpath, 'test_exporttosvgdpi.svg')
        svg_file_path_2 = os.path.join(self.basetestpath, 'test_exporttosvgdpi_2.svg')
        self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success)
        self.assertTrue(os.path.exists(svg_file_path))
        self.assertTrue(os.path.exists(svg_file_path_2))

        # metadata
        def checkMetadata(f, expected):
            # ideally we'd check the path too - but that's very complex given that
            # the output from Qt svg generator isn't valid XML, and no Python standard library
            # xml parser handles invalid xml...
            self.assertEqual('proj title' in open(f).read(), expected)
            self.assertEqual('proj author' in open(f).read(), expected)
            self.assertEqual('proj identifier' in open(f).read(), expected)
            self.assertEqual('2011-05-03' in open(f).read(), expected)
            self.assertEqual('proj abstract' in open(f).read(), expected)
            self.assertEqual('kw1' in open(f).read(), expected)
            self.assertEqual('kw2' in open(f).read(), expected)

        for f in [svg_file_path, svg_file_path_2]:
            checkMetadata(f, True)

        rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttosvgdpi.png')
        svgToPng(svg_file_path, rendered_page_1, width=936)
        rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttosvgdpi2.png')
        svgToPng(svg_file_path_2, rendered_page_2, width=467)

        self.assertTrue(self.checkImage('exporttosvgdpi_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1))
        self.assertTrue(self.checkImage('exporttosvgdpi_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1))

        # no metadata
        settings.exportMetadata = False
        self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success)
        for f in [svg_file_path, svg_file_path_2]:
            checkMetadata(f, False)

        # layered
        settings.exportAsLayers = True
        settings.exportMetadata = True

        svg_file_path = os.path.join(self.basetestpath, 'test_exporttosvglayered.svg')
        svg_file_path_2 = os.path.join(self.basetestpath, 'test_exporttosvglayered_2.svg')
        self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success)
        self.assertTrue(os.path.exists(svg_file_path))
        self.assertTrue(os.path.exists(svg_file_path_2))

        rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttosvglayered.png')
        svgToPng(svg_file_path, rendered_page_1, width=936)
        rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttosvglayered2.png')
        svgToPng(svg_file_path_2, rendered_page_2, width=467)

        self.assertTrue(self.checkImage('exporttosvglayered_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1))
        self.assertTrue(self.checkImage('exporttosvglayered_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1))

        for f in [svg_file_path, svg_file_path_2]:
            checkMetadata(f, True)

        # layered no metadata
        settings.exportAsLayers = True
        settings.exportMetadata = False
        self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success)
        for f in [svg_file_path, svg_file_path_2]:
            checkMetadata(f, False)
Beispiel #12
0
 def testEquality(self):
     range = QgsDateRange(QDate(2010, 3, 1), QDate(2010, 6, 2), False,
                          False)
     self.assertEqual(
         range,
         QgsDateRange(QDate(2010, 3, 1), QDate(2010, 6, 2), False, False))
     self.assertNotEqual(
         range,
         QgsDateRange(QDate(2010, 3, 1), QDate(2010, 6, 2), False, True))
     self.assertNotEqual(
         range,
         QgsDateRange(QDate(2010, 3, 1), QDate(2010, 6, 2), True, False))
     self.assertNotEqual(
         range,
         QgsDateRange(QDate(2010, 3, 1), QDate(2010, 6, 3), False, False))
     self.assertNotEqual(
         range,
         QgsDateRange(QDate(2010, 3, 2), QDate(2010, 6, 2), False, False))
    def testExportToImage(self):
        md = QgsProject.instance().metadata()
        md.setTitle('proj title')
        md.setAuthor('proj author')
        md.setCreationDateTime(QDateTime(QDate(2011, 5, 3), QTime(9, 4, 5), QTimeZone(36000)))
        md.setIdentifier('proj identifier')
        md.setAbstract('proj abstract')
        md.setKeywords({'kw': ['kw1', 'kw2'], 'KWx': ['kw3', 'kw4']})
        QgsProject.instance().setMetadata(md)
        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()

        # add a second page
        page2 = QgsLayoutItemPage(l)
        page2.setPageSize('A5')
        l.pageCollection().addPage(page2)

        # add some items
        item1 = QgsLayoutItemShape(l)
        item1.attemptSetSceneRect(QRectF(10, 20, 100, 150))
        fill = QgsSimpleFillSymbolLayer()
        fill_symbol = QgsFillSymbol()
        fill_symbol.changeSymbolLayer(0, fill)
        fill.setColor(Qt.green)
        fill.setStrokeStyle(Qt.NoPen)
        item1.setSymbol(fill_symbol)
        l.addItem(item1)

        item2 = QgsLayoutItemShape(l)
        item2.attemptSetSceneRect(QRectF(10, 20, 100, 150))
        item2.attemptMove(QgsLayoutPoint(10, 20), page=1)
        fill = QgsSimpleFillSymbolLayer()
        fill_symbol = QgsFillSymbol()
        fill_symbol.changeSymbolLayer(0, fill)
        fill.setColor(Qt.cyan)
        fill.setStrokeStyle(Qt.NoPen)
        item2.setSymbol(fill_symbol)
        l.addItem(item2)

        exporter = QgsLayoutExporter(l)
        # setup settings
        settings = QgsLayoutExporter.ImageExportSettings()
        settings.dpi = 80

        rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagedpi.png')
        self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success)

        self.assertTrue(self.checkImage('exporttoimagedpi_page1', 'exporttoimagedpi_page1', rendered_file_path))
        page2_path = os.path.join(self.basetestpath, 'test_exporttoimagedpi_2.png')
        self.assertTrue(self.checkImage('exporttoimagedpi_page2', 'exporttoimagedpi_page2', page2_path))

        for f in (rendered_file_path, page2_path):
            d = gdal.Open(f)
            metadata = d.GetMetadata()
            self.assertEqual(metadata['Author'], 'proj author')
            self.assertEqual(metadata['Created'], '2011-05-03T09:04:05+10:00')
            self.assertEqual(metadata['Keywords'], 'KWx: kw3,kw4;kw: kw1,kw2')
            self.assertEqual(metadata['Subject'], 'proj abstract')
            self.assertEqual(metadata['Title'], 'proj title')

        # crop to contents
        settings.cropToContents = True
        settings.cropMargins = QgsMargins(10, 20, 30, 40)

        rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagecropped.png')
        self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success)

        self.assertTrue(self.checkImage('exporttoimagecropped_page1', 'exporttoimagecropped_page1', rendered_file_path))
        page2_path = os.path.join(self.basetestpath, 'test_exporttoimagecropped_2.png')
        self.assertTrue(self.checkImage('exporttoimagecropped_page2', 'exporttoimagecropped_page2', page2_path))

        # specific pages
        settings.cropToContents = False
        settings.pages = [1]

        rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagepages.png')
        self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success)

        self.assertFalse(os.path.exists(rendered_file_path))
        page2_path = os.path.join(self.basetestpath, 'test_exporttoimagepages_2.png')
        self.assertTrue(self.checkImage('exporttoimagedpi_page2', 'exporttoimagedpi_page2', page2_path))

        # image size
        settings.imageSize = QSize(600, 851)
        rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagesize.png')
        self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success)
        self.assertFalse(os.path.exists(rendered_file_path))
        page2_path = os.path.join(self.basetestpath, 'test_exporttoimagesize_2.png')
        self.assertTrue(self.checkImage('exporttoimagesize_page2', 'exporttoimagesize_page2', page2_path))

        # image size with incorrect aspect ratio
        # this can happen as a result of data defined page sizes
        settings.imageSize = QSize(851, 600)
        rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagesizebadaspect.png')
        self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success)

        page2_path = os.path.join(self.basetestpath, 'test_exporttoimagesizebadaspect_2.png')
        im = QImage(page2_path)
        self.assertTrue(self.checkImage('exporttoimagesize_badaspect', 'exporttoimagedpi_page2', page2_path), '{}x{}'.format(im.width(), im.height()))
    def testExportToPdf(self):
        md = QgsProject.instance().metadata()
        md.setTitle('proj title')
        md.setAuthor('proj author')
        md.setCreationDateTime(QDateTime(QDate(2011, 5, 3), QTime(9, 4, 5), QTimeZone(36000)))
        md.setIdentifier('proj identifier')
        md.setAbstract('proj abstract')
        md.setKeywords({'kw': ['kw1', 'kw2'], 'KWx': ['kw3', 'kw4']})
        QgsProject.instance().setMetadata(md)

        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()

        # add a second page
        page2 = QgsLayoutItemPage(l)
        page2.setPageSize('A5')
        l.pageCollection().addPage(page2)

        # add some items
        item1 = QgsLayoutItemShape(l)
        item1.attemptSetSceneRect(QRectF(10, 20, 100, 150))
        fill = QgsSimpleFillSymbolLayer()
        fill_symbol = QgsFillSymbol()
        fill_symbol.changeSymbolLayer(0, fill)
        fill.setColor(Qt.green)
        fill.setStrokeStyle(Qt.NoPen)
        item1.setSymbol(fill_symbol)
        l.addItem(item1)

        item2 = QgsLayoutItemShape(l)
        item2.attemptSetSceneRect(QRectF(10, 20, 100, 150))
        item2.attemptMove(QgsLayoutPoint(10, 20), page=1)
        fill = QgsSimpleFillSymbolLayer()
        fill_symbol = QgsFillSymbol()
        fill_symbol.changeSymbolLayer(0, fill)
        fill.setColor(Qt.cyan)
        fill.setStrokeStyle(Qt.NoPen)
        item2.setSymbol(fill_symbol)
        l.addItem(item2)

        exporter = QgsLayoutExporter(l)
        # setup settings
        settings = QgsLayoutExporter.PdfExportSettings()
        settings.dpi = 80
        settings.rasterizeWholeImage = False
        settings.forceVectorOutput = False
        settings.exportMetadata = True

        pdf_file_path = os.path.join(self.basetestpath, 'test_exporttopdfdpi.pdf')
        self.assertEqual(exporter.exportToPdf(pdf_file_path, settings), QgsLayoutExporter.Success)
        self.assertTrue(os.path.exists(pdf_file_path))

        rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttopdfdpi.png')
        dpi = 80
        pdfToPng(pdf_file_path, rendered_page_1, dpi=dpi, page=1)
        rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttopdfdpi2.png')
        pdfToPng(pdf_file_path, rendered_page_2, dpi=dpi, page=2)

        self.assertTrue(self.checkImage('exporttopdfdpi_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1))
        self.assertTrue(self.checkImage('exporttopdfdpi_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1))

        d = gdal.Open(pdf_file_path)
        metadata = d.GetMetadata()
        self.assertEqual(metadata['AUTHOR'], 'proj author')
        self.assertEqual(metadata['CREATION_DATE'], "D:20110503090405+10'0'")
        self.assertEqual(metadata['KEYWORDS'], 'KWx: kw3,kw4;kw: kw1,kw2')
        self.assertEqual(metadata['SUBJECT'], 'proj abstract')
        self.assertEqual(metadata['TITLE'], 'proj title')
Beispiel #15
0
 def saveCheckingOnStartLastDate(self):
     """ set today's date as the day of last checking  """
     settings = QgsSettings()
     settings.setValue(settingsGroup + "/checkOnStartLastDate",
                       QDate.currentDate())
Beispiel #16
0
    def test_temporal_animation(self):
        """
        Test temporal animation logic
        """
        canvas = QgsMapCanvas()
        self.assertEqual(canvas.mapSettings().frameRate(), -1)
        self.assertEqual(canvas.mapSettings().currentFrame(), -1)

        controller = QgsTemporalController()
        canvas.setTemporalController(controller)
        controller.updateTemporalRange.emit(
            QgsDateTimeRange(QDateTime(QDate(2020, 1, 2), QTime(1, 2, 3)),
                             QDateTime(QDate(2020, 1, 4), QTime(1, 2, 3))))
        # should be no change
        self.assertEqual(canvas.mapSettings().frameRate(), -1)
        self.assertEqual(canvas.mapSettings().currentFrame(), -1)

        temporal_no = QgsTemporalNavigationObject()
        temporal_no.setTemporalExtents(
            QgsDateTimeRange(QDateTime(QDate(2020, 1, 2), QTime(1, 2, 3)),
                             QDateTime(QDate(2020, 1, 4), QTime(1, 2, 3))))
        temporal_no.setFrameDuration(QgsInterval(0, 0, 0, 0, 1, 0, 0))

        canvas.setTemporalController(temporal_no)
        controller.updateTemporalRange.emit(
            QgsDateTimeRange(QDateTime(QDate(2020, 1, 2), QTime(1, 2, 3)),
                             QDateTime(QDate(2020, 1, 4), QTime(1, 2, 3))))
        # should be no change
        self.assertEqual(canvas.mapSettings().frameRate(), -1)
        self.assertEqual(canvas.mapSettings().currentFrame(), -1)

        temporal_no.setFramesPerSecond(30)
        temporal_no.pause()
        temporal_no.setCurrentFrameNumber(6)
        canvas.refresh()

        # should be no change - temporal controller is not in animation mode
        self.assertEqual(canvas.mapSettings().frameRate(), -1)
        self.assertEqual(canvas.mapSettings().currentFrame(), -1)

        temporal_no.setNavigationMode(QgsTemporalNavigationObject.Animated)
        self.assertEqual(canvas.mapSettings().frameRate(), 30)
        self.assertEqual(canvas.mapSettings().currentFrame(), 6)

        temporal_no.setCurrentFrameNumber(7)
        self.assertEqual(canvas.mapSettings().frameRate(), 30)
        self.assertEqual(canvas.mapSettings().currentFrame(), 6)

        # switch off animation mode
        temporal_no.setNavigationMode(QgsTemporalNavigationObject.FixedRange)
        self.assertEqual(canvas.mapSettings().frameRate(), -1)
        self.assertEqual(canvas.mapSettings().currentFrame(), -1)

        temporal_no.setNavigationMode(QgsTemporalNavigationObject.Animated)
        self.assertEqual(canvas.mapSettings().frameRate(), 30)
        self.assertEqual(canvas.mapSettings().currentFrame(), 7)

        temporal_no.setNavigationMode(
            QgsTemporalNavigationObject.NavigationOff)
        self.assertEqual(canvas.mapSettings().frameRate(), -1)
        self.assertEqual(canvas.mapSettings().currentFrame(), -1)
from timemanager.timemanagerprojecthandler import TimeManagerProjectHandler
from timemanager.utils.tmlogging import warn  # , info

from timemanager import conf
from timemanager.layers import layer_settings
"""
The QTSlider only supports integers as the min and max, therefore the maximum maximum value
is whatever can be stored in an int. Making it a signed int to be sure.
(http://qt-project.org/doc/qt-4.8/qabstractslider.html)
"""
MAX_TIME_LENGTH_SECONDS_SLIDER = 2**31 - 1
"""
according to the docs of QDateTime, the minimum date supported is the first day of
year 100  (http://qt-project.org/doc/qt-4.8/qdatetimeedit.html#minimumDate-prop)
"""
MIN_QDATE = QDate(100, 1, 1)

DOCK_WIDGET_FILE = "dockwidget2.ui"
ADD_VECTOR_LAYER_WIDGET_FILE = "addLayer.ui"
ADD_RASTER_LAYER_WIDGET_FILE = "addRasterLayer.ui"
ARCH_WIDGET_FILE = "arch.ui"
OPTIONS_WIDGET_FILE = "options.ui"
ANIMATION_WIDGET_FILE = "animate.ui"
LABEL_OPTIONS_WIDGET_FILE = "label_options.ui"


class TimestampLabelConfig(object):
    """Object that has the settings for rendering timestamp labels. Can be customized via the UI"""
    PLACEMENTS = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']
    DEFAULT_FONT_SIZE = 25
    font = "Arial"  # Font names or family, comma-separated CSS style
    def testDualFieldMode(self):
        layer = QgsVectorLayer(
            "Point?field=fldtxt:string&field=fldint:integer&field=start_field:datetime&field=end_field:datetime",
            "test", "memory")
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.fields()[2].type(), QVariant.DateTime)
        self.assertEqual(layer.fields()[3].type(), QVariant.DateTime)

        range = QgsDateTimeRange(
            QDateTime(QDate(2019, 3, 4), QTime(11, 12, 13)),
            QDateTime(QDate(2020, 5, 6), QTime(8, 9, 10)))

        props = QgsVectorLayerTemporalProperties(enabled=False)
        props.setMode(QgsVectorLayerTemporalProperties.
                      ModeFeatureDateTimeStartAndEndFromFields)
        props.setStartField('start_field')
        props.setEndField('end_field')
        self.assertFalse(props.createFilterString(layer, range))

        props.setIsActive(True)
        self.assertEqual(
            props.createFilterString(layer, range),
            '("start_field" <= make_datetime(2020,5,6,8,9,10) OR "start_field" IS NULL) AND ("end_field" >= make_datetime(2019,3,4,11,12,13) OR "end_field" IS NULL)'
        )

        range = QgsDateTimeRange(QDateTime(QDate(2019, 3, 4),
                                           QTime(11, 12, 13)),
                                 QDateTime(QDate(2020, 5, 6), QTime(8, 9, 10)),
                                 includeBeginning=False)
        self.assertEqual(
            props.createFilterString(layer, range),
            '("start_field" <= make_datetime(2020,5,6,8,9,10) OR "start_field" IS NULL) AND ("end_field" > make_datetime(2019,3,4,11,12,13) OR "end_field" IS NULL)'
        )

        range = QgsDateTimeRange(QDateTime(QDate(2019, 3, 4),
                                           QTime(11, 12, 13)),
                                 QDateTime(QDate(2020, 5, 6), QTime(8, 9, 10)),
                                 includeEnd=False)
        self.assertEqual(
            props.createFilterString(layer, range),
            '("start_field" < make_datetime(2020,5,6,8,9,10) OR "start_field" IS NULL) AND ("end_field" >= make_datetime(2019,3,4,11,12,13) OR "end_field" IS NULL)'
        )

        props.setEndField('')
        self.assertEqual(
            props.createFilterString(layer, range),
            '"start_field" <= make_datetime(2020,5,6,8,9,10) OR "start_field" IS NULL'
        )

        range = QgsDateTimeRange(QDateTime(QDate(2019, 3, 4),
                                           QTime(11, 12, 13)),
                                 QDateTime(QDate(2020, 5, 6), QTime(8, 9, 10)),
                                 includeBeginning=False)
        self.assertEqual(
            props.createFilterString(layer, range),
            '"start_field" < make_datetime(2020,5,6,8,9,10) OR "start_field" IS NULL'
        )

        range = QgsDateTimeRange(QDateTime(QDate(2019, 3, 4),
                                           QTime(11, 12, 13)),
                                 QDateTime(QDate(2020, 5, 6), QTime(8, 9, 10)),
                                 includeEnd=False)
        self.assertEqual(
            props.createFilterString(layer, range),
            '"start_field" <= make_datetime(2020,5,6,8,9,10) OR "start_field" IS NULL'
        )

        props.setStartField('')
        props.setEndField('end_field')
        self.assertEqual(
            props.createFilterString(layer, range),
            '"end_field" >= make_datetime(2019,3,4,11,12,13) OR "end_field" IS NULL'
        )

        range = QgsDateTimeRange(QDateTime(QDate(2019, 3, 4),
                                           QTime(11, 12, 13)),
                                 QDateTime(QDate(2020, 5, 6), QTime(8, 9, 10)),
                                 includeBeginning=False)
        self.assertEqual(
            props.createFilterString(layer, range),
            '"end_field" > make_datetime(2019,3,4,11,12,13) OR "end_field" IS NULL'
        )

        range = QgsDateTimeRange(QDateTime(QDate(2019, 3, 4),
                                           QTime(11, 12, 13)),
                                 QDateTime(QDate(2020, 5, 6), QTime(8, 9, 10)),
                                 includeEnd=False)
        self.assertEqual(
            props.createFilterString(layer, range),
            '"end_field" >= make_datetime(2019,3,4,11,12,13) OR "end_field" IS NULL'
        )
Beispiel #19
0
    def testIndividualStats(self):
        # tests calculation of statistics one at a time, to make sure statistic calculations are not
        # dependent on each other
        tests = [
            {
                'stat': QgsDateTimeStatisticalSummary.Count,
                'expected': 9
            },
            {
                'stat': QgsDateTimeStatisticalSummary.CountDistinct,
                'expected': 6
            },
            {
                'stat': QgsDateTimeStatisticalSummary.CountMissing,
                'expected': 2
            },
            {
                'stat': QgsDateTimeStatisticalSummary.Min,
                'expected': QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54))
            },
            {
                'stat': QgsDateTimeStatisticalSummary.Max,
                'expected': QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1))
            },
            {
                'stat': QgsDateTimeStatisticalSummary.Range,
                'expected': QgsInterval(693871147)
            },
        ]

        # we test twice, once with values added as a list and once using values
        # added one-at-a-time
        s = QgsDateTimeStatisticalSummary()
        s3 = QgsDateTimeStatisticalSummary()
        for t in tests:
            # test constructor
            s2 = QgsDateTimeStatisticalSummary(t['stat'])
            self.assertEqual(s2.statistics(), t['stat'])

            s.setStatistics(t['stat'])
            self.assertEqual(s.statistics(), t['stat'])
            s3.setStatistics(t['stat'])

            dates = [
                QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
                QDateTime(QDate(2011, 1, 5), QTime(15, 3, 1)),
                QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
                QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
                QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1)),
                QDateTime(),
                QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54)),
                QDateTime(),
                QDateTime(QDate(2011, 1, 5), QTime(11, 10, 54))
            ]
            s.calculate(dates)
            s3.reset()
            for d in dates:
                s3.addValue(d)
            s3.finalize()

            self.assertEqual(s.statistic(t['stat']), t['expected'])
            self.assertEqual(s3.statistic(t['stat']), t['expected'])

            # display name
            self.assertTrue(
                len(QgsDateTimeStatisticalSummary.displayName(t['stat'])) > 0)
Beispiel #20
0
    def testOverlaps(self):
        # includes both ends
        range = QgsDateRange(QDate(2010, 3, 1), QDate(2010, 6, 2))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 4, 1), QDate(2010, 4, 5))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 4, 1), QDate(2010, 6, 2))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 3, 1), QDate(2010, 4, 5))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 3, 1), QDate(2010, 6, 2))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2009, 4, 1), QDate(2010, 4, 5))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 4, 1), QDate(2017, 4, 5))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 4, 1), QDate())))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(), QDate(2010, 4, 1))))
        self.assertFalse(
            range.overlaps(QgsDateRange(QDate(2009, 4, 1), QDate(2009, 8, 5))))
        self.assertFalse(
            range.overlaps(QgsDateRange(QDate(2019, 4, 1), QDate(2019, 8, 5))))

        range = QgsDateRange(QDate(), QDate(2010, 6, 2))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 4, 1), QDate(2010, 4, 5))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 4, 1), QDate(2010, 6, 2))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 3, 1), QDate(2010, 4, 5))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 3, 1), QDate(2010, 6, 2))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2009, 4, 1), QDate(2010, 4, 5))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 4, 1), QDate(2017, 4, 5))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 4, 1), QDate())))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(), QDate(2010, 4, 1))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2009, 4, 1), QDate(2009, 8, 5))))
        self.assertFalse(
            range.overlaps(QgsDateRange(QDate(2019, 4, 1), QDate(2019, 8, 5))))

        range = QgsDateRange(QDate(2010, 3, 1), QDate())
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 4, 1), QDate(2010, 4, 5))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 4, 1), QDate(2010, 6, 2))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 3, 1), QDate(2010, 4, 5))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 3, 1), QDate(2010, 6, 2))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2009, 4, 1), QDate(2010, 4, 5))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 4, 1), QDate(2017, 4, 5))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2010, 4, 1), QDate())))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(), QDate(2010, 4, 1))))
        self.assertFalse(
            range.overlaps(QgsDateRange(QDate(2009, 4, 1), QDate(2009, 8, 5))))
        self.assertTrue(
            range.overlaps(QgsDateRange(QDate(2019, 4, 1), QDate(2019, 8, 5))))
Beispiel #21
0
    def testDateTime(self):
        """ Test that datetime fields work correctly """

        endpoint = self.basetestpath + '/oid_fake_qgis_http_endpoint'
        with open(sanitize(endpoint, '?f=json'), 'wb') as f:
            f.write("""
        {"currentVersion":10.22,"id":1,"name":"QGIS Test","type":"Feature Layer","description":
        "QGIS Provider Test Layer.\n","geometryType":"esriGeometryPoint","copyrightText":"","parentLayer":{"id":0,"name":"QGIS Tests"},"subLayers":[],
        "minScale":72225,"maxScale":0,
        "defaultVisibility":true,
        "extent":{"xmin":-71.123,"ymin":66.33,"xmax":-65.32,"ymax":78.3,
        "spatialReference":{"wkid":4326,"latestWkid":4326}},
        "hasAttachments":false,"htmlPopupType":"esriServerHTMLPopupTypeAsHTMLText",
        "displayField":"LABEL","typeIdField":null,
        "fields":[{"name":"OBJECTID","type":"esriFieldTypeOID","alias":"OBJECTID","domain":null},
        {"name":"pk","type":"esriFieldTypeInteger","alias":"pk","domain":null},
        {"name":"dt","type":"esriFieldTypeDate","alias":"dt","length":8,"domain":null}],
        "relationships":[],"canModifyLayer":false,"canScaleSymbols":false,"hasLabels":false,
        "capabilities":"Map,Query,Data","maxRecordCount":1000,"supportsStatistics":true,
        "supportsAdvancedQueries":true,"supportedQueryFormats":"JSON, AMF",
        "ownershipBasedAccessControlForFeatures":{"allowOthersToQuery":true},"useStandardizedQueries":true}"""
                    .encode('UTF-8'))

        with open(
                sanitize(endpoint,
                         '/query?f=json_where=1=1&returnIdsOnly=true'),
                'wb') as f:
            f.write("""
        {
         "objectIdFieldName": "OBJECTID",
         "objectIds": [
          1,
          2
         ]
        }
        """.encode('UTF-8'))

        # Create test layer
        vl = QgsVectorLayer("url='http://" + endpoint + "' crs='epsg:4326'",
                            'test', 'arcgisfeatureserver')

        self.assertTrue(vl.isValid())
        with open(
                sanitize(
                    endpoint,
                    '/query?f=json&objectIds=1,2&inSR=4326&outSR=4326&returnGeometry=true&outFields=OBJECTID,pk,dt&returnM=false&returnZ=false'
                ), 'wb') as f:
            f.write("""
        {
         "displayFieldName": "name",
         "fieldAliases": {
          "name": "name"
         },
         "geometryType": "esriGeometryPoint",
         "spatialReference": {
          "wkid": 4326,
          "latestWkid": 4326
         },
         "fields":[{"name":"OBJECTID","type":"esriFieldTypeOID","alias":"OBJECTID","domain":null},
        {"name":"pk","type":"esriFieldTypeInteger","alias":"pk","domain":null},
        {"name":"dt","type":"esriFieldTypeDate","alias":"dt","domain":null},
        {"name":"Shape","type":"esriFieldTypeGeometry","alias":"Shape","domain":null}],
         "features": [
          {
           "attributes": {
            "OBJECTID": 1,
            "pk": 1,
            "dt":1493769600000
           },
           "geometry": {
            "x": -70.332,
            "y": 66.33
           }
          },
          {
           "attributes": {
            "OBJECTID": 2,
            "pk": 2,
            "dt":null
           },
           "geometry": {
            "x": -68.2,
            "y": 70.8
           }
          }
         ]
        }""".encode('UTF-8'))

        features = [f for f in vl.getFeatures()]
        self.assertEqual(len(features), 2)
        self.assertEqual([f['dt'] for f in features],
                         [QDate(2017, 5, 3), NULL])
    def testDateTime(self):
        """ Test calculation of aggregates on date/datetime fields"""

        layer = QgsVectorLayer("Point?field=flddate:date&field=flddatetime:datetime", "layer", "memory")
        pr = layer.dataProvider()

        # must be same length:
        datetime_values = [QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
                           QDateTime(QDate(2011, 1, 5), QTime(15, 3, 1)),
                           QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
                           QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
                           QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1)),
                           QDateTime(),
                           QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54)),
                           QDateTime(),
                           QDateTime(QDate(2011, 1, 5), QTime(11, 10, 54))]
        date_values = [QDate(2015, 3, 4),
                       QDate(2015, 3, 4),
                       QDate(2019, 12, 28),
                       QDate(),
                       QDate(1998, 1, 2),
                       QDate(),
                       QDate(2011, 1, 5),
                       QDate(2011, 1, 5),
                       QDate(2011, 1, 5)]
        self.assertEqual(len(datetime_values), len(date_values))

        features = []
        for i in range(len(datetime_values)):
            f = QgsFeature()
            f.setFields(layer.fields())
            f.setAttributes([date_values[i], datetime_values[i]])
            features.append(f)
        assert pr.addFeatures(features)

        tests = [[QgsAggregateCalculator.Count, 'flddatetime', 9],
                 [QgsAggregateCalculator.Count, 'flddate', 9],
                 [QgsAggregateCalculator.CountDistinct, 'flddatetime', 6],
                 [QgsAggregateCalculator.CountDistinct, 'flddate', 5],
                 [QgsAggregateCalculator.CountMissing, 'flddatetime', 2],
                 [QgsAggregateCalculator.CountMissing, 'flddate', 2],
                 [QgsAggregateCalculator.Min, 'flddatetime', QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54))],
                 [QgsAggregateCalculator.Min, 'flddate', QDateTime(QDate(1998, 1, 2), QTime(0, 0, 0))],
                 [QgsAggregateCalculator.Max, 'flddatetime', QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1))],
                 [QgsAggregateCalculator.Max, 'flddate', QDateTime(QDate(2019, 12, 28), QTime(0, 0, 0))],

                 [QgsAggregateCalculator.Range, 'flddatetime', QgsInterval(693871147)],
                 [QgsAggregateCalculator.Range, 'flddate', QgsInterval(693792000)],

                 ]

        agg = QgsAggregateCalculator(layer)
        for t in tests:
            val, ok = agg.calculate(t[0], t[1])
            self.assertTrue(ok)
            self.assertEqual(val, t[2])

        # bad tests - the following stats should not be calculatable for string fields
        for t in [QgsAggregateCalculator.Sum,
                  QgsAggregateCalculator.Mean,
                  QgsAggregateCalculator.Median,
                  QgsAggregateCalculator.StDev,
                  QgsAggregateCalculator.StDevSample,
                  QgsAggregateCalculator.Minority,
                  QgsAggregateCalculator.Majority,
                  QgsAggregateCalculator.FirstQuartile,
                  QgsAggregateCalculator.ThirdQuartile,
                  QgsAggregateCalculator.InterQuartileRange,
                  QgsAggregateCalculator.StringMinimumLength,
                  QgsAggregateCalculator.StringMaximumLength,
                  ]:
            val, ok = agg.calculate(t, 'flddatetime')
            self.assertFalse(ok)
Beispiel #23
0
 def testIsInfinite(self):
     self.assertFalse(QgsDateRange(QDate(2010, 3, 1), QDate(2010, 6, 2)).isInfinite())
     self.assertFalse(QgsDateRange(QDate(2010, 3, 1), QDate(2010, 3, 1)).isInfinite())
     self.assertFalse(QgsDateRange(QDate(2010, 3, 1), QDate(2010, 3, 1), False, False).isInfinite())
     self.assertTrue(QgsDateRange(QDate(), QDate()).isInfinite())
Beispiel #24
0
    def testCreateExpression(self):
        """ Test creating an expression using the widget"""
        layer = QgsVectorLayer(
            "Point?field=date:date&field=time:time&field=datetime:datetime",
            "test", "memory")

        w = QgsDateTimeSearchWidgetWrapper(layer, 0)
        config = {"field_format": 'yyyy-MM-dd', "display_format": 'yyyy-MM-dd'}
        w.setConfig(config)
        c = w.widget()

        # first check with date field type
        c.setDateTime(QDateTime(QDate(2013, 4, 5), QTime()))
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull),
                         '"date" IS NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull),
                         '"date" IS NOT NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo),
                         '"date"=\'2013-04-05\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo),
                         '"date"<>\'2013-04-05\'')
        self.assertEqual(
            w.createExpression(QgsSearchWidgetWrapper.GreaterThan),
            '"date">\'2013-04-05\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.LessThan),
                         '"date"<\'2013-04-05\'')
        self.assertEqual(
            w.createExpression(QgsSearchWidgetWrapper.GreaterThanOrEqualTo),
            '"date">=\'2013-04-05\'')
        self.assertEqual(
            w.createExpression(QgsSearchWidgetWrapper.LessThanOrEqualTo),
            '"date"<=\'2013-04-05\'')

        # time field type
        w = QgsDateTimeSearchWidgetWrapper(layer, 1)
        config = {"field_format": 'HH:mm:ss', "display_format": 'HH:mm:ss'}
        w.setConfig(config)
        c = w.widget()

        c.setDateTime(QDateTime(QDate(2013, 4, 5), QTime(13, 14, 15)))
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull),
                         '"time" IS NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull),
                         '"time" IS NOT NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo),
                         '"time"=\'13:14:15\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo),
                         '"time"<>\'13:14:15\'')
        self.assertEqual(
            w.createExpression(QgsSearchWidgetWrapper.GreaterThan),
            '"time">\'13:14:15\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.LessThan),
                         '"time"<\'13:14:15\'')
        self.assertEqual(
            w.createExpression(QgsSearchWidgetWrapper.GreaterThanOrEqualTo),
            '"time">=\'13:14:15\'')
        self.assertEqual(
            w.createExpression(QgsSearchWidgetWrapper.LessThanOrEqualTo),
            '"time"<=\'13:14:15\'')

        # datetime field type
        w = QgsDateTimeSearchWidgetWrapper(layer, 2)
        config = {
            "field_format": 'yyyy-MM-dd HH:mm:ss',
            "display_format": 'yyyy-MM-dd HH:mm:ss'
        }
        w.setConfig(config)
        c = w.widget()

        c.setDateTime(QDateTime(QDate(2013, 4, 5), QTime(13, 14, 15)))
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull),
                         '"datetime" IS NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull),
                         '"datetime" IS NOT NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo),
                         '"datetime"=\'2013-04-05 13:14:15\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo),
                         '"datetime"<>\'2013-04-05 13:14:15\'')
        self.assertEqual(
            w.createExpression(QgsSearchWidgetWrapper.GreaterThan),
            '"datetime">\'2013-04-05 13:14:15\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.LessThan),
                         '"datetime"<\'2013-04-05 13:14:15\'')
        self.assertEqual(
            w.createExpression(QgsSearchWidgetWrapper.GreaterThanOrEqualTo),
            '"datetime">=\'2013-04-05 13:14:15\'')
        self.assertEqual(
            w.createExpression(QgsSearchWidgetWrapper.LessThanOrEqualTo),
            '"datetime"<=\'2013-04-05 13:14:15\'')
Beispiel #25
0
    def testIsEmpty(self):
        range = QgsDateRange(QDate(2010, 3, 1), QDate(2010, 6, 2))
        self.assertFalse(range.isEmpty())

        range = QgsDateRange(QDate(), QDate(2010, 6, 2))
        self.assertFalse(range.isEmpty())

        range = QgsDateRange(QDate(2010, 3, 1), QDate())
        self.assertFalse(range.isEmpty())

        range = QgsDateRange(QDate(), QDate())
        self.assertTrue(range.isEmpty())

        range = QgsDateRange(QDate(2017, 3, 1), QDate(2010, 6, 2))
        self.assertTrue(range.isEmpty())

        range = QgsDateRange(QDate(2010, 3, 1), QDate(2010, 3, 1))
        self.assertFalse(range.isEmpty())

        range = QgsDateRange(QDate(2010, 3, 1), QDate(2010, 3, 1), False,
                             False)
        self.assertTrue(range.isEmpty())
Beispiel #26
0
    def checkExpectedMetadata(self, m):
        """
        Checks that a metadata object matches that returned by createTestMetadata
        """
        self.assertEqual(m.identifier(), '1234')
        self.assertEqual(m.parentIdentifier(), 'xyz')
        self.assertEqual(m.language(), 'en-CA')
        self.assertEqual(m.type(), 'dataset')
        self.assertEqual(m.title(), 'roads')
        self.assertEqual(m.abstract(), 'my roads')
        self.assertEqual(m.fees(), 'None')
        self.assertEqual(m.constraints()[0].constraint, 'None')
        self.assertEqual(m.constraints()[0].type, 'access')
        self.assertEqual(m.rights(), ['Copyright foo 2017'])
        self.assertEqual(m.licenses(), ['WTFPL'])
        self.assertEqual(m.history(), ['history a', 'history b'])
        self.assertEqual(m.encoding(), 'utf-8')
        self.assertEqual(
            m.keywords(),
            {'GEMET': ['kw1', 'kw2'], 'gmd:topicCategory': ['natural']})
        self.assertEqual(m.crs().authid(), 'EPSG:4326')

        extent = m.extent().spatialExtents()[0]
        self.assertEqual(extent.extentCrs.authid(), 'EPSG:4326')
        self.assertEqual(extent.bounds.xMinimum(), -180.0)
        self.assertEqual(extent.bounds.yMinimum(), -90.0)
        self.assertEqual(extent.bounds.xMaximum(), 180.0)
        self.assertEqual(extent.bounds.yMaximum(), 90.0)
        self.assertEqual(m.extent().temporalExtents()[0].begin(), QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47)))
        self.assertTrue(m.extent().temporalExtents()[0].isInstant())
        self.assertFalse(m.extent().temporalExtents()[1].isInstant())
        self.assertEqual(m.extent().temporalExtents()[1].end(), QDateTime(QDate(2020, 12, 17), QTime(9, 30, 47)))

        self.assertEqual(m.contacts()[0].name, 'John Smith')
        self.assertEqual(m.contacts()[0].organization, 'ACME')
        self.assertEqual(m.contacts()[0].position, 'staff')
        self.assertEqual(m.contacts()[0].voice, '1500 515 555')
        self.assertEqual(m.contacts()[0].fax, 'xx.xxx.xxx.xxxx')
        self.assertEqual(m.contacts()[0].email, '*****@*****.**')
        self.assertEqual(m.contacts()[0].role, 'pointOfContact')
        self.assertEqual(m.contacts()[0].addresses[0].type, 'postal')
        self.assertEqual(m.contacts()[0].addresses[0].address, '123 Main Street')
        self.assertEqual(m.contacts()[0].addresses[0].city, 'anycity')
        self.assertEqual(m.contacts()[0].addresses[0].administrativeArea, 'anyprovince')
        self.assertEqual(m.contacts()[0].addresses[0].postalCode, '90210')
        self.assertEqual(m.contacts()[0].addresses[0].country, 'Canada')
        self.assertEqual(m.links()[0].name, 'geonode:roads')
        self.assertEqual(m.links()[0].type, 'OGC:WMS')
        self.assertEqual(m.links()[0].description, 'my GeoNode road layer')
        self.assertEqual(m.links()[0].url, 'http://example.org/wms')
        self.assertEqual(m.links()[1].name, 'geonode:roads')
        self.assertEqual(m.links()[1].type, 'OGC:WFS')
        self.assertEqual(m.links()[1].description, 'my GeoNode road layer')
        self.assertEqual(m.links()[1].url, 'http://example.org/wfs')
        self.assertEqual(m.links()[2].name, 'roads')
        self.assertEqual(m.links()[2].type, 'WWW:LINK')
        self.assertEqual(m.links()[2].description, 'full dataset download')
        self.assertEqual(m.links()[2].url, 'http://example.org/roads.tgz')
        self.assertEqual(m.links()[2].format, 'ESRI Shapefile')
        self.assertEqual(m.links()[2].mimeType, 'application/gzip')
        self.assertEqual(m.links()[2].size, '283676')
Beispiel #27
0
    def testProjectMode(self):
        """
        Create a fully populated QgsProjectMetadata object, then set it to the widget and re-read back
        the generated metadata to ensure that no content is lost.
        """
        w = QgsMetadataWidget()

        m = QgsProjectMetadata()
        m.setIdentifier('1234')
        m.setParentIdentifier('xyz')
        m.setLanguage('en-CA')
        m.setType('project')
        m.setTitle('roads')
        m.setAbstract('my roads')
        m.setHistory(['history a', 'history b'])
        m.setKeywords({
            'GEMET': ['kw1', 'kw2'],
            'gmd:topicCategory': ['natural'],
        })

        c = QgsAbstractMetadataBase.Contact()
        c.name = 'John Smith'
        c.organization = 'ACME'
        c.position = 'staff'
        c.voice = '1500 515 555'
        c.fax = 'xx.xxx.xxx.xxxx'
        c.email = '*****@*****.**'
        c.role = 'pointOfContact'
        address = QgsAbstractMetadataBase.Address()
        address.type = 'postal'
        address.address = '123 Main Street'
        address.city = 'anycity'
        address.administrativeArea = 'anyprovince'
        address.postalCode = '90210'
        address.country = 'Canada'
        c.addresses = [address]
        m.setContacts([c])

        l = QgsAbstractMetadataBase.Link()
        l.name = 'geonode:roads'
        l.type = 'OGC:WMS'
        l.description = 'my GeoNode road layer'
        l.url = 'http://example.org/wms'

        l2 = QgsAbstractMetadataBase.Link()
        l2.name = 'geonode:roads'
        l2.type = 'OGC:WFS'
        l2.description = 'my GeoNode road layer'
        l2.url = 'http://example.org/wfs'

        l3 = QgsAbstractMetadataBase.Link()
        l3.name = 'roads'
        l3.type = 'WWW:LINK'
        l3.description = 'full dataset download'
        l3.url = 'http://example.org/roads.tgz'
        l3.format = 'ESRI Shapefile'
        l3.mimeType = 'application/gzip'
        l3.size = '283676'

        m.setLinks([l, l2, l3])

        m.setAuthor('my author')
        m.setCreationDateTime(QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47)))

        # set widget metadata
        w.setMetadata(m)
        self.assertEqual(w.mode(), QgsMetadataWidget.ProjectMetadata)

        m = w.metadata()
        self.assertIsInstance(m, QgsProjectMetadata)

        self.assertEqual(m.identifier(), '1234')
        self.assertEqual(m.parentIdentifier(), 'xyz')
        self.assertEqual(m.language(), 'en-CA')
        self.assertEqual(m.type(), 'project')
        self.assertEqual(m.title(), 'roads')
        self.assertEqual(m.abstract(), 'my roads')
        self.assertEqual(m.history(), ['history a', 'history b'])
        self.assertEqual(
            m.keywords(),
            {'GEMET': ['kw1', 'kw2'], 'gmd:topicCategory': ['natural']})

        self.assertEqual(m.contacts()[0].name, 'John Smith')
        self.assertEqual(m.contacts()[0].organization, 'ACME')
        self.assertEqual(m.contacts()[0].position, 'staff')
        self.assertEqual(m.contacts()[0].voice, '1500 515 555')
        self.assertEqual(m.contacts()[0].fax, 'xx.xxx.xxx.xxxx')
        self.assertEqual(m.contacts()[0].email, '*****@*****.**')
        self.assertEqual(m.contacts()[0].role, 'pointOfContact')
        self.assertEqual(m.contacts()[0].addresses[0].type, 'postal')
        self.assertEqual(m.contacts()[0].addresses[0].address, '123 Main Street')
        self.assertEqual(m.contacts()[0].addresses[0].city, 'anycity')
        self.assertEqual(m.contacts()[0].addresses[0].administrativeArea, 'anyprovince')
        self.assertEqual(m.contacts()[0].addresses[0].postalCode, '90210')
        self.assertEqual(m.contacts()[0].addresses[0].country, 'Canada')
        self.assertEqual(m.links()[0].name, 'geonode:roads')
        self.assertEqual(m.links()[0].type, 'OGC:WMS')
        self.assertEqual(m.links()[0].description, 'my GeoNode road layer')
        self.assertEqual(m.links()[0].url, 'http://example.org/wms')
        self.assertEqual(m.links()[1].name, 'geonode:roads')
        self.assertEqual(m.links()[1].type, 'OGC:WFS')
        self.assertEqual(m.links()[1].description, 'my GeoNode road layer')
        self.assertEqual(m.links()[1].url, 'http://example.org/wfs')
        self.assertEqual(m.links()[2].name, 'roads')
        self.assertEqual(m.links()[2].type, 'WWW:LINK')
        self.assertEqual(m.links()[2].description, 'full dataset download')
        self.assertEqual(m.links()[2].url, 'http://example.org/roads.tgz')
        self.assertEqual(m.links()[2].format, 'ESRI Shapefile')
        self.assertEqual(m.links()[2].mimeType, 'application/gzip')
        self.assertEqual(m.links()[2].size, '283676')

        self.assertEqual(m.author(), 'my author')
        self.assertEqual(m.creationDateTime(), QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47)))
    def createTestMetadata(self):
        """
        Returns a standard metadata which can be tested with checkExpectedMetadata
        """
        m = QgsProjectMetadata()
        m.setIdentifier('1234')
        m.setParentIdentifier('xyz')
        m.setLanguage('en-CA')
        m.setType('project')
        m.setTitle('roads')
        m.setAbstract('my roads')
        m.setHistory(['history a', 'history b'])
        m.setKeywords({
            'GEMET': ['kw1', 'kw2'],
            'gmd:topicCategory': ['natural'],
        })

        c = QgsAbstractMetadataBase.Contact()
        c.name = 'John Smith'
        c.organization = 'ACME'
        c.position = 'staff'
        c.voice = '1500 515 555'
        c.fax = 'xx.xxx.xxx.xxxx'
        c.email = '*****@*****.**'
        c.role = 'pointOfContact'
        address = QgsAbstractMetadataBase.Address()
        address.type = 'postal'
        address.address = '123 Main Street'
        address.city = 'anycity'
        address.administrativeArea = 'anyprovince'
        address.postalCode = '90210'
        address.country = 'Canada'
        c.addresses = [address]
        m.setContacts([c])

        l = QgsAbstractMetadataBase.Link()
        l.name = 'geonode:roads'
        l.type = 'OGC:WMS'
        l.description = 'my GeoNode road layer'
        l.url = 'http://example.org/wms'

        l2 = QgsAbstractMetadataBase.Link()
        l2.name = 'geonode:roads'
        l2.type = 'OGC:WFS'
        l2.description = 'my GeoNode road layer'
        l2.url = 'http://example.org/wfs'

        l3 = QgsAbstractMetadataBase.Link()
        l3.name = 'roads'
        l3.type = 'WWW:LINK'
        l3.description = 'full dataset download'
        l3.url = 'http://example.org/roads.tgz'
        l3.format = 'ESRI Shapefile'
        l3.mimeType = 'application/gzip'
        l3.size = '283676'

        m.setLinks([l, l2, l3])

        m.setAuthor('my author')
        m.setCreationDateTime(QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47)))

        return m
Beispiel #29
0
    def processAlgorithm(self, feedback):
        inLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))
        boundary = self.getParameterValue(self.MODE) == self.MODE_BOUNDARY
        smallestArea = self.getParameterValue(self.MODE) == self.MODE_SMALLEST_AREA
        keepSelection = self.getParameterValue(self.KEEPSELECTION)
        processLayer = vector.duplicateInMemory(inLayer)

        if not keepSelection:
            # Make a selection with the values provided
            attribute = self.getParameterValue(self.ATTRIBUTE)
            comparison = self.comparisons[self.getParameterValue(self.COMPARISON)]
            comparisonvalue = self.getParameterValue(self.COMPARISONVALUE)

            selectindex = vector.resolveFieldIndex(processLayer, attribute)
            selectType = processLayer.fields()[selectindex].type()
            selectionError = False

            if selectType in [QVariant.Int, QVariant.LongLong, QVariant.UInt, QVariant.ULongLong]:
                try:
                    y = int(comparisonvalue)
                except ValueError:
                    selectionError = True
                    msg = self.tr('Cannot convert "%s" to integer' % str(comparisonvalue))
            elif selectType == QVariant.Double:
                try:
                    y = float(comparisonvalue)
                except ValueError:
                    selectionError = True
                    msg = self.tr('Cannot convert "%s" to float' % str(comparisonvalue))
            elif selectType == QVariant.String:
                # 10: string, boolean
                try:
                    y = str(comparisonvalue)
                except ValueError:
                    selectionError = True
                    msg = self.tr('Cannot convert "%s" to Unicode' % str(comparisonvalue))
            elif selectType == QVariant.Date:
                # date
                dateAndFormat = comparisonvalue.split(' ')

                if len(dateAndFormat) == 1:
                    # QDate object
                    y = QLocale.system().toDate(dateAndFormat[0])

                    if y.isNull():
                        msg = self.tr('Cannot convert "%s" to date with system date format %s' % (str(dateAndFormat), QLocale.system().dateFormat()))
                elif len(dateAndFormat) == 2:
                    y = QDate.fromString(dateAndFormat[0], dateAndFormat[1])

                    if y.isNull():
                        msg = self.tr('Cannot convert "%s" to date with format string "%s"' % (str(dateAndFormat[0]), dateAndFormat[1]))
                else:
                    y = QDate()
                    msg = ''

                if y.isNull():
                    # Conversion was unsuccessful
                    selectionError = True
                    msg += self.tr('Enter the date and the date format, e.g. "07.26.2011" "MM.dd.yyyy".')

            if (comparison == 'begins with' or comparison == 'contains') \
               and selectType != QVariant.String:
                selectionError = True
                msg = self.tr('"%s" can only be used with string fields' % comparison)

            selected = []

            if selectionError:
                raise GeoAlgorithmExecutionException(
                    self.tr('Error in selection input: %s' % msg))
            else:
                for feature in processLayer.getFeatures():
                    aValue = feature.attributes()[selectindex]

                    if aValue is None:
                        continue

                    if selectType in [QVariant.Int, QVariant.LongLong, QVariant.UInt, QVariant.ULongLong]:
                        x = int(aValue)
                    elif selectType == QVariant.Double:
                        x = float(aValue)
                    elif selectType == QVariant.String:
                        # 10: string, boolean
                        x = str(aValue)
                    elif selectType == QVariant.Date:
                        # date
                        x = aValue  # should be date

                    match = False

                    if comparison == '==':
                        match = x == y
                    elif comparison == '!=':
                        match = x != y
                    elif comparison == '>':
                        match = x > y
                    elif comparison == '>=':
                        match = x >= y
                    elif comparison == '<':
                        match = x < y
                    elif comparison == '<=':
                        match = x <= y
                    elif comparison == 'begins with':
                        match = x.startswith(y)
                    elif comparison == 'contains':
                        match = x.find(y) >= 0

                    if match:
                        selected.append(feature.id())

            processLayer.selectByIds(selected)

        if processLayer.selectedFeatureCount() == 0:
            ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
                                   self.tr('%s: (No selection in input layer "%s")' % (self.commandLineName(), self.getParameterValue(self.INPUT))))

        # Keep references to the features to eliminate
        featToEliminate = []
        for aFeat in processLayer.selectedFeatures():
            featToEliminate.append(aFeat)

        # Delete all features to eliminate in processLayer (we won't save this)
        processLayer.startEditing()
        processLayer.deleteSelectedFeatures()

        # ANALYZE
        if len(featToEliminate) > 0:  # Prevent zero division
            start = 20.00
            add = 80.00 / len(featToEliminate)
        else:
            start = 100

        feedback.setProgress(start)
        madeProgress = True

        # We go through the list and see if we find any polygons we can
        # merge the selected with. If we have no success with some we
        # merge and then restart the whole story.
        while madeProgress:  # Check if we made any progress
            madeProgress = False
            featNotEliminated = []

            # Iterate over the polygons to eliminate
            for i in range(len(featToEliminate)):
                feat = featToEliminate.pop()
                geom2Eliminate = feat.geometry()
                bbox = geom2Eliminate.boundingBox()
                fit = processLayer.getFeatures(
                    QgsFeatureRequest().setFilterRect(bbox).setSubsetOfAttributes([]))
                mergeWithFid = None
                mergeWithGeom = None
                max = 0
                min = -1
                selFeat = QgsFeature()

                # use prepared geometries for faster intersection tests
                engine = QgsGeometry.createGeometryEngine(geom2Eliminate.geometry())
                engine.prepareGeometry()

                while fit.nextFeature(selFeat):
                    selGeom = selFeat.geometry()

                    if engine.intersects(selGeom.geometry()):
                        # We have a candidate
                        iGeom = geom2Eliminate.intersection(selGeom)

                        if not iGeom:
                            continue

                        if boundary:
                            selValue = iGeom.length()
                        else:
                            # area. We need a common boundary in
                            # order to merge
                            if 0 < iGeom.length():
                                selValue = selGeom.area()
                            else:
                                selValue = -1

                        if -1 != selValue:
                            useThis = True

                            if smallestArea:
                                if -1 == min:
                                    min = selValue
                                else:
                                    if selValue < min:
                                        min = selValue
                                    else:
                                        useThis = False
                            else:
                                if selValue > max:
                                    max = selValue
                                else:
                                    useThis = False

                            if useThis:
                                mergeWithFid = selFeat.id()
                                mergeWithGeom = QgsGeometry(selGeom)
                # End while fit

                if mergeWithFid is not None:
                    # A successful candidate
                    newGeom = mergeWithGeom.combine(geom2Eliminate)

                    if processLayer.changeGeometry(mergeWithFid, newGeom):
                        madeProgress = True
                    else:
                        raise GeoAlgorithmExecutionException(
                            self.tr('Could not replace geometry of feature with id %s' % mergeWithFid))

                    start = start + add
                    feedback.setProgress(start)
                else:
                    featNotEliminated.append(feat)

            # End for featToEliminate

            featToEliminate = featNotEliminated

        # End while

        # Create output
        output = self.getOutputFromName(self.OUTPUT)
        writer = output.getVectorWriter(processLayer.fields(),
                                        processLayer.wkbType(), processLayer.crs())

        # Write all features that are left over to output layer
        iterator = processLayer.getFeatures()
        for feature in iterator:
            writer.addFeature(feature)

        # Leave processLayer untouched
        processLayer.rollBack()

        for feature in featNotEliminated:
            writer.addFeature(feature)
 def testVariantStats(self):
     """ test with non-datetime values """
     s = QgsDateTimeStatisticalSummary()
     self.assertEqual(s.statistics(), QgsDateTimeStatisticalSummary.All)
     s.calculate([
         QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)), 'asdasd',
         QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)), 34,
         QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1)),
         QDateTime(),
         QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54)),
         QDateTime(),
         QDateTime(QDate(2011, 1, 5), QTime(11, 10, 54))
     ])
     self.assertEqual(s.count(), 9)
     self.assertEqual(
         set(s.distinctValues()),
         set([
             QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
             QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1)),
             QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54)),
             QDateTime(QDate(2011, 1, 5), QTime(11, 10, 54)),
             QDateTime()
         ]))
     self.assertEqual(s.countMissing(), 4)
     self.assertEqual(s.min(), QDateTime(QDate(1998, 1, 2),
                                         QTime(1, 10, 54)))
     self.assertEqual(s.max(),
                      QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1)))
     self.assertEqual(s.range(), QgsInterval(693871147))
Beispiel #31
0
 def saveCheckingOnStartLastDate(self):
     """ set today's date as the day of last checking  """
     settings = QgsSettings()
     settings.setValue(settingsGroup + "/checkOnStartLastDate", QDate.currentDate())
    def testStats(self):
        # we test twice, once with values added as a list and once using values
        # added one-at-a-time

        dates = [
            QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
            QDateTime(QDate(2011, 1, 5), QTime(15, 3, 1)),
            QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
            QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
            QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1)),
            QDateTime(),
            QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54)),
            QDateTime(),
            QDateTime(QDate(2011, 1, 5), QTime(11, 10, 54))
        ]
        s = QgsDateTimeStatisticalSummary()
        self.assertEqual(s.statistics(), QgsDateTimeStatisticalSummary.All)
        s.calculate(dates)
        s2 = QgsDateTimeStatisticalSummary()
        for d in dates:
            s2.addValue(d)
        s2.finalize()
        self.assertEqual(s.count(), 9)
        self.assertEqual(s2.count(), 9)
        self.assertEqual(s.countDistinct(), 6)
        self.assertEqual(s2.countDistinct(), 6)
        self.assertEqual(
            set(s.distinctValues()),
            set([
                QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
                QDateTime(QDate(2011, 1, 5), QTime(15, 3, 1)),
                QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1)),
                QDateTime(),
                QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54)),
                QDateTime(QDate(2011, 1, 5), QTime(11, 10, 54))
            ]))
        self.assertEqual(s2.distinctValues(), s.distinctValues())
        self.assertEqual(s.countMissing(), 2)
        self.assertEqual(s2.countMissing(), 2)
        self.assertEqual(s.min(), QDateTime(QDate(1998, 1, 2),
                                            QTime(1, 10, 54)))
        self.assertEqual(s2.min(),
                         QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54)))
        self.assertEqual(s.max(),
                         QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1)))
        self.assertEqual(s2.max(),
                         QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1)))
        self.assertEqual(s.range(), QgsInterval(693871147))
        self.assertEqual(s2.range(), QgsInterval(693871147))
	def _onPointClicked(self, ps_layer, point):
		# get the id of the point feature under the mouse click
		from .MapTools import FeatureFinder
		fid = FeatureFinder.findAtPoint(ps_layer, point, canvas=self.iface.mapCanvas(), onlyTheClosestOne=True, onlyIds=True)
		if fid is None:
			return

		# get the attribute map of the selected feature
		feat = QgsFeature()
		feats = ps_layer.getFeatures( QgsFeatureRequest(fid) )
		feats.nextFeature(feat)
		attrs = feat.attributes()

		x, y = [], []	# lists containg x,y values
		infoFields = {}	# hold the index->name of the fields containing info to be displayed

		ps_source = ps_layer.source()
		ps_fields = ps_layer.dataProvider().fields()

		providerType = ps_layer.providerType()
		uri = ps_source
		subset = ""

		if providerType == 'ogr' and ps_source.lower().endswith( ".shp" ):
			# Shapefile
			for idx, fld in enumerate(ps_fields):
				if QRegExp( "D\\d{8}", Qt.CaseInsensitive ).indexIn( fld.name() ) < 0:
					# info fields are all except those containing dates
					infoFields[ idx ] = fld
				else:
					x.append( QDate.fromString( fld.name()[1:], "yyyyMMdd" ).toPyDate() )
					y.append( float(attrs[ idx ]) )

		elif providerType == 'ogr' and (ps_source.upper().startswith("OCI:") or ps_source.lower().endswith(".vrt")):	# Oracle Spatial

			# fields containing values
			dateField = "data_misura"
			valueField = "spost_rel_mm"
			infoFields = dict(enumerate(ps_fields))

			# search for the id_dataset and code_target fields needed to join
			# PS and TS tables
			idDataset = codeTarget = None
			for idx, fld in enumerate(ps_fields):
				if fld.name().lower() == "id_dataset":
					idDataset = attrs[ idx ]
				if fld.name().lower() == "code_target":
					codeTarget = attrs[ idx ]

			if idDataset is None or codeTarget is None:
				QgsMessageLog.logMessage( "idDataset is %s, codeTarget is %s. Exiting" % (idDataset, codeTarget), "PSTimeSeriesViewer" )
				return
			subset = "id_dataset='%s' AND code_target='%s'" % (idDataset, codeTarget)

			# create the uri
			if ps_source.upper().startswith( "OCI:" ):
				default_tbl_name = "RISKNAT.RNAT_TARGET_SSTO"
			elif ps_source.lower().endswith(".vrt"):
				default_tbl_name = "rnat_target_sso.vrt"
			else:
				default_tbl_name = ""
			if not self._askTStablename( ps_layer,  default_tbl_name ):
				return

			if ps_source.upper().startswith( "OCI:" ):
				# uri is like OCI:userid/password@database:table
				pos = uri.indexOf(':', 4)
				if pos >= 0:
					uri = uri[0:pos]
				uri = "%s:%s" % (uri, self.ts_tablename)
			else:
				# it's a VRT file
				uri = "%s/%s" % (QFileInfo(ps_source).path(), self.ts_tablename)
				uri = QDir.toNativeSeparators( uri )

			# load the layer containing time series
			ts_layer = self._createTSlayer( uri, providerType, subset )
			if ts_layer is None:
				return

			# get time series X and Y values
			try:
				x, y = self._getXYvalues( ts_layer, dateField, valueField )
			finally:
				ts_layer.deleteLater()
				del ts_layer

		elif providerType in ['postgres', 'spatialite']:# either PostGIS or SpatiaLite

			# fields containing values
			dateField = "dataripresa"
			valueField = "valore"
			infoFields = dict(enumerate(ps_fields))

			# search for the id_dataset and code_target fields needed to join
			# PS and TS tables
			code = None
			for idx, fld in enumerate( ps_fields ):
				if fld.name().lower() == "code":
					code = attrs[ idx ]

			if code is None:
				QgsMessageLog.logMessage( "code is None. Exiting" % code, "PSTimeSeriesViewer" )
				return
			subset = "code='%s'" % code

			# create the uri
			dsuri = QgsDataSourceUri( ps_layer.source() )
			default_tbl_name = "ts_%s" % dsuri.table()
			if not self._askTStablename( ps_layer,  default_tbl_name ):
				return
			dsuri.setDataSource( dsuri.schema(), self.ts_tablename, None ) # None or "" ? check during tests
			dsuri.setWkbType(QgsWkbTypes.Unknown)
			dsuri.setSrid(None)
			uri = dsuri.uri()

			# load the layer containing time series
			ts_layer = self._createTSlayer( uri, providerType, subset )
			if ts_layer is None:
				return

			# get time series X and Y values
			try:
				x, y = self._getXYvalues( ts_layer, dateField, valueField )
			finally:
				ts_layer.deleteLater()
				del ts_layer

		if len(x) * len(y) <= 0:
			QMessageBox.warning( self.iface.mainWindow(),
					"PS Time Series Viewer",
					"No time series values found for the selected point." )
			QgsMessageLog.logMessage( "provider: %s - uri: %s\nsubset: %s" % (providerType, uri, subset), "PSTimeSeriesViewer" )
			return

		# display the plot dialog
		from .pstimeseries_dlg import PSTimeSeries_Dlg
		dlg = PSTimeSeries_Dlg( ps_layer, infoFields )
		dlg.setFeatureId( fid )
		dlg.setData( x, y )
		return dlg
Beispiel #34
0
    def testLayerMode(self):
        """
        Create a fully populated QgsLayerMetadata object, then set it to the widget and re-read back
        the generated metadata to ensure that no content is lost.
        """
        w = QgsMetadataWidget()

        m = QgsLayerMetadata()
        m.setIdentifier('1234')
        m.setParentIdentifier('xyz')
        m.setLanguage('en-CA')
        m.setType('dataset')
        m.setTitle('roads')
        m.setAbstract('my roads')
        m.setFees('None')
        m.setConstraints([QgsLayerMetadata.Constraint('None', 'access')])
        m.setRights(['Copyright foo 2017'])
        m.setLicenses(['WTFPL'])
        m.setHistory(['history a', 'history b'])
        m.setKeywords({
            'GEMET': ['kw1', 'kw2'],
            'gmd:topicCategory': ['natural'],
        })
        #m.setEncoding('utf-8')
        m.setCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4326'))

        e = QgsLayerMetadata.Extent()
        se = QgsLayerMetadata.SpatialExtent()
        se.extentCrs = QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4326')
        se.bounds = QgsBox3d(-180, -90, 0, 180, 90, 0)
        e.setSpatialExtents([se])
        dates = [
            QgsDateTimeRange(
                QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47)),
                QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47)))
        ]
        e.setTemporalExtents(dates)
        m.setExtent(e)

        c = QgsLayerMetadata.Contact()
        c.name = 'John Smith'
        c.organization = 'ACME'
        c.position = 'staff'
        c.voice = '1500 515 555'
        c.fax = 'xx.xxx.xxx.xxxx'
        c.email = '*****@*****.**'
        c.role = 'pointOfContact'
        address = QgsLayerMetadata.Address()
        address.type = 'postal'
        address.address = '123 Main Street'
        address.city = 'anycity'
        address.administrativeArea = 'anyprovince'
        address.postalCode = '90210'
        address.country = 'Canada'
        c.addresses = [address]
        m.setContacts([c])

        l = QgsLayerMetadata.Link()
        l.name = 'geonode:roads'
        l.type = 'OGC:WMS'
        l.description = 'my GeoNode road layer'
        l.url = 'http://example.org/wms'

        l2 = QgsLayerMetadata.Link()
        l2.name = 'geonode:roads'
        l2.type = 'OGC:WFS'
        l2.description = 'my GeoNode road layer'
        l2.url = 'http://example.org/wfs'

        l3 = QgsLayerMetadata.Link()
        l3.name = 'roads'
        l3.type = 'WWW:LINK'
        l3.description = 'full dataset download'
        l3.url = 'http://example.org/roads.tgz'
        l3.format = 'ESRI Shapefile'
        l3.mimeType = 'application/gzip'
        l3.size = '283676'

        m.setLinks([l, l2, l3])

        # set widget metadata
        w.setMetadata(m)
        self.assertEqual(w.mode(), QgsMetadataWidget.LayerMetadata)

        m = w.metadata()
        self.assertIsInstance(m, QgsLayerMetadata)

        self.assertEqual(m.identifier(), '1234')
        self.assertEqual(m.parentIdentifier(), 'xyz')
        self.assertEqual(m.language(), 'en-CA')
        self.assertEqual(m.type(), 'dataset')
        self.assertEqual(m.title(), 'roads')
        self.assertEqual(m.abstract(), 'my roads')
        self.assertEqual(m.fees(), 'None')
        self.assertEqual(m.constraints()[0].constraint, 'None')
        self.assertEqual(m.constraints()[0].type, 'access')
        self.assertEqual(m.rights(), ['Copyright foo 2017'])
        self.assertEqual(m.licenses(), ['WTFPL'])
        self.assertEqual(m.history(), ['history a', 'history b'])
        #self.assertEqual(m.encoding(), 'utf-8')
        self.assertEqual(
            m.keywords(),
            {'GEMET': ['kw1', 'kw2'], 'gmd:topicCategory': ['natural']})
        self.assertEqual(m.crs().authid(), 'EPSG:4326')

        extent = m.extent().spatialExtents()[0]
        self.assertEqual(extent.extentCrs.authid(), 'EPSG:4326')
        self.assertEqual(extent.bounds.xMinimum(), -180.0)
        self.assertEqual(extent.bounds.yMinimum(), -90.0)
        self.assertEqual(extent.bounds.xMaximum(), 180.0)
        self.assertEqual(extent.bounds.yMaximum(), 90.0)
        self.assertEqual(m.extent().temporalExtents()[0].begin(), QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47)))
        self.assertTrue(m.extent().temporalExtents()[0].isInstant())

        self.assertEqual(m.contacts()[0].name, 'John Smith')
        self.assertEqual(m.contacts()[0].organization, 'ACME')
        self.assertEqual(m.contacts()[0].position, 'staff')
        self.assertEqual(m.contacts()[0].voice, '1500 515 555')
        self.assertEqual(m.contacts()[0].fax, 'xx.xxx.xxx.xxxx')
        self.assertEqual(m.contacts()[0].email, '*****@*****.**')
        self.assertEqual(m.contacts()[0].role, 'pointOfContact')
        self.assertEqual(m.contacts()[0].addresses[0].type, 'postal')
        self.assertEqual(m.contacts()[0].addresses[0].address, '123 Main Street')
        self.assertEqual(m.contacts()[0].addresses[0].city, 'anycity')
        self.assertEqual(m.contacts()[0].addresses[0].administrativeArea, 'anyprovince')
        self.assertEqual(m.contacts()[0].addresses[0].postalCode, '90210')
        self.assertEqual(m.contacts()[0].addresses[0].country, 'Canada')
        self.assertEqual(m.links()[0].name, 'geonode:roads')
        self.assertEqual(m.links()[0].type, 'OGC:WMS')
        self.assertEqual(m.links()[0].description, 'my GeoNode road layer')
        self.assertEqual(m.links()[0].url, 'http://example.org/wms')
        self.assertEqual(m.links()[1].name, 'geonode:roads')
        self.assertEqual(m.links()[1].type, 'OGC:WFS')
        self.assertEqual(m.links()[1].description, 'my GeoNode road layer')
        self.assertEqual(m.links()[1].url, 'http://example.org/wfs')
        self.assertEqual(m.links()[2].name, 'roads')
        self.assertEqual(m.links()[2].type, 'WWW:LINK')
        self.assertEqual(m.links()[2].description, 'full dataset download')
        self.assertEqual(m.links()[2].url, 'http://example.org/roads.tgz')
        self.assertEqual(m.links()[2].format, 'ESRI Shapefile')
        self.assertEqual(m.links()[2].mimeType, 'application/gzip')
        self.assertEqual(m.links()[2].size, '283676')
    def testFixedRangeMode(self):
        props = QgsVectorLayerTemporalProperties(enabled=True)
        props.setMode(QgsVectorLayerTemporalProperties.ModeFixedTemporalRange)
        props.setFixedTemporalRange(
            QgsDateTimeRange(QDateTime(QDate(2019, 3, 4), QTime(11, 12, 13)),
                             QDateTime(QDate(2020, 5, 6), QTime(8, 9, 10))))

        self.assertTrue(
            props.isVisibleInTemporalRange(
                QgsDateTimeRange(
                    QDateTime(QDate(2019, 3, 4), QTime(11, 12, 13)),
                    QDateTime(QDate(2020, 5, 6), QTime(8, 9, 10)))))
        self.assertTrue(
            props.isVisibleInTemporalRange(
                QgsDateTimeRange(
                    QDateTime(QDate(2019, 1, 4), QTime(11, 12, 13)),
                    QDateTime(QDate(2019, 5, 6), QTime(8, 9, 10)))))
        self.assertTrue(
            props.isVisibleInTemporalRange(
                QgsDateTimeRange(
                    QDateTime(QDate(2020, 3, 4), QTime(11, 12, 13)),
                    QDateTime(QDate(2019, 9, 6), QTime(8, 9, 10)))))
        self.assertFalse(
            props.isVisibleInTemporalRange(
                QgsDateTimeRange(
                    QDateTime(QDate(2120, 3, 4), QTime(11, 12, 13)),
                    QDateTime(QDate(2121, 9, 6), QTime(8, 9, 10)))))
        self.assertFalse(
            props.isVisibleInTemporalRange(
                QgsDateTimeRange(
                    QDateTime(QDate(1920, 3, 4), QTime(11, 12, 13)),
                    QDateTime(QDate(1921, 9, 6), QTime(8, 9, 10)))))

        layer = QgsVectorLayer(
            "Point?field=fldtxt:string&field=fldint:integer&field=start_field:datetime",
            "test", "memory")
        range = QgsDateTimeRange(
            QDateTime(QDate(2019, 3, 4), QTime(11, 12, 13)),
            QDateTime(QDate(2020, 5, 6), QTime(8, 9, 10)))
        # ALWAYS must be empty for ModeFixedTemporalRange
        self.assertFalse(props.createFilterString(layer, range))
Beispiel #36
0
    def testIsEmpty(self):
        range = QgsDateRange(QDate(2010, 3, 1), QDate(2010, 6, 2))
        self.assertFalse(range.isEmpty())

        range = QgsDateRange(QDate(), QDate(2010, 6, 2))
        self.assertFalse(range.isEmpty())

        range = QgsDateRange(QDate(2010, 3, 1), QDate())
        self.assertFalse(range.isEmpty())

        # check QgsDateRange docs - this is treated as an infinite range, so is NOT empty
        range = QgsDateRange(QDate(), QDate())
        self.assertFalse(range.isEmpty())

        range = QgsDateRange(QDate(2017, 3, 1), QDate(2010, 6, 2))
        self.assertTrue(range.isEmpty())

        range = QgsDateRange(QDate(2010, 3, 1), QDate(2010, 3, 1))
        self.assertFalse(range.isEmpty())

        range = QgsDateRange(QDate(2010, 3, 1), QDate(2010, 3, 1), False,
                             False)
        self.assertTrue(range.isEmpty())
Beispiel #37
0
    def testContainsElement(self):
        # includes both ends
        range = QgsDateRange(QDate(2010, 3, 1), QDate(2010, 6, 2))
        self.assertTrue(range.contains(QDate(2010, 3, 1)))
        self.assertTrue(range.contains(QDate(2010, 5, 2)))
        self.assertTrue(range.contains(QDate(2010, 6, 2)))
        self.assertFalse(range.contains(QDate(2009, 6, 2)))
        self.assertFalse(range.contains(QDate(2017, 6, 2)))
        self.assertFalse(range.contains(QDate()))

        # infinite left end
        range = QgsDateRange(QDate(), QDate(2010, 6, 2))
        self.assertTrue(range.contains(QDate(2010, 3, 1)))
        self.assertTrue(range.contains(QDate(2010, 5, 2)))
        self.assertTrue(range.contains(QDate(2010, 6, 2)))
        self.assertTrue(range.contains(QDate(2009, 6, 2)))
        self.assertFalse(range.contains(QDate(2017, 6, 2)))
        self.assertFalse(range.contains(QDate()))

        # infinite right end
        range = QgsDateRange(QDate(2010, 3, 1), QDate())
        self.assertTrue(range.contains(QDate(2010, 3, 1)))
        self.assertTrue(range.contains(QDate(2010, 5, 2)))
        self.assertTrue(range.contains(QDate(2010, 6, 2)))
        self.assertFalse(range.contains(QDate(2009, 6, 2)))
        self.assertTrue(range.contains(QDate(2017, 6, 2)))
        self.assertFalse(range.contains(QDate()))
Beispiel #38
0
 def timeForChecking(self):
     """ determine whether it's the time for checking for news and updates now """
     if self.checkingOnStartInterval() == 0:
         return True
     settings = QgsSettings()
     try:
         # QgsSettings may contain ivalid value...
         interval = settings.value(settingsGroup + "/checkOnStartLastDate", type=QDate).daysTo(QDate.currentDate())
     except:
         interval = 0
     if interval >= self.checkingOnStartInterval():
         return True
     else:
         return False
Beispiel #39
0
    def getPage(self, fs):
        (db, conninfo) = self.plugin.opendb()
        if db is None:
            return None

        qry = QSqlQuery(db)
        if qry.exec_("SELECT 1 FROM information_schema.columns WHERE table_schema={} AND table_name='eignerart' AND column_name='anteil'".format(quote(self.plugin.settings.schema))) and qry.next():
            exists_ea_anteil = qry.value(0) == 1
        else:
            exists_ea_anteil = False

        html = ""
        for i in range(0, len(fs)):
            flsnr = fs[i]['flsnr']

            best = self.fetchall(db, (
                "SELECT " +
                "ea.bvnr" +
                ",'' as pz" +
                ",(SELECT eignerart FROM eign_shl WHERE ea.b=b) as eignerart" +
                ",%s as anteil" +
                ",ea.ff_stand AS zhist" +
                ",b.bestdnr" +
                ",b.gbbz" +
                ",b.gbblnr" +
                ",b.bestfl" +
                ",b.ff_stand AS bhist" +
                " FROM eignerart ea" +
                " JOIN bestand b ON ea.bestdnr = b.bestdnr" +
                " WHERE ea.flsnr = '%s'" +
                " ORDER BY zhist,bhist,b") % ("ea.anteil" if exists_ea_anteil else "''", flsnr)
            )

            res = self.fetchall(db, "SELECT f.*,g.gemarkung FROM flurst f LEFT OUTER JOIN gema_shl g ON (f.gemashl=g.gemashl) WHERE f.flsnr='%s' AND f.ff_stand=0" % flsnr)
            if len(res) == 1:
                res = res[0]
            else:
                QMessageBox.information(None, "Fehler", u"Flurstück %s nicht gefunden.\n[%s]" % (flsnr, repr(fs)))
                return None

            res['datum'] = QDate.currentDate().toString("d. MMMM yyyy")
            res['hist'] = 0

            if qry.exec_(u"SELECT " + u" AND ".join(["has_table_privilege('{}', 'SELECT')".format(x) for x in ['strassen', 'str_shl']])) and qry.next() and qry.value(0):
                res['str'] = self.fetchall(db, "SELECT sstr.strname,str.hausnr FROM str_shl sstr JOIN strassen str ON str.strshl=sstr.strshl WHERE str.flsnr='%s' AND str.ff_stand=0" % flsnr)

            if qry.exec_(u"SELECT " + u" AND ".join(["has_table_privilege('{}', 'SELECT')".format(x) for x in ['nutz_21', 'nutz_shl']])) and qry.next() and qry.value(0):
                res['nutz'] = self.fetchall(db, "SELECT n21.*, nu.nutzshl, nu.nutzung FROM nutz_21 n21, nutz_shl nu WHERE n21.flsnr='%s' AND n21.nutzsl=nu.nutzshl AND n21.ff_stand=0" % flsnr)

            if qry.exec_(u"SELECT " + u" AND ".join(["has_table_privilege('{}', 'SELECT')".format(x) for x in ['klas_3x', 'kls_shl']])) and qry.next() and qry.value(0):
                res['klas'] = self.fetchall(db, "SELECT sum(fl::int) AS fl, min(kls.klf_text) AS klf_text FROM klas_3x kl, kls_shl kls WHERE kl.flsnr='%s' AND kl.klf=kls.klf AND kl.ff_stand=0 GROUP BY kls.klf" % flsnr)

            if qry.exec_(u"SELECT " + u" AND ".join(["has_table_privilege('{}', 'SELECT')".format(x) for x in ['ausfst', 'afst_shl']])) and qry.next() and qry.value(0):
                res['afst'] = self.fetchall(db, "SELECT au.*, af.afst_txt FROM ausfst au,afst_shl af WHERE au.flsnr='%s' AND au.ausf_st=af.ausf_st AND au.ff_stand=0" % flsnr)

            if qry.exec_(u"SELECT " + u" AND ".join(["has_table_privilege('{}', 'SELECT')".format(x) for x in ['bestand', 'eignerart', 'eign_shl']])) and qry.next() and qry.value(0):
                res['best'] = self.fetchall(db, "SELECT ea.bvnr,'' as pz,(SELECT eignerart FROM eign_shl WHERE ea.b = b) as eignerart,%s as anteil,ea.ff_stand AS zhist,b.bestdnr,b.gbbz,b.gbblnr,b.bestfl,b.ff_stand AS bhist FROM eignerart ea JOIN bestand b ON ea.bestdnr = b.bestdnr WHERE ea.flsnr='%s' ORDER BY zhist,bhist,b" % (
                    "ea.anteil" if exists_ea_anteil else "''",
                    flsnr
                ))

                if qry.exec_("SELECT has_table_privilege('eigner', 'SELECT')") and qry.next() and qry.value(0):
                    for b in res['best']:
                        b['bse'] = self.fetchall(db, "SELECT * FROM eigner WHERE bestdnr='%s' AND ff_stand=0" % b['bestdnr'])

#                        for k,v in res.iteritems():
#                                qDebug( u"%s:%s\n" % ( k, unicode(v) ) )

            html = u"""
<HTML xmlns="http://www.w3.org/1999/xhtml">
  <HEAD>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  </HEAD>
  <BODY>
<style>
.fls_tab{width:100%%;empty-cells:show}
.fls_headline{font-weight:bold;font-size:4em;}
.fls_headline_col{background-color:#EEEEEE;width:100%%;height:30px;text-align:left;}
.fls_time        {background-color:#EEEEEE;font-weight:bold;font-size:4em;text-align:right;width:100%%}
.fls_col_names{font-weight:bold;}
.fls_col_values{vertical-align:top;}
.fls_bst{width:100%%;empty-cells:show}
.fls_hr{border:dotted 1px;color:#080808;}
.fls_footnote{text-align:center;}
</style>

<TABLE class="fls_tab" border="0" width="100%%" cellspacing="0">
    <TR class="fls_headline">
        <TD colspan="3" class="fls_headline_col">Flurst&uuml;cksnachweis</TD><TD class="fls_time" colspan="4" align="right">%(datum)s</TD></TR>
    </TR>
    <TR><TD colspan="7">&nbsp;</TD></TR>
    <TR>
        <TD colspan="7"><h3>Flurst&uuml;ck %(gemashl)s-%(flr)s-%(flsnrk)s<hr style="width:100%%"></h3></TD>
    </TR>
    <TR class="fls_col_names">
        <TD width="15%%">Gemarkung</TD>
        <TD width="6%%">Flur</TD>
        <TD width="15%%">Flurst&uuml;ck</TD>
        <TD width="20%%">Flurkarte</TD>
        <TD width="17%%">Entstehung</TD>
        <TD width="17%%">Fortf&uuml;hrung</TD>
        <TD width="5%%">Fl&auml;che</TD>
    </TR>
    <TR class="fls_col_values">
        <TD>%(gemashl)s<br>%(gemarkung)s</TD>
        <TD>%(flr)s</TD>
        <TD>%(flsnrk)s</TD>
        <TD>%(flurknr)s</TD>
        <TD>%(entst)s</TD>
        <TD>%(fortf)s</TD>
        <TD>%(flsfl)s&nbsp;m&sup2;</TD>
    </TR>
</TABLE>
""" % res

            if res['blbnr']:
                html += u"""
<TABLE class="fls_tab" border="0" width="100%%">
    <TR class="fls_col_names">
        <TD width="21%%"></TD>
        <TD width="79%%">Baulastenblattnr.</TD>
    </TR>
    <TR class="fls_col_values">
        <TD></TD>
        <TD>%(blbnr)s</TD>
    </TR>
</TABLE>
""" % res

            if res['lagebez'] or res['anl_verm']:
                html += u"""
<TABLE class="fls_tab" border="0" width="100%%">
    <TR class="fls_col_names">
        <TD width="21%%"></TD>
        <TD width="52%%">Lage</TD>
        <TD width="27%%">Anliegervermerk</TD>
    </TR>
    <TR class="fls_col_values">
        <TD></TD>
        <TD>%(lagebez)s</TD>
        <TD>%(anl_verm)s</TD>
    </TR>
</TABLE>
""" % res

            if 'str' in res:
                if res['str']:
                    html += u"""
<TABLE border="0" class="fls_tab" width="100%">
    <TR class="fls_col_names">
        <TD width="21%"></TD>
        <TD width="52%">Strasse</TD>
        <TD width="27%">Hausnummer</TD>
    </TR>
"""

                    for strres in res['str']:
                        html += u"""
    <TR class="fls_col_values">
        <TD></TD><TD>%(strname)s</TD><TD>%(hausnr)s</TD></TR>
    </TR>
""" % strres

                    html += u"""
</TABLE>
"""

            if 'nutz' in res:
                html += u"""
<TABLE border="0" class="fls_tab" width="100%">
        <TR class="fls_col_names"><TD width="21%"></TD><TD width="69%">Nutzung</TD><TD width="10%">Fl&auml;che</TD></TR>
"""
                if res['nutz']:
                    for nutz in res['nutz']:
                        html += u"""
        <TR class="fls_col_values"><TD></TD><TD>21%(nutzshl)s - %(nutzung)s</TD><TD>%(fl)s&nbsp;m&sup2;</TD></TR>
""" % nutz
                else:
                    html += u"""
        <TR class="fls_col_values"><TD></TD><TD colspan=2>Keine</TD></TR>
"""

            html += u"""
</TABLE>
"""

            if 'klas' in res:
                html += u"""
<TABLE border="0" class="fls_tab" width="100%">
        <TR class="fls_col_names"><TD width="21%"></TD><TD width="69%">Klassifizierung(en)</TD><TD width="10%">Fl&auml;che</TD></TR>
"""

                if res['klas']:
                    for klas in res['klas']:
                        html += u"""
        <TR class="fls_col_values"><TD></TD><TD>%(klf_text)s</TD><TD>%(fl)s&nbsp;m&sup2;</TD></TR>
""" % klas
                else:
                    html += u"""
        <TR class="fls_col_values"><TD></TD><TD colspan=2>Keine</TD></TR>
"""

            html += u"""
</TABLE>
"""

            if 'afst' in res:
                html += u"""
<TABLE border="0" class="fls_tab" width="100%">
        <TR class="fls_col_names"><TD width="21%"></TD><TD width="79%">Ausf&uuml;hrende Stelle(n)</TD></TR>
"""

                if res['afst']:
                    for afst in res['afst']:
                        html += u"""
        <TR class="fls_col_values"><TD></TD><TD>%(afst_txt)s</TD></TR>
""" % afst

                else:
                    html += u"""
        <TR class="fls_col_values"><TD></TD><TD colspan=2>Keine</TD></TR>
"""

                html += u"""
</TABLE>
"""

            if 'best' in res:
                if res['best']:
                    html += u"""
<br>
<TABLE border="0" class="fls_bst" width="100%">
        <TR><TD colspan="6"><h3>Best&auml;nde<hr style="width:100%"></h3></TD></TR>
"""

                    for best in res['best']:
                        html += u"""
        <TR class="fls_col_names">
                <TD>Bestandsnummer</TD>
                <TD>Grundbuchbezirk</TD>
                <TD colspan="2">Grundbuchblattnr.</TD>
                <TD>Anteil</TD>
        </TR>
        <TR class="fls_col_values">
                <TD>%(bestdnr)s</TD>
                <TD>%(gbbz)s</TD>
                <TD colspan="2">%(gbblnr)s</TD>
                <TD>%(anteil)s</TD>
        </TR>
        <TR class="fls_col_names">
                <TD></TD>
                <TD>Buchungskennz.</TD>
                <TD>BVNR</TD>
                <TD>PZ</TD>
""" % best

                        if res['hist']:
                            html += u"""
                <TD>Hist. Bestand</TD><TD>Hist. Zuordnung</TD>
"""
                        else:
                            html += u"""
                <TD></TD><TD></TD>
"""

                        html += u"""
        </TR>
        <TR class="fls_col_values">
                <TD></TD>
                <TD>%(eignerart)s</TD>
                <TD>%(bvnr)s</TD>
                <TD>%(pz)s</TD>
""" % best

                        html += "<TD>%s</TD>" % ("ja" if res['hist'] and best['bhist'] else "")
                        html += "<TD>%s</TD>" % ("ja" if res['hist'] and best['zhist'] else "")

                        html += u"""
        </TR>
"""

                        if 'bse' in best:
                            if best['bse']:
                                html += u"""
        <TR class="fls_col_names"><TD>Anteil</TD><TD colspan="5">Namensinformation</TD></TR>
"""

                                for bse in best['bse']:
                                    html += u"""
        <TR class="fls_col_values">
                <TD>%(antverh)s</TD>
                <TD colspan="5">%(name1)s %(name2)s<br>%(name3)s<br>%(name4)s</TD>
        </TR>
""" % bse
                            else:
                                html += u"""
        <p>Kein Eigentümer gefunden.</p>
"""

                            html += u"""
        <TR><TD colspan="6"><hr class="fls_hr"></TD></TR>
"""

        html += u"""
"""

        footnote = self.plugin.settings.footnote
        if footnote:
            html += u"""
        <TR><TD colspan="7" class="fls_footnote">%s</TD></TR>
""" % footnote

        html += u"""
        </TABLE>
</BODY>
</HTML>
"""

        return html