def testStringToFeatureList(self): """Test converting json string to features""" fields = QgsFields() fields.append(QgsField("name", QVariant.String)) # empty string features = QgsJSONUtils.stringToFeatureList("", fields, codec) self.assertEqual(features, []) # bad string features = QgsJSONUtils.stringToFeatureList("asdasdas", fields, codec) self.assertEqual(features, []) # geojson string with 1 feature features = QgsJSONUtils.stringToFeatureList( '{\n"type": "Feature","geometry": {"type": "Point","coordinates": [125, 10]},"properties": {"name": "Dinagat Islands"}}', fields, codec, ) self.assertEqual(len(features), 1) self.assertFalse(features[0].geometry().isEmpty()) self.assertEqual(features[0].geometry().wkbType(), QgsWkbTypes.Point) point = features[0].geometry().geometry() self.assertEqual(point.x(), 125.0) self.assertEqual(point.y(), 10.0) self.assertEqual(features[0]["name"], "Dinagat Islands") # geojson string with 2 features features = QgsJSONUtils.stringToFeatureList( '{ "type": "FeatureCollection","features":[{\n"type": "Feature","geometry": {"type": "Point","coordinates": [125, 10]},"properties": {"name": "Dinagat Islands"}}, {\n"type": "Feature","geometry": {"type": "Point","coordinates": [110, 20]},"properties": {"name": "Henry Gale Island"}}]}', fields, codec, ) self.assertEqual(len(features), 2) self.assertFalse(features[0].geometry().isEmpty()) self.assertEqual(features[0].geometry().wkbType(), QgsWkbTypes.Point) point = features[0].geometry().geometry() self.assertEqual(point.x(), 125.0) self.assertEqual(point.y(), 10.0) self.assertEqual(features[0]["name"], "Dinagat Islands") self.assertFalse(features[1].geometry().isEmpty()) self.assertEqual(features[1].geometry().wkbType(), QgsWkbTypes.Point) point = features[1].geometry().geometry() self.assertEqual(point.x(), 110.0) self.assertEqual(point.y(), 20.0) self.assertEqual(features[1]["name"], "Henry Gale Island")
for f in fields_list: fields.append(f) feature = QgsFeature(fields) feature.setGeometry(QgsGeometry.fromPoint(QgsPoint(60, 5))) feature.setAttributes(["George", 34, 1.69]) # Exports all attributes from a QgsFeature as a JSON map type. with codecs.open('feature.json', 'wb', encoding='utf-8') as f: json_text = QgsJSONUtils.exportAttributes(feature) f.write(json_text) # Attempts to retrieve the fields from a GeoJSON string representing a # collection of features. fields = QgsJSONUtils.stringToFields( geojson_contributors_string, QTextCodec.codecForName('UTF-8') ) for f in fields: print(f.name(), f.type()) # Attempts to parse a GeoJSON string to a collection of features. features = QgsJSONUtils.stringToFeatureList( geojson_contributors_string, fields, QTextCodec.codecForName('UTF-8') ) print(features)
def btn_calculate(self): if self.area_admin.isChecked(): if not self.area_admin_0.currentText(): QtGui.QMessageBox.critical( None, self.tr("Error"), self.tr("Choose a first level administrative boundary."), None) return False self.button_calculate.setEnabled(False) geojson = self.load_admin_polys() self.button_calculate.setEnabled(True) if not geojson: QtGui.QMessageBox.critical( None, self.tr("Error"), self.tr("Unable to load administrative boundaries."), None) return False else: if not self.area_fromfile_file.text(): QtGui.QMessageBox.critical( None, self.tr("Error"), self.tr("Choose a file to define the area of interest."), None) return False layer = QgsVectorLayer(self.area_fromfile_file.text(), 'calculation boundary', 'ogr') if not layer.isValid(): QtGui.QMessageBox.critical( None, self.tr("Error"), self.tr("Unable to read area file."), None) return False log('Loaded layer: {}'.format( layer.dataProvider().dataSourceUri())) #TODO: Fix this kludge for f in layer.getFeatures(): aoi = f.geometry() break crs_source = layer.crs() crs_dest = QgsCoordinateReferenceSystem(4326) aoi.transform(QgsCoordinateTransform(crs_source, crs_dest)) geojson = json.loads(aoi.exportToGeoJSON()) # Calculate bounding box of input polygon and then convert back to # geojson fields = QgsJSONUtils.stringToFields(json.dumps(geojson), QTextCodec.codecForName('UTF8')) features = QgsJSONUtils.stringToFeatureList( json.dumps(geojson), fields, QTextCodec.codecForName('UTF8')) if len(features) > 1: log("Found {} features in geojson - using first feature only.". format(len(features))) # Make a copy of this geometry self.aoi = QgsGeometry(features[0].geometry()) self.bbox = json.loads( QgsGeometry.fromRect(self.aoi.boundingBox()).exportToGeoJSON()) return True
def testStringToFeatureList(self): """Test converting json string to features""" fields = QgsFields() fields.append(QgsField("name", QVariant.String)) # empty string features = QgsJSONUtils.stringToFeatureList("", fields, codec) self.assertEqual(features, []) # bad string features = QgsJSONUtils.stringToFeatureList("asdasdas", fields, codec) self.assertEqual(features, []) # geojson string with 1 feature features = QgsJSONUtils.stringToFeatureList( '{\n"type": "Feature","geometry": {"type": "Point","coordinates": [125, 10]},"properties": {"name": "Dinagat Islands"}}', fields, codec) self.assertEqual(len(features), 1) self.assertFalse(features[0].geometry().isNull()) self.assertEqual(features[0].geometry().wkbType(), QgsWkbTypes.Point) point = features[0].geometry().geometry() self.assertEqual(point.x(), 125.0) self.assertEqual(point.y(), 10.0) self.assertEqual(features[0]['name'], "Dinagat Islands") # geojson string with 2 features features = QgsJSONUtils.stringToFeatureList( '{ "type": "FeatureCollection","features":[{\n"type": "Feature","geometry": {"type": "Point","coordinates": [125, 10]},"properties": {"name": "Dinagat Islands"}}, {\n"type": "Feature","geometry": {"type": "Point","coordinates": [110, 20]},"properties": {"name": "Henry Gale Island"}}]}', fields, codec) self.assertEqual(len(features), 2) self.assertFalse(features[0].geometry().isNull()) self.assertEqual(features[0].geometry().wkbType(), QgsWkbTypes.Point) point = features[0].geometry().geometry() self.assertEqual(point.x(), 125.0) self.assertEqual(point.y(), 10.0) self.assertEqual(features[0]['name'], "Dinagat Islands") self.assertFalse(features[1].geometry().isNull()) self.assertEqual(features[1].geometry().wkbType(), QgsWkbTypes.Point) point = features[1].geometry().geometry() self.assertEqual(point.x(), 110.0) self.assertEqual(point.y(), 20.0) self.assertEqual(features[1]['name'], "Henry Gale Island")
def btn_calculate(self): if self.area_admin.isChecked(): if not self.area_admin_0.currentText(): QtGui.QMessageBox.critical(None, self.tr("Error"), self.tr("Choose a first level administrative boundary."), None) return False self.button_calculate.setEnabled(False) geojson = self.load_admin_polys() self.button_calculate.setEnabled(True) if not geojson: QtGui.QMessageBox.critical(None, self.tr("Error"), self.tr("Unable to load administrative boundaries."), None) return False elif self.area_fromfile.isChecked(): if not self.area_fromfile_file.text(): QtGui.QMessageBox.critical(None, self.tr("Error"), self.tr("Choose a file to define the area of interest."), None) return False layer = QgsVectorLayer(self.area_fromfile_file.text(), 'calculation boundary', 'ogr') crs_source = layer.crs() crs_dest = QgsCoordinateReferenceSystem(4326) extent = layer.extent() extent_transformed = QgsCoordinateTransform(crs_source, crs_dest).transform(extent) geojson = json.loads(QgsGeometry.fromRect(extent_transformed).exportToGeoJSON()) else: # Area from point if not self.point_x.text() and not self.point_y.text(): QtGui.QMessageBox.critical(None, self.tr("Error"), self.tr("Choose a point to define the area of interest."), None) return False point = QgsPoint(float(self.point_x.text()), float(self.point_y.text())) crs_source = QgsCoordinateReferenceSystem(self.canvas.mapRenderer().destinationCrs().authid()) crs_dest = QgsCoordinateReferenceSystem(4326) point = QgsCoordinateTransform(crs_source, crs_dest).transform(point) geojson = json.loads(QgsGeometry.fromPoint(point).exportToGeoJSON()) self.close() # Calculate bounding box of input polygon and then convert back to # geojson fields = QgsJSONUtils.stringToFields(json.dumps(geojson), QTextCodec.codecForName('UTF8')) features = QgsJSONUtils.stringToFeatureList(json.dumps(geojson), fields, QTextCodec.codecForName('UTF8')) if len(features) > 1: log("Found {} features in geojson - using first feature only.".format(len(features))) #self.bbox = json.loads(features[0].geometry().convexHull().exportToGeoJSON()) self.bbox = json.loads(QgsGeometry.fromRect(features[0].geometry().boundingBox()).exportToGeoJSON()) log("Calculating timeseries for: {}.".format(self.bbox)) ndvi_dataset = self.datasets['NDVI'][self.dataset_ndvi.currentText()]['GEE Dataset'] self.calculate_timeseries(self.bbox, ndvi_dataset)
def __init__(self, f=None, geojson=None, datatype='polygon'): """ Can initialize with either a file, or a geojson. Note datatype is ignored unless geojson is used. """ self.isValid = False if f and not geojson: l = QgsVectorLayer(f, "calculation boundary", "ogr") log("Geom type: {}, {}".format(l.geometryType(), QGis.Polygon)) if not l.isValid(): return if l.geometryType() == QGis.Polygon: datatype = "polygon" elif l.geometryType() == QGis.Point: datatype = "point" else: QtGui.QMessageBox.critical(None, tr("Error"), tr("Failed to process area of interest - unknown geometry type:{}".format(l.geometryType()))) log("Failed to process area of interest - unknown geometry type.") return elif not f and geojson: l = QgsVectorLayer("{}?crs=epsg:4326".format(datatype), "calculation boundary", "memory") fields = QgsJSONUtils.stringToFields(json.dumps(geojson), QTextCodec.codecForName('UTF8')) features = QgsJSONUtils.stringToFeatureList(json.dumps(geojson), fields, QTextCodec.codecForName('UTF8')) ret = l.dataProvider().addFeatures(features) l.commitChanges() if not ret: QtGui.QMessageBox.critical(None, tr("Error"), tr("Failed to add geojson to temporary layer.")) log("Failed to add geojson to temporary layer.") return l.commitChanges() else: raise ValueError("Must specify file or geojson") crs_source = l.crs() crs_dest = QgsCoordinateReferenceSystem(4326) t = QgsCoordinateTransform(crs_source, crs_dest) # Transform layer to WGS84 l_wgs84 = QgsVectorLayer("{}?crs=epsg:4326".format(datatype), "calculation boundary (wgs84)", "memory") #CRS transformation feats = [] for f in l.getFeatures(): g = f.geometry() g.transform(t) f.setGeometry(g) feats.append(f) l_wgs84.dataProvider().addFeatures(feats) l_wgs84.commitChanges() if not l_wgs84.isValid(): self.layer = None log("Error transforming AOI coordinates to WGS84") return else: self.layer = l_wgs84 # Transform bounding box to WGS84 self.bounding_box_geom = QgsGeometry.fromRect(l_wgs84.extent()) # Save a geometry of the bounding box self.bounding_box_geom.transform(t) # Also save a geojson of the bounding box (needed for shipping to GEE) self.bounding_box_geojson = json.loads(self.bounding_box_geom.exportToGeoJSON()) # Check the coordinates of the bounding box are now in WGS84 (in case # no transformation was available for the chosen coordinate systems) bbox = self.bounding_box_geom.boundingBox() log("Bounding box: {}, {}, {}, {}".format(bbox.xMaximum(), bbox.xMinimum(), bbox.yMinimum(), bbox.yMinimum())) if (bbox.xMinimum() < -180) or \ (bbox.xMaximum() > 180) or \ (bbox.yMinimum() < -90) or \ (bbox.yMinimum() > 90): QtGui.QMessageBox.critical(None, tr("Error"), tr("Coordinates of area of interest could not be transformed to WGS84. Check that the projection system is defined."), None) log("Error transforming AOI coordinates to WGS84") else: self.isValid = True