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'])
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']
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")
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 })
def get_extent(self, srid=3857): return self.features.annotate( geom_transformed=Transform('geom', srid) ).aggregate( extent=Extent('geom_transformed') )
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.")