Пример #1
0
    def validate_wfs(self):
        """Validate input arguments with the WFS service."""
        wfs = WebFeatureService(self.url, version=self.version)

        valid_layers = list(wfs.contents)
        if self.layer is None:
            raise MissingInputs("The layer argument is missing." +
                                " The following layers are available:\n" +
                                ", ".join(valid_layers))

        if self.layer not in valid_layers:
            raise InvalidInputValue("layers", valid_layers)

        valid_outformats = wfs.getOperationByName(
            "GetFeature").parameters["outputFormat"]["values"]
        valid_outformats = [v.lower() for v in valid_outformats]
        if self.outformat is None:
            raise MissingInputs(
                "The outformat argument is missing." +
                " The following output formats are available:\n" +
                ", ".join(valid_outformats))

        if self.outformat not in valid_outformats:
            raise InvalidInputValue("outformat", valid_outformats)

        valid_crss = [
            f"{s.authority.lower()}:{s.code}"
            for s in wfs[self.layer].crsOptions
        ]
        if self.crs.lower() not in valid_crss:
            raise InvalidInputValue("crs", valid_crss)
Пример #2
0
class HandleWFS():

    def __init__(self, url, version="1.0.0"):
        self.wfs = WebFeatureService(url, version=version)
        self.type = self.wfs.identification.type
        self.version = self.wfs.identification.version
        self.title = self.wfs.identification.title
        self.abstract = self.wfs.identification.abstract

    def do_layer_check(self, data_dict):
        layer_list = list(self.wfs.contents)
        resource = data_dict.get("resource", {})
        this_layer = resource.get("layer")
        try:
            first_layer = layer_list[0]
            if this_layer in layer_list:
                return this_layer
            elif this_layer.lower() in layer_list:
                return this_layer.lower()
            else:
                return first_layer
        except Exception:
            pass

    def build_url(self, typename=None, method='{http://www.opengis.net/wfs}Get',
                  operation='{http://www.opengis.net/wfs}GetFeature', maxFeatures=None):
        service_url = self.wfs.getOperationByName(operation).methods[method]['url']
        request = {'service': 'WFS', 'version': self.version}
        try:
            assert len(typename) > 0
            request['typename'] = ','.join([typename])
        except Exception:
            request['typename'] = ','.join('ERROR_HERE')
            pass

        if maxFeatures: request['maxfeatures'] = str(maxFeatures)

        encoded_request = "&".join("%s=%s" % (key,value) for (key,value) in request.items())
        url = service_url + "&" + encoded_request
        return url

    def make_geojson(self, data_dict):
        geojson = []
        type_name = self.do_layer_check(data_dict)
        wfs_url = self.build_url(type_name, maxFeatures=100)
        source = ogr.Open(wfs_url)
        layer = source.GetLayerByIndex(0)
        for feature in layer:
            geojson.append(feature.ExportToJson(as_object=True))
        return geojson

    def make_recline_json(self, data_dict):
        recline_json = []
        geojson = self.make_geojson(data_dict)
        for i in geojson:
            properties = i['properties']
            properties.update(dict(geometry=i['geometry']))
            recline_json.append(properties)
        return recline_json
Пример #3
0
def doWfs(url):
    ## Huom! Minulle tuli ongelmia ilman version-parametria.
    ##  - Ilmeisesti oman ympäristön owslib lähti hakemaan versiota 1.0.0, joka aiheutti virheen joka jäi joko ikilooppiin tai oli vaan törkeän hidas
    ##  - Aivan kaikki palvelut eivät tue WFS 1.1.0:aa, mutta koetetaan tällä kunnes tulee ongelmia vastaan
    wfs = WebFeatureService(url, version='1.1.0')
    wfsGetFeature = next((i
                          for i in wfs.getOperationByName('GetFeature').methods
                          if i['type'] == 'Get'), None)

    ## Ei taideta tarvita formaattia WFS:llä
    return {
        'type': 'WFS',
        'contents': list(wfs.contents),
        'url': wfsGetFeature['url'],
        'service': wfs
    }
Пример #4
0
class HandleWFS():
    """
    Processor for WFS resources.  Requires a getCapabilities URL for the WFS and a WFS version passed in as a string.
    Default version is '1.0.0'; other supported versions are '1.1.0' and '2.0.0'
    """
    def __init__(self, url, version="1.0.0"):
        self.wfs = WebFeatureService(url, version=version)
        self.type = self.wfs.identification.type
        self.version = self.wfs.identification.version
        self.title = self.wfs.identification.title
        self.abstract = self.wfs.identification.abstract

    # Return a specific service URL, getFeature is default
    def get_service_url(self,
                        operation='{http://www.opengis.net/wfs}GetFeature',
                        method='{http://www.opengis.net/wfs}Get'):
        return self.wfs.getOperationByName(operation).methods[method]['url']

    # Pass in a dictionary with the layer name bound to 'layer'.  If the 'layer' is not found, then just return the
    # first layer in the list of available layers
    def do_layer_check(self, data_dict):
        wfs_layers = list(self.wfs.contents)
        resource = data_dict.get("resource", {})
        res_layer = resource.get("layer", None)

        if res_layer and wfs_layers:
            wfs_lower = [x.lower() for x in wfs_layers]
            res_lower = res_layer.lower()
            if res_lower in wfs_lower:
                return res_layer
        elif wfs_layers:
            return wfs_layers[0]

    # Build a URL for accessing service data, getFeature is default
    def build_url(self,
                  typename=None,
                  method='{http://www.opengis.net/wfs}Get',
                  operation='{http://www.opengis.net/wfs}GetFeature',
                  maxFeatures=None):
        service_url = self.wfs.getOperationByName(
            operation).methods[method]['url']
        request = {'service': 'WFS', 'version': self.version}
        try:
            assert len(typename) > 0
            request['typename'] = ','.join([typename])
        except Exception:
            request['typename'] = ','.join('ERROR_HERE')
            pass

        if maxFeatures: request['maxfeatures'] = str(maxFeatures)

        encoded_request = "&".join("%s=%s" % (key, value)
                                   for (key, value) in request.items())
        url = service_url + "&" + encoded_request
        return url

    # Take a data_dict, use information to build a getFeature URL and get features as GML.  Then take that GML response
    # and turn it into GeoJSON.
    def make_geojson(self, data_dict):
        geojson = []
        type_name = self.do_layer_check(data_dict)
        wfs_url = self.build_url(type_name, maxFeatures=100)
        source = ogr.Open(wfs_url)
        layer = source.GetLayerByIndex(0)
        for feature in layer:
            geojson.append(feature.ExportToJson(as_object=True))
        return geojson

    # Recline.js doesn't support the GeoJSON specification and instead just wants it's own flavor of spatial-json.  So,
    # give this method the same data_dict you would give the 'make_geojson' method and we'll take the GeoJSON and turn
    # it into Recline JSON.
    def make_recline_json(self, data_dict):
        recline_json = []
        geojson = self.make_geojson(data_dict)
        for i in geojson:
            properties = i['properties']
            properties.update(dict(geometry=i['geometry']))
            recline_json.append(properties)
        return recline_json
Пример #5
0
class WFS():
    def __init__(self, url, version):
        self.wfs = WebFeatureService(url=url, version=version)

    def set_collection(self, collection):
        collection_exist = self._check_collection(collection)
        if collection_exist:
            self.collection = collection
        return collection_exist

    def _check_collection(self, collection):
        feature_types = list(self.wfs.contents)
        collection_exist = True if collection in feature_types else False
        return collection_exist

    def get_schema(self):
        if hasattr(self, 'collection'):
            return self.wfs.get_schema(self.collection)
        else:
            return None

    def make_request(self,
                     max_dataset=100,
                     sort_by=None,
                     start_index=0,
                     constraint=None):
        output_format = self._get_outputformat()
        result = self.wfs.getfeature(typename=self.collection,
                                     filter=constraint,
                                     maxfeatures=max_dataset,
                                     sortby=sort_by,
                                     startindex=start_index,
                                     outputFormat=output_format)
        result = result.read()
        if 'json' in output_format:
            return json.loads(result)
        else:
            return result

    def get_request(self,
                    max_dataset=None,
                    sort_by=None,
                    start_index=0,
                    constraint=None):
        output_format = self._get_outputformat()
        result = self.wfs.getGETGetFeatureRequest(typename=self.collection,
                                                  filter=constraint,
                                                  maxfeatures=max_dataset,
                                                  sortby=sort_by,
                                                  startindex=start_index,
                                                  outputFormat=output_format)

        return result

    def _get_outputformat(self):
        getfeature_param = self.wfs.getOperationByName('GetFeature').parameters
        allowed_output_format = getfeature_param["outputFormat"]["values"]

        for output_format in OUTPUT_FORMAT:
            if output_format in allowed_output_format:
                return output_format
        return None

    def set_filter_equal_to(self, propertyname, value):
        constraint = PropertyIsLike(propertyname=propertyname, literal=value)
        filterxml = etree.tostring(constraint.toXML()).decode("utf-8")
        return filterxml
class HandleWFS():
    """
    Processor for WFS resources.  Requires a getCapabilities URL for the WFS and a WFS version passed in as a string.
    Default version is '1.1.0'; other supported versions are '1.0.0' and '2.0.0'
    """

    def __init__(self, url, version="1.1.0"):
        self.wfs = WebFeatureService(url, version=version)
        self.type = self.wfs.identification.type
        self.version = self.wfs.identification.version
        self.title = self.wfs.identification.title
        self.abstract = self.wfs.identification.abstract

    # Return a specific service URL, getFeature is default
    def get_service_url(self, operation='{http://www.opengis.net/wfs}GetFeature', method='{http://www.opengis.net/wfs}Get'):
        if self.version == "1.1.0":
            operation = "GetFeature"
            method = "Get"

        return self.wfs.getOperationByName(operation).methods[method]['url']

    # Pass in a dictionary with the layer name bound to 'layer'.  If the 'layer' is not found, then just return the
    # first layer in the list of available layers
    def do_layer_check(self, data_dict):
        layer_list = list(self.wfs.contents)
        resource = data_dict.get("resource", {})
        this_layer = resource.get("layer")
        try:
            first_layer = layer_list[0]
            if this_layer in layer_list:
                return this_layer
            elif this_layer.lower() in layer_list:
                return this_layer.lower()
            else:
                return first_layer
        except Exception:
            pass

    # Build a URL for accessing service data, getFeature is default
    def build_url(self, typename=None, method='{http://www.opengis.net/wfs}Get', operation='{http://www.opengis.net/wfs}GetFeature', maxFeatures=None):

        if self.version == "1.1.0":
            operation = "GetFeature"
            method = "Get"

        service_url = self.wfs.getOperationByName(operation).methods[method]['url']
        request = {
            'service': 'WFS',
            'version': self.version
        }

        if self.version == "1.1.0":
            request = {
                'service': 'WFS',
                'version': self.version,
                'request': 'GetFeature'
            }

        try:
            assert len(typename) > 0
            request['typename'] = ','.join([typename])
        except Exception:
            request['typename'] = ','.join('ERROR_HERE')
            pass

        if maxFeatures:
            request['maxfeatures'] = str(maxFeatures)

        encoded_request = "&".join("%s=%s" % (key, value) for (key, value) in request.items())
        url = service_url + "&" + encoded_request

        if self.version == "1.1.0":
            url = service_url + "?" + encoded_request

        return url

    # Take a data_dict, use information to build a getFeature URL and get features as GML.  Then take that GML response
    # and turn it into GeoJSON.
    def make_geojson(self, data_dict):
        geojson = []
        type_name = self.do_layer_check(data_dict)
        wfs_url = self.build_url(type_name, maxFeatures=100)
        source = ogr.Open(wfs_url)
        layer = source.GetLayerByIndex(0)
        for feature in layer:
            geojson.append(feature.ExportToJson(as_object=True))
        return geojson

    # Recline.js doesn't support the GeoJSON specification and instead just wants it's own flavor of spatial-json.  So,
    # give this method the same data_dict you would give the 'make_geojson' method and we'll take the GeoJSON and turn
    # it into Recline JSON.
    def make_recline_json(self, data_dict):
        recline_json = []
        geojson = self.make_geojson(data_dict)
        for i in geojson:
            properties = i['properties']
            properties.update(dict(geometry=i['geometry']))
            recline_json.append(properties)
        return recline_json
Пример #7
0
    
    print("\n\tProvider: ", dir(wfs.provider))
    print(wfs.provider.name)
    print(wfs.provider.url)
    print(wfs.provider.contact.email)
    print(wfs.provider.contact.phone)
    print(wfs.provider.contact.name)
    print(wfs.provider.contact.organization)
    print(wfs.provider.contact.city)
    print(wfs.provider.contact.region)
    print(wfs.provider.contact.postcode)
    print(wfs.provider.contact.country)

    print("\n\tOperations: ", [op.name for op in wfs.operations])
    
    op_describe = wfs.getOperationByName('DescribeFeatureType')
    help(op_describe)

    get_cap = wfs.getOperationByName('GetCapabilities')
    # help(get_cap)
    
    print(wfs.getGETGetFeatureRequest())

    get_feat = wfs.getOperationByName('GetFeature')
    # help(get_feat)
    

    for layer in list(wfs.contents):
        try:
            print(u'Layer: %s, Features: %s, SR: %s...' % (wfs[layer].title, wfs[layer].abstract, wfs[layer].crsOptions))
            print(wfs[layer].boundingBox)
Пример #8
0
class HandleWFS():
    def __init__(self, url, version="1.0.0"):
        self.wfs = WebFeatureService(url, version=version)
        self.type = self.wfs.identification.type
        self.version = self.wfs.identification.version
        self.title = self.wfs.identification.title
        self.abstract = self.wfs.identification.abstract

    def do_layer_check(self, data_dict):
        layer_list = list(self.wfs.contents)
        resource = data_dict.get("resource", {})
        this_layer = resource.get("layer")
        try:
            first_layer = layer_list[0]
            if this_layer in layer_list:
                return this_layer
            elif this_layer.lower() in layer_list:
                return this_layer.lower()
            else:
                return first_layer
        except Exception:
            pass

    def build_url(self,
                  typename=None,
                  method='{http://www.opengis.net/wfs}Get',
                  operation='{http://www.opengis.net/wfs}GetFeature',
                  maxFeatures=None):
        service_url = self.wfs.getOperationByName(
            operation).methods[method]['url']
        request = {'service': 'WFS', 'version': self.version}
        try:
            assert len(typename) > 0
            request['typename'] = ','.join([typename])
        except Exception:
            request['typename'] = ','.join('ERROR_HERE')
            pass

        if maxFeatures: request['maxfeatures'] = str(maxFeatures)

        encoded_request = "&".join("%s=%s" % (key, value)
                                   for (key, value) in request.items())
        url = service_url + "&" + encoded_request
        return url

    def make_geojson(self, data_dict):
        geojson = []
        type_name = self.do_layer_check(data_dict)
        wfs_url = self.build_url(type_name, maxFeatures=100)
        source = ogr.Open(wfs_url)
        layer = source.GetLayerByIndex(0)
        for feature in layer:
            geojson.append(feature.ExportToJson(as_object=True))
        return geojson

    def make_recline_json(self, data_dict):
        recline_json = []
        geojson = self.make_geojson(data_dict)
        for i in geojson:
            properties = i['properties']
            properties.update(dict(geometry=i['geometry']))
            recline_json.append(properties)
        return recline_json
Пример #9
0
    def build_wfs_url(self, api_layer, srv_details, rsc_type="ds_dyn_lyr_srv", mode="complete"):
        """Reformat the input WMS url so it fits QGIS criterias.

        Tests weither all the needed information is provided in the url, and
        then build the url in the syntax understood by QGIS.
        """
        # local variables
        layer_title = api_layer.get("titles")[0].get("value", "WFS Layer")
        wfs_url_getcap = srv_details.get("path")\
                         + "?request=GetCapabilities&service=WFS"
        geoserver = "geoserver" in wfs_url_getcap
        layer_id = api_layer.get("id")
        layer_name = re.sub('\{.*?}', "", layer_id)
        # handling WFS namespaces
        if "{" in layer_id:
            namespace = layer_id[layer_id.find("{") + 1:layer_id.find("}")]
            logging.debug("WFS - Namespace: " + namespace)
        else:
            namespace = ""

        if mode == "quicky":
            # let's try a quick & dirty url build
            srs_map = plg_tools.get_map_crs()
            wfs_url_base = srv_details.get("path")
            uri = QgsDataSourceURI()
            uri.setParam("url", wfs_url_base)
            uri.setParam("typename", layer_name)
            uri.setParam("version", "auto")
            uri.setParam("srsname", srs_map)
            uri.setParam("restrictToRequestBBOX", "1")
            wfs_url_quicky = uri.uri()

            btn_lbl = "WFS : {}".format(layer_title)
            return ["WFS", layer_title, wfs_url_quicky,
                    api_layer, srv_details, btn_lbl]
        elif mode == "complete":
            # Clean, complete but slower way - OWSLib -------------------------
            if srv_details.get("path") == self.cached_wfs.get("srv_path"):
                logger.debug("WFS: already in cache")
            else:
                self.cached_wfs["srv_path"] = srv_details.get("path")
                logger.debug("WFS: new service")
                pass
            # basic checks on service url
            try:
                wfs = WebFeatureService(wfs_url_getcap)
            except ServiceException as e:
                logger.error(str(e))
                return 0, "WFS - Bad operation: " + wfs_url_getcap, str(e)
            except HTTPError as e:
                logger.error(str(e))
                return 0, "WFS - Service not reached: " + wfs_url_getcap, str(e)
            except Exception as e:
                return 0, e

            # check if GetFeature and DescribeFeatureType operation are available
            if not hasattr(wfs, "getfeature") or "GetFeature" not in [op.name for op in wfs.operations]:
                self.cached_wfs["GetFeature"] = 0
                return 0, "Required GetFeature operation not available in: " + wfs_url_getcap
            else:
                self.cached_wfs["GetFeature"] = 1
                logger.info("GetFeature available")
                pass

            if "DescribeFeatureType" not in [op.name for op in wfs.operations]:
                self.cached_wfs["DescribeFeatureType"] = 0
                return 0, "Required DescribeFeatureType operation not available in: " + wfs_url_getcap
            else:
                self.cached_wfs["DescribeFeatureType"] = 1
                logger.info("DescribeFeatureType available")
                pass

            # check if required layer is present
            try:
                wfs_lyr = wfs[layer_name]
            except KeyError as e:
                logger.error("Layer {} not found in WFS service: {}"
                             .format(layer_name,
                                     wfs_url_getcap))
                if geoserver and layer_name in [l.split(":")[1] for l in list(wfs.contents)]:
                    layer_name = list(wfs.contents)[[l.split(":")[1]
                                                    for l in list(wfs.contents)].index(layer_name)]
                    try:
                        wfs_lyr = wfs[layer_name]
                    except KeyError as e:
                        return (0,
                                "Layer {} not found in WFS service: {}"
                                .format(layer_name,
                                        wfs_url_getcap),
                                e)

            # SRS definition
            srs_map = plg_tools.get_map_crs()
            srs_lyr_new = qsettings.value("/Projections/defaultBehaviour")
            srs_lyr_crs = qsettings.value("/Projections/layerDefaultCrs")
            srs_qgs_new = qsettings.value("/Projections/projectDefaultCrs")
            srs_qgs_otf_on = qsettings.value("/Projections/otfTransformEnabled")
            srs_qgs_otf_auto = qsettings.value("/Projections/otfTransformAutoEnable")

            # DEV
            # print("CRS: ", wms_lyr.crsOptions,
            #       "For new layers: " + srs_lyr_new + srs_lyr_crs,
            #       "For new projects: " + srs_qgs_new,
            #       "OTF enabled: " + srs_qgs_otf_on,
            #       "OTF smart enabled: " + srs_qgs_otf_auto,
            #       "Map canvas SRS:" + plg_tools.get_map_crs())

            wfs_lyr_crs_epsg = ["{}:{}".format(srs.authority, srs.code)
                                for srs in wfs_lyr.crsOptions]
            self.cached_wfs["CRS"] = wfs_lyr_crs_epsg
            if srs_map in wfs_lyr_crs_epsg:
                logger.debug("It's a SRS match! With map canvas: " + srs_map)
                srs = srs_map
            elif srs_qgs_new in wfs_lyr_crs_epsg\
                 and srs_qgs_otf_on == "false"\
                 and srs_qgs_otf_auto == "false":
                logger.debug("It's a SRS match! With default new project: " + srs_qgs_new)
                srs = srs_qgs_new
            elif srs_lyr_crs in wfs_lyr_crs_epsg and srs_lyr_new == "useGlobal":
                logger.debug("It's a SRS match! With default new layer: " + srs_lyr_crs)
                srs = srs_lyr_crs
            elif "EPSG:4326" in wfs_lyr_crs_epsg:
                logger.debug("It's a SRS match! With standard WGS 84 (EPSG:4326)")
                srs = "EPSG:4326"
            else:
                logger.debug("Map Canvas SRS not available within service CRS.")
                srs = wfs_lyr_crs_epsg[0]

            # Style definition
            # print("Styles: ", wms_lyr.styles, type(wms_lyr.styles))
            # lyr_style = wfs_lyr.styles.keys()[0]
            # print(lyr_style)

            # GetFeature URL
            wfs_lyr_url = wfs.getOperationByName('GetFeature').methods
            wfs_lyr_url = wfs_lyr_url[0].get("url")
            if wfs_lyr_url[-1] != "&":
                wfs_lyr_url = wfs_lyr_url + "&"
            else:
                pass
            self.cached_wfs["url"] = wfs_lyr_url

            # url construction
            try:
                wfs_url_params = {"SERVICE": "WFS",
                                  "VERSION": "1.0.0",
                                  "TYPENAME": layer_name,
                                  "SRSNAME": srs,
                                  }
                wfs_url_final = wfs_lyr_url + unquote(urlencode(wfs_url_params, "utf8"))
            except UnicodeEncodeError:
                wfs_url_params = {"SERVICE": "WFS",
                                  "VERSION": "1.0.0",
                                  "TYPENAME": layer_name.decode("latin1"),
                                  "SRSNAME": srs,
                                  }
                wfs_url_final = wfs_lyr_url + unquote(urlencode(wfs_url_params))
            # method ending
            logger.debug(wfs_url_final)
            # logger.debug(uri)
            return ["WFS", layer_title, wfs_url_final]
            # return ["WFS", layer_title, uri.uri()]
        else:
            return None
Пример #10
0
    
    print(("\n\tProvider: ", dir(wfs.provider)))
    print(wfs.provider.name)
    print(wfs.provider.url)
    print(wfs.provider.contact.email)
    print(wfs.provider.contact.phone)
    print(wfs.provider.contact.name)
    print(wfs.provider.contact.organization)
    print(wfs.provider.contact.city)
    print(wfs.provider.contact.region)
    print(wfs.provider.contact.postcode)
    print(wfs.provider.contact.country)

    print(("\n\tOperations: ", [op.name for op in wfs.operations]))
    
    op_describe = wfs.getOperationByName('DescribeFeatureType')
    help(op_describe)

    get_cap = wfs.getOperationByName('GetCapabilities')
    # help(get_cap)
    
    print(wfs.getGETGetFeatureRequest())

    get_feat = wfs.getOperationByName('GetFeature')
    # help(get_feat)
    

    for layer in list(wfs.contents):
        try:
            print(u'Layer: %s, Features: %s, SR: %s...' % (wfs[layer].title, wfs[layer].abstract, wfs[layer].crsOptions))
            print(wfs[layer].boundingBox)
Пример #11
0
    def build_wfs_url(self,
                      api_layer,
                      srv_details,
                      rsc_type="ds_dyn_lyr_srv",
                      mode="complete"):
        """Reformat the input WMS url so it fits QGIS criterias.

        Tests weither all the needed information is provided in the url, and
        then build the url in the syntax understood by QGIS.
        """
        # local variables
        layer_title = "WFS Layer"
        if len(api_layer.get("titles")):
            layer_title = api_layer.get("titles")[0].get("value", "WFS Layer")
        else:
            pass

        wfs_url_getcap = (srv_details.get("path") +
                          "?request=GetCapabilities&service=WFS")
        geoserver = "geoserver" in wfs_url_getcap
        layer_id = api_layer.get("id")
        layer_name = re.sub("\{.*?}", "", layer_id)
        # handling WFS namespaces
        if "{" in layer_id:
            first_car = layer_id.find("{") + 1
            last_car = layer_id.find("}")
            namespace = layer_id[first_car:last_car]
            logging.debug("WFS - Namespace: " + namespace)
        else:
            namespace = ""

        if mode == "quicky":
            # let's try a quick & dirty url build
            srs_map = plg_tools.get_map_crs()
            wfs_url_base = srv_details.get("path")
            uri = QgsDataSourceUri()
            uri.setParam("url", wfs_url_base)
            uri.setParam("typename", layer_name)
            uri.setParam("version", "auto")
            uri.setParam("srsname", srs_map)
            uri.setParam("restrictToRequestBBOX", "1")
            wfs_url_quicky = uri.uri()

            btn_lbl = "WFS : {}".format(layer_title)
            return [
                "WFS", layer_title, wfs_url_quicky, api_layer, srv_details,
                btn_lbl
            ]
        elif mode == "complete":
            # Clean, complete but slower way - OWSLib -------------------------
            if srv_details.get("path") == self.cached_wfs.get("srv_path"):
                logger.debug("WFS: already in cache")
            else:
                self.cached_wfs["srv_path"] = srv_details.get("path")
                logger.debug("WFS: new service")
                pass
            # basic checks on service url
            try:
                wfs = WebFeatureService(wfs_url_getcap)
            except ServiceException as e:
                logger.error(str(e))
                return 0, "WFS - Bad operation: " + wfs_url_getcap, str(e)
            except HTTPError as e:
                logger.error(str(e))
                return 0, "WFS - Service not reached: " + wfs_url_getcap, str(
                    e)
            except Exception as e:
                return 0, e

            # check if GetFeature and DescribeFeatureType operation are available
            if not hasattr(wfs, "getfeature") or "GetFeature" not in [
                    op.name for op in wfs.operations
            ]:
                self.cached_wfs["GetFeature"] = 0
                return (
                    0,
                    "Required GetFeature operation not available in: " +
                    wfs_url_getcap,
                )
            else:
                self.cached_wfs["GetFeature"] = 1
                logger.info("GetFeature available")
                pass

            if "DescribeFeatureType" not in [op.name for op in wfs.operations]:
                self.cached_wfs["DescribeFeatureType"] = 0
                return (
                    0,
                    "Required DescribeFeatureType operation not available in: "
                    + wfs_url_getcap,
                )
            else:
                self.cached_wfs["DescribeFeatureType"] = 1
                logger.info("DescribeFeatureType available")
                pass

            # check if required layer is present
            try:
                wfs_lyr = wfs[layer_name]
            except KeyError as e:
                logger.error("Layer {} not found in WFS service: {}".format(
                    layer_name, wfs_url_getcap))
                if geoserver and layer_name in [
                        l.split(":")[1] for l in list(wfs.contents)
                ]:
                    layer_name = list(wfs.contents)[[
                        l.split(":")[1] for l in list(wfs.contents)
                    ].index(layer_name)]
                    try:
                        wfs_lyr = wfs[layer_name]
                    except KeyError as e:
                        return (
                            0,
                            "Layer {} not found in WFS service: {}".format(
                                layer_name, wfs_url_getcap),
                            e,
                        )
                else:
                    return (
                        0,
                        "Layer {} not found in WFS service: {}".format(
                            layer_name, wfs_url_getcap),
                        e,
                    )

            # SRS definition
            srs_map = plg_tools.get_map_crs()
            srs_lyr_new = qsettings.value("/Projections/defaultBehaviour")
            srs_lyr_crs = qsettings.value("/Projections/layerDefaultCrs")
            srs_qgs_new = qsettings.value("/Projections/projectDefaultCrs")
            srs_qgs_otf_on = qsettings.value(
                "/Projections/otfTransformEnabled")
            srs_qgs_otf_auto = qsettings.value(
                "/Projections/otfTransformAutoEnable")

            # DEV
            # print("CRS: ", wms_lyr.crsOptions,
            #       "For new layers: " + srs_lyr_new + srs_lyr_crs,
            #       "For new projects: " + srs_qgs_new,
            #       "OTF enabled: " + srs_qgs_otf_on,
            #       "OTF smart enabled: " + srs_qgs_otf_auto,
            #       "Map canvas SRS:" + plg_tools.get_map_crs())

            wfs_lyr_crs_epsg = [
                "{}:{}".format(srs.authority, srs.code)
                for srs in wfs_lyr.crsOptions
            ]
            self.cached_wfs["CRS"] = wfs_lyr_crs_epsg
            if srs_map in wfs_lyr_crs_epsg:
                logger.debug("It's a SRS match! With map canvas: " + srs_map)
                srs = srs_map
            elif (srs_qgs_new in wfs_lyr_crs_epsg and srs_qgs_otf_on == "false"
                  and srs_qgs_otf_auto == "false"):
                logger.debug("It's a SRS match! With default new project: " +
                             srs_qgs_new)
                srs = srs_qgs_new
            elif srs_lyr_crs in wfs_lyr_crs_epsg and srs_lyr_new == "useGlobal":
                logger.debug("It's a SRS match! With default new layer: " +
                             srs_lyr_crs)
                srs = srs_lyr_crs
            elif "EPSG:4326" in wfs_lyr_crs_epsg:
                logger.debug(
                    "It's a SRS match! With standard WGS 84 (EPSG:4326)")
                srs = "EPSG:4326"
            else:
                logger.debug(
                    "Map Canvas SRS not available within service CRS.")
                srs = wfs_lyr_crs_epsg[0]

            # Style definition
            # print("Styles: ", wms_lyr.styles, type(wms_lyr.styles))
            # lyr_style = wfs_lyr.styles.keys()[0]
            # print(lyr_style)

            # GetFeature URL
            wfs_lyr_url = wfs.getOperationByName("GetFeature").methods
            wfs_lyr_url = wfs_lyr_url[0].get("url")
            if wfs_lyr_url[-1] != "&":
                wfs_lyr_url = wfs_lyr_url + "&"
            else:
                pass
            self.cached_wfs["url"] = wfs_lyr_url

            # url construction
            try:
                wfs_url_params = {
                    "SERVICE": "WFS",
                    "VERSION": "1.0.0",
                    "TYPENAME": layer_name,
                    "SRSNAME": srs,
                }
                wfs_url_final = wfs_lyr_url + unquote(
                    urlencode(wfs_url_params, "utf8"))
            except UnicodeEncodeError:
                wfs_url_params = {
                    "SERVICE": "WFS",
                    "VERSION": "1.0.0",
                    "TYPENAME": layer_name.decode("latin1"),
                    "SRSNAME": srs,
                }
                wfs_url_final = wfs_lyr_url + unquote(
                    urlencode(wfs_url_params))
            # method ending
            logger.debug(wfs_url_final)
            # logger.debug(uri)
            return ["WFS", layer_title, wfs_url_final]
            # return ["WFS", layer_title, uri.uri()]
        else:
            return None