예제 #1
0
def Get_grid_Mercator_Parent(grdfile, name='MERCATOR_PARENT'):
    nc = Dataset(grdfile)
    lon = nc.variables['lon'][22:93]
    lat = nc.variables['lat'][18:86]
    var = nc.variables['votemper'][0, 0, 18:86,
                                   22:93]  #; depth = nc.variables['depth'][:]
    #lon = nc.variables['lon'][:]; lat = nc.variables['lat'][:]; var = nc.variables['votemper'][0,0,:,:]#; depth = nc.variables['depth'][:]
    print np.shape(lon), np.shape(lat), np.shape(var)
    nc.close()
    lon, lat = np.meshgrid(lon, lat)
    lon_t = lon[:, :]
    lat_t = lat[:, :]
    lon_vert = 0.5 * (lon[:, 1:] + lon[:, :-1])
    lon_vert = 0.5 * (lon_vert[1:, :] + lon_vert[:-1, :])
    lat_vert = 0.5 * (lat[1:, :] + lat[:-1, :])
    lat_vert = 0.5 * (lat_vert[:, 1:] + lat_vert[:, :-1])
    a = np.ones((len(var), len(var.T)))
    a[var.mask == True] = 0
    mask_t = a
    for i in range(len(var)):
        for j in range(len(var.T)):
            if point_inside_polygon(lat[i, j], lon[i, j], poly) == False:
                #if point_inside_polygon(lat[i,j],lon[i,j],poly_parent)==False:
                mask_t[i, j] = 0
    z_t = 1
    h = 1
    geod = pyproj.Geod(ellps='WGS84')
    az_forward, az_back, dx = geod.inv(lon_vert[:, :-1], lat_vert[:, :-1],
                                       lon_vert[:, 1:], lat_vert[:, 1:])
    angle = 0.5 * (az_forward[1:, :] + az_forward[:-1, :])
    angle = (90 - angle) * np.pi / 180.
    return Grid_VALID(lon_t, lat_t, lon_vert, lat_vert, mask_t, z_t, h, angle,
                      name)
예제 #2
0
파일: plot.py 프로젝트: fossabot/PySAR
    def draw_scale_bar(self, lat_c, lon_c, distance, ax=None, font_size=12, yoffset=None, color='k'):
        """draw a simple map scale from x1,y to x2,y in map projection coordinates, label it with actual distance
        ref_link: http://matplotlib.1069221.n5.nabble.com/basemap-scalebar-td14133.html
        Parameters: lat_c/lon_c : float, longitude and latitude of scale bar center, in degree
                    distance    : float, distance of scale bar, in m
                    yoffset     : float, optional, scale bar length at two ends, in degree
        Example:    m.drawscale(33.06, 131.18, 2000)
        """
        gc = pyproj.Geod(a=self.rmajor, b=self.rminor)
        if distance > 1000.0:
            distance = np.rint(distance/1000.0)*1000.0
        lon_c2, lat_c2, az21 = gc.fwd(lon_c, lat_c, 90, distance)
        length = np.abs(lon_c - lon_c2)
        lon0 = lon_c - length/2.0
        lon1 = lon_c + length/2.0
        if not yoffset:
            yoffset = 0.1*length

        self.plot([lon0, lon1], [lat_c, lat_c], color=color)
        self.plot([lon0, lon0], [lat_c, lat_c+yoffset], color=color)
        self.plot([lon1, lon1], [lat_c, lat_c+yoffset], color=color)
        if not ax:
            ax = plt.gca()
        if distance < 1000.0:
            ax.text(lon0+0.5*length, lat_c+yoffset*3, '%d m' % (distance),
                    verticalalignment='top', horizontalalignment='center', fontsize=font_size, color=color)
        else:
            ax.text(lon0+0.5*length, lat_c+yoffset*3, '%d km' % (distance/1000.0),
                    verticalalignment='top', horizontalalignment='center', fontsize=font_size, color=color)
예제 #3
0
def distance(evnt_click, evnt_release):
    g = pyproj.Geod(ellps='WGS84')
    _, _, dist = g.inv(evnt_click.xdata, evnt_click.ydata, evnt_release.xdata,
                       evnt_release.ydata)
    print("(%f, %f) to (%f, %f): %f km" %
          (evnt_click.xdata, evnt_click.ydata, evnt_release.xdata,
           evnt_release.ydata, dist / 1000.0))
예제 #4
0
    def _calculate_grid_angle(self):
        geod = pyproj.Geod(ellps='WGS84')
        az_forward, az_back, dx = geod.inv(self.lon_t[:,:-1], self.lat_t[:,:-1], \
                                           self.lon_t[:,1:], self.lat_t[:,1:])

        angle = 0.5 * (az_forward[1:, :] + az_forward[:-1, :])
        self.angle = (90 - angle) * np.pi / 180.
예제 #5
0
파일: utils.py 프로젝트: jukiforde/MSS
def latlon_points(p1, p2, numpoints=100, connection='linear'):
    """
    Compute intermediate points between two given points.

    Arguments:
    p1, p2 -- points given as lat/lon pairs, i.e. p1, p2 = [lat, lon]
    numpoints -- number of intermediate points to be computed aloing the path
    connection -- method to compute the intermediate points. Can be
                  'linear' or 'greatcircle'

    Returns two arrays lats, lons with intermediate latitude and longitudes.
    """
    LAT = 0
    LON = 1
    TIME = 2
    lats, lons, times = None, None, None

    if connection == 'linear':
        lats = np.linspace(p1[LAT], p2[LAT], numpoints)
        lons = np.linspace(p1[LON], p2[LON], numpoints)
    elif connection == 'greatcircle':
        if numpoints > 2:
            gc = pyproj.Geod(ellps="WGS84")
            pts = gc.npts(p1[LON], p1[LAT], p2[LON], p2[LAT], numpoints - 2)
            lats = np.asarray([p1[LAT]] + [_x[1] for _x in pts] + [p2[LAT]])
            lons = np.asarray([p1[LON]] + [_x[0] for _x in pts] + [p2[LON]])
        else:
            lats = np.asarray([p1[LAT], p2[LAT]])
            lons = np.asarray([p1[LON], p2[LON]])

    p1_time, p2_time = nc.date2num([p1[TIME], p2[TIME]],
                                   "seconds since 2000-01-01")
    times = np.linspace(p1_time, p2_time, numpoints)

    return lats, lons, nc.num2date(times, "seconds since 2000-01-01")
예제 #6
0
def get_nc_Grid_HYCOM(grdfile, name='PUSSY'):

    nc = Dataset(grdfile)
    lon = nc.variables['longitude'][:]
    lat = nc.variables['latitude'][:]
    #depth = nc.variables['depth'][:]
    print "2"
    var = nc.variables['t2m'][0, :, :]
    nc.close()

    lon, lat = np.meshgrid(lon, lat)

    lon_t = lon[:, :]
    lat_t = lat[:, :]

    lon_vert = 0.5 * (lon[:, 1:] + lon[:, :-1])
    lon_vert = 0.5 * (lon_vert[1:, :] + lon_vert[:-1, :])

    lat_vert = 0.5 * (lat[1:, :] + lat[:-1, :])
    lat_vert = 0.5 * (lat_vert[:, 1:] + lat_vert[:, :-1])

    mask_t = np.ones((len(var[:, 0]), len(var[0, :])))

    z_t = 1
    h = 1

    geod = pyproj.Geod(ellps='WGS84')
    az_forward, az_back, dx = geod.inv(lon_vert[:, :-1], lat_vert[:, :-1],
                                       lon_vert[:, 1:], lat_vert[:, 1:])
    angle = 0.5 * (az_forward[1:, :] + az_forward[:-1, :])
    angle = (90 - angle) * np.pi / 180.

    return Grid_HYCOM(lon_t, lat_t, lon_vert, lat_vert, mask_t, z_t, h, angle,
                      name)
예제 #7
0
파일: tableview.py 프로젝트: Open-MSS/MSS
    def addWayPoint(self):
        """
        Handler for button <btAddWayPointToFlightTrack>. Adds a new waypoint
        behind the currently selected waypoint.
        """
        tableView = self.tableWayPoints
        index = tableView.currentIndex()
        lon, lat = 0, 0
        if not index.isValid():
            row = 0
            flightlevel = 0
        else:
            row = index.row() + 1
            flightlevel = self.waypoints_model.waypoint_data(row - 1).flightlevel
            if row < len(self.waypoints_model.all_waypoint_data()):
                wp_prev = self.waypoints_model.waypoint_data(row - 1)
                wp_next = self.waypoints_model.waypoint_data(row)
                gc = pyproj.Geod(ellps="WGS84")  # a=40e6, b=40e6)
                lon, lat = gc.npts(wp_prev.lon, wp_prev.lat, wp_next.lon, wp_next.lat, 3)[1]

        self.waypoints_model.insertRows(
            row, waypoints=[ft.Waypoint(lat=lat, lon=lon, flightlevel=flightlevel)])

        index = self.waypoints_model.index(row, 0)
        tableView = self.tableWayPoints
        tableView.setFocus()
        tableView.setCurrentIndex(index)
        # tableView.edit(index)
        tableView.resizeRowsToContents()
예제 #8
0
        def ellipse(self, x0, y0, a, b, n, ax=None, **kwargs):
            """Extension to Basemap class from `basemap` to draw ellipses.
            Parameters
            ----------
            x0 : :class: `float`
                Centroid of the ellipse in the X axis.
            y0 : :class: `float`
                Centroid of the ellipse in the Y axis.
            a : :class: `float`
                Semi-major axis of the ellipse.
            b : :class: `float`
                Semi-minor axis of the ellipse.
            n : :class: `int`
                Number of points to draw the ellipse.
            Returns
            -------
            :class: `Basemap`
                It returns one Basemap ellipse at a time.
            """
            ax = kwargs.pop('ax', None) or self._check_ax()
            g = pyproj.Geod(a=self.rmajor, b=self.rminor)
            azf, azb, dist = g.inv([x0, x0], [y0, y0], [x0 + a, x0],
                                   [y0, y0 + b])
            tsid = dist[0] * dist[1]  # a * b
            seg = [self(x0 + a, y0)]
            AZ = np.linspace(azf[0], 360. + azf[0], n)
            for i, az in enumerate(AZ):
                # Skips segments along equator (Geod can't handle equatorial arcs).
                if np.allclose(0., y0) and (np.allclose(90., az)
                                            or np.allclose(270., az)):
                    continue

                # In polar coordinates, with the origin at the center of the
                # ellipse and with the angular coordinate ``az`` measured from the
                # major axis, the ellipse's equation  is [1]:
                #
                #                           a * b
                # r(az) = ------------------------------------------
                #         ((b * cos(az))**2 + (a * sin(az))**2)**0.5
                #
                # Azymuth angle in radial coordinates and corrected for reference
                # angle.
                azr = 2. * np.pi / 360. * (az + 90.)
                A = dist[0] * np.sin(azr)
                B = dist[1] * np.cos(azr)
                r = tsid / (B**2. + A**2.)**0.5
                lon, lat, azb = g.fwd(x0, y0, az, r)
                x, y = self(lon, lat)

                # Add segment if it is in the map projection region.
                if x < 1e20 and y < 1e20:
                    seg.append((x, y))

            poly = Polygon(seg, **kwargs)
            ax.add_patch(poly)

            # Set axes limits to fit map region.
            self.set_axes_limits(ax=ax)

            return poly
예제 #9
0
def Get_grid_ODYSSEA_Parent(grdfile, name='ODYSSEA_PARENT'):
    nc = Dataset(grdfile)
    lon = nc.variables['lon'][:]
    lat = nc.variables['lat'][:]
    var = nc.variables['analysed_sst'][0, :, :]
    nc.close()
    lon, lat = np.meshgrid(lon, lat)
    lon_t = lon[:, :]
    lat_t = lat[:, :]
    lon_vert = 0.5 * (lon[:, 1:] + lon[:, :-1])
    lon_vert = 0.5 * (lon_vert[1:, :] + lon_vert[:-1, :])
    lat_vert = 0.5 * (lat[1:, :] + lat[:-1, :])
    lat_vert = 0.5 * (lat_vert[:, 1:] + lat_vert[:, :-1])
    a = np.ones((len(var), len(var.T)))
    a[var.mask == True] = 0
    mask_t = a
    for i in range(len(var)):
        for j in range(len(var.T)):
            if point_inside_polygon(lat[i, j], lon[i, j], poly) == False:
                #if point_inside_polygon(lat[i,j],lon[i,j],poly_parent)==False:
                mask_t[i, j] = 0
    z_t = 1
    h = 1
    geod = pyproj.Geod(ellps='WGS84')
    az_forward, az_back, dx = geod.inv(lon_vert[:, :-1], lat_vert[:, :-1],
                                       lon_vert[:, 1:], lat_vert[:, 1:])
    angle = 0.5 * (az_forward[1:, :] + az_forward[:-1, :])
    angle = (90 - angle) * np.pi / 180.
    return Grid_VALID(lon_t, lat_t, lon_vert, lat_vert, mask_t, z_t, h, angle,
                      name)
예제 #10
0
    def gcpoints_path(self, lons, lats, del_s=100., map_coords=True):
        """
        Same as gcpoints2, but for an entire path, i.e. multiple
        line segments. lons and lats are lists of waypoint coordinates.
        """
        # use great circle formula for a perfect sphere.
        gc = pyproj.Geod(a=self.rmajor, b=self.rminor)
        assert len(lons) == len(lats)
        assert len(lons) > 1
        gclons = [lons[0]]
        gclats = [lats[0]]
        for i in range(len(lons) - 1):
            az12, az21, dist = gc.inv(lons[i], lats[i], lons[i + 1],
                                      lats[i + 1])
            npoints = int((dist + 0.5 * 1000. * del_s) / (1000. * del_s))
            # BUG -- weird path in cyl projection on waypoint move
            # On some system configurations, the path is wrongly plotted when one
            # of the waypoints is moved by the user and the current projection is cylindric.
            # The weird thing is that when comparing cyl projection and stereo projection
            # (which works), the exact same arguments are passed to gc.npts(). Also, the
            # gc is initialised with the exact same a and b. Nevertheless, for the cyl
            # projection, gc.npts() returns lons that connect lon1 and lat2, not lon1 and
            # lon2 ... I cannot figure out why, maybe this is an issue in certain versions
            # of pyproj?? (mr, 16Oct2012)
            lonlats = []
            if npoints > 0:
                lonlats = gc.npts(lons[i], lats[i], lons[i + 1], lats[i + 1],
                                  npoints)
            # The cylindrical projection of matplotlib is not periodic, that means that
            # -170 longitude and 190 longitude are not identical. The gc projection however
            # assumes identity and maps all longitudes to -180 to 180. This is no issue for
            # most other projections.
            # The clean solution would be to have a periodic display, where the locations
            # and path are plotted periodically every 360 degree. As long as this is not
            # supported by matplotlib.basemap, we "hack" this to map the path to the
            # longitude range defined by the locations. This breaks potentially down in case
            # that the locations are too far apart (>180 degree), but this is not the typical
            # use case and will thus hopefully not pose a problem.
            if self.projection == "cyl" and npoints > 0:
                lonlats = np.asarray(lonlats)
                milon = min(lons[i], lons[i + 1])
                malon = max(lons[i], lons[i + 1])
                sel = lonlats[:, 0] < milon
                lonlats[sel, 0] += 360
                sel = lonlats[:, 0] > malon
                lonlats[sel, 0] -= 360

            for lon, lat in lonlats:
                gclons.append(lon)
                gclats.append(lat)
            gclons.append(lons[i + 1])
            gclats.append(lats[i + 1])
        if map_coords:
            x, y = self(gclons, gclats)
        else:
            x, y = (gclons, gclats)
        return x, y
예제 #11
0
파일: utils.py 프로젝트: jukiforde/MSS
def get_distance(coord0, coord1):
    """
    Computes the distance between two points on the Earth surface
    Args:
        coord0: coordinate(lat/lon) of first point
        coord1: coordinate(lat/lon) of second point

    Returns:
        length of distance in km
    """
    pr = pyproj.Geod(ellps='WGS84')
    return (pr.inv(coord0[1], coord0[0], coord1[1], coord1[0])[-1] / 1000.)
예제 #12
0
def getGridHYCOM(grdfile, varname3D='water_temp', name='GLBv0.08_expt_93.0'):
    """
    grd = get_nc_Grid_HYCOM(grdfile)

    Load grid object for HYCOM_GLBv0.08_expt93.0
    """

    with Dataset(grdfile, 'r') as nc:
        lon = nc.variables['lon'][:]
        lat = nc.variables['lat'][:]
        lon, lat = np.meshgrid(lon, lat)

        depth = nc.variables['depth'][:]
        var = nc.variables[varname3D][0, :, 1:-1, 1:-1]

    lon_t = lon[1:-1, 1:-1]
    lat_t = lat[1:-1, 1:-1]

    lon_vert = 0.5 * (lon[:, 1:] + lon[:, :-1])
    lon_vert = 0.5 * (lon_vert[1:, :] + lon_vert[:-1, :])

    lat_vert = 0.5 * (lat[1:, :] + lat[:-1, :])
    lat_vert = 0.5 * (lat_vert[:, 1:] + lat_vert[:, :-1])

    mask_t = np.array(~var[:].mask, dtype='int')

    z_t = np.tile(depth, (mask_t.shape[2], mask_t.shape[1], 1)).T

    depth_bnds = np.zeros(len(depth) + 1)
    for i in range(1, len(depth)):
        depth_bnds[i] = 0.5 * (depth[i - 1] + depth[i])
    depth_bnds[-1] = 5750

    bottom = pyroms.utility.get_bottom(var[::-1, :, :],
                                       mask_t[0],
                                       spval=var.fill_value)
    nlev = len(depth)
    bottom = (nlev - 1) - bottom
    h = np.zeros(mask_t[0, :].shape)
    for i in range(mask_t[0, :].shape[1]):
        for j in range(mask_t[0, :].shape[0]):
            if mask_t[0, j, i] == 1:
                h[j, i] = depth_bnds[int(bottom[j, i]) + 1]

    geod = pyproj.Geod(ellps='WGS84')
    az_forward, az_back, dx = geod.inv(lon_vert[:, :-1], lat_vert[:, :-1],
                                       lon_vert[:, 1:], lat_vert[:, 1:])
    angle = 0.5 * (az_forward[1:, :] + az_forward[:-1, :])
    angle = (90 - angle) * np.pi / 180.

    return Grid_HYCOM(lon_t, lat_t, lon_vert, lat_vert, mask_t, z_t, h, angle,
                      name)
예제 #13
0
def get_nc_Grid_HYCOM(grdfile, name='GLBa0.08_NEP'):
    """
    grd = get_nc_Grid_HYCOM(grdfile)

    Load grid object for HYCOM_GLBa0.08_NEP
    """

    nc = netCDF4.Dataset(grdfile)
    lon = nc.variables['lon'][:]
    lat = nc.variables['lat'][:]
    depth = nc.variables['z'][:]
    var = nc.variables['temp'][0, :, 1:-1, 1:-1]
    nc.close()

    lon_t = lon[1:-1, 1:-1]
    lat_t = lat[1:-1, 1:-1]

    lon_vert = 0.5 * (lon[:, 1:] + lon[:, :-1])
    lon_vert = 0.5 * (lon_vert[1:, :] + lon_vert[:-1, :])

    lat_vert = 0.5 * (lat[1:, :] + lat[:-1, :])
    lat_vert = 0.5 * (lat_vert[:, 1:] + lat_vert[:, :-1])

    mask_t = np.array(~var[:].mask, dtype='int')

    z_t = np.tile(depth, (mask_t.shape[2], mask_t.shape[1], 1)).T

    depth_bnds = np.zeros(len(depth) + 1)
    for i in range(1, len(depth)):
        depth_bnds[i] = 0.5 * (depth[i - 1] + depth[i])
    depth_bnds[-1] = 5750

    bottom = pycnal.utility.get_bottom(var[::-1, :, :],
                                       mask_t[0],
                                       spval=var.fill_value)
    nlev = len(depth)
    bottom = (nlev - 1) - bottom
    h = np.zeros(mask_t[0, :].shape)
    for i in range(mask_t[0, :].shape[1]):
        for j in range(mask_t[0, :].shape[0]):
            if mask_t[0, j, i] == 1:
                h[j, i] = depth_bnds[bottom[j, i] + 1]

    geod = pyproj.Geod(ellps='WGS84')
    az_forward, az_back, dx = geod.inv(lon_vert[:, :-1], lat_vert[:, :-1],
                                       lon_vert[:, 1:], lat_vert[:, 1:])
    angle = 0.5 * (az_forward[1:, :] + az_forward[:-1, :])
    angle = (90 - angle) * np.pi / 180.

    return Grid_HYCOM(lon_t, lat_t, lon_vert, lat_vert, mask_t, z_t, h, angle,
                      name)
예제 #14
0
def Get_any_standard_grid(grdfile):
    nc = Dataset(grdfile, 'r')
    variables = list(nc.variables.keys())
    if 'lon' in variables and 'lat' in variables:
        lon = nc.variables['lon'][:]
        lat = nc.variables['lat'][:]
    elif 'longitude' in variables and 'latitude' in variables:
        lon = nc.variables['longitude'][:]
        lat = nc.variables['latitude'][:]
    else:
        raise NameError('No conditional latitude and longitude found')

    for i in variables:

        if nc.variables[i][:].ndim == 3:
            var = nc.variables[i][0]
            break
        elif nc.variables[i][:].ndim == 4:
            var = nc.variables[i][0, 0]
            break
        else:
            pass
    nc.close()
    try:
        lon, lat = np.meshgrid(lon, lat)
        lon_t, lat_t = lon, lat

        lon_vert = 0.5 * (lon[:, 1:] + lon[:, :-1])
        lon_vert = 0.5 * (lon_vert[1:, :] + lon_vert[:-1, :])
        lat_vert = 0.5 * (lat[1:, :] + lat[:-1, :])
        lat_vert = 0.5 * (lat_vert[:, 1:] + lat_vert[:, :-1])

        a = np.ones((len(var), len(var.T)))
        a[var.mask == True] = 0
        mask_t = a

        z_t = 1
        h = 1
        geod = pyproj.Geod(ellps='WGS84')
        az_forward, az_back, dx = geod.inv(lon_vert[:, :-1], lat_vert[:, :-1],
                                           lon_vert[:, 1:], lat_vert[:, 1:])
        angle = 0.5 * (az_forward[1:, :] + az_forward[:-1, :])
        angle = (90 - angle) * np.pi / 180.

        name = grdfile.split('/')[-1].split('_')[0].split('.')[0]
        return Class_grid(lon_t, lat_t, lon_vert, lat_vert, mask_t, z_t, h,
                          angle, name)
    except:
        raise NameError('No variables are found')
예제 #15
0
    def _calculate_metrics(self):
        # calculate metrics based on x and y grid
        super(CGrid_geo, self)._calculate_metrics()

        # optionally calculate dx and dy based on great circle distances
        # for more accurate cell sizes.
        if self.use_gcdist:
            geod = pyproj.Geod(ellps=self.ellipse)
            az_forward, az_back, dx = geod.inv(self.lon[:,1:],  self.lat[:,1:], \
                                               self.lon[:,:-1], self.lat[:,:-1])
            self.dx = 0.5 * (dx[1:, :] + dx[:-1, :])
            self.pm = 1.0 / self.dx
            az_forward, az_back, dy = geod.inv(self.lon[1:,:],  self.lat[1:,:], \
                                               self.lon[:-1,:], self.lat[:-1,:])
            self.dy = 0.5 * (dy[:, 1:] + dy[:, :-1])
            self.pn = 1.0 / self.dy
예제 #16
0
def Get_grid_Mercator_Nest(grdfile, name='MERCATOR_NEST'):
    nc = Dataset(grdfile)
    #lon = nc.variables['lon'][52:78]; lat = nc.variables['lat'][39:65]; var = nc.variables['votemper'][0,0,39:65,52:78]#; depth = nc.variables['depth'][:]
    lon = nc.variables['lon'][22:93]
    lat = nc.variables['lat'][18:86]
    var = nc.variables['votemper'][0, 0, 18:86, 22:93]
    print np.shape(lon), np.shape(lat), np.shape(var)
    nc.close()
    lon, lat = np.meshgrid(lon, lat)
    lon_t = lon[:, :]
    lat_t = lat[:, :]
    lon_vert = 0.5 * (lon[:, 1:] + lon[:, :-1])
    lon_vert = 0.5 * (lon_vert[1:, :] + lon_vert[:-1, :])
    lat_vert = 0.5 * (lat[1:, :] + lat[:-1, :])
    lat_vert = 0.5 * (lat_vert[:, 1:] + lat_vert[:, :-1])
    #mask_t = np.array(~var[:].mask, dtype='int')
    a = np.ones((len(var), len(var.T)))
    a[var.mask == True] = 0
    #print a
    mask_t = a
    #mask correction
    for i in range(len(var)):
        for j in range(len(var.T)):
            if point_inside_polygon(lat[i, j], lon[i, j], poly) == False:
                mask_t[i, j] = 0
    #z_t = np.tile(depth,(mask_t.shape[2],mask_t.shape[1],1)).T
    #depth_bnds = np.zeros(len(depth)+1)
    #for i in range(1,len(depth)):
    #    depth_bnds[i] = 0.5 * (depth[i-1] + depth[i])
    #depth_bnds[-1] = 1000
    #bottom = pyroms.utility.get_bottom(var[::-1,:,:], mask_t[0], spval=var.fill_value)
    #nlev = len(depth)
    #bottom = (nlev-1) - bottom
    #h = np.zeros(mask_t[0,:].shape)
    #for i in range(mask_t[0,:].shape[1]):
    #    for j in range(mask_t[0,:].shape[0]):
    #        if mask_t[0,j,i] == 1:
    #            h[j,i] = depth_bnds[bottom[j,i]+1]
    z_t = 1
    h = 1
    geod = pyproj.Geod(ellps='WGS84')
    az_forward, az_back, dx = geod.inv(lon_vert[:, :-1], lat_vert[:, :-1],
                                       lon_vert[:, 1:], lat_vert[:, 1:])
    angle = 0.5 * (az_forward[1:, :] + az_forward[:-1, :])
    angle = (90 - angle) * np.pi / 180.
    return Grid_VALID(lon_t, lat_t, lon_vert, lat_vert, mask_t, z_t, h, angle,
                      name)
예제 #17
0
def get_nc_Grid_HYCOM(grdfile, name='PUSSY'):

    nc = Dataset(grdfile)
    lon = nc.variables['lon'][:]
    lat = nc.variables['lat'][:]
    depth = nc.variables['depth'][:]
    var = nc.variables['votemper'][0,:,:,:]
    nc.close()	

    lon,lat=np.meshgrid(lon,lat)

    lon_t = lon[:,:]
    lat_t = lat[:,:]

    lon_vert = 0.5 * (lon[:,1:] + lon[:,:-1])
    lon_vert = 0.5 * (lon_vert[1:,:] + lon_vert[:-1,:])

    lat_vert = 0.5 * (lat[1:,:] + lat[:-1,:])
    lat_vert = 0.5 * (lat_vert[:,1:] + lat_vert[:,:-1])

    mask_t = np.array(~var[:].mask, dtype='int')

    z_t = np.tile(depth,(mask_t.shape[2],mask_t.shape[1],1)).T
    print z_t
    depth_bnds = np.zeros(len(depth)+1)
    for i in range(1,len(depth)):
        depth_bnds[i] = 0.5 * (depth[i-1] + depth[i])
    depth_bnds[-1] = 1000

    bottom = pyroms.utility.get_bottom(var[::-1,:,:], mask_t[0], spval=var.fill_value)
    nlev = len(depth)
    bottom = (nlev-1) - bottom
    h = np.zeros(mask_t[0,:].shape)
    for i in range(mask_t[0,:].shape[1]):
        for j in range(mask_t[0,:].shape[0]):
            if mask_t[0,j,i] == 1:
                h[j,i] = depth_bnds[bottom[j,i]+1]


    geod = pyproj.Geod(ellps='WGS84')
    az_forward, az_back, dx = geod.inv(lon_vert[:,:-1], lat_vert[:,:-1], lon_vert[:,1:], lat_vert[:,1:])
    angle = 0.5 * (az_forward[1:,:] + az_forward[:-1,:])
    angle = (90 - angle) * np.pi/180.


    return Grid_HYCOM(lon_t, lat_t, lon_vert, lat_vert, mask_t, z_t, h, angle, name)
예제 #18
0
    def _calculate_grid_angle(self):
        geod = pyproj.Geod(ellps='WGS84')
        # This is how it used to be, but it fails for some reason.
        #       az_forward, az_back, dx = geod.inv(self.lon_t_vert[:,:-1], self.lat_t_vert[:,:-1], \
        #                                          self.lon_t_vert[:,1:], self.lat_t_vert[:,1:])
        #       angle = 0.5 * (az_forward[1:,:] + az_forward[:-1,:])

        # Seems to work...
        sizey, sizex = self.lon_t_vert.shape
        angle = np.zeros(self.h.shape)

        for i in range(sizex - 1):
            az_forward, az_back, dx = geod.inv(self.lon_t_vert[:,i], self.lat_t_vert[:,i], \
                                               self.lon_t_vert[:,i+1], self.lat_t_vert[:,i+1])

            angle[:, i] = 0.5 * (az_forward[1:] + az_forward[:-1])

        # part of original code
        self.angle = (90 - angle) * np.pi / 180.
예제 #19
0
    def _calculate_angle_rho(self):
        if isinstance(self.lon, np.ma.MaskedArray) or \
           isinstance(self.lat, np.ma.MaskedArray):
            self.angle_rho = np.ma.zeros(self.lon.shape, dtype='d')
        else:
            self.angle_rho = np.zeros(self.lon.shape, dtype='d')

        # calculate metrics based on x and y grid
        super(CGrid_geo, self)._calculate_angle_rho()

        # optionally calculate dx and dy based on great circle distances
        # for more accurate cell sizes.
        if self.use_gcdist:
            geod = pyproj.Geod(ellps=self.ellipse)
            az_forward, az_back, dx = geod.inv(self.lon[:,:-1], self.lat[:,:-1], \
                                               self.lon[:,1:], self.lat[:,1:])

            angle = 0.5 * (az_forward[1:, :] + az_forward[:-1, :])
            self.angle_rho = (90 - angle) * np.pi / 180.
예제 #20
0
 def gcpoints2(self, lon1, lat1, lon2, lat2, del_s=100., map_coords=True):
     """
     The same as basemap.gcpoints(), but takes a distance interval del_s
     to space the points instead of a number of points.
     """
     # use great circle formula for a perfect sphere.
     gc = pyproj.Geod(a=self.rmajor, b=self.rminor)
     az12, az21, dist = gc.inv(lon1, lat1, lon2, lat2)
     npoints = int((dist + 0.5 * 1000. * del_s) / (1000. * del_s))
     lonlats = gc.npts(lon1, lat1, lon2, lat2, npoints)
     lons = [lon1]
     lats = [lat1]
     for lon, lat in lonlats:
         lons.append(lon)
         lats.append(lat)
     lons.append(lon2)
     lats.append(lat2)
     if map_coords:
         x, y = self(lons, lats)
     else:
         x, y = (lons, lats)
     return x, y
예제 #21
0
def get_nc_Grid_Nest(grdfile, name='NESTED'):

    nc = Dataset(grdfile)
    lon = nc.variables['lon_rho'][:]
    lat = nc.variables['lat_rho'][:]
    #depth = nc.variables['depth'][:]
    h = nc.variables['h'][:]
    print "3"
    nc.close()	

    #lon,lat=np.meshgrid(lon,lat)

    lon_t = lon[:,:]
    lat_t = lat[:,:]

    lon_vert = 0.5 * (lon[:,1:] + lon[:,:-1])
    lon_vert = 0.5 * (lon_vert[1:,:] + lon_vert[:-1,:])

    lat_vert = 0.5 * (lat[1:,:] + lat[:-1,:])
    lat_vert = 0.5 * (lat_vert[:,1:] + lat_vert[:,:-1])

    rr = Dataset('Nested_grid.nc', 'a', format='NETCDF4')
    mask_t = rr.variables['mask_rho'][:]

    z_t = 1
    #h=1


    geod = pyproj.Geod(ellps='WGS84')
    az_forward, az_back, dx = geod.inv(lon_vert[:,:-1], lat_vert[:,:-1], lon_vert[:,1:], lat_vert[:,1:])
    angle=rr.variables['angle'][:]
    rr.close()
    #angle = 0.5 * (az_forward[1:,:] + az_forward[:-1,:])
    #angle = (90 - angle) * np.pi/180.


    return Grid_Nest(lon_t, lat_t, lon_vert, lat_vert, mask_t, z_t, h, angle, name)
예제 #22
0
def get_cell_area(lon, lat):

    if np.size(lon.shape) == 1:
        lon, lat = np.meshgrid(lon, lat)

    #compute position of the vertices of the cell
    lonv = np.zeros((lon.shape[0] + 1, lon.shape[1] + 1))
    latv = np.zeros((lat.shape[0] + 1, lat.shape[1] + 1))

    lonv[1:-1, 1:-1] = 0.25 * (lon[1:, 1:] + lon[:-1, :-1] + lon[1:, :-1] +
                               lon[:-1, 1:])
    lonv[0, :] = lonv[1, :]
    lonv[-1, :] = lonv[-2, :]
    lonv[:, 0] = lonv[:, 1] - (lonv[:, 2] - lonv[:, 1])
    lonv[:, -1] = lonv[:, -2] + (lonv[:, -2] - lonv[:, -3])

    latv[1:-1, 1:-1] = 0.25 * (lat[1:, 1:] + lat[:-1, :-1] + lat[1:, :-1] +
                               lat[:-1, 1:])
    latv[:, 0] = latv[:, 1]
    latv[:, -1] = latv[:, -2]
    latv[0, :] = latv[1, :] - (latv[2, :] - latv[1, :])
    latv[-1, :] = latv[-2, :] + (latv[-2, :] - latv[-3, :])

    #get dx and dy based on great circle distances
    ellipse = 'WGS84'
    geod = pyproj.Geod(ellps=ellipse)
    az_forward, az_back, dx = geod.inv(lonv[:,1:], latv[:,1:], \
                                       lonv[:,:-1], latv[:,:-1])
    dx = 0.5 * (dx[1:, :] + dx[:-1, :])
    az_forward, az_back, dy = geod.inv(lonv[1:,:], latv[1:,:], \
                                       lonv[:-1,:], latv[:-1,:])
    dy = 0.5 * (dy[:, 1:] + dy[:, :-1])

    area = dx * dy

    return dx, dy, area
예제 #23
0
    def drawscale(self, length, yoffset=None):
        """draw a simple map scale from x1,y to x2,y in map projection 
		coordinates, label it with actual distance in miles"""

        # Define dimensions
        x1, y1, x2, y, extra = 0.03 * map.xmax, 0.03 * map.xmax, 0.03 * map.xmax + length, 0.05 * map.xmax, 0.01 * map.xmax

        # Call rectangle function for bounding box
        drawRect(x1 - extra, y1 - extra, length + 2 * extra + 1300,
                 y1 + 2 * extra, 'k', 1)

        # Get info for scale bar
        yoffset = 0.01 * map.ymax
        lon1, lat1 = self(x1, y, inverse=True)
        lon2, lat2 = self(x2, y, inverse=True)

        # Convert to map projection units
        gc = pyproj.Geod(a=self.rmajor, b=self.rminor)

        # This gets the distance on a level plane (inv), to get distance on the plane, use sqrt()
        az12, az21, dist = gc.inv(lon1, lat1, lon2, lat2)

        # These are the pieces of the scale bar
        map.plot([x1, x2], [y, y], linewidth=1, color='k')
        # Vertical ticks
        map.plot([x1, x1], [y - yoffset, y + yoffset], linewidth=1, color='k')
        map.plot([x1 + length / 6.0, x1 + length / 6.0],
                 [y - yoffset, y + yoffset],
                 linewidth=1,
                 color='k')
        map.plot([x1 + length / 3.0, x1 + length / 3.0],
                 [y - yoffset, y + yoffset],
                 linewidth=1,
                 color='k')
        map.plot([x1 + 2 * length / 3.0, x1 + 2 * +length / 3.0],
                 [y - yoffset, y + yoffset],
                 linewidth=1,
                 color='k')
        map.plot([x2, x2], [y - yoffset, y + yoffset], linewidth=1, color='k')
        # Label after converting to miles
        # 0
        text(x1,
             y - yoffset - 0.5 * extra,
             '%d' % (dist * 0 * 0.621371, ),
             verticalalignment='top',
             horizontalalignment='center',
             fontsize=9,
             color='k',
             fontweight='normal')
        # 0.5
        text(x1 + length / 6.0,
             y - yoffset - 0.5 * extra,
             '%g' % (round(dist / 6 / 1000. * 0.621371, 1), ),
             verticalalignment='top',
             horizontalalignment='center',
             fontsize=9,
             color='k',
             fontweight='normal')
        # 1
        text(x1 + length / 3.0,
             y - yoffset - 0.5 * extra,
             '%d' % (dist / 3 / 1000. * 0.621371, ),
             verticalalignment='top',
             horizontalalignment='center',
             fontsize=9,
             color='k',
             fontweight='normal')
        # 2
        text(x1 + length * 2 / 3.0,
             y - yoffset - 0.5 * extra,
             '%d' % (dist * 2 / 3 / 1000. * 0.621371, ),
             verticalalignment='top',
             horizontalalignment='center',
             fontsize=9,
             color='k',
             fontweight='normal')
        # 3
        text(x1 - 200 + length,
             y - yoffset - 0.5 * extra,
             '%d miles' % (dist / 1000. * 0.621371, ),
             verticalalignment='top',
             horizontalalignment='left',
             fontsize=9,
             color='k',
             fontweight='normal')
예제 #24
0
파일: mpl_map.py 프로젝트: Open-MSS/MSS
    def __init__(self, identifier=None, CRS=None, BBOX_UNITS=None, OPERATION_NAME=None,
                 appearance=None, **kwargs):
        """
        New constructor automatically adds coastlines, continents, and
        a graticule to the map.

        Keyword arguments are the same as for mpl_toolkits.basemap.

        Additional arguments:
        CRS -- string describing the coordinate reference system of the map.
        BBOX_UNITS -- string describing the units of the map coordinates.
        OPERATION_NAME -- string with operation name

        """
        # Coordinate reference system identifier and coordinate system units.
        self.crs = CRS if CRS is not None else self.crs if hasattr(self, "crs") else None
        if BBOX_UNITS is not None:
            self.bbox_units = BBOX_UNITS
        else:
            self.bbox_units = getattr(self, "bbox_units", None)

        self.operation_name = OPERATION_NAME if OPERATION_NAME is not None else self.operation_name \
            if hasattr(self, "operation_name") else None

        # Dictionary containing map appearance settings.
        if appearance is not None:
            param_appearance = appearance
        else:
            param_appearance = getattr(self, "appearance", {})

        default_appearance = {"draw_graticule": True,
                              "draw_coastlines": True,
                              "fill_waterbodies": True,
                              "fill_continents": True,
                              "colour_water": ((153 / 255.), (255 / 255.), (255 / 255.), (255 / 255.)),
                              "colour_land": ((204 / 255.), (153 / 255.), (102 / 255.), (255 / 255.))}
        default_appearance.update(param_appearance)
        self.appearance = default_appearance
        # Identifier of this map canvas (used to query data structures that
        # are observed by different views).
        if identifier is not None:
            self.identifier = identifier
        else:
            self.identifier = getattr(self, "identifier", None)

        # Call the Basemap constructor. If a cylindrical projection was used
        # before, Basemap stores an EPSG code that will not be changed if
        # the Basemap constructor is called a second time. Hence, we have to
        # delete the attribute (mr, 08Feb2013).
        if hasattr(self, "epsg"):
            del self.epsg
        super().__init__(**kwargs)

        self.gc = pyproj.Geod(a=self.rmajor, b=self.rminor)

        self.kwargs = kwargs

        # Set up the map appearance.
        if self.appearance["draw_coastlines"]:
            self.map_coastlines = None
            if len(self.coastsegs) > 0 and len(self.coastsegs[0]) > 0:
                self.map_coastlines = self.drawcoastlines(zorder=3)
            self.map_countries = self.drawcountries(zorder=3)
        else:
            self.map_coastlines = None
            self.map_countries = None
        if self.appearance["fill_waterbodies"]:
            self.map_boundary = self.drawmapboundary(fill_color=self.appearance["colour_water"])
        else:
            self.map_boundary = None

        # zorder = 0 is necessary to paint over the filled continents with
        # scatter() for drawing the flight tracks and trajectories.
        # Curiously, plot() works fine without this setting, but scatter()
        # doesn't.
        if self.appearance["fill_continents"]:
            self.map_continents = self.fillcontinents(
                color=self.appearance["colour_land"], lake_color=self.appearance["colour_water"], zorder=1)
        else:
            self.map_continents = None

        self.image = None

        # Print project name and CRS identifier into figure.
        crs_text = ""
        if self.operation_name is not None:
            crs_text += self.operation_name
        if self.crs is not None:
            if len(crs_text) > 0:
                crs_text += "\n"
            crs_text += self.crs
        if hasattr(self, "crs_text"):  # update existing textbox
            self.crs_text.set_text(crs_text)
        else:
            self.crs_text = self.ax.figure.text(0, 0, crs_text)

        if self.appearance["draw_graticule"]:
            pass
            # self._draw_auto_graticule() ; It's already called in mpl_qtwidget.py in MplTopviewCanvas init_map().
        else:
            self.map_parallels = None
            self.map_meridians = None

        # self.warpimage() # disable fillcontinents when loading bluemarble
        self.ax.set_autoscale_on(False)
        if not hasattr(self, "airports") or not self.airports:
            self.airports = None
            self.airtext = None
        if not hasattr(self, "airspaces") or not self.airspaces:
            self.airspaces = None
            self.airspacetext = None
예제 #25
0
    def geodesic(self, lon1, lat1, lon2, lat2, del_s=.01, clip=True, **kwargs):
        """
        Plot a geodesic curve from (lon1, lat1) to (lon2, lat2), with
        points separated by arc length del_s.  Return a list of Line2D
        instances for the curves comprising the geodesic.  If the geodesic does
        not cross the map limb, there will be only a single curve; if it
        crosses the limb, there will be two curves.
        """

        # TODO:  Perhaps return a single Line2D instance when there is only a
        # single segment, and a list of segments only when there are two segs?

        # TODO:  Check the units of del_s.

        # This is based on Basemap.drawgreatcircle (which draws an *arc* of a
        # great circle), but addresses a limitation of that method, supporting
        # geodesics that cross the map boundary by breaking them into two
        # segments, one in the eastern hemisphere and the other in the western.
        gc = pyproj.Geod(a=self.rmajor, b=self.rminor)
        az12, az21, dist = gc.inv(lon1, lat1, lon2, lat2)
        npoints = int((dist + 0.5**del_s) / del_s)
        # Calculate lon & lat for points on the arc.
        lonlats = gc.npts(lon1, lat1, lon2, lat2, npoints)
        lons = [lon1]
        lats = [lat1]
        for lon, lat in lonlats:
            lons.append(lon)
            lats.append(lat)
        lons.append(lon2)
        lats.append(lat2)
        # Break the arc into segments as needed, when there is a longitudinal
        # hemisphere crossing.
        segs = []
        seg_lons, seg_lats = [lon1], [lat1]
        cur_hem = self.east_hem(lon1)
        for lon, lat in zip(lons[1:], lats[1:]):
            if self.east_hem(lon) == cur_hem:
                seg_lons.append(lon)
                seg_lats.append(lat)
            else:
                # We should interpolate a new pt at the boundary, but in
                # the mean time just rely on the step size being small.
                segs.append((seg_lons, seg_lats))
                seg_lons, seg_lats = [lon], [lat]
                cur_hem = not cur_hem
        segs.append((seg_lons, seg_lats))
        # Plot each segment; return a list of the mpl lines.
        lines = []
        for lons, lats in segs:
            x, y = self(lons, lats)
            if clip and self._limb:
                line = plot(x, y, clip_path=self._limb, **kwargs)[0]
            else:
                line = plot(x, y, **kwargs)[0]
            lines.append(line)
        # If there are multiple segments and no color args, reconcile the
        # colors, which mpl will have autoset to different values.
        # *** Does this screw up mpl's color set sequence for later lines?
        if 'c' not in kwargs or 'color' in kwargs:
            if len(lines) > 1:
                c1 = lines[0].get_color()
                for line in lines[1:]:
                    line.set_color(c1)
        return lines
예제 #26
0
"""

import logging
import netCDF4 as nc
import numpy as np
from scipy.interpolate import interp1d
from scipy.ndimage import map_coordinates

try:
    import mpl_toolkits.basemap.pyproj as pyproj
except ImportError:
    import pyproj

from mslib.utils.config import config_loader

__PR = pyproj.Geod(ellps='WGS84')


def get_distance(lat0, lon0, lat1, lon1):
    """
    Computes the distance between two points on the Earth surface
    Args:
        lat0: lat of first point
        lon0: lon of first point
        lat1: lat of second point
        lon1: lon of second point

    Returns:
        length of distance in km
    """
    return __PR.inv(lon0, lat0, lon1, lat1)[-1] / 1000.
예제 #27
0
    def tissot(self, lon_0, lat_0, radius_deg, npts, ax=None, **kwargs):
        """
        Draw a polygon centered at ``lon_0,lat_0``.  The polygon
        approximates a circle on the surface of the earth with radius
        ``radius_deg`` degrees latitude along longitude ``lon_0``,
        made up of ``npts`` vertices.
        
        The polygon represents a Tissot's indicatrix
        (http://en.wikipedia.org/wiki/Tissot's_Indicatrix),
        which when drawn on a map shows the distortion inherent in the map
        projection.  Tissots can be used to display azimuthally symmetric
        directional uncertainties ("error circles").

        Extra keyword ``ax`` can be used to override the default axis instance.

        Other \**kwargs passed on to matplotlib.patches.Polygon.

        returns a list of matplotlib.patches.Polygon objects, with two polygons
        when the tissot crosses the limb, and just one polygon otherwise.
        """

        # TODO:  Just return the polygon (not a list) when there is only one
        # polygon?  Or stick with the list for consistency?

        # This is based on Basemap.tissot, but addresses a limitation of that
        # method by handling tissots that cross the limb of the map by finding
        # separate polygons in the eastern and western hemispheres comprising
        # the tissot.
        ax = kwargs.pop('ax', None) or self._check_ax()
        g = pyproj.Geod(a=self.rmajor, b=self.rminor)
        az12, az21, dist = g.inv(lon_0, lat_0, lon_0, lat_0 + radius_deg)
        start_hem = self.east_hem(lon_0)
        segs1 = [self(lon_0, lat_0 + radius_deg)]
        over, segs2 = [], []
        delaz = 360. / npts
        az = az12
        last_lon = lon_0
        # Note adjacent and opposite edge longitudes, in case the tissot
        # runs over the edge.
        if start_hem:  # eastern case
            adj_lon = self.east_lon
            opp_lon = self.west_lon
        else:
            adj_lon = self.west_lon
            opp_lon = self.east_lon
        for n in range(npts):
            az = az + delaz
            # skip segments along equator (Geod can't handle equatorial arcs)
            if np.allclose(0., lat_0) and (np.allclose(90., az)
                                           or np.allclose(270., az)):
                continue
            else:
                lon, lat, az21 = g.fwd(lon_0, lat_0, az, dist)
            # If in the starting hemisphere, add to 1st polygon seg list.
            if self.east_hem(lon) == start_hem:
                x, y = self(lon, lat)
                # Add segment if it is in the map projection region.
                if x < 1.e20 and y < 1.e20:
                    segs1.append((x, y))
                    last_lon = lon
            # Otherwise, we cross hemispheres.
            else:
                # Trace the edge of each hemisphere.
                x, y = self(adj_lon, lat)
                if x < 1.e20 and y < 1.e20:
                    segs1.append((x, y))
                    # We presume if adj projection is okay, opposite is.
                    segs2.append(self(opp_lon, lat))
                # Also store the overlap in the opposite hemisphere.
                x, y = self(lon, lat)
                if x < 1.e20 and y < 1.e20:
                    over.append((x, y))
                    last_lon = lon
        poly1 = Polygon(segs1, **kwargs)
        ax.add_patch(poly1)
        if segs2:
            over.reverse()
            segs2.extend(over)
            poly2 = Polygon(segs2, **kwargs)
            ax.add_patch(poly2)
            return [poly1, poly2]
        else:
            return [poly1]
예제 #28
0
#!/usr/bin/env python

import calendar
import pickle
import numpy as np
from mpl_toolkits.basemap import pyproj
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
from opendrift.models.oceandrift3D import OceanDrift3D
from opendrift.readers import reader_ROMS_native
from opendrift.readers import reader_netCDF_CF_generic

geod = pyproj.Geod(ellps='WGS84')
recalc = True

alldata = {'CODE': {'norshelf': {'stokes': None, 'nostokes': None},
                    'globcur':  {'stokes': None, 'nostokes': None}},
           'iSphere': {'norshelf': {'stokes': None, 'nostokes': None},
                        'globcur':  {'stokes': None, 'nostokes': None}}
            }

# Read drifter data
f = '/disk1/data/drifter/all_trajectories_wind_unfiltered.dat'
data = pickle.load(open(f))
#print data.keys()
#print data[12].keys()

if recalc is True:
    for with_stokes in [True, False]:
        if with_stokes is True:
            hasstokes = 'stokes'
예제 #29
0
    glon2 *= 180. / np.pi
    glat2 *= 180. / np.pi
    baz *= 180. / np.pi

    return (glon2, glat2, baz)


def equi(m, centerlon, centerlat, radius, *args, **kwargs):
    glon1 = centerlon
    glat1 = centerlat
    X = []
    Y = []
    for azimuth in range(0, 360):
        glon2, glat2, baz = shoot(glon1, glat1, azimuth, radius)
        X.append(glon2)
        Y.append(glat2)
    X.append(X[0])
    Y.append(Y[0])

    #~ m.plot(X,Y,**kwargs) #Should work, but doesn't...
    X, Y = m(X, Y)
    plt.plot(X, Y, **kwargs)
    m.plot(X, Y, **kwargs)


_GEOD = pyproj.Geod(ellps='WGS84')


def CalcDist(lon1, lat1, lon2, lat2):
    return _GEOD.inv(lon1, lat1, lon2, lat2)[2] / 1000.
예제 #30
0
def mapModisRanking(mapSize,
                    mapTitle,
                    mapFile,
                    boundaryFile,
                    notePosition,
                    legendPosition,
                    outName,
                    outRes=200,
                    backgroundLabel='',
                    citiesFile=None,
                    citiesField=None,
                    citiesLabelSize=None,
                    citiesMarkerSize=None):
    '''
    Maps the ranking raster and export to file
    
    mapSize (tuple of num): Size of the ap in inches
    mapTitle (str): Title of the map 
    mapFile (str): Full address of the raster with 
        the ranking information
    boundaryFile (str): Full address of the shapefile 
        with the boundaries information
    notePosition (tuple of num): Two values between 0 and 
        1 giving the position of the top left corner of the 
        note on the chart. 
        The value are relative to the chart, so (0,0) is the
        bottom left corner and (1,1) is the top right corner. 
    legendPosition (tuple of num): Two values giving the 
        position of the legend. Same as notePosition
    outName (str): Full address of the output name for the
        chart (.png)
    outRes (int): Dpi resolution for the output chart
    backgroundLabel (str): Label for the white background
        pixels
    citiesFile (str): Full address of the shapefile with the 
        information on the cities.
    citiesField (str): Name of the field in the shapefile with 
        name of the cities to use as label
    citiesLabelSize (int): Size of the labels
    '''

    #Create new figure window
    fig = plt.figure(figsize=mapSize)  # a new figure window
    ax = fig.add_subplot(1, 1, 1)  # specify (nrows, ncols, axnum)

    #Remove frame of subplot
    ax.axis('off')

    #Add title
    ax.set_title(mapTitle, fontsize=24, weight='bold', y=1.02)

    # Read the data and metadata
    datafile = gdal.Open(mapFile)
    bnd1 = datafile.GetRasterBand(1).ReadAsArray()

    #Get no data value
    nodata = datafile.GetRasterBand(1).GetNoDataValue()

    #Change data type and remove no data value from raster
    bnd1 = bnd1.astype(float)
    bnd1[bnd1 == nodata] = np.nan

    #Get raster size, projection, and resolution
    nx = datafile.RasterXSize  # Raster xsize
    ny = datafile.RasterYSize  # Raster ysize
    gt = datafile.GetGeoTransform()
    proj = datafile.GetProjection()
    xres = gt[1]
    yres = gt[5]

    # get the edge coordinates and add half the resolution
    # to go to center coordinates
    xmin = gt[0] + xres * 0.5
    xmax = gt[0] + (xres * nx) - xres * 0.5
    ymin = gt[3] + (yres * ny) + yres * 0.5
    ymax = gt[3] - yres * 0.5

    # create a grid of lat/lon coordinates in the original projection
    (lon_source, lat_source) = np.mgrid[xmin:xmax + xres:xres,
                                        ymax + yres:ymin:yres]

    #Create the basemap
    mapR = Basemap(projection='cyl',llcrnrlat=ymin,urcrnrlat=ymax,\
                llcrnrlon=xmin,urcrnrlon=xmax , resolution='i', ax=ax)

    #Prepare the color map
    #Colors and values for scale
    colorsScale = [(255, 254, 141), (239, 48, 166), (197, 38, 182),
                   (113, 28, 198), (19, 0, 236), (28, 67, 198), (5, 251, 255)]
    stopsScale = [-3, 10, 30, 50, 70, 90, 110]
    #Normalize the colors to 0-1
    norm = mpl.colors.Normalize(vmin=0., vmax=255.)
    colorsScale = [tuple(norm(v) for v in T) for T in colorsScale]
    #Normalize the values for the scale
    norm = mpl.colors.Normalize(vmin=-3., vmax=110.)
    stopsScale = [norm(v) for v in stopsScale]
    #Combine into color scale for mapping
    purpleBlue = zip(stopsScale, colorsScale)
    #Create the segmented color map
    purpleBlueLinear = col.LinearSegmentedColormap.from_list('purpleBlue',
                                                             purpleBlue,
                                                             N=256,
                                                             gamma=1.0)
    #Create labels for colormap
    purpleBlueLabels = [
        'Below min', 'Min of the 10 ref. years', '',
        'Median of the 10 ref. years', '', 'Max of the 10 ref. Years',
        'Above max'
    ]

    # project in the original Basemap and plot with pcolormesh
    mapR.pcolormesh(lon_source, lat_source, bnd1.T, cmap=purpleBlueLinear)

    #Add boundary
    aoi_info = mapR.readshapefile(boundaryFile,
                                  'aoi',
                                  color='black',
                                  linewidth=1.3)

    if citiesFile:
        #Add major cities
        cities_info = mapR.readshapefile(citiesFile, 'cities')

        #Add the city names as labels
        cityFont = {
            'fontname': 'Arial',
            'size': str(citiesLabelSize),
            'color': 'black',
            'weight': 'bold'
        }
        for info, city in zip(mapR.cities_info, mapR.cities):
            mapR.plot(city[0],
                      city[1],
                      marker='o',
                      color='black',
                      markersize=citiesMarkerSize,
                      markeredgewidth=2)  #'o' for circle, '.' for point
            plt.text(city[0] + 0.01, city[1] + 0.005,
                     unicode(info[citiesField], 'utf-8'), **cityFont)

    #Add scale bar
    scaleParam = {
        'startLon': xmin + (xmax - xmin) * 0.62,
        'startLat': ymin + 0.01,
        'lengthKm': 100,
        'yoffset': 0.02
    }
    #Get initial lon lat in map units
    lon1, lat1 = mapR(scaleParam['startLon'],
                      scaleParam['startLat'],
                      inverse=True)
    #Get final lon lat from distance
    gc = pyproj.Geod(a=mapR.rmajor, b=mapR.rminor)
    lon2, lat2, az = gc.fwd(lon1, lat1, 90, scaleParam['lengthKm'] * 1000)
    #Get back the final lon lat in map units
    x2, y2 = mapR(lon2, lat2, inverse=False)
    #Plot the lines for the scale
    barHeight = abs(scaleParam['startLon'] - x2) / 100.
    mapR.plot([scaleParam['startLon'], x2],
              [scaleParam['startLat'], scaleParam['startLat']],
              color='k')
    mapR.plot([scaleParam['startLon'], scaleParam['startLon']], [
        scaleParam['startLat'] - barHeight, scaleParam['startLat'] + barHeight
    ],
              color='k')
    mapR.plot([x2, x2], [
        scaleParam['startLat'] - barHeight, scaleParam['startLat'] + barHeight
    ],
              color='k')
    scaleFont = {
        'fontname': 'Arial',
        'size': '18',
        'color': 'black',
        'weight': 'bold',
        'horizontalalignment': 'center'
    }
    plt.text(scaleParam['startLon'], scaleParam['startLat'] + barHeight + 0.01,
             '0', **scaleFont)
    plt.text(x2, scaleParam['startLat'] + barHeight + 0.01,
             '%s km' % (scaleParam['lengthKm']), **scaleFont)

    #Add note
    commentFont = {'fontname': 'Arial', 'size': '18', 'color': 'black'}
    comment = 'Notes:'\
        '\n--Most pixels contain other land uses \nbesides coffee.'\
        '\n--The index shows health of vegetation in \neach pixel compared to reference years, \n'\
        'not coffee production directly. '\
        '\n--Vegetative health is affected mostly by \n'\
        'natural factors (rain, etc.) but can also be \naffected by human intervention (pruning, \netc.).'
    plt.text(notePosition[0],
             notePosition[1],
             comment,
             horizontalalignment='left',
             verticalalignment='center',
             transform=ax.transAxes,
             **commentFont)

    #Prepare color legend
    if backgroundLabel:
        cmap = mpl.colors.ListedColormap([(1, 1, 1)] + colorsScale)
        #bounds = range(len(colorsScale)+1)
    else:
        cmap = mpl.colors.ListedColormap(colorsScale)
    bounds = range(cmap.N)
    norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
    #Add axis for the color legend
    legendFont = {
        'fontsize': 18,
        'fontweight': 'bold',
        'verticalalignment': 'center'
    }
    axColors = fig.add_axes([
        legendPosition[0], legendPosition[1], 0.05, 0.15
    ])  #left, bottom, width, height] in fractions of figure width and height
    cb = mpl.colorbar.ColorbarBase(
        axColors,
        cmap=cmap,
        norm=norm,
        boundaries=bounds,
        ticks=[y + 0.5 for y in range(len(colorsScale) + 1)],
        spacing='uniform',
        orientation='vertical')
    cb.ax.set_title('Legend', fontsize=20, weight='bold', x=0.7, y=1.05)
    axColors.tick_params(axis=u'both', which=u'both', length=0)
    if backgroundLabel:
        legendLabels = [backgroundLabel] + purpleBlueLabels
    else:
        legendLabels = purpleBlueLabels
    axColors.set_yticklabels(legendLabels, fontdict=legendFont)

    #Fit layout for smaller image
    plt.tight_layout()

    #Save plot
    plt.savefig(outName, dpi=outRes)