def get_bbox_from_data(*args):
    """
    Get geometry of bbox for available data in the style: [xmin, ymin, xmax, ymax].

    :param args: Ids inside the bounding box
    :type args: list
    :return: list
    """
    try:
        if args:
            bounds = Entries.objects.filter(pk__in=args[0]).aggregate(Extent('location'))
        else:
            bounds = Entries.objects.all().aggregate(Extent('location'))
    except TypeError as ex:
        print('\033[91m Exeption in loading bbox: {}\033[0m'.format(ex))
        logger.warning('\033[91m Data Extend cannot be loaded in query_functions.py. Using fixed values.\033[0m')
        bounds = {'location__extent': [11.221124, 52.08632, 11.222354, 52.086891]}

    return list(bounds['location__extent'])
Beispiel #2
0
def reparent_cities(country, clear=False, output_every=256):
    """ Réorganiser la hiérarchie des villes d'un pays """
    if not settings.DEBUG:
        # Récupérer les éléments de type A (ex. ADM1)
        if clear:
            City.objects.filter(country=country).update(parent=None)
        parents = City.objects.filter(Q(feature='A') | Q(type__in=['PPLA', 'PPLA2', 'PPLA3', 'PPLA4']), country=country).order_by('type').distinct()
        rows = parents.count()
        country_name = country.get_name()
        # Parcourir ces éléments et mettre à jour les enfants directs
        for idx, parent in enumerate(parents, start=1):
            level, acode = 1, parent.acode
            # Trouver le niveau administratif actuel de l'élément
            for i, codestart in enumerate(range(0, 16, 4), start=1):
                level = i if acode[codestart:codestart + 4] != "AAAA" else level
            # Update les P et ADMD enfants
            criteria = {'acode': acode, 'country': country, 'parent__isnull': True}
            type_filter = (Q(feature='P') | Q(type="ADMD")) if parent.type != 'ADMD' else Q(feature='P')
            City.objects.filter(type_filter, **criteria).exclude(id=parent.id).update(parent_id=parent.id, level=level)
            # Update les A enfants
            if level < 4 and parent.feature == "A" and parent.type != 'ADMD':
                criteria['feature'] = 'A'
                criteria['acode__startswith'] = acode[0:level * 4]
                criteria['acode__endswith'] = "AAAA" * (3 - level)
                del criteria['acode']
                City.objects.filter(**criteria).exclude(id=parent.id).update(parent_id=parent.id, level=level)
            # Sortie logging ou console
            if idx % output_every == 0 or idx == rows - 1:
                output_progress("Rebuilding {country}: {pc:>5.1f}% ({idx:>10}/{rows:>10})", idx, rows, output_every, {'country': country_name})
        # Calculer la latitude et longitude moyennes du pays
        extent = City.objects.filter(country=country, city=True).aggregate(bounds=Extent('position'))
        average_latitude = (extent['bounds'][1] + extent['bounds'][3]) / 2
        average_longitude = (extent['bounds'][0] + extent['bounds'][2]) / 2
        country.position = Point(average_longitude, average_latitude)
        country.updated = timezone.now()
        country.save()
        return True
    return False
 def get_feed_extent(self, obj):
     p = Route.objects.in_feed(obj).aggregate(Extent('geometry'))
     return p['geometry__extent']
Beispiel #4
0
def getfeature(request, service, wfs_version):
    context = {}
    propertyname = None
    featureversion = None
    maxfeatures = None
    typename = None
    featureid = None
    filtr = None
    bbox = None
    bbox_has_crs = False
    outputFormat = None
    resolution = None

    # A fallback value, if no features can be found
    crs = WGS84_CRS

    for key, value in request.GET.items():
        low_key = key.lower()
        low_value = value.lower()

        if low_key == "propertyname":
            propertyname = low_value

        elif low_key == "featureversion":
            featureversion = low_value

        elif low_key == "maxfeatures":
            try:
                maxfeatures = int(low_value)
            except:
                return wfs_exception(request, "InvalidParameterValue",
                                     "maxfeatures", value)
            else:
                if maxfeatures < 1:
                    return wfs_exception(request, "InvalidParameterValue",
                                         "maxfeatures", value)

        elif low_key == "typename":
            typename = low_value

        elif low_key == "featureid":
            featureid = low_value

        elif low_key == "filter":
            filtr = low_value

        elif low_key == "resolution":
            try:
                resolution = float(low_value)
            except:
                return wfs_exception(request, "InvalidParameterValue",
                                     "resolution", value)

        elif low_key == "bbox":
            #
            # See the following URL for all the gory details on the passed in bounding box:
            #
            # http://augusttown.blogspot.co.at/2010/08/mysterious-bbox-parameter-in-web.html
            bbox_values = low_value.split(",")

            if len(bbox_values) != 4 and (wfs_version == "1.0.0"
                                          or len(bbox_values) != 5):
                return wfs_exception(request, "InvalidParameterValue", "bbox",
                                     value)

            try:
                bbox_has_crs = len(bbox_values) == 5

                bbox_crs = CRS(bbox_values[4]) if bbox_has_crs else crs

                if bbox_crs.crsid == "CRS84":
                    # we and GeoDjango operate in longitude/latitude mode, so ban CRS84
                    bbox = Polygon.from_bbox(
                        (float(bbox_values[1]), float(bbox_values[0]),
                         float(bbox_values[3]), float(bbox_values[2])))
                    bbox_crs = WGS84_CRS
                else:
                    bbox = Polygon.from_bbox(
                        (float(bbox_values[0]), float(bbox_values[1]),
                         float(bbox_values[2]), float(bbox_values[3])))

                bbox.set_srid(bbox_crs.srid)
            except:
                return wfs_exception(request, "InvalidParameterValue",
                                     "maxfeatures", value)

        elif low_key == "srsname":
            try:
                crs = CRS(low_value)

                if crs.crsid == "CRS84":
                    # we and GeoDjango operate in longitude/latitude mode, so ban CRS84
                    crs = WGS84_CRS

            except:
                return wfs_exception(request, "InvalidParameterValue",
                                     "maxfeatures", value)

            # This is for the case, that srsname is hit after the bbox parameter above
            if bbox and not bbox_has_crs:
                bbox.set_srid(crs.srid)

        elif low_key == "filter":
            filtr = low_value

        elif low_key == "outputformat":

            if low_value in ALL_JSON_OUTPUT_FORMATS:
                outputFormat = JSON_OUTPUT_FORMAT
            elif low_value in ALL_XML_OUTPUT_FORMATS:
                outputFormat = XML_OUTPUT_FORMAT
            else:
                return wfs_exception(request, "InvalidParameterValue",
                                     "outputformat", value)

    if propertyname is not None:
        raise NotImplementedError

    if featureversion is not None:
        raise NotImplementedError

    if filtr is not None:
        raise NotImplementedError

    result_bbox = None

    # If FeatureID is present we return every feature on the list of ID's
    if featureid is not None:

        feature_list = []

        # we assume every feature is identified by its Featuretype name + its object ID like "name.id"
        for feature in featureid.split(","):
            try:
                ftname, fid = get_feature_from_parameter(feature)
            except ValueError:
                return wfs_exception(request, "InvalidParameterValue",
                                     "featureid", feature)
            try:
                ft = service.featuretype_set.get(name=ftname)
                ft_crs = CRS(ft.srs)
                try:
                    geom_field = ft.find_first_geometry_field()
                    if geom_field is None:
                        return wfs_exception(request, "NoGeometryField",
                                             "feature")

                    flter = json.loads(ft.query)
                    objs = ft.model.model_class().objects

                    if bbox:
                        bbox_args = {geom_field + "__bboverlaps": bbox}
                        objs = objs.filter(**bbox_args)

                    if crs.srid != ft_crs.srid:
                        objs = objs.annotate(
                            xform=Transform(geom_field, crs.srid))
                        geom_field = "xform"

                    if outputFormat == JSON_OUTPUT_FORMAT:
                        objs = objs.annotate(geojson=AsGeoJSON(geom_field))
                    else:
                        objs = objs.annotate(gml=AsGML(geom_field))

                    if flter:
                        objs = objs.filter(**flter)

                    f = objs.filter(id=fid)

                    bb_res = f.aggregate(Extent(geom_field))[geom_field +
                                                             '__extent']

                    if log.getEffectiveLevel() <= logging.DEBUG:
                        log.debug("Bounding box for feature [%s] is [%s]" %
                                  (feature, bb_res))

                    if result_bbox is None:
                        result_bbox = bb_res
                    else:
                        result_bbox = (min(result_bbox[0], bb_res[0]),
                                       min(result_bbox[1], bb_res[1]),
                                       max(result_bbox[2], bb_res[2]),
                                       max(result_bbox[3], bb_res[3]))

                    feature_list.append((ft, f[0]))
                except:
                    log.exception("caught exception in request [%s %s?%s]",
                                  request.method, request.path,
                                  request.environ['QUERY_STRING'])
                    return wfs_exception(request, "MalformedJSONQuery",
                                         "query")
            except FeatureType.DoesNotExist:
                return wfs_exception(request, "InvalidParameterValue",
                                     "featureid", feature)
    # If FeatureID isn't present we rely on TypeName and return every feature present it the requested FeatureTypes
    elif typename is not None:

        feature_list = type_feature_iter()

        for typen in typename.split(","):
            try:
                ft = service.featuretype_set.get(name__iexact=typen)
                ft_crs = CRS(ft.srs)
            except FeatureType.DoesNotExist:
                return wfs_exception(request, "InvalidParameterValue",
                                     "typename", typen)
            try:
                geom_field = ft.find_first_geometry_field()
                if geom_field is None:
                    return wfs_exception(request, "NoGeometryField", "feature")

                flter = json.loads(ft.query)

                objs = ft.model.model_class().objects

                if bbox:
                    bbox_args = {geom_field + "__bboverlaps": bbox}
                    objs = objs.filter(**bbox_args)

                if crs.srid != ft_crs.srid:
                    objs = objs.annotate(xform=Transform(geom_field, crs.srid))
                    geom_field = "xform"

                if outputFormat == JSON_OUTPUT_FORMAT:
                    objs = objs.annotate(geojson=AsGeoJSON(geom_field))
                else:
                    objs = objs.annotate(gml=AsGML(geom_field))

                if flter:
                    objs = objs.filter(**flter)

                if resolution is not None:

                    res_flter = ft.resolutionfilter_set.filter(
                        min_resolution__lte=resolution).order_by(
                            "-min_resolution").first()

                    if res_flter:
                        log.debug(
                            "Applying extra filter [%s] with condition [%s] for resolution [%f]"
                            % (res_flter, res_flter.query, resolution))
                        res_flter_parsed = json.loads(res_flter.query)
                        objs = objs.filter(**res_flter_parsed)

                bb_res = objs.aggregate(Extent(geom_field))[geom_field +
                                                            '__extent']

                if log.getEffectiveLevel() <= logging.DEBUG:
                    log.debug("Bounding box for feature type [%s] is [%s]" %
                              (typen, bb_res))

                if result_bbox is None:
                    result_bbox = bb_res
                else:
                    result_bbox = (min(result_bbox[0], bb_res[0]),
                                   min(result_bbox[1], bb_res[1]),
                                   max(result_bbox[2], bb_res[2]),
                                   max(result_bbox[3], bb_res[3]))

                feature_list.add_type_with_features(ft, objs)

            except:
                log.exception("caught exception in request [%s %s?%s]",
                              request.method, request.path,
                              request.environ['QUERY_STRING'])
                return wfs_exception(request, "MalformedJSONQuery", "query")
    else:
        return wfs_exception(request, "MissingParameter", "typename")

    if outputFormat == JSON_OUTPUT_FORMAT:

        return StreamingHttpResponse(streaming_content=GeoJsonIterator(
            service.id, crs, result_bbox, feature_list),
                                     content_type="application/json")

    else:
        context['features'] = feature_list
        if result_bbox:
            context['bbox0'] = result_bbox[0]
            context['bbox1'] = result_bbox[1]
            context['bbox2'] = result_bbox[2]
            context['bbox3'] = result_bbox[3]
        context['crs'] = crs
        context['version'] = wfs_version
        context[
            'wfs_path'] = "1.0.0/WFS-basic.xsd" if wfs_version == "1.0.0" else "1.1.0/wfs.xsd"
        return render(request,
                      'getFeature.xml',
                      context,
                      content_type="text/xml")
Beispiel #5
0
    def get(request, selection):

        simple_queries = {
            'variables': 'variable__name__in',
            'institution': 'nmpersonsentries__person__organisation_name__in',
            'project': 'nmentrygroups__group__type__name__in'
        }

        filter_dict = {}
        fair_query = Q(embargo=True) & Q(embargo_end__gte=timezone.now())

        for i in QueryDict(selection):
            if i in simple_queries:
                filter_dict[simple_queries[i]] = QueryDict(selection).getlist(
                    i)
            elif i == 'date':
                filter_dict['datasource__temporal_scale__observation_end__gte'] = \
                    make_aware(datetime.datetime.strptime(QueryDict(selection).getlist('date')[0], "%Y-%m-%d"))
                filter_dict['datasource__temporal_scale__observation_start__lte'] = \
                    make_aware(datetime.datetime.strptime(QueryDict(selection).getlist('date')[1], "%Y-%m-%d"))
            # elif i == 'is_FAIR' and QueryDict(selection).getlist(i) == ['true']:
            #     fair_query = Q(embargo=True) & Q(embargo_end__gte=timezone.now())
            elif i == 'is_FAIR' and QueryDict(selection).getlist(i) == [
                    'false'
            ]:
                # TODO: figure out how to avoid the following useless query
                #  (this exists because in exclude query is always some input needed)
                fair_query = Q(embargo=True) & Q(embargo=False)
            elif i == 'draw':
                values = QueryDict(selection).getlist(i)[0]
                it = iter([float(item) for item in values.split(',')])
                poly = Polygon(tuple(zip(it, it)), srid=4326)
                filter_dict['location__intersects'] = poly

        query = Entries.objects.filter(
            **filter_dict).exclude(fair_query).only('id')
        total_results = query.count()

        # From here collect data to update map:
        data_ext = [7.574234, 47.581351, 10.351323,
                    49.625873]  # an arbitrarily zoom location for NO RESULT
        if query:
            data_ext = list(
                query.aggregate(Extent('location'))['location__extent'])

        IDs = list(query.values_list('id', flat=True))
        id_layer = 'ID_layer' + str(request.user)
        if get_layer(id_layer, HomeView.store, HomeView.workspace):
            delete_layer(id_layer, HomeView.store, HomeView.workspace)

        if IDs:
            create_layer(request, id_layer, HomeView.store, HomeView.workspace,
                         str(IDs)[1:-1])
        else:
            # TODO: Selection with no result has to be handled properly
            pass

        return JsonResponse({
            'selection': selection,
            'total': total_results,
            'ID_layer': id_layer,
            'dataExt': data_ext,
            'IDs': IDs
        })
Beispiel #6
0
 def get_extent(self, srid=3857):
     return self.features.annotate(
         geom_transformed=Transform('geom', srid)
     ).aggregate(
         extent=Extent('geom_transformed')
     )
Beispiel #7
0
def getfeature(request, service, wfs_version):
    context = {}
    propertyname = None
    featureversion = None
    maxfeatures = None
    typename = None
    featureid = None
    filtr = None
    bbox = None
    bbox_has_crs = False
    outputFormat = None
    resolution = None
    precision = None

    # A fallback value, if no features can be found
    crs = WGS84_CRS

    for key, value in request.GET.items():
        low_key = key.lower()
        low_value = value.lower()

        if low_key == "propertyname":
            propertyname = low_value

        elif low_key == "featureversion":
            featureversion = low_value

        elif low_key == "maxfeatures":
            try:
                maxfeatures = int(low_value)
            except:
                return wfs_exception(request, "InvalidParameterValue",
                                     "maxfeatures", value)
            else:
                if maxfeatures < 1:
                    return wfs_exception(request, "InvalidParameterValue",
                                         "maxfeatures", value)

        elif low_key == "typename":
            typename = low_value

        elif low_key == "featureid":
            featureid = low_value

        elif low_key == "filter":
            filtr = low_value

        elif low_key == "resolution":
            try:
                resolution = float(low_value)
            except:
                return wfs_exception(request, "InvalidParameterValue",
                                     "resolution", value)

        elif low_key == "precision":
            try:
                precision = float(low_value)
            except:
                return wfs_exception(request, "InvalidParameterValue",
                                     "precision", value)

        elif low_key == "bbox":
            #
            # See the following URL for all the gory details on the passed in bounding box:
            #
            # http://augusttown.blogspot.co.at/2010/08/mysterious-bbox-parameter-in-web.html
            bbox_values = low_value.split(",")

            if len(bbox_values) != 4 and (wfs_version == "1.0.0"
                                          or len(bbox_values) != 5):
                return wfs_exception(request, "InvalidParameterValue", "bbox",
                                     value)

            try:
                bbox_has_crs = len(bbox_values) == 5

                bbox_crs = CRS(bbox_values[4]) if bbox_has_crs else crs

                if bbox_crs.crsid == "CRS84":
                    # we and GeoDjango operate in longitude/latitude mode, so ban CRS84
                    bbox = Polygon.from_bbox(
                        (float(bbox_values[1]), float(bbox_values[0]),
                         float(bbox_values[3]), float(bbox_values[2])))
                    bbox_crs = WGS84_CRS
                else:
                    bbox = Polygon.from_bbox(
                        (float(bbox_values[0]), float(bbox_values[1]),
                         float(bbox_values[2]), float(bbox_values[3])))

                bbox.set_srid(bbox_crs.srid)
            except:
                return wfs_exception(request, "InvalidParameterValue", "bbox",
                                     value)

        elif low_key == "srsname":
            try:
                crs = CRS(low_value)

                if crs.crsid == "CRS84":
                    # we and GeoDjango operate in longitude/latitude mode, so ban CRS84
                    crs = WGS84_CRS

            except:
                return wfs_exception(request, "InvalidParameterValue",
                                     "maxfeatures", value)

            # This is for the case, that srsname is hit after the bbox parameter above
            if bbox and not bbox_has_crs:
                bbox.set_srid(crs.srid)

        elif low_key == "filter":
            filtr = low_value

        elif low_key == "outputformat":

            if low_value in ALL_JSON_OUTPUT_FORMATS:
                outputFormat = JSON_OUTPUT_FORMAT
            elif low_value in ALL_XML_OUTPUT_FORMATS:
                outputFormat = XML_OUTPUT_FORMAT
            else:
                return wfs_exception(request, "InvalidParameterValue",
                                     "outputformat", value)

    if propertyname is not None:
        raise NotImplementedError

    if featureversion is not None:
        raise NotImplementedError

    if filtr is not None:
        raise NotImplementedError

    result_bbox = None

    closeable = None

    try:

        # If FeatureID is present we return every feature on the list of ID's
        if featureid is not None:

            feature_list = []

            # we assume every feature is identified by its Featuretype name + its object ID like "name.id"
            for feature in featureid.split(","):
                try:
                    ftname, fid = get_feature_from_parameter(feature)
                except ValueError:
                    return wfs_exception(request, "InvalidParameterValue",
                                         "featureid", feature)
                try:
                    ft = service.featuretype_set.get(name=ftname)
                    ft_crs = CRS(ft.srs)
                    try:

                        if ft.model is None:

                            # GML output of raw results not yet implemented
                            if outputFormat != JSON_OUTPUT_FORMAT:
                                raise NotImplementedError

                            # prepare SQL statement
                            select = parse_single(
                                preprocess_query(ft.query, resolution,
                                                 precision, bbox))
                            identifiers = get_identifiers(select)
                            shape = find_identifier(identifiers, "shape")
                            idi = find_identifier(identifiers, "id")

                            # replace shape by ST_Simplify(shape,%s)
                            if precision is not None:
                                simplified = build_function_call(
                                    "ST_Simplify", shape, 1, True)
                                replace_identifier(identifiers, shape,
                                                   simplified)

                            # add restriction id=%s
                            add_condition(select, build_comparison(idi, "="))

                            sql = str(select)

                            if log.getEffectiveLevel() <= logging.DEBUG:
                                log.debug(
                                    "Final SQL for feature [%s] is [%s]" %
                                    (feature, sql))

                            # raw SQL result set
                            with connection.cursor() as cur:

                                if precision is None:
                                    cur.execute(sql, (fid, ))
                                else:
                                    cur.execute(sql, (precision, fid))

                                row = cur.fetchone()

                                feature = RawFeature(cur.description, row,
                                                     crs.srid)

                                if feature.geometry is None:
                                    return wfs_exception(
                                        request, "NoGeometryField", "feature")

                                feature_list.append((ft, feature))
                        else:
                            # django model based result set.
                            geom_field = ft.find_first_geometry_field()
                            if geom_field is None:
                                return wfs_exception(request,
                                                     "NoGeometryField",
                                                     "feature")

                            flter = parse_query(ft.query)
                            objs = ft.model.model_class().objects

                            if flter:
                                objs = objs.filter(**flter)

                            if bbox:
                                bbox_args = {geom_field + "__bboverlaps": bbox}
                                objs = objs.filter(**bbox_args)

                            objs = objs.filter(id=fid)

                            if crs.srid != ft_crs.srid:
                                objs = objs.annotate(
                                    xform=Transform(geom_field, crs.srid))
                                geom_field = "xform"

                            bb_res = objs.aggregate(
                                Extent(geom_field))[geom_field + '__extent']

                            if log.getEffectiveLevel() <= logging.DEBUG:
                                log.debug(
                                    "Bounding box for feature [%s] is [%s]" %
                                    (feature, bb_res))

                            if result_bbox is None:
                                result_bbox = bb_res
                            else:
                                result_bbox = (min(result_bbox[0], bb_res[0]),
                                               min(result_bbox[1], bb_res[1]),
                                               max(result_bbox[2], bb_res[2]),
                                               max(result_bbox[3], bb_res[3]))

                            if outputFormat == XML_OUTPUT_FORMAT:
                                objs = objs.annotate(gml=AsGML(geom_field))

                            f = objs.first()

                            if f is None:
                                log.warning("Feature with ID [%s] not found." %
                                            feature)
                            else:
                                if outputFormat == JSON_OUTPUT_FORMAT:
                                    feature_list.append(
                                        (ft,
                                         DjangoFeature(ft, objs[0],
                                                       precision)))
                                else:
                                    feature_list.append((ft, objs[0]))

                    except:
                        log.exception("caught exception in request [%s %s?%s]",
                                      request.method, request.path,
                                      request.environ['QUERY_STRING'])
                        return wfs_exception(request, "MalformedJSONQuery",
                                             "query")
                except FeatureType.DoesNotExist:
                    return wfs_exception(request, "InvalidParameterValue",
                                         "featureid", feature)
        # If FeatureID isn't present we rely on TypeName and return every feature present it the requested FeatureTypes
        elif typename is not None:

            feature_list = type_feature_iter(
                outputFormat != JSON_OUTPUT_FORMAT, crs.srid, precision)
            closeable = feature_list

            for typen in typename.split(","):
                try:
                    ft = service.featuretype_set.get(name__iexact=typen)
                    ft_crs = CRS(ft.srs)
                except FeatureType.DoesNotExist:
                    return wfs_exception(request, "InvalidParameterValue",
                                         "typename", typen)

                if ft.model is None:

                    # raw SQL result set

                    # GML output of raw results not yet implemented
                    if outputFormat != JSON_OUTPUT_FORMAT:
                        raise NotImplementedError

                    # prepare SQL statement
                    select = parse_single(
                        preprocess_query(ft.query, resolution, precision,
                                         bbox))
                    identifiers = get_identifiers(select)
                    shape = find_identifier(identifiers, "shape")
                    idi = find_identifier(identifiers, "id")

                    # parameters of SQL query
                    params = []

                    # replace shape by ST_Simplify(shape,%s)
                    if precision is not None:
                        simplified = build_function_call(
                            "ST_Simplify", shape, 1, True)
                        replace_identifier(identifiers, shape, simplified)
                        params.append(precision)

                    if resolution is not None:

                        res_flter = ft.resolutionfilter_set.filter(
                            min_resolution__lte=resolution).order_by(
                                "-min_resolution").first()

                        if res_flter:
                            if log.getEffectiveLevel() <= logging.DEBUG:
                                log.debug(
                                    "Applying extra filter [%s] with condition [%s] for resolution [%f]"
                                    % (res_flter, res_flter.query, resolution))

                            res_flter_parsed = parse_single(res_flter.query)

                            add_condition(select, res_flter_parsed)

                    if bbox is not None:

                        if ft.fields:
                            if ft.fields != "{nobbox}":
                                add_condition(
                                    select,
                                    build_function_call(
                                        "ST_Intersects", ft.fields, 1))
                        else:
                            add_condition(
                                select,
                                build_function_call("ST_Intersects", shape, 1))

                        params.append(bbox.hexewkb.decode("utf-8"))

                    sql = str(select)

                    if log.getEffectiveLevel() <= logging.DEBUG:
                        log.debug("Final SQL for feature [%s] is [%s]" %
                                  (ft.name, sql))

                    cur = connection.cursor()

                    try:
                        cur.execute(sql, params)

                        has_geometry = False

                        for colinfo in cur.description:
                            if _is_geom_column(colinfo):
                                has_geometry = True
                                break

                        if not has_geometry:
                            return wfs_exception(request, "NoGeometryField",
                                                 "feature")

                        feature_list.add_type_with_features(ft, cur)

                    except:
                        cur.close()
                        log.exception("caught exception in request [%s %s?%s]",
                                      request.method, request.path,
                                      request.environ['QUERY_STRING'])
                        return wfs_exception(request, "MalformedJSONQuery",
                                             "query")

                else:
                    try:
                        geom_field = ft.find_first_geometry_field()
                        if geom_field is None:
                            return wfs_exception(request, "NoGeometryField",
                                                 "feature")

                        flter = parse_query(ft.query)

                        objs = ft.model.model_class().objects

                        if flter:
                            objs = objs.filter(**flter)

                        if resolution is not None:

                            res_flter = ft.resolutionfilter_set.filter(
                                min_resolution__lte=resolution).order_by(
                                    "-min_resolution").first()

                            if res_flter:
                                log.debug(
                                    "Applying extra filter [%s] with condition [%s] for resolution [%f]"
                                    % (res_flter, res_flter.query, resolution))
                                res_flter_parsed = parse_query(res_flter.query)
                                objs = objs.filter(**res_flter_parsed)

                        if bbox:
                            bbox_args = {geom_field + "__bboverlaps": bbox}
                            objs = objs.filter(**bbox_args)

                        if crs.srid != ft_crs.srid:
                            objs = objs.annotate(
                                xform=Transform(geom_field, crs.srid))
                            geom_field = "xform"

                        bb_res = objs.aggregate(
                            Extent(geom_field))[geom_field + '__extent']

                        if log.getEffectiveLevel() <= logging.DEBUG:
                            log.debug(
                                "Bounding box for feature type [%s] is [%s]" %
                                (typen, bb_res))

                        if result_bbox is None:
                            result_bbox = bb_res
                        else:
                            result_bbox = (min(result_bbox[0], bb_res[0]),
                                           min(result_bbox[1], bb_res[1]),
                                           max(result_bbox[2], bb_res[2]),
                                           max(result_bbox[3], bb_res[3]))

                        if outputFormat == XML_OUTPUT_FORMAT:
                            objs = objs.annotate(gml=AsGML(geom_field))

                        feature_list.add_type_with_features(ft, objs)

                    except:
                        log.exception("caught exception in request [%s %s?%s]",
                                      request.method, request.path,
                                      request.environ['QUERY_STRING'])
                        return wfs_exception(request, "MalformedJSONQuery",
                                             "query")
        else:
            return wfs_exception(request, "MissingParameter", "typename")

        if outputFormat == JSON_OUTPUT_FORMAT:

            ret = StreamingHttpResponse(streaming_content=GeoJsonIterator(
                service.id, crs, result_bbox, feature_list),
                                        content_type="application/json")

        else:
            context['features'] = feature_list
            if result_bbox:
                context['bbox0'] = result_bbox[0]
                context['bbox1'] = result_bbox[1]
                context['bbox2'] = result_bbox[2]
                context['bbox3'] = result_bbox[3]
            context['crs'] = crs
            context['version'] = wfs_version
            context[
                'wfs_path'] = "1.0.0/WFS-basic.xsd" if wfs_version == "1.0.0" else "1.1.0/wfs.xsd"
            ret = render(request,
                         'getFeature.xml',
                         context,
                         content_type="text/xml")

        # Now, closing of resources is delegated to the HTTP response
        closeable = None
        return ret

    finally:
        if closeable is not None:
            try:
                closeable.close()
            except:
                log.exception(
                    "Error closing left-over SQL cursor in WFS service.")