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

Reply via email to