Revision: 4076
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4076&view=rev
Author: jswhit
Date: 2007-10-31 20:18:09 -0700 (Wed, 31 Oct 2007)
Log Message:
-----------
initial Shapely integration
Modified Paths:
--------------
trunk/toolkits/basemap-testing/lib/matplotlib/toolkits/basemap/basemap.py
Modified:
trunk/toolkits/basemap-testing/lib/matplotlib/toolkits/basemap/basemap.py
===================================================================
--- trunk/toolkits/basemap-testing/lib/matplotlib/toolkits/basemap/basemap.py
2007-11-01 03:16:07 UTC (rev 4075)
+++ trunk/toolkits/basemap-testing/lib/matplotlib/toolkits/basemap/basemap.py
2007-11-01 03:18:09 UTC (rev 4076)
@@ -17,6 +17,8 @@
from matplotlib.numerix.mlab import squeeze
from matplotlib.cbook import popd, is_scalar
from shapelib import ShapeFile
+from shapely.geometry import Polygon as PolygonShape
+from shapely import wkb
# basemap data files now installed in lib/matplotlib/toolkits/basemap/data
basemap_datadir = os.sep.join([os.path.dirname(__file__), 'data'])
@@ -676,521 +678,23 @@
area_thresh = 10.
else:
raise ValueError, "boundary resolution must be one of
'c','l','i' or 'h'"
- # read in coastline data (only those polygons whose area >
area_thresh).
- coastlons = []; coastlats = []; coastsegind = []; coastsegtype = []
- msg = """
-Unable to open boundary dataset file. Only the 'crude', 'low'
-and 'intermediate' resolution datasets are installed by default. If you
-are requesting a 'high' resolution dataset, you need to download
-and install those files manually (see the basemap README for details)."""
- try:
- bdatfile =
open(os.path.join(basemap_datadir,'gshhs_'+resolution+'.txt'))
- except:
- raise IOError, msg
- for line in bdatfile:
- linesplit = line.split()
- if line.startswith('P'):
- area = float(linesplit[5])
- west,east,south,north =
float(linesplit[6]),float(linesplit[7]),float(linesplit[8]),float(linesplit[9])
- typ = int(linesplit[3])
- useit = self.latmax>=south and self.latmin<=north and
area>area_thresh
- if useit:
- coastsegind.append(len(coastlons))
- coastsegtype.append(typ)
- continue
- # lon/lat
- if useit:
- lon, lat = [float(val) for val in linesplit]
- coastlons.append(lon)
- coastlats.append(lat)
- coastsegtype.append(typ)
- coastsegind.append(len(coastlons))
-
- # read in country boundary data.
- cntrylons = []; cntrylats = []; cntrysegind = []
- try:
- bdatfile =
open(os.path.join(basemap_datadir,'countries_'+resolution+'.txt'))
- except:
- raise IOError, msg
- for line in bdatfile:
- linesplit = line.split()
- if line.startswith('>'):
- west,east,south,north =
float(linesplit[7]),float(linesplit[8]),float(linesplit[9]),float(linesplit[10])
- useit = self.latmax>=south and self.latmin<=north
- if useit: cntrysegind.append(len(cntrylons))
- continue
- # lon/lat
- if useit:
- lon, lat = [float(val) for val in linesplit]
- cntrylons.append(lon)
- cntrylats.append(lat)
- cntrysegind.append(len(cntrylons))
-
- # read in state boundaries (Americas only).
- statelons = []; statelats = []; statesegind = []
- try:
- bdatfile =
open(os.path.join(basemap_datadir,'states_'+resolution+'.txt'))
- except:
- raise IOError, msg
- for line in bdatfile:
- linesplit = line.split()
- if line.startswith('>'):
- west,east,south,north =
float(linesplit[7]),float(linesplit[8]),float(linesplit[9]),float(linesplit[10])
- useit = self.latmax>=south and self.latmin<=north
- if useit: statesegind.append(len(statelons))
- continue
- # lon/lat
- if useit:
- lon, lat = [float(val) for val in linesplit]
- statelons.append(lon)
- statelats.append(lat)
- statesegind.append(len(statelons))
-
- # read in major rivers.
- riverlons = []; riverlats = []; riversegind = []
- try:
- bdatfile =
open(os.path.join(basemap_datadir,'rivers_'+resolution+'.txt'))
- except:
- raise IOError, msg
- for line in bdatfile:
- linesplit = line.split()
- if line.startswith('>'):
- west,east,south,north =
float(linesplit[7]),float(linesplit[8]),float(linesplit[9]),float(linesplit[10])
- useit = self.latmax>=south and self.latmin<=north
- if useit: riversegind.append(len(riverlons))
- continue
- # lon/lat
- if useit:
- lon, lat = [float(val) for val in linesplit]
- riverlons.append(lon)
- riverlats.append(lat)
- riversegind.append(len(riverlons))
-
- # extend longitudes around the earth a second time
- # so valid longitudes can range from -360 to 720.
- # This means a lot of redundant processing is done when
- # creating the class instance, but it a lot easier to figure
- # out what to do when the projection domain straddles the
- # Greenwich meridian.
- coastlons2 = [lon+360. for lon in coastlons]
- cntrylons2 = [lon+360. for lon in cntrylons]
- statelons2 = [lon+360. for lon in statelons]
- riverlons2 = [lon+360. for lon in riverlons]
- coastlons3 = [lon-360. for lon in coastlons]
- cntrylons3 = [lon-360. for lon in cntrylons]
- statelons3 = [lon-360. for lon in statelons]
- riverlons3 = [lon-360. for lon in riverlons]
-
- # transform coastline polygons to native map coordinates.
- xc,yc = proj(NX.array(coastlons),NX.array(coastlats))
- xc = xc.tolist(); yc = yc.tolist()
- xc2,yc2 = proj(NX.array(coastlons2),NX.array(coastlats))
- xc3,yc3 = proj(NX.array(coastlons3),NX.array(coastlats))
- xc2 = xc2.tolist(); yc2 = yc2.tolist()
- xc3 = xc3.tolist(); yc3 = yc3.tolist()
-
- # set up segments in form needed for LineCollection,
- # ignoring 'inf' values that are off the map.
- segments = [zip(xc[i0:i1],yc[i0:i1]) for i0,i1 in
zip(coastsegind[:-1],coastsegind[1:])]
- segmentsll = [zip(coastlons[i0:i1],coastlats[i0:i1]) for i0,i1 in
zip(coastsegind[:-1],coastsegind[1:])]
- segtypes = [i for i in coastsegtype[:-1]]
- segments2 = [zip(xc2[i0:i1],yc2[i0:i1]) for i0,i1 in
zip(coastsegind[:-1],coastsegind[1:]) if max(xc2[i0:i1]) < 1.e20 and
max(yc2[i0:i1]) < 1.e20]
- segmentsll2 = [zip(coastlons2[i0:i1],coastlats[i0:i1]) for i0,i1 in
zip(coastsegind[:-1],coastsegind[1:]) if max(xc2[i0:i1]) < 1.e20 and
max(yc2[i0:i1]) < 1.e20]
- segtypes2 = [i for i0,i1,i in
zip(coastsegind[:-1],coastsegind[1:],coastsegtype[:-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(coastsegind[:-1],coastsegind[1:]) if max(xc3[i0:i1]) < 1.e20 and
max(yc3[i0:i1]) < 1.e20]
- segmentsll3 = [zip(coastlons3[i0:i1],coastlats[i0:i1]) for i0,i1 in
zip(coastsegind[:-1],coastsegind[1:]) if max(xc3[i0:i1]) < 1.e20 and
max(yc3[i0:i1]) < 1.e20]
- segtypes3 = [i for i0,i1,i in
zip(coastsegind[:-1],coastsegind[1:],coastsegtype[:-1]) if max(xc3[i0:i1]) <
1.e20 and max(yc3[i0:i1]) < 1.e20]
- self.coastsegs = segments+segments2+segments3
- self.coastsegsll = segmentsll+segmentsll2+segmentsll3
- self.coastsegtypes = segtypes+segtypes2+segtypes3
-
- # same as above for country segments.
- xc,yc = proj(NX.array(cntrylons),NX.array(cntrylats))
- xc = xc.tolist(); yc = yc.tolist()
- xc2,yc2 = proj(NX.array(cntrylons2),NX.array(cntrylats))
- xc3,yc3 = proj(NX.array(cntrylons3),NX.array(cntrylats))
- xc2 = xc2.tolist(); yc2 = yc2.tolist()
- xc3 = xc3.tolist(); yc3 = yc3.tolist()
- 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 segments.
- xc,yc = proj(NX.array(statelons),NX.array(statelats))
- xc = xc.tolist(); yc = yc.tolist()
- xc2,yc2 = proj(NX.array(statelons2),NX.array(statelats))
- xc3,yc3 = proj(NX.array(statelons3),NX.array(statelats))
- xc2 = xc2.tolist(); yc2 = yc2.tolist()
- xc3 = xc3.tolist(); yc3 = yc3.tolist()
- 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
-
- # same as above for river segments.
- xc,yc = proj(NX.array(riverlons),NX.array(riverlats))
- xc = xc.tolist(); yc = yc.tolist()
- xc2,yc2 = proj(NX.array(riverlons2),NX.array(riverlats))
- xc3,yc3 = proj(NX.array(riverlons3),NX.array(riverlats))
- xc2 = xc2.tolist(); yc2 = yc2.tolist()
- xc3 = xc3.tolist(); yc3 = yc3.tolist()
- segments = [zip(xc[i0:i1],yc[i0:i1]) for i0,i1 in
zip(riversegind[:-1],riversegind[1:])]
- segments2 = [zip(xc2[i0:i1],yc2[i0:i1]) for i0,i1 in
zip(riversegind[:-1],riversegind[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(riversegind[:-1],riversegind[1:]) if max(xc3[i0:i1]) < 1.e20 and
max(yc3[i0:i1]) < 1.e20]
- self.riversegs = segments+segments2+segments3
-
- # store coast polygons for filling.
+ self.area_thresh = area_thresh
+ # define map boundary polygon (in lat/lon coordinates)
+ self._boundarypoly = self._getmapboundary()
+ # read in coastline polygons, only keeping those that
+ # intersect map boundary polygon.
+ self.coastsegs, self.coastpolygontypes =
self._readboundarydata('gshhs')
+ # same for countries, states, rivers.
+ self.cntrysegs, types = self._readboundarydata('countries')
+ self.statesegs, types = self._readboundarydata('states')
+ self.riversegs, types = self._readboundarydata('rivers')
+ # for coastlines, reformat as polygons.
self.coastpolygons = []
- coastpolygonsll = []
- self.coastpolygontypes = []
- if projection in ['merc','mill']:
- xsp,ysp = proj(0.,-89.9) # s. pole coordinates.
- xa,ya = proj(0.,-68.) # edge of antarctica.
- x0,y0 = proj(0.,0.)
- xm360,ym360 = proj(-360.,0.)
- x360,y360 = proj(360.,0.)
- x720,y720 = proj(720.,0.)
- for seg,segtype,segll in
zip(self.coastsegs,self.coastsegtypes,self.coastsegsll):
- x = [lon for lon,lat in seg]
- y = [lat for lon,lat in seg]
- lons = [lon for lon,lat in segll]
- lats = [lat for lon,lat in segll]
- # 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)
- lons.append(0.)
- lats.append(-90.)
- lons.insert(0,360.)
- lats.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)
- lons.append(360.)
- lats.append(-90.)
- lons.insert(0,720.)
- lats.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)
- lons.append(-360.)
- lats.append(-90.)
- lons.insert(0,0.)
- lats.insert(0,-90.)
- elif projection in ['merc','mill']:
- if math.fabs(x[-1]-x0) < 1. and y[-1] < ya: # close antarctica
- x.append(x0)
- y.append(ysp)
- x.insert(0,x360)
- y.insert(0,ysp)
- lons.append(0.)
- lats.append(-90.)
- lons.insert(0,360.)
- lats.insert(0,-90.)
- if math.fabs(x[-1]-x360) < 1. and y[-1] < ya:
- x.append(x360)
- y.append(ysp)
- x.insert(0,x720)
- y.insert(0,ysp)
- lons.append(360.)
- lats.append(-90.)
- lons.insert(0,720.)
- lats.insert(0,-90.)
- if math.fabs(x[-1]-xm360) < 1. and y[-1] < ya:
- x.append(xm360)
- y.append(ysp)
- x.insert(0,x0)
- y.insert(0,ysp)
- lons.append(-360.)
- lats.append(-90.)
- lons.insert(0,0.)
- lats.insert(0,-90.)
+ for xy in self.coastsegs:
+ x = [x1 for x1,x2 in xy]
+ y = [x2 for x1,x2 in xy]
self.coastpolygons.append((x,y))
- coastpolygonsll.append((lons,lats))
- self.coastpolygontypes.append(segtype)
- # remove those segments/polygons that don't intersect map region.
- coastsegs = []
- coastsegtypes = []
- for seg,segtype in zip(self.coastsegs,self.coastsegtypes):
- if self._insidemap_seg(seg):
- coastsegs.append(seg)
- coastsegtypes.append(segtype)
- self.coastsegs = coastsegs
- self.coastsegtypes = coastsegtypes
- polygons = []
- polygonsll = []
- polygontypes = []
- for poly,polytype,polyll in
zip(self.coastpolygons,self.coastpolygontypes,coastpolygonsll):
- if self._insidemap_poly(poly,polyll):
- polygons.append(poly)
- polygontypes.append(polytype)
- polygonsll.append(polyll)
- self.coastpolygons = polygons
- coastpolygonsll = polygonsll
- self.coastpolygontypes = polygontypes
- states = []; rivers = []; countries = []
- for seg in self.cntrysegs:
- if self._insidemap_seg(seg):
- countries.append(seg)
- for seg in self.statesegs:
- if self._insidemap_seg(seg):
- states.append(seg)
- for seg in self.riversegs:
- if self._insidemap_seg(seg):
- rivers.append(seg)
- self.statesegs = states
- self.riversegs = rivers
- self.cntryegs = countries
-
- # split up segments that go outside projection limb
- coastsegs = []
- coastsegtypes = []
- for seg,segtype in zip(self.coastsegs,self.coastsegtypes):
- xx = NX.array([x for x,y in seg],NX.Float32)
- yy = NX.array([y for x,y in seg],NX.Float32)
- i1,i2 = self._splitseg(xx,yy)
- if i1 and i2:
- for i,j in zip(i1,i2):
- segment = zip(xx[i:j].tolist(),yy[i:j].tolist())
- coastsegs.append(segment)
- coastsegtypes.append(segtype)
- else:
- coastsegs.append(seg)
- coastsegs.append(segtype)
- self.coastsegs = coastsegs
- self.coastsegtypes = coastsegtypes
- states = []
- for seg in self.statesegs:
- xx = NX.array([x for x,y in seg],NX.Float32)
- yy = NX.array([y for x,y in seg],NX.Float32)
- i1,i2 = self._splitseg(xx,yy)
- if i1 and i2:
- for i,j in zip(i1,i2):
- segment = zip(xx[i:j].tolist(),yy[i:j].tolist())
- states.append(segment)
- else:
- states.append(seg)
- self.statesegs = states
- countries = []
- for seg in self.cntrysegs:
- xx = NX.array([x for x,y in seg],NX.Float32)
- yy = NX.array([y for x,y in seg],NX.Float32)
- i1,i2 = self._splitseg(xx,yy)
- if i1 and i2:
- for i,j in zip(i1,i2):
- segment = zip(xx[i:j].tolist(),yy[i:j].tolist())
- countries.append(segment)
- else:
- countries.append(seg)
- self.cntrysegs = countries
- rivers = []
- for seg in self.riversegs:
- xx = NX.array([x for x,y in seg],NX.Float32)
- yy = NX.array([y for x,y in seg],NX.Float32)
- i1,i2 = self._splitseg(xx,yy)
- if i1 and i2:
- for i,j in zip(i1,i2):
- segment = zip(xx[i:j].tolist(),yy[i:j].tolist())
- rivers.append(segment)
- else:
- rivers.append(seg)
- self.riversegs = rivers
-
- # split coastline segments that jump across entire plot.
- coastsegs = []
- coastsegtypes = []
- for seg,segtype in zip(self.coastsegs,self.coastsegtypes):
- xx = NX.array([x for x,y in seg],NX.Float32)
- yy = NX.array([y for x,y in seg],NX.Float32)
- xd = (xx[1:]-xx[0:-1])**2
- yd = (yy[1:]-yy[0:-1])**2
- dist = NX.sqrt(xd+yd)
- split = dist > 5000000.
- if NX.sum(split) and self.projection not in ['merc','cyl','mill']:
- ind =
(NX.compress(split,squeeze(split*NX.indices(xd.shape)))+1).tolist()
- iprev = 0
- ind.append(len(xd))
- for i in ind:
- coastsegs.append(zip(xx[iprev:i],yy[iprev:i]))
- coastsegtypes.append(segtype)
- iprev = i
- else:
- coastsegs.append(seg)
- coastsegtypes.append(segtype)
- self.coastsegs = coastsegs
- self.coastsegtypes = coastsegtypes
-
- # special treatment of coastline polygons for
- # geostationary, orthographic, sinusoidal, mollweide and robinson.
- # (polygon clipping along projection limb)
- if self.projection in ['ortho','geos']:
- if self.projection == 'ortho':
- lat_0 = math.radians(self.projparams['lat_0'])
- else:
- lat_0 = 0.
- lon_0d = self.projparams['lon_0']
- lon_0 = math.radians(lon_0d)
- if self.projection == 'ortho':
- rad = self.rmajor
- else:
- # quadratic mean radius of ellipsoid.
- rad = math.sqrt((3.*self._width**2 + self._height**2)/4.)
- del_s = 50.
- gc = pyproj.Geod(a=self.rmajor,b=self.rminor)
- coastpolygons = []
- coastpolygontypes = []
- for poly,polytype,polyll in
zip(self.coastpolygons,self.coastpolygontypes,coastpolygonsll):
- x = poly[0]
- y = poly[1]
- lons = polyll[0]
- lats = polyll[1]
- mask = NX.logical_or(NX.greater(x,1.e20),NX.greater(y,1.e20))
- # replace values in polygons that are over the horizon.
- xsave = False
- ysave = False
- if NX.sum(mask):
- i1,i2 = self._splitseg(x,y,mask=mask)
- # loop over segments of polygon that are outside projection limb.
- for i,j in zip(i1,i2):
- # if it's not the rest of the polygon ...
- if i and j != len(x):
- # compute distance and azimuth between projection center
- # and last point inside project limb.
-
az1,alpha21,dist=gc.inv(lon_0,lat_0,math.radians(lons[i]),math.radians(lats[i]),radians=True)
- # also compute lat, lon of that great circle, plus back
- # azimuth.
-
lon1,lat1,az=gc.fwd(lon_0,lat_0,az1,0.5*math.pi*rad,radians=True)
- # compute distance and azimuth between projection center
- # and next point inside projection limb.
-
az2,alpha21,dist=gc.inv(lon_0,lat_0,math.radians(lons[j]),math.radians(lats[j]),radians=True)
- # also compute lat, lon of that great circle, plus back
- # azimuth.
-
lon2,lat2,az=gc.fwd(lon_0,lat_0,az2,0.5*math.pi*rad,radians=True)
- # compute distance between those two points.
- az12,az21,dist =
gc.inv(lon1,lon2,lat1,lat2,radians=True)
- # compute set of equally space points del_s meters apart
- # along great circle between those two points (the last
- # inside the projection limb and the next point inside the
- # the projection limb).
- npoints = int((dist+0.5*1000.*del_s)/(1000.*del_s))
- if npoints < 2: npoints=2
- lonlats =
gc.npts(math.degrees(lon2),math.degrees(lat2),math.degrees(lon1),math.degrees(lat1),npoints)
-
lonstmp=[math.degrees(lon2)];latstmp=[math.degrees(lat2)]
- for lon,lat in lonlats:
- lonstmp.append(lon); latstmp.append(lat)
- lonstmp.append(math.degrees(lon1));
latstmp.append(math.degrees(lat1))
- # convert that set of points to projection coordinates.
- # replace the points in the polygon which were outside
- # the projection limb.
- xx, yy = self(lonstmp, latstmp)
- xnew = x[i:j] + xx
- ynew = y[i:j] + yy
- coastpolygons.append((xnew,ynew))
- coastpolygontypes.append(polytype)
- elif i == 0:
- xsave = x[0:j]
- ysave = y[0:j]
- lats_save = lats[0:j]
- lons_save = lons[0:j]
- # it's the entire rest of the polygon ...
- elif j == len(x):
- xnew = x[i:j] + xsave
- ynew = y[i:j] + ysave
- lonsnew = lons[i:j] + lons_save
- latsnew = lats[i:j] + lats_save
-
az1,alpha21,dist=gc.inv(lon_0,lat_0,math.radians(lonsnew[0]),math.radians(latsnew[0]),radians=True)
-
lon1,lat1,az=gc.fwd(lon_0,lat_0,az1,0.5*math.pi*rad,radians=True)
-
az2,alpha21,dist=gc.inv(lon_0,lat_0,math.radians(lonsnew[-1]),math.radians(latsnew[-1]),radians=True)
-
lon2,lat2,az=gc.fwd(lon_0,lat_0,az2,0.5*math.pi*rad,radians=True)
- az12,az21,dist =
gc.inv(lon2,lat2,lon1,lat1,radians=True)
- npoints = int((dist+0.5*1000.*del_s)/(1000.*del_s))
- if npoints < 2: npoints=2
- lonlats =
gc.npts(math.degrees(lon2),math.degrees(lat2),math.degrees(lon1),math.degrees(lat1),npoints)
-
lonstmp=[math.degrees(lon2)];latstmp=[math.degrees(lat2)]
- for lon,lat in lonlats:
- lonstmp.append(lon); latstmp.append(lat)
-
lonstmp.append(math.degrees(lon1));latstmp.append(math.degrees(lat1))
- xx, yy = self(lonstmp, latstmp)
- xnew = xnew + xx
- ynew = ynew + yy
- coastpolygons.append((xnew,ynew))
- coastpolygontypes.append(polytype)
- else: # no part of polygon outside projection limb.
- coastpolygons.append(poly)
- coastpolygontypes.append(polytype)
- self.coastpolygons = coastpolygons
- self.coastpolygontypes = coastpolygontypes
- elif self.projection in ['moll','robin','sinu']:
- lon_0 = self.projparams['lon_0']
- coastpolygons=[]
- for poly,polytype,polyll in
zip(self.coastpolygons,self.coastpolygontypes,coastpolygonsll):
- x = poly[0]
- y = poly[1]
- lons = polyll[0]
- lats = polyll[1]
- xn=[]
- yn=[]
- # antarctic segment goes from 360 back to 0
- # reorder to go from lon_0-180 to lon_0+180.
- if lats[-1] < -68.0:
- lons.reverse()
- lats.reverse()
- xx,yy = self(lons,lats)
- xx = NX.array(xx); yy = NX.array(yy)
- xdist = NX.fabs(xx[1:]-xx[0:-1])
- if max(xdist) > 1000000:
- nmin = NX.argmax(xdist)+1
- xnew = NX.zeros(len(xx),NX.Float64)
- ynew = NX.zeros(len(xx),NX.Float64)
- lonsnew = len(xx)*[0]
- latsnew = len(xx)*[0]
- xnew[0:len(xx)-nmin] = xx[nmin:]
- ynew[0:len(xx)-nmin] = yy[nmin:]
- xnew[len(xx)-nmin:] = xx[0:nmin]
- ynew[len(xx)-nmin:] = yy[0:nmin]
- lonsnew[0:len(xx)-nmin] = lons[nmin:]
- latsnew[0:len(xx)-nmin] = lats[nmin:]
- lonsnew[len(xx)-nmin:] = lons[0:nmin]
- latsnew[len(xx)-nmin:] = lats[0:nmin]
- x = xnew.tolist(); y = ynew.tolist()
- lons = lonsnew; lats = latsnew
- else:
- x.reverse()
- y.reverse()
- # close polygon (add lines along left and right edges down
to S pole)
- for phi in NX.arange(-89.999,lats[0],0.1):
- xx,yy = self(lon_0-179.99,phi)
- xn.append(xx); yn.append(yy)
- xn = xn+x
- yn = yn+y
- for phi in NX.arange(lats[-1],-89.999,-0.1):
- xx,yy = self(lon_0+179.99,phi)
- xn.append(xx); yn.append(yy)
- # move points outside map to edge of map
- # along constant latitude.
- else:
- for x,y,lon,lat in zip(x,y,lons,lats):
- if lon > lon_0+180 or lon < lon_0-180:
- if lon >= lon_0+180: lon=lon_0+180.
- if lon <= lon_0-180: lon=lon_0-180.
- xx,yy = self(lon,lat)
- xn.append(xx); yn.append(yy)
- else:
- xn.append(x); yn.append(y)
- coastpolygons.append((xn,yn))
- self.coastpolygons = coastpolygons
-
def _splitseg(self,xx,yy,mask=None):
"""split segment up around missing values (outside projection limb)"""
if mask is None:
@@ -1266,6 +770,138 @@
"""
return self.projtran.makegrid(nx,ny,returnxy=returnxy)
+ def _readboundarydata(self,name):
+ msg = """
+Unable to open boundary dataset file. Only the 'crude', 'low'
+and 'intermediate' resolution datasets are installed by default. If you
+are requesting a 'high' resolution dataset, you need to download
+and install those files manually (see the basemap README for details)."""
+ try:
+ bdatfile =
open(os.path.join(basemap_datadir,name+'_'+self.resolution+'.dat'),'rb')
+ bdatmetafile =
open(os.path.join(basemap_datadir,name+'meta_'+self.resolution+'.dat'),'r')
+ except:
+ raise IOError, msg
+ polygons = []
+ polygon_types = []
+ for line in bdatmetafile:
+ linesplit = line.split()
+ area = float(linesplit[1])
+ type = int(linesplit[0])
+ south = float(linesplit[2])
+ north = float(linesplit[3])
+ if area < 0.: area = 1.e30
+ useit = self.latmax>=south and self.latmin<=north and
area>self.area_thresh
+ # skip Antartica for now.
+ if name == 'gshhs' and south < -60.: useit=False
+ if useit:
+ offsetbytes = int(linesplit[4])
+ bytecount = int(linesplit[5])
+ bdatfile.seek(offsetbytes,0)
+ polystring = bdatfile.read(bytecount)
+ poly = wkb.loads(polystring)
+ if poly.intersects(self._boundarypoly):
+ #a = npy.asarray(self._boundarypoly.boundary)
+ #b = npy.asarray(poly.boundary)
+ #import pylab
+ #pylab.fill(a[:,0],a[:,1],'r')
+ #pylab.fill(b[:,0],b[:,1],'b')
+ #pylab.show()
+ poly = poly.intersection(self._boundarypoly)
+ if hasattr(poly,'geoms'):
+ geoms = poly.geoms
+ else:
+ geoms = [poly]
+ for psub in geoms:
+ if name == 'gshhs':
+ b = npy.asarray(psub.boundary)
+ else:
+ b = npy.asarray(psub.coords)
+ blons = b[:,0]; blats = b[:,1]
+ bx, by = self(blons, blats)
+ #if (bx > 1.20).any() or (by > 1.e20).any():
+ # continue
+ polygons.append(zip(bx,by))
+ polygon_types.append(type)
+ return polygons, polygon_types
+
+
+ def _getmapboundary(self):
+ """
+ define map boundary polygon (in lat/lon coordinates)
+ """
+ dtheta = 0.1
+ dx = (self.xmax-self.xmin)/100.
+ dy = (self.ymax-self.ymin)/100.
+ if self.projection == 'ortho' and self._fulldisk:
+ # circular region.
+ thetas = npy.arange(0.,2.*npy.pi,dtheta)
+ radius = self.rmajor
+ x = radius*npy.cos(thetas) + 0.5*self.xmax
+ y = radius*npy.sin(thetas) + 0.5*self.ymax
+ elif self.projection == 'geos' and self._fulldisk:
+ # elliptical region
+ thetas = npy.arange(0.,2.*npy.pi+0.5*dtheta,dtheta)
+ rminor = self._height
+ rmajor = self._width
+ x = rmajor*npy.cos(thetas) + 0.5*self.xmax
+ y = rminor*npy.sin(thetas) + 0.5*self.ymax
+ elif self.projection in ['moll','robin','sinu']:
+ # quasi-elliptical region.
+ x = []; y = []
+ # left side
+ lats = NX.arange(-89.9,89.9+dtheta,dtheta).tolist()
+ lons = len(lats)*[self.projparams['lon_0']-179.9]
+ x,y = self(lons,lats)
+ # top.
+ lons =
NX.arange(self.projparams['lon_0']-179.9,self.projparams['lon_0']+179+dtheta,dtheta).tolist()
+ lats = len(lons)*[89.9]
+ xx,yy = self(lons,lats)
+ x = x+xx; y = y+yy
+ # right side
+ lats = NX.arange(89.9,-89.9-dtheta,-dtheta).tolist()
+ lons = len(lats)*[self.projparams['lon_0']+179.9]
+ xx,yy = self(lons,lats)
+ x = x+xx; y = y+yy
+ # bottom.
+ lons =
NX.arange(self.projparams['lon_0']+179.9,self.projparams['lon_0']-180-dtheta,-dtheta).tolist()
+ lats = len(lons)*[-89.9]
+ xx,yy = self(lons,lats)
+ x = x+xx; y = y+yy
+ x = npy.array(x,npy.float64)
+ y = npy.array(y,npy.float64)
+ else: # all other projections are rectangular.
+ # left side (x = xmin, ymin <= y <= ymax)
+ yy = npy.arange(self.ymin, self.ymax+0.5*dy, dy)
+ x = len(yy)*[self.xmin]; y = yy.tolist()
+ # top (y = ymax, xmin <= x <= xmax)
+ xx = npy.arange(self.xmin, self.xmax+0.5*dx, dx)
+ x = x + xx.tolist()
+ y = y + len(xx)*[self.ymax]
+ # right side (x = xmax, ymin <= y <= ymax)
+ yy = npy.arange(self.ymax, self.ymin-0.5*dy, -dy)
+ x = x + len(yy)*[self.xmax]; y = y + yy.tolist()
+ # bottom (y = ymin, xmin <= x <= xmax)
+ xx = npy.arange(self.xmax, self.xmin-0.5*dx, -dx)
+ x = x + xx.tolist()
+ y = y + len(xx)*[self.ymin]
+ x = npy.array(x,npy.float64)
+ y = npy.array(y,npy.float64)
+ lons, lats = self(x,y,inverse=True)
+ # fix lons so there are no jumps.
+ n = 1
+ lonprev = lons[0]
+ for lon,lat in zip(lons[1:],lats[1:]):
+ if npy.abs(lon-lonprev) > 90.:
+ if lonprev < 0:
+ lon = lon - 360.
+ else:
+ lon = lon + 360
+ lons[n] = lon
+ lonprev = lon
+ n = n + 1
+ return PolygonShape(zip(lons,lats))
+
+
def drawmapboundary(self,color='k',linewidth=1.0,ax=None):
"""
draw boundary around map projection region. If ax=None (default),
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins