Example #1
0
File: mesh.py Project: pslh/nhlib
    def triangulate(self):
        """
        Convert mesh points to vectors in Cartesian space.

        :returns:
            Tuple of four elements, each being 2d numpy array of 3d vectors
            (the same structure and shape as the mesh itself). Those arrays
            are:

            #. points vectors,
            #. vectors directed from each point (excluding the last column)
               to the next one in a same row →,
            #. vectors directed from each point (excluding the first row)
               to the previous one in a same column ↑,
            #. vectors pointing from a bottom left point of each mesh cell
               to top right one ↗.

            So the last three arrays of vectors allow to construct triangles
            covering the whole mesh.
        """
        points = geo_utils.spherical_to_cartesian(self.lons, self.lats,
                                                  self.depths)
        # triangulate the mesh by defining vectors of triangles edges:
        # →
        along_azimuth = points[:, 1:] - points[:, :-1]
        # ↑
        updip = points[:-1] - points[1:]
        # ↗
        diag = points[:-1, 1:] - points[1:, :-1]

        return points, along_azimuth, updip, diag
def _polygon_wkt_to_xyz(polygon, as_wkt=False):
    '''Converts a polygon in 'POLYGON' wkt format to xyz. If as_wkt is 
    True, will return the xyz output back as a wkt format, otherwise
    it will return an array'''
    polygon = wkt.loads(polygon)
    polygon = polygon.boundary.xy
    number_nodes = len(polygon[0])
    xyz =  spherical_to_cartesian(polygon[0], polygon[1], 
        np.zeros(number_nodes, dtype=float))
    if as_wkt:
        xyz = asPolygon(xyz[:, :-1]).wkt
    return xyz
Example #3
0
    def __init__(self, catalogue):
        '''Instantiate
        :param catalogue:
            Instance of MTKCatalogue Class
        '''
        self.catalogue = deepcopy(catalogue)
        self.time_value = decimal_time(catalogue['year'], 
                                       catalogue['month'],
                                       catalogue['day'], 
                                       catalogue['hour'], 
                                       catalogue['minute'],
                                       catalogue['second'])

        self.catalogue_mesh = Mesh(catalogue['longitude'],
                                   catalogue['latitude'],
                                   catalogue['depth'])
        if not isinstance(catalogue['xyz'], np.ndarray):
            self.catalogue['xyz'] = spherical_to_cartesian(
                self.catalogue['longitude'],
                self.catalogue['latitude'],
                self.catalogue['depth'])
        self.number_events = len(catalogue['eventID'])
Example #4
0
 def _init_plane(self):
     """
     Prepare everything needed for projecting arbitrary points on a plane
     containing the surface.
     """
     tl, tr, bl, br = geo_utils.spherical_to_cartesian(
         self.corner_lons, self.corner_lats, self.corner_depths
     )
     # these two parameters define the plane that contains the surface
     # (in 3d Cartesian space): a normal unit vector,
     self.normal = geo_utils.normalized(numpy.cross(tl - tr, tl - bl))
     # ... and scalar "d" parameter from the plane equation (uses
     # an equation (3) from http://mathworld.wolfram.com/Plane.html)
     self.d = - (self.normal * tl).sum()
     # these two 3d vectors together with a zero point represent surface's
     # coordinate space (the way to translate 3d Cartesian space with
     # a center in earth's center to 2d space centered in surface's top
     # left corner with basis vectors directed to top right and bottom left
     # corners. see :meth:`_project`.
     self.uv1 = geo_utils.normalized(tr - tl)
     self.uv2 = numpy.cross(self.normal, self.uv1)
     self.zero_zero = tl
Example #5
0
    def select_within_polygon(self, polygon, distance=None, **kwargs):
        '''Select earthquakes within polygon
        :param point:
            Centre point as instance of nhlib.geo.polygon.Polygon class
        :param distance:
            Buffer distance (km) (can take negative values)
        :returns:
            Selected catalogue (as dictionary) and number of selected events
        
        '''
        if distance:
            zone_polygon = polygon.dilate(distance)
        else:
            zone_polygon = polygon

        zone_polygon = spherical_to_cartesian(
            zone_polygon.lons,
            zone_polygon.lats, 
            np.zeros(len(zone_polygon.lons), dtype=float))
        
        # Initially all points are invalid
        valid_id = np.zeros(self.number_events, dtype=bool)
        
        # Make valid all events inside depth range
        upper_depth, lower_depth = _check_depth_limits(kwargs)
        valid_depth = np.logical_and(self.catalogue['depth'] >= upper_depth,
                                     self.catalogue['depth'] < lower_depth)
        # Events outside polygon returned to invalid assignment
        valid_id[valid_depth] = points_inside_poly(
            self.catalogue['xyz'][valid_depth, :2],
            zone_polygon[:, :2])

        number_selected = np.sum(valid_id)
        valid_id = np.logical_not(valid_id)
        return purge_catalogue(self.catalogue, valid_id.astype(int)), \
            number_selected
Example #6
0
    def _project(self, lons, lats, depths):
        """
        Project points to a surface's plane.

        Parameters are lists or numpy arrays of coordinates of points
        to project.

        :returns:
            A tuple of three items: distances between original points
            and surface's plane in km, "x" and "y" coordinates of points'
            projections to the plane (in a surface's coordinate space).
        """
        points = geo_utils.spherical_to_cartesian(lons, lats, depths)

        # uses method from http://www.9math.com/book/projection-point-plane
        dists = (self.normal * points).sum(axis=-1) + self.d
        t0 = - dists
        projs = points + self.normal * t0.reshape(t0.shape + (1, ))

        # translate projected points' to surface's coordinate space
        vectors2d = projs - self.zero_zero
        xx = (vectors2d * self.uv1).sum(axis=-1)
        yy = (vectors2d * self.uv2).sum(axis=-1)
        return dists, xx, yy
Example #7
0
 def test_from_vector(self):
     point = geo.Point(12.34, -56.78, 91.011)
     vector = spherical_to_cartesian(point.longitude, point.latitude,
                                     point.depth)
     self.assertEqual(point, geo.Point.from_vector(vector))
 def _hypocentres_to_xyz(self):
     '''Converts the catalogue hypocentres into a cartesian coordinate
     system'''
     self.data['xyz'] = spherical_to_cartesian(
         self.data['longitude'], self.data['latitude'], 
         self.data['depth'])