1
2from kartograph.geometry import MultiLineFeature
3from kartograph.layersource.layersource import LayerSource
4from shapely.geometry import LineString
5
6
7class GraticuleLayer(LayerSource):
8    """
9    special layer source for grid of longitudes and latitudes (graticule)
10    """
11    def get_features(self, latitudes, longitudes, proj, bbox=[-180, -90, 180, 90]):
12        """
13        returns a list of line features that make up
14        the graticule
15        """
16        minLat = max(proj.minLat, bbox[1])
17        maxLat = min(proj.maxLat, bbox[3])
18        minLon = bbox[0]
19        maxLon = bbox[2]
20
21        def xfrange(start, stop, step):
22            while (step > 0 and start < stop) or (step < 0 and start > step):
23                yield start
24                start += step
25
26        line_features = []
27        # latitudes
28        for lat in latitudes:
29            if lat < minLat or lat > maxLat:
30                continue
31            pts = []
32            props = {'lat': lat}
33            for lon in xfrange(-180, 181, 0.5):
34                if lon < minLon or lon > maxLon:
35                    continue
36                #if isinstance(proj, Azimuthal):
37                #    lon += proj.lon0
38                #    if lon < -180:
39                #        lon += 360
40                #    if lon > 180:
41                #        lon -= 360
42                if proj._visible(lon, lat):
43                    pts.append((lon, lat))
44            if len(pts) > 1:
45                line = MultiLineFeature(LineString(pts), props)
46                line_features.append(line)
47        # print line_features
48
49        # longitudes
50        for lon in longitudes:
51            if lon < minLon or lon > maxLon:
52                continue
53            pts = []
54            props = {'lon': lon}
55            #lat_range = xfrange(step[0], 181-step[0],1)
56            #if lon % 90 == 0:
57            #    lat_range = xfrange(0, 181,1)
58            for lat in xfrange(0, 181, 0.5):
59                lat_ = lat - 90
60                if lat_ < minLat or lat_ > maxLat:
61                    continue
62                if proj._visible(lon, lat_):
63                    pts.append((lon, lat_))
64            if len(pts) > 1:
65                line = MultiLineFeature(LineString(pts), props)
66                line_features.append(line)
67
68        return line_features
69