コード例 #1
0
ファイル: utils_test.py プロジェクト: gongshimin/oq-hazardlib
    def test_nonconvex_polygon(self):
        coords = [(0, 0), (0, 3), (2, 2), (1, 2), (1, 1), (1, 0), (0, 0)]
        for polygon_coords in (coords, list(reversed(coords))):
            polygon = shapely.geometry.Polygon(polygon_coords)
            pxx = numpy.array([0.5, 0.5, 0.5, 0.5, 0.5])
            pyy = numpy.array([0.0, 0.5, 1.0, 2.0, 2.5])
            dist = utils.point_to_polygon_distance(polygon, pxx, pyy)
            numpy.testing.assert_equal(dist, 0)

            pxx = numpy.array([1.5, 3.0, -2.0])
            pyy = numpy.array([1.5, 2.0, 2.0])
            dist = utils.point_to_polygon_distance(polygon, pxx, pyy)
            numpy.testing.assert_almost_equal(dist, [0.5, 1, 2])
コード例 #2
0
ファイル: utils_test.py プロジェクト: vhmar/oq-engine
    def test_nonconvex_polygon(self):
        coords = [(0, 0), (0, 3), (2, 2), (1, 2), (1, 1), (1, 0), (0, 0)]
        for polygon_coords in (coords, list(reversed(coords))):
            polygon = shapely.geometry.Polygon(polygon_coords)
            pxx = numpy.array([0.5, 0.5, 0.5, 0.5, 0.5])
            pyy = numpy.array([0.0, 0.5, 1.0, 2.0, 2.5])
            dist = utils.point_to_polygon_distance(polygon, pxx, pyy)
            numpy.testing.assert_equal(dist, 0)

            pxx = numpy.array([1.5, 3.0, -2.0])
            pyy = numpy.array([1.5, 2.0, 2.0])
            dist = utils.point_to_polygon_distance(polygon, pxx, pyy)
            numpy.testing.assert_almost_equal(dist, [0.5, 1, 2])
コード例 #3
0
ファイル: polygon.py プロジェクト: larsbutler/oq-hazardlib
    def intersects(self, mesh):
        """
        Check for intersection with each point of the ``mesh``.

        Mesh coordinate values are in decimal degrees.

        :param mesh:
            :class:`openquake.hazardlib.geo.mesh.Mesh` instance.
        :returns:
            Numpy array of `bool` values in the same shapes in the input
            coordinate arrays with ``True`` on indexes of points that
            lie inside the polygon or on one of its edges and ``False``
            for points that neither lie inside nor touch the boundary.
        """
        self._init_polygon2d()
        pxx, pyy = self._projection(mesh.lons, mesh.lats)
        return utils.point_to_polygon_distance(self._polygon2d, pxx, pyy) == 0
コード例 #4
0
ファイル: polygon.py プロジェクト: digitalsatori/oq-engine
    def intersects(self, mesh):
        """
        Check for intersection with each point of the ``mesh``.

        Mesh coordinate values are in decimal degrees.

        :param mesh:
            :class:`openquake.hazardlib.geo.mesh.Mesh` instance.
        :returns:
            Numpy array of `bool` values in the same shapes in the input
            coordinate arrays with ``True`` on indexes of points that
            lie inside the polygon or on one of its edges and ``False``
            for points that neither lie inside nor touch the boundary.
        """
        self._init_polygon2d()
        pxx, pyy = self._projection(mesh.lons, mesh.lats)
        return utils.point_to_polygon_distance(self._polygon2d, pxx, pyy) == 0
コード例 #5
0
    def get_joyner_boore_distance(self, mesh):

        # Get indexes of the finite points composing the edges
        iupp = np.nonzero(np.isfinite(self.mesh.lons[0, :]))[0]
        ilow = np.flipud(np.nonzero(np.isfinite(self.mesh.lons[-1, :]))[0])
        irig = np.nonzero(np.isfinite(self.mesh.lons[:, -1]))[0]
        ilef = np.flipud(np.nonzero(np.isfinite(self.mesh.lons[:, 0]))[0])

        # Building the polygon
        pnts = []
        for corner in [(0, iupp), (irig, -1), (-1, ilow), (ilef, 0)]:
            pnts.extend(
                zip(self.mesh.lons[corner], self.mesh.lats[corner],
                    self.mesh.depths[corner]))
        perimeter = np.array(pnts)

        distances = geodetic.min_geodetic_distance(
            (perimeter[:, 0], perimeter[:, 1]), (mesh.lons, mesh.lats))

        idxs = (distances < 40).nonzero()[0]  # indices on the first dimension
        if not len(idxs):
            # no point is close enough, return distances as they are
            return distances

        # Get the projection
        proj = geo_utils.OrthographicProjection(
            *geo_utils.get_spherical_bounding_box(perimeter[:,
                                                            0], perimeter[:,
                                                                          1]))

        # Mesh projected coordinates
        mesh_xx, mesh_yy = proj(mesh.lons[idxs], mesh.lats[idxs])

        # Create the shapely Polygon using projected coordinates
        xp, yp = proj(perimeter[:, 0], perimeter[:, 1])
        polygon = Polygon([[x, y] for x, y in zip(xp, yp)])

        # Calculate the distances
        distances[idxs] = geo_utils.point_to_polygon_distance(
            polygon, mesh_xx, mesh_yy)

        return distances
コード例 #6
0
ファイル: kite_fault.py プロジェクト: g-weatherill/oq-engine
    def get_joyner_boore_distance(self, mesh) -> np.ndarray:
        """
        Computes the Rjb distance between the rupture and the points included
        in the mesh provided.

        :param mesh:
            An instance of :class:`openquake.hazardlib.geo.mesh.Mesh`
        :returns:
            A :class:`numpy.ndarray` instance with the Rjb values
        """

        blo, bla = self._get_external_boundary()
        distances = geodetic.min_geodetic_distance((blo, bla),
                                                   (mesh.lons, mesh.lats))

        idxs = (distances < 40).nonzero()[0]  # indices on the first dimension
        if len(idxs) < 1:
            # no point is close enough, return distances as they are
            return distances

        # Get the projection
        proj = geo_utils.OrthographicProjection(
            *geo_utils.get_spherical_bounding_box(blo, bla))

        # Mesh projected coordinates
        mesh_xx, mesh_yy = proj(mesh.lons[idxs], mesh.lats[idxs])

        # Create the shapely Polygon using projected coordinates
        xp, yp = proj(blo, bla)
        polygon = Polygon([[x, y] for x, y in zip(xp, yp)])

        # Calculate the distances
        distances[idxs] = geo_utils.point_to_polygon_distance(
            polygon, mesh_xx, mesh_yy)

        return distances
コード例 #7
0
ファイル: mesh.py プロジェクト: cbworden/oq-hazardlib
    def get_joyner_boore_distance(self, mesh):
        """
        Compute and return Joyner-Boore distance to each point of ``mesh``.
        Point's depth is ignored.

        See
        :meth:`openquake.hazardlib.geo.surface.base.BaseQuadrilateralSurface.get_joyner_boore_distance`
        for definition of this distance.

        :returns:
            numpy array of distances in km of the same shape as ``mesh``.
            Distance value is considered to be zero if a point
            lies inside the polygon enveloping the projection of the mesh
            or on one of its edges.
        """
        # we perform a hybrid calculation (geodetic mesh-to-mesh distance
        # and distance on the projection plane for close points). first,
        # we find the closest geodetic distance for each point of target
        # mesh to this one. in general that distance is greater than
        # the exact distance to enclosing polygon of this mesh and it
        # depends on mesh spacing. but the difference can be neglected
        # if calculated geodetic distance is over some threshold.
        distances = geodetic.min_geodetic_distance(self.lons, self.lats,
                                                   mesh.lons.flatten(),
                                                   mesh.lats.flatten())

        # here we find the points for which calculated mesh-to-mesh
        # distance is below a threshold. this threshold is arbitrary:
        # lower values increase the maximum possible error, higher
        # values reduce the efficiency of that filtering. the maximum
        # error is equal to the maximum difference between a distance
        # from site to two adjacent points of the mesh and distance
        # from site to the line connecting them. thus the error is
        # a function of distance threshold and mesh spacing. the error
        # is maximum when the site lies on a perpendicular to the line
        # connecting points of the mesh and that passes the middle
        # point between them. the error then can be calculated as
        # ``err = trsh - d = trsh - \sqrt(trsh^2 - (ms/2)^2)``, where
        # ``trsh`` and ``d`` are distance to mesh points (the one
        # we found on the previous step) and distance to the line
        # connecting them (the actual distance) and ``ms`` is mesh
        # spacing. the threshold of 40 km gives maximum error of 314
        # meters for meshes with spacing of 10 km and 5.36 km for
        # meshes with spacing of 40 km. if mesh spacing is over
        # ``(trsh / \sqrt(2)) * 2`` then points lying in the middle
        # of mesh cells (that is inside the polygon) will be filtered
        # out by the threshold and have positive distance instead of 0.
        # so for threshold of 40 km mesh spacing should not be more
        # than 56 km (typical values are 5 to 10 km).

        [idxs] = (distances < 40).nonzero()
        if not len(idxs):
            # no point is close enough, return distances as they are
            return distances

        # for all the points that are closer than the threshold we need
        # to recalculate the distance and set it to zero, if point falls
        # inside the enclosing polygon of the mesh. for doing that we
        # project both this mesh and the points of the second mesh--selected
        # by distance threshold--to the same Cartesian space, define
        # minimum shapely polygon enclosing the mesh and calculate point
        # to polygon distance, which gives the most accurate value
        # of distance in km (and that value is zero for points inside
        # the polygon).
        proj, polygon = self._get_proj_enclosing_polygon()
        if not isinstance(polygon, shapely.geometry.Polygon):
            # either line or point is our enclosing polygon. draw
            # a square with side of 10 m around in order to have
            # a proper polygon instead.
            polygon = polygon.buffer(self.DIST_TOLERANCE, 1)
        mesh_lons, mesh_lats = mesh.lons.take(idxs), mesh.lats.take(idxs)
        mesh_xx, mesh_yy = proj(mesh_lons, mesh_lats)
        distances_2d = geo_utils.point_to_polygon_distance(
            polygon, mesh_xx, mesh_yy)

        # replace geodetic distance values for points-closer-than-the-threshold
        # by more accurate point-to-polygon distance values.
        distances.put(idxs, distances_2d)
        return distances.reshape(mesh.shape)
コード例 #8
0
ファイル: utils_test.py プロジェクト: vhmar/oq-engine
 def test_2d_array_of_points(self):
     pxx = [[-1., 0.3], [-0.25, 0.5]]
     pyy = [[2., 1.1], [3.9, -0.3]]
     dist = utils.point_to_polygon_distance(self.polygon, pxx, pyy)
     numpy.testing.assert_almost_equal(dist,
                                       [[1.4142135, 0.1], [2.9107559, 0.3]])
コード例 #9
0
ファイル: utils_test.py プロジェクト: vhmar/oq-engine
 def test_list_of_points(self):
     pxx = [-1., 0.3, -0.25]
     pyy = [2., 1.1, 3.9]
     dist = utils.point_to_polygon_distance(self.polygon, pxx, pyy)
     numpy.testing.assert_almost_equal(dist, [1.4142135, 0.1, 2.9107559])
コード例 #10
0
ファイル: utils_test.py プロジェクト: vhmar/oq-engine
 def test_one_point(self):
     dist = utils.point_to_polygon_distance(self.polygon, 0.5, 0.5)
     self.assertEqual(dist, 0)
     dist = utils.point_to_polygon_distance(self.polygon, 0.5, 1.5)
     self.assertAlmostEqual(dist, 0.5)
コード例 #11
0
ファイル: mesh.py プロジェクト: gem/oq-engine
    def get_joyner_boore_distance(self, mesh):
        """
        Compute and return Joyner-Boore distance to each point of ``mesh``.
        Point's depth is ignored.

        See
        :meth:`openquake.hazardlib.geo.surface.base.BaseSurface.get_joyner_boore_distance`
        for definition of this distance.

        :returns:
            numpy array of distances in km of the same shape as ``mesh``.
            Distance value is considered to be zero if a point
            lies inside the polygon enveloping the projection of the mesh
            or on one of its edges.
        """
        # we perform a hybrid calculation (geodetic mesh-to-mesh distance
        # and distance on the projection plane for close points). first,
        # we find the closest geodetic distance for each point of target
        # mesh to this one. in general that distance is greater than
        # the exact distance to enclosing polygon of this mesh and it
        # depends on mesh spacing. but the difference can be neglected
        # if calculated geodetic distance is over some threshold.
        # get the highest slice from the 3D mesh
        distances = geodetic.min_geodetic_distance(
            (self.lons, self.lats), (mesh.lons, mesh.lats))
        # here we find the points for which calculated mesh-to-mesh
        # distance is below a threshold. this threshold is arbitrary:
        # lower values increase the maximum possible error, higher
        # values reduce the efficiency of that filtering. the maximum
        # error is equal to the maximum difference between a distance
        # from site to two adjacent points of the mesh and distance
        # from site to the line connecting them. thus the error is
        # a function of distance threshold and mesh spacing. the error
        # is maximum when the site lies on a perpendicular to the line
        # connecting points of the mesh and that passes the middle
        # point between them. the error then can be calculated as
        # ``err = trsh - d = trsh - \sqrt(trsh^2 - (ms/2)^2)``, where
        # ``trsh`` and ``d`` are distance to mesh points (the one
        # we found on the previous step) and distance to the line
        # connecting them (the actual distance) and ``ms`` is mesh
        # spacing. the threshold of 40 km gives maximum error of 314
        # meters for meshes with spacing of 10 km and 5.36 km for
        # meshes with spacing of 40 km. if mesh spacing is over
        # ``(trsh / \sqrt(2)) * 2`` then points lying in the middle
        # of mesh cells (that is inside the polygon) will be filtered
        # out by the threshold and have positive distance instead of 0.
        # so for threshold of 40 km mesh spacing should not be more
        # than 56 km (typical values are 5 to 10 km).
        idxs = (distances < 40).nonzero()[0]  # indices on the first dimension
        if not len(idxs):
            # no point is close enough, return distances as they are
            return distances

        # for all the points that are closer than the threshold we need
        # to recalculate the distance and set it to zero, if point falls
        # inside the enclosing polygon of the mesh. for doing that we
        # project both this mesh and the points of the second mesh--selected
        # by distance threshold--to the same Cartesian space, define
        # minimum shapely polygon enclosing the mesh and calculate point
        # to polygon distance, which gives the most accurate value
        # of distance in km (and that value is zero for points inside
        # the polygon).
        proj, polygon = self._get_proj_enclosing_polygon()
        if not isinstance(polygon, shapely.geometry.Polygon):
            # either line or point is our enclosing polygon. draw
            # a square with side of 10 m around in order to have
            # a proper polygon instead.
            polygon = polygon.buffer(self.DIST_TOLERANCE, 1)
        mesh_xx, mesh_yy = proj(mesh.lons[idxs], mesh.lats[idxs])
        # replace geodetic distance values for points-closer-than-the-threshold
        # by more accurate point-to-polygon distance values.
        distances[idxs] = geo_utils.point_to_polygon_distance(
            polygon, mesh_xx, mesh_yy)

        return distances
コード例 #12
0
ファイル: utils_test.py プロジェクト: gongshimin/oq-hazardlib
 def test_2d_array_of_points(self):
     pxx = [[-1., 0.3], [-0.25, 0.5]]
     pyy = [[2., 1.1], [3.9, -0.3]]
     dist = utils.point_to_polygon_distance(self.polygon, pxx, pyy)
     numpy.testing.assert_almost_equal(dist, [[1.4142135, 0.1],
                                              [2.9107559, 0.3]])
コード例 #13
0
ファイル: utils_test.py プロジェクト: gongshimin/oq-hazardlib
 def test_list_of_points(self):
     pxx = [-1., 0.3, -0.25]
     pyy = [2., 1.1, 3.9]
     dist = utils.point_to_polygon_distance(self.polygon, pxx, pyy)
     numpy.testing.assert_almost_equal(dist, [1.4142135, 0.1, 2.9107559])
コード例 #14
0
ファイル: utils_test.py プロジェクト: gongshimin/oq-hazardlib
 def test_one_point(self):
     dist = utils.point_to_polygon_distance(self.polygon, 0.5, 0.5)
     self.assertEqual(dist, 0)
     dist = utils.point_to_polygon_distance(self.polygon, 0.5, 1.5)
     self.assertAlmostEqual(dist, 0.5)