# 关于获取要素：

## 获取要素中的坐标值最好用ExportToWkb而不要用GetX,GetY

ExportToWkb可以批量获取所有的坐标值。而GetX，GetY只能获取单独的一个值。在绘制的时候还要费神去把它们合成一个数组，而获取了wkb，就可以进行批量解析，一下生成数组，这样，我们就可以利用到了强大的Numeric模块，进行神奇的矩阵魔术。至于wkb的格式，这里有简单的说明。 我写了一个小模块，用于解析wkb

```   1 import struct
2 import ogr
3 from array import array
4
5 import sys
6 endian_name = sys.byteorder
7
8 wkbXDR = '>'     # Big Endian
9 wkbNDR = '<'     # Little Endian
10
11 def choose(bool, a, b):
12     return (bool and [a] or [b])[0]
13
14 BTOR = choose(endian_name == 'little',wkbNDR,wkbNDR)
15
16 def up_endian_type(wkb):
17     endian_t = struct.unpack('b',wkb[0])[0]
18     endian = choose(endian_t,'<','>')
19     wkbtype = struct.unpack(endian+'I',wkb[1:5])[0]
20     return endian,wkbtype,endian_t
21
22 def up_len(wkb,beg,endian):
23     return struct.unpack(endian+'I',wkb[beg:beg+4])[0]
24
25 def up_point(wkb):
26     endian,wkbtype,et = up_endian_type(wkb)
27     points = struct.unpack(endian+"2d",wkb[5:])
28     return points
29
30 def up_linestring(wkb):
31     endian,wkbtype,et = up_endian_type(wkb)
32     lenght = up_len(wkb,5,endian)
33     points = array('d',wkb[9:9+lenght*16])
34     if endian != BTOR : points.byteswap()
35     return points
36
37 def up_linearring(wkb,ringcount,endian):
38     #endian,wkbtype,et = up_endian_type(wkb)
39     points = []
40     ptr = 0
41     for i in range(ringcount):
42         length = up_len(wkb,ptr,endian)
43         ps = array('d',wkb[ptr+4:ptr+4+length*16])
44         if endian != BTOR : ps.byteswap()
45         points.append(ps)
46         ptr += 4+length*16
47     return points,ptr
48
49 def up_polygon(wkb,sub=-1):
50     endian,wkbtype,et = up_endian_type(wkb)
51     if sub == -1:
52         ringcount = up_len(wkb,5,endian)
53         points = up_linearring(wkb[9:],ringcount,endian)[0]
54         return points
55     else:
56         points = []
57         ptr = 5
58         ringcount = up_len(wkb,ptr,endian)
59         ps,ringlen = up_linearring(wkb[ptr+4:],ringcount,endian)
60         points.append(ps)
61         ptr += 4+ringlen
62         return points,ptr
63
64 def up_mpoint(wkb):
65     endian,wkbtype,et = up_endian_type(wkb)
66     subcount = up_len(wkb,5,endian)
67     points = []
68     ptr = 9
69     for i in range(subcount):
70         subps = up_point(wkb[ptr:])
71         points.append(subps)
72         ptr += 9+len(subps)*8
73     return points
74
75 def up_mlinestring(wkb):
76     endian,wkbtype,et = up_endian_type(wkb)
77     subcount = up_len(wkb,5,endian)
78     points = []
79     ptr = 9
80     for i in range(subcount):
81         subps = up_linestring(wkb[ptr:])
82         points.append(subps)
83         ptr += 9+len(subps)*8
84     return points
85
86 def up_mpolygon(wkb):
87     endian,wkbtype,et = up_endian_type(wkb)
88     subcount = up_len(wkb,5,endian)
89     points = []
90     ptr = 9
91     for i in range(subcount):
92         subps,size = up_polygon(wkb[ptr:],i)
93         points.append(subps)
94         ptr += size
95     return points
96
97 fun_map = {
98         ogr.wkbPoint : up_point,
99         ogr.wkbLineString : up_linestring,
100         ogr.wkbPolygon : up_polygon,
101         ogr.wkbMultiPoint : up_mpoint,
102         ogr.wkbMultiLineString : up_mlinestring,
103         ogr.wkbMultiPolygon : up_mpolygon
104         }
105
106 def WkbUnPacker(wkb):
107     endian,wkbtype,endian_t = up_endian_type(wkb)
108     foo = fun_map[wkbtype]
109     points = foo(wkb)
110     return [endian_t,wkbtype,points]
111
112
113 if __name__ == "__main__":
114     import time
115     ds = ogr.Open("e:/gisdata/data/country.shp")
116     layer = ds.GetLayer()
117     begt = time.time()
118     #count = layer.GetFeatureCount()
119     #count  = 2
120     feature = layer.GetNextFeature()
121     #for i in [1]:#range(count):
122     while feature is not None:
123         #feature = layer.GetFeature(i)
124         geom = feature.GetGeometryRef()
125         #print geom.ExportToWkt()
126         wkb = geom.ExportToWkb()
127         wkbarr = WkbUnPacker(wkb)
128         feature = layer.GetNextFeature()
129         #print wkbarr
130     print time.time()-begt
```

## 加快读取大量feature时的循环速度

ogr在python绑定中读取大量feature时速度总是很慢。16000条记录单单只是获取Feature竟然运行了130秒，简直令人无法忍受。后来打开了ogr.py察看了一下绑定代码，发现在Feature类中有“setarr"和"getarr"两个自省方法在创建Feature后不断运行。试着注释掉它们，速度一下就提高到2秒。简直是飞跃啊！不过注释掉自省方法会不会有后遗症，我现在还不敢说（如果大家发现注释掉这两个自省方法有问题，或者不需要注释掉调代码而有更好的方法，希望能反馈给我）。

# 反馈

lilin/ogr-notice (last edited 2009-12-25 07:14:51 by localhost)