コード例 #1
0
ファイル: nominatim.py プロジェクト: Troctolite/QuickOSM
    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
コード例 #2
0
ファイル: query_preparation.py プロジェクト: 3liz/QuickOSM
    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()
コード例 #3
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")
コード例 #4
0
    def process_get_call(self,
                         url,
                         url_query_items,
                         timeout=None,
                         report_url=True):
        """
        Run a GET request and return reply data
        :param url: url for request
        :param url_query_items:
        :param timeout: in ms
        :param report_url: True if URL should be reported to feedback
        :return: response or error message in json format
        """

        url_query = QUrl(url)
        if report_url:
            self.report_info('GET ' + url_query.toString())

        if url_query_items:
            url_query.setQuery(url_query_items)

        request = QNetworkRequest(url_query)
        if self.connection.auth_cfg != '':
            request.setRawHeader("Accept".encode("utf-8"),
                                 "*/*".encode("utf-8"))
        if timeout is not None and "setTransferTimeout" in dir(request):
            request.setTransferTimeout(timeout)

        reply = self.network_access_manager.blockingGet(
            request, self.connection.auth_cfg, True, self.feedback)
        return self.process_qgs_reply(reply)
コード例 #5
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="{}"'.format(self._output_format),
                           self._query_prepared)
            query = re.sub(r'\[out:[a-z]*',
                           '[out:{}'.format(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()
コード例 #6
0
ファイル: nominatim.py プロジェクト: 3liz/QuickOSM
    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")
コード例 #7
0
ファイル: tools.py プロジェクト: kannes/Nominatim-Qgis-Plugin
def getHttp(uri, params):
    nam = QgsNetworkAccessManager.instance()
    QgsApplication.setOverrideCursor(Qt.WaitCursor)
    try:
        rq = QUrl(uri)
        q = QUrlQuery()
        for (k, v) in params.items():
            q.addQueryItem(k, v)

        rq.setQuery(q)
        req = QNetworkRequest(rq)
        try:
            reply = nam.blockingGet(req)
            resource = reply.content().data().decode("utf8")
            r = json.loads(resource)

            if isinstance(r, list):
                return r
            else:
                return [r]

        except Exception as e:
            for m in e.args:
                QgsMessageLog.logMessage(m, "Extensions")

    finally:
        QgsApplication.restoreOverrideCursor()

    return None
コード例 #8
0
 def url_with_param(url, params) -> str:
     url = QUrl(url)
     q = QUrlQuery(url)
     for key, value in params.items():
         q.addQueryItem(key, value)
     url.setQuery(q)
     return url
コード例 #9
0
    def wfs(self):
        name = self.connectionCombo.currentText()
        conn = QgsOwsConnection("wfs", name)
        uri = conn.uri().param('url')
        req_version = conn.uri().param('version')
        s = QgsSettings()
        checked_version = s.value(
            "qgis/connections-wfs/{}/checked_version".format(name), False)
        if req_version == "auto" or not checked_version:
            # detect version
            u = QUrlQuery()
            u.addQueryItem("request", "GetCapabilities")
            u.addQueryItem("service", "WFS")
            if req_version == "auto":
                u.addQueryItem("acceptversions", "2.0.0,1.1.0,1.0.0")
            elif not checked_version:
                u.addQueryItem("version", req_version)
            final_url = QUrl(uri)
            final_url.setQuery(u)

            xml, ns_map = xml_parse(remote_open_from_qgis(
                final_url.toString()))
            root = xml.getroot()
            if 'ows' in ns_map:
                versions = [
                    v.text for v in root.findall(
                        "./ows:ServiceIdentification/ows:ServiceTypeVersion",
                        ns_map)
                ]
            else:
                versions = [
                    v.text for v in root.findall(
                        "./ServiceIdentification/ServiceTypeVersion", ns_map)
                ]
            if not versions:
                if 'version' in root.attrib:
                    versions = [root.attrib['version']]
            if not versions:
                raise RuntimeError("Cannot determine WFS version")
            # take the greatest version, if more than one
            version = sorted(versions)[-1]

            if version != req_version:
                QgsMessageLog.logMessage(
                    "Requested WFS version {}, got {}".format(
                        req_version, version))
            else:
                s.setValue(
                    "qgis/connections-wfs/{}/checked_version".format(name),
                    True)
        else:
            version = req_version

        with qgis_proxy_settings():
            return WebFeatureService(url=uri, version=version)
コード例 #10
0
    def query(self, query):
        """
        Make a query to the overpass

        @param query:Query to execute
        @type query:str

        @raise OverpassBadRequestException,NetWorkErrorException,
        OverpassTimeoutException

        @return: the result of the query
        @rtype: str
        """

        url_query = QUrl(self.__url + 'interpreter')

        # The output format can be forced (JSON or XML)
        if self.__output:
            query = re.sub(r'output="[a-z]*"',
                           'output="' + self.__output + '"', query)
            query = re.sub(r'\[out:[a-z]*', '[out:' + self.__output, query)

        # noinspection PyCallByClass
        # encoded_query = QUrl.toPercentEncoding(query)
        query_string = QUrlQuery()
        query_string.addQueryItem('data', query)
        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:
            file_obj = codecs.open(self.result_path, 'r', 'utf-8')
            file_obj.seek(0, 2)
            fsize = file_obj.tell()
            file_obj.seek(max(fsize - 1024, 0), 0)
            lines = file_obj.readlines()

            lines = lines[-10:]  # Get last 10 lines
            timeout = '<remark> runtime error: Query timed out in "[a-z]+" ' \
                      'at line [\d]+ after ([\d]+) seconds. </remark>'
            if re.search(timeout, ''.join(lines)):
                raise OverpassTimeoutException
            else:
                return self.result_path

        elif self.network_reply.error() == QNetworkReply.UnknownContentError:
            raise OverpassBadRequestException
        else:
            raise NetWorkErrorException(suffix="Overpass OSM API")
コード例 #11
0
    def post(self,
             url,
             params: dict = None,
             data: bytes = b'',
             timeout: int = 20000,
             content_type: str = None,
             **kwargs) -> Reply:
        '''
        posts data to given url (POST)

        asynchronous posts are not implemented yet

        Parameters
        ----------
        url : str
            the url to post to
        params : dict, optional
            query parameters with the parameters as keys and the values as
            values, defaults to no query parameters
        data : bytes, optional
            the data to post as a byte-string, defaults to no data posted
        timeout : int, optional
            the timeout of synchronous requests in milliseconds, will be ignored
            when making asynchronous requests, defaults to 20000 ms
        content_type : str, optional
            the content type of the data, puts content type into header of
            request
        **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._post_sync(qurl,
                                   timeout=timeout,
                                   data=data,
                                   content_type=content_type)

        return self._post_async(qurl, content_type=content_type)
コード例 #12
0
def clean_ows_url(url):
    """clean an OWS URL of added basic service parameters"""

    url = QUrl(url)
    query_string = url.query()

    if query_string:
        query_string = QUrlQuery(query_string)
        query_string.removeQueryItem('service')
        query_string.removeQueryItem('SERVICE')
        query_string.removeQueryItem('request')
        query_string.removeQueryItem('REQUEST')
        url.setQuery(query_string)

    return url.toString()
コード例 #13
0
ファイル: util.py プロジェクト: cayetanobv/QGIS
def clean_ows_url(url):
    """clean an OWS URL of added basic service parameters"""

    url = QUrl(url)
    query_string = url.query()

    if query_string:
        query_string = QUrlQuery(query_string)
        query_string.removeQueryItem('service')
        query_string.removeQueryItem('SERVICE')
        query_string.removeQueryItem('request')
        query_string.removeQueryItem('REQUEST')
        url.setQuery(query_string)

    return url.toString()
コード例 #14
0
    def process_post_call(self,
                          url,
                          url_query_items,
                          data,
                          is_read_only=True,
                          report_url=True):
        """
        Run a POST request and return reply data
        :param url: url for request
        :param url_query_items:
        :param data:
        :param is_read_only: True if the request does not update data
        :param report_url: True if URL should be reported to feedback
        :return: response or error message in json format
        """

        if self.connection.read_only and not is_read_only:
            return {
                "error": {
                    "msg": "Graphium connection is set to read-only!"
                }
            }

        url_query = QUrl(url)
        if report_url:
            self.report_info('POST ' + url_query.toString())

        if url_query_items:
            url_query.setQuery(url_query_items)

        # data_byte_array = json.dumps(data).encode('utf8')
        # data = QtCore.QByteArray( json.dumps( json_request ) )
        data_byte_array = QJsonDocument.fromVariant(data)

        request = QNetworkRequest(url_query)
        if self.connection.auth_cfg != '':
            request.setRawHeader("Accept".encode("utf-8"),
                                 "*/*".encode("utf-8"))
        request.setHeader(QNetworkRequest.ContentTypeHeader,
                          "application/json")
        reply = self.network_access_manager.blockingPost(
            request, data_byte_array.toJson(), self.connection.auth_cfg, True,
            self.feedback)
        return self.process_qgs_reply(reply)
コード例 #15
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
コード例 #16
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)
コード例 #17
0
    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)
コード例 #18
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)
コード例 #19
0
ファイル: query_preparation.py プロジェクト: ghtmtt/QuickOSM
    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()
コード例 #20
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()))