def __eq__(self, other, rtol=1.0e-5, atol=1.0e-8): """Override '==' to allow comparison with other vector objecs Args: * other: Vector instance to compare to * rtol, atol: Relative and absolute tolerance. See numpy.allclose for details Note: The algorithm will try to falsify every aspect of equality for the two layers such as data, geometry, projection, keywords etc. Only if none of them can be falsified will it return True. """ # Check type if not isinstance(other, Vector): msg = ('Vector instance cannot be compared to %s' ' as its type is %s ' % (str(other), type(other))) raise TypeError(msg) # Check keywords if self.keywords != other.keywords: return False # Check number of features match if len(self) != len(other): return False # Check projection if self.projection != other.projection: return False # Check geometry type if self.geometry_type != other.geometry_type: return False # Check geometry if self.is_polygon_data: geom0 = self.get_geometry(as_geometry_objects=True) geom1 = other.get_geometry(as_geometry_objects=True) else: geom0 = self.get_geometry() geom1 = other.get_geometry() if len(geom0) != len(geom1): return False if self.is_point_data: if not numpy.allclose(geom0, geom1, rtol=rtol, atol=atol): return False elif self.is_line_data: # Check vertices of each line for i in range(len(geom0)): if not rings_equal(geom0[i], geom1[i], rtol=rtol, atol=atol): return False elif self.is_polygon_data: # Check vertices of outer and inner rings for i in range(len(geom0)): x = geom0[i].outer_ring y = geom1[i].outer_ring if not rings_equal(x, y, rtol=rtol, atol=atol): return False for j, ring0 in enumerate(geom0[i].inner_rings): ring1 = geom1[i].inner_rings[j] if not rings_equal(ring0, ring1, rtol=rtol, atol=atol): return False else: msg = ('== not implemented for geometry type: %s' % self.geometry_type) raise InaSAFEError(msg) # Check keys for attribute values x = self.get_data() y = other.get_data() if x is None: if y is not None: return False else: for key in x[0]: for i in range(len(y)): if key not in y[i]: return False for key in y[0]: for i in range(len(x)): if key not in x[i]: return False # Check attribute values for i, a in enumerate(x): for key in a: X = a[key] Y = y[i][key] if X != Y: # Not obviously equal, try some special cases try: # Try numerical comparison with tolerances res = numpy.allclose(X, Y, rtol=rtol, atol=atol) except (NotImplementedError, TypeError): # E.g. '' (Not implemented) # or None or {} (Type error) pass else: if not res: return False # Finally cast as booleans. # This will e.g. match False with None or '' if not (bool(X) is bool(Y)): return False # Vector layers are identical up to the specified tolerance return True
def __eq__(self, other, rtol=1.0e-5, atol=1.0e-8): """Override '==' to allow comparison with other vector objecs Args: * other: Vector instance to compare to * rtol, atol: Relative and absolute tolerance. See numpy.allclose for details Note: The algorithm will try to falsify every aspect of equality for the two layers such as data, geometry, projection, keywords etc. Only if none of them can be falsified will it return True. """ # Check type if not isinstance(other, Vector): msg = ('Vector instance cannot be compared to %s' ' as its type is %s ' % (str(other), type(other))) raise TypeError(msg) # Check keywords if self.keywords != other.keywords: return False # Check number of features match if len(self) != len(other): return False # Check projection if self.projection != other.projection: return False # Check geometry type if self.geometry_type != other.geometry_type: return False # Check geometry if self.is_polygon_data: geom0 = self.get_geometry(as_geometry_objects=True) geom1 = other.get_geometry(as_geometry_objects=True) else: geom0 = self.get_geometry() geom1 = other.get_geometry() if len(geom0) != len(geom1): return False if self.is_point_data: if not numpy.allclose(geom0, geom1, rtol=rtol, atol=atol): return False elif self.is_line_data: # Check vertices of each line for i in range(len(geom0)): if not rings_equal(geom0[i], geom1[i], rtol=rtol, atol=atol): return False elif self.is_polygon_data: # Check vertices of outer and inner rings for i in range(len(geom0)): x = geom0[i].outer_ring y = geom1[i].outer_ring if not rings_equal(x, y, rtol=rtol, atol=atol): return False for j, ring0 in enumerate(geom0[i].inner_rings): ring1 = geom1[i].inner_rings[j] if not rings_equal(ring0, ring1, rtol=rtol, atol=atol): return False else: msg = ('== not implemented for geometry type: %s' % self.geometry_type) # noinspection PyExceptionInherit raise InaSAFEError(msg) # Check keys for attribute values x = self.get_data() y = other.get_data() if x is None: if y is not None: return False else: for key in x[0]: for i in range(len(y)): if key not in y[i]: return False for key in y[0]: for i in range(len(x)): if key not in x[i]: return False # Check attribute values for i, a in enumerate(x): for key in a: X = a[key] Y = y[i][key] if X != Y: # Not obviously equal, try some special cases try: # Try numerical comparison with tolerances res = numpy.allclose(X, Y, rtol=rtol, atol=atol) except (NotImplementedError, TypeError): # E.g. '' (Not implemented) # or None or {} (Type error) pass else: if not res: return False # Finally cast as booleans. # This will e.g. match False with None or '' if not (bool(X) is bool(Y)): return False # Vector layers are identical up to the specified tolerance return True