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)
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__"
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)
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' )
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' )
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 ]])
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))
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')
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)
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')
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))
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)
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
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("'", "'") 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
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')
""" __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()