def test_one_point(self): dist = float( geodetic.distance_to_semi_arc(12.3, 44.5, 39.4, plons=13.4, plats=46.9)) self.assertAlmostEqual(dist, -105.12464364) dist = float( geodetic.distance_to_arc(12.3, 44.5, 219.4, plons=13.4, plats=46.9)) self.assertAlmostEqual(dist, +105.12464364) dist = float( geodetic.distance_to_semi_arc(12.3, 44.5, 39.4, plons=13.4, plats=44.9)) self.assertAlmostEqual(dist, 38.34459954) # This tests the distance to a point in the y-negative halfspace in a # reference system which uses as the origin the reference point # (i.e. (12.3; 44.5)) and the y direction as the direction with # azimuth = 39.4) dist = float( geodetic.distance_to_semi_arc(12.3, 44.5, 39.4, plons=11.3, plats=44.5)) self.assertAlmostEqual(dist, -79.3093368)
def test_one_point(self): dist = float(geodetic.distance_to_semi_arc( 12.3, 44.5, 39.4, plons=13.4, plats=46.9)) self.assertAlmostEqual(dist, -105.12464364) dist = float(geodetic.distance_to_arc( 12.3, 44.5, 219.4, plons=13.4, plats=46.9)) self.assertAlmostEqual(dist, +105.12464364) dist = float(geodetic.distance_to_semi_arc( 12.3, 44.5, 39.4, plons=13.4, plats=44.9)) self.assertAlmostEqual(dist, 38.34459954) # This tests the distance to a point in the y-negative halfspace in a # reference system which uses as the origin the reference point # (i.e. (12.3; 44.5)) and the y direction as the direction with # azimuth = 39.4) dist = float(geodetic.distance_to_semi_arc( 12.3, 44.5, 39.4, plons=11.3, plats=44.5)) self.assertAlmostEqual(dist, -79.3093368)
def get_rx_distance(self, mesh): """ Compute distance between each point of mesh and surface's great circle arc. Distance is measured perpendicular to the rupture strike, from the surface projection of the updip edge of the rupture, with the down dip direction being positive (this distance is usually called ``Rx``). In other words, is the horizontal distance to top edge of rupture measured perpendicular to the strike. Values on the hanging wall are positive, values on the footwall are negative. :param mesh: :class:`~openquake.hazardlib.geo.mesh.Mesh` of points to calculate Rx-distance to. :returns: Numpy array of distances in km. """ top_edge = self.mesh[0:1] dists = [] ia = 0 ib = top_edge.lons.shape[1] - 2 if (self.__class__.__name__ == 'KiteSurface'): idxs = numpy.nonzero(numpy.isfinite(top_edge.lons[0, :]))[0] ia = min(idxs) ib = sorted(idxs)[-2] if top_edge.lons.shape[1] < 3: i = 0 if ((self.__class__.__name__ == 'KiteSurface') and (numpy.isnan(top_edge.lons[0, i]) or numpy.isnan(top_edge.lons[0, i + 1]))): msg = 'Rx calculation. Top of rupture has less than two points' raise ValueError(msg) p1 = Point(top_edge.lons[0, i], top_edge.lats[0, i], top_edge.depths[0, i]) p2 = Point(top_edge.lons[0, i + 1], top_edge.lats[0, i + 1], top_edge.depths[0, i + 1]) azimuth = p1.azimuth(p2) dists.append( geodetic.distance_to_arc(p1.longitude, p1.latitude, azimuth, mesh.lons, mesh.lats)) else: for i in range(top_edge.lons.shape[1] - 1): if ((self.__class__.__name__ == 'KiteSurface') and (numpy.isnan(top_edge.lons[0, i]) or numpy.isnan(top_edge.lons[0, i + 1]))): continue p1 = Point(top_edge.lons[0, i], top_edge.lats[0, i], top_edge.depths[0, i]) p2 = Point(top_edge.lons[0, i + 1], top_edge.lats[0, i + 1], top_edge.depths[0, i + 1]) # Swapping if i == 0: pt = p1 p1 = p2 p2 = pt # Computing azimuth and distance if i == ia or i == ib: azimuth = p1.azimuth(p2) tmp = geodetic.distance_to_semi_arc( p1.longitude, p1.latitude, azimuth, mesh.lons, mesh.lats) else: tmp = geodetic.min_distance_to_segment( numpy.array([p1.longitude, p2.longitude]), numpy.array([p1.latitude, p2.latitude]), mesh.lons, mesh.lats) # Correcting the sign of the distance if i == 0: tmp *= -1 dists.append(tmp) # Computing distances dists = numpy.array(dists) iii = abs(dists).argmin(axis=0) dst = dists[iii, list(range(dists.shape[1]))] if numpy.any(numpy.isnan(dst)): raise ValueError('NaN in Rx') return dst
def get_rx_distance(self, mesh): """ Compute distance between each point of mesh and surface's great circle arc. Distance is measured perpendicular to the rupture strike, from the surface projection of the updip edge of the rupture, with the down dip direction being positive (this distance is usually called ``Rx``). In other words, is the horizontal distance to top edge of rupture measured perpendicular to the strike. Values on the hanging wall are positive, values on the footwall are negative. :param mesh: :class:`~openquake.hazardlib.geo.mesh.Mesh` of points to calculate Rx-distance to. :returns: Numpy array of distances in km. """ top_edge = self.mesh[0:1] dists = [] if top_edge.lons.shape[1] < 3: i = 0 p1 = Point(top_edge.lons[0, i], top_edge.lats[0, i], top_edge.depths[0, i]) p2 = Point(top_edge.lons[0, i + 1], top_edge.lats[0, i + 1], top_edge.depths[0, i + 1]) azimuth = p1.azimuth(p2) dists.append( geodetic.distance_to_arc(p1.longitude, p1.latitude, azimuth, mesh.lons, mesh.lats)) else: for i in range(top_edge.lons.shape[1] - 1): p1 = Point(top_edge.lons[0, i], top_edge.lats[0, i], top_edge.depths[0, i]) p2 = Point(top_edge.lons[0, i + 1], top_edge.lats[0, i + 1], top_edge.depths[0, i + 1]) # Swapping if i == 0: pt = p1 p1 = p2 p2 = pt # Computing azimuth and distance if i == 0 or i == top_edge.lons.shape[1] - 2: azimuth = p1.azimuth(p2) tmp = geodetic.distance_to_semi_arc( p1.longitude, p1.latitude, azimuth, mesh.lons, mesh.lats) else: tmp = geodetic.min_distance_to_segment( numpy.array([p1.longitude, p2.longitude]), numpy.array([p1.latitude, p2.latitude]), mesh.lons, mesh.lats) # Correcting the sign of the distance if i == 0: tmp *= -1 dists.append(tmp) # Computing distances dists = numpy.array(dists) iii = abs(dists).argmin(axis=0) dst = dists[iii, list(range(dists.shape[1]))] return dst
def get_rx_distance(self, mesh): """ See :meth:`superclass method <.base.BaseSurface.get_rx_distance>` for spec of input and result values. The method extracts the top edge of the surface. For each point in mesh it computes the Rx distance to each segment the top edge is made of. The calculation is done by calling the function :func:`openquake.hazardlib.geo.geodetic.distance_to_arc`. The final Rx distance matrix is then constructed by taking, for each point in mesh, the minimum Rx distance value computed. """ top_edge = self.get_mesh()[0:1] dists = [] if top_edge.lons.shape[1] < 3: i = 0 p1 = Point( top_edge.lons[0, i], top_edge.lats[0, i], top_edge.depths[0, i] ) p2 = Point( top_edge.lons[0, i + 1], top_edge.lats[0, i + 1], top_edge.depths[0, i + 1] ) azimuth = p1.azimuth(p2) dists.append( geodetic.distance_to_arc( p1.longitude, p1.latitude, azimuth, mesh.lons, mesh.lats ) ) else: for i in range(top_edge.lons.shape[1] - 1): p1 = Point( top_edge.lons[0, i], top_edge.lats[0, i], top_edge.depths[0, i] ) p2 = Point( top_edge.lons[0, i + 1], top_edge.lats[0, i + 1], top_edge.depths[0, i + 1] ) # Swapping if i == 0: pt = p1 p1 = p2 p2 = pt # Computing azimuth and distance if i == 0 or i == top_edge.lons.shape[1] - 2: azimuth = p1.azimuth(p2) tmp = geodetic.distance_to_semi_arc(p1.longitude, p1.latitude, azimuth, mesh.lons, mesh.lats) else: tmp = geodetic.min_distance_to_segment([p1.longitude, p2.longitude], [p1.latitude, p2.latitude], mesh.lons, mesh.lats) # Correcting the sign of the distance if i == 0: tmp *= -1 dists.append(tmp) # Computing distances dists = numpy.array(dists) iii = abs(dists).argmin(axis=0) dst = dists[iii, list(range(dists.shape[1]))] return dst
def get_rx_distance(self, mesh): """ Compute distance between each point of mesh and surface's great circle arc. Distance is measured perpendicular to the rupture strike, from the surface projection of the updip edge of the rupture, with the down dip direction being positive (this distance is usually called ``Rx``). In other words, is the horizontal distance to top edge of rupture measured perpendicular to the strike. Values on the hanging wall are positive, values on the footwall are negative. :param mesh: :class:`~openquake.hazardlib.geo.mesh.Mesh` of points to calculate Rx-distance to. :returns: Numpy array of distances in km. """ top_edge = self.mesh[0:1] dists = [] if top_edge.lons.shape[1] < 3: i = 0 p1 = Point( top_edge.lons[0, i], top_edge.lats[0, i], top_edge.depths[0, i] ) p2 = Point( top_edge.lons[0, i + 1], top_edge.lats[0, i + 1], top_edge.depths[0, i + 1] ) azimuth = p1.azimuth(p2) dists.append( geodetic.distance_to_arc( p1.longitude, p1.latitude, azimuth, mesh.lons, mesh.lats ) ) else: for i in range(top_edge.lons.shape[1] - 1): p1 = Point( top_edge.lons[0, i], top_edge.lats[0, i], top_edge.depths[0, i] ) p2 = Point( top_edge.lons[0, i + 1], top_edge.lats[0, i + 1], top_edge.depths[0, i + 1] ) # Swapping if i == 0: pt = p1 p1 = p2 p2 = pt # Computing azimuth and distance if i == 0 or i == top_edge.lons.shape[1] - 2: azimuth = p1.azimuth(p2) tmp = geodetic.distance_to_semi_arc(p1.longitude, p1.latitude, azimuth, mesh.lons, mesh.lats) else: tmp = geodetic.min_distance_to_segment( numpy.array([p1.longitude, p2.longitude]), numpy.array([p1.latitude, p2.latitude]), mesh.lons, mesh.lats) # Correcting the sign of the distance if i == 0: tmp *= -1 dists.append(tmp) # Computing distances dists = numpy.array(dists) iii = abs(dists).argmin(axis=0) dst = dists[iii, list(range(dists.shape[1]))] return dst