Beispiel #1
0
import numarray, cPickle
from numarray import nd_image

# example to demonstrate plotting data on a map projection.
# requires numarray, proj module (which in turn requires 
# proj command from http://proj.maptools.org)

# set up map projection parameters (lambert conformal conic,
# standard parallels at 50 deg N, center longitued 107 deg W.
params = {}
params['proj'] = 'lcc'
params['R'] = 63712000
params['lat_1'] = 50
params['lat_2'] = 50
params['lon_0'] = -107
proj = Proj(params)
llcornerx, llcornery = proj(-145.5,1.)
xmax=11297266.68; ymax=8959901.16
params['x_0'] = -llcornerx # add cartesian offset so lower left corner = (0,0)
params['y_0'] = -llcornery
# create a Proj instance for desired map.
proj = Proj(params)

# define grid (nx x ny regularly spaced native projection grid)
nx = 349; ny = 277                                                              
dx = xmax/(nx-1); dy = ymax/(ny-1)
xgrid = dx*numarray.indices((ny,nx))[1,:,:]
ygrid = dy*numarray.indices((ny,nx))[0,:,:]
# compute lons, lats of regular projection grid.
lonout, latout = proj(xgrid, ygrid, inverse=True)
# make sure lons are between 0 and 360
Beispiel #2
0
    def __init__(self,llcrnrlon,llcrnrlat,urcrnrlon,urcrnrlat,\
        resolution='c',area_thresh=10000.,projection='cyl',rsphere=6371009.,\
        lat_ts=None,lat_1=None,lat_2=None,lat_0=None,lon_0=None):
        """
 create a Basemap instance.
 
 mandatory input arguments:
 
 llcrnrlon - longitude of lower left hand corner of the desired map domain.
 llcrnrlon - latitude of lower left hand corner of the desired map domain.      
 urcrnrlon - longitude of upper right hand corner of the desired map domain.
 urcrnrlon - latitude of upper right hand corner of the desired map domain.
 
 optional keyword parameters:
 
 resolution - resolution of coastline database to use. Can be 'c' (crude, 
  roughly 25 km resolution) or 'l' (low, roughly 5 km resolution). Default 'c'.
  Coastline data is from the GSHHS 
  (http://www.soest.hawaii.edu/wessel/gshhs/gshhs.html).
 area_thresh - coastline with an area smaller than area_thresh in km^2
  will not be plotted.  Default 10,000.
 projection - map projection.  'cyl' - cylindrical equidistant, 'merc' -
  mercator, 'lcc' - lambert conformal conic, 'stere' - stereographic,
  'aea' - albers equal area conic, and 
  'laea' - lambert azimuthal equal area currently available.  Default 'cyl'.
 rsphere - radius of the sphere used to define map projection (default
  6371009 meters, close to the arithmetic mean radius of the earth).
  
 The following parameters are map projection parameters which all default to 
 None.  Not all parameters are used by all projections, some are ignored.
 
 lat_ts - latitude of natural origin (used for mercator and stereographic
  projections).
 lat_1 - first standard parallel for lambert conformal and albers
  equal area projections.
 lat_2 - second standard parallel for lambert conformal and albers
  equal area projections.
 lat_0 - central latitude (y-axis origin) - used by stereographic and
  lambert azimuthal projections).
 lon_0 - central meridian (x-axis origin - used by lambert conformal
  and lambert azimuthal and stereographic projections).
        """

        # read in coastline data.
        coastlons = []
        coastlats = []
        coastsegind = []
        coastsegarea = []
        i = 0  # the current ind
        for line in open(os.path.join(_datadir,
                                      'gshhs_' + resolution + '.txt')):
            linesplit = line.split()
            if line.startswith('P'):
                coastsegind.append(i)
                coastsegarea.append(float(linesplit[5]))
                continue
            # lon/lat
            lon, lat = [float(val) for val in linesplit]
            coastlons.append(lon)
            coastlats.append(lat)
            i += 1

        # read in country boundary data.
        cntrylons = []
        cntrylats = []
        cntrysegind = []
        i = 0  # the current ind
        for line in open(
                os.path.join(_datadir, 'countries_' + resolution + '.txt')):
            linesplit = line.split()
            if line.startswith('>'):
                cntrysegind.append(i)
                continue
            # lon/lat
            lon, lat = [float(val) for val in linesplit]
            cntrylons.append(lon)
            cntrylats.append(lat)
            i += 1

        # read in state boundaries (Americas only).
        statelons = []
        statelats = []
        statesegind = []
        i = 0  # the current ind
        for line in open(
                os.path.join(_datadir, 'states_' + resolution + '.txt')):
            linesplit = line.split()
            if line.startswith('>'):
                statesegind.append(i)
                continue
            # lon/lat
            lon, lat = [float(val) for val in linesplit]
            statelons.append(lon)
            statelats.append(lat)
            i += 1

        # extend longitudes around the earth a second time
        # (in case projection region straddles Greenwich meridian).
        # also include negative longitudes, so valid longitudes
        # can range from -360 to 720.
        coastlons2 = [lon + 360. for lon in coastlons]
        cntrylons2 = [lon + 360. for lon in cntrylons]
        statelons2 = [lon + 360. for lon in statelons]
        coastlons3 = [lon - 360. for lon in coastlons]
        cntrylons3 = [lon - 360. for lon in cntrylons]
        statelons3 = [lon - 360. for lon in statelons]

        # set up projections using Proj class.
        self.projection = projection
        self.llcrnrlon = llcrnrlon
        self.llcrnrlat = llcrnrlat
        self.urcrnrlon = urcrnrlon
        self.urcrnrlat = urcrnrlat
        projparams = {}
        projparams['proj'] = projection
        projparams['R'] = rsphere
        self.rsphere = rsphere
        if projection == 'lcc':
            if lat_1 is None or lon_0 is None:
                raise ValueError, 'must specify lat_1 and lon_0 for Lambert Conformal basemap'
            projparams['lat_1'] = lat_1
            if lat_2 != None:
                projparams['lat_2'] = lat_2
            projparams['lon_0'] = lon_0
            proj = Proj(projparams, llcrnrlon, llcrnrlat, urcrnrlon, urcrnrlat)
        elif projection == 'aea':
            if lat_1 is None or lat_2 is None or lon_0 is None:
                raise ValueError, 'must specify lat_1, lat_2 and lon_0 for Albers Equal Area basemap'
            projparams['lat_1'] = lat_1
            projparams['lat_2'] = lat_2
            projparams['lon_0'] = lon_0
            proj = Proj(projparams, llcrnrlon, llcrnrlat, urcrnrlon, urcrnrlat)
        elif projection == 'stere':
            if lat_ts is None or lat_0 is None or lon_0 is None:
                raise ValueError, 'must specify lat_ts,lat_0 and lon_0 for Stereographic basemap'
            projparams['lat_ts'] = lat_ts
            projparams['lat_0'] = lat_0
            projparams['lon_0'] = lon_0
            proj = Proj(projparams, llcrnrlon, llcrnrlat, urcrnrlon, urcrnrlat)
        elif projection == 'laea':
            if None or lat_0 is None or lon_0 is None:
                raise ValueError, 'must specify lat_0 and lon_0 for Lambert Azimuthal basemap'
            projparams['lat_0'] = lat_0
            projparams['lon_0'] = lon_0
            proj = Proj(projparams, llcrnrlon, llcrnrlat, urcrnrlon, urcrnrlat)
        elif projection == 'merc':
            if lat_ts is None:
                raise ValueError, 'must specify lat_ts for Mercator basemap'
            projparams['lat_ts'] = lat_ts
            proj = Proj(projparams, llcrnrlon, llcrnrlat, urcrnrlon, urcrnrlat)
        elif projection == 'cyl':
            proj = Proj(projparams, llcrnrlon, llcrnrlat, urcrnrlon, urcrnrlat)
        else:
            raise ValueError, 'unsupported projection'

        # make Proj instance a Basemap instance variable.
        self.projtran = proj
        # set instance variables defining map region.
        self.xmin = proj.xmin
        self.xmax = proj.xmax
        self.ymin = proj.ymin
        self.ymax = proj.ymax
        if projection == 'cyl' or projection == 'merc':
            self.aspect = (urcrnrlat - llcrnrlat) / (urcrnrlon - llcrnrlon)
        else:
            self.aspect = (proj.ymax - proj.ymin) / (proj.xmax - proj.xmin)
        self.llcrnrx = proj.llcrnrx
        self.llcrnry = proj.llcrnry
        self.urcrnrx = proj.urcrnrx
        self.urcrnry = proj.urcrnry

        # transform coastline polygons to native map coordinates.
        xc, yc = proj(N.array(coastlons, 'f'), N.array(coastlats, 'f'))
        xc2, yc2 = proj(N.array(coastlons2, 'f'), N.array(coastlats, 'f'))
        xc3, yc3 = proj(N.array(coastlons3, 'f'), N.array(coastlats, 'f'))
        if projection == 'merc': yc2 = yc
        # set up segments in form needed for LineCollection,
        # ignoring 'inf' values that are off the map, and skipping
        # polygons that have an area > area_thresh..
        segments = [
            zip(xc[i0:i1], yc[i0:i1]) for a, i0, i1 in zip(
                coastsegarea[:-1], coastsegind[:-1], coastsegind[1:])
            if a > area_thresh
        ]
        segments2 = [
            zip(xc2[i0:i1], yc2[i0:i1]) for a, i0, i1 in zip(
                coastsegarea[:-1], coastsegind[:-1], coastsegind[1:])
            if a > area_thresh and max(xc2[i0:i1]) < 1.e20
            and max(yc2[i0:i1]) < 1.e20
        ]
        segments3 = [
            zip(xc3[i0:i1], yc3[i0:i1]) for a, i0, i1 in zip(
                coastsegarea[:-1], coastsegind[:-1], coastsegind[1:])
            if a > area_thresh and max(xc3[i0:i1]) < 1.e20
            and max(yc3[i0:i1]) < 1.e20
        ]
        self.coastsegs = segments + segments2 + segments3

        # same as above for country polygons.
        xc, yc = proj(N.array(cntrylons, 'f'), N.array(cntrylats, 'f'))
        xc2, yc2 = proj(N.array(cntrylons2, 'f'), N.array(cntrylats, 'f'))
        xc3, yc3 = proj(N.array(cntrylons2, 'f'), N.array(cntrylats, 'f'))
        segments = [
            zip(xc[i0:i1], yc[i0:i1])
            for i0, i1 in zip(cntrysegind[:-1], cntrysegind[1:])
        ]
        segments2 = [
            zip(xc2[i0:i1], yc2[i0:i1])
            for i0, i1 in zip(cntrysegind[:-1], cntrysegind[1:])
            if max(xc2[i0:i1]) < 1.e20 and max(yc2[i0:i1]) < 1.e20
        ]
        segments3 = [
            zip(xc3[i0:i1], yc3[i0:i1])
            for i0, i1 in zip(cntrysegind[:-1], cntrysegind[1:])
            if max(xc3[i0:i1]) < 1.e20 and max(yc3[i0:i1]) < 1.e20
        ]
        self.cntrysegs = segments + segments2 + segments3

        # same as above for state polygons.
        xc, yc = proj(N.array(statelons, 'f'), N.array(statelats, 'f'))
        xc2, yc2 = proj(N.array(statelons2, 'f'), N.array(statelats, 'f'))
        xc3, yc3 = proj(N.array(statelons3, 'f'), N.array(statelats, 'f'))
        segments = [
            zip(xc[i0:i1], yc[i0:i1])
            for i0, i1 in zip(statesegind[:-1], statesegind[1:])
        ]
        segments2 = [
            zip(xc2[i0:i1], yc2[i0:i1])
            for i0, i1 in zip(statesegind[:-1], statesegind[1:])
            if max(xc2[i0:i1]) < 1.e20 and max(yc2[i0:i1]) < 1.e20
        ]
        segments3 = [
            zip(xc3[i0:i1], yc3[i0:i1])
            for i0, i1 in zip(statesegind[:-1], statesegind[1:])
            if max(xc3[i0:i1]) < 1.e20 and max(yc3[i0:i1]) < 1.e20
        ]
        self.statesegs = segments + segments2 + segments3

        # store coast polygons for filling.
        # special treatment (kludge) for Antarctica.
        self.coastpolygons = []
        if projection == 'merc':
            xsp, ysp = proj(0., -89.9)  # s. pole coordinates.
            xa, ya = proj(0., -68.0)  # edge of antarctica.
        for seg in self.coastsegs:
            x = [lon for lon, lat in seg]
            y = [lat for lon, lat in seg]
            # the antarctic polygon is a nuisance, since it
            # spans all longitudes, it's not closed and will not be filled
            # without some projection dependant tweaking.
            if projection == 'cyl':
                if x[-1] == 0.000 and y[-1] < -68.:  # close antarctica
                    x.append(0.)
                    y.append(-90.0000)
                    x.insert(0, 360.)
                    y.insert(0, -90)
                if x[-1] == 360.000 and y[-1] < -68.:
                    x.append(360.)
                    y.append(-90)
                    x.insert(0, 720.)
                    y.insert(0, -90)
                if x[-1] == -360.000 and y[-1] < -68.:
                    x.append(-360.)
                    y.append(-90)
                    x.insert(0, 0.)
                    y.insert(0, -90)
            elif projection == 'merc':
                if x[-1] == 0.000 and y[-1] < ya:  # close antarctica
                    x.append(0.)
                    y.append(ysp)
                    x.insert(0, 360.)
                    y.insert(0, ysp)
                if x[-1] == 360.000 and y[-1] < ya:
                    x.append(360.)
                    y.append(ysp)
                    x.insert(0, 720.)
                    y.insert(0, ysp)
                if x[-1] == -360.000 and y[-1] < ya:
                    x.append(-360.)
                    y.append(ysp)
                    x.insert(0, 0.)
                    y.insert(0, ysp)
            self.coastpolygons.append((x, y))