def find_polygons(
        points,
        polygons,
        polygon_proxies=None,
        all_polygons=False,
        subdivision_depth=points_spatial_tree.DEFAULT_SUBDIVISION_DEPTH):
    """
    Efficient point-in-polygon testing when there are many relatively uniformly spaced points to be tested against polygons.
    
    points: a sequence of 'pygplates.PointOnSphere'.
    
    polygons: a sequence of 'pygplates.PolygonOnSphere'.
    
    polygon_proxies: Optional sequence of objects associated with 'polygons'.
                     If not specified then the proxies default to the polygons themselves.
                     These can be any object (such as the 'pygplates.Feature' that the polygon came from).
    
    all_polygons: Whether to find all polygons containing each point or just the first one encountered.
                  Set to True if polygons overlap each other, otherwise set to False (for non-overlapping polygons).
                  Defaults to False (non-overlapping polygons).
    
    subdivision_depth: The depth of the lat/lon quad tree used to speed up point-in-polygon queries.
                       The lat/lon width of a leaf quad tree node is (90 / (2^subdivision_depth)) degrees.
                       Generally the denser the 'points' the larger the depth should be.
                       Setting this value too high causes unnecessary time to be spent generating a deep quad tree.
                       Setting this value too low reduces the culling efficiency of the quad tree.
                       However a value of 4 seems to work quite well for a uniform lat/lon spacing of 'points' of 1 degree and below
                       without the cost of generating a deep quad tree.
                       So most of the time the subdivision depth can be left at its default value.
    
    Returns: A list of polygon proxies associated with 'points'.
             The length of the returned list matches the length of 'points'.
             For each point in 'points', if the point is contained by a polygon then that polygon's proxy
             is stored (otherwise None is stored) at the same index (as the point) in the returned list.
             If 'all_polygons' is False then each item in returned list is a single polygon proxy (or a single None).
             If 'all_polygons' is True then each item in returned list is a *list* of polygon proxies (or a single None).
    
    Raises ValueError if the lengths of 'polygons' and 'polygon_proxies' (if specified) do not match.
    """

    spatial_tree_of_points = points_spatial_tree.PointsSpatialTree(
        points, subdivision_depth)
    return find_polygons_using_points_spatial_tree(points,
                                                   spatial_tree_of_points,
                                                   polygons, polygon_proxies,
                                                   all_polygons)
Пример #2
0
def reconstruct_raster(raster_class,
                       static_polygons,
                       rotation_model,
                       time_from,
                       time_to,
                       grid_sampling=1.,
                       anchor_plate_id=0,
                       sampling_method='scipy'):

    grid_longitudes, grid_latitudes = np.meshgrid(
        np.arange(-180., 180.0001, grid_sampling),
        np.arange(-90., 90.0001, grid_sampling))
    grid_longitudes = grid_longitudes.flatten()
    grid_latitudes = grid_latitudes.flatten()

    points = [
        pygplates.PointOnSphere(point)
        for point in zip(grid_latitudes, grid_longitudes)
    ]

    spatial_tree_of_uniform_recon_points = points_spatial_tree.PointsSpatialTree(
        points)

    (time_to_point_lons, time_to_point_lats, time_from_point_lons,
     time_from_point_lats) = reconstruct_raster_stage(
         static_polygons, rotation_model, time_from, time_to, points,
         spatial_tree_of_uniform_recon_points, anchor_plate_id)

    if sampling_method == 'scipy':
        point_raster_values = raster_class.sample(time_from_point_lons,
                                                  time_from_point_lats)
    elif sampling_method == 'gmt':
        point_raster_values = raster_class.sample_using_gmt(
            time_from_point_lons, time_from_point_lats)
    elif sampling_method == 'stripy':
        point_raster_values = raster_class.sample_using_stripy(
            time_from_point_lons, time_from_point_lats)

    return time_to_point_lons, time_to_point_lats, point_raster_values
Пример #3
0
def find_closest_points_to_geometries(
        geometries,
        points,
        point_proxies=None,
        distance_threshold_radians=None,
        return_closest_position=False,
        return_closest_index=False,
        geometries_are_solid=False,
        all_points=False,
        subdivision_depth=points_spatial_tree.DEFAULT_SUBDIVISION_DEPTH,
        point_filter=None):
    """
    Efficient geometry-to-point distance queries when geometries are tested against many relatively uniformly spaced points.
    
    geometries: a sequence of 'pygplates.GeometryOnSphere'.
    
    points: a sequence of 'pygplates.PointOnSphere'.
    
    point_proxies: Optional sequence of objects associated with 'points'.
                   If not specified then the proxies default to the points themselves.
                   These can be any object (such as a scalar value associated with the point).
    
    distance_threshold_radians: Optional distance threshold in radians - threshold should be in the range [0,PI] if specified.
    
    return_closest_position: Whether to also return the closest point on each geometry - default is False.
    
    return_closest_index: Whether to also return the index of the closest point (for multi-points) or
                          the index of the closest segment (for polylines and polygons) - default is False.
    
    geometries_are_solid: Whether the interiors of the geometries are solid or not - only applies to polygon geometries - default is False.
    
    all_points: Whether to find all points near each geometry (within threshold distance) or just the closest.
                Defaults to False (only returns closest point to each geometry).
    
    subdivision_depth: The depth of the lat/lon quad tree used to speed up point-to-geometry distance queries.
                       The lat/lon width of a leaf quad tree node is (90 / (2^subdivision_depth)) degrees.
                       Generally the denser the 'points' the larger the depth should be.
                       Setting this value too high causes unnecessary time to be spent generating a deep quad tree.
                       Setting this value too low reduces the culling efficiency of the quad tree.
                       However a value of 4 seems to work quite well for a uniform lat/lon spacing of 'points' of 1 degree and below
                       without the cost of generating a deep quad tree.
                       So most of the time the subdivision depth can be left at its default value.
    
    Returns: A list of point proxies associated with 'geometries'.
             The length of the returned list matches the length of 'geometries'.
             For each geometry in 'geometries', if the geometry is close to a point then that point's proxy (and its distance information)
             is stored (otherwise None is stored) at the same index (as the geometry) in the returned list.
             If 'all_points' is False then each item in returned list is a single point proxy (and its distance information)
             representing the closest point within threshold distance (or a single None).
             If 'all_points' is True then each item in returned list is a *list* of point proxies (and their distance informations)
             representing all points within threshold distance (or a single None).
             Above we mentioned "point proxy (and its distance information)". This is a tuple whose size depends on
             the values of 'return_closest_position' and 'return_closest_index' according to...
             
                if return_closest_position and return_closest_index:
                    point_proxy_to_point = (distance, closest_position, closest_index, point_proxy)
                elif return_closest_position:
                    point_proxy_to_point = (distance, closest_position, point_proxy)
                elif return_closest_index:
                    point_proxy_to_point = (distance, closest_index, point_proxy)
                else:
                    point_proxy_to_point = (distance, point_proxy)
    
    The arguments 'distance_threshold_radians', 'return_closest_position', 'return_closest_index' and 'geometries_are_solid' are
    similar to those in pygplates.GeometryOnSphere.distance()...
    See http://www.gplates.org/docs/pygplates/generated/pygplates.GeometryOnSphere.html#pygplates.GeometryOnSphere.distance
    
    Raises ValueError if the lengths of 'points' and 'point_proxies' (if specified) do not match.
    """

    spatial_tree_of_points = points_spatial_tree.PointsSpatialTree(
        points, subdivision_depth)

    return find_closest_points_to_geometries_using_points_spatial_tree(
        geometries, points, spatial_tree_of_points, point_proxies,
        distance_threshold_radians, return_closest_position,
        return_closest_index, geometries_are_solid, all_points, point_filter)
def query_raster_at_points(raster_filename,
                           query_points,
                           search_radius_radians,
                           smoothing_radius_radians=None):
    """
    Query the raster at query points.
    
    raster_filename: The filename of the raster/grid file.
    
    query_points: The query points as a sequence of pygplates.PointOnSphere.
    
    search_radius_radians: The distance (in radians) from query point to search for non-NaN raster grid values.
                           If none are found for a query point then it will have a query scalar value of NaN.
    
    smoothing_radius_radians: Determines which non-NaN raster grid values (if any) to use in a weighted average for a query point.
                              All points within a radius of 'min_dist + smoothing_radius_radians' of the query point are included
                              (where 'min_dist' is the distance to the closest non-NaN raster grid location).
                              Note that 'smoothing_radius_radians' should be less than 'search_radius_radians'.
                              Default value is None which results in only the closest non-NaN raster grid value being chosen.
    
    Returns a list raster scalars associated with the query points (one scalar per query point).
    Each scalar value is either:
    - sampled from raster (at query point location), or
    - the nearest raster value(s) if query point is in masked (NaN) region of raster (and within search radius), or
    - NaN if there are no non-NaN grid values within search radius.
    """

    # Get a list of points and a list of scalar for each pixel node location in raster (excluding no-data nodes).
    raster_grid_points, raster_grid_scalars = get_raster_grid_positions_and_scalars(
        raster_filename)

    # Reuse the spatial tree of raster grid points since it's expensive to generate.
    raster_grid_points_spatial_tree = points_spatial_tree.PointsSpatialTree(
        raster_grid_points)

    # Find the closest raster grid points near each query point (within threshold distance).
    #
    # Note that this only finds the closest raster grid point to each query point.
    # If smoothing is enabled then another search will be done with a smoothing radius around closest point (per-query-point).
    raster_grid_points_closest_to_query_points = proximity_query.find_closest_points_to_geometries_using_points_spatial_tree(
        query_points,
        raster_grid_points,
        raster_grid_points_spatial_tree,
        # Indices into the raster grid points and scalars...
        list(range(len(raster_grid_points))),
        distance_threshold_radians=search_radius_radians)

    # List of associated raster values at query point locations.
    query_scalars = []

    # Iterate over the query points to get the closest raster grid point (to each query point).
    for query_point_index, closest_raster_grid_point_distance_and_index in enumerate(
            raster_grid_points_closest_to_query_points):
        if closest_raster_grid_point_distance_and_index is not None:
            # Get the closest raster grid point to the current query point.
            _, closest_raster_grid_point_index = closest_raster_grid_point_distance_and_index

            # We'll need to collect more than just the closest raster grid value if smoothing is enabled.
            if smoothing_radius_radians is not None:
                # Find the raster grid points within smoothing radius of closest raster grid point to the current query point.
                raster_grid_point_scalars_to_weight = proximity_query.find_closest_points_to_geometry_using_points_spatial_tree(
                    raster_grid_points[closest_raster_grid_point_index],
                    raster_grid_points,
                    raster_grid_points_spatial_tree,
                    raster_grid_scalars,
                    distance_threshold_radians=smoothing_radius_radians,
                    all_points=True)

                # Calculate distance-weighted average of closest raster scalar values.
                sum_weights = 0.0
                sum_weighted_scalars = 0.0
                for distance, scalar in raster_grid_point_scalars_to_weight:
                    # Weight range is [0.1, 1.0] for distance range [smoothing_radius_radians, 0.0].
                    weight = (
                        (smoothing_radius_radians * smoothing_radius_radians) /
                        (smoothing_radius_radians * smoothing_radius_radians +
                         9 * distance * distance))
                    sum_weights += weight
                    sum_weighted_scalars += weight * scalar

                query_point_scalar = sum_weighted_scalars / sum_weights
            else:
                # No smoothing so just choose the scalar value of the closest raster grid point.
                query_point_scalar = raster_grid_scalars[
                    closest_raster_grid_point_index]

        else:
            query_point_scalar = float('nan')

        query_scalars.append(query_point_scalar)

    return query_scalars