def testUnion(self): rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0) rect2 = QgsRectangle(2.0, 2.0, 7.0, 7.0) pnt1 = QgsPointXY(6.0, 2.0) rect1.combineExtentWith(rect2) myMessage = ('Expected: %s\nGot: %s\n' % (True, rect1.contains(rect2))) assert rect1.contains(rect2), myMessage print((rect1.toString())) assert rect1 == QgsRectangle( 0.0, 0.0, 7.0, 7.0), 'Wrong combine with rectangle result' rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0) rect1.combineExtentWith(6.0, 2.0) myMessage = ('Expected: %s\nGot: %s\n' % (True, rect1.contains(pnt1))) assert rect1.contains(pnt1), myMessage myExpectedResult = QgsRectangle(0.0, 0.0, 6.0, 5.0).toString() myResult = rect1.toString() myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedResult, myResult)) self.assertEqual(myResult, myExpectedResult, myMessage) rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0) rect1.combineExtentWith(rect2) myMessage = ('Expected: %s\nGot: %s\n' % (True, rect1.contains(rect2))) assert rect1.contains(rect2), myMessage assert rect1 == QgsRectangle(0.0, 0.0, 7.0, 7.0), "Wrong union result"
def testUnion(self): rect1 = QgsRectangle( 0.0, 0.0, 5.0, 5.0) rect2 = QgsRectangle( 2.0, 2.0, 7.0, 7.0) pnt1 = QgsPoint(6.0, 2.0) rect1.combineExtentWith(rect2) myMessage = ('Expected: %s\nGot: %s\n' % (True, rect1.contains(rect2))) assert rect1.contains(rect2), myMessage print rect1.toString() assert rect1 == QgsRectangle(0.0, 0.0, 7.0, 7.0), "Wrong combine with rectangle result" rect1 = QgsRectangle( 0.0, 0.0, 5.0, 5.0) rect1.combineExtentWith(6.0, 2.0) myMessage = ('Expected: %s\nGot: %s\n' % (True, rect1.contains(pnt1))) assert rect1.contains(pnt1), myMessage myExpectedResult = QgsRectangle(0.0, 0.0, 6.0, 5.0).toString() myResult = rect1.toString() myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedResult, myResult)) self.assertEquals(myResult, myExpectedResult, myMessage) rect1 = QgsRectangle( 0.0, 0.0, 5.0, 5.0) rect1.unionRect(rect2) myMessage = ('Expected: %s\nGot: %s\n' % (True, rect1.contains(rect2))) assert rect1.contains(rect2), myMessage assert rect1 == QgsRectangle(0.0, 0.0, 7.0, 7.0), "Wrong union result"
def test_mouse_drag(self): """Test setting extents by dragging works. This currently fails as QTest does not properly do the mouse interactions with the canvas. """ # Click the capture button QTest.mouseClick(self.dialog.capture_button, Qt.LeftButton) # drag a rect on the canvas QTest.mousePress(CANVAS, Qt.LeftButton, pos=QPoint(0, 0), delay=500) QTest.mouseRelease(CANVAS, Qt.LeftButton, pos=QPoint(300, 300), delay=-1) # on drag the extents selector windows should appear again QTest.qWaitForWindowShown(self.dialog) # Click ok to dispose of the window again ok = self.dialog.button_box.button(QtGui.QDialogButtonBox.Ok) QTest.mouseClick(ok, Qt.LeftButton) # Check the extent emitted on closing teh dialog is correct expected_extent = QgsRectangle(10.0, 10.0, 30.0, 20.0) self.assertEqual(self.extent.toString(), expected_extent.toString())
def test_mouse_drag(self): """Test setting extents by dragging works. This currently fails as QTest does not properly do the mouse interactions with the canvas. """ # Imported here because it is not available in OSX QGIS bundle # pylint: disable=redefined-outer-name from PyQt4.QtTest import QTest # Click the capture button QTest.mouseClick(self.dialog.capture_button, Qt.LeftButton) # drag a rect on the canvas QTest.mousePress(CANVAS, Qt.LeftButton, pos=QPoint(0, 0), delay=500) QTest.mouseRelease( CANVAS, Qt.LeftButton, pos=QPoint(300, 300), delay=-1) # on drag the extents selector windows should appear again QTest.qWaitForWindowShown(self.dialog) # Click ok to dispose of the window again ok = self.dialog.button_box.button(QtGui.QDialogButtonBox.Ok) QTest.mouseClick(ok, Qt.LeftButton) # Check the extent emitted on closing teh dialog is correct expected_extent = QgsRectangle(10.0, 10.0, 30.0, 20.0) self.assertEqual(self.extent.toString(), expected_extent.toString())
def bounds(self): """ Function for recalculating the bounded extents of the layers as they are processed. Under construction :return: """ # Requires refinement for raster manipulation of bounds selected_extent = unicode(self.getParameterValue(self.MAP_EXTENT)).split(',') xMin = float(selected_extent[0]) xMax = float(selected_extent[1]) yMin = float(selected_extent[2]) yMax = float(selected_extent[3]) extent = QgsRectangle(xMin, yMin, xMax, yMax) mapCRS = iface.mapCanvas().mapSettings().destinationCrs() transform = QgsCoordinateTransform( mapCRS, QgsCoordinateReferenceSystem('EPSG:4326') # WGS84 # QgsCoordinateReferenceSystem('EPSG:3785') # Popular vis mercator ) try: layer_extent = transform.transform(extent) except QgsCsException: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, "exception in transform layer srs") layer_extent = QgsRectangle(-180, -90, 180, 90) ProcessingLog.addToLog(ProcessingLog.LOG_INFO, layer_extent.toString()) return layer_extent
def test_point_to_rectangle(self): """Test for point to rectangle.""" point = QgsPoint(1.0, 1.0) rectangle = point_to_rectangle(point) expected_rectangle = QgsRectangle(0.9999999999900000, 0.9999999999900000, 1.0000000000100000, 1.0000000000100000) self.assertEqual(rectangle.toString(), expected_rectangle.toString())
def test_point_to_rectangle(self): """Test for point to rectangle.""" point = QgsPoint(1.0, 1.0) rectangle = point_to_rectangle(point) expected_rectangle = QgsRectangle( 0.9999999999900000, 0.9999999999900000, 1.0000000000100000, 1.0000000000100000) self.assertEqual(rectangle.toString(), expected_rectangle.toString())
def test_spinboxes(self): """Test validate extent method.""" self.dialog.x_maximum.clear() self.dialog.extent_defined.connect(self.extent_defined) QTest.mouseClick(self.dialog.x_maximum, Qt.LeftButton) QTest.keyClick(self.dialog.x_maximum, '3') QTest.keyClick(self.dialog.x_maximum, '0') ok = self.dialog.button_box.button(QtGui.QDialogButtonBox.Ok) QTest.mouseClick(ok, Qt.LeftButton) expected_extent = QgsRectangle(10.0, 10.0, 30.0, 20.0) self.assertEqual(self.extent.toString(), expected_extent.toString())
def testToString(self): """Test the different string representations""" rect = QgsRectangle(0, 0.1, 0.2, 0.3) myExpectedString = '0.0000000000000000,0.1000000000000000 : 0.2000000000000000,0.3000000000000000' myString = rect.toString() myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString)) assert myString == myExpectedString, myMessage myExpectedString = '0,0 : 0,0' myString = rect.toString(0) myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString)) assert myString == myExpectedString, myMessage myExpectedString = '0.00,0.10 : 0.20,0.30' myString = rect.toString(2) myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString)) assert myString == myExpectedString, myMessage myExpectedString = '0.0,0.1 : 0.2,0.3' myString = rect.toString(1) myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString)) assert myString == myExpectedString, myMessage myExpectedString = '0.00,0.10 : 0.20,0.30' myString = rect.toString(-1) myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString)) assert myString == myExpectedString, myMessage rect = QgsRectangle(5000000.01111, -0.3, 5000000.44111, 99.8) myExpectedString = '5000000.01,-0.30 : 5000000.44,99.80' myString = rect.toString(-1) myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString)) assert myString == myExpectedString, myMessage
def _retrieve_features(self): # Construct an MBR in which to look for vectors in the layer rect = QgsRectangle(self.pt1, self.pt2) log.logMessage( "Getting features in layer {}, intersecting rect {}".format( self.layer.name(), rect.toString()), level=QgsMessageLog.INFO) # Retrieve vectors from the layer that intersect the constructed MBR feat_geom_map = { f: f.geometry() for f in self.layer.getFeatures(QgsFeatureRequest(rect)) } log.logMessage("Got {} features".format(len(feat_geom_map)), level=QgsMessageLog.INFO) return feat_geom_map
def testToString(self): """Test the different string representations""" self.assertEqual(QgsRectangle().toString(), 'Empty') rect = QgsRectangle(0, 0.1, 0.2, 0.3) myExpectedString = '0.0000000000000000,0.1000000000000000 : 0.2000000000000000,0.3000000000000000' myString = rect.toString() myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString)) assert myString == myExpectedString, myMessage # can't test the actual result here, because floating point inaccuracies mean the result is unpredictable # at this precision self.assertEqual(len(rect.toString(20)), 93) myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString)) assert myString == myExpectedString, myMessage myExpectedString = '0,0 : 0,0' myString = rect.toString(0) myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString)) assert myString == myExpectedString, myMessage myExpectedString = '0.00,0.10 : 0.20,0.30' myString = rect.toString(2) myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString)) assert myString == myExpectedString, myMessage myExpectedString = '0.0,0.1 : 0.2,0.3' myString = rect.toString(1) myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString)) assert myString == myExpectedString, myMessage myExpectedString = '0.00,0.10 : 0.20,0.30' myString = rect.toString(-1) myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString)) assert myString == myExpectedString, myMessage rect = QgsRectangle(5000000.01111, -0.3, 5000000.44111, 99.8) myExpectedString = '5000000.01,-0.30 : 5000000.44,99.80' myString = rect.toString(-1) myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString)) assert myString == myExpectedString, myMessage
def testUnion(self): rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0) rect2 = QgsRectangle(2.0, 2.0, 7.0, 7.0) pnt1 = QgsPointXY(6.0, 2.0) rect1.combineExtentWith(rect2) self.assertTrue(rect1.contains(rect2)) self.assertEqual(rect1, QgsRectangle(0.0, 0.0, 7.0, 7.0)) rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0) rect1.combineExtentWith(6.0, 2.0) self.assertTrue(rect1.contains(pnt1)) self.assertEqual(rect1.toString(), QgsRectangle(0.0, 0.0, 6.0, 5.0).toString()) rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0) rect1.combineExtentWith(rect2) self.assertTrue(rect1.contains(rect2)) self.assertEqual(rect1, QgsRectangle(0.0, 0.0, 7.0, 7.0))
def testToString(self): """Test the different string representations""" self.assertEqual(QgsRectangle().toString(), 'Empty') rect = QgsRectangle(0, 0.1, 0.2, 0.3) self.assertEqual( rect.toString(), '0.0000000000000000,0.1000000000000000 : 0.2000000000000000,0.3000000000000000' ) # can't test the actual result here, because floating point inaccuracies mean the result is unpredictable # at this precision self.assertEqual(len(rect.toString(20)), 93) self.assertEqual(rect.toString(0), '0,0 : 0,0') self.assertEqual(rect.toString(2), '0.00,0.10 : 0.20,0.30') self.assertEqual(rect.toString(1), '0.0,0.1 : 0.2,0.3') self.assertEqual(rect.toString(-1), '0.00,0.10 : 0.20,0.30') rect = QgsRectangle(5000000.01111, -0.3, 5000000.44111, 99.8) self.assertEqual(rect.toString(-1), '5000000.01,-0.30 : 5000000.44,99.80')
def write_csv(self): layer = self.iface.activeLayer() if layer.type() != QgsMapLayer.VectorLayer: self.show_message( 'The active layer "{}" is NOT a vector layer containing plot data.\nPlease make a polygon layer active in the layermanager.' .format(layer.name())) return reply = QMessageBox.question( self.iface.mainWindow(), 'FieldExplorer NL', 'Save current active layer "{}" to FieldExplorer CSV?'.format( layer.name()), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) if reply == QMessageBox.No: return layer_path = layer.dataProvider().dataSourceUri() (directory, file_name) = os.path.split(layer_path) file_name = file_name.split('|')[0] csv_name = os.path.splitext(file_name)[0] + '.csv' csv_file = os.path.join(directory, csv_name) # check if dir is writable if not os.access(directory, os.W_OK): # W_OK is for writing, R_OK for reading self.show_message( 'The data directory "{}"\nis not writable, will not be able to write a csv there.' .format(directory)) return # check if layer's crs = epsg:4326 if 'EPSG:4326' != layer.crs().authid(): self.show_message( 'The layer should have EPSG:4326 as crs, but is: "{}".\nPlease provide a layer in EPSG:4326 (lat lon coordinates).' .format(layer.crs().authid())) return # or coordinates within 2,50.0 : 8.0,55 (NL)) layer_extent = layer.extent() nl_extent = QgsRectangle(2, 50.0, 8.0, 55) if not nl_extent.contains(layer_extent): self.show_message( 'The data/layer extent:\n{}\nis not within The Netherlands.\nPlease provide data within\n{}.' .format(layer_extent.toString(), nl_extent.toString())) return features = layer.getFeatures() attributes = layer.fields().names() if not ('Plot-ID' in attributes and 'Comments' in attributes): self.show_message( 'The data should contain both an "Plot-ID" and a "Comments" attribute.\nAvailable attributes: {}' .format(attributes)) return # check for touches (could also be intersects) for feature in features: others = layer.getFeatures() for other in others: # self.log('Testing: \n{} with {}'.format(feature.attributes(), other.attributes())) if feature['Plot-ID'] == other['Plot-ID']: # self.log('IDEM: \n{} {}'.format(feature.attributes(),other.attributes())) pass elif feature.geometry().intersects(other.geometry()): self.show_message( 'These two features intersect each other: ' '\n{}\n{}. They should not share vertices and segments should not touch.' .format(feature.attributes(), other.attributes())) return features = layer.getFeatures() with open(csv_file, 'w', newline='') as f: self.log( 'Starting to write "{}" ({} in {}) to FieldExplorer NL CSV'. format(layer.name(), file_name, directory)) # QUOTE_NONNUMERIC, QUOTE_MINIMAL csv_writer = csv.writer(f, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) # NO quoting # header csv_writer.writerow( ('Plot-ID', 'A(LAT)', 'A(LONG)', 'B(LAT)', 'B(LONG)', 'C(LAT)', 'C(LONG)', 'D(LAT)', 'D(LONG)', 'Comments')) for feature in features: geom = feature.geometry() # force singletype (so both multi and single will work) if not geom.convertToSingleType(): self.show_message( 'Cannot convert feature {} to a single polygon.'. format(feature.attributes())) return # force clockwise direction! geom.forceRHR() coordinates = [] for vertex in geom.vertices(): coordinates.append(vertex) # check if just 5 if len(coordinates) > 5: self.show_message( 'The feature {}\ncontains too many vertices,\nthere should be just 4, but has: {}' .format(feature.attributes(), len(coordinates) - 1)) return if len(f'{feature["Plot-ID"]:}') > 50: self.show_message( 'The feature {}\nhas a Plot-ID of length {}\nPlease change this Plot-ID to a shorter one:\n"{}"' .format(feature.attributes(), len(feature['Plot-ID']), feature['Plot-ID'])) return # check for '\ / : * ? " < > |' forbidden_chars = ('\\', '/', ':', '*', '?', '"', '<', '>', '|') for c in forbidden_chars: if c in f'{feature["Plot-ID"]:}': self.show_message( 'The feature {}\ncontains the character "{}" which is forbidden in Plot-IDs\nPlease change this Plot-ID: "{}"' .format(feature.attributes(), c, feature['Plot-ID'])) return row = [] row.append(feature['Plot-ID']) for coord in coordinates[:-1]: row.append(coord.y()) row.append(coord.x()) if 'Comments' in attributes: row.append(feature['Comments']) csv_writer.writerow(row) # OK, done! self.iface.messageBar().pushMessage( 'Done!', 'Succesfully wrote FieldExplorer CSV file to:\n{}'.format( csv_file), level=Qgis.Info, duration=15)
def drawDebugInformation(layer, renderContext, zoom, xmin, ymin, xmax, ymax): self = layer mapSettings = self.iface.mapCanvas().mapSettings() lines = [] lines.append("TileLayer") lines.append( " zoom: %d, tile matrix extent: (%d, %d) - (%d, %d), tile count: %d * %d" % (zoom, xmin, ymin, xmax, ymax, xmax - xmin, ymax - ymin)) extent = renderContext.extent() lines.append(" map extent (renderContext): %s" % extent.toString()) lines.append(" map center (renderContext): %lf, %lf" % (extent.center().x(), extent.center().y())) lines.append(" map size: %f, %f" % (extent.width(), extent.height())) lines.append(" map extent (map canvas): %s" % self.iface.mapCanvas().extent().toString()) map2pixel = renderContext.mapToPixel() painter = renderContext.painter() viewport = painter.viewport() mapExtent = QgsRectangle( map2pixel.toMapCoordinatesF(0, 0), map2pixel.toMapCoordinatesF(viewport.width(), viewport.height())) lines.append(" map extent (calculated): %s" % mapExtent.toString()) lines.append(" map center (calc rect): %lf, %lf" % (mapExtent.center().x(), mapExtent.center().y())) center = map2pixel.toMapCoordinatesF(0.5 * viewport.width(), 0.5 * viewport.height()) lines.append(" map center (calc pt): %lf, %lf" % (center.x(), center.y())) lines.append(" viewport size (pixel): %d, %d" % (viewport.width(), viewport.height())) lines.append(" window size (pixel): %d, %d" % (painter.window().width(), painter.window().height())) lines.append( " outputSize (pixel): %d, %d" % (mapSettings.outputSize().width(), mapSettings.outputSize().height())) device = painter.device() lines.append(" deviceSize (pixel): %f, %f" % (device.width(), device.height())) lines.append(" logicalDpi: %f, %f" % (device.logicalDpiX(), device.logicalDpiY())) lines.append(" outputDpi: %f" % mapSettings.outputDpi()) lines.append(" mapToPixel: %s" % map2pixel.showParameters()) mupp = map2pixel.mapUnitsPerPixel() lines.append(" map units per pixel: %f" % mupp) lines.append(" meters per pixel (renderContext): %f" % (extent.width() / viewport.width())) transform = renderContext.coordinateTransform() if transform: mpp = mupp * { QGis.Feet: 0.3048, QGis.Degrees: self.layerDef.TSIZE1 / 180 }.get(transform.destCRS().mapUnits(), 1) lines.append(" meters per pixel (calc 1): %f" % mpp) cx, cy = 0.5 * viewport.width(), 0.5 * viewport.height() geometry = QgsGeometry.fromPolyline([ map2pixel.toMapCoordinatesF(cx - 0.5, cy), map2pixel.toMapCoordinatesF(cx + 0.5, cy) ]) geometry.transform( QgsCoordinateTransform( transform.destCRS(), transform.sourceCrs())) # project CRS to layer CRS (EPSG:3857) mpp = geometry.length() lines.append(" meters per pixel (calc center pixel): %f" % mpp) lines.append(" scaleFactor: %f" % renderContext.scaleFactor()) lines.append(" rendererScale: %f" % renderContext.rendererScale()) scaleX, scaleY = self.getScaleToVisibleExtent(renderContext) lines.append(" scale: %f, %f" % (scaleX, scaleY)) # draw information textRect = painter.boundingRect(QRect(QPoint(0, 0), viewport.size()), Qt.AlignLeft, "Q") for i, line in enumerate(lines): painter.drawText(10, (i + 1) * textRect.height(), line) self.log(line) # diagonal painter.drawLine( QPointF(0, 0), QPointF(painter.viewport().width(), painter.viewport().height())) painter.drawLine(QPointF(painter.viewport().width(), 0), QPointF(0, painter.viewport().height())) # credit label margin, paddingH, paddingV = (3, 4, 3) credit = "This is credit" rect = QRect(0, 0, painter.viewport().width() - margin, painter.viewport().height() - margin) textRect = painter.boundingRect(rect, Qt.AlignBottom | Qt.AlignRight, credit) bgRect = QRect(textRect.left() - paddingH, textRect.top() - paddingV, textRect.width() + 2 * paddingH, textRect.height() + 2 * paddingV) painter.drawRect(bgRect) painter.drawText(rect, Qt.AlignBottom | Qt.AlignRight, credit)
def testBoundingBox(self): # 2-+-+-+-+-3 # | | # + 6-+-+-7 + # | | | | # + + 9-+-8 + # | | | # ! 5-+-+-+-4 ! # | # 1-+-+-+-+-0 ! points = [ QgsPoint(5,0), QgsPoint(0,0), QgsPoint(0,4), QgsPoint(5,4), QgsPoint(5,1), QgsPoint(1,1), QgsPoint(1,3), QgsPoint(4,3), QgsPoint(4,2), QgsPoint(2,2) ] polyline = QgsGeometry.fromPolyline(points) expbb = QgsRectangle(0,0,5,4) bb = polyline.boundingBox() assert expbb == bb, "Expected:\n%s\nGot:\n%s\n" % (expbb.toString(), bb.toString()) # 2-3 6-+-7 # | | | | # 0-1 4 5 8-9 points = [ [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,0), ], [ QgsPoint(3,0), QgsPoint(3,1), QgsPoint(5,1), QgsPoint(5,0), QgsPoint(6,0), ] ] polyline = QgsGeometry.fromMultiPolyline(points) expbb = QgsRectangle(0,0,6,1) bb = polyline.boundingBox() assert expbb == bb, "Expected:\n%s\nGot:\n%s\n" % (expbb.toString(), bb.toString()) # 5---4 # | | # | 2-3 # | | # 0-1 points = [[ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0), ]] polygon = QgsGeometry.fromPolygon(points) expbb = QgsRectangle(0,0,2,2) bb = polygon.boundingBox() assert expbb == bb, "Expected:\n%s\nGot:\n%s\n" % (expbb.toString(), bb.toString()) # 3-+-+-2 # | | # + 8-7 + # | | | | # + 5-6 + # | | # 0-+-+-1 points = [ [ QgsPoint(0,0), QgsPoint(3,0), QgsPoint(3,3), QgsPoint(0,3), QgsPoint(0,0) ], [ QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(1,2), QgsPoint(1,1) ], ] polygon = QgsGeometry.fromPolygon(points) expbb = QgsRectangle(0,0,3,3) bb = polygon.boundingBox() assert expbb == bb, "Expected:\n%s\nGot:\n%s\n" % (expbb.toString(), bb.toString()) # 5-+-4 0-+-9 # | | | | # | 2-3 1-2 | # | | | | # 0-1 7-8 points = [ [ [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0), ] ], [ [ QgsPoint(4,0), QgsPoint(5,0), QgsPoint(5,2), QgsPoint(3,2), QgsPoint(3,1), QgsPoint(4,1), QgsPoint(4,0), ] ] ] polygon = QgsGeometry.fromMultiPolygon(points) expbb = QgsRectangle(0,0,5,2) bb = polygon.boundingBox() assert expbb == bb, "Expected:\n%s\nGot:\n%s\n" % (expbb.toString(), bb.toString())
def drawDebugInformation(layer, renderContext, zoom, xmin, ymin, xmax, ymax): self = layer mapSettings = self.iface.mapCanvas().mapSettings() lines = [] lines.append("TileLayer") lines.append(" zoom: %d, tile matrix extent: (%d, %d) - (%d, %d), tile count: %d * %d" % (zoom, xmin, ymin, xmax, ymax, xmax - xmin, ymax - ymin)) extent = renderContext.extent() lines.append(" map extent (renderContext): %s" % extent.toString()) lines.append(" map center (renderContext): %lf, %lf" % (extent.center().x(), extent.center().y())) lines.append(" map size: %f, %f" % (extent.width(), extent.height())) lines.append(" map extent (map canvas): %s" % self.iface.mapCanvas().extent().toString()) map2pixel = renderContext.mapToPixel() painter = renderContext.painter() viewport = painter.viewport() mapExtent = QgsRectangle(map2pixel.toMapCoordinatesF(0, 0), map2pixel.toMapCoordinatesF(viewport.width(), viewport.height())) lines.append(" map extent (calculated): %s" % mapExtent.toString()) lines.append(" map center (calc rect): %lf, %lf" % (mapExtent.center().x(), mapExtent.center().y())) center = map2pixel.toMapCoordinatesF(0.5 * viewport.width(), 0.5 * viewport.height()) lines.append(" map center (calc pt): %lf, %lf" % (center.x(), center.y())) lines.append(" viewport size (pixel): %d, %d" % (viewport.width(), viewport.height())) lines.append(" window size (pixel): %d, %d" % (painter.window().width(), painter.window().height())) lines.append(" outputSize (pixel): %d, %d" % (mapSettings.outputSize().width(), mapSettings.outputSize().height())) device = painter.device() lines.append(" deviceSize (pixel): %f, %f" % (device.width(), device.height())) lines.append(" logicalDpi: %f, %f" % (device.logicalDpiX(), device.logicalDpiY())) lines.append(" outputDpi: %f" % mapSettings.outputDpi()) lines.append(" mapToPixel: %s" % map2pixel.showParameters()) mupp = map2pixel.mapUnitsPerPixel() lines.append(" map units per pixel: %f" % mupp) lines.append(" meters per pixel (renderContext): %f" % (extent.width() / viewport.width())) transform = renderContext.coordinateTransform() if transform: mpp = mupp * {QGis.Feet: 0.3048, QGis.Degrees: self.layerDef.TSIZE1 / 180}.get(transform.destCRS().mapUnits(), 1) lines.append(" meters per pixel (calc 1): %f" % mpp) cx, cy = 0.5 * viewport.width(), 0.5 * viewport.height() geometry = QgsGeometry.fromPolyline([map2pixel.toMapCoordinatesF(cx - 0.5, cy), map2pixel.toMapCoordinatesF(cx + 0.5, cy)]) geometry.transform(QgsCoordinateTransform(transform.destCRS(), transform.sourceCrs())) # project CRS to layer CRS (EPSG:3857) mpp = geometry.length() lines.append(" meters per pixel (calc center pixel): %f" % mpp) lines.append(" scaleFactor: %f" % renderContext.scaleFactor()) lines.append(" rendererScale: %f" % renderContext.rendererScale()) scaleX, scaleY = self.getScaleToVisibleExtent(renderContext) lines.append(" scale: %f, %f" % (scaleX, scaleY)) # draw information textRect = painter.boundingRect(QRect(QPoint(0, 0), viewport.size()), Qt.AlignLeft, "Q") for i, line in enumerate(lines): painter.drawText(10, (i + 1) * textRect.height(), line) self.log(line) # diagonal painter.drawLine(QPointF(0, 0), QPointF(painter.viewport().width(), painter.viewport().height())) painter.drawLine(QPointF(painter.viewport().width(), 0), QPointF(0, painter.viewport().height())) # credit label margin, paddingH, paddingV = (3, 4, 3) credit = "This is credit" rect = QRect(0, 0, painter.viewport().width() - margin, painter.viewport().height() - margin) textRect = painter.boundingRect(rect, Qt.AlignBottom | Qt.AlignRight, credit) bgRect = QRect(textRect.left() - paddingH, textRect.top() - paddingV, textRect.width() + 2 * paddingH, textRect.height() + 2 * paddingV) painter.drawRect(bgRect) painter.drawText(rect, Qt.AlignBottom | Qt.AlignRight, credit)
def __select_wfs_layer(self) -> None: indexes = self.tbl_wdgt_stored_queries.selectedIndexes() if not indexes: LOGGER.warning( tr("Could not execute select"), extra=bar_msg(tr("Data source must be selected first!")), ) return self.selected_stored_query = self.stored_queries[indexes[0].row()] LOGGER.info( tr("Selected query id: {}", self.selected_stored_query.id)) # type: ignore # noqa E501 self.sq_factory.expand(self.selected_stored_query) # type: ignore for widget_set in self.parameter_rows.values(): for widget in widget_set: if isinstance(widget, QVBoxLayout): self.grid.removeItem(widget) else: self.grid.removeWidget(widget) widget.hide() widget.setParent(None) widget = None self.parameter_rows = {} row_idx = -1 self.extent_group_box_bbox.setEnabled(False) for param_name, parameter in self.selected_stored_query.parameters.items( ): # type: ignore # noqa E501 possible_values = parameter.possible_values widgets = set() # type: ignore if parameter.type in (QVariant.Rect, QVariant.RectF): self.parameter_rows[param_name] = widgets self.extent_group_box_bbox.setEnabled(True) if possible_values: dataset_extent = QgsRectangle( *(map(float, possible_values[0].split(",")))) current_extent: QgsRectangle = ( self.extent_group_box_bbox.outputExtent()) extent_msg = tr( "Your extent: {}, dataset maximum extent: {}", current_extent.toString(2), dataset_extent.toString(2), ) if dataset_extent.area() / current_extent.area() > 100: LOGGER.warning( tr("Big difference in bounding boxes"), extra=bar_msg( tr( "You might want to get a larger extent. {}", extent_msg, )), ) elif current_extent.area() / dataset_extent.area() > 100: LOGGER.warning( tr("Big difference in bounding boxes"), extra=bar_msg( tr( "You might want to get a smaller extent. {}", extent_msg, )), ) if not current_extent.toRectF().intersects( dataset_extent.toRectF()): LOGGER.warning( tr("Your bounding box and dataset bounding " "box do not intersect"), extra=bar_msg( tr( "You might want to change your extent. {}", extent_msg, )), ) continue row_idx += 1 widget: QWidget = widget_for_field(parameter.type) # type: ignore if (isinstance(widget, QComboBox) or isinstance(widget, QSpinBox) or isinstance(widget, QgsDoubleSpinBox)): widget = QLineEdit() if possible_values: if len(possible_values) == 1: widget.setText(possible_values[0]) else: widget = QComboBox() widget.addItems(possible_values) widget.setEditable(True) if isinstance(widget, QgsDateTimeEdit) and possible_values: widget.setDateTimeRange(min(possible_values), max(possible_values)) if param_name.startswith("end"): widget.setDateTime(max(possible_values)) else: widget.setDateTime(min(possible_values)) if len(possible_values) == 1: widget.setEnabled(False) widget.setToolTip(parameter.abstract) if parameter.type == QVariant.StringList: if parameter.has_variables(): widget = QVBoxLayout() widget.addStretch(1) for variable in parameter.variables: box = QCheckBox(text=variable.alias) box.setToolTip(variable.label) widgets.add(box) widget.addWidget(box) LOGGER.info(tr("Variables: {}", variable.alias)) # TODO: all others if widget is None: LOGGER.error( tr("Unknown parameter type"), extra=bar_msg( tr('With parameter"{}": {}', param_name, parameter.type)), ) return label = QLabel(text=parameter.name) label.setToolTip(parameter.abstract) widgets.update({label, widget}) self.grid.addWidget(label, row_idx, 1) if isinstance(widget, QVBoxLayout): self.grid.addLayout(widget, row_idx, 2) else: self.grid.addWidget(widget, row_idx, 2) self.parameter_rows[param_name] = widgets
class ExtentSelectorTest(unittest.TestCase): """Test Import Dialog widget """ # noinspection PyPep8Naming def setUp(self): """Runs before each test.""" self.extent = QgsRectangle(10.0, 10.0, 20.0, 20.0) self.crs = QgsCoordinateReferenceSystem('EPSG:4326') CANVAS.setExtent(self.extent) self.dialog = ExtentSelectorDialog(IFACE, PARENT, self.extent, self.crs) self.signal_received = False self.dialog.extent_defined.connect(self.extent_defined) self.widget = QtGui.QWidget() self.widget.setGeometry(0, 0, 500, 500) layout = QtGui.QVBoxLayout(self.widget) layout.addWidget(CANVAS) self.widget.show() QTest.qWaitForWindowShown(self.widget) self.dialog.show() QTest.qWaitForWindowShown(self.dialog) def tearDown(self): """Runs after each test.""" self.dialog.reject() self.dialog = None self.extent = None self.crs = None def extent_defined(self, extent, crs): """Slot for when extents are changed in dialog. :param extent: Rectangle that was created. :type extent: QgsRectangle :param crs: Coordiate reference system. :type crs: QgsCoordinateReferenceSystem """ self.extent = extent self.crs = crs self.signal_received = True def canvas_mouse_moved(self, point): """Slot for when the mouse moves on the canvas.""" print point.toString() def test_spinboxes(self): """Test validate extent method.""" self.dialog.x_maximum.clear() self.dialog.extent_defined.connect(self.extent_defined) QTest.mouseClick(self.dialog.x_maximum, Qt.LeftButton) QTest.keyClick(self.dialog.x_maximum, '3') QTest.keyClick(self.dialog.x_maximum, '0') ok = self.dialog.button_box.button(QtGui.QDialogButtonBox.Ok) QTest.mouseClick(ok, Qt.LeftButton) expected_extent = QgsRectangle(10.0, 10.0, 30.0, 20.0) self.assertEqual(self.extent.toString(), expected_extent.toString()) @unittest.expectedFailure @unittest.skip def test_mouse_drag(self): """Test setting extents by dragging works. This currently fails as QTest does not properly do the mouse interactions with the canvas. """ # Click the capture button QTest.mouseClick(self.dialog.capture_button, Qt.LeftButton) # drag a rect on the canvas QTest.mousePress(CANVAS, Qt.LeftButton, pos=QPoint(0, 0), delay=500) QTest.mouseRelease(CANVAS, Qt.LeftButton, pos=QPoint(300, 300), delay=-1) # on drag the extents selector windows should appear again QTest.qWaitForWindowShown(self.dialog) # Click ok to dispose of the window again ok = self.dialog.button_box.button(QtGui.QDialogButtonBox.Ok) QTest.mouseClick(ok, Qt.LeftButton) # Check the extent emitted on closing teh dialog is correct expected_extent = QgsRectangle(10.0, 10.0, 30.0, 20.0) self.assertEqual(self.extent.toString(), expected_extent.toString())
class ExtentSelectorTest(unittest.TestCase): """Test Import Dialog widget """ # noinspection PyPep8Naming def setUp(self): """Runs before each test.""" self.extent = QgsRectangle(10.0, 10.0, 20.0, 20.0) self.crs = QgsCoordinateReferenceSystem('EPSG:4326') CANVAS.setExtent(self.extent) self.dialog = ExtentSelectorDialog( IFACE, PARENT, self.extent, self.crs) self.signal_received = False self.dialog.extent_defined.connect(self.extent_defined) self.widget = QtGui.QWidget() self.widget.setGeometry(0, 0, 500, 500) layout = QtGui.QVBoxLayout(self.widget) layout.addWidget(CANVAS) self.widget.show() QTest.qWaitForWindowShown(self.widget) self.dialog.show() QTest.qWaitForWindowShown(self.dialog) def tearDown(self): """Runs after each test.""" self.dialog.reject() self.dialog = None self.extent = None self.crs = None def extent_defined(self, extent, crs): """Slot for when extents are changed in dialog. :param extent: Rectangle that was created. :type extent: QgsRectangle :param crs: Coordiate reference system. :type crs: QgsCoordinateReferenceSystem """ self.extent = extent self.crs = crs self.signal_received = True def canvas_mouse_moved(self, point): """Slot for when the mouse moves on the canvas.""" print point.toString() def test_spinboxes(self): """Test validate extent method.""" self.dialog.x_maximum.clear() self.dialog.extent_defined.connect(self.extent_defined) QTest.mouseClick(self.dialog.x_maximum, Qt.LeftButton) QTest.keyClick(self.dialog.x_maximum, '3') QTest.keyClick(self.dialog.x_maximum, '0') ok = self.dialog.button_box.button(QtGui.QDialogButtonBox.Ok) QTest.mouseClick(ok, Qt.LeftButton) expected_extent = QgsRectangle(10.0, 10.0, 30.0, 20.0) self.assertEqual(self.extent.toString(), expected_extent.toString()) @unittest.expectedFailure @unittest.skip def test_mouse_drag(self): """Test setting extents by dragging works. This currently fails as QTest does not properly do the mouse interactions with the canvas. """ # Imported here because it is not available in OSX QGIS bundle # pylint: disable=redefined-outer-name from PyQt4.QtTest import QTest # Click the capture button QTest.mouseClick(self.dialog.capture_button, Qt.LeftButton) # drag a rect on the canvas QTest.mousePress(CANVAS, Qt.LeftButton, pos=QPoint(0, 0), delay=500) QTest.mouseRelease( CANVAS, Qt.LeftButton, pos=QPoint(300, 300), delay=-1) # on drag the extents selector windows should appear again QTest.qWaitForWindowShown(self.dialog) # Click ok to dispose of the window again ok = self.dialog.button_box.button(QtGui.QDialogButtonBox.Ok) QTest.mouseClick(ok, Qt.LeftButton) # Check the extent emitted on closing teh dialog is correct expected_extent = QgsRectangle(10.0, 10.0, 30.0, 20.0) self.assertEqual(self.extent.toString(), expected_extent.toString())