Example #1
0
    def outattrPrep(self, dlg, lyr):
        feat = QgsFeature()

        species = ''
        production = ''
        most = QDateTime.currentDateTimeUtc()

        rn = dlg.tableWidget.rowCount()
        for i in range(rn):
            if i==0:
                species = dlg.tableWidget.item(i, 0).text()
                production = dlg.tableWidget.item(i, 1).text()
            else:
                species = species + ' | ' + dlg.tableWidget.item(i, 0).text()
                production = production + ' | ' + dlg.tableWidget.item(i, 1).text()

        flds = lyr.dataProvider().fields()
        feat.setFields(flds, True)
        feat.setAttribute(feat.fieldNameIndex('localid'), dlg.lineEdit_3.text())
        feat.setAttribute(feat.fieldNameIndex('code'), dlg.lineEdit_5.text())
        feat.setAttribute(feat.fieldNameIndex('largescale'), dlg.comboBox_4.currentText())
        feat.setAttribute(feat.fieldNameIndex('disease'), dlg.comboBox_2.currentText())
        feat.setAttribute(feat.fieldNameIndex('animalno'), dlg.lineEdit_6.text())
        feat.setAttribute(feat.fieldNameIndex('species'), species)
        feat.setAttribute(feat.fieldNameIndex('production'), production)
        feat.setAttribute(feat.fieldNameIndex('year'), dlg.lineEdit_4.text())
        feat.setAttribute(feat.fieldNameIndex('status'), dlg.comboBox_3.currentText())
        feat.setAttribute(feat.fieldNameIndex('suspect'), self.dateCheck(dlg.dateEdit.date()))
        feat.setAttribute(feat.fieldNameIndex('confirmation'), self.dateCheck(dlg.dateEdit_2.date()))
        feat.setAttribute(feat.fieldNameIndex('expiration'), self.dateCheck(dlg.dateEdit_3.date()))
        feat.setAttribute(feat.fieldNameIndex('notes'), dlg.textEdit.toPlainText())
        feat.setAttribute(feat.fieldNameIndex('hrid'), self.hashIDer(most))
        feat.setAttribute(feat.fieldNameIndex('timestamp'), most.toString('dd/MM/yyyy hh:mm:ss'))
        return feat
    def replyFinished(self):
        reply = self.sender()
        url = reply.request().url().toString()
        self.log("replyFinished: %s" % url)
        if not url in self.fetchedFiles:
            self.fetchedFiles[url] = None
        self.requestingUrls.remove(url)
        self.replies.remove(reply)
        isFromCache = 0
        httpStatusCode = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
        if reply.error() == QNetworkReply.NoError:
            self.fetchSuccesses += 1
            if reply.attribute(QNetworkRequest.SourceIsFromCacheAttribute):
                self.cacheHits += 1
                isFromCache = 1
            elif not reply.hasRawHeader("Cache-Control"):
                cache = QgsNetworkAccessManager.instance().cache()
                if cache:
                    metadata = cache.metaData(reply.request().url())
                    # self.log("Expiration date: " + metadata.expirationDate().toString().encode("utf-8"))
                    if metadata.expirationDate().isNull():
                        metadata.setExpirationDate(
                            QDateTime.currentDateTime().addSecs(self.default_cache_expiration * 60 * 60))
                        cache.updateMetaData(metadata)
                        self.log(
                            "Default expiration date has been set: %s (%d h)" % (url, self.default_cache_expiration))

            if reply.isReadable():
                data = reply.readAll()
                self.fetchedFiles[url] = data
            else:
                qDebug("http status code: " + str(httpStatusCode))
        else:
            if self.sync and httpStatusCode == 404:
                self.fetchedFiles[url] = self.NOT_FOUND
            self.fetchErrors += 1
            if self.errorStatus == self.NO_ERROR:
                self.errorStatus = self.UNKNOWN_ERROR

        self.replyFinished.emit(url, reply.error(), isFromCache)
        reply.deleteLater()

        if debug_mode:
            qDebug("queue: %d, requesting: %d" % (len(self.queue), len(self.requestingUrls)))

        if len(self.queue) + len(self.requestingUrls) == 0:
            # all replies have been received
            if self.sync:
                self.logT("eventLoop.quit()")
                self.eventLoop.quit()
            else:
                self.timer.stop()
        elif len(self.queue) > 0:
            # start fetching the next file
            self.fetchNext()
        self.log("replyFinished End: %s" % url)
Example #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__"
Example #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)
"""
__author__ = 'Denis Rouzaud'
__date__ = '2018-01-04'
__copyright__ = 'Copyright 2017, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '885f47d2af26cc804c87a8161ec880893455b0c2'

import qgis  # NOQA

from qgis.gui import QgsDateTimeEdit
from qgis.PyQt.QtCore import Qt, QDateTime
from qgis.testing import start_app, unittest

start_app()

DATE = QDateTime.fromString('2018-01-01 01:02:03', Qt.ISODate)


class TestQgsDateTimeEdit(unittest.TestCase):

    def testSettersGetters(self):
        """ test widget handling of null values """
        w = qgis.gui.QgsDateTimeEdit()
        w.setAllowNull(False)

        w.setDateTime(DATE)
        self.assertEqual(DATE, w.dateTime())
        # date should remain when setting an invalid date
        w.setDateTime(QDateTime())
        self.assertEqual(DATE, w.dateTime())
    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.asWkt(),
                        '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)
    def test_existing_complex_keywords(self):
        """Test for existing complex keywords in wizard in locale mode."""
        from safe.test.utilities import (
            clone_shp_layer, remove_vector_temp_file)
        layer = clone_shp_layer(
            name='tsunami_polygon', include_keywords=True, source_directory='')

        from safe.test.utilities import get_qgis_app
        # Get Qgis app handle
        # noinspection PyPep8Naming
        _, _, IFACE, PARENT = get_qgis_app(qsetting=INASAFE_TEST)

        from safe.gui.tools.wizard.wizard_dialog import WizardDialog

        # noinspection PyTypeChecker
        dialog = WizardDialog(PARENT, IFACE)
        dialog.set_keywords_creation_mode(layer)

        # select hazard
        self.select_from_list_widget('ancaman',
                                     dialog.step_kw_purpose.lstCategories)
        dialog.pbnNext.click()

        # select volcano
        self.select_from_list_widget('gunung berapi', dialog.
                                     step_kw_subcategory.lstSubcategories)
        dialog.pbnNext.click()

        # select volcano categorical unit
        self.select_from_list_widget('Kategori gunung berapi',
                                     dialog.step_kw_unit.lstUnits)
        dialog.pbnNext.click()

        # select GRIDCODE
        self.select_from_list_widget(
            'GRIDCODE', dialog.step_kw_field.lstFields)
        dialog.pbnNext.click()

        unit = dialog.step_kw_unit.selected_unit()
        default_classes = unit['classes']
        unassigned_values = []  # no need to check actually, not save in file
        assigned_values = {
            'low': ['5.0'],
            'medium': ['3.0', '4.0'],
            'high': ['2.0']
        }
        dialog.step_kw_classify.populate_classified_values(
            unassigned_values, assigned_values, default_classes)
        dialog.pbnNext.click()

        source = 'Source'
        source_scale = 'Source Scale'
        source_url = 'Source Url'
        source_date = QDateTime.fromString(
            '06-12-2015 12:30',
            'dd-MM-yyyy HH:mm')

        dialog.step_kw_source.leSource.setText(source)
        dialog.step_kw_source.leSource_scale.setText(source_scale)
        dialog.step_kw_source.leSource_url.setText(source_url)
        dialog.step_kw_source.leSource_date.seDateTime(source_date)
        dialog.pbnNext.click()  # next
        dialog.pbnNext.click()  # finish

        # noinspection PyTypeChecker
        dialog = WizardDialog(PARENT, IFACE)
        dialog.set_keywords_creation_mode(layer)

        # step 1 of 7 - select category
        self.check_current_text(
            'ancaman', dialog.step_kw_purpose.lstCategories)

        # Click Next
        dialog.pbnNext.click()

        # step 2 of 7 - select subcategory
        # noinspection PyTypeChecker
        self.check_current_text('gunung berapi',
                                dialog.step_kw_subcategory.lstSubcategories)

        # Click Next
        dialog.pbnNext.click()

        # step 3 of 7 - select volcano units
        self.check_current_text('Kategori gunung berapi',
                                dialog.step_kw_unit.lstUnits)

        # Click Next
        dialog.pbnNext.click()

        # step 4 of 7 - select field
        self.check_current_text('GRIDCODE', dialog.step_kw_field.lstFields)

        # Click Next
        dialog.pbnNext.click()

        for index in range(dialog.step_classify.lstUniqueValues.count()):
            message = ('%s Should be in unassigned values' %
                       dialog.step_classify.lstUniqueValues.item(index).text())
            self.assertIn(
                dialog.step_classify.lstUniqueValues.item(index).text(),
                unassigned_values,
                message)
        real_assigned_values = dialog.step_classify.selected_mapping()
        self.assertDictEqual(real_assigned_values, assigned_values)

        # Click Next
        dialog.pbnNext.click()

        # step 6 of 7 - enter source
        message = ('Invalid Next button state in step 6! Disabled while '
                   'source is optional')
        self.assertTrue(dialog.pbnNext.isEnabled(), message)

        message = 'Source should be %s' % source
        self.assertEqual(
            dialog.step_kw_source.leSource.text(), source, message)
        message = 'Source Url should be %s' % source_url
        self.assertEqual(dialog.step_kw_source.leSource_url.text(),
                         source_url, message)
        message = 'Source Date should be %s' % source_date.toString(
            'dd-MM-yyyy HH:mm')
        self.assertEqual(dialog.step_kw_source.leSource_date.dateTime(),
                         source_date, message)
        message = 'Source Scale should be %s' % source_scale
        self.assertEqual(dialog.step_kw_source.leSource_scale.text(),
                         source_scale, message)
        dialog.pbnNext.click()

        dialog.pbnCancel.click()

        remove_vector_temp_file(layer.source())
 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))
    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)
Example #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']})
        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])
        e.setTemporalExtents([
            QgsDateTimeRange(QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47)),
                             QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47)))
        ])
        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 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 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'
        )
Example #13
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)
    def testExpressionMode(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)
        context = QgsVectorLayerTemporalContext()
        context.setLayer(layer)

        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.
                      ModeFeatureDateTimeStartAndEndFromExpressions)
        props.setStartExpression(
            'to_datetime("my string field",  \'yyyy MM dd hh::mm:ss\')"')
        props.setEndExpression(
            'to_datetime("my end field",  \'yyyy MM dd hh::mm:ss\')"')
        self.assertFalse(props.createFilterString(context, range))

        props.setIsActive(True)
        self.assertEqual(
            props.createFilterString(context, range),
            '((to_datetime("my string field",  \'yyyy MM dd hh::mm:ss\')") <= make_datetime(2020,5,6,8,9,10)) AND ((to_datetime("my end field",  \'yyyy MM dd hh::mm:ss\')") >= make_datetime(2019,3,4,11,12,13))'
        )

        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(context, range),
            '((to_datetime("my string field",  \'yyyy MM dd hh::mm:ss\')") <= make_datetime(2020,5,6,8,9,10)) AND ((to_datetime("my end field",  \'yyyy MM dd hh::mm:ss\')") > make_datetime(2019,3,4,11,12,13))'
        )

        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(context, range),
            '((to_datetime("my string field",  \'yyyy MM dd hh::mm:ss\')") < make_datetime(2020,5,6,8,9,10)) AND ((to_datetime("my end field",  \'yyyy MM dd hh::mm:ss\')") >= make_datetime(2019,3,4,11,12,13))'
        )

        props.setEndExpression('')
        self.assertEqual(
            props.createFilterString(context, range),
            '(to_datetime("my string field",  \'yyyy MM dd hh::mm:ss\')") <= make_datetime(2020,5,6,8,9,10)'
        )

        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(context, range),
            '(to_datetime("my string field",  \'yyyy MM dd hh::mm:ss\')") < make_datetime(2020,5,6,8,9,10)'
        )

        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(context, range),
            '(to_datetime("my string field",  \'yyyy MM dd hh::mm:ss\')") <= make_datetime(2020,5,6,8,9,10)'
        )

        props.setStartExpression('')
        props.setEndExpression(
            'to_datetime("my end field",  \'yyyy MM dd hh::mm:ss\')"')
        self.assertEqual(
            props.createFilterString(context, range),
            '(to_datetime("my end field",  \'yyyy MM dd hh::mm:ss\')") >= make_datetime(2019,3,4,11,12,13)'
        )

        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(context, range),
            '(to_datetime("my end field",  \'yyyy MM dd hh::mm:ss\')") > make_datetime(2019,3,4,11,12,13)'
        )

        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(context, range),
            '(to_datetime("my end field",  \'yyyy MM dd hh::mm:ss\')") >= make_datetime(2019,3,4,11,12,13)'
        )
    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))
    def testStartAndDurationMode(self):
        layer = QgsVectorLayer(
            "Point?field=fldtxt:string&field=fldint:integer&field=start_field:datetime&field=duration:double",
            "test", "memory")
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.fields()[2].type(), QVariant.DateTime)
        self.assertEqual(layer.fields()[3].type(), QVariant.Double)
        context = QgsVectorLayerTemporalContext()
        context.setLayer(layer)

        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.
                      ModeFeatureDateTimeStartAndDurationFromFields)
        props.setStartField('start_field')
        props.setDurationField('duration')
        props.setDurationUnits(QgsUnitTypes.TemporalMilliseconds)
        self.assertFalse(props.createFilterString(context, range))

        props.setIsActive(True)
        self.assertEqual(
            props.createFilterString(context, range),
            '("start_field" <= make_datetime(2020,5,6,8,9,10) OR "start_field" IS NULL) AND (("start_field" + make_interval(0,0,0,0,0,0,"duration"/1000) >= make_datetime(2019,3,4,11,12,13)) OR "duration" IS NULL)'
        )

        props.setDurationUnits(QgsUnitTypes.TemporalSeconds)
        self.assertEqual(
            props.createFilterString(context, range),
            '("start_field" <= make_datetime(2020,5,6,8,9,10) OR "start_field" IS NULL) AND (("start_field" + make_interval(0,0,0,0,0,0,"duration") >= make_datetime(2019,3,4,11,12,13)) OR "duration" IS NULL)'
        )

        props.setDurationUnits(QgsUnitTypes.TemporalMinutes)
        self.assertEqual(
            props.createFilterString(context, range),
            '("start_field" <= make_datetime(2020,5,6,8,9,10) OR "start_field" IS NULL) AND (("start_field" + make_interval(0,0,0,0,0,"duration",0) >= make_datetime(2019,3,4,11,12,13)) OR "duration" IS NULL)'
        )

        props.setDurationUnits(QgsUnitTypes.TemporalHours)
        self.assertEqual(
            props.createFilterString(context, range),
            '("start_field" <= make_datetime(2020,5,6,8,9,10) OR "start_field" IS NULL) AND (("start_field" + make_interval(0,0,0,0,"duration",0,0) >= make_datetime(2019,3,4,11,12,13)) OR "duration" IS NULL)'
        )

        props.setDurationUnits(QgsUnitTypes.TemporalDays)
        self.assertEqual(
            props.createFilterString(context, range),
            '("start_field" <= make_datetime(2020,5,6,8,9,10) OR "start_field" IS NULL) AND (("start_field" + make_interval(0,0,0,"duration",0,0,0) >= make_datetime(2019,3,4,11,12,13)) OR "duration" IS NULL)'
        )

        props.setDurationUnits(QgsUnitTypes.TemporalWeeks)
        self.assertEqual(
            props.createFilterString(context, range),
            '("start_field" <= make_datetime(2020,5,6,8,9,10) OR "start_field" IS NULL) AND (("start_field" + make_interval(0,0,"duration",0,0,0,0) >= make_datetime(2019,3,4,11,12,13)) OR "duration" IS NULL)'
        )

        props.setDurationUnits(QgsUnitTypes.TemporalMonths)
        self.assertEqual(
            props.createFilterString(context, range),
            '("start_field" <= make_datetime(2020,5,6,8,9,10) OR "start_field" IS NULL) AND (("start_field" + make_interval(0,"duration",0,0,0,0,0) >= make_datetime(2019,3,4,11,12,13)) OR "duration" IS NULL)'
        )

        props.setDurationUnits(QgsUnitTypes.TemporalYears)
        self.assertEqual(
            props.createFilterString(context, range),
            '("start_field" <= make_datetime(2020,5,6,8,9,10) OR "start_field" IS NULL) AND (("start_field" + make_interval("duration",0,0,0,0,0,0) >= make_datetime(2019,3,4,11,12,13)) OR "duration" IS NULL)'
        )

        props.setDurationUnits(QgsUnitTypes.TemporalDecades)
        self.assertEqual(
            props.createFilterString(context, range),
            '("start_field" <= make_datetime(2020,5,6,8,9,10) OR "start_field" IS NULL) AND (("start_field" + make_interval(10 * "duration",0,0,0,0,0,0) >= make_datetime(2019,3,4,11,12,13)) OR "duration" IS NULL)'
        )

        props.setDurationUnits(QgsUnitTypes.TemporalCenturies)
        self.assertEqual(
            props.createFilterString(context, range),
            '("start_field" <= make_datetime(2020,5,6,8,9,10) OR "start_field" IS NULL) AND (("start_field" + make_interval(100 * "duration",0,0,0,0,0,0) >= make_datetime(2019,3,4,11,12,13)) OR "duration" IS NULL)'
        )
    def testSingleFieldMode(self):
        layer = QgsVectorLayer(
            "Point?field=fldtxt:string&field=fldint:integer&field=start_field:datetime",
            "test", "memory")
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.fields()[2].type(), QVariant.DateTime)
        context = QgsVectorLayerTemporalContext()
        context.setLayer(layer)

        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.
                      ModeFeatureDateTimeInstantFromField)
        props.setStartField('start_field')
        self.assertFalse(props.createFilterString(context, range))

        props.setIsActive(True)
        self.assertEqual(
            props.createFilterString(context, range),
            '("start_field" >= make_datetime(2019,3,4,11,12,13) AND "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(context, range),
            '("start_field" > make_datetime(2019,3,4,11,12,13) AND "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(context, range),
            '("start_field" >= make_datetime(2019,3,4,11,12,13) AND "start_field" < make_datetime(2020,5,6,8,9,10)) OR "start_field" IS NULL'
        )

        # with fixed duration
        props.setFixedDuration(3)
        props.setDurationUnits(QgsUnitTypes.TemporalDays)
        range = QgsDateTimeRange(
            QDateTime(QDate(2019, 3, 4), QTime(11, 12, 13)),
            QDateTime(QDate(2020, 5, 6), QTime(8, 9, 10)))
        self.assertEqual(
            props.createFilterString(context, range),
            '("start_field" >= make_datetime(2019,3,1,11,12,13) AND "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(context, range),
            '("start_field" > make_datetime(2019,3,1,11,12,13) AND "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(context, range),
            '("start_field" >= make_datetime(2019,3,1,11,12,13) AND "start_field" < make_datetime(2020,5,6,8,9,10)) OR "start_field" IS NULL'
        )

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

        # accumulate mode
        props.setAccumulateFeatures(True)
        range = QgsDateTimeRange(
            QDateTime(QDate(2019, 3, 4), QTime(11, 12, 13)),
            QDateTime(QDate(2020, 5, 6), QTime(8, 9, 10)))
        self.assertEqual(
            props.createFilterString(context, 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(context, 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(context, range),
            '("start_field" < make_datetime(2020,5,6,8,9,10)) OR "start_field" IS NULL'
        )
Example #18
0
    def test_stations_to_features(self):
        """
        Test converting stations to features
        """
        path = os.path.join(os.path.dirname(__file__), 'data', 'stations.xml')
        with open(path, 'rb') as f:
            content = f.read()

        byte_array = QByteArray(content)

        parser = FDSNStationXMLParser()
        fdsn = parser.parse(byte_array)

        features = fdsn.to_station_features([])
        self.assertEqual(len(features), 9)

        self.assertEqual([f.attributes() for f in features],
                         [[
                             'SeisComP', 'SED', NULL, NULL,
                             QDateTime(2021, 11, 30, 0, 56, 10, 720,
                                       Qt.TimeSpec(1)), 'CH',
                             QDateTime(1980, 1, 1, 0, 0, 0, 0, Qt.TimeSpec(1)),
                             NULL, '', 'open', NULL,
                             NULL, 'National Seismic Networks of Switzerland',
                             NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'WIMIS',
                             QDateTime(2000, 5, 24, 0,
                                       0, 0, 0, Qt.TimeSpec(1)), NULL, '',
                             'open', NULL, NULL, 46.66488, 7.62418, 770.0,
                             'Wimmis, BE', NULL, NULL, NULL, NULL, NULL,
                             QDateTime(2000, 5, 24, 0,
                                       0, 0, 0, Qt.TimeSpec(1)), NULL,
                             NULL, NULL, NULL, NULL
                         ],
                          [
                              'SeisComP', 'SED', NULL, NULL,
                              QDateTime(2021, 11, 30, 0, 56, 10, 720,
                                        Qt.TimeSpec(1)), 'CH',
                              QDateTime(1980, 1, 1, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, '', 'open',
                              NULL, NULL,
                              'National Seismic Networks of Switzerland', NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL, 'SINS',
                              QDateTime(2012, 9, 14, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, '', 'open',
                              NULL, NULL, 46.68692, 7.86414, 560.0,
                              'Interlaken, Schloss, BE', NULL, NULL, NULL,
                              NULL, NULL,
                              QDateTime(2012, 9, 14, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, NULL, NULL,
                              NULL, NULL
                          ],
                          [
                              'SeisComP', 'SED', NULL, NULL,
                              QDateTime(2021, 11, 30, 0, 56, 10, 720,
                                        Qt.TimeSpec(1)), 'CH',
                              QDateTime(1980, 1, 1, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, '', 'open',
                              NULL, NULL,
                              'National Seismic Networks of Switzerland', NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL, 'SFRS',
                              QDateTime(2018, 10, 11, 22, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, '', 'open',
                              NULL, NULL, 46.58232, 7.65632, 772.3,
                              'Frutigen, Schulhaus Kanderbrück, BE', NULL,
                              NULL, NULL, NULL, NULL,
                              QDateTime(2018, 10, 11, 22, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, NULL, NULL,
                              NULL, NULL
                          ],
                          [
                              'SeisComP', 'SED', NULL, NULL,
                              QDateTime(2021, 11, 30, 0, 56, 10, 720,
                                        Qt.TimeSpec(1)), 'CH',
                              QDateTime(1980, 1, 1, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, '', 'open',
                              NULL, NULL,
                              'National Seismic Networks of Switzerland', NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL, 'STHK',
                              QDateTime(2015, 4, 21, 11, 31, 34, 0,
                                        Qt.TimeSpec(1)), NULL, '', 'open',
                              NULL, NULL, 46.7437, 7.62953, 559.0,
                              'Thun, Kantonsschule, BE', NULL, NULL, NULL,
                              NULL, NULL,
                              QDateTime(2015, 4, 21, 11, 31, 34, 0,
                                        Qt.TimeSpec(1)), NULL, NULL, NULL,
                              NULL, NULL
                          ],
                          [
                              'SeisComP', 'SED', NULL, NULL,
                              QDateTime(2021, 11, 30, 0, 56, 10, 720,
                                        Qt.TimeSpec(1)), 'CH',
                              QDateTime(1980, 1, 1, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, '', 'open',
                              NULL, NULL,
                              'National Seismic Networks of Switzerland', NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL, 'SOLB',
                              QDateTime(2011, 11, 22, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, '', 'open',
                              NULL, NULL, 47.206835, 7.517052, 430.0,
                              'Solothurn, Schulhaus Bruehl, SO', NULL, NULL,
                              NULL, NULL, NULL,
                              QDateTime(2011, 11, 22, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, NULL, NULL,
                              NULL, NULL
                          ],
                          [
                              'SeisComP', 'SED', NULL, NULL,
                              QDateTime(2021, 11, 30, 0, 56, 10, 720,
                                        Qt.TimeSpec(1)), 'CH',
                              QDateTime(1980, 1, 1, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, '', 'open',
                              NULL, NULL,
                              'National Seismic Networks of Switzerland', NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL, 'SOLZ',
                              QDateTime(2012, 1, 12, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, '', 'open',
                              NULL, NULL, 47.208825, 7.538306, 444.0,
                              'Solothurn, Zeughausgasse, SO', NULL, NULL, NULL,
                              NULL, NULL,
                              QDateTime(2012, 1, 12, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, NULL, NULL,
                              NULL, NULL
                          ],
                          [
                              'SeisComP', 'SED', NULL, NULL,
                              QDateTime(2021, 11, 30, 0, 56, 10, 720,
                                        Qt.TimeSpec(1)), 'CH',
                              QDateTime(1980, 1, 1, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, '', 'open',
                              NULL, NULL,
                              'National Seismic Networks of Switzerland', NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL, 'LAUCH',
                              QDateTime(2010, 10, 21, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, '', 'open',
                              NULL, NULL, 46.41554, 7.77166, 2160.0,
                              'Lauchernalp - Loetschental, VS', NULL, NULL,
                              NULL, NULL, NULL,
                              QDateTime(2010, 10, 21, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, NULL, NULL,
                              NULL, NULL
                          ],
                          [
                              'SeisComP', 'SED', NULL, NULL,
                              QDateTime(2021, 11, 30, 0, 56, 10, 720,
                                        Qt.TimeSpec(1)), 'Z3',
                              QDateTime(2015, 1, 1, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)),
                              QDateTime(2022, 12, 31, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), '', 'closed', NULL,
                              NULL,
                              'AlpArray Seismic Network (AASN) temporary component',
                              '10.12686/alparray/z3_2015', NULL, NULL, NULL,
                              NULL, NULL, NULL, 'A060A',
                              QDateTime(2015, 8, 14, 14, 0, 0, 0,
                                        Qt.TimeSpec(1)),
                              QDateTime(2017, 2, 16, 10, 0, 0, 0,
                                        Qt.TimeSpec(1)), '', 'closed', NULL,
                              NULL, 47.0305, 7.8904, 1112.1,
                              'Wasen, Napf, BE, Switzerland', NULL, NULL, NULL,
                              NULL, NULL,
                              QDateTime(2015, 8, 14, 14, 0, 0, 0,
                                        Qt.TimeSpec(1)), NULL, NULL, NULL,
                              NULL, NULL
                          ],
                          [
                              'SeisComP', 'SED', NULL, NULL,
                              QDateTime(2021, 11, 30, 0, 56, 10, 720,
                                        Qt.TimeSpec(1)), 'Z3',
                              QDateTime(2015, 1, 1, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)),
                              QDateTime(2022, 12, 31, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), '', 'closed', NULL,
                              NULL,
                              'AlpArray Seismic Network (AASN) temporary component',
                              '10.12686/alparray/z3_2015', NULL, NULL, NULL,
                              NULL, NULL, NULL, 'A060B',
                              QDateTime(2017, 5, 9, 12, 30, 0, 0,
                                        Qt.TimeSpec(1)),
                              QDateTime(2022, 12, 31, 0, 0, 0, 0,
                                        Qt.TimeSpec(1)), '', 'closed', NULL,
                              NULL, 46.993, 7.97764, 1049.1,
                              'Romoos, Napf, BE, Switzerland', NULL, NULL,
                              NULL, NULL, NULL,
                              QDateTime(2017, 5, 9, 12, 30, 0, 0,
                                        Qt.TimeSpec(1)), NULL, NULL, NULL,
                              NULL, NULL
                          ]])
Example #19
0
    def testTemporal1(self):
        """
        Test timeinfo parsing
        """
        endpoint = self.basetestpath + '/temporal1_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}
        ],
        "timeInfo": {
          "startTimeField": "date_start",
          "endTimeField": null,
          "trackIdField": null,
          "timeExtent": [
           1142000000000,
           1487000000000
          ]
         },
        "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,
          3
         ]
        }
        """.encode('UTF-8'))

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

        self.assertTrue(vl.isValid())
        self.assertTrue(
            vl.dataProvider().temporalCapabilities().hasTemporalCapabilities())
        self.assertEqual(vl.dataProvider().temporalCapabilities().startField(),
                         'date_start')
        self.assertFalse(vl.dataProvider().temporalCapabilities().endField())
        self.assertEqual(
            vl.dataProvider().temporalCapabilities().mode(),
            QgsVectorDataProviderTemporalCapabilities.
            ProviderStoresFeatureDateTimeInstantInField)
        self.assertEqual(
            vl.dataProvider().temporalCapabilities().availableTemporalRange().
            begin(), QDateTime(QDate(2006, 3, 10), QTime(14, 13, 20), Qt.UTC))
        self.assertEqual(
            vl.dataProvider().temporalCapabilities().availableTemporalRange().
            end(), QDateTime(QDate(2017, 2, 13), QTime(15, 33, 20), Qt.UTC))
Example #20
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')
Example #21
0
    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)
Example #22
0
    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 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\'')
    def save_metadata(db_qr, metadata):
        """
        :param db_qr: DBConnector
        :param metadata: Dict with the following information:
                            QR_METADATA_TOOL
                            QR_METADATA_DATA_SOURCE
                            QR_METADATA_TOLERANCE
                            QR_METADATA_TIMESTAMP
                            QR_METADATA_RULES
                            QR_METADATA_OPTIONS
                            QR_METADATA_PERSON
        :return: tuple (bool with the result, string with a descriptive message)
        """
        if not hasattr(db_qr.names, "T_ID_F"):
            db_qr.test_connection()

        names = db_qr.names
        layers = {names.ERR_METADATA_T: None, names.ERR_RULE_TYPE_T: None}

        app.core.get_layers(db_qr, layers, load=True)

        if not layers:
            return False, "At least one layer was not found in the QR DB!"

        metadata_layer = layers[names.ERR_METADATA_T]

        idx_t_ili_tid = metadata_layer.fields().indexOf(names.T_ILI_TID_F)
        idx_date = metadata_layer.fields().indexOf(
            names.ERR_METADATA_T_VALIDATION_DATE_F)
        idx_data_source = metadata_layer.fields().indexOf(
            names.ERR_METADATA_T_DATA_SOURCE_F)
        idx_tool = metadata_layer.fields().indexOf(names.ERR_METADATA_T_TOOL_F)
        idx_person = metadata_layer.fields().indexOf(
            names.ERR_METADATA_T_PERSON_F)
        idx_tolerance = metadata_layer.fields().indexOf(
            names.ERR_METADATA_T_TOLERANCE_F)
        idx_rules = metadata_layer.fields().indexOf(
            names.ERR_METADATA_T_RULES_F)
        idx_options = metadata_layer.fields().indexOf(
            names.ERR_METADATA_T_RULE_OPTIONS_F)

        # Initially, the metadata table had references to QR types, but as soon as we
        # wanted to save them as ARRAYs in GPKG or PG, ili2db said "no, I cannot handle that."
        # See https://github.com/claeis/ili2db/issues/438
        #dict_rules = {f[names.ERR_ERROR_TYPE_T_CODE_F]:f[names.T_ID_F] for f in layers[names.ERR_RULE_TYPE_T].getFeatures()}
        #list_rules = str([dict_rules[qr_key] for qr_key in metadata[QR_METADATA_RULES] if qr_key in dict_rules])

        time_structure = time.strptime(metadata[QR_METADATA_TIMESTAMP],
                                       '%Y%m%d_%H%M%S')
        iso_timestamp = time.strftime('%Y-%m-%dT%H:%M:%S', time_structure)

        attr_map = {
            idx_t_ili_tid:
            str(uuid.uuid4()),
            idx_date:
            QDateTime().fromString(iso_timestamp, Qt.ISODate),
            idx_data_source:
            metadata[QR_METADATA_DATA_SOURCE],
            idx_tool:
            metadata[QR_METADATA_TOOL],
            idx_person:
            metadata[QR_METADATA_PERSON],
            idx_tolerance:
            metadata[QR_METADATA_TOLERANCE],
            idx_rules:
            "{}: {}".format(len(metadata[QR_METADATA_RULES]),
                            str(metadata[QR_METADATA_RULES])),
            idx_options:
            str(metadata[QR_METADATA_OPTIONS])
        }

        metadata_layer.dataProvider().addFeature(
            QgsVectorLayerUtils().createFeature(metadata_layer,
                                                attributes=attr_map))

        logger.info(__name__, "Quality rules metadata successfully saved!")
        return True, "Success!"
    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')
Example #26
0
    def testValidateNative(self):  # spellok
        """
        Test validating metadata against QGIS native schema
        """
        m = self.createTestMetadata()
        v = QgsNativeProjectMetadataValidator()

        res, list = v.validate(m)
        self.assertTrue(res)
        self.assertFalse(list)

        # corrupt metadata piece by piece...
        m = self.createTestMetadata()
        m.setIdentifier('')
        res, list = v.validate(m)
        self.assertFalse(res)
        self.assertEqual(list[0].section, 'identifier')

        m = self.createTestMetadata()
        m.setLanguage('')
        res, list = v.validate(m)
        self.assertFalse(res)
        self.assertEqual(list[0].section, 'language')

        m = self.createTestMetadata()
        m.setType('')
        res, list = v.validate(m)
        self.assertFalse(res)
        self.assertEqual(list[0].section, 'type')

        m = self.createTestMetadata()
        m.setTitle('')
        res, list = v.validate(m)
        self.assertFalse(res)
        self.assertEqual(list[0].section, 'title')

        m = self.createTestMetadata()
        m.setAbstract('')
        res, list = v.validate(m)
        self.assertFalse(res)
        self.assertEqual(list[0].section, 'abstract')

        m = self.createTestMetadata()
        m.setContacts([])
        res, list = v.validate(m)
        self.assertFalse(res)
        self.assertEqual(list[0].section, 'contacts')

        m = self.createTestMetadata()
        m.setLinks([])
        res, list = v.validate(m)
        self.assertFalse(res)
        self.assertEqual(list[0].section, 'links')

        m = self.createTestMetadata()
        m.setKeywords({'': ['kw1', 'kw2']})
        res, list = v.validate(m)
        self.assertFalse(res)
        self.assertEqual(list[0].section, 'keywords')
        self.assertEqual(list[0].identifier, 0)

        m = self.createTestMetadata()
        m.setKeywords({'AA': []})
        res, list = v.validate(m)
        self.assertFalse(res)
        self.assertEqual(list[0].section, 'keywords')
        self.assertEqual(list[0].identifier, 0)

        m = self.createTestMetadata()
        c = m.contacts()[0]
        c.name = ''
        m.setContacts([c])
        res, list = v.validate(m)
        self.assertFalse(res)
        self.assertEqual(list[0].section, 'contacts')
        self.assertEqual(list[0].identifier, 0)

        m = self.createTestMetadata()
        l = m.links()[0]
        l.name = ''
        m.setLinks([l])
        res, list = v.validate(m)
        self.assertFalse(res)
        self.assertEqual(list[0].section, 'links')
        self.assertEqual(list[0].identifier, 0)

        m = self.createTestMetadata()
        l = m.links()[0]
        l.type = ''
        m.setLinks([l])
        res, list = v.validate(m)
        self.assertFalse(res)
        self.assertEqual(list[0].section, 'links')
        self.assertEqual(list[0].identifier, 0)

        m = self.createTestMetadata()
        l = m.links()[0]
        l.url = ''
        m.setLinks([l])
        res, list = v.validate(m)
        self.assertFalse(res)
        self.assertEqual(list[0].section, 'links')
        self.assertEqual(list[0].identifier, 0)

        m = self.createTestMetadata()
        m.setAuthor('')
        res, list = v.validate(m)
        self.assertFalse(res)
        self.assertEqual(list[0].section, 'author')

        m = self.createTestMetadata()
        m.setCreationDateTime(QDateTime())
        res, list = v.validate(m)
        self.assertFalse(res)
        self.assertEqual(list[0].section, 'creation')
    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))
Example #28
0
    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
    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)],
            [
                QgsAggregateCalculator.ArrayAggregate, 'flddatetime',
                [None if v.isNull() else v for v in datetime_values]
            ],
            [
                QgsAggregateCalculator.ArrayAggregate, 'flddate',
                [None if v.isNull() else v for v in date_values]
            ],
        ]

        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)
    def __init__(self, parent=None, plugin=None):
        super().__init__(parent=parent)
        self.setupUi(self)
        self._plugin = plugin

        self.emitFiltersChanged = True

        # Set up sources (in 2 columns; layout is grid)
        checked = ['PSScene4Band']
        row_total = floor(len(DAILY_ITEM_TYPES) / 2)
        row = col = 0
        gl = QGridLayout(self.frameSources)
        gl.setContentsMargins(0, 0, 0, 0)
        for a, b in DAILY_ITEM_TYPES:
            # Strip ' Scene' to reduce horizontal width of 2-column layout, except for SkySat
            name = b.replace(' Scene', '') if b != "SkySat Scene" else b
            cb = QCheckBox(name, parent=self.frameSources)
            cb.setChecked(a in checked)
            cb.setProperty('api-name', a)
            cb.setToolTip(b)
            # noinspection PyUnresolvedReferences
            cb.stateChanged[int].connect(self.filtersChanged)
            gl.addWidget(cb, row, col)
            row += 1
            if row > row_total:
                row = 0
                col += 1

        self.frameSources.setLayout(gl)

        # TODO: (Eventually) Add multi-date range widget with and/or selector

        # noinspection PyUnresolvedReferences
        self.startDateEdit.valueChanged['QDateTime'].connect(
            self.filtersChanged)
        # noinspection PyUnresolvedReferences
        self.startDateEdit.valueChanged['QDateTime'].connect(
            self.set_min_enddate)
        # noinspection PyUnresolvedReferences
        self.startDateEdit.valueChanged['QDateTime'].connect(
            self.change_date_vis)
        # noinspection PyUnresolvedReferences
        self.endDateEdit.valueChanged['QDateTime'].connect(
            self.filtersChanged)
        # noinspection PyUnresolvedReferences
        self.endDateEdit.valueChanged['QDateTime'].connect(
            self.set_max_startdate)
        # noinspection PyUnresolvedReferences
        self.endDateEdit.valueChanged['QDateTime'].connect(
            self.change_date_vis)

        # Setup datetime boxes
        current_day = QDateTime().currentDateTimeUtc()
        self.startDateEdit.setDateTime(current_day.addMonths(-3))
        self.endDateEdit.setDateTime(current_day)

        # TODO: (Eventually) Add multi-field searching, with +/- operation
        #       of adding new field/QLineEdit, without duplicates
        # noinspection PyUnresolvedReferences
        self.leStringIDs.textChanged['QString'].connect(self.filters_changed)

        self.rangeCloudCover = PlanetExplorerRangeSlider(
            title='Cloud cover',
            filter_key='cloud_cover',
            prefix='',
            suffix='%',
            minimum=0,
            maximum=100,
            low=0,
            high=100,
            step=1,
            precision=1
        )
        # Layout's parent widget takes ownership
        self.frameRangeSliders.layout().addWidget(self.rangeCloudCover)
        self.rangeCloudCover.rangeChanged[float, float].connect(
            self.filters_changed)

        self.rangeAzimuth = PlanetExplorerRangeSlider(
            title='Sun Azimuth',
            filter_key='sun_azimuth',
            prefix='',
            suffix='°',
            minimum=0,
            maximum=360,
            low=0,
            high=360,
            step=1,
            precision=1
        )
        # Layout's parent widget takes ownership
        self.frameRangeSliders.layout().addWidget(self.rangeAzimuth)
        self.rangeAzimuth.rangeChanged[float, float].connect(
            self.filters_changed)

        self.rangeElevation = PlanetExplorerRangeSlider(
            title='Sun Elevation',
            filter_key='sun_elevation',
            prefix='',
            suffix='°',
            minimum=0,
            maximum=90,
            low=0,
            high=90,
            step=1,
            precision=1
        )
        # Layout's parent widget takes ownership
        self.frameRangeSliders.layout().addWidget(self.rangeElevation)
        self.rangeElevation.rangeChanged[float, float].connect(
            self.filters_changed)

        self.rangeViewAngle = PlanetExplorerRangeSlider(
            title='View Angle',
            filter_key='view_angle',
            prefix='',
            suffix='°',
            minimum=-25,
            maximum=25,
            low=0,
            high=25,
            step=1,
            precision=1
        )
        # Layout's parent widget takes ownership
        self.frameRangeSliders.layout().addWidget(self.rangeViewAngle)
        self.rangeViewAngle.rangeChanged[float, float].connect(
            self.filters_changed)

        self.rangeGsd = PlanetExplorerRangeSlider(
            title='Ground Sample Distance',
            filter_key='gsd',
            prefix='',
            suffix='m',
            minimum=0,
            maximum=50,
            low=0,
            high=50,
            step=1,
            precision=1
        )
        # Layout's parent widget takes ownership
        self.frameRangeSliders.layout().addWidget(self.rangeGsd)
        self.rangeGsd.rangeChanged[float, float].connect(
            self.filters_changed)

        self.rangeAnomalousPx = PlanetExplorerRangeSlider(
            title='Anomalous Pixels',
            filter_key='anomalous_pixels',
            prefix='',
            suffix='%',
            minimum=0,
            maximum=100,
            low=0,
            high=100,
            step=1,
            precision=1
        )

        # Layout's parent widget takes ownership
        self.frameRangeSliders.layout().addWidget(self.rangeAnomalousPx)
        self.rangeAnomalousPx.rangeChanged[float, float].connect(
            self.filters_changed)

        self.rangeUsable = PlanetExplorerRangeSlider(
            title='Usable Pixels',
            filter_key='usable_data',
            prefix='',
            suffix='%',
            minimum=0,
            maximum=100,
            low=0,
            high=100,
            step=1,
            precision=1
        )
        # Layout's parent widget takes ownership
        self.frameRangeSliders.layout().addWidget(self.rangeUsable)
        self.rangeUsable.rangeChanged[float, float].connect(
            self.filters_changed)

        self.rangeAreaCoverage = PlanetExplorerRangeSlider(
            title='Area Coverage',
            filter_key='area_coverage',
            prefix='',
            suffix='%',
            minimum=0,
            maximum=100,
            low=0,
            high=100,
            step=1,
            precision=1
        )
        self.frameRangeSliders.layout().addWidget(self.rangeAreaCoverage)
        self.rangeAreaCoverage.rangeChanged[float, float].connect(
            self.filters_changed)

        # TODO: Add rest of range sliders

        # Ground control filter checkbox
        # noinspection PyUnresolvedReferences
        self.chkBxGroundControl.stateChanged[int].connect(self.filters_changed)

        # Access Filter checkbox
        # noinspection PyUnresolvedReferences
        self.chkBxCanDownload.stateChanged[int].connect(self.filters_changed)
Example #31
0
    def __init__(
            self,  # pylint: disable=too-many-locals,too-many-statements
            service_type,
            event_service,
            event_start_date=None,
            event_end_date=None,
            event_min_magnitude=None,
            event_max_magnitude=None,
            limit_extent_rect=False,
            min_latitude=None,
            max_latitude=None,
            min_longitude=None,
            max_longitude=None,
            limit_extent_circle=False,
            circle_latitude=None,
            circle_longitude=None,
            circle_min_radius=None,
            circle_max_radius=None,
            circle_radius_unit=QgsUnitTypes.DistanceDegrees,
            earthquake_number_mdps_greater=None,
            earthquake_max_intensity_greater=None,
            event_ids=None,
            contributor_id=None,
            network_codes=None,
            station_codes=None,
            locations=None,
            parent=None,
            output_fields=None,
            output_type=EXTENDED,
            convert_negative_depths=False,
            depth_unit=QgsUnitTypes.DistanceMeters,
            event_type: Optional[str] = None,
            updated_after: Optional[QDateTime] = None,
            split_strategy: Optional[str] = None,
            styles: Dict[str, str] = None,
            url=None):
        super().__init__(parent=parent)

        self.service_type = service_type
        self.service_id = event_service
        self.service_config = SERVICE_MANAGER.service_details(
            self.service_type, self.service_id)

        self.split_strategy = split_strategy
        self.exceeded_limit = False

        self.event_start_date = event_start_date
        self.event_end_date = event_end_date

        # if we have a split strategy set, we HAVE to have a full date range available
        if self.split_strategy is not None and self.event_start_date is None:
            self.event_start_date = QDateTime.fromString(
                self.service_config.get('datestart'), Qt.ISODate)
        if self.split_strategy is not None and self.event_end_date is None:
            self.event_end_date = QDateTime.fromString(
                self.service_config.get('dateend'),
                Qt.ISODate) if self.service_config.get(
                    'dateend') else QDateTime.currentDateTime()

        self.event_start_date_limit = self.event_start_date
        self.event_end_date_limit = self.event_end_date

        if self.split_strategy is not None:
            self.ranges = Fetcher.split_range_by_strategy(
                self.split_strategy, self.event_start_date,
                self.event_end_date)
            self.event_start_date, self.event_end_date = self.ranges[0]
            del self.ranges[0]
        else:
            self.ranges = None

        self.event_min_magnitude = event_min_magnitude
        self.event_max_magnitude = event_max_magnitude
        self.event_type = event_type
        self.limit_extent_rect = limit_extent_rect
        self.min_latitude = min_latitude
        self.max_latitude = max_latitude
        self.min_longitude = min_longitude
        self.max_longitude = max_longitude
        self.limit_extent_circle = limit_extent_circle
        self.circle_latitude = circle_latitude
        self.circle_longitude = circle_longitude
        self.circle_min_radius = circle_min_radius
        self.circle_max_radius = circle_max_radius
        self.circle_radius_unit = circle_radius_unit
        self.earthquake_number_mdps_greater = earthquake_number_mdps_greater
        self.earthquake_max_intensity_greater = earthquake_max_intensity_greater
        self.event_ids = event_ids
        self.contributor_id = contributor_id
        self.network_codes = network_codes
        self.station_codes = station_codes
        self.locations = locations
        self.pending_event_ids = event_ids
        self.macro_pending_event_ids = event_ids
        self.output_type = output_type
        self.convert_negative_depths = convert_negative_depths
        self.depth_unit = depth_unit
        self.updated_after = updated_after
        self.url = url

        s = QgsSettings()
        self.preferred_origins_only = s.value('/plugins/qquake/output_preferred_origins', True, bool) or not \
            self.service_config['settings'].get('queryincludeallorigins', False)
        self.preferred_magnitudes_only = s.value('/plugins/qquake/output_preferred_magnitude', True, bool) or not \
            self.service_config['settings'].get('queryincludeallmagnitudes', False)
        self.preferred_mdp_only = s.value(
            '/plugins/qquake/output_preferred_mdp', True, bool)

        self.output_fields = output_fields[:] if output_fields else []

        if self.output_type == self.EXTENDED:
            if not self.preferred_origins_only and "!IsPrefOrigin" not in self.output_fields:
                self.output_fields.append("!IsPrefOrigin")
            if not self.preferred_magnitudes_only and "!IsPrefMag" not in self.output_fields:
                self.output_fields.append("!IsPrefMag")
            if not self.preferred_mdp_only and "!IsPrefMdpset" not in self.output_fields:
                self.output_fields.append("!IsPrefMdpset")

            self.result = QuakeMlParser(
                convert_negative_depths=self.convert_negative_depths,
                depth_unit=self.depth_unit)
        else:
            self.result = BasicTextParser(
                convert_negative_depths=self.convert_negative_depths,
                depth_unit=self.depth_unit)

        self.missing_origins = set()
        self.is_missing_origin_request = False
        self.require_mdp_basic_text_request = self.output_type == self.BASIC and self.service_type == SERVICE_MANAGER.MACROSEISMIC
        self.is_mdp_basic_text_request = False
        self.is_first_request = True
        self.query_limit = None
        self.styles = styles
Example #32
0
    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 endHTMLscript(wfsLayers, layerSearch, filterItems, labelCode, labels,
                  searchLayer, useHeat, useRaster, labelsList, mapUnitLayers):
    if labels == "":
        endHTML = ""
    else:
        endHTML = """
        map.on("zoomend", function(){
%s
        });""" % labels
    if wfsLayers == "":
        endHTML += """
        setBounds();
        %s""" % labelCode
        endHTML += labels
    if len(mapUnitLayers) > 0:
        lyrs = []
        for layer in mapUnitLayers:
            lyrs.append("""
            layer_%s.setStyle(style_%s_0);""" % (layer, layer))
        lyrScripts = "".join(lyrs)
        endHTML += """
        newM2px();
%s
        map.on("zoomend", function(){
            newM2px();
%s
        });""" % (lyrScripts, lyrScripts)
    if layerSearch != "None":
        searchVals = layerSearch.split(": ")
        endHTML += """
        map.addControl(new L.Control.Search({{
            layer: {searchLayer},
            initial: false,
            hideMarkerOnCollapse: true,
            propertyName: '{field}'}}));
        document.getElementsByClassName('search-button')[0].className +=
         ' fa fa-binoculars';
            """.format(searchLayer=searchLayer, field=searchVals[1])
    filterItems = sorted(filterItems, key=lambda k: k['type'])
    filterNum = len(filterItems)
    if filterNum != 0:
        endHTML += """
        var mapDiv = document.getElementById('map');
        var row = document.createElement('div');
        row.className="row";
        row.id="all";
        row.style.height = "100%";
        var col1 = document.createElement('div');
        col1.className="col9";
        col1.id = "mapWindow";
        col1.style.height = "99%";
        col1.style.width = "80%";
        col1.style.display = "inline-block";
        var col2 = document.createElement('div');
        col2.className="col3";
        col2.id = "menu";
        col2.style.display = "inline-block";
        mapDiv.parentNode.insertBefore(row, mapDiv);
        document.getElementById("all").appendChild(col1);
        document.getElementById("all").appendChild(col2);
        col1.appendChild(mapDiv)
        var Filters = {"""
        filterList = []
        for item in range(0, filterNum):
            filterList.append('"' + filterItems[item]["name"] + '": "' +
                              filterItems[item]["type"] + '"')
        endHTML += ",".join(filterList) + "};"
        endHTML += """
        function filterFunc() {
          map.eachLayer(function(lyr){
          if ("options" in lyr && "dataVar" in lyr["options"]){
            features = this[lyr["options"]["dataVar"]].features.slice(0);
            try{
              for (key in Filters){
                if (Filters[key] == "str" || Filters[key] == "bool"){
                  var selection = [];
                  var options = document.getElementById("sel_" + key).options
                  for (var i=0; i < options.length; i++) {
                    if (options[i].selected) selection.push(options[i].value);
                  }
                    try{
                      if (key in features[0].properties){
                        for (i = features.length - 1;
                          i >= 0; --i){
                          if (selection.indexOf(
                          features[i].properties[key])<0
                          && selection.length>0) {
                          features.splice(i,1);
                          }
                        }
                      }
                    } catch(err){
                  }
                }
                if (Filters[key] == "int"){
                  sliderVals =  document.getElementById(
                    "div_" + key).noUiSlider.get();
                  try{
                    if (key in features[0].properties){
                    for (i = features.length - 1; i >= 0; --i){
                      if (parseInt(features[i].properties[key])
                          < sliderVals[0]
                          || parseInt(features[i].properties[key])
                          > sliderVals[1]){
                            features.splice(i,1);
                          }
                        }
                      }
                    } catch(err){
                    }
                  }
                if (Filters[key] == "real"){
                  sliderVals =  document.getElementById(
                    "div_" + key).noUiSlider.get();
                  try{
                    if (key in features[0].properties){
                    for (i = features.length - 1; i >= 0; --i){
                      if (features[i].properties[key]
                          < sliderVals[0]
                          || features[i].properties[key]
                          > sliderVals[1]){
                            features.splice(i,1);
                          }
                        }
                      }
                    } catch(err){
                    }
                  }
                if (Filters[key] == "date"
                  || Filters[key] == "datetime"
                  || Filters[key] == "time"){
                  try{
                    if (key in features[0].properties){
                      HTMLkey = key.replace(/[&\/\\#,+()$~%.'":*?<>{} ]/g, '');
                      startdate = document.getElementById("dat_" +
                        HTMLkey + "_date1").value.replace(" ", "T");
                      enddate = document.getElementById("dat_" +
                        HTMLkey + "_date2").value.replace(" ", "T");
                      for (i = features.length - 1; i >= 0; --i){
                        if (features[i].properties[key] < startdate
                          || features[i].properties[key] > enddate){
                          features.splice(i,1);
                        }
                      }
                    }
                  } catch(err){
                  }
                }
              }
            } catch(err){
            }
          this[lyr["options"]["layerName"]].clearLayers();
          this[lyr["options"]["layerName"]].addData(features);
          }
          })
        }"""
        for item in range(0, filterNum):
            itemName = filterItems[item]["name"]
            if filterItems[item]["type"] in ["str", "bool"]:
                selSize = 2
                if filterItems[item]["type"] == "str":
                    if len(filterItems[item]["values"]) > 10:
                        selSize = 10
                    else:
                        selSize = len(filterItems[item]["values"])
                endHTML += """
            document.getElementById("menu").appendChild(
                document.createElement("div"));
            var div_{nameS} = document.createElement('div');
            div_{nameS}.id = "div_{name}";
            div_{nameS}.className= "filterselect";
            document.getElementById("menu").appendChild(div_{nameS});
            sel_{nameS} = document.createElement('select');
            sel_{nameS}.multiple = true;
            sel_{nameS}.size = {s};
            sel_{nameS}.id = "sel_{name}";
            var {nameS}_options_str = "<option value='' unselected></option>";
            sel_{nameS}.onchange = function(){{filterFunc()}};
            """.format(name=itemName, nameS=safeName(itemName), s=selSize)
                for entry in filterItems[item]["values"]:
                    try:
                        safeEntry = entry.replace("'", "&apos;")
                    except:
                        safeEntry = entry
                    endHTML += """
            {nameS}_options_str  += '<option value="{e}">{e}</option>';
                        """.format(e=safeEntry,
                                   name=itemName,
                                   nameS=safeName(itemName))
                endHTML += """
            sel_{nameS}.innerHTML = {nameS}_options_str;
            div_{nameS}.appendChild(sel_{nameS});
            var lab_{nameS} = document.createElement('div');
            lab_{nameS}.innerHTML = '{name}';
            lab_{nameS}.className = 'filterlabel';
            div_{nameS}.appendChild(lab_{nameS});
            var reset_{nameS} = document.createElement('div');
            reset_{nameS}.innerHTML = 'clear filter';
            reset_{nameS}.className = 'filterlabel';
            reset_{nameS}.onclick = function() {{
                var options = document.getElementById("sel_{nameS}").options;
                for (var i=0; i < options.length; i++) {{
                    options[i].selected = false;
                }}
                filterFunc();
            }};
            div_{nameS}.appendChild(reset_{nameS});
                """.format(name=itemName, nameS=safeName(itemName))
            if filterItems[item]["type"] in ["int", "real"]:
                endHTML += """
            document.getElementById("menu").appendChild(
                document.createElement("div"));
            var div_{nameS} = document.createElement("div");
            div_{nameS}.id = "div_{name}";
            div_{nameS}.className = "slider";
            document.getElementById("menu").appendChild(div_{nameS});
            var lab_{nameS} = document.createElement('div');
            lab_{nameS}.innerHTML  = '{name}: <span id="val_{name}"></span>';
            lab_{nameS}.className = 'filterlabel';
            document.getElementById("menu").appendChild(lab_{nameS});
            var reset_{nameS} = document.createElement('div');
            reset_{nameS}.innerHTML = 'clear filter';
            reset_{nameS}.className = 'filterlabel';
            lab_{nameS}.className = 'filterlabel';
            reset_{nameS}.onclick = function() {{
                sel_{nameS}.noUiSlider.reset();
            }};
            document.getElementById("menu").appendChild(reset_{nameS});
            var sel_{nameS} = document.getElementById('div_{name}');
            """.format(name=itemName, nameS=safeName(itemName))
                if filterItems[item]["type"] == "int":
                    endHTML += """
            noUiSlider.create(sel_{nameS}, {{
                connect: true,
                start: [{min}, {max}],
                step: 1,
                format: wNumb({{
                    decimals: 0,
                    }}),
                range: {{
                min: {min},
                max: {max}
                }}
            }});
            sel_{nameS}.noUiSlider.on('update', function (values) {{
            filterVals =[];
            for (value in values){{
            filterVals.push(parseInt(value))
            }}
            val_{nameS} = document.getElementById('val_{name}');
            val_{nameS}.innerHTML = values.join(' - ');
                filterFunc()
            }});""".format(name=itemName,
                           nameS=safeName(itemName),
                           min=filterItems[item]["values"][0],
                           max=filterItems[item]["values"][1])
                else:
                    endHTML += """
            noUiSlider.create(sel_{nameS}, {{
                connect: true,
                start: [{min}, {max}],
                range: {{
                min: {min},
                max: {max}
                }}
            }});
            sel_{nameS}.noUiSlider.on('update', function (values) {{
            val_{nameS} = document.getElementById('val_{name}');
            val_{nameS}.innerHTML = values.join(' - ');
                filterFunc()
            }});
            """.format(name=itemName,
                       nameS=safeName(itemName),
                       min=filterItems[item]["values"][0],
                       max=filterItems[item]["values"][1])
            if filterItems[item]["type"] in ["date", "time", "datetime"]:
                startDate = filterItems[item]["values"][0]
                endDate = filterItems[item]["values"][1]
                d = "'YYYY-mm-dd'"
                t = "'HH:ii:ss'"
                Y1 = startDate.toString("yyyy")
                M1 = startDate.toString("M")
                D1 = startDate.toString("d")
                hh1 = startDate.toString("h")
                mm1 = startDate.toString("m")
                ss1 = startDate.toString("s")
                Y2 = endDate.toString("yyyy")
                M2 = endDate.toString("M")
                D2 = endDate.toString("d")
                hh2 = endDate.toString("h")
                mm2 = endDate.toString("m")
                ss2 = endDate.toString("s")
                if filterItems[item]["type"] == "date":
                    t = "false"
                    hh1 = 0
                    mm1 = 0
                    ss1 = 0
                    hh2 = 0
                    mm2 = 0
                    ss2 = 0
                    ds = QDateTime(startDate).toMSecsSinceEpoch()
                    de = QDateTime(endDate).toMSecsSinceEpoch()
                if filterItems[item]["type"] == "datetime":
                    ds = startDate.toMSecsSinceEpoch()
                    de = endDate.toMSecsSinceEpoch()
                if filterItems[item]["type"] == "time":
                    d = "false"
                    Y1 = 0
                    M1 = 1
                    D1 = 0
                    Y2 = 0
                    M2 = 1
                    D2 = 0
                    ds = "null"
                    de = "null"
                endHTML += """
            document.getElementById("menu").appendChild(
                document.createElement("div"));
            var div_{nameS}_date1 = document.createElement("div");
            div_{nameS}_date1.id = "div_{nameS}_date1";
            div_{nameS}_date1.className= "filterselect";
            document.getElementById("menu").appendChild(div_{nameS}_date1);
            dat_{nameS}_date1 = document.createElement('input');
            dat_{nameS}_date1.type = "text";
            dat_{nameS}_date1.id = "dat_{nameS}_date1";
            div_{nameS}_date1.appendChild(dat_{nameS}_date1);
            var lab_{nameS}_date1 = document.createElement('div');
            lab_{nameS}_date1.innerHTML  = '{name} from';
            lab_{nameS}_date1.className = 'filterlabel';
            document.getElementById("div_{nameS}_date1").appendChild(
                lab_{nameS}_date1);
            var reset_{nameS}_date1 = document.createElement('div');
            reset_{nameS}_date1.innerHTML = "clear";
            reset_{nameS}_date1.className = 'filterlabel';
            reset_{nameS}_date1.onclick = function() {{
                tail.DateTime("#dat_{nameS}_date1", {{
                    dateStart: {ds},
                    dateEnd: {de},
                    dateFormat: {d},
                    timeFormat: {t},
                    today: false,
                    weekStart: 1,
                    position: "left",
                    closeButton: true,
                    timeStepMinutes:1,
                    timeStepSeconds: 1
                }}).selectDate({Y1},{M1}-1,{D1},{hh1},{mm1},{ss1});
                tail.DateTime("#dat_{nameS}_date1").reload()
            }}
            document.getElementById("div_{nameS}_date1").appendChild(
                reset_{nameS}_date1);
            document.addEventListener("DOMContentLoaded", function(){{
                tail.DateTime("#dat_{nameS}_date1", {{
                    dateStart: {ds},
                    dateEnd: {de},
                    dateFormat: {d},
                    timeFormat: {t},
                    today: false,
                    weekStart: 1,
                    position: "left",
                    closeButton: true,
                    timeStepMinutes:1,
                    timeStepSeconds: 1
                }}).selectDate({Y1},{M1}-1,{D1},{hh1},{mm1},{ss1});
                tail.DateTime("#dat_{nameS}_date1").reload()
                """.format(name=itemName,
                           nameS=safeName(itemName),
                           de=de,
                           ds=ds,
                           d=d,
                           t=t,
                           Y1=Y1,
                           M1=M1,
                           D1=D1,
                           hh1=hh1,
                           mm1=mm1,
                           ss1=ss1)
                endHTML += """
                tail.DateTime("#dat_{nameS}_date2", {{
                    dateStart: {ds},
                    dateEnd: {de},
                    dateFormat: {d},
                    timeFormat: {t},
                    today: false,
                    weekStart: 1,
                    position: "left",
                    closeButton: true,
                    timeStepMinutes:1,
                    timeStepSeconds: 1
                }}).selectDate({Y2},{M2}-1,{D2},{hh2},{mm2},{ss2});
                tail.DateTime("#dat_{nameS}_date2").reload()
                filterFunc()
                dat_{nameS}_date1.onchange = function(){{filterFunc()}};
                dat_{nameS}_date2.onchange = function(){{filterFunc()}};
            }});
            """.format(name=itemName,
                       nameS=safeName(itemName),
                       de=de,
                       ds=ds,
                       d=d,
                       t=t,
                       Y2=Y2,
                       M2=M2,
                       D2=D2,
                       hh2=hh2,
                       mm2=mm2,
                       ss2=ss2)
                endHTML += """
            var div_{nameS}_date2 = document.createElement("div");
            div_{nameS}_date2.id = "div_{nameS}_date2";
            div_{nameS}_date2.className= "filterselect";
            document.getElementById("menu").appendChild(div_{nameS}_date2);
            dat_{nameS}_date2 = document.createElement('input');
            dat_{nameS}_date2.type = "text";
            dat_{nameS}_date2.id = "dat_{nameS}_date2";
            div_{nameS}_date2.appendChild(dat_{nameS}_date2);
            var lab_{nameS}_date2 = document.createElement('div');
            lab_{nameS}_date2.innerHTML  = '{name} till';
            lab_{nameS}_date2.className = 'filterlabel';
            document.getElementById("div_{nameS}_date2")
              .appendChild(lab_{nameS}_date2);
            var reset_{nameS}_date2 = document.createElement('div');
            reset_{nameS}_date2.innerHTML = "clear";
            reset_{nameS}_date2.className = 'filterlabel';
            reset_{nameS}_date2.onclick = function() {{
                tail.DateTime("#dat_{nameS}_date2", {{
                    dateStart: {ds},
                    dateEnd: {de},
                    dateFormat: {d},
                    timeFormat: {t},
                    today: false,
                    weekStart: 1,
                    position: "left",
                    closeButton: true,
                    timeStepMinutes:1,
                    timeStepSeconds: 1
                }}).selectDate({Y2},{M2}-1,{D2},{hh2},{mm2},{ss2});
                tail.DateTime("#dat_{nameS}_date2").reload()
            }}
            document.getElementById("div_{nameS}_date2").appendChild(
                reset_{nameS}_date2);
            """.format(name=itemName,
                       nameS=safeName(itemName),
                       de=de,
                       ds=ds,
                       d=d,
                       t=t,
                       Y2=Y2,
                       M2=M2,
                       D2=D2,
                       hh2=hh2,
                       mm2=mm2,
                       ss2=ss2)
    if useHeat:
        endHTML += """
        function geoJson2heat(geojson, weight) {
          return geojson.features.map(function(feature) {
            return [
              feature.geometry.coordinates[1],
              feature.geometry.coordinates[0],
              feature.properties[weight]
            ];
          });
        }"""
    if useRaster:
        endHTML += """
        L.ImageOverlay.include({
            getBounds: function () {
                return this._bounds;
            }
        });"""
    if labelsList != "":
        endHTML += """
        resetLabels([%s]);
        map.on("zoomend", function(){
            resetLabels([%s]);
        });
        map.on("layeradd", function(){
            resetLabels([%s]);
        });
        map.on("layerremove", function(){
            resetLabels([%s]);
        });""" % (labelsList, labelsList, labelsList, labelsList)
    endHTML += """
        </script>%s""" % wfsLayers
    return endHTML
Example #34
0
    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')
Example #35
0
"""
__author__ = 'Denis Rouzaud'
__date__ = '2018-01-04'
__copyright__ = 'Copyright 2017, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '43ed203e898d1e318809ddbc7b047cbe71302dde'

import qgis  # NOQA

from qgis.gui import QgsDateTimeEdit
from qgis.PyQt.QtCore import Qt, QDateTime
from qgis.testing import start_app, unittest

start_app()

DATE = QDateTime.fromString('2018-01-01 01:02:03', Qt.ISODate)


class TestQgsDateTimeEdit(unittest.TestCase):
    def testSettersGetters(self):
        """ test widget handling of null values """
        w = qgis.gui.QgsDateTimeEdit()
        w.setAllowNull(False)

        w.setDateTime(DATE)
        self.assertEqual(DATE, w.dateTime())
        # date should remain when setting an invalid date
        w.setDateTime(QDateTime())
        self.assertEqual(DATE, w.dateTime())

    def testNullValueHandling(self):
# debug
f.write( "<GeoElevationGrid\n" )
f.write( "  geoGridOrigin='%f %f %f'\n" % (geoGridOrigin[1], geoGridOrigin[0],  geoGridOrigin[2]) )
f.write( "  xDimension='%d'\n" % xDimension)
f.write( "  zDimension='%d'\n" % zDimension)
f.write( "  xSpacing='%f'\n" % xSpacing )
f.write( "  zSpacing='%f'\n" % -zSpacing ) # need to reverse since starting from NW, flipped normals
f.write( "  solid='false'\n" ) # need to show backface
f.write( "  yScale='%s'\n" % vertical_exaggeration )
if geoSystem != ['GD','WE']:
    f.write( "  geoSystem='%s'\n" % " ".join(gS) )
f.write( "  height=' ")
for v in values:
    if v is None: v = noDataValue
    f.write( "%.*G " % (int(significant_digits_in_output), v))
f.write( "'>\n" )
#f.write( ">\n" )

f.write( "  <MetadataSet name='Raster metadata' >\n")
f.write( "    <MetadataString name='title' value='%s' ></MetadataString>\n" % r.name() )
f.write( "    <MetadataString name='attribution' value='%s' ></MetadataString>\n" % r.attribution() )
f.write( "    <MetadataString name='attributionReference' value='%s' ></MetadataString>\n" % r.attributionUrl() )
f.write( "    <MetadataString name='generator' value='QGIS Processing DEM_raster_to_X3D.py' ></MetadataString>\n" )
now = QDateTime.currentDateTime()
f.write( "    <MetadataString name='generated' value='%s' ></MetadataString>\n" % now.toString() )
f.write ( "  </MetadataSet>\n")

f.write( "</GeoElevationGrid>" )

f.close()