def find_parameters(f): """ Find the polar stereographic parameters from a ROMS netcdf file Input: f: a netCDF4.Dataset from a grid file Returnurns a PolarStereographic instance The variables lon_rho, lat_rho, angle, and pm are required in the file. Return some nonsence if the grid is not polar stereographic with center at North pole, spherical earth radius 6371 km and true length at 60 degrees. The function is_polstereo can be used to detect this. """ lat_ts = 60.0 # Latitude of true scale # The number of grid cells Lm = len(f.dimensions['xi_rho']) - 2 Mm = len(f.dimensions['eta_rho']) - 2 #print "Lm, Mm =", Lm, Mm try: lon0 = f.variables['lon_rho'][0, 0] lat0 = f.variables['lat_rho'][0, 0] angle0 = f.variables['angle'][0, 0] pm0 = f.variables['pm'][0, 0] except KeyError as e: v = "Missing essential variable %s in %s" % (e, ROMSfile) raise KeyError(v) sys.exit(1) ylon = lon0 + angle0 * deg ylon = round(ylon, 2) dx = 1.0 / pm0 * (1 + np.sin(lat_ts * rad)) / (1 + np.sin(lat0 * rad)) dx = round(dx, 2) # Make a grid mapping with origin at north pole gmap0 = gridmap.PolarStereographic(0.0, 0.0, dx, ylon, 1, 1) x, y = gmap0.ll2grid(lon0, lat0) xp = round(-x, 3) yp = round(-y, 3) return gridmap.PolarStereographic(xp, yp, dx, ylon, Lm, Mm)
def setUp(self): """Make a small grid file for testing""" xp, yp, dx, ylon = 418.25, 257.25, 10000, 58 Lm, Mm = 30, 20 self.grid_name = "test10km" self.file_name = self.grid_name + "_grid.nc" self.gmap = gridmap.PolarStereographic(xp, yp, dx, ylon, Lm, Mm) gridmap.create_grid(self.gmap, self.grid_name, self.file_name)
from __future__ import print_function import pyproj import gridmap xp = 418.25 # x grid coordinate of north pole yp = 257.25 # y grid coordinate of north pole dx = 10000 # grid resolution (at lat_ts) [m] ylon = 58.0 # angle of y-axis [deg] lon, lat = 2, 66 # Station M x, y = 200.0, 100.0 print("\n --- sphere ---\n") gmap = gridmap.PolarStereographic(xp, yp, dx, ylon) print(gmap.proj4string) pmap = pyproj.Proj(gmap.proj4string) x0, y0 = gmap.ll2grid(lon, lat) x1, y1 = pmap(lon, lat) x1, y1 = x1 / gmap.dx, y1 / gmap.dx print("pyproj : ", x1, y1) print("gmap.ll2grid : ", x0, y0) print("difference [m] : ", ((x1 - x0)**2 + (y1 - y0)**2)**0.5 * gmap.dx) lon0, lat0 = gmap.grid2ll(x, y) lon1, lat1 = pmap(x * gmap.dx, y * gmap.dx, inverse=True)
import gridmap #f = Dataset('b0.nc') #gmap = gridmap.fromfile(f) #L = len(f.dimensions['xi_rho']) #M = len(f.dimensions['eta_rho']) xp = 418.25 # x grid coordinate of north pole yp = 257.25 # y grid coordinate of north pole dx = 10000 # grid resolution (at lat_ts) [m] ylon = 58.0 # angle of y-axis [deg] Lm, Mm = 125, 100 L, M = Lm + 1, Mm + 1 gmap = gridmap.PolarStereographic(xp, yp, dx, ylon) lon0, lat0 = gmap.grid2ll(0.0, 0.0) lon1, lat1 = gmap.grid2ll(L, M) projection = '-JS%s/90.0/22c' % str(ylon) extent = '-R%g/%g/%g/%gr' % (lon0, lat0, lon1, lat1) boundary = "-B30g15/20g5" landcolor = '-Ggreen' command = "pscoast %s %s %s %s -Wthinnest -A200 > a.ps" % \ (projection, extent, boundary, landcolor) print(command) system(command) system('gv a.ps')
class test_PolarStereographic0(unittest.TestCase): """Test some analytic properties of the polar stereographic map""" xp, yp, dx, ylon = 418.25, 257.25, 10000.0, 58.0 map0 = gridmap.PolarStereographic(xp, yp, dx, ylon) map1 = gridmap.PolarStereographic(xp, yp, dx, ylon, ellipsoid=gridmap.WGS84) # Flytt de to første, til test_Interface def test_scalar(self): """Should return a scalar for scalar input""" pass def test_vector(self): """Return arrays of the same shape as the input""" def test_north_pole_forward(self): """The coordinates of the North Pole are xp, yp""" lon, lat = 17.2, 90.0 # sphere x0, y0 = self.map0.ll2grid(lon, lat) self.assertEqual((x0, y0), (self.xp, self.yp)) # WGS84 x1, y1 = self.map1.ll2grid(lon, lat) self.assertEqual((x1, y1), (self.xp, self.yp)) def test_north_pole_backward(self): """Longitude is not defined at the North Pole""" # Should raise an exception # sphere lon0, lat0 = self.map0.grid2ll(self.xp, self.yp) # WGS84 lon1, lat1 = self.map1.grid2ll(self.xp, self.yp) def test_ylon(self): """lon = ylon <=> x = xp""" # lon = ylon => x = xp lon, lat = self.ylon, 72.3 # sphere x0, y0 = self.map0.ll2grid(lon, lat) self.assertEqual(x0, self.xp) # WGS84 x1, y1 = self.map1.ll2grid(lon, lat) self.assertEqual(x1, self.xp) # x = xp => y = ylon x, y = self.xp, 222.222 # sphere lon0, lat0 = self.map0.grid2ll(x, y) self.assertAlmostEqual(lon0, self.ylon, places=13) # WGS84 lon1, lat1 = self.map1.grid2ll(x, y) self.assertAlmostEqual(lon1, self.ylon, places=13) # x = xp, => angle = 0 x, y = self.xp, 222.222 # sphere angle0 = self.map0.angle(x, y) self.assertEqual(angle0, 0.0) # WGS84 angle1 = self.map1.angle(x, y) self.assertEqual(angle1, 0.0) def test_inverse(self): """grid2ll and ll2grid are inverse""" lon, lat = 5.323333, 60.3925 # Bergen # sphere: ll -> xy -> ll x0, y0 = self.map0.ll2grid(lon, lat) lon0, lat0 = self.map0.grid2ll(x0, y0) self.assertAlmostEqual(lon0, lon, places=14) self.assertEqual(lat0, lat) # WGS84: ll -> zy -> ll x1, y1 = self.map1.ll2grid(lon, lat) lon1, lat1 = self.map1.grid2ll(x1, y1) self.assertAlmostEqual(lon1, lon, places=14) self.assertAlmostEqual(lat1, lat, places=10) x, y = 200.0, 133.12345 # "Arbitrary" # sphere xy -> ll -> xy lon0, lat0 = self.map0.grid2ll(x, y) x0, y0 = self.map0.ll2grid(lon0, lat0) self.assertAlmostEqual(x0, x, places=12) self.assertAlmostEqual(y0, y, places=12) # WGS84: xy -> ll -> xy lon1, lat1 = self.map1.grid2ll(x, y) x1, y1 = self.map1.ll2grid(lon1, lat1) self.assertAlmostEqual(x1, x, places=9) self.assertAlmostEqual(y1, y, places=9) def test_angle(self): """angle = ylon - lon [rad]""" lon, lat = 5.323333, 60.3925 # Bergen angle = (self.ylon - lon)*pi/180 # sphere x0, y0 = self.map0.ll2grid(lon, lat) angle0 = self.map0.angle(x0, y0) self.assertAlmostEqual(angle0, angle, places=15) # WGS84 x1, y1 = self.map1.ll2grid(lon, lat) angle1 = self.map1.angle(x1, y1) self.assertAlmostEqual(angle1, angle, places=15) def test_scale(self): """scale = 1 at 60 deg""" lon, lat = -10.0, 60.0 # sphere x0, y0 = self.map0.ll2grid(lon, lat) scale0 = self.map0.map_scale(x0, y0) self.assertAlmostEqual(scale0, 1.0, places=15) # WGS84 x1, y1 = self.map1.ll2grid(lon, lat) scale1 = self.map1.map_scale(x1, y1) self.assertAlmostEqual(scale1, 1.0, places=12)
def setUp(self): """Make a test projection""" xp, yp, dx, ylon = 418.25, 257.25, 10000, 58 Lm, Mm = 100, 80 self.gmap = gridmap.PolarStereographic(xp, yp, dx, ylon, Lm, Mm)
#Lm, Mm = 1, 1 # Name of grid grid_name = "demo10km" #grid_name = "demo10km_WGS84" # global_attributes = dict(Institution='Institute of Marine Research', date=str(datetime.date.today())) # ----------------------------------- # Define the grid map object, with grid size try: gmap = gridmap.PolarStereographic(xp, yp, dx, ylon, Lm=Lm, Mm=Mm, ellipsoid=ellipsoid) except NameError: # ellipsoid not set, using default (= sphere) gmap = gridmap.PolarStereographic(xp, yp, dx, ylon, Lm, Mm) # Create the ROMS grid file #gridmap.create_grid(gmap, grid_name) gridmap.create_grid(gmap, grid_name, global_attributes=global_attributes, format='NETCDF4_CLASSIC')
class test_PolarStereographic(unittest.TestCase): xp, yp, dx, ylon = 418.25, 257.25, 10000.0, 58.0 map0 = gridmap.PolarStereographic(xp, yp, dx, ylon) map1 = gridmap.PolarStereographic(xp, yp, dx, ylon, ellipsoid=gridmap.WGS84) def test_sphere_values(self): """Test some check values using spherical earth Check values from proj4 with projstring +proj=stere +a=6371000.0 +lat_0=90 +lat_ts=60.0 \ +x_0=4182500.0 +y_0=2572500.0 +lon_0=58.0 """ #print self.map0.projstring2() lon, lat = 2, 66 # Station M x0, y0 = 208.75489165788943, 115.9437651864196 # from proj4 x, y = self.map0.ll2grid(lon, lat) #self.assertAlmostEqual(x, x0, places=12) #self.assertAlmostEqual(y, y0, places=12) lon, lat = 5.323333, 60.3925 # Bergen x, y = self.map0.ll2grid(lon, lat) x0, y0 = 168.398192, 66.753081 # from proj4 #self.assertAlmostEqual(x, x0, places=12) #self.assertAlmostEqual(y, y0, places=12) def test_WGS84_values(self): """Test some check values using WGS84 ellipsoid Check values from proj4 proj +proj=stere +lat_0=90 +lon_0=ylon +lat_ts=60 +x_0=xp*dx +y_0=yp*dx """ lon, lat = 2, 66 # Station M x0, y0 = 207.924459, 115.383632 # from proj4 x, y = self.map1.ll2grid(lon, lat) self.assertAlmostEqual(x, x0, places=6) self.assertAlmostEqual(y, y0, places=6) lon, lat = 5.323333, 60.3925 # Bergen x, y = self.map1.ll2grid(lon, lat) x0, y0 = 167.482134, 66.054642 # from proj4 self.assertAlmostEqual(x, x0, places=6) self.assertAlmostEqual(y, y0, places=6) def test_inverse_sphere(self): lon0, lat0 = 2, 66 # Station M x, y = self.map0.ll2grid(lon0, lat0) lon1, lat1 = self.map0.grid2ll(x, y) self.assertAlmostEqual(lon0, lon1, places=12) self.assertAlmostEqual(lat0, lat1, places=12) lon0, lat0 = 5.323333, 60.3925 # Bergen x, y = self.map0.ll2grid(lon0, lat0) lon1, lat1 = self.map0.grid2ll(x, y) self.assertAlmostEqual(lon0, lon1, places=12) self.assertAlmostEqual(lat0, lat1, places=12) def test_inverse_WGS84(self): lon0, lat0 = 2, 66 # Station M x, y = self.map1.ll2grid(lon0, lat0) lon1, lat1 = self.map1.grid2ll(x, y) self.assertAlmostEqual(lon0, lon1, places=12) self.assertAlmostEqual(lat0, lat1, places=10) lon0, lat0 = 5.323333, 60.3925 # Bergen x, y = self.map1.ll2grid(lon0, lat0) lon1, lat1 = self.map1.grid2ll(x, y) self.assertAlmostEqual(lon0, lon1, places=12) self.assertAlmostEqual(lat0, lat1, places=10) def test_angle(self): lon, lat = self.ylon, 71.2 # at "vertical" latitude x, y = self.map0.ll2grid(lon, lat) angle = self.map0.angle(x, y) self.assertEqual(angle, 0.0) x, y = self.map1.ll2grid(lon, lat) angle = self.map1.angle(x, y) self.assertEqual(angle, 0.0) lon, lat = 2, 66 # Station M x, y = self.map0.ll2grid(lon, lat) angle = self.map0.angle(x, y) self.assertEqual(angle, (self.ylon - lon) * pi / 180) x, y = self.map1.ll2grid(lon, lat) angle = self.map1.angle(x, y) self.assertEqual(angle, (self.ylon - lon) * pi / 180) def test_scale(self): """map_scale should give 1 at 60 degrees north""" lon, lat = 5, 60 # at true latitude x, y = self.map0.ll2grid(lon, lat) scale = self.map0.map_scale(x, y) self.assertAlmostEqual(scale, 1.0, places=14) x, y = self.map1.ll2grid(lon, lat) scale = self.map1.map_scale(x, y) self.assertAlmostEqual(scale, 1.0, places=12)