Example #1
0
    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()
Example #2
0
    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
Example #3
0
    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
Example #4
0
    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
Example #5
0
    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)
Example #6
0
    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")
Example #7
0
    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
Example #8
0
    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")
Example #9
0
    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
Example #10
0
    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)
Example #12
0
    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()
Example #13
0
    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)
Example #14
0
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
Example #15
0
    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()
Example #17
0
    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()))