def prepare_url(self): """Prepare a query to be as an URL. if the query is not ready to be URL prepared, a None is returned. :return: The URL encoded with the query. :rtype: basestring """ if not self._query_is_ready: return None if self._output_format: query = re.sub( r'output="[a-z]*"', 'output="%s"' % self._output_format, self._query_prepared) query = re.sub( r'\[out:[a-z]*', '[out:%s' % self._output_format, query) else: query = self._query_prepared url_query = QUrl(self._overpass) query_string = QUrlQuery() query_string.addQueryItem('data', query) query_string.addQueryItem('info', 'QgisQuickOSMPlugin') url_query.setQuery(query_string) return url_query.toString()
class MyUrl: def __init__(self, url): self.url = url self.query = QUrlQuery() @classmethod def fromLocalFile(cls, filename): return cls(QUrl.fromLocalFile(filename)) def addQueryItem(self, k, v): self.query.addQueryItem(k, v) def toString(self): urlstr = self.url.toString() querystr = self.query.toString(QUrl.FullyDecoded) if querystr != "": urlstr += "?" urlstr += querystr return urlstr
class MyUrl: def __init__(self, url): self.url = url self.query = QUrlQuery() @classmethod def fromLocalFile(cls, filename): return cls(QUrl.fromLocalFile(filename)) def addQueryItem(self, k, v): self.query.addQueryItem(k, v) def toString(self): urlstr = self.url.toString() querystr = self.query.toString(QUrl.FullyDecoded) if querystr != '': urlstr += '?' urlstr += querystr return urlstr
def do_request(self, point: QgsPointXY) -> None: query = QUrlQuery() query.addQueryItem("lat", str(point.y())) query.addQueryItem("lon", str(point.x())) query.addQueryItem("format", "json") url = QUrl(self.URL) url.setQuery(query) request = QNetworkRequest(url) request.setHeader(QNetworkRequest.UserAgentHeader, "*****@*****.**") response = self.nam.blockingGet(request) self._status_code = response.attribute( QNetworkRequest.HttpStatusCodeAttribute) self._content = json.loads(bytes(response.content())) if self._content.get("error"): self._error_string = self._content["error"] return
def get(self, url: str, params: dict = None, timeout: int = 20000, **kwargs) -> Reply: ''' queries given url (GET) Parameters ---------- url : str the url to request params : dict, optional query parameters with the parameters as keys and the values as values, defaults to no query parameters timeout : int, optional the timeout of synchronous requests in milliseconds, will be ignored when making asynchronous requests, defaults to 20000 ms **kwargs : additional parameters matching the requests interface will be ignored (e.g. verify is not supported) Returns ---------- Reply the response is returned in case of synchronous calls, if you are using asynchronous calls retrieve the response via the finished- signal instead ''' qurl = QUrl(url) if params: query = QUrlQuery() for param, value in params.items(): query.addQueryItem(param, str(value)) qurl.setQuery(query.query()) if self.synchronous: return self._get_sync(qurl, timeout=timeout) return self._get_async(qurl)
def query(self, query): """ Perform a nominatim query @param query: Query to execute @type query: str @raise NetWorkErrorException @return: the result of the query @rtype: str """ url_query = QUrl(self.__url) # query = QUrl.toPercentEncoding(query) query_string = QUrlQuery() query_string.addQueryItem('q', query) query_string.addQueryItem('format', 'json') query_string.addQueryItem('info', 'QgisQuickOSMPlugin') url_query.setQuery(query_string) request = QNetworkRequest(url_query) # request.setRawHeader("User-Agent", "QuickOSM") self.network_reply = self.network.get(request) self.loop = QEventLoop() self.network.finished.connect(self._end_of_request) self.loop.exec_() if self.network_reply.error() == QNetworkReply.NoError: return json.loads(self.data) else: raise NetWorkErrorException(suffix="Nominatim API")
def query(self, query: str) -> dict: """Perform a nominatim query. :param query: Query to execute on the nominatim server. :type query: basestring :return: The result of the query as a dictionary. :rtype: dict :raise NetWorkErrorException: """ query_string = QUrlQuery() query_string.addQueryItem('q', query) query_string.addQueryItem('format', 'json') query_string.addQueryItem('info', 'QgisQuickOSMPlugin') self._url.setQuery(query_string) self.download() with open(self.result_path, encoding='utf8') as json_file: data = json.load(json_file) if not data: raise NominatimBadRequest(query) return data
def query(self, query): """ Perform a nominatim query @param query: Query to execute @type query: str @raise NetWorkErrorException @return: the result of the query @rtype: str """ url_query = QUrl(self.__url) # query = QUrl.toPercentEncoding(query) query_string = QUrlQuery() query_string.addQueryItem('q', query) query_string.addQueryItem('format', 'json') query_string.addQueryItem('info', 'QgisQuickOSMPlugin') url_query.setQuery(query_string) request = QNetworkRequest(url_query) # request.setRawHeader("User-Agent", "QuickOSM") self.network_reply = self.network.get(request) self.loop = QEventLoop() self.network.finished.connect(self._end_of_request) self.loop.exec_() if self.network_reply.error() == QNetworkReply.NoError: return json.loads(self.data) else: raise NetWorkErrorException(suffix="Nominatim API")
def query(self, query): """Perform a nominatim query. :param query: Query to execute on the nominatim server. :type query: basestring :return: The result of the query as a dictionary. :rtype: dict :raise NetWorkErrorException """ url_query = QUrl(self.__url) query_string = QUrlQuery() query_string.addQueryItem('q', query) query_string.addQueryItem('format', 'json') query_string.addQueryItem('info', 'QgisQuickOSMPlugin') url_query.setQuery(query_string) loop = QEventLoop() downloader = QgsFileDownloader(url_query, self.result_path, delayStart=True) downloader.downloadExited.connect(loop.quit) downloader.downloadError.connect(self.error) downloader.downloadCanceled.connect(self.canceled) downloader.downloadCompleted.connect(self.completed) downloader.startDownload() loop.exec_() with open(self.result_path) as json_file: data = json.load(json_file) return data
def wfs(self): conn = QgsOwsConnection("wfs", self.connectionCombo.currentText()) uri = conn.uri().param('url') version = conn.uri().param('version') if version == "auto": # detect version u = QUrlQuery(uri) u.addQueryItem("request", "GetCapabilities") u.addQueryItem("acceptversions", "2.0.0,1.1.0,1.0.0") xml, ns_map = xml_parse(remote_open_from_qgis(u.query())) root = xml.getroot() versions = [ v.text for v in root.findall( "./ows:ServiceIdentification/ows:ServiceTypeVersion", ns_map) ] # take the greatest version, if more than one version = sorted(versions)[-1] with qgis_proxy_settings(): return WebFeatureService(url=uri, version=version)
def test_real_wrong_request(self): """Test wrong request. This is test is using internet. """ url = QUrl(OVERPASS_SERVERS[0]) query_string = QUrlQuery() query_string.addQueryItem('data', 'fake_query') url.setQuery(query_string) overpass = ConnexionOAPI(url.toString()) self.assertListEqual(overpass.errors, []) # We don't want the FileNotFoundError try: overpass.run() except OverpassBadRequestException: self.assertTrue(True) except FileNotFoundError: self.assertFalse(True) else: self.assertFalse(True) self.assertEqual(len(overpass.errors), 1)
def prepare_url(self): """Prepare a query to be as an URL. :return: The URL encoded with the query. :rtype: basestring """ if not self._query_prepared: return '' if self._output_format: query = re.sub(r'output="[a-z]*"', 'output="%s"' % self._output_format, self._query_prepared) query = re.sub(r'\[out:[a-z]*', '[out:%s' % self._output_format, query) else: query = self._query_prepared url_query = QUrl(self._overpass) query_string = QUrlQuery() query_string.addQueryItem('data', query) query_string.addQueryItem('info', 'QgisQuickOSMPlugin') url_query.setQuery(query_string) return url_query.toString()
def _sendRequest(self, url, params, headers={}): if self.asynchonous: if self.reply is not None: self.reply.finished.disconnect(self.reply_finished) self.reply.abort() self.reply = None url = QUrl(url) urlQuery = QUrlQuery(url) for key, value in params.items(): urlQuery.addQueryItem(key, value) QgsLogger.debug('Request: {}'.format(url.toEncoded())) url.setQuery(urlQuery) request = QNetworkRequest(url) for key, value in headers.items(): request.setRawHeader(key, value) self.reply = QgsNetworkAccessManager.instance().get(request) else: url = url + '?' + urllib.parse.urlencode(params) response = urllib.request.urlopen(url) data = json.load(response) self.load_data(data)
def import_layer_from_csv(parent, csv_path, layer_name, iface, longitude_field='lon', latitude_field='lat', delimiter=',', quote='"', lines_to_skip_count=0, wkt_field=None, save_format=None, save_dest=None, zoom_to_layer=True, has_geom=True, subset=None, add_to_legend=True, add_on_top=False): if not lines_to_skip_count: lines_to_skip_count = count_heading_commented_lines(csv_path) url = QUrl.fromLocalFile(csv_path) url_query = QUrlQuery() url_query.addQueryItem('type', 'csv') if has_geom: if wkt_field is not None: url_query.addQueryItem('wktField', wkt_field) else: url_query.addQueryItem('xField', longitude_field) url_query.addQueryItem('yField', latitude_field) url_query.addQueryItem('spatialIndex', 'no') url_query.addQueryItem('crs', 'epsg:4326') url_query.addQueryItem('subsetIndex', 'no') url_query.addQueryItem('watchFile', 'no') url_query.addQueryItem('delimiter', delimiter) url_query.addQueryItem('quote', quote) url_query.addQueryItem('skipLines', str(lines_to_skip_count)) url_query.addQueryItem('trimFields', 'yes') if subset is not None: # NOTE: it loads all features and applies a filter in visualization url_query.addQueryItem('subset', subset) # i.e. '"fieldname" != 0' url.setQuery(url_query) layer_uri = url.toString() layer = QgsVectorLayer(layer_uri, layer_name, "delimitedtext") if save_format: if save_format == 'ESRI Shapefile': fmt = '.shp' fmt_text = 'Shapefiles (*.shp)' elif save_format == 'GPKG': fmt = '.gpkg' fmt_text = 'Geopackages (*.gpkg)' else: raise NotImplementedError( 'Only shapefiles and geopackages are supported. Got %s' % save_format) dest_filename = save_dest if not dest_filename: dest_filename, file_filter = QFileDialog.getSaveFileName( parent, 'Save as...', os.path.expanduser("~"), fmt_text) if dest_filename: if os.path.splitext(dest_filename)[1] != fmt: dest_filename += fmt else: return writer_error, error_msg = save_layer_as( layer, dest_filename, save_format) if writer_error: raise RuntimeError( 'Could not save layer. %s: %s' % (writer_error, error_msg)) layer = QgsVectorLayer(dest_filename, layer_name, 'ogr') if layer.isValid(): if add_to_legend: if add_on_top: root = QgsProject.instance().layerTreeRoot() QgsProject.instance().addMapLayer(layer, False) root.insertLayer(0, layer) else: QgsProject.instance().addMapLayer(layer, True) iface.setActiveLayer(layer) if zoom_to_layer: iface.zoomToActiveLayer() else: raise RuntimeError('Unable to load layer') return layer
def query(self, *args: object, max_retries: int = 2, **kwargs: object ) -> Reply: ''' query the service Parameters ---------- *args query parameters without keyword **kwargs query parameters with keyword and value max_retries: int, optional maximum number of retries after connection error, defaults to 2 retries Returns ---------- Reply the reply of the geocoding API, contains a list of geojson features with "geometry" attribute of the matched address "properties" containing "text" (description of found address in BKG database), "typ", "treffer" and "score" (the higher the better the match) Raises ---------- RuntimeError critical error (no parameters, no access to service/url), it is recommended to abort geocoding ValueError request got through but parameters were malformed, may still work for different features ''' self.params = {} retries = 0 if self.rs: self.params['filter'] = f'rs:{self.rs}' self.params['srsname'] = self.crs query = self._build_params(*args, **kwargs) if not query: raise ValueError('keine Suchparameter gefunden') self.params['query'] = query do_post = self.area_wkt is not None if self.area_wkt: self.params['geometry'] = self.area_wkt while True: try: if not do_post: self.reply = requests.get(self.url, params=self.params) else: content_type = 'application/x-www-form-urlencoded' data = QUrlQuery() for k, v in self.params.items(): data.addQueryItem(k, v) self.reply = requests.post( self.url, data=data.query().encode('utf-8'), content_type=content_type ) except ConnectionError: if retries >= max_retries: raise RuntimeError( f'Anfrage nach {retries + 1} gescheiterten ' 'Verbindungsversuchen abgebrochen.') retries += 1 continue break self.raise_on_error(self.reply) return self.reply
def url(self): query = QUrlQuery() query.addQueryItem('application', CoopsApplicationName) query.addQueryItem('begin_date', self.startTime.toString('yyyyMMdd hh:mm')) query.addQueryItem('end_date', self.endTime.addSecs(-1).toString('yyyyMMdd hh:mm')) query.addQueryItem('units', 'english') query.addQueryItem('time_zone', 'gmt') query.addQueryItem('product', self.productName) query.addQueryItem('format', 'xml') self.addQueryItems(query) return self.baseUrl + '?' + query.query()
def result(self, result): # See if OK was pressed if result: project = QgsProject.instance() # First get all the values of the GUI items crs_input = self.dlg.crs_input.crs() crs_out = QgsCoordinateReferenceSystem( 'EPSG:4326') # we need this to be WGS84 for Nominatim lineedit_text = self.dlg.lineedit_xy.value() # Protect the free text field for coordinates from generic user failure try: lineedit_yx = [ float(coord.strip()) for coord in lineedit_text.split(',') ] except: QMessageBox.critical( self.iface.mainWindow(), 'QuickAPI error', "Did you really specify a coordinate in comma-separated Lat/Long?\nExiting..." ) return # Create a Point and transform if necessary point = QgsPointXY(*reversed(lineedit_yx)) if crs_input.authid() != 'EPSG:4326': xform = QgsCoordinateTransform(crs_input, crs_out, project) point_transform = xform.transform(point) point = point_transform # Set up the GET Request to Nominatim query = QUrlQuery() query.addQueryItem('lat', str(point.y())) query.addQueryItem('lon', str(point.x())) query.addQueryItem('format', 'json') url = QUrl('https://nominatim.openstreetmap.org/reverse') url.setQuery(query) request = QNetworkRequest(url) request.setHeader(QNetworkRequest.UserAgentHeader, '*****@*****.**') nam = QgsNetworkAccessManager() response: QgsNetworkReplyContent = nam.blockingGet(request) # Only process if HTTP status code is 200 status_code = response.attribute( QNetworkRequest.HttpStatusCodeAttribute) if status_code == 200: # Get the content of the response and process it response_json = json.loads(bytes(response.content())) if response_json.get('error'): QMessageBox.critical( self.iface.mainWindow(), "Quick API error", "The request was not processed succesfully!\n\n" "Message:\n" "{}".format(response_json['error'])) return x = float(response_json['lon']) y = float(response_json['lat']) address = response_json['display_name'] license = response_json['licence'] # Create the output memory layer layer_out = QgsVectorLayer( "Point?crs=EPSG:4326&field=address:string&field=license:string", "Nominatim Reverse Geocoding", "memory") # Create the output feature (only one here) point_out = QgsPointXY(x, y) feature = QgsFeature() feature.setGeometry(QgsGeometry.fromPointXY(point_out)) feature.setAttributes([address, license]) # Add feature to layer and layer to map layer_out.dataProvider().addFeature(feature) layer_out.updateExtents() project.addMapLayer(layer_out) # build bbox for auto-zoom feature bbox = [float(coord) for coord in response_json['boundingbox']] min_y, max_y, min_x, max_x = bbox bbox_geom = QgsGeometry.fromRect( QgsRectangle(min_x, min_y, max_x, max_y)) # Transform bbox if map canvas has a different CRS if project.crs().authid() != 'EPSG:4326': xform = QgsCoordinateTransform(crs_out, project.crs(), project) bbox_geom.transform(xform) self.iface.mapCanvas().zoomToFeatureExtent( QgsRectangle.fromWkt(bbox_geom.asWkt()))