def processAlgorithm(self, progress):
        apik = apikey(False)
        if apik is None:
             raise GeoAlgorithmExecutionException("what3words API key is not defined")
        w3w = what3words(apikey=apik)
        filename = self.getParameterValue(self.INPUT)
        layer = dataobjects.getObjectFromUri(filename)
        vprovider = layer.dataProvider()
        fields = vprovider.fields()
        caps = layer.dataProvider().capabilities()
        if not (caps & QgsVectorDataProvider.AddAttributes):
            raise GeoAlgorithmExecutionException("The selected layer does not support adding new attributes.")

        idxField = fields.indexFromName("3WordAddr")
        if idxField == -1:
            vprovider.addAttributes([QgsField("3WordAddr", QVariant.String)])
            layer.updateFields()
            idxField = len(fields)
        nFeat = layer.featureCount()
        epsg4326 = QgsCoordinateReferenceSystem("EPSG:4326")
        transform = QgsCoordinateTransform(layer.crs(), epsg4326)

        for i, feat in enumerate(layer.getFeatures()):
            progress.setPercentage(int(100 * i / nFeat))
            pt = feat.geometry().vertexAt(0)
            try:
                pt4326 = transform.transform(pt.x(), pt.y())
                threeWords = ".".join(w3w.getWords(pt4326.y(), pt4326.x())["words"])
            except Exception,e :
                threeWords = ""
            layer.dataProvider().changeAttributeValues({feat.id() : {idxField: threeWords}})
示例#2
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT, context)
        fields = source.fields()
        field = QgsField("w3w", QVariant.String)
        fields.append(field)
        apiKey = pluginSetting("apiKey")
        w3w = what3words(apikey=apiKey)
        (sink, dest_id) = self.parameterAsSink(parameters,
                                               self.OUTPUT, context, fields,
                                               source.wkbType(),
                                               source.sourceCrs())

        features = source.getFeatures()
        total = 100.0 / source.featureCount() if source.featureCount() else 0

        epsg4326 = QgsCoordinateReferenceSystem('EPSG:4326')
        transform = QgsCoordinateTransform(source.sourceCrs(), epsg4326,
                                           QgsProject.instance())

        for current, feat in enumerate(features):
            if feedback.isCanceled():
                break

            feedback.setProgress(int(current * total))
            attrs = feat.attributes()
            pt = feat.geometry().centroid().asPoint()
            try:
                pt4326 = transform.transform(pt.x(), pt.y())
                threeWords = w3w.reverseGeocode(pt4326.y(),
                                                pt4326.x())["words"]
            except Exception as e:
                progress.setDebugInfo(
                    "Failed to retrieve w3w address for feature {}:\n{}".
                    format(feat.id(), str(e)))
                threeWords = ""

            attrs.append(threeWords)
            feat.setAttributes(attrs)
            sink.addFeature(feat, QgsFeatureSink.FastInsert)

        return {self.OUTPUT: dest_id}
    def processAlgorithm(self, progress):
        apik = pluginSetting("apiKey")
        if apik is None or apik == ""::
             raise GeoAlgorithmExecutionException("what3words API key is not defined")

        filename = self.getParameterValue(self.INPUT)
        layer = dataobjects.getObjectFromUri(filename)
        provider = layer.dataProvider()
        caps = provider.capabilities()
        if not (caps & QgsVectorDataProvider.AddAttributes):
            raise GeoAlgorithmExecutionException("The selected layer does not support adding new attributes.")

        idxField = layer.fieldNameIndex("3WordAddr")
        if idxField == -1:
            provider.addAttributes([QgsField("3WordAddr", QVariant.String, "", 254, 0)])
            layer.updateFields()
            idxField = layer.fieldNameIndex("3WordAddr")

        w3w = what3words(apikey=apik)

        nFeat = layer.featureCount()
        epsg4326 = QgsCoordinateReferenceSystem("EPSG:4326")
        transform = QgsCoordinateTransform(layer.crs(), epsg4326)

        for i, feat in enumerate(layer.getFeatures()):
            progress.setPercentage(int(100 * i / nFeat))
            pt = feat.geometry().vertexAt(0)
            try:
                pt4326 = transform.transform(pt.x(), pt.y())
                threeWords = w3w.reverseGeocode(pt4326.y(), pt4326.x())["words"]
            except Exception as e:
                progress.setDebugInfo("Failed to retrieve w3w address for feature {}:\n{}".format(feat.id(), str(e)))
                threeWords = ""

            provider.changeAttributeValues({feat.id() : {idxField: threeWords}})

        self.setOutputValue(self.OUTPUT, filename)
    def processAlgorithm(self, progress):
        apik = apikey(False)
        if apik is None:
            raise GeoAlgorithmExecutionException(
                "what3words API key is not defined")
        w3w = what3words(apikey=apik)
        filename = self.getParameterValue(self.INPUT)
        layer = dataobjects.getObjectFromUri(filename)
        vprovider = layer.dataProvider()
        fields = vprovider.fields()
        caps = layer.dataProvider().capabilities()
        if not (caps & QgsVectorDataProvider.AddAttributes):
            raise GeoAlgorithmExecutionException(
                "The selected layer does not support adding new attributes.")

        idxField = fields.indexFromName("3WordAddr")
        if idxField == -1:
            vprovider.addAttributes([QgsField("3WordAddr", QVariant.String)])
            layer.updateFields()
            idxField = len(fields)
        nFeat = layer.featureCount()
        epsg4326 = QgsCoordinateReferenceSystem("EPSG:4326")
        transform = QgsCoordinateTransform(layer.crs(), epsg4326)

        for i, feat in enumerate(layer.getFeatures()):
            progress.setPercentage(int(100 * i / nFeat))
            pt = feat.geometry().vertexAt(0)
            try:
                pt4326 = transform.transform(pt.x(), pt.y())
                threeWords = ".".join(
                    w3w.getWords(pt4326.y(), pt4326.x())["words"])
            except Exception, e:
                threeWords = ""
            layer.dataProvider().changeAttributeValues(
                {feat.id(): {
                     idxField: threeWords
                 }})
示例#5
0
 def __init__(self, canvas):
     QgsMapTool.__init__(self, canvas)
     self.setCursor(Qt.CrossCursor)
     apiKey = pluginSetting("apiKey")
     self.w3w = what3words(apikey=apiKey)
示例#6
0
 def setApiKey(self, apikey):
     self.w3w = what3words(apikey=apikey)
class Add3WordsFieldAlgorithm(GeoAlgorithm):

    '''
    An algorithm that takes a points layer and oututs the same layer but with 
    an additional field containing w3w adresses of points in the input layer.
    '''

    INPUT = 'INPUT'
    OUTPUT = 'OUTPUT'

    def processAlgorithm(self, progress):
        '''
        Here is where the algorithm functionality takes places. This method is 
        called when the algorithm is executed'''

        apik = pluginSetting("apiKey")
        if apik is None or apik == ""::
            '''
            When there is a problem in a Processing algorithm, a 
            GeoAlgorithmExecutionException should be raised.
            '''
             raise GeoAlgorithmExecutionException("what3words API key is not defined")

        '''
        Get value selected by user. It will always be a string with the path 
        to the layer source.
        '''
        filename = self.getParameterValue(self.INPUT)
        
        '''Convert it to a QGIS layer object'''
        layer = dataobjects.getObjectFromUri(filename)
        
        '''Some checking'''
        provider = layer.dataProvider()
        caps = provider.capabilities()
        if not (caps & QgsVectorDataProvider.AddAttributes):
            raise GeoAlgorithmExecutionException("The selected layer does not support adding new attributes.")

        '''
        Check if there is a field named '3WordAddr'. If it exists already, 
        we will overwrite its content. Otherwise, we create a new one.
        '''
        idxField = layer.fieldNameIndex("3WordAddr")
        if idxField == -1:
            provider.addAttributes([QgsField("3WordAddr", QVariant.String, "", 254, 0)])
            layer.updateFields()
            idxField = layer.fieldNameIndex("3WordAddr")

        w3w = what3words(apikey=apik)

        nFeat = layer.featureCount()
        epsg4326 = QgsCoordinateReferenceSystem("EPSG:4326")

        '''
        We use this object to convert point coords from the layer CRS into 
        EPSG:4326, which is needed to call the w3w service
        '''
        transform = QgsCoordinateTransform(layer.crs(), epsg4326)

        '''Iterate over features'''
        for i, feat in enumerate(layer.getFeatures()):
            progress.setPercentage(int(100 * i / nFeat))
            '''Get Coordinate in layer CRS'''
            pt = feat.geometry().vertexAt(0)
            try:
                '''Convert to 4326'''
                pt4326 = transform.transform(pt.x(), pt.y())
                '''Convert 4326 coord into w3w address'''
                threeWords = w3w.reverseGeocode(pt4326.y(), pt4326.x())["words"]
            except Exception as e:
                progress.setDebugInfo("Failed to retrieve w3w address for feature {}:\n{}".format(feat.id(), str(e)))
                threeWords = ""

            provider.changeAttributeValues({feat.id() : {idxField: threeWords}})

        self.setOutputValue(self.OUTPUT, filename)