Beispiel #1
0
def _project_polygon_latlng_to_xy(polygon_object_latlng,
                                  centroid_latitude_deg=None,
                                  centroid_longitude_deg=None):
    """Projects polygon from lat-long to x-y coordinates.

    :param polygon_object_latlng: Instance of `shapely.geometry.Polygon`, where
        x-coordinates are actually longitudes and y-coordinates are actually
        latitudes.
    :param centroid_latitude_deg: Latitude (deg N) at polygon centroid.
    :param centroid_longitude_deg: Longitude (deg E) at polygon centroid.
    :return: polygon_object_xy: Instance of `shapely.geometry.Polygon`, where x-
        and y-coordinates are in metres.
    """

    projection_object = projections.init_lcc_projection(
        standard_latitudes_deg=numpy.full(2, centroid_latitude_deg),
        central_longitude_deg=centroid_longitude_deg)

    vertex_latitudes_deg = numpy.asarray(polygon_object_latlng.exterior.xy[1])
    vertex_longitudes_deg = numpy.asarray(polygon_object_latlng.exterior.xy[0])
    vertex_x_metres, vertex_y_metres = projections.project_latlng_to_xy(
        vertex_latitudes_deg, vertex_longitudes_deg,
        projection_object=projection_object, false_easting_metres=0.,
        false_northing_metres=0.)

    return polygons.vertex_arrays_to_polygon_object(
        vertex_x_metres, vertex_y_metres)
def init_projection(model_name):
    """Initializes projection used by model.

    :param model_name: Model name (must be accepted by `check_model_name`).
    :return: projection_object: Instance of `pyproj.Proj`, specifying the
        projection.
    """

    standard_latitudes_deg, central_longitude_deg = get_projection_params(
        model_name)

    return projections.init_lcc_projection(
        standard_latitudes_deg=standard_latitudes_deg,
        central_longitude_deg=central_longitude_deg)
Beispiel #3
0
    def test_project_xy_to_latlng(self):
        """Ensures that project_xy_to_latlng does not crash.

        This is an integration test, not a unit test, because it requires
        init_lcc_projection to create the projection object.
        """

        projection_object = projections.init_lcc_projection(
            standard_latitudes_deg=STANDARD_LATITUDES_DEG,
            central_longitude_deg=CENTRAL_LONGITUDE_DEG)

        projections.project_xy_to_latlng(
            x_coords_metres=X_COORDS_METRES,
            y_coords_metres=Y_COORDS_METRES,
            projection_object=projection_object,
            false_easting_metres=FALSE_EASTING_METRES,
            false_northing_metres=FALSE_NORTHING_METRES)
Beispiel #4
0
    def test_project_both_ways(self):
        """Ensures that the two projection methods are inverses.

        This is an integration test, not a unit test, because it calls both
        projection methods.  Also, it requires init_lcc_projection
        to create the projection object.
        """

        projection_object = projections.init_lcc_projection(
            standard_latitudes_deg=STANDARD_LATITUDES_DEG,
            central_longitude_deg=CENTRAL_LONGITUDE_DEG)

        these_x_coords_metres, these_y_coords_metres = (
            projections.project_latlng_to_xy(
                latitudes_deg=LATITUDES_DEG,
                longitudes_deg=LONGITUDES_DEG,
                projection_object=projection_object,
                false_easting_metres=FALSE_EASTING_METRES,
                false_northing_metres=FALSE_NORTHING_METRES))

        these_latitudes_deg, these_longitudes_deg = (
            projections.project_xy_to_latlng(
                x_coords_metres=these_x_coords_metres,
                y_coords_metres=these_y_coords_metres,
                projection_object=projection_object,
                false_easting_metres=FALSE_EASTING_METRES,
                false_northing_metres=FALSE_NORTHING_METRES))

        self.assertTrue(
            numpy.allclose(these_latitudes_deg,
                           LATITUDES_DEG,
                           atol=TOLERANCE,
                           equal_nan=True))
        self.assertTrue(
            numpy.allclose(these_longitudes_deg,
                           LONGITUDES_DEG,
                           atol=TOLERANCE,
                           equal_nan=True))
Beispiel #5
0
def _get_grid_point_coords(model_name,
                           first_row_in_full_grid,
                           last_row_in_full_grid,
                           first_column_in_full_grid,
                           last_column_in_full_grid,
                           grid_id=None,
                           basemap_object=None):
    """Returns x-y and lat-long coords for a subgrid of the full model grid.

    This method generates different x-y coordinates than
    `nwp_model_utils.get_xy_grid_point_matrices`, because (like
    `mpl_toolkits.basemap.Basemap`) this method sets false easting = false
    northing = 0 metres.

    :param model_name: Name of NWP model (must be accepted by
        `nwp_model_utils.check_grid_name`).
    :param first_row_in_full_grid: Row 0 in the subgrid is row
        `first_row_in_full_grid` in the full grid.
    :param last_row_in_full_grid: Last row in the subgrid is row
        `last_row_in_full_grid` in the full grid.  If you want last row in the
        subgrid to equal last row in the full grid, make this -1.
    :param first_column_in_full_grid: Column 0 in the subgrid is column
        `first_column_in_full_grid` in the full grid.
    :param last_column_in_full_grid: Last column in the subgrid is column
        `last_column_in_full_grid` in the full grid.  If you want last column in
        the subgrid to equal last column in the full grid, make this -1.
    :param grid_id: Grid for NWP model (must be accepted by
        `nwp_model_utils.check_grid_name`).
    :param basemap_object: Instance of `mpl_toolkits.basemap.Basemap` for the
        given NWP model.  If you don't have one, no big deal -- leave this
        argument empty.
    :return: coordinate_dict: Dictionary with the following keys.
    coordinate_dict['grid_point_x_matrix_metres']: M-by-N numpy array of
        x-coordinates.
    coordinate_dict['grid_point_y_matrix_metres']: M-by-N numpy array of
        y-coordinates.
    coordinate_dict['grid_point_lat_matrix_deg']: M-by-N numpy array of
        latitudes (deg N).
    coordinate_dict['grid_point_lng_matrix_deg']: M-by-N numpy array of
        longitudes (deg E).
    """

    num_rows_in_full_grid, num_columns_in_full_grid = (
        nwp_model_utils.get_grid_dimensions(model_name=model_name,
                                            grid_name=grid_id))

    error_checking.assert_is_integer(first_row_in_full_grid)
    error_checking.assert_is_geq(first_row_in_full_grid, 0)
    error_checking.assert_is_integer(last_row_in_full_grid)
    if last_row_in_full_grid < 0:
        last_row_in_full_grid += num_rows_in_full_grid

    error_checking.assert_is_greater(last_row_in_full_grid,
                                     first_row_in_full_grid)
    error_checking.assert_is_less_than(last_row_in_full_grid,
                                       num_rows_in_full_grid)

    error_checking.assert_is_integer(first_column_in_full_grid)
    error_checking.assert_is_geq(first_column_in_full_grid, 0)
    error_checking.assert_is_integer(last_column_in_full_grid)
    if last_column_in_full_grid < 0:
        last_column_in_full_grid += num_columns_in_full_grid

    error_checking.assert_is_greater(last_column_in_full_grid,
                                     first_column_in_full_grid)
    error_checking.assert_is_less_than(last_column_in_full_grid,
                                       num_columns_in_full_grid)

    grid_point_lat_matrix_deg, grid_point_lng_matrix_deg = (
        nwp_model_utils.get_latlng_grid_point_matrices(model_name=model_name,
                                                       grid_name=grid_id))

    grid_point_lat_matrix_deg = grid_point_lat_matrix_deg[
        first_row_in_full_grid:(last_row_in_full_grid + 1),
        first_column_in_full_grid:(last_column_in_full_grid + 1)]

    grid_point_lng_matrix_deg = grid_point_lng_matrix_deg[
        first_row_in_full_grid:(last_row_in_full_grid + 1),
        first_column_in_full_grid:(last_column_in_full_grid + 1)]

    if basemap_object is None:
        standard_latitudes_deg, central_longitude_deg = (
            nwp_model_utils.get_projection_params(model_name))

        projection_object = projections.init_lcc_projection(
            standard_latitudes_deg=standard_latitudes_deg,
            central_longitude_deg=central_longitude_deg)

        grid_point_x_matrix_metres, grid_point_y_matrix_metres = (
            projections.project_latlng_to_xy(
                latitudes_deg=grid_point_lat_matrix_deg,
                longitudes_deg=grid_point_lng_matrix_deg,
                projection_object=projection_object,
                false_northing_metres=0.,
                false_easting_metres=0.))
    else:
        grid_point_x_matrix_metres, grid_point_y_matrix_metres = basemap_object(
            grid_point_lng_matrix_deg, grid_point_lat_matrix_deg)

    return {
        X_COORD_MATRIX_KEY: grid_point_x_matrix_metres,
        Y_COORD_MATRIX_KEY: grid_point_y_matrix_metres,
        LATITUDE_MATRIX_KEY: grid_point_lat_matrix_deg,
        LONGITUDE_MATRIX_KEY: grid_point_lng_matrix_deg,
    }
Beispiel #6
0
    def test_init_lcc_projection_no_crash(self):
        """Ensures that init_lcc_projection does not crash."""

        projections.init_lcc_projection(
            standard_latitudes_deg=STANDARD_LATITUDES_DEG,
            central_longitude_deg=CENTRAL_LONGITUDE_DEG)
Beispiel #7
0
def _run(input_shapefile_name, output_pickle_file_name):
    """Converts SPC convective outlook to nicer file format.

    This is effectively the main method.

    :param input_shapefile_name: See documentation at top of file.
    :param output_pickle_file_name: Same.
    """

    projection_object = projections.init_lcc_projection(
        standard_latitudes_deg=STANDARD_LATITUDES_DEG,
        central_longitude_deg=CENTRAL_LONGITUDE_DEG,
        ellipsoid_name=ELLIPSOID_NAME)

    print('Reading data from: "{0:s}"...'.format(input_shapefile_name))
    shapefile_handle = shapefile.Reader(input_shapefile_name)

    list_of_polygon_objects_latlng = []
    risk_type_strings = []

    for this_record_object in shapefile_handle.iterShapeRecords():
        # print this_record_object.record
        this_risk_type_enum = this_record_object.record[RISK_TYPE_INDEX]

        try:
            this_risk_type_string = RISK_TYPE_ENUM_TO_STRING[
                this_risk_type_enum]
        except KeyError:
            continue

        these_xy_tuples = this_record_object.shape.points
        this_num_vertices = len(these_xy_tuples)

        these_x_coords_metres = numpy.array(
            [these_xy_tuples[k][0] for k in range(this_num_vertices)])

        these_y_coords_metres = numpy.array(
            [these_xy_tuples[k][1] for k in range(this_num_vertices)])

        these_latitudes_deg, these_longitudes_deg = (
            projections.project_xy_to_latlng(
                x_coords_metres=these_x_coords_metres,
                y_coords_metres=these_y_coords_metres,
                projection_object=projection_object,
                false_easting_metres=FALSE_EASTING_METRES,
                false_northing_metres=FALSE_NORTHING_METRES))

        this_polygon_object_latlng = (polygons.vertex_arrays_to_polygon_object(
            exterior_x_coords=these_longitudes_deg,
            exterior_y_coords=these_latitudes_deg))

        risk_type_strings.append(this_risk_type_string)
        list_of_polygon_objects_latlng.append(this_polygon_object_latlng)

    outlook_dict = {
        RISK_TYPE_COLUMN: risk_type_strings,
        POLYGON_COLUMN: list_of_polygon_objects_latlng
    }

    outlook_table = pandas.DataFrame.from_dict(outlook_dict)
    # print(outlook_table)

    print('Writing outlook polygons to file: "{0:s}"...'.format(
        output_pickle_file_name))

    file_system_utils.mkdir_recursive_if_necessary(
        file_name=output_pickle_file_name)

    pickle_file_handle = open(output_pickle_file_name, 'wb')
    pickle.dump(outlook_table, pickle_file_handle)
    pickle_file_handle.close()
Beispiel #8
0
def create_equidistant_grid(min_latitude_deg,
                            max_latitude_deg,
                            min_longitude_deg,
                            max_longitude_deg,
                            x_spacing_metres,
                            y_spacing_metres,
                            azimuthal=True):
    """Creates equidistant grid.

    M = number of rows
    N = number of columns

    :param min_latitude_deg: Minimum latitude (deg N) in grid.
    :param max_latitude_deg: Max latitude (deg N) in grid.
    :param min_longitude_deg: Minimum longitude (deg E) in grid.
    :param max_longitude_deg: Max longitude (deg E) in grid.
    :param x_spacing_metres: Spacing between grid points in adjacent columns.
    :param y_spacing_metres: Spacing between grid points in adjacent rows.
    :param azimuthal: Boolean flag.  If True, will create azimuthal equidistant
        grid.  If False, will create Lambert conformal grid.
    :return: grid_dict: Dictionary with the following keys.
    grid_dict['grid_point_x_coords_metres']: length-N numpy array with unique
        x-coordinates at grid points.
    grid_dict['grid_point_y_coords_metres']: length-M numpy array with unique
        y-coordinates at grid points.
    grid_dict['projection_object']: Instance of `pyproj.Proj` (used to convert
        between lat-long coordinates and the x-y coordinates of the grid).
    """

    # Check input args.
    error_checking.assert_is_valid_latitude(min_latitude_deg)
    error_checking.assert_is_valid_latitude(max_latitude_deg)
    error_checking.assert_is_greater(max_latitude_deg, min_latitude_deg)
    error_checking.assert_is_greater(x_spacing_metres, 0.)
    error_checking.assert_is_greater(y_spacing_metres, 0.)
    error_checking.assert_is_boolean(azimuthal)

    min_longitude_deg = lng_conversion.convert_lng_negative_in_west(
        min_longitude_deg, allow_nan=False)
    max_longitude_deg = lng_conversion.convert_lng_negative_in_west(
        max_longitude_deg, allow_nan=False)
    error_checking.assert_is_greater(max_longitude_deg, min_longitude_deg)

    # Create lat-long grid.
    num_grid_rows = 1 + int(
        numpy.round((max_latitude_deg - min_latitude_deg) /
                    DUMMY_LATITUDE_SPACING_DEG))
    num_grid_columns = 1 + int(
        numpy.round((max_longitude_deg - min_longitude_deg) /
                    DUMMY_LONGITUDE_SPACING_DEG))

    unique_latitudes_deg, unique_longitudes_deg = get_latlng_grid_points(
        min_latitude_deg=min_latitude_deg,
        min_longitude_deg=min_longitude_deg,
        lat_spacing_deg=DUMMY_LATITUDE_SPACING_DEG,
        lng_spacing_deg=DUMMY_LONGITUDE_SPACING_DEG,
        num_rows=num_grid_rows,
        num_columns=num_grid_columns)

    latitude_matrix_deg, longitude_matrix_deg = latlng_vectors_to_matrices(
        unique_latitudes_deg=unique_latitudes_deg,
        unique_longitudes_deg=unique_longitudes_deg)

    # Create projection.
    central_latitude_deg = 0.5 * (min_latitude_deg + max_latitude_deg)
    central_longitude_deg = 0.5 * (min_longitude_deg + max_longitude_deg)

    if azimuthal:
        projection_object = projections.init_azimuthal_equidistant_projection(
            central_latitude_deg=central_latitude_deg,
            central_longitude_deg=central_longitude_deg)
    else:
        projection_object = projections.init_lcc_projection(
            standard_latitudes_deg=numpy.full(2, central_latitude_deg),
            central_longitude_deg=central_longitude_deg)

    # Convert lat-long grid to preliminary x-y grid.
    prelim_x_matrix_metres, prelim_y_matrix_metres = (
        projections.project_latlng_to_xy(latitudes_deg=latitude_matrix_deg,
                                         longitudes_deg=longitude_matrix_deg,
                                         projection_object=projection_object))

    # Find corners of preliminary x-y grid.
    x_min_metres = numpy.min(prelim_x_matrix_metres)
    x_max_metres = numpy.max(prelim_x_matrix_metres)
    y_min_metres = numpy.min(prelim_y_matrix_metres)
    y_max_metres = numpy.max(prelim_y_matrix_metres)

    # Find corners of final x-y grid.
    x_min_metres = number_rounding.floor_to_nearest(x_min_metres,
                                                    x_spacing_metres)
    x_max_metres = number_rounding.ceiling_to_nearest(x_max_metres,
                                                      x_spacing_metres)
    y_min_metres = number_rounding.floor_to_nearest(y_min_metres,
                                                    y_spacing_metres)
    y_max_metres = number_rounding.ceiling_to_nearest(y_max_metres,
                                                      y_spacing_metres)

    # Create final x-y grid.
    num_grid_rows = 1 + int(
        numpy.round((y_max_metres - y_min_metres) / y_spacing_metres))
    num_grid_columns = 1 + int(
        numpy.round((x_max_metres - x_min_metres) / x_spacing_metres))

    unique_x_coords_metres, unique_y_coords_metres = get_xy_grid_points(
        x_min_metres=x_min_metres,
        y_min_metres=y_min_metres,
        x_spacing_metres=x_spacing_metres,
        y_spacing_metres=y_spacing_metres,
        num_rows=num_grid_rows,
        num_columns=num_grid_columns)

    return {
        X_COORDS_KEY: unique_x_coords_metres,
        Y_COORDS_KEY: unique_y_coords_metres,
        PROJECTION_KEY: projection_object
    }