Exemple #1
0
    def _reverse_geocode(self, point):
        """Performs reverse geocoding"""

        providers, provider_name, ok = self._get_provider_input()
        if ok:
            provider = [
                provider for provider in providers
                if provider['name'] == provider_name
            ][0]
            clnt = client.Client(provider)
            responsehandler = response_handler.ResponseHandler(
                QgsField('id', QVariant.String))
            try:
                response = clnt.request(provider['endpoints']['reverse'], {
                    'point.lat': point.y(),
                    'point.lon': point.x(),
                    'size': 5
                })
                layer_out = responsehandler.get_layer('reverse', response)
                layer_out.updateExtents()
                self.project.addMapLayer(layer_out)

            except:
                raise

            finally:
                QApplication.restoreOverrideCursor()
                self.point_tool.canvasClicked.disconnect()
                self.iface.mapCanvas().setMapTool(self.last_maptool)
Exemple #2
0
    def _forward_geocode(self):
        """Performs quick forward geocoding"""

        address, ok = QInputDialog.getText(self.iface.mainWindow(),
                                           "Pelias Forward Geocoding",
                                           "Enter an address")
        if not ok:
            return

        providers, provider_name, ok = self._get_provider_input()
        if ok:
            provider = [
                provider for provider in providers
                if provider['name'] == provider_name
            ][0]
            clnt = client.Client(provider)
            responsehandler = response_handler.ResponseHandler(
                QgsField('id', QVariant.String))
            response = clnt.request(provider['endpoints']['search'], {
                'text': address,
                'size': 5
            })
            layer_out = responsehandler.get_layer('search', response)
            layer_out.updateExtents()
            self.project.addMapLayer(layer_out)
Exemple #3
0
    def _run_main_dialog(self):
        """Runs the main function when Apply is clicked."""

        self.dlg.debug_text.clear()

        provider = self.dlg.provider_combo.currentData()
        clnt = client.Client(
            provider=provider)  # provider object has all data from config.yml
        clnt_msg = ''

        # Notify user when query limit is reached
        sleep_notifier = "OverQueryLimit: Wait for {} seconds"
        clnt.overQueryLimit.connect(
            lambda sleep_for: self.dlg.debug_text.setText(
                sleep_notifier.format(str(sleep_for))))

        # Collect base parameters common for both endpoints
        params = self._collect_base_params()

        if self.dlg.search_tab.currentIndex() == 0:
            method = 'search'
            params['text'] = self.dlg.search_free_text.value()

        elif self.dlg.search_tab.currentIndex() == 1:
            method = 'structured'
            layers_list = self.dlg.layer_list
            for idx in range(layers_list.count()):
                item = layers_list.item(idx).text()
                param, value = item.split("=")
                params[param] = value

        elif self.dlg.search_tab.currentIndex() == 2:
            method = 'reverse'
            params['point.lon'] = self.dlg.reverse_x.value()
            params['point.lat'] = self.dlg.reverse_y.value()

        responsehandler = response_handler.ResponseHandler(
            QgsField('id', QVariant.String), self.dlg.debug_check.isChecked())
        try:
            response = clnt.request(provider['endpoints'][method], params)
            layer_out = responsehandler.get_layer(method, response)
            layer_out.updateExtents()
            self.project.addMapLayer(layer_out)
        except exceptions.Timeout:
            msg = "The connection has timed out!"
            logger.log(msg, 2)
            self.dlg.debug_text.setText(msg)

        except (exceptions.ApiError, exceptions.InvalidKey,
                exceptions.GenericServerError) as e:

            msg = [e.__class__.__name__, str(e)]
            logger.log("{}: {}".format(*msg), 2)
            clnt_msg += "<b>{}</b>: ({})<br>".format(*msg)

        except Exception as e:
            msg = [e.__class__.__name__, str(e)]
            logger.log("{}: {}".format(*msg), 2)
            clnt_msg += "<b>{}</b>: {}<br>".format(*msg)
            raise

        finally:
            # Write some output
            if clnt.warnings is not None:
                for warning in clnt.warnings:
                    clnt_msg += "<b>Warning</b>: {}<br>".format(warning)
                    logger.log(warning, 1)

            clnt_msg += '<a href="{0}">{0}</a><br>'.format(clnt.url)
            self.dlg.debug_text.setHtml(clnt_msg)
Exemple #4
0
    def processAlgorithm(self, parameters, context, feedback):
        providers = configmanager.read_config()['providers']

        # Init client
        provider = providers[self.parameterAsEnum(parameters, self.IN_PROVIDER,
                                                  context)]
        in_source = self.parameterAsSource(parameters, self.IN_POINTS, context)
        in_id_field_name = self.parameterAsString(parameters, self.IN_ID_FIELD,
                                                  context)
        in_country = self.parameterAsString(parameters, self.IN_COUNTRY,
                                            context)
        in_layers = self.parameterAsEnums(parameters, self.IN_LAYERS, context)
        in_sources = self.parameterAsEnums(parameters, self.IN_SOURCES,
                                           context)
        in_size = self.parameterAsInt(parameters, self.IN_SIZE, context)

        # Get user specified ID field as object
        in_id_field = in_source.fields().field(in_id_field_name)

        clnt = client.Client(provider)
        clnt.overQueryLimit.connect(lambda sleep_for: feedback.reportError(
            "OverQueryLimit: Wait for {} seconds".format(sleep_for)))

        params = dict()

        if in_country:
            params['boundary.country'] = in_country
        if in_layers:
            params['layers'] = convert.comma_list(
                [LAYERS[idx] for idx in in_layers])
        if in_sources:
            params['sources'] = convert.comma_list(
                [SOURCES[idx] for idx in in_sources])
        params['size'] = str(in_size)

        responsehandler = response_handler.ResponseHandler(in_id_field)

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUT, context,
                                               responsehandler.get_fields(),
                                               QgsWkbTypes.Point, self.crs_out)

        xformer = transform.transformToWGS(in_source.sourceCrs())
        for num, feat_in in enumerate(in_source.getFeatures()):
            if feedback.isCanceled():
                break
            x_point = xformer.transform(feat_in.geometry().asPoint())
            params['point.lon'] = x_point.x()
            params['point.lat'] = x_point.y()

            in_id_field_value = feat_in[in_id_field_name]
            try:
                response = clnt.request(
                    provider['endpoints'][self.ALGO_NAME_LIST[1]], params)
            except (exceptions.ApiError, exceptions.GenericServerError,
                    exceptions.InvalidKey) as e:
                msg = "Feature ID {} caused a {}:\n{}".format(
                    in_id_field_value, e.__class__.__name__, str(e))
                feedback.reportError(msg)
                logger.log(msg, 2)
                continue

            features_out = responsehandler.generate_out_features(
                response, in_id_field_value)
            for feat_out in features_out:
                sink.addFeature(feat_out)

            feedback.setProgress(int(100.0 / in_source.featureCount() * num))

        return {self.OUT: dest_id}
Exemple #5
0
    def processAlgorithm(self, parameters, context, feedback):
        providers = configmanager.read_config()['providers']
        # Init client
        provider = providers[self.parameterAsEnum(parameters, self.IN_PROVIDER,
                                                  context)]
        in_source = self.parameterAsSource(parameters, self.IN_POINTS, context)
        in_id_field_name = self.parameterAsString(parameters, self.IN_ID_FIELD,
                                                  context)
        in_text_field_name = self.parameterAsString(parameters,
                                                    self.IN_TEXT_FIELD,
                                                    context)
        in_focus = self.parameterAsPoint(parameters, self.IN_FOCUS, context,
                                         self.crs_out)
        in_rectangle = self.parameterAsExtent(parameters, self.IN_RECTANGLE,
                                              context, self.crs_out)
        in_circle = self.parameterAsPoint(parameters, self.IN_CIRCLE, context,
                                          self.crs_out)
        in_circle_radius = self.parameterAsInt(parameters,
                                               self.IN_CIRCLE_RADIUS, context)
        in_country = self.parameterAsString(parameters, self.IN_COUNTRY,
                                            context)
        in_layers = self.parameterAsEnums(parameters, self.IN_LAYERS, context)
        in_sources = self.parameterAsEnums(parameters, self.IN_SOURCES,
                                           context)
        in_size = self.parameterAsInt(parameters, self.IN_SIZE, context)

        # Get user specified ID field as object
        in_id_field = in_source.fields().field(in_id_field_name)

        clnt = client.Client(provider)
        clnt.overQueryLimit.connect(lambda sleep_for: feedback.reportError(
            "OverQueryLimit: Wait for {} seconds".format(sleep_for)))

        params = dict()

        if in_focus.x() and in_focus.y():
            params['focus.lon'], params['focus.lat'] = [
                convert.format_float(coord) for coord in in_focus
            ]
        if not in_rectangle.isNull():
            (params['boundary.rect.min_lon'], params['boundary.rect.min_lat'],
             params['boundary.rect.max_lon'],
             params['boundary.rect.max_lat']) = [
                 convert.format_float(coord)
                 for coord in in_rectangle.toRectF().getCoords()
             ]
        if in_circle.x() and in_circle.y():
            (params['boundary.circle.lon'], params['boundary.circle.lat']) = [
                convert.format_float(coord) for coord in in_circle
            ]
            params['boundary.circle.radius'] = str(in_circle_radius)
        if in_country:
            params['boundary.country'] = in_country
        if in_layers:
            params['layers'] = convert.comma_list(
                [LAYERS[idx] for idx in in_layers])
        if in_sources:
            params['sources'] = convert.comma_list(
                [SOURCES[idx] for idx in in_sources])
        params['size'] = str(in_size)

        responsehandler = response_handler.ResponseHandler(in_id_field)

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUT, context,
                                               responsehandler.get_fields(),
                                               QgsWkbTypes.Point, self.crs_out)

        for num, feat_in in enumerate(in_source.getFeatures()):
            if feedback.isCanceled():
                break

            params_feat = dict()
            if in_text_field_name and feat_in[in_text_field_name]:
                params_feat['text'] = feat_in[in_text_field_name]
            in_id_field_value = feat_in[in_id_field_name]

            try:
                response = clnt.request(
                    provider['endpoints'][self.ALGO_NAME_LIST[1]], {
                        **params,
                        **params_feat
                    })
            except (exceptions.ApiError, exceptions.GenericServerError,
                    exceptions.InvalidKey) as e:
                msg = "Feature ID {} caused a {}:\n{}".format(
                    in_id_field_value, e.__class__.__name__, str(e))
                feedback.reportError(msg)
                logger.log(msg, 2)
                continue

            features_out = responsehandler.generate_out_features(
                response, in_id_field_value)
            for feat_out in features_out:
                sink.addFeature(feat_out)

            feedback.setProgress(int(100.0 / in_source.featureCount() * num))

        return {self.OUT: dest_id}