Source code for qsrlib_qsrs.qsr_ra

# -*- coding: utf-8 -*-
from __future__ import print_function, division
from numpy import isnan
from qsrlib_qsrs.qsr_dyadic_abstractclass import QSR_Dyadic_1t_Abstractclass


[docs]class QSR_RA(QSR_Dyadic_1t_Abstractclass): """Rectangle Algebra. Members: * _unique_id: "ra" * _all_possible_relations: ("<", ">", "m", "mi", "o", "oi", "s", "si", "d", "di", "f", "fi", "=") * _dtype: "bounding_boxes" .. seealso:: For further details about RA, refer to its :doc:`description. <../handwritten/qsrs/ra>` """ _unique_id = "ra" """str: Unique identifier name of the QSR.""" _all_possible_relations = ("<", ">", "m", "mi", "o", "oi", "s", "si", "d", "di", "f", "fi", "=") """tuple: All possible relations of the QSR.""" _dtype = "bounding_boxes" """str: On what kind of data the QSR works with.""" _inverse_map = {"<": ">", "m": "mi", "o": "oi", "s": "si", "d": "di", "f": "fi", ">": "<", "mi": "m", "o1": "o", "si": "s", "di": "d", "fi": "f"} """dict: Inverse relations""" def __init__(self): """Constructor. :return: """ super(QSR_RA, self).__init__() def _compute_qsr(self, bb1, bb2, qsr_params, **kwargs): """Compute QSR value. :param bb1: First object's bounding box. :type bb2: tuple or list :param bb2: Second object's bounding box. :type bb2: tuple or list :param qsr_params: QSR specific parameters passed in `dynamic_args`. :type qsr_params: dict :param kwargs: Optional further arguments. :return: The computed QSR value: two/three comma separated Allen relations for 2D/3D. :rtype: str """ if len(bb1) == 4 and len(bb2) == 4: # 2D version return ",".join([self.__allen((bb1[0], bb1[2]), (bb2[0], bb2[2])), self.__allen((bb1[1], bb1[3]), (bb2[1], bb2[3]))]) elif len(bb1) == 6 and len(bb2) == 6: # 3D version return ",".join([self.__allen((bb1[0], bb1[3]), (bb2[0], bb2[3])), self.__allen((bb1[1], bb1[4]), (bb2[1], bb2[4])), self.__allen((bb1[2], bb1[5]), (bb2[2], bb2[5]))]) else: raise ValueError("bb1 and bb2 must have length of 4 (2D) or 6 (3D)") def __allen(self, i1, i2): if isnan(i1).any() or isnan(i2).any(): # nan values cause dragons raise ValueError("illegal 'nan' values found") if i1[1] < i2[0]: return "<" if i1[1] == i2[0]: return "m" if i1[0] < i2[0] < i1[1] and i2[0] < i1[1] < i2[1]: return "o" if i1[0] == i2[0] and i1[1] < i2[1]: return "s" if i2[0] < i1[0] < i2[1] and i2[0] < i1[1] < i2[1]: return "d" if i2[0] < i1[0] < i2[1] and i1[1] == i2[1]: return "f" if i1[0] == i2[0] and i1[1] == i2[1]: return "=" return self._inverse_map[self.__allen(i2, i1)]