root/trunk/plugins/input/shape/shape_index_featureset.cpp @ 1583

Revision 1583, 6.3 kB (checked in by artem, 8 months ago)

+ implement missing support for :

multipoint
multipointm
multipointz

Line 
1/*****************************************************************************
2 *
3 * This file is part of Mapnik (c++ mapping toolkit)
4 *
5 * Copyright (C) 2006 Artem Pavlenko
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 *
21 *****************************************************************************/
22
23//$Id: shape_index_featureset.cc 36 2005-04-05 14:32:18Z pavlenko $
24
25#include <mapnik/feature_factory.hpp>
26// boost
27#include <boost/iostreams/stream.hpp>
28#include <boost/iostreams/device/file.hpp>
29#include <boost/iostreams/device/mapped_file.hpp>
30
31#include "shape_index_featureset.hpp"
32
33using namespace boost::iostreams;
34
35template <typename filterT>
36shape_index_featureset<filterT>::shape_index_featureset(const filterT& filter,
37                                                        const std::string& shape_file,
38                                                        const std::set<std::string>& attribute_names,
39                                                        std::string const& encoding)
40    : filter_(filter),
41      shape_type_(0),
42      shape_(shape_file),
43      tr_(new transcoder(encoding)),
44      count_(0)
45
46{
47    shape_.shp().skip(100);
48    stream<mapped_file_source> file(shape_file + ".index");
49    if (file)
50    {
51        shp_index<filterT,stream<mapped_file_source> >::query(filter,file,ids_);
52        file.close();
53    }
54    std::sort(ids_.begin(),ids_.end());   
55   
56#ifdef MAPNIK_DEBUG
57    std::clog<< "query size=" << ids_.size() << "\n";
58#endif
59
60    itr_ = ids_.begin();
61
62    // deal with attributes
63    std::set<std::string>::const_iterator pos=attribute_names.begin();
64    while (pos!=attribute_names.end())
65    {
66        for (int i=0;i<shape_.dbf().num_fields();++i)
67        {
68            if (shape_.dbf().descriptor(i).name_ == *pos)
69            {
70                attr_ids_.insert(i);
71                break;
72            }
73        }
74        ++pos;
75    }
76}
77
78template <typename filterT>
79feature_ptr shape_index_featureset<filterT>::next()
80{   
81    using mapnik::feature_factory;
82    using mapnik::point_impl;
83    if (itr_!=ids_.end())
84    {
85        int pos=*itr_++;
86        shape_.move_to(pos);
87        int type=shape_.type();
88       
89        feature_ptr feature(feature_factory::create(shape_.id_));
90        if (type == shape_io::shape_point)
91        {
92            double x=shape_.shp().read_double();
93            double y=shape_.shp().read_double();           
94            geometry2d * point = new point_impl;
95            point->move_to(x,y);
96            feature->add_geometry(point);
97            ++count_;
98        }
99 
100        else if (type == shape_io::shape_pointm)
101        {
102            double x=shape_.shp().read_double();
103            double y=shape_.shp().read_double();
104            shape_.shp().skip(8);// skip m
105            geometry2d * point = new point_impl;
106            point->move_to(x,y);
107            feature->add_geometry(point);
108            ++count_;
109        }
110        else if (type == shape_io::shape_pointz)
111        {
112            double x=shape_.shp().read_double();
113            double y=shape_.shp().read_double();
114            shape_.shp().skip(8*2); // skip m,z
115            geometry2d * point = new point_impl;
116            point->move_to(x,y);
117            feature->add_geometry(point);
118            ++count_;
119        }       
120        else
121        {
122            while(!filter_.pass(shape_.current_extent()) && 
123                  itr_!=ids_.end())
124            {
125                pos=*itr_++;
126                shape_.move_to(pos);
127            }
128           
129            switch (type)
130            {
131            case shape_io::shape_multipoint:
132            case shape_io::shape_multipointm:
133            case shape_io::shape_multipointz:
134            {
135                int num_points = shape_.shp().read_ndr_integer();
136                for (int i=0; i< num_points;++i)
137                { 
138                    double x=shape_.shp().read_double();
139                    double y=shape_.shp().read_double();
140                    geometry2d * point = new point_impl;
141                    point->move_to(x,y);
142                    feature->add_geometry(point);
143                }
144                // ignore m and z for now
145                ++count_;
146                break;
147            }
148            case shape_io::shape_polyline:
149            {
150                geometry2d * line = shape_.read_polyline();
151                feature->add_geometry(line);
152                ++count_;
153                break;
154            }
155            case shape_io::shape_polylinem:
156            {
157                geometry2d * line = shape_.read_polylinem();
158                feature->add_geometry(line);
159                ++count_;
160                break;
161            }
162            case shape_io::shape_polylinez:
163            {
164                geometry2d * line = shape_.read_polylinez();
165                feature->add_geometry(line);
166                ++count_;
167                break;
168            }
169            case shape_io::shape_polygon:
170            { 
171                geometry2d * poly = shape_.read_polygon();
172                feature->add_geometry(poly);
173                ++count_;
174                break;
175            }
176            case shape_io::shape_polygonm:
177            { 
178                geometry2d * poly = shape_.read_polygonm();
179                feature->add_geometry(poly);
180                ++count_;
181                break;
182            }
183            case shape_io::shape_polygonz:
184            {
185                geometry2d * poly = shape_.read_polygonz();
186                feature->add_geometry(poly);
187                ++count_;
188                break;
189            }
190            }
191        }
192        if (attr_ids_.size())
193        {
194            shape_.dbf().move_to(shape_.id_);
195            std::set<int>::const_iterator pos=attr_ids_.begin();
196            while (pos!=attr_ids_.end())
197            {
198                try 
199                {
200                    shape_.dbf().add_attribute(*pos,*tr_,*feature);
201                }
202                catch (...)
203                {
204                    std::clog<<"exception caught\n";
205                }
206                ++pos;
207            }
208        }
209        return feature;
210    }
211    else
212    {
213
214#ifdef MAPNIK_DEBUG
215        std::clog<<count_<<" features\n";
216#endif
217        return feature_ptr();
218    }
219}
220
221
222template <typename filterT>
223shape_index_featureset<filterT>::~shape_index_featureset() {}
224
225template class shape_index_featureset<mapnik::filter_in_box>;
226template class shape_index_featureset<mapnik::filter_at_point>;
Note: See TracBrowser for help on using the browser.