source: qesdi/geoplot/trunk/lib/geoplot/map_national_grid.py @ 5710

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/qesdi/geoplot/trunk/lib/geoplot/map_national_grid.py@5710
Revision 5710, 5.8 KB checked in by pnorton, 11 years ago (diff)

Cleaned up a the import statements for the geoplot modules, also fixed a couple of the tests.

Line 
1"""
2map_national_grid.py
3===================
4Holds the MapNationalGrid class which is used to draw a grid above a national grid scaled map. This class uses the matplotlib.toolkits.basemap class to render the national grid map.
5"""
6
7import logging
8import math
9
10from matplotlib.ticker import FuncFormatter, FixedLocator
11
12import geoplot.mpl_imports
13from geoplot.map_base import MapBase
14from geoplot.filtered_basemap import FilteredBasemap
15
16log = logging.getLogger(__name__)
17
18BASEMAP_RESOLUTION = 'l'
19
20# National Grid parameters
21trueOrigin = (358.0, 49.0)
22falseOrigin = (-400000, 100000)
23
24bmxLimits = (-20,20); bmyLimits = (40,70)
25
26llBasemaps = {}
27
28def getBasemap(resolution):
29   
30    if resolution not in llBasemaps.keys():
31        addBasemap(resolution)
32   
33    return llBasemaps[resolution]
34
35def addBasemap(resolution):
36   
37    llBasemaps[resolution] = \
38        FilteredBasemap(projection='tmerc',
39                    lon_0=trueOrigin[0],
40                    lat_0=trueOrigin[1],
41                    llcrnrlon=bmxLimits[0],
42                    llcrnrlat=bmyLimits[0],
43                    urcrnrlon=bmxLimits[1],
44                    urcrnrlat=bmyLimits[1],
45                    resolution=resolution,
46                    suppress_ticks=False)
47       
48
49class MapNationalGrid(MapBase):
50    """
51    Represents a map scaled to the national grid. This class is repsonsible for knowing about
52    the limits of the map, what is to be drawn on it as well as getting the grid to draw itself
53    and basemap to draw the map.
54    """
55    def __init__(self, xLimits, yLimits, drawCoast=True, drawRivers=True, addShapefile=False,
56                 resolution=None):
57        """
58        Constructs the map object.
59
60        @param xLimits:a tuple representing the (longitude) limits of the map
61        @type xLimits: a tuple of 2 floats, corresponding to (min, max)
62        @param yLimits:a tuple representing the (latitude) limits of the map
63        @type yLimits: a tuple of 2 floats , corresponding to (min, max)
64        @param drawCoast: indicates if coaslines should be drawn
65        @type drawCoast: boolean
66        @param drawRivers: indicates if rivers should be drawn
67        @type drawRivers: boolean
68        @param addShapefile: location of shapefile to overlay
69        @type addShapefile: string
70        """
71
72        if resolution == None:
73            self.basemap = getBasemap(BASEMAP_RESOLUTION)
74        else:
75            self.basemap = getBasemap(resolution)
76
77        MapBase.__init__(self, xLimits, yLimits, drawCoast, drawRivers, addShapefile)
78
79       
80    def _configAxes(self, axes):
81        """
82        Configure an axes instance to account for the false origin.
83
84        Call this method on the axes instance of a plot to make the
85        tick labels match the false origin of the projection.
86
87        @note: THIS IS A HACK.
88
89        """
90       
91
92        xff = FuncFormatter(self._makeFormatFunc('x'))
93        yff = FuncFormatter(self._makeFormatFunc('y'))
94
95        axes.xaxis.set_major_formatter(xff)
96        axes.yaxis.set_major_formatter(yff)
97
98        self._setFormatLocations(axes.xaxis, falseOrigin[0])
99        self._setFormatLocations(axes.yaxis, falseOrigin[1])
100
101    def _setFormatLocations(self, axis, shift):
102       
103        #get the min and max in terms of National grid units
104        if geoplot.mpl_imports.oldMatplotlib == True:
105            interval = axis.get_major_locator().viewInterval
106            min =  interval.get_bounds()[0]- shift
107            max = interval.get_bounds()[1]- shift
108        else:
109            interval = axis.get_view_interval()
110            min = interval[0] - shift
111            max = interval[1] - shift
112           
113        spacingList = [200000, 100000, 50000, 20000, 10000, 5000, 1000]
114
115        for spacing in spacingList:
116#            log.debug("trying spacing " + str(spacing))
117            #work out the first and last tick to be drawn,
118            #note that stop is the tick after the end of the axis, this is to make sure all
119            #the ticks are drawn
120            start = int(math.ceil(min/spacing) * spacing)
121            stop =  int(math.ceil(max/spacing) * spacing)
122#            log.debug("stop, start:" + str(stop) + "," + str(start))
123#            log.debug("(stop - start)/spacing:" + str((stop-start)/spacing))
124
125            #if there are at least 3 axis ticks use this spacing.
126            if (stop - start) / spacing > 2 :
127                break
128
129        #get the locations
130        locs =  [ p + shift for p in range(start, stop, spacing)]
131
132        #draw then on the axis
133        axis.set_major_locator(FixedLocator(locs))
134
135    def _makeFormatFunc(self, axis):
136        if axis == 'x':
137            offset = falseOrigin[0]
138        elif axis == 'y':
139            offset = falseOrigin[1]
140        else:
141            raise ValueError("axis must be 'x' or 'y'")
142
143        def kmFormatFunc(m, pos=None):
144            """Format a value in metres into a string in km.
145
146            """
147            km = (float(m)  - offset) / 1000
148            return '%.0f km'%km
149
150        return kmFormatFunc
151
152if __name__ == '__main__':
153   
154    import geoplot.log_util as log_util
155    log_util.setupGeoplotConsoleHandler(log)
156         
157    from matplotlib.backends.backend_agg import FigureCanvasAgg
158    from matplotlib.figure import Figure     
159   
160    import pkg_resources, os
161    outputsDir = os.path.abspath(pkg_resources.resource_filename('geoplot', '../../outputs'))   
162
163    #setup the figure
164    figsize=(600 / 80, 800 / 80)
165    fig = Figure(figsize=figsize, dpi=80)
166    axes = fig.add_axes([0.1, 0.1, 0.8, 0.8])
167   
168    xLimits=(-7.5, 7.5) ; yLimits=(45.0, 65.0)
169   
170    map = MapNationalGrid(xLimits, yLimits)
171   
172    map.drawMap(axes)
173   
174    canvas = FigureCanvasAgg(fig)
175    filename = "map_national_grid_test.png"
176   
177    fullPath = os.path.join(outputsDir, filename)
178    canvas.print_figure(fullPath)
179    log.debug("Wrote " + fullPath)
Note: See TracBrowser for help on using the repository browser.