def matches(self, eo_object, containment="overlaps"): if not len(self): return True bbox = [None, None, None, None] srid = self.srid if srid is None: srid = 4326 max_extent = crss.crs_bounds(srid) tolerance = crss.crs_tolerance(srid) footprint = eo_object.footprint begin_time = eo_object.begin_time end_time = eo_object.end_time for subset in self: if isinstance(subset, Slice): is_slice = True value = subset.value elif isinstance(subset, Trim): is_slice = False low = subset.low high = subset.high if subset.is_temporal: if is_slice: if begin_time > value or end_time < value: return False elif low is None and high is not None: if begin_time > high: return False elif low is not None and high is None: if end_time < low: return False else: if begin_time > high or end_time < low: return False else: if is_slice: if subset.is_x: line = Line( (value, max_extent[1]), (value, max_extent[3]) ) else: line = Line( (max_extent[0], value), (max_extent[2], value) ) line.srid = srid if srid != 4326: line.transform(4326) if not line.intersects(footprint): return False else: if subset.is_x: bbox[0] = subset.low bbox[2] = subset.high else: bbox[1] = subset.low bbox[3] = subset.high if bbox != [None, None, None, None]: bbox = map( lambda v: v[0] if v[0] is not None else v[1], zip(bbox, max_extent) ) bbox[0] -= tolerance; bbox[1] -= tolerance bbox[2] += tolerance; bbox[3] += tolerance logger.debug( "Applying BBox %s with containment '%s'." % (bbox, containment) ) poly = Polygon.from_bbox(bbox) poly.srid = srid if srid != 4326: poly.transform(4326) if containment == "overlaps": if not footprint.intersects(poly): return False elif containment == "contains": if not footprint.within(poly): return False return True
def filter(self, queryset, containment="overlaps"): if not len(self): return queryset qs = queryset bbox = [None, None, None, None] srid = self.srid if srid is None: srid = 4326 max_extent = crss.crs_bounds(srid) tolerance = crss.crs_tolerance(srid) for subset in self: if isinstance(subset, Slice): is_slice = True value = subset.value elif isinstance(subset, Trim): is_slice = False low = subset.low high = subset.high if subset.is_temporal: if is_slice: qs = qs.filter( begin_time__lte=value, end_time__gte=value ) else: if high is not None: qs = qs.filter( begin_time__lte=high ) if low is not None: qs = qs.filter( end_time__gte=low ) # check if the temporal bounds must be strictly contained if containment == "contains": if high is not None: qs = qs.filter( end_time__lte=high ) if low is not None: qs = qs.filter( begin_time__gte=low ) else: if is_slice: if subset.is_x: line = LineString( (value, max_extent[1]), (value, max_extent[3]) ) else: line = LineString( (max_extent[0], value), (max_extent[2], value) ) line.srid = srid if srid != 4326: line.transform(4326) qs = qs.filter(footprint__intersects=line) else: if subset.is_x: bbox[0] = subset.low bbox[2] = subset.high else: bbox[1] = subset.low bbox[3] = subset.high if bbox != [None, None, None, None]: bbox = map( lambda v: v[0] if v[0] is not None else v[1], zip(bbox, max_extent) ) bbox[0] -= tolerance; bbox[1] -= tolerance bbox[2] += tolerance; bbox[3] += tolerance logger.debug( "Applying BBox %s with containment '%s'." % (bbox, containment) ) poly = Polygon.from_bbox(bbox) poly.srid = srid if srid != 4326: poly.transform(4326) if containment == "overlaps": qs = qs.filter(footprint__intersects=poly) elif containment == "contains": qs = qs.filter(footprint__within=poly) return qs
def matches(self, eo_object, containment="overlaps"): """ Check if the given :class:`EOObject <eoxserver.resources.coverages.models.EOObject>` matches the given subsets. :param eo_object: the ``EOObject`` to match :param containment: either "overlaps" or "contains" :returns: a boolean value indicating if the object is contained in the given subsets """ if not len(self): return True bbox = [None, None, None, None] srid = self.srid if srid is None: srid = 4326 max_extent = crss.crs_bounds(srid) tolerance = crss.crs_tolerance(srid) # check if time intervals are configured as "open" or "closed" config = get_eoxserver_config() reader = SubsetConfigReader(config) # note that the operator is inverted from filter() above as the # filters use an inclusive search whereas here it's exclusive if reader.time_interval_interpretation == "closed": gt_op = operator.gt lt_op = operator.lt else: gt_op = operator.ge lt_op = operator.le footprint = eo_object.footprint begin_time = eo_object.begin_time end_time = eo_object.end_time for subset in self: if isinstance(subset, Slice): is_slice = True value = subset.value elif isinstance(subset, Trim): is_slice = False low = subset.low high = subset.high # we need the value in case low == high value = low if subset.is_temporal: if is_slice or (low == high and containment == "overlaps"): if begin_time > value or end_time < value: return False elif low == high: if begin_time < value or end_time > value: return False else: # check if the temporal bounds must be strictly contained if containment == "contains": if high is not None: if gt_op(end_time, high): return False if low is not None: if lt_op(begin_time, low): return False # or just overlapping else: if high is not None: if gt_op(begin_time, high): return False if low is not None: if lt_op(end_time, low): return False else: if is_slice: if subset.is_x: line = LineString( (value, max_extent[1]), (value, max_extent[3]) ) else: line = LineString( (max_extent[0], value), (max_extent[2], value) ) line.srid = srid if srid != 4326: line.transform(4326) if not line.intersects(footprint): return False else: if subset.is_x: bbox[0] = subset.low bbox[2] = subset.high else: bbox[1] = subset.low bbox[3] = subset.high if bbox != [None, None, None, None]: bbox = map( lambda v: v[0] if v[0] is not None else v[1], zip(bbox, max_extent) ) bbox[0] -= tolerance bbox[1] -= tolerance bbox[2] += tolerance bbox[3] += tolerance logger.debug( "Applying BBox %s with containment '%s'." % (bbox, containment) ) poly = Polygon.from_bbox(bbox) poly.srid = srid if srid != 4326: poly.transform(4326) if containment == "overlaps": if not footprint.intersects(poly): return False elif containment == "contains": if not footprint.within(poly): return False return True
def get_filters(self, containment="overlaps"): """ Filter a :class:`Django QuerySet <django.db.models.query.QuerySet>` of objects inheriting from :class:`EOObject <eoxserver.resources.coverages.models.EOObject>`. :param queryset: the ``QuerySet`` to filter :param containment: either "overlaps" or "contains" :returns: a ``dict`` with the filters """ filters = {} if not len(self): return filters bbox = [None, None, None, None] srid = self.srid if srid is None: srid = 4326 max_extent = crss.crs_bounds(srid) tolerance = crss.crs_tolerance(srid) # check if time intervals are configured as "open" or "closed" config = get_eoxserver_config() reader = SubsetConfigReader(config) if reader.time_interval_interpretation == "closed": gt_op = "__gte" lt_op = "__lte" else: gt_op = "__gt" lt_op = "__lt" for subset in self: if isinstance(subset, Slice): is_slice = True value = subset.value elif isinstance(subset, Trim): is_slice = False low = subset.low high = subset.high # we need the value in case low == high value = low if subset.is_temporal: if is_slice or (high == low and containment == "overlaps"): filters['begin_time__lte'] = value filters['end_time__gte'] = value elif high == low: filters['begin_time__gte'] = value filters['end_time__lte'] = value else: # check if the temporal bounds must be strictly contained if containment == "contains": if high is not None: filters['end_time' + lt_op] = high if low is not None: filters['begin_time' + gt_op] = low # or just overlapping else: if high is not None: filters['begin_time' + lt_op] = high if low is not None: filters['end_time' + gt_op] = low else: if is_slice: if subset.is_x: line = LineString( (value, max_extent[1]), (value, max_extent[3]) ) else: line = LineString( (max_extent[0], value), (max_extent[2], value) ) line.srid = srid if srid != 4326: line.transform(4326) filters['footprint__intersects'] = line else: if subset.is_x: bbox[0] = subset.low bbox[2] = subset.high else: bbox[1] = subset.low bbox[3] = subset.high if bbox != [None, None, None, None]: bbox = list(map( lambda v: v[0] if v[0] is not None else v[1], zip(bbox, max_extent) )) bbox[0] -= tolerance bbox[1] -= tolerance bbox[2] += tolerance bbox[3] += tolerance logger.debug( "Applying BBox %s with containment '%s'." % (bbox, containment) ) poly = Polygon.from_bbox(bbox) poly.srid = srid if srid != 4326: poly.transform(4326) if containment == "overlaps": filters['footprint__intersects'] = poly elif containment == "contains": filters['footprint__within'] = poly return filters
def filter(self, queryset, containment="overlaps"): """ Filter a :class:`Django QuerySet <django.db.models.query.QuerySet>` of objects inheriting from :class:`EOObject <eoxserver.resources.coverages.models.EOObject>`. :param queryset: the ``QuerySet`` to filter :param containment: either "overlaps" or "contains" :returns: a ``QuerySet`` with additional filters applied """ if not len(self): return queryset qs = queryset bbox = [None, None, None, None] srid = self.srid if srid is None: srid = 4326 max_extent = crss.crs_bounds(srid) tolerance = crss.crs_tolerance(srid) # check if time intervals are configured as "open" or "closed" config = get_eoxserver_config() reader = SubsetConfigReader(config) if reader.time_interval_interpretation == "closed": gt_op = "__gte" lt_op = "__lte" else: gt_op = "__gt" lt_op = "__lt" for subset in self: if isinstance(subset, Slice): is_slice = True value = subset.value elif isinstance(subset, Trim): is_slice = False low = subset.low high = subset.high # we need the value in case low == high value = low if subset.is_temporal: if is_slice or (high == low and containment == "overlaps"): qs = qs.filter( begin_time__lte=value, end_time__gte=value ) elif high == low: qs = qs.filter( begin_time__gte=value, end_time__lte=value ) else: # check if the temporal bounds must be strictly contained if containment == "contains": if high is not None: qs = qs.filter(**{ "end_time" + lt_op: high }) if low is not None: qs = qs.filter(**{ "begin_time" + gt_op: low }) # or just overlapping else: if high is not None: qs = qs.filter(**{ "begin_time" + lt_op: high }) if low is not None: qs = qs.filter(**{ "end_time" + gt_op: low }) else: if is_slice: if subset.is_x: line = LineString( (value, max_extent[1]), (value, max_extent[3]) ) else: line = LineString( (max_extent[0], value), (max_extent[2], value) ) line.srid = srid if srid != 4326: line.transform(4326) qs = qs.filter(footprint__intersects=line) else: if subset.is_x: bbox[0] = subset.low bbox[2] = subset.high else: bbox[1] = subset.low bbox[3] = subset.high if bbox != [None, None, None, None]: bbox = map( lambda v: v[0] if v[0] is not None else v[1], zip(bbox, max_extent) ) bbox[0] -= tolerance bbox[1] -= tolerance bbox[2] += tolerance bbox[3] += tolerance logger.debug( "Applying BBox %s with containment '%s'." % (bbox, containment) ) poly = Polygon.from_bbox(bbox) poly.srid = srid if srid != 4326: poly.transform(4326) if containment == "overlaps": qs = qs.filter(footprint__intersects=poly) elif containment == "contains": qs = qs.filter(footprint__within=poly) return qs