Esempio n. 1
0
    def test_shift_points_by_meters_test(self):
        east_shift_meters = 1
        north_shift_meters = 1
        world_poly_4326 = wkt_loader(
            "POLYGON((-77.12352759307811 38.969453670463515,-76.92302710479686 "
            "38.969453670463515,-76.92302710479686 38.834794725571776,-77.12352759307811 "
            "38.834794725571776,-77.12352759307811 38.969453670463515))")
        world_poly_3857 = photogram.reproject_geometry(world_poly_4326,
                                                       crs_defs.PROJ_4326,
                                                       crs_defs.PROJ_3857)
        x_points_4326 = np.array(world_poly_4326.boundary.xy[0])
        y_points_4326 = np.array(world_poly_4326.boundary.xy[1])

        x_points_3857 = np.array(world_poly_3857.boundary.xy[0])
        y_points_3857 = np.array(world_poly_3857.boundary.xy[1])
        shifted_points_4326 = photogram.shift_points_by_meters(
            east_shift_meters, north_shift_meters, crs_defs.PROJ_4326,
            x_points_4326, y_points_4326)

        reprojected_shifted = proj_transform(crs_defs.PROJ_4326,
                                             crs_defs.PROJ_3857,
                                             shifted_points_4326[0],
                                             shifted_points_4326[1])

        assert shifted_points_4326[0][0] > x_points_4326[0]
        assert shifted_points_4326[1][0] > y_points_4326[0]

        north_shift = reprojected_shifted[0][0] - x_points_3857[0]
        east_shift = reprojected_shifted[1][0] - y_points_3857[0]

        assert np.isclose(east_shift_meters, east_shift)
        assert np.isclose(north_shift_meters, north_shift)
        print("shift by meters test passed")
Esempio n. 2
0
    def pixel_x_y_to_lon_lat_alt(
            self,
            pixels_x,  # type: ndarray
            pixels_y,  # type: ndarray
            dem,  # type: AbstractDem
            world_proj=None,  # type: Proj
            dem_sample_distance=None,  # type: float
            dem_highest_alt=None,  # type: float
            dem_lowest_alt=None,  # type: float
            band=None,  # type: int
    ):  # type: (...) -> (float, float, float)
        """
        Solves for pixel x, y by casting rays onto a DEM.  Uses _pixel_x_y_to_lon_lat_ray_caster_native under the hood
        and provides some convenience to the user, such as automatic handling of world projections
        :param pixels_x: x pixels, as a 1d or 2d numpy ndarray
        :param pixels_y: y pixels, as a 1d or 2d numpy ndarray
        :param dem: concrete implementation of an AbstractDem, defaults to a flat earth DEM with an elevation of zero if
        this parameter is not provided.
        :param world_proj: world projection of the output longitudes and latitudes.
        :param dem_sample_distance: sample distance to use when sampling the DEM.  Defaults to 5 meters
        :param dem_highest_alt: Highest DEM altitude.  This will be calculated using the full DEM if it is not provided
        :param dem_lowest_alt: Lowest DEM altitude.  This will be calculated using the full DEM if it is not provided
        :param band: Image band, as an int, or None if all of the image bands are coregistered.
        :return: (longitude, latitude, altitude) in the projection specified by the world_proj input parameter, and
        The altitude specified by the input dem object parameter.
        """

        DEFAULT_DEM_SAMPLE_DISTANCE = 5
        if dem_sample_distance is None:
            dem_sample_distance = DEFAULT_DEM_SAMPLE_DISTANCE

        if world_proj is None:
            world_proj = self.get_projection()

        native_lons, native_lats, native_alts = self._pixel_x_y_to_lon_lat_ray_caster_native(
            pixels_x,
            pixels_y,
            dem,
            dem_sample_distance,
            dem_highest_alt,
            dem_lowest_alt,
            band=band)

        if world_proj.srs != self.get_projection().srs:
            lons, lats = proj_transform(self.get_projection(), world_proj,
                                        native_lons, native_lats)
            return lons, lats, native_alts
        else:
            return native_lons, native_lats, native_alts
Esempio n. 3
0
 def pixel_x_y_alt_to_lon_lat(
         self,
         pixel_xs,  # type: ndarray
         pixel_ys,  # type: ndarray
         alts,  # type: ndarray
         world_proj=None,  # type: Proj
         band=None,  # type: int
         pixel_error_threshold=0.01,  # type: float
         max_iter=1000,  # type: int
 ):  # type: (...) -> (ndarray, ndarray)
     """
     This will calculate a pixel's lon / lat location on earth.  It uses _pixel_x_y_alt_to_lon_lat_native under the
     hood, and if that method is not implemented it will solve iteratively using _pixel_x_y_alt_to_lon_lat_native_solver.
     It provides conveniences to users such as automatic handling of world projections, and allows the user to input
     either numbers, or 1d or 2d numpy arrays as inputs for pixel values and altitudes.
     :param pixel_xs: x pixels, as either a float or 1d or 2d numpy array
     :param pixel_ys: y pixels, as either a float or 1d or 2d numpy array
     :param alts: altitudes in the point calculator's native elevation datum reference, provided as a numpy ndarray
     :param world_proj: projection of the input longitudes and latitudes
     :param band: band number of the image
     :param pixel_error_threshold: pixel threshold to use if the iterative solver is used. Defaults to 0.01 pixels
     :param max_iter: maximum iteration.  This is used if the iterative solver does not converge to avoid entering
     an infinite loop.  Defaults to 1000 iterations.
     :return: (lon, lat) as a tuple of float, or tuple of 1d or 2d numpy ndarray, to match the input of pixel_xs, and pixel_ys
     """
     if world_proj is None:
         world_proj = self.get_projection()
     if self._pixel_x_y_alt_to_lon_lat_native(pixel_xs, pixel_ys, alts,
                                              band) is not None:
         native_lons, native_lats = self._pixel_x_y_alt_to_lon_lat_native(
             pixel_xs, pixel_ys, alts, band=band)
     else:
         native_lons, native_lats = \
             self._pixel_x_y_alt_to_lon_lat_native_solver(pixel_xs,
                                                          pixel_ys,
                                                          alts,
                                                          band=band,
                                                          max_pixel_error=pixel_error_threshold,
                                                          max_iter=max_iter)
     if world_proj.srs != self.get_projection().srs:
         lons, lats = proj_transform(self.get_projection(), world_proj,
                                     native_lons, native_lats)
         return lons, lats
     else:
         return native_lons, native_lats
Esempio n. 4
0
def transform_points(points):
    """
    Tranform the projection of points from WGS84 to Web Mercator
    Spatial analysis is usually under projected coordinate system.

    Parameters
    ----------
    points : [type]
        [description]
    
    """
    wgs_84 = Proj("+init=epsg:4326")
    web_mercator = Proj("+init=epsg:3857")

    trans_points = []
    for point in points:
        tp = proj_transform(wgs_84, web_mercator, point[0], point[1])
        trans_points.append(tp)

    return trans_points
# In the cell below, get the upper left col,row (ul_col,ul_row) and upper left and lower
# right x,y (ul_x,ul_y,lr_x,lr_y)
# coordinates the upper left corner of
# your subscene as in the image_zoom notebook.  Use ul_col, ul_row, ul_x, ul_y plus your subscene
# width and height to make a rasterio window and new transform.
#
#     window=Window(ul_col, ul_row, small_width, small_height)
#     new_affine=Affine(30.,0.,ul_x,0.,-30.,ul_y)
#     extent = [ul_x,lr_x,lr_y,ul_y]
#

# %% {"nbgrader": {"grade": true, "grade_id": "cell-5d894d6363b58394", "locked": false, "points": 10, "schema_version": 1, "solution": true}}
### BEGIN SOLUTION
ubc_lon = -123.2460
ubc_lat = 49.2606
ubc_x, ubc_y = proj_transform(p_lonlat, p_utm, ubc_lon, ubc_lat)
ubc_col, ubc_row = ~big_transform * (ubc_x, ubc_y)
ubc_col, ubc_row = int(ubc_col), int(ubc_row)
l_col_offset = -100
t_row_offset = -100
width = 200
height = 200
ul_col = ubc_col + l_col_offset
ul_row = ubc_row + t_row_offset
ul_x, ul_y = big_transform * (ul_col, ul_row)
lr_x, lr_y = big_transform * (ul_col + width, ul_row + height)
small_window = Window(ul_col, ul_row, width, height)
new_affine = Affine(30., 0., ul_x, 0., -30., ul_y)
extent = [ul_x, lr_x, lr_y, ul_y]
### END SOLUTION
Esempio n. 6
0
    def lon_lat_alt_to_pixel_x_y(
        self,
        lons,  # type: ndarray
        lats,  # type: ndarray
        alts,  # type: ndarray
        world_proj=None,  # type: Proj
        band=None  # type: int
    ):  # type: (...) -> (ndarray, ndarray)
        """
        This method calculates pixel x / y values given longitude, latitude and altitude information.  It uses
        _lon_lat_alt_to_pixel_x_y_native under the hood, and provides some convenience to the user.  These
        conveniences include automatic handling of different projections, and also allows the user to input
        longitudes, latitudes and altidues as either 1d or 2d numpy arrays.  The results will be output in the
        same dimensions as the inputs.
        :param lons: longitudes provided as a numpy ndarray, can be either 1d or 2d numpy array, or a single float value
        :param lats: latitudes provided as a numpy ndarray, can be either 1d or 2d numpy array, or a single float value
        :param alts: altitudes in the point calculator's native elevation datum reference, provided as a numpy ndarray
        :param world_proj: projection of the input longitudes and latitudes
        :param band: specific image band provided as an int.  If this variable is None it assumes all bands are coregistered
        :return: (pixel x, pixel y) as a tuple of numpy ndarrays (1d or 2d), or a tuple of float.  The output will match the input
        """
        # check for some errors up front
        if alts is None:
            alts = 0
        # standardize inputs, make everything 1 dimensional ndarrays
        lons_is_number = isinstance(lons, numbers.Number)
        lats_is_number = isinstance(lats, numbers.Number)
        alts_is_number = isinstance(alts, numbers.Number)
        if lons_is_number or lats_is_number:
            lons = np.array([lons])
            lats = np.array([lats])
        if alts_is_number:
            alts = np.zeros(lons.shape) + alts
        world_xyz_is_2d = False
        # auto-detect if world x-y-z arrays are 2d and flatten world_x and world_y arrays they are are 2d.
        # This is done to make all the vector math less complicated and keep it fast without needing to use loops
        if np.ndim(lons) == 2:
            world_xyz_is_2d = True
            nx = np.shape(lons)[1]
            ny = np.shape(lons)[0]
            lons = np.reshape(lons, nx * ny)
            lats = np.reshape(lats, nx * ny)
            alts = np.reshape(alts, nx * ny)

        # now actually do the calculations with everything in a standard form
        if world_proj is None:
            world_proj = self.get_projection()
        if world_proj.srs != self.get_projection().srs:
            lons, lats, alts = proj_transform(world_proj,
                                              self.get_projection(), lons,
                                              lats, alts)
        pixel_coords = self._lon_lat_alt_to_pixel_x_y_native(
            lons, lats, alts, band)

        if lons_is_number or lats_is_number:
            pixel_coords = pixel_coords[0][0], pixel_coords[1][0]

        # now transform everything back if it wasn't in a standard form coming in
        # unflatten world_xyz arrays if the original inputs were 2d
        if world_xyz_is_2d:
            pixel_coords_x_2d = np.reshape(pixel_coords[0], (ny, nx))
            pixel_coords_y_2d = np.reshape(pixel_coords[1], (ny, nx))
            return pixel_coords_x_2d, pixel_coords_y_2d

        return pixel_coords
Esempio n. 7
0
fig, ax = plt.subplots(1, 1,figsize=[8,8],
                       subplot_kw={'projection': cartopy_crs})
image_extent=[ul_x,lr_x,lr_y,ul_y]
ax.imshow(b2_refl,cmap=cmap_ref,norm=the_norm,origin="upper",
      extent=image_extent,transform=cartopy_crs);
ax.coastlines(resolution='10m',color='red',lw=2);


# # confirm that pyproj and NASA agree
# 
# Convert the lower right corner from x,y to lon, lat and
# check against the metadata

# In[6]:


print(f"x,y coords of lr corner: {lr_x,lr_y}")
p_utm_18N_nasa = Proj(cartopy_crs_zone.proj4_init)
p_latlon=Proj(proj='latlong',datum='WGS84')
out =proj_transform(p_utm_18N_nasa,p_latlon,lr_x,lr_y)
print(f"pyproj lon,lat {out}")
nasa_lr=meta_dict['CORNER_LR_LON_PRODUCT'],meta_dict['CORNER_LR_LAT_PRODUCT']
print(f"nasa metadata lon,lat {out}")
#
# note that the transform will default to p_latlon, so we don't really
# need to specify it if we don't want to
#
out=p_utm_18N_nasa(lr_x,lr_y,inverse=True)
print(f"pyproj lon,lat for lr corner: {out}")

proj_params = get_proj_params(generic_m3)
swath_def = SwathDefinition(lons, lats)
area_def = swath_def.compute_optimal_bb_area(proj_dict=proj_params)
area_def

# %%
print(swath_def.shape)
print(area_def.shape)

# %% {"scrolled": false}
#p_utm = Proj(crs)
p_lonlat = Proj(proj='latlong', datum='WGS84')
stn_lon = -105.237
stn_lat = 40.125
stn_x, stn_y = proj_transform(p_lonlat, Proj(area_def.proj_dict), stn_lon,
                              stn_lat)
min_x, min_y = proj_transform(p_lonlat, Proj(area_def.proj_dict),
                              metadata['min_lon'], metadata['min_lat'])
max_x, max_y = proj_transform(p_lonlat, Proj(area_def.proj_dict),
                              metadata['max_lon'], metadata['max_lat'])

# %%
crs = area_def.to_cartopy_crs()
fig, ax = plt.subplots(1, 1, figsize=(10, 10), subplot_kw={'projection': crs})
ax.gridlines(linewidth=2)
ax.add_feature(cartopy.feature.GSHHSFeature(levels=[1, 2, 3]))
#scale='coarse'

ax.set_extent(crs.bounds, crs)
ax.scatter(0, 0, marker='o', color='k', label='Projection centre')
ax.scatter(stn_x, stn_y, marker='x', color='r', label='station location')
Esempio n. 9
0
def _transform_point(coords, srid_from, srid_to):
    proj_in = get_proj_from_srid(srid_from)
    proj_out = get_proj_from_srid(srid_to)
    return proj_transform(proj_in, proj_out, coords[0], coords[1])
Esempio n. 10
0
def plot_geom(hdf_file, stn_lon, stn_lat):
    """
    given an hdf file creats a plot with diagonal corner line with upper
    and lower edge of swath with a projection centre point. plots station
    with given coordinates in lon lat

    Parameters
    ----------

    hdf_file:  Path or str with path to hdf file

    Returns
    -------

    proj_params: axis with large plot

    """

    area_def, lons, lats, metadata, swath_def = get_area_def(hdf_file)

    #Transfom lats and longs into gridded goordinates on projection

    p_lonlat = Proj(proj='latlong', datum='WGS84')
    stn_x, stn_y = proj_transform(p_lonlat, Proj(area_def.proj_dict), stn_lon,
                                  stn_lat)
    swath_x, swath_y = proj_transform(p_lonlat, Proj(area_def.proj_dict), lons,
                                      lats)
    min_x, min_y = proj_transform(p_lonlat, Proj(area_def.proj_dict),
                                  metadata['min_lon'], metadata['min_lat'])
    max_x, max_y = proj_transform(p_lonlat, Proj(area_def.proj_dict),
                                  metadata['max_lon'], metadata['max_lat'])
    xis = [min_x, max_x]
    yis = [min_y, max_y]
    crs = area_def.to_cartopy_crs()

    #def make_plot(swath_x, swath_y, stn_x, stn_y, area_def, xis, yis):

    crs = area_def.to_cartopy_crs()

    fig, ax = plt.subplots(1,
                           1,
                           figsize=(15, 15),
                           subplot_kw={'projection': crs})
    ax.gridlines(linewidth=2)
    ax.add_feature(cartopy.feature.GSHHSFeature(levels=[1, 2, 3]))
    #scale='coarse'
    ax.set_extent(crs.bounds, crs)

    ax.scatter(0, 0, marker='o', color='k', label='Projection centre')
    ax.scatter(stn_x, stn_y, marker='x', color='r', label='ground station')
    ax.scatter(swath_x[0:10],
               swath_y[0:10],
               marker='o',
               color='r',
               label='swath bound lower')
    ax.scatter(swath_x[-10:-1],
               swath_y[-10:-1],
               marker='o',
               color='r',
               label='swath bound upper')
    ax.plot(xis, yis, label='Corners Connect')

    #ax.set(title= str(generic_m3))
    ax.legend()