Changeset 1599

Show
Ignore:
Timestamp:
07/08/07 23:41:39 (1 year ago)
Author:
wrobe..@pld-linux.org
Message:

- move to OO oriented API

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • gmeye/trunk/gmeye/items.py

    r1594 r1599  
    33 
    44class BItem(Item): 
    5     def __init__(self, id, x, y, data=None): 
     5    def __init__(self, id, x, y, data, fields): 
    66        super(BItem, self).__init__() 
    77        self.id = id 
     
    99        self.y = y 
    1010        self._data = data 
     11        self._fields = fields 
    1112 
    1213 
     
    5556 
    5657class Layer(Item): 
    57     def __init__(self, name, x0, y0, x1, y1, p_cls = None): 
     58    def __init__(self, name): 
    5859        super(Layer, self).__init__() 
    5960        self.name = name 
    60         self.x0 = x0 
    61         self.y0 = y0 
    62         self.x1 = x1 
    63         self.y1 = y1 
    64  
    65         self._data = {} 
    66         self.icls = Line 
    67         if p_cls: 
    68             self.icls = p_cls 
     61        self._features = {} 
    6962 
    7063 
    71     def addPoint(self, id, x, y): 
    72         self._data[id] = self.icls(id, x, y) 
    73         return self._data[id] 
    74  
    75  
    76     def addLine(self, id, x, y, points): 
    77         self._data[id] = self.icls(id, x, y, points) 
    78  
     64    def add(self, feature): 
     65        self._features[feature.id] = feature  
    7966 
    8067    def draw(self, context): 
     
    8269 
    8370 
    84     def children(self): 
    85         return self._data 
     71    def features(self): 
     72        return self._features 
    8673 
    8774 
     
    9279        cr = context.cairo 
    9380        cr.set_line_width(0.005) 
    94         for d in self._data.values(): 
     81        for feature in self._features.values(): 
    9582            cr.save() 
    96             cr.translate(d.x, d.y) 
    97             if isinstance(d, Line): 
    98                 x, y = d._data[0] 
     83            cr.translate(feature.x, feature.y) 
     84            if isinstance(feature, Line): 
     85                x, y = feature._data[0] 
    9986                cr.move_to(x, y) 
    100                 for x, y in d._data[1:]: 
     87                for x, y in feature._data[1:]: 
    10188                    cr.line_to(x, y) 
    10289            cr.restore() 
  • gmeye/trunk/gmeye/loader.py

    r1594 r1599  
    22import osr 
    33 
     4import gmeye.items as item 
    45 
    5 def get_layer(ds, name, l_cls, p_cls, extents=None): 
    6     layer = ds.GetLayer(name) 
     6class Factory(object): 
     7    # Feature types 
     8    POINT = 0x01 
     9    LINE  = 0x02 
    710 
    8     if extents: 
    9         x0, y0, x1, y1 = extents 
    10     else: 
    11         x0, y0, x1, y1 = layer.GetExtent() 
    12     clayer = l_cls(name, x0, y0, x1, y1, p_cls) 
    13  
    14     fc = layer.GetFeatureCount() 
    15     print layer.GetName(), layer.GetFeatureCount(), layer.GetExtent() 
    16     f = layer.GetNextFeature() 
    17     id_index = f.GetFieldIndex('cat')  
    18     ii = 0 
    19  
    20     #ortho = osr.SpatialReference() 
    21     #proj = '+proj=ortho +lon_0=%f +lat_0=%f' % (x,y) 
    22     #ortho.ImportFromProj4(proj) 
    23     for i in range(fc): 
    24         id = f.GetField(id_index) 
    25         g = f.GetGeometryRef() 
    26         #g.TransformTo(ortho) 
    27         if g.GetGeometryType() == ogr.wkbLineString: 
    28             line = [(g.GetX(i), g.GetY(i)) for i in range(g.GetPointCount())] 
     11    def __init__(self): 
     12        self._layers = {} 
    2913 
    3014 
    31             # affine transformation for screen 
    32             x0 = min(p[0] for p in line) 
    33             y0 = max(p[1] for p in line) 
    34             line = [(x - x0, -y + y0) for x, y in line] 
    35             clayer.addLine(ii, x0 - clayer.x0, -y0 + clayer.y1, line) 
    36         elif g.GetGeometryType() == ogr.wkbPoint: 
    37             id_name = f.GetFieldIndex('FULLNAME')  
    38             name = f.GetField(id_name) 
    39             print id_name, name 
    40             x0, y0 = g.GetX(0), g.GetY(0) 
    41             pp = clayer.addPoint(ii, x0 - clayer.x0, -y0 + clayer.y1) 
    42             pp.name = name 
     15    def registerLayer(self, layer): 
     16        self._layers[layer.name] = layer 
     17 
     18 
     19    def setFeatureClass(self, name, ftype, cls): 
     20        self._layers[name]._items[ftype] = cls 
     21 
     22 
     23    def createFeature(self, name, ftype, id, x, y, data, fields): 
     24        cls = self._layers[name]._items[ftype] 
     25        return cls(id, x, y, data, fields) 
     26 
     27 
     28    def createLayer(self, name): 
     29        cls = self._layers[name].cls 
     30        return cls(name) 
     31 
     32 
     33 
     34class LayerData(object): 
     35    def __init__(self, name): 
     36        self.name = name 
     37        self.id_field = None 
     38        self.fields = [] 
     39        self._items = {} 
     40        self._items[Factory.POINT] = item.Point 
     41        self._items[Factory.LINE] = item.Line 
     42        self.cls = item.Background 
     43 
     44 
     45 
     46 
     47class Loader(object): 
     48    """ 
     49    Map loader. Reads map layers from a map. 
     50 
     51    @attr dsn: map data source name 
     52    @attr factory: items factory 
     53    """ 
     54    def __init__(self, dsn=None): 
     55        self.dsn = dsn 
     56        self.factory = Factory() 
     57        self._extents = None 
     58 
     59 
     60    def addLayer(self, name, cls=item.Background, id=None, fields=[]): 
     61        """ 
     62        Add layer to loader. 
     63 
     64        @param name:   layer name 
     65        @param cls:    layer item class 
     66        @param id:     name of field used to assign feature id 
     67        @param fields: list of fields names to be loaded from layer data 
     68        """ 
     69        ld = LayerData(name) 
     70        ld.cls = cls 
     71        ld.id = id 
     72        ld.fields = fields 
     73        self.factory.registerLayer(ld) 
     74 
     75 
     76    def load(self): 
     77        ds = ogr.Open(self.dsn) 
     78        all_layers = [] 
     79 
     80        for ld in self.factory._layers.values(): 
     81            layer = self._loadLayer(ds, ld) 
     82            all_layers.append(layer) 
     83        print all_layers 
     84        return all_layers 
     85 
     86 
     87    def _loadLayer(self, ds, ld): 
     88        layer = ds.GetLayer(ld.name) 
     89 
     90        if self._extents: 
     91            x0, y0, x1, y1 = self._extents 
    4392        else: 
    44             raise Exception, 'unknown type %d' % g.GetGeometryType() 
    45              
     93            self._extents = x0, y0, x1, y1 = layer.GetExtent() 
     94 
     95        clayer = self.factory.createLayer(ld.name) 
     96 
     97        fc = layer.GetFeatureCount() 
     98        if __debug__: 
     99            print layer.GetName(), layer.GetFeatureCount(), layer.GetExtent() 
     100 
    46101        f = layer.GetNextFeature() 
    47         ii += 1 
     102        if ld.id_field: 
     103            id_index = f.GetFieldIndex(ld.id_field) 
     104            if id_index == -1: 
     105                raise ValueError, 'field %s does not exist' % ld.id_field 
     106        else: 
     107            id = 0 
    48108 
    49     return clayer 
     109        indices = [ f.GetFieldIndex(fname) for fname in ld.fields ] 
     110        if -1 in indices: 
     111            idx = indices.index(-1) 
     112            raise ValueError, 'field %s does not exist' % ld.fields[idx] 
    50113 
    51 def get_layers(dsn, layers): 
    52     ds = ogr.Open(dsn) 
    53     all = [] 
     114        for i in range(fc): 
     115            if ld.id_field: 
     116                id = f.GetField(id_index) 
     117            else: 
     118                id += 1 
    54119 
    55     # get first to get extents 
    56     name, l_cls, p_cls =  layers[0] 
    57     l = get_layer(ds, name, l_cls, p_cls) 
    58     all.append(l) 
     120            if id is None: 
     121                raise ValueError, 'id cannot be null' 
    59122 
    60     extents = l.x0, l.y0, l.x1, l.y1 
    61     for name, l_cls, p_cls in layers[1:]: 
    62         l = get_layer(ds, name, l_cls, p_cls, extents) 
    63         all.append(l) 
    64     print 'data loaded' 
    65     return all 
     123            g = f.GetGeometryRef() 
     124            ftype = g.GetGeometryType() 
     125            if ftype == ogr.wkbLineString: 
     126                # get line data 
     127                data = [(g.GetX(i), g.GetY(i)) for i in range(g.GetPointCount())] 
     128 
     129                # affine transformation for screen 
     130                xf = min(p[0] for p in data) 
     131                yf = max(p[1] for p in data) 
     132                data = [ (x - xf, -y + yf) for x, y in data ] 
     133            elif ftype == ogr.wkbPoint: 
     134                xf, yf = g.GetX(0), g.GetY(0) 
     135                data = [] 
     136            else: 
     137                raise Exception, 'unknown feature type %d' % g.GetGeometryType() 
     138 
     139            # feature position on screen 
     140            xf = xf - x0 
     141            yf = -yf + y1 
     142 
     143            # load additional data 
     144            fields = [ f.GetField(i) for i in indices ] 
     145            fields = dict(zip(ld.fields, fields)) 
     146 
     147            cf = self.factory.createFeature(ld.name, ftype, id, xf, yf, data, fields) 
     148            clayer.add(cf) 
     149                 
     150            f = layer.GetNextFeature() 
     151 
     152        return clayer 
  • gmeye/trunk/gmeye_demo

    r1594 r1599  
    1111from gaphas.util import text_align, text_set_font 
    1212 
    13 import gmeye.loader 
     13from gmeye.loader import Loader 
    1414import gmeye.items as item 
    1515from gmeye.tool import DefaultTool 
     
    3131            text_set_font(cr, 'sans 0.2') 
    3232        cr.move_to(0, 0) 
    33         cr.show_text(self.name
     33        cr.show_text(self._fields['fullname']
    3434        cr.stroke() 
    3535        cr.restore() 
     
    7777    w = create_window(c, 'GM Eye') 
    7878 
    79     desc = [ 
    80         ('borders', item.Background, None), 
    81 #        ('roads', item.Layer, RailRoad), 
    82 #        ('rail', item.Layer, RailRoad), 
    83 #        ('pcities', item.Layer, RailRoad), 
    84         ('mcities', item.Layer, City), 
    85     ] 
    86     layers = gmeye.loader.get_layers(sys.argv[1], desc) 
     79    mloader = Loader(sys.argv[1]) 
     80    mloader.addLayer('borders') 
     81#    mloader.addLayer('roads', item.Layer, RailRoad), 
     82#    mloader.addLayer('rail', item.Layer, RailRoad), 
     83#    mloader.addLayer('pcities', item.Layer, RailRoad), 
     84    mloader.addLayer('mcities', cls=item.Layer, id='uf1', fields=['fullname']) 
    8785 
    88     # align layers 
    89     rx, ry = layers[0].x0, layers[0].y0 
     86    factory = mloader.factory 
     87    factory.setFeatureClass('mcities', factory.POINT, City) 
     88 
     89    layers = mloader.load() 
    9090 
    9191    t1 = time.time() 
     
    9595 
    9696    for layer in layers: 
    97         for d in layer.children().values(): 
     97        for d in layer.features().values(): 
    9898            d.matrix.translate(d.x, d.y) 
    9999            #print d.x, d.y