206 lines
9.4 KiB
Python

# Import basic libs
import json
import time
# Import PyQt libs
from qgis.PyQt.QtCore import QObject, pyqtSignal, QUrl, Qt, QVariant
from qgis.PyQt.QtGui import QColor
from qgis.PyQt.QtNetwork import QNetworkRequest, QNetworkReply
from qgis.PyQt.QtWidgets import QDialog, QPushButton, QApplication, QVBoxLayout, QHBoxLayout, QButtonGroup, QCheckBox, QLabel
# Import PyQgis libs
from qgis.utils import iface
from qgis.core import QgsProject, QgsFeature, QgsDataSourceUri, QgsRectangle, QgsNetworkAccessManager, QgsVectorLayer, QgsPointXY, QgsWkbTypes, QgsMapLayerProxyModel, QgsGeometry, QgsCoordinateReferenceSystem, QgsCoordinateTransform, QgsField
from qgis.gui import QgsMapTool, QgsMapMouseEvent, QgsRubberBand, QgsMapLayerComboBox
class GetTaxrefId(QObject):
finished_dl = pyqtSignal()
"""Get multiples informations from a getcapabilities request.
List all layers available, get the maximal extent of all the Wfs' data."""
def __init__(self, network_manager=None, project=None, layer=None, field_name=None, field_rank=None):
super().__init__()
self.network_manager = network_manager
self.project = project
self.layer = layer
self.field_name = field_name
self.field_rank = field_rank
self._pending_downloads = 0
self.ids = []
self.names = []
self.rank = []
for obs in self.layer.getFeatures():
self.ids.append(obs.id())
self.names.append(obs[self.field_name])
self.rank.append(obs[self.field_rank])
self._pending_downloads = len(self.names)
self._iterate_names = 0
self.download(self.ids[self._iterate_names], self.names[self._iterate_names], self.rank[self._iterate_names])
@property
def pending_downloads(self):
return self._pending_downloads
@property
def iterate_names(self):
return self._iterate_names
def download(self, feature_id, nom, rank):
if rank.lower() == 'stateofmatter':
self._iterate_names += 1
self.download(self.ids[self._iterate_names], self.names[self._iterate_names], self.rank[self._iterate_names])
else:
if rank.lower() == 'complex' or rank.lower() == 'hybrid':
rank = 'species'
elif rank.lower() == 'epifamily' or rank.lower() == 'section':
rank = 'genus'
elif rank.lower() == 'subtribe':
rank = 'subfamily'
url = "https://api.checklistbank.org/nameusage/search?content=SCIENTIFIC_NAME&datasetKey=2008&facet=datasetKey&facet=rank&facet=issue&facet=status&facet=nomStatus&facet=nameType&facet=field&facet=authorship&facet=authorshipYear&facet=extinct&facet=environment&facet=origin&limit=50&offset=0&q={nom}&rank={rank}&type=PREFIX".format(nom=nom.split("(")[0], rank=rank.lower())
print(url)
request = QNetworkRequest(QUrl(url))
request.setHeader(QNetworkRequest.KnownHeaders(0), "application/json")
reply = self.network_manager.get(request)
reply.finished.connect(lambda: self.handle_finished(reply, feature_id))
self._iterate_names += 1
def handle_finished(self, reply, feature_id):
self._pending_downloads -= 1
if reply.error() != QNetworkReply.NetworkError(0):
print(f"code: {reply.error()} message: {reply.errorString()}")
if reply.error() == 403:
print("Service down")
else:
data_request = reply.readAll().data().decode()
if data_request != "":
res = json.loads(data_request)
if "result" in res:
taxref_id = res["result"][0]["id"]
taxref_name = res["result"][0]["usage"]["label"]
self.layer.startEditing()
self.layer.changeAttributeValue(feature_id, self.layer.fields().indexFromName("cd_nom"), taxref_id)
self.layer.changeAttributeValue(feature_id, self.layer.fields().indexFromName("nom_scien"), taxref_name)
self.layer.commitChanges()
self.layer.triggerRepaint()
if self.pending_downloads == 0:
self.project.addMapLayer(self.layer)
self.finished_dl.emit()
else:
self.download(self.ids[self._iterate_names], self.names[self._iterate_names], self.rank[self._iterate_names])
class ImportDataGbif(QObject):
finished_dl = pyqtSignal()
"""Get multiples informations from a getcapabilities request.
List all layers available, get the maximal extent of all the Wfs' data."""
def __init__(self, network_manager=None, project=None, geom=None, ):
super().__init__()
self._pending_downloads = 0
self._pending_pages = 1
self.network_manager = network_manager
self.project = project
self.layer = self.new_layer()
self.geom = geom
self.new_features = []
self.max_obs = 0
self.total_pages = 0
self.download()
@property
def pending_downloads(self):
return self._pending_downloads
@property
def pending_pages(self):
return self._pending_pages
def new_layer(self):
geom_type = "Point"
new_layer = QgsVectorLayer(geom_type + "?crs=epsg:4326", "GBIF", "memory")
new_layer.startEditing()
new_layer.addAttribute(QgsField("id", QVariant.String, "string", 254))
new_layer.addAttribute(QgsField("cd_nom", QVariant.Int, "integer", 10))
new_layer.addAttribute(QgsField("niveau", QVariant.String, "string", 254))
new_layer.addAttribute(QgsField("nom", QVariant.String, "string", 254))
new_layer.addAttribute(QgsField("nom_scien", QVariant.String, "string", 100000))
new_layer.addAttribute(QgsField("observat", QVariant.String, "string", 254))
new_layer.addAttribute(QgsField("date", QVariant.String, "string", 254))
new_layer.addAttribute(QgsField("projet", QVariant.String, "string", 254))
new_layer.addAttribute(QgsField("effectif", QVariant.Int, "integer", 10))
new_layer.addAttribute(QgsField("url", QVariant.String, "string", 254))
new_layer.commitChanges()
new_layer.triggerRepaint()
return new_layer
def download(self):
url = "https://api.gbif.org/v1/occurrence/search?advanced=false&geometry={polygon}&offset={offset}&limit=1000".format(
offset=self.pending_pages, polygon=self.geom.asWkt())
url = QUrl(url)
self.nb_request = 1
print(url)
request = QNetworkRequest(url)
request.setHeader(QNetworkRequest.KnownHeaders(0), "application/json")
reply = self.network_manager.get(request)
reply.finished.connect(lambda: self.handle_finished(reply))
self._pending_downloads += 1
def handle_finished(self, reply):
self._pending_downloads -= 1
if reply.error() != QNetworkReply.NetworkError(0):
print(f"code: {reply.error()} message: {reply.errorString()}")
if reply.error() == 403:
print("Service down")
else:
data_request = reply.readAll().data().decode()
if self.pending_downloads == 0:
res = json.loads(data_request)
self.max_obs = res["count"]
self.total_pages = int(self.max_obs/20) + 1
for obs in res["results"]:
new_geom = QgsGeometry.fromPointXY(QgsPointXY(obs["decimalLongitude"], obs["decimalLatitude"]))
new_feature = QgsFeature(self.layer.fields())
new_feature.setGeometry(new_geom)
new_feature.setAttribute(0, str(obs["key"]))
new_feature.setAttribute(1, 0)
new_feature.setAttribute(2, obs["taxonRank"])
if obs["taxonRank"].lower() in ['kingdom', 'phylum', 'order', 'family', 'genus', 'species']:
new_feature.setAttribute(3, obs[obs["taxonRank"].lower()])
else:
new_feature.setAttribute(3, obs["scientificName"])
new_feature.setAttribute(4, "")
new_feature.setAttribute(5, "")
new_feature.setAttribute(6, str(obs["eventDate"]))
# new_feature.setAttribute(7, obs["_datasetKey"]["title"])
new_feature.setAttribute(7, obs["datasetName"] if "datasetName" in obs.keys() else None )
new_feature.setAttribute(8, 1)
new_feature.setAttribute(9, "https://www.gbif.org/fr/occurrence/" + str(obs["key"]))
self.new_features.append(new_feature)
if self.nb_request == 10:
time.sleep(10)
if self.pending_pages < self.total_pages:
self._pending_pages += 300
self.nb_request += 1
self.download()
else:
# Add the new feature to the temporary layer
self.layer.startEditing()
self.layer.dataProvider().addFeatures(self.new_features)
self.layer.updateExtents()
self.layer.commitChanges()
self.layer.triggerRepaint()
GetTaxrefId(self.network_manager, self.project, self.layer, "nom", "niveau")
self.finished_dl.emit()