Пример #1
0
    def test_get_area1(self):
        pntsa = npoints_towards(lon=0.32,
                                lat=0.0,
                                depth=0.0,
                                azimuth=45,
                                hdist=10.0,
                                vdist=0.0,
                                npoints=2)
        pntsb = npoints_towards(lon=pntsa[0][1],
                                lat=pntsa[1][1],
                                depth=pntsa[2][1],
                                azimuth=45 + 90,
                                hdist=10.0,
                                vdist=10.0,
                                npoints=2)
        pntsc = npoints_towards(lon=0.32,
                                lat=0.0,
                                depth=0.0,
                                azimuth=45 + 90,
                                hdist=10.0,
                                vdist=10.0,
                                npoints=2)
        tmp = Point(pntsc[0][1], pntsc[1][1], pntsc[2][1])
        prf3 = Line([Point(0.32, 0, 0), tmp])
        tmp1 = Point(pntsa[0][1], pntsa[1][1], pntsa[2][1])
        tmp2 = Point(pntsb[0][1], pntsb[1][1], pntsb[2][1])
        prf4 = Line([tmp1, tmp2])
        sfcb = KiteSurface.from_profiles([prf3, prf4], 0.2, 0.2)

        computed = sfcb.get_area()
        expected = 10.0 * 14.14
        msg = 'Multi fault surface: area is wrong'
        aae(expected, computed, decimal=-1, err_msg=msg)
Пример #2
0
 def test_zero_distance(self):
     lon, lat, depth, azimuth = 12, 34, 56, 78
     lons, lats, depths = geodetic.npoints_towards(
         lon, lat, depth, azimuth, hdist=0, vdist=0, npoints=5
     )
     expected_lons = [lon] * 5
     expected_lats = [lat] * 5
     expected_depths = [depth] * 5
     assert_aeq(lons, expected_lons)
     assert_aeq(lats, expected_lats)
     assert_aeq(depths, expected_depths)
Пример #3
0
 def test_zero_distance(self):
     lon, lat, depth, azimuth = 12, 34, 56, 78
     lons, lats, depths = geodetic.npoints_towards(
         lon, lat, depth, azimuth, hdist=0, vdist=0, npoints=5
     )
     expected_lons = [lon] * 5
     expected_lats = [lat] * 5
     expected_depths = [depth] * 5
     self.assertTrue(numpy.allclose(lons, expected_lons))
     self.assertTrue(numpy.allclose(lats, expected_lats))
     self.assertTrue(numpy.allclose(depths, expected_depths))
Пример #4
0
 def test_zero_distance(self):
     lon, lat, depth, azimuth = 12, 34, 56, 78
     lons, lats, depths = geodetic.npoints_towards(
         lon, lat, depth, azimuth, hdist=0, vdist=0, npoints=5
     )
     expected_lons = [lon] * 5
     expected_lats = [lat] * 5
     expected_depths = [depth] * 5
     assert_aeq(lons, expected_lons)
     assert_aeq(lats, expected_lats)
     assert_aeq(depths, expected_depths)
Пример #5
0
    def setUp(self):

        # First surface - Almost vertical dipping to south
        prf1 = Line([Point(0, 0, 0), Point(0, -0.00001, 20.)])
        prf2 = Line([Point(0.15, 0, 0), Point(0.15, -0.00001, 20.)])
        prf3 = Line([Point(0.3, 0, 0), Point(0.3, -0.00001, 20.)])
        sfca = KiteSurface.from_profiles([prf1, prf2, prf3], 1., 1.)

        # Second surface - Strike to NE and dip to SE
        pntsa = npoints_towards(lon=0.32,
                                lat=0.0,
                                depth=0.0,
                                azimuth=45,
                                hdist=10.0,
                                vdist=0.0,
                                npoints=2)
        pntsb = npoints_towards(lon=pntsa[0][1],
                                lat=pntsa[1][1],
                                depth=pntsa[2][1],
                                azimuth=45 + 90,
                                hdist=10.0,
                                vdist=10.0,
                                npoints=2)
        pntsc = npoints_towards(lon=0.32,
                                lat=0.0,
                                depth=0.0,
                                azimuth=45 + 90,
                                hdist=10.0,
                                vdist=10.0,
                                npoints=2)
        tmp = Point(pntsc[0][1], pntsc[1][1], pntsc[2][1])
        prf3 = Line([Point(0.32, 0, 0), tmp])
        tmp1 = Point(pntsa[0][1], pntsa[1][1], pntsa[2][1])
        tmp2 = Point(pntsb[0][1], pntsb[1][1], pntsb[2][1])
        prf4 = Line([tmp1, tmp2])
        sfcb = KiteSurface.from_profiles([prf3, prf4], 0.2, 0.2)

        # Create surface and mesh needed for the test
        self.msrf = MultiSurface([sfca, sfcb])
        self.coo = np.array([[-0.1, 0.0], [0.0, 0.1]])
        self.mesh = Mesh(self.coo[:, 0], self.coo[:, 1])
Пример #6
0
    def compute_profiles(self, bffer):
        """
        Compute the profile for each cross-section using the slab mesh.

        :param bffer:
            Buffer distance [km] from the plane of the cross-section used to
            find the points.
        """
        hspacing = 5.0
        slab_points = copy.copy(self.points)

        # Set values in the range [-180, 180]
        idx = numpy.nonzero(self.points[:, 0] > 180)
        if len(idx[0]):
            slab_points[idx[0], 0] = slab_points[idx[0], 0] - 360.

        # Loop over the cross-sections
        self.profiles = {}
        for ics, cs in enumerate(self.cross_sections):
            pnts = copy.copy(slab_points)

            # Get min and max longitude and latitude values
            minlo, maxlo, minla, maxla, qual = cs.get_mm()

            # Find the nodes of the grid within a certain distance from the
            # plane of the cross-section
            if qual == 0:
                minlo, maxlo, minla, maxla, qual = cs.get_mm(2.0)
                idxslb, dsts = cs.get_grd_nodes_within_buffer(
                    pnts[:, 0], pnts[:, 1], bffer, minlo, maxlo, minla, maxla)
            if qual == 1:
                idxslb, dsts = cs.get_grd_nodes_within_buffer_idl(
                    pnts[:, 0], pnts[:, 1], bffer, minlo, maxlo, minla, maxla)

            # Check if the array with cross-section data is not empty
            if idxslb is None:
                continue

            # Points
            num = numpy.ceil(cs.length[0]/hspacing).astype(int)
            psec = npoints_towards(cs.olo, cs.ola, 0.0, cs.strike[0],
                                   cs.length[0], 0., num)
            p = pnts[idxslb, :]
            interp = LinearNDInterpolator(p[:, 0:2], p[:, 2])
            z = interp(psec[0], psec[1])

            iii = numpy.isfinite(z)
            pro = numpy.concatenate((numpy.expand_dims(psec[0][iii], axis=1),
                                     numpy.expand_dims(psec[1][iii], axis=1),
                                     numpy.expand_dims(z[iii], axis=1)),
                                    axis=1)
            pro[:, 2] *= -1
            self.profiles['{:03d}'.format(ics)] = pro
Пример #7
0
 def test_input_as_int(self):
     lons, lats, depths = geodetic.npoints_towards(
         lon=0, lat=0, depth=0, azimuth=0,
         hdist=0, vdist=5, npoints=7
     )
     expected_lons = [0, 0, 0, 0, 0, 0, 0]
     expected_lats = [0, 0, 0, 0, 0, 0, 0]
     expected_depths = [0, 0.8333333, 1.6666667, 2.5, 3.3333333, 4.1666667, 5]
     numpy.testing.assert_almost_equal(lons, expected_lons)
     numpy.testing.assert_almost_equal(lats, expected_lats)
     numpy.testing.assert_almost_equal(depths, expected_depths)
     self.assertEqual(lons[0], 0)
     self.assertEqual(lats[0], 0)
     self.assertEqual(depths[0], 0)
Пример #8
0
 def test_input_as_int(self):
     lons, lats, depths = geodetic.npoints_towards(
         lon=0, lat=0, depth=0, azimuth=0,
         hdist=0, vdist=5, npoints=7
     )
     expected_lons = [0, 0, 0, 0, 0, 0, 0]
     expected_lats = [0, 0, 0, 0, 0, 0, 0]
     expected_depths = [0, 0.8333333, 1.6666667, 2.5, 3.3333333,
                        4.1666667, 5]
     numpy.testing.assert_almost_equal(lons, expected_lons)
     numpy.testing.assert_almost_equal(lats, expected_lats)
     numpy.testing.assert_almost_equal(depths, expected_depths)
     self.assertEqual(lons[0], 0)
     self.assertEqual(lats[0], 0)
     self.assertEqual(depths[0], 0)
Пример #9
0
 def test(self):
     lons, lats, depths = geodetic.npoints_towards(
         lon=-30.5, lat=23.6, depth=55, azimuth=-100.5,
         hdist=400, vdist=-40, npoints=5
     )
     expected_lons = [-30.5, -31.46375358, -32.42503446,
                      -33.3837849, -34.33995063]
     expected_lats = [23.6, 23.43314083, 23.26038177,
                      23.08178673, 22.8974212]
     expected_depths = [55, 45, 35, 25, 15]
     self.assertTrue(numpy.allclose(lons, expected_lons))
     self.assertTrue(numpy.allclose(lats, expected_lats))
     self.assertTrue(numpy.allclose(depths, expected_depths))
     # the first point should be exactly the same
     # as the original starting point
     self.assertEqual(lons[0], -30.5)
     self.assertEqual(lats[0], 23.6)
     self.assertEqual(depths[0], 55)
Пример #10
0
 def test_topo(self):
     lons, lats, depths = geodetic.npoints_towards(
         lon=-30.5, lat=23.6, depth=2, azimuth=-100.5,
         hdist=400, vdist=-4, npoints=5
     )
     expected_lons = [-30.5, -31.46375358, -32.42503446,
                      -33.3837849, -34.33995063]
     expected_lats = [23.6, 23.43314083, 23.26038177,
                      23.08178673, 22.8974212]
     expected_depths = [2, 1, 0, -1, -2]
     assert_aeq(lons, expected_lons)
     assert_aeq(lats, expected_lats)
     assert_aeq(depths, expected_depths)
     # the first point should be exactly the same
     # as the original starting point
     self.assertEqual(lons[0], -30.5)
     self.assertEqual(lats[0], 23.6)
     self.assertEqual(depths[0], 2)
Пример #11
0
 def test_topo(self):
     lons, lats, depths = geodetic.npoints_towards(
         lon=-30.5, lat=23.6, depth=2, azimuth=-100.5,
         hdist=400, vdist=-4, npoints=5
     )
     expected_lons = [-30.5, -31.46375358, -32.42503446,
                      -33.3837849, -34.33995063]
     expected_lats = [23.6, 23.43314083, 23.26038177,
                      23.08178673, 22.8974212]
     expected_depths = [2, 1, 0, -1, -2]
     assert_aeq(lons, expected_lons)
     assert_aeq(lats, expected_lats)
     assert_aeq(depths, expected_depths)
     # the first point should be exactly the same
     # as the original starting point
     self.assertEqual(lons[0], -30.5)
     self.assertEqual(lats[0], 23.6)
     self.assertEqual(depths[0], 2)
Пример #12
0
def _resample_profile(line, sampling_dist):
    # TODO split this function into smaller components.
    """
    :parameter line:
        An instance of :class:`openquake.hazardlib.geo.line.Line`
    :parameter sampling_dist:
        A scalar definining the distance [km] used to sample the profile
    :returns:
        An instance of :class:`openquake.hazardlib.geo.line.Line`
    """
    lo = [pnt.longitude for pnt in line.points]
    la = [pnt.latitude for pnt in line.points]
    de = [pnt.depth for pnt in line.points]

    # Set projection
    g = Geod(ellps='WGS84')

    # Add a tolerance length to the last point of the profile
    # check that final portion of the profile is not vertical
    if abs(lo[-2] - lo[-1]) > 1e-5 and abs(la[-2] - la[-1]) > 1e-5:
        az12, _, odist = g.inv(lo[-2], la[-2], lo[-1], la[-1])
        odist /= 1e3
        slope = np.arctan((de[-1] - de[-2]) / odist)
        hdist = TOL * sampling_dist * np.cos(slope)
        vdist = TOL * sampling_dist * np.sin(slope)
        endlon, endlat, _ = g.fwd(lo[-1], la[-1], az12, hdist * 1e3)
        lo[-1] = endlon
        la[-1] = endlat
        de[-1] = de[-1] + vdist
        az12, _, odist = g.inv(lo[-2], la[-2], lo[-1], la[-1])

        # Checking
        odist /= 1e3
        slopec = np.arctan((de[-1] - de[-2]) / odist)
        assert abs(slope - slopec) < 1e-3
    else:
        de[-1] = de[-1] + TOL * sampling_dist

    # Initialise the cumulated distance
    cdist = 0.

    # Get the azimuth of the profile
    azim = azimuth(lo[0], la[0], lo[-1], la[-1])

    # Initialise the list with the resampled nodes
    idx = 0
    resampled_cs = [Point(lo[idx], la[idx], de[idx])]

    # Set the starting point
    slo = lo[idx]
    sla = la[idx]
    sde = de[idx]

    # Resampling
    while 1:

        # Check loop exit condition
        if idx > len(lo) - 2:
            break

        # Compute the distance between the starting point and the next point
        # on the profile
        segment_len = distance(slo, sla, sde, lo[idx + 1], la[idx + 1],
                               de[idx + 1])

        # Search for the point
        if cdist + segment_len > sampling_dist:

            # This is the lenght of the last segment-fraction needed to
            # obtain the sampling distance
            delta = sampling_dist - cdist

            # Compute the slope of the last segment and its horizontal length.
            # We need to manage the case of a vertical segment TODO
            segment_hlen = distance(slo, sla, 0., lo[idx + 1], la[idx + 1], 0.)
            if segment_hlen > 1e-5:
                segment_slope = np.arctan((de[idx + 1] - sde) / segment_hlen)
            else:
                segment_slope = 90.

            # Horizontal and vertical lenght of delta
            delta_v = delta * np.sin(segment_slope)
            delta_h = delta * np.cos(segment_slope)

            # Add a new point to the cross section
            pnts = npoints_towards(slo, sla, sde, azim, delta_h, delta_v, 2)

            # Update the starting point
            slo = pnts[0][-1]
            sla = pnts[1][-1]
            sde = pnts[2][-1]
            resampled_cs.append(Point(slo, sla, sde))

            # Reset the cumulative distance
            cdist = 0.

        else:
            cdist += segment_len
            idx += 1
            slo = lo[idx]
            sla = la[idx]
            sde = de[idx]

    # Check the distances along the profile
    coo = [[pnt.longitude, pnt.latitude, pnt.depth] for pnt in resampled_cs]
    coo = np.array(coo)
    for i in range(0, coo.shape[0] - 1):
        dst = distance(coo[i, 0], coo[i, 1], coo[i, 2], coo[i + 1, 0],
                       coo[i + 1, 1], coo[i + 1, 2])
        if abs(dst - sampling_dist) > 0.1 * sampling_dist:
            raise ValueError('Wrong distance between points along the profile')

    return Line(resampled_cs)
Пример #13
0
def _resample_edge_with_direction(edge,
                                  sampling_dist,
                                  reference_idx,
                                  direct=+1):
    """
    :param edge:
    :param sampling_dist:
    :param reference_idx:
    :param direct:
    """
    #
    # checking that the increment is either 1 or -1
    assert abs(direct) == 1
    #
    # create three lists: one with longitude, one with latitude and one with
    # depth
    lo = [pnt.longitude for pnt in edge.points]
    la = [pnt.latitude for pnt in edge.points]
    de = [pnt.depth for pnt in edge.points]
    #
    # initialise the variable used to store the cumulated distance
    cdist = 0.
    #
    # initialise the list with the resampled nodes
    idx = reference_idx
    resampled_cs = [Point(lo[idx], la[idx], de[idx])]
    #
    # set the starting point
    slo = lo[idx]
    sla = la[idx]
    sde = de[idx]
    #
    # get the azimuth of the first segment on the edge in the given direction
    azim = azimuth(lo[idx], la[idx], lo[idx + direct], la[idx + direct])
    #
    # resampling
    old_dst = 1.e10
    while 1:
        #
        # this is a sanity check
        assert idx <= len(lo) - 1
        #
        # check loop exit condition
        if direct > 0 and idx > len(lo) - 1:
            break
        if direct < 0 and idx < 1:
            break
        #
        # compute the distance between the starting point and the next point
        # on the profile
        segment_len = distance(slo, sla, sde, lo[idx + direct],
                               la[idx + direct], de[idx + direct])
        #
        # search for the point
        if cdist + segment_len > sampling_dist:
            #
            # check
            if segment_len > old_dst:
                print(segment_len, '>', old_dst)
                raise ValueError('The segment length is increasing')
            else:
                old_dst = segment_len
            #
            # this is the lenght of the last segment-fraction needed to
            # obtain the sampling distance
            delta = sampling_dist - cdist
            #
            # compute the slope of the last segment and its horizontal length.
            # we need to manage the case of a vertical segment TODO
            segment_hlen = distance(slo, sla, 0., lo[idx + direct],
                                    la[idx + direct], 0.)
            segment_slope = np.arctan((de[idx + direct] - sde) / segment_hlen)
            #
            # horizontal and vertical lenght of delta
            delta_v = delta * np.sin(segment_slope)
            delta_h = delta * np.cos(segment_slope)
            #
            # add a new point to the cross section
            pnts = npoints_towards(slo, sla, sde, azim, delta_h, delta_v, 2)
            #
            # update the starting point
            slo = pnts[0][-1]
            sla = pnts[1][-1]
            sde = pnts[2][-1]
            #
            # checking distance between the reference point and latest point
            # included in the resampled section
            pnt = resampled_cs[-1]
            checkd = distance(slo, sla, sde, pnt.longitude, pnt.latitude,
                              pnt.depth)
            # >>> TOLERANCE
            if (cdist < 1e-2
                    and abs(checkd - sampling_dist) > 0.05 * sampling_dist):
                print(checkd, sampling_dist)
                msg = 'Segment distance different than sampling dst'
                raise ValueError(msg)
            #
            # updating the resample cross-section
            resampled_cs.append(Point(slo, sla, sde))
            #
            #
            tot = distance(lo[idx], la[idx], de[idx], lo[idx + direct],
                           la[idx + direct], de[idx + direct])
            downd = distance(slo, sla, sde, lo[idx], la[idx], de[idx])
            upd = distance(slo, sla, sde, lo[idx + direct], la[idx + direct],
                           de[idx + direct])
            #
            # >>> TOLERANCE
            if abs(tot - (downd + upd)) > tot * 0.05:
                print('     upd, downd, tot', upd, downd, tot)
                print(abs(tot - (downd + upd)))
                raise ValueError('Distances are not matching')
            #
            # reset the cumulative distance
            cdist = 0.
        else:
            # print('aa', cdist, segment_len, sampling_dist)
            # print('  ', idx, len(lo)-1, direct)
            #
            #
            old_dst = 1.e10

            cdist += segment_len
            idx += direct
            slo = lo[idx]
            sla = la[idx]
            sde = de[idx]
            #
            # get the azimuth of the profile
            if idx < len(lo) - 1:
                azim = azimuth(lo[idx], la[idx], lo[idx + direct],
                               la[idx + direct])
            else:
                break
    #
    #
    return resampled_cs
Пример #14
0
def rsmpl_unsure(ix, iy, sampling_dist):
    direct = 1
    idx = 0
    #
    # create three lists: one with longitude, one with latitude and one with
    # depth
    lo = list(ix)
    la = list(iy)
    de = list(numpy.zeros_like(ix))
    #
    # initialise the variable used to store the cumulated distance
    cdist = 0.
    #
    # set the starting point
    slo = lo[idx]
    sla = la[idx]
    sde = de[idx]
    #
    # get the azimuth of the first segment on the edge in the given direction
    azim = azimuth(lo[idx], la[idx], lo[idx + direct], la[idx + direct])
    #
    # initialise the list with the resampled nodes
    resampled_cs = [[lo[idx], la[idx], azim]]
    #
    # resampling
    while 1:
        #
        # this is a sanity check
        assert idx <= len(lo) - 1
        #
        # check loop exit condition
        if direct > 0 and idx > len(lo) - 1:
            break
        #
        # compute the distance between the starting point and the next point
        # on the profile
        segment_len = distance(slo, sla, sde, lo[idx + direct],
                               la[idx + direct], de[idx + direct])
        #
        # search for the point
        if cdist + segment_len > sampling_dist:
            #
            # this is the lenght of the last segment-fraction needed to
            # obtain the sampling distance
            delta = sampling_dist - cdist
            #
            # add a new point to the cross section
            pnts = npoints_towards(slo, sla, sde, azim, delta, 0., 2)
            #
            # update the starting point
            slo = pnts[0][-1]
            sla = pnts[1][-1]
            sde = pnts[2][-1]
            resampled_cs.append([slo, sla, azim])
            #
            # reset the cumulative distance
            cdist = 0.
        else:
            cdist += segment_len
            idx += direct
            slo = lo[idx]
            sla = la[idx]
            sde = de[idx]
            #
            # get the azimuth of the profile
            if idx < len(lo) - 1:
                azim = azimuth(lo[idx], la[idx], lo[idx + direct],
                               la[idx + direct])
            else:
                break
    # code.interact(local=locals())
    return numpy.array(resampled_cs)
Пример #15
0
def _resample_profile(line, sampling_dist):
    """
    :parameter line:
        An instance of :class:`openquake.hazardlib.geo.line.Line`
    :parameter sampling_dist:
        A scalar definining the distance used to sample the profile
    :returns:
        An instance of :class:`openquake.hazardlib.geo.line.Line`
    """
    lo = [pnt.longitude for pnt in line.points]
    la = [pnt.latitude for pnt in line.points]
    de = [pnt.depth for pnt in line.points]
    #
    # initialise the cumulated distance
    cdist = 0.
    #
    # get the azimuth of the profile
    azim = azimuth(lo[0], la[0], lo[-1], la[-1])
    #
    # initialise the list with the resampled nodes
    idx = 0
    resampled_cs = [Point(lo[idx], la[idx], de[idx])]
    #
    # set the starting point
    slo = lo[idx]
    sla = la[idx]
    sde = de[idx]
    #
    # resampling
    while 1:
        #
        # check loop exit condition
        if idx > len(lo) - 2:
            break
        #
        # compute the distance between the starting point and the next point
        # on the profile
        segment_len = distance(slo, sla, sde, lo[idx + 1], la[idx + 1],
                               de[idx + 1])
        #
        # search for the point
        if cdist + segment_len > sampling_dist:
            #
            # this is the lenght of the last segment-fraction needed to
            # obtain the sampling distance
            delta = sampling_dist - cdist
            #
            # compute the slope of the last segment and its horizontal length.
            # We need to manage the case of a vertical segment TODO
            segment_hlen = distance(slo, sla, 0., lo[idx + 1], la[idx + 1], 0.)
            segment_slope = np.arctan((de[idx + 1] - sde) / segment_hlen)
            #
            # horizontal and vertical lenght of delta
            delta_v = delta * np.sin(segment_slope)
            delta_h = delta * np.cos(segment_slope)
            #
            # add a new point to the cross section
            pnts = npoints_towards(slo, sla, sde, azim, delta_h, delta_v, 2)
            #
            # update the starting point
            slo = pnts[0][-1]
            sla = pnts[1][-1]
            sde = pnts[2][-1]
            resampled_cs.append(Point(slo, sla, sde))
            #
            # reset the cumulative distance
            cdist = 0.

        else:
            cdist += segment_len
            idx += 1
            slo = lo[idx]
            sla = la[idx]
            sde = de[idx]

    line = Line(resampled_cs)
    return line