forked from CEN38/plugin_gn_tools
206 lines
9.4 KiB
Python
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()
|