~ubuntu-branches/ubuntu/trusty/mapnik/trusty

« back to all changes in this revision

Viewing changes to src/wkb.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Sauthier
  • Date: 2009-08-27 00:28:37 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090827002837-ztqzfg2rmclfh4i9
Tags: 0.6.1-0ubuntu1
* New upstream release.
* Change usr/lib to usr/lib* to enable build on 64 bits systems due to new
  configuration in SConstruct in :
  - debian/libmapnik-dev.install
  - debian/libmapnik0.6.install
  - debian/mapnik-plugin-base

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
//$Id: wkb.cpp 19 2005-03-22 13:53:27Z pavlenko $
24
24
 
 
25
#include <mapnik/global.hpp>
25
26
#include <mapnik/wkb.hpp>
26
 
 
27
27
#include <mapnik/geom_util.hpp>
28
28
#include <mapnik/feature.hpp>
29
29
 
 
30
// boost
 
31
#include <boost/utility.hpp>
 
32
 
30
33
namespace mapnik
31
34
{
32
 
   struct wkb_reader
33
 
   {
34
 
      private:
35
 
         enum wkbByteOrder {
 
35
    struct wkb_reader : boost::noncopyable
 
36
    {
 
37
    private:
 
38
        enum wkbByteOrder {
36
39
            wkbXDR=0,
37
40
            wkbNDR=1
38
 
         };
39
 
         const char* wkb_;
40
 
         unsigned size_;
41
 
         unsigned pos_;
42
 
         wkbByteOrder byteOrder_;
43
 
         bool needSwap_;
44
 
         wkbFormat format_;
 
41
        };
 
42
        const char* wkb_;
 
43
        unsigned size_;
 
44
        unsigned pos_;
 
45
        wkbByteOrder byteOrder_;
 
46
        bool needSwap_;
 
47
        wkbFormat format_;
45
48
 
46
 
      public:
 
49
    public:
47
50
        
48
 
         enum wkbGeometryType {
 
51
        enum wkbGeometryType {
49
52
            wkbPoint=1,
50
53
            wkbLineString=2,
51
54
            wkbPolygon=3,
53
56
            wkbMultiLineString=5,
54
57
            wkbMultiPolygon=6,
55
58
            wkbGeometryCollection=7
56
 
         };
 
59
        };
57
60
        
58
 
         wkb_reader(const char* wkb,unsigned size,wkbFormat format)
 
61
        wkb_reader(const char* wkb,unsigned size,wkbFormat format)
59
62
            : wkb_(wkb),
60
63
              size_(size),
61
64
              pos_(0),
62
65
              format_(format)
63
 
         {
 
66
        {
64
67
            switch (format_)
65
68
            {
66
 
               case wkbSpatiaLite:
67
 
                  byteOrder_ = (wkbByteOrder) wkb_[1];
68
 
                  pos_ = 39;
69
 
                  break;
 
69
            case wkbSpatiaLite:
 
70
                byteOrder_ = (wkbByteOrder) wkb_[1];
 
71
                pos_ = 39;
 
72
                break;
70
73
 
71
 
               case wkbGeneric:
72
 
               default:
73
 
                  byteOrder_ = (wkbByteOrder) wkb_[0];
74
 
                  pos_ = 1;
75
 
                  break;
 
74
            case wkbGeneric:
 
75
            default:
 
76
                byteOrder_ = (wkbByteOrder) wkb_[0];
 
77
                pos_ = 1;
 
78
                break;
76
79
            }
77
80
 
78
 
#ifndef WORDS_BIGENDIAN
 
81
#ifndef MAPNIK_BIG_ENDIAN
79
82
            needSwap_=byteOrder_?wkbXDR:wkbNDR;
80
83
#else
81
84
            needSwap_=byteOrder_?wkbNDR:wkbXDR; 
82
85
#endif      
83
 
         }
84
 
 
85
 
         ~wkb_reader() {}
86
 
 
87
 
         void read_multi(Feature & feature) 
88
 
         {
 
86
        }
 
87
 
 
88
        ~wkb_reader() {}
 
89
 
 
90
        void read_multi(Feature & feature) 
 
91
        {
89
92
            int type=read_integer();
90
93
            switch (type)
91
94
            {
92
 
               case wkbPoint:
93
 
                  read_point(feature);
94
 
                  break;
95
 
               case wkbLineString:
96
 
                  read_linestring(feature);
97
 
                  break;
98
 
               case wkbPolygon:
99
 
                  read_polygon(feature);
100
 
                  break;
101
 
               case wkbMultiPoint:
102
 
                  read_multipoint(feature);
103
 
                  break;
104
 
               case wkbMultiLineString:
105
 
                  read_multilinestring(feature);
106
 
                  break;
107
 
               case wkbMultiPolygon:
108
 
                  read_multipolygon(feature);
109
 
                  break;
110
 
               case wkbGeometryCollection:
111
 
                  break;
112
 
               default:
113
 
                  break;
 
95
            case wkbPoint:
 
96
                read_point(feature);
 
97
                break;
 
98
            case wkbLineString:
 
99
                read_linestring(feature);
 
100
                break;
 
101
            case wkbPolygon:
 
102
                read_polygon(feature);
 
103
                break;
 
104
            case wkbMultiPoint:
 
105
                read_multipoint(feature);
 
106
                break;
 
107
            case wkbMultiLineString:
 
108
                read_multilinestring(feature);
 
109
                break;
 
110
            case wkbMultiPolygon:
 
111
                read_multipolygon(feature);
 
112
                break;
 
113
            case wkbGeometryCollection:
 
114
                break;
 
115
            default:
 
116
                break;
114
117
            }
115
 
         }
 
118
        }
116
119
         
117
 
         void read(Feature & feature) 
118
 
         {
 
120
        void read(Feature & feature) 
 
121
        {
119
122
            int type=read_integer();
120
123
            switch (type)
121
124
            {
122
 
               case wkbPoint:
123
 
                  read_point(feature);
124
 
                  break;
125
 
               case wkbLineString:
126
 
                  read_linestring(feature);
127
 
                  break;
128
 
               case wkbPolygon:
129
 
                  read_polygon(feature);
130
 
                  break;
131
 
               case wkbMultiPoint:
132
 
                  read_multipoint_2(feature);
133
 
                  break;
134
 
               case wkbMultiLineString:
135
 
                  read_multilinestring_2(feature);
136
 
                  break;
137
 
               case wkbMultiPolygon:
138
 
                  read_multipolygon_2(feature);
139
 
                  break;
140
 
               case wkbGeometryCollection:
141
 
                  break;
142
 
               default:
143
 
                  break;
 
125
            case wkbPoint:
 
126
                read_point(feature);
 
127
                break;
 
128
            case wkbLineString:
 
129
                read_linestring(feature);
 
130
                break;
 
131
            case wkbPolygon:
 
132
                read_polygon(feature);
 
133
                break;
 
134
            case wkbMultiPoint:
 
135
                read_multipoint_2(feature);
 
136
                break;
 
137
            case wkbMultiLineString:
 
138
                read_multilinestring_2(feature);
 
139
                break;
 
140
            case wkbMultiPolygon:
 
141
                read_multipolygon_2(feature);
 
142
                break;
 
143
            case wkbGeometryCollection:
 
144
                break;
 
145
            default:
 
146
                break;
144
147
            }
145
 
         }
 
148
        }
146
149
          
147
 
      private:
148
 
         wkb_reader(const wkb_reader&);
149
 
         wkb_reader& operator=(const wkb_reader&);
150
 
        
151
 
         int read_integer() 
152
 
         {
153
 
            int n;
154
 
 
155
 
            if (!needSwap_)
 
150
    private:
 
151
        
 
152
        int read_integer() 
 
153
        {
 
154
            boost::int32_t n;
 
155
            if (needSwap_)
156
156
            {
157
 
               memcpy(&n,wkb_+pos_,4);
 
157
                read_int32_xdr(wkb_+pos_,n);
158
158
            } 
159
159
            else 
160
160
            {
161
 
               const char* b=wkb_+pos_;
162
 
               n = (b[3]&0xff) | ((b[2]&0xff)<<8) | ((b[1]&0xff)<<16) | ((b[0]&0xff)<<24);
 
161
                read_int32_ndr(wkb_+pos_,n);
163
162
            }
164
163
            pos_+=4;
165
 
 
 
164
            
166
165
            return n;
167
 
         }
 
166
        }
168
167
        
169
 
         double read_double()
170
 
         {
 
168
        double read_double()
 
169
        {
171
170
            double d;
172
 
 
173
 
            if (!needSwap_)
 
171
            if (needSwap_)
174
172
            {
175
 
               memcpy(&d,wkb_+pos_,8);
 
173
                read_double_xdr(wkb_ + pos_, d);
176
174
            }
177
175
            else 
178
176
            {
179
 
               // we rely on the fact that "long long" is in C standard,
180
 
               // but not in C++ yet
181
 
               // this is not quite portable
182
 
               const char* b= wkb_+pos_;
183
 
               long long n = ((long long)b[7]&0xff) | 
184
 
                             (((long long)b[6]&0xff)<<8) | 
185
 
                             (((long long)b[5]&0xff)<<16) | 
186
 
                             (((long long)b[4]&0xff)<<24) |
187
 
                             (((long long)b[3]&0xff)<<32) |
188
 
                             (((long long)b[2]&0xff)<<40) |
189
 
                             (((long long)b[1]&0xff)<<48) |
190
 
                             (((long long)b[0]&0xff)<<56);
191
 
               memcpy(&d,&n,8);
 
177
                read_double_ndr(wkb_ + pos_, d);
192
178
            }
193
179
            pos_+=8;
194
 
 
 
180
            
195
181
            return d;
196
 
         }
 
182
        }
197
183
        
198
 
         void read_coords(CoordinateArray& ar)
199
 
         {
 
184
        void read_coords(CoordinateArray& ar)
 
185
        {
200
186
            int size=sizeof(coord<double,2>)*ar.size();
201
187
            if (!needSwap_)
202
188
            {
203
 
               std::memcpy(&ar[0],wkb_+pos_,size);
204
 
                
 
189
                std::memcpy(&ar[0],wkb_+pos_,size);
 
190
                pos_+=size;
205
191
            }
206
192
            else 
207
193
            {
208
 
               for (unsigned i=0;i<ar.size();++i)
209
 
               {
210
 
                  ar[i].x=read_double();
211
 
                  ar[i].y=read_double();
212
 
               }
 
194
                for (unsigned i=0;i<ar.size();++i)
 
195
                {
 
196
                    read_double_xdr(wkb_ + pos_,ar[i].x);
 
197
                    read_double_xdr(wkb_ + pos_ + 8,ar[i].y);
 
198
                    pos_ += 16;
 
199
                }
213
200
            }
214
 
            pos_+=size;
215
 
         }
 
201
            
 
202
        }
216
203
        
217
 
         void read_point(Feature & feature)
218
 
         {
 
204
        void read_point(Feature & feature)
 
205
        {
219
206
            geometry2d * pt = new point<vertex2d>;
220
207
            double x = read_double();
221
208
            double y = read_double();
222
209
            pt->move_to(x,y);
223
210
            feature.add_geometry(pt);
224
 
         }
 
211
        }
225
212
         
226
 
         void read_multipoint(Feature & feature)
227
 
         {
 
213
        void read_multipoint(Feature & feature)
 
214
        {
228
215
            int num_points = read_integer();
229
216
            for (int i=0;i<num_points;++i) 
230
217
            {
231
 
               pos_+=5;
232
 
               read_point(feature);
 
218
                pos_+=5;
 
219
                read_point(feature);
233
220
            }
234
 
         }
 
221
        }
235
222
         
236
 
         void read_multipoint_2(Feature & feature)
237
 
         {
 
223
        void read_multipoint_2(Feature & feature)
 
224
        {
238
225
            geometry2d * pt = new point<vertex2d>;
239
226
            int num_points = read_integer(); 
240
227
            for (int i=0;i<num_points;++i) 
241
228
            {
242
 
               pos_+=5;
243
 
               double x = read_double();
244
 
               double y = read_double();
245
 
               pt->move_to(x,y);
 
229
                pos_+=5;
 
230
                double x = read_double();
 
231
                double y = read_double();
 
232
                pt->move_to(x,y);
246
233
            }
247
234
            feature.add_geometry(pt);
248
 
         }
 
235
        }
249
236
         
250
 
         void read_linestring(Feature & feature)
251
 
         {
 
237
        void read_linestring(Feature & feature)
 
238
        {
252
239
            geometry2d * line = new line_string<vertex2d>;
253
240
            int num_points=read_integer();
254
241
            CoordinateArray ar(num_points);
257
244
            line->move_to(ar[0].x,ar[0].y);
258
245
            for (int i=1;i<num_points;++i)
259
246
            {
260
 
               line->line_to(ar[i].x,ar[i].y);
 
247
                line->line_to(ar[i].x,ar[i].y);
261
248
            }
262
249
            feature.add_geometry(line);
263
 
         }
 
250
        }
264
251
         
265
 
         void read_multilinestring(Feature & feature)
266
 
         {
 
252
        void read_multilinestring(Feature & feature)
 
253
        {
267
254
            int num_lines=read_integer();
268
255
            for (int i=0;i<num_lines;++i)
269
256
            {
270
 
               pos_+=5;
271
 
               read_linestring(feature);
 
257
                pos_+=5;
 
258
                read_linestring(feature);
272
259
            }
273
 
         }
 
260
        }
274
261
 
275
 
         void read_multilinestring_2(Feature & feature)
276
 
         {
 
262
        void read_multilinestring_2(Feature & feature)
 
263
        {
277
264
            geometry2d * line = new line_string<vertex2d>;
278
265
            int num_lines=read_integer();
279
266
            unsigned capacity = 0;
280
267
            for (int i=0;i<num_lines;++i)
281
268
            {
282
 
               pos_+=5;
283
 
               int num_points=read_integer();
284
 
               capacity+=num_points;
285
 
               CoordinateArray ar(num_points); 
286
 
               read_coords(ar);
287
 
               line->set_capacity(capacity);
288
 
               line->move_to(ar[0].x,ar[0].y); 
289
 
               for (int i=1;i<num_points;++i) 
290
 
               { 
291
 
                  line->line_to(ar[i].x,ar[i].y); 
292
 
               } 
 
269
                pos_+=5;
 
270
                int num_points=read_integer();
 
271
                capacity+=num_points;
 
272
                CoordinateArray ar(num_points); 
 
273
                read_coords(ar);
 
274
                line->set_capacity(capacity);
 
275
                line->move_to(ar[0].x,ar[0].y); 
 
276
                for (int i=1;i<num_points;++i) 
 
277
                { 
 
278
                    line->line_to(ar[i].x,ar[i].y); 
 
279
                } 
293
280
            }
294
281
            feature.add_geometry(line);
295
 
         }
 
282
        }
296
283
         
297
 
         void read_polygon(Feature & feature) 
298
 
         {
 
284
        void read_polygon(Feature & feature) 
 
285
        {
299
286
            geometry2d * poly = new polygon<vertex2d>;
300
287
            int num_rings=read_integer();
301
288
            unsigned capacity = 0;
302
289
            for (int i=0;i<num_rings;++i)
303
290
            {
304
 
               int num_points=read_integer();
305
 
               capacity+=num_points;
306
 
               CoordinateArray ar(num_points);
307
 
               read_coords(ar);
308
 
               poly->set_capacity(capacity);
309
 
               poly->move_to(ar[0].x,ar[0].y);
310
 
               for (int j=1;j<num_points;++j)
311
 
               {
312
 
                  poly->line_to(ar[j].x,ar[j].y);
313
 
               }
 
291
                int num_points=read_integer();
 
292
                capacity+=num_points;
 
293
                CoordinateArray ar(num_points);
 
294
                read_coords(ar);
 
295
                poly->set_capacity(capacity);
 
296
                poly->move_to(ar[0].x,ar[0].y);
 
297
                for (int j=1;j<num_points;++j)
 
298
                {
 
299
                    poly->line_to(ar[j].x,ar[j].y);
 
300
                }
314
301
            }
315
302
            feature.add_geometry(poly);
316
 
         }
 
303
        }
317
304
        
318
 
         void read_multipolygon(Feature & feature)
319
 
         {
 
305
        void read_multipolygon(Feature & feature)
 
306
        {
320
307
            int num_polys=read_integer();
321
308
            for (int i=0;i<num_polys;++i)
322
309
            {
323
 
               pos_+=5;
324
 
               read_polygon(feature);
 
310
                pos_+=5;
 
311
                read_polygon(feature);
325
312
            }
326
 
         }
 
313
        }
327
314
 
328
 
         void read_multipolygon_2(Feature & feature)
329
 
         {
 
315
        void read_multipolygon_2(Feature & feature)
 
316
        {
330
317
            geometry2d * poly = new polygon<vertex2d>;
331
318
            int num_polys=read_integer();
332
319
            unsigned capacity = 0;
333
320
            for (int i=0;i<num_polys;++i)
334
321
            {
335
 
               pos_+=5;
336
 
               int num_rings=read_integer();
337
 
               for (int i=0;i<num_rings;++i)
338
 
               {
339
 
                  int num_points=read_integer();
340
 
                  capacity += num_points;
341
 
                  CoordinateArray ar(num_points);
342
 
                  read_coords(ar);
343
 
                  poly->set_capacity(capacity);
344
 
                  poly->move_to(ar[0].x,ar[0].y);
 
322
                pos_+=5;
 
323
                int num_rings=read_integer();
 
324
                for (int i=0;i<num_rings;++i)
 
325
                {
 
326
                    int num_points=read_integer();
 
327
                    capacity += num_points;
 
328
                    CoordinateArray ar(num_points);
 
329
                    read_coords(ar);
 
330
                    poly->set_capacity(capacity);
 
331
                    poly->move_to(ar[0].x,ar[0].y);
345
332
                  
346
 
                  for (int j=1;j<num_points;++j)
347
 
                  {
348
 
                     poly->line_to(ar[j].x,ar[j].y);
349
 
                  }
350
 
                  poly->line_to(ar[0].x,ar[0].y);
351
 
               }
 
333
                    for (int j=1;j<num_points;++j)
 
334
                    {
 
335
                        poly->line_to(ar[j].x,ar[j].y);
 
336
                    }
 
337
                    poly->line_to(ar[0].x,ar[0].y);
 
338
                }
352
339
            }
353
340
            feature.add_geometry(poly);
354
 
         }
355
 
   };
356
 
   
357
 
   void geometry_utils::from_wkb (Feature & feature,
 
341
        }
 
342
    };
 
343
    
 
344
    void geometry_utils::from_wkb (Feature & feature,
358
345
                                   const char* wkb,
359
346
                                   unsigned size,
360
347
                                   bool multiple_geometries,
361
348
                                   wkbFormat format) 
362
 
   {
363
 
      wkb_reader reader(wkb,size,format);
364
 
      if (multiple_geometries)
365
 
         return reader.read_multi(feature);
366
 
      else
367
 
         return reader.read(feature);
368
 
   }    
 
349
    {
 
350
        wkb_reader reader(wkb,size,format);
 
351
        if (multiple_geometries)
 
352
            return reader.read_multi(feature);
 
353
        else
 
354
            return reader.read(feature);
 
355
    }    
369
356
}