예제 #1
0
 def test_points_too_far(self):
     proj = utils.get_orthographic_projection(180, 180, 45, 45)
     with self.assertRaises(ValueError) as ar:
         proj(90, -45)
     self.assertEqual(ar.exception.message,
                      'some points are too far from the projection '
                      'center lon=180.0 lat=45.0')
예제 #2
0
파일: mesh.py 프로젝트: pslh/nhlib
    def get_convex_hull(self):
        """
        Get a convex polygon object that contains projections of all the points
        of the mesh.

        :returns:
            Instance of :class:`nhlib.geo.polygon.Polygon` that is a convex
            hull around all the points in this mesh. If the original mesh
            had only one point, the resulting polygon has a square shape
            with a side length of 10 meters. If there were only two points,
            resulting polygon is a stripe 10 meters wide.
        """
        # avoid circular imports
        from nhlib.geo.polygon import Polygon
        # create a projection centered in the center of points collection
        proj = geo_utils.get_orthographic_projection(
            *geo_utils.get_spherical_bounding_box(self.lons, self.lats)
        )
        # project all the points and create a shapely multipoint object.
        # need to copy an array because otherwise shapely misinterprets it
        coords = numpy.transpose(proj(self.lons, self.lats)).copy()
        multipoint = shapely.geometry.MultiPoint(coords)
        # create a 2d polygon from a convex hull around that multipoint
        polygon2d = multipoint.convex_hull
        # if mesh had only one point, the convex hull is a point. if there
        # were two, it is a line string. we need to return a convex polygon
        # object, so extend that area-less geometries by some arbitrarily
        # small distance, like five meters.
        if isinstance(polygon2d, (shapely.geometry.LineString,
                                  shapely.geometry.Point)):
            polygon2d = polygon2d.buffer(0.005, 1)
        return Polygon._from_2d(polygon2d, proj)
예제 #3
0
 def test_projection(self):
     # values verified against pyproj's implementation
     proj = utils.get_orthographic_projection(10, 16, -2, 30)
     lons = numpy.array([10., 20., 30., 40.])
     lats = numpy.array([-1., -2., -3., -4.])
     xx, yy = proj(lons, lats)
     exx = [-309.89151465, 800.52541443, 1885.04014687, 2909.78079661]
     eyy = [-1650.93260348, -1747.79256663, -1797.62444771, -1802.28117183]
     self.assertTrue(numpy.allclose(xx, exx, atol=0.01, rtol=0.005))
     self.assertTrue(numpy.allclose(yy, eyy, atol=0.01, rtol=0.005))
예제 #4
0
 def test_projecting_back_and_forth(self):
     lon0, lat0 = -10.4, 20.3
     proj = utils.get_orthographic_projection(lon0, lat0, lon0, lat0)
     lons = lon0 + (numpy.random.random((20, 10)) * 50 - 25)
     lats = lat0 + (numpy.random.random((20, 10)) * 50 - 25)
     xx, yy = proj(lons, lats, reverse=False)
     self.assertEqual(xx.shape, (20, 10))
     self.assertEqual(yy.shape, (20, 10))
     blons, blats = proj(xx, yy, reverse=True)
     self.assertTrue(numpy.allclose(blons, lons))
     self.assertTrue(numpy.allclose(blats, lats))
예제 #5
0
def get_polygon_area(polygon):
    """
	Compute polygon area in squared kilometers.
	"""
    lons = [lon for lon, lat in polygon]
    lats = [lat for lon, lat in polygon]

    west, east, north, south = _utils.get_spherical_bounding_box(lons, lats)
    proj = _utils.get_orthographic_projection(west, east, north, south)
    xx, yy = proj(lons, lats)

    polygon2d = shapely.geometry.Polygon(zip(xx, yy))

    return polygon2d.area
def get_polygon_area(polygon):
	"""
	Compute polygon area in squared kilometers.
	"""
	lons = [lon for lon,lat in polygon]
	lats = [lat for lon,lat in polygon]
	
	west, east, north, south = _utils.get_spherical_bounding_box(lons, lats)
	proj = _utils.get_orthographic_projection(west, east, north, south)
	xx, yy = proj(lons, lats)
	
	polygon2d = shapely.geometry.Polygon(zip(xx, yy))
	
	return polygon2d.area
예제 #7
0
파일: mesh.py 프로젝트: pslh/nhlib
    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:`nhlib.geo.surface.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.
        """
        bounding_mesh = self._get_bounding_mesh(with_depths=False)
        assert bounding_mesh.depths is None
        lons, lats = bounding_mesh.lons, bounding_mesh.lats
        depths = numpy.zeros_like(lons)
        proj = geo_utils.get_orthographic_projection(
            *geo_utils.get_spherical_bounding_box(lons, lats)
        )
        xx, yy = proj(lons, lats)
        mesh_2d = numpy.array([xx, yy], dtype=float).transpose().copy()
        if len(xx) == 2:
            mesh_2d = shapely.geometry.LineString(mesh_2d)
        elif len(xx) == 1:
            mesh_2d = shapely.geometry.Point(*mesh_2d)
        elif len(xx) > 2:
            mesh_2d = shapely.geometry.Polygon(mesh_2d)
        mesh_lons, mesh_lats = mesh.lons.flatten(), mesh.lats.flatten()
        mesh_xx, mesh_yy = proj(mesh_lons, mesh_lats)

        distances = []
        for i in xrange(len(mesh_lons)):
            point_2d = shapely.geometry.Point(mesh_xx[i], mesh_yy[i])
            dist = mesh_2d.distance(point_2d)
            if dist < 500:
                # if the distance is below threshold of 500 kilometers,
                # consider the distance measured on the projection accurate
                # enough (an error doesn't exceed half km).
                distances.append(dist)
            else:
                # ... otherwise get the precise distance between bounding mesh
                # projection and the point projection using pure numerical way
                distances.append(geodetic.min_distance(
                    lons, lats, depths, mesh_lons[i], mesh_lats[i], 0
                ))
        return numpy.array(distances).reshape(mesh.shape)
예제 #8
0
    def test(self):
        polygon2d = shapely.geometry.Polygon([
            (-12, 0), (0, 14.5), (17.1, 3), (18, 0), (16.5, -3), (0, -10)
        ])
        proj = geo_utils.get_orthographic_projection(0, 0, 0, 0)
        poly = polygon.Polygon._from_2d(polygon2d, proj)
        elons = [-0.10791866, 0., 0.1537842, 0.1618781, 0.14838825, 0.]
        elats = [0., 0.13040175, 0.02697965, 0., -0.02697965, -0.0899322]
        ebbox = [-0.10791866, 0.1618781, 0.13040175, -0.0899322]
        numpy.testing.assert_allclose(poly.lons, elons)
        numpy.testing.assert_allclose(poly.lats, elats)
        numpy.testing.assert_allclose(poly._bbox, ebbox)
        self.assertIs(poly._polygon2d, polygon2d)
        self.assertIs(poly._projection, proj)

        poly = polygon.Polygon._from_2d(poly._polygon2d, poly._projection)
        numpy.testing.assert_allclose(poly.lons, elons)
        numpy.testing.assert_allclose(poly.lats, elats)
        numpy.testing.assert_allclose(poly._bbox, ebbox)
        self.assertIs(poly._polygon2d, polygon2d)
        self.assertIs(poly._projection, proj)
예제 #9
0
파일: point.py 프로젝트: GEMStudents/nhlib
    def to_polygon(self, radius):
        """
        Create a circular polygon with specified radius centered in the point.

        :param radius:
            Required radius of a new polygon, in km.
        :returns:
            Instance of :class:`~nhlib.geo.polygon.Polygon` that approximates
            a circle around the point with specified radius.
        """
        assert radius > 0
        # avoid circular imports
        from nhlib.geo.polygon import Polygon
        # get a projection that is centered in the point
        proj = geo_utils.get_orthographic_projection(
            self.longitude, self.longitude, self.latitude, self.latitude
        )
        # create a shapely object from a projected point coordinates,
        # which are supposedly (0, 0)
        point = shapely.geometry.Point(*proj(self.longitude, self.latitude))
        # extend the point to a shapely polygon using buffer()
        # and create nhlib.geo.polygon.Polygon object from it
        return Polygon._from_2d(point.buffer(radius), proj)
예제 #10
0
    def _init_polygon2d(self):
        """
        Spherical bounding box, projection, and Cartesian polygon are all
        cached to prevent redundant computations.

        If any of them are `None`, recalculate all of them.
        """
        if (self._polygon2d is None or self._projection is None
            or self._bbox is None):
            # resample polygon line segments:
            lons, lats = get_resampled_coordinates(self.lons, self.lats)

            # find the bounding box of a polygon in spherical coordinates:
            self._bbox = utils.get_spherical_bounding_box(lons, lats)

            # create a projection that is centered in a polygon center:
            self._projection = \
                utils.get_orthographic_projection(*self._bbox)

            # project polygon vertices to the Cartesian space and create
            # a shapely polygon object:
            xx, yy = self._projection(lons, lats)
            self._polygon2d = shapely.geometry.Polygon(zip(xx, yy))