def testAsWktPolygon(self): """Test that we can get a proper rect wkt polygon representation for rect""" rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0) myExpectedWkt = "POLYGON((0 0, " "5 0, " "5 5, " "0 5, " "0 0))" myWkt = rect1.asWktPolygon() myMessage = "Expected: %s\nGot: %s\n" % (myExpectedWkt, myWkt) assert compareWkt(myWkt, myExpectedWkt), myMessage
def testAsWktPolygon(self): """Test that we can get a proper wkt polygon representation fo the rect""" rect1 = QgsRectangle( 0.0, 0.0, 5.0, 5.0) myExpectedWkt = ('POLYGON((0.0000000000000000 0.0000000000000000, ' '5.0000000000000000 0.0000000000000000, ' '5.0000000000000000 5.0000000000000000, ' '0.0000000000000000 5.0000000000000000, ' '0.0000000000000000 0.0000000000000000))') myWkt = rect1.asWktPolygon() myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedWkt, myWkt)) self.assertEquals(myWkt, myExpectedWkt, myMessage)
def testAsWktPolygon(self): """Test that we can get a proper rect wkt polygon representation for rect""" rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0) myExpectedWkt = ('POLYGON((0 0, ' '5 0, ' '5 5, ' '0 5, ' '0 0))') myWkt = rect1.asWktPolygon() myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedWkt, myWkt)) assert compareWkt(myWkt, myExpectedWkt), myMessage
def createRectangle(self): llx = float(self.dlg.lleast.text()) lly = float(self.dlg.llnorth.text()) urx = float(self.dlg.ureast.text()) ury = float(self.dlg.urnorth.text()) print llx, lly, urx, ury p1 = QgsPoint(llx, lly) p2 = QgsPoint(urx, ury) rectangle = QgsRectangle(p1, p2) rectangleLayer = QgsVectorLayer("Polygon?crs=EPSG:2056", "rectangle", "memory") rectangleLayerProvider = rectangleLayer.dataProvider() newFeat = QgsFeature() geom = QgsGeometry.fromWkt(rectangle.asWktPolygon()) newFeat.setGeometry(geom) rectangleLayerProvider.addFeatures([newFeat]) QgsMapLayerRegistry.instance().addMapLayer(rectangleLayer)
def envelope2layer(self, envelope): """Transform metadata envelope into a QGIS layer.""" # layer md_lyr = QgsVectorLayer("Polygon?crs=epsg:4326", "Metadata envelope", "memory") symbols = md_lyr.renderer().symbols(QgsRenderContext()) symbol = symbols[0] symbol.setColor(QColor.fromRgb(255, 20, 147)) symbol.setOpacity(0.25) if envelope.get("type") == "Polygon": # parse coordinates coords = envelope.get("coordinates")[0] poly_pts = [ QgsPointXY(round(i[0], 3), round(i[1], 3)) for i in coords ] # add geometry to layer poly = QgsFeature() poly.setGeometry(QgsGeometry.fromPolygonXY([poly_pts])) md_lyr.dataProvider().addFeatures([poly]) md_lyr.updateExtents() elif envelope.get("type") == "MultiPolygon": coords = envelope.get("bbox") bbox = QgsRectangle( round(coords[0], 3), round(coords[1], 3), round(coords[2], 3), round(coords[3], 3), ) poly = QgsFeature() poly.setGeometry(QgsGeometry.fromWkt(bbox.asWktPolygon())) md_lyr.dataProvider().addFeatures([poly]) md_lyr.updateExtents() elif envelope.get("type") == "Point": return md_lyr else: pass # method ending return md_lyr
def envelope2layer(self, envelope): """Transform metadata envelope into a QGIS layer.""" # layer md_lyr = QgsVectorLayer("Polygon?crs=epsg:4326", "Metadata envelope", "memory") md_lyr.setLayerTransparency(75) symbols = md_lyr.rendererV2().symbols() symbol = symbols[0] symbol.setColor(QColor.fromRgb(255,20,147)) if envelope.get("type") == "Polygon": # parse coordinates coords = envelope.get("coordinates")[0] poly_pts = [QgsPoint(round(i[0], 3), round(i[1], 3)) for i in coords] # add geometry to layer poly = QgsFeature() poly.setGeometry(QgsGeometry.fromPolygon([poly_pts])) md_lyr.dataProvider().addFeatures([poly]) md_lyr.updateExtents() elif envelope.get("type") == "MultiPolygon": coords = envelope.get("bbox") bbox = QgsRectangle(round(coords[0], 3), round(coords[1], 3), round(coords[2], 3), round(coords[3], 3),) poly = QgsFeature() poly.setGeometry(QgsGeometry.fromWkt(bbox.asWktPolygon())) md_lyr.dataProvider().addFeatures([poly]) md_lyr.updateExtents() elif envelope.get("type") == "Point": return md_lyr else: pass # method ending return md_lyr
def envelope2layer(self, envelope): """Transform metadata envelope into a QGIS layer.""" # layer md_lyr = QgsVectorLayer("Polygon?crs=epsg:4326", "Metadata envelope", "memory") md_lyr.setLayerTransparency(75) if envelope.get("type") == "Polygon": # parse coordinates coords = envelope.get("coordinates")[0] poly_pts = [ QgsPoint(round(i[0], 3), round(i[1], 3)) for i in coords ] # add geometry to layer poly = QgsFeature() poly.setGeometry(QgsGeometry.fromPolygon([poly_pts])) md_lyr.dataProvider().addFeatures([poly]) md_lyr.updateExtents() elif envelope.get("type") == "MultiPolygon": coords = envelope.get("bbox") bbox = QgsRectangle( round(coords[0], 3), round(coords[1], 3), round(coords[2], 3), round(coords[3], 3), ) poly = QgsFeature() poly.setGeometry(QgsGeometry.fromWkt(bbox.asWktPolygon())) md_lyr.dataProvider().addFeatures([poly]) md_lyr.updateExtents() elif envelope.get("type") == "Point": return md_lyr else: pass # method ending return md_lyr
def processAlgorithm(self, parameters, context, feedback): feedback.setProgress(0) filenames = self.parameterAsString(parameters, self.INPUT, context) dbindex = self.parameterAsEnum(parameters, self.OUTPUT_BASE, context) db = self.pgpointcloudDatabases()[dbindex] table = self.parameterAsString(parameters, self.OUTPUT_TABLE, context) crs = QgsCoordinateReferenceSystem.fromEpsgId(4326) fields = QgsFields() fields.append(QgsField("filename", QVariant.String)) fields.append(QgsField("db", QVariant.String)) fields.append(QgsField("table", QVariant.String)) fields.append(QgsField("points", QVariant.Int)) outputWkb = QgsWkbTypes.Polygon (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LAYER, context, fields, outputWkb, crs) total = 100 / len(filenames.split(";")) count = 0 for filename in filenames.split(";"): if feedback.isCanceled(): break feedback.setProgress(count * total) count += 1 QgsMessageLog.logMessage("FILENAME:::::::") QgsMessageLog.logMessage(filename) pipejson = """ {{ \"pipeline\":[ \"{}\" ] }} """.format(filename) pipeline = pdal.Pipeline(pipejson) pipeline.validate() pipeline.loglevel = 4 pipeline.execute() meta = json.loads(pipeline.get_metadata()) minx = meta["metadata"]["readers.las"][0]['minx'] maxx = meta["metadata"]["readers.las"][0]['maxx'] miny = meta["metadata"]["readers.las"][0]['miny'] maxy = meta["metadata"]["readers.las"][0]['maxy'] count = meta["metadata"]["readers.las"][0]['count'] extent = QgsRectangle(minx, miny, maxx, maxy) wkt = extent.asWktPolygon() geom = QgsGeometry().fromWkt(wkt) f = QgsFeature() f.setFields(QgsFields()) f.setGeometry(geom) f.setAttributes([filename, db, table, count]) sink.addFeature(f, QgsFeatureSink.FastInsert) #features = vlayer.getFeatures() #for current, inFeat in enumerate(features): # sink.addFeature(inFeat, QgsFeatureSink.FastInsert) return {self.OUTPUT_LAYER: dest_id}
def search(self): try: # Current service service = self.tab.tabText(self.tab.currentIndex()) # Params params = {'geometry': self.polygonInput.text()} # Set auth and add params according to service if service == 'BaseMap': # ! Auth self.bmSetAuth() # Set request attributes url = 'https://view.geoapi-airbusds.com/api/v1/images' auth = self.bmAuth headers = None # Update params params.update({ 'size': self.maxResultsInput.value(), 'insertdtstart': '1970-01-01T00:00:00', 'insertdtend': self.now() }) # Dates if self.bmFromCheck.isChecked(): params['insertdtstart'] = self.bmFromInput.dateTime( ).toString(Qt.ISODate) if self.bmToCheck.isChecked(): params['insertdtend'] = self.bmToInput.dateTime().toString( Qt.ISODate) else: # ! Auth self.dtSetAuth() url = 'https://search.oneatlas.geoapi-airbusds.com/api/v1/opensearch' auth = None headers = self.dtHeaders # Constellations (at least one) constellations = [] if self.dtSpotCheck.isChecked(): constellations.append('SPOT') if self.dtPleiadesCheck.isChecked(): constellations.append('PHR') # Dates # MAYBE remove hours from dates dateFrom, dateTo = '1970-01-01T00:00:00', self.now() if self.dtFromCheck.isChecked(): dateFrom = self.dtFromInput.dateTime().toString(Qt.ISODate) if self.dtToCheck.isChecked(): dateTo = self.dtToInput.dateTime().toString(Qt.ISODate) # Angles angleMin, angleMax = 0, 30 if self.dtAngleMinCheck.isChecked(): angleMin = self.dtAngleMinInput.value() if self.dtAngleMaxCheck.isChecked(): angleMax = self.dtAngleMaxInput.value() # Covers (directlly update params) if self.dtCloudCheck.isChecked(): params['cloudCover'] = f'[0,{self.dtCloudInput.value()}]' if self.dtSnowCheck.isChecked(): params['snowCover'] = f'[0,{self.dtSnowInput.value()}]' # Workspaces (at leat one) workspaces = [] if self.dtPublicCheck.isChecked(): workspaces.append('0e33eb50-3404-48ad-b835-b0b4b72a5625') if self.dtPrivateCheck.isChecked(): workspaces.append(self.dtWorkspaceId) # Update all params with right format params.update({ 'itemsPerPage': self.maxResultsInput.value(), 'constellation': ','.join(constellations), 'acquisitionDate': f'[{dateFrom},{dateTo}]', 'incidenceAngle': f'[{angleMin},{angleMax}]', 'workspace': ','.join(workspaces) }) # Finally do the api call t = datetime.datetime.now() print(f'START {service} search') r = self.session.get(url, auth=auth, headers=headers, params=params) rSearch = r.json() # Exception request error if r.status_code != 200: self.error( f'{service} search error {r.status_code}\n{rSearch["message"]}' ) return # Create the search result layer with fields according to current service layer = QgsVectorLayer( f'Polygon?crs=epsg:4326&index=yes&{FIELDS[service]}', providerLib='memory', baseName=f'{service} search results') # Extract features features = [] self.errorFeatures = [] for rFeature in rSearch['features']: # Add a feature of the bbox on the new layer feature = QgsFeature(layer.fields()) # Try to get each attributes feature['service'] = service feature['constellation'] = self.getPropertie( rFeature, 'constellation') feature['incidenceAngle'] = self.getPropertie( rFeature, 'incidenceAngle') feature['cloudCover'] = self.getPropertie( rFeature, 'cloudCover') if service == 'BaseMap': feature['id'] = rFeature['id'] feature['insertionDate'] = self.getPropertie( rFeature, 'insertionDate') feature['wmts'] = self.getPropertie(rFeature, 'wmts') # Bbox fBbox = rFeature['properties']['bbox'] rectangle = QgsRectangle(fBbox[0], fBbox[1], fBbox[2], fBbox[3]) else: feature['id'] = self.getPropertie(rFeature, 'id') feature['acquisitionDate'] = self.getPropertie( rFeature, 'acquisitionDate') feature['snowCover'] = self.getPropertie( rFeature, 'snowCover') try: for json in rFeature['_links']['imagesWmts']: feature[f'wmts_{json["name"]}'] = json['href'] for json in rFeature['_links']['imagesWcs']: if 'buffer' in rFeature['rights']: feature[f'wcs_{json["name"]}'] = json['href'] else: feature[f'wcs_{json["name"]}'] = None except Exception as e: print( f'ERROR * eF = qgis.utils.plugins["OneAtlas"].mySearch.errorFeatures[{len(self.errorFeatures)}]' ) print(str(e)) self.errorFeatures.append(rFeature) continue # Bbox coordinates = rFeature['geometry']['coordinates'][0] rectangle = QgsRectangle(coordinates[0][0], coordinates[0][1], coordinates[2][0], coordinates[2][1]) # Add geometry from rectangle feature.setGeometry( QgsGeometry.fromWkt(rectangle.asWktPolygon())) # Add feature to list features.append(feature) # Total if service == 'BaseMap': # Note : rSearch['totalResults'] is maybe the number of total element in bbox ? # and numberOfElements is the true total result total = rSearch['numberOfElements'] color = QColor.fromRgb(0, 250, 0) else: total = rSearch['totalResults'] color = QColor.fromRgb(0, 250, 250) if len(self.errorFeatures) > 0: total -= len(self.errorFeatures) print(f'* {len(self.errorFeatures)} error feature') # Notification for number of total results msgBox = QMessageBox() msgBox.setWindowTitle(WINDOW_TITLE) msgBox.setText(f'There are {total} results') if total > len(features): msgBox.setIcon(QMessageBox.Warning) msgBox.setInformativeText( f'The maximum is configured to {self.maxResultsInput.value()}\nPlease refine your criteria or your AOI' ) msgBox.setStandardButtons(QMessageBox.Retry | QMessageBox.Ignore) msgBox.setDefaultButton(QMessageBox.Retry) else: msgBox.setIcon(QMessageBox.Information) msgBox.setStandardButtons(QMessageBox.Retry | QMessageBox.Ok) msgBox.setDefaultButton(QMessageBox.Ok) msgBox.button(QMessageBox.Retry).setText('Refine') msgBox.button(QMessageBox.Retry).setIcon( QIcon(os.path.dirname(__file__) + f'/search.png')) reply = msgBox.exec_() if reply == QMessageBox.Retry or len(features) == 0: return # Add result feature to the new layer (res, outFeats) = layer.dataProvider().addFeatures(features) # Change layer syle programmatically # Note : if we styling before save and add layer, we avoid to update legend style # => self.iface.layerTreeView().refreshLayerSymbology(vlayer.id()) symbol = layer.renderer().symbol() symbol.setOpacity(0.2) symbol.setColor(color) QgsProject.instance().addMapLayer(layer) # And refresh view layer.triggerRepaint() self.close() except: return
def processAlgorithm(self, parameters, context, feedback): feedback.setProgress(0) filenames = self.parameterAsString(parameters, self.INPUT, context) dbindex = self.parameterAsEnum(parameters, self.OUTPUT_BASE, context) db = self.pgpointcloudDatabases()[dbindex] uri = self.uri(db) table = self.parameterAsString(parameters, self.OUTPUT_TABLE, context) sink = None dest_id = None total = 100 / len(filenames.split(";")) count = 0 for filename in filenames.split(";"): if feedback.isCanceled(): break feedback.setProgress( count * total ) count += 1 QgsMessageLog.logMessage("FILENAME:::::::") QgsMessageLog.logMessage(filename) pipejson = """ {{ \"pipeline\":[ {{ \"type\":\"readers.las\", \"filename\": \"{}\" }}, {{ \"type\":\"filters.chipper\", \"capacity\":400 }}, {{ \"type\":\"writers.pgpointcloud\", \"connection\":\"host={} port={} dbname={} user={} password={}\", \"table\":\"{}\", \"compression\":\"las\", \"overwrite\":\"true\" }} ] }} """.format(filename, uri.host(), uri.port(), uri.database(), uri.username(),uri.password(), table) pipeline = pdal.Pipeline(pipejson) pipeline.validate() pipeline.loglevel = 4 pipeline.execute() meta = json.loads(pipeline.get_metadata()) minx = meta["metadata"]["readers.las"][0]['minx'] maxx = meta["metadata"]["readers.las"][0]['maxx'] miny = meta["metadata"]["readers.las"][0]['miny'] maxy = meta["metadata"]["readers.las"][0]['maxy'] if not sink: uri.setDataSource("public", table, "pa", "", "id") vlayer = QgsVectorLayer(uri.uri(), table, "postgres") fields = QgsFields() outputWkb = QgsWkbTypes.Polygon (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LAYER, context, fields, outputWkb, vlayer.crs() ) extent = QgsRectangle(minx, miny, maxx, maxy) wkt = extent.asWktPolygon() geom = QgsGeometry().fromWkt( wkt ) f = QgsFeature() f.setFields( QgsFields() ) f.setGeometry( geom ) sink.addFeature( f, QgsFeatureSink.FastInsert ) #features = vlayer.getFeatures() #for current, inFeat in enumerate(features): # sink.addFeature(inFeat, QgsFeatureSink.FastInsert) return {self.OUTPUT_LAYER: dest_id}