root/trunk/clustr/clustr.h

Revision 461, 7.7 kB (checked in by aaron, 1 year ago)

version 0.2

Line 
1 /*
2 Clustr.  Copyright (c) 2007-2008 Yahoo! Inc.
3
4 All rights reserved.  This code is free software; you can redistribute it
5 and/or modify it under the terms of the GNU General Public License (GPL),
6 version 2 only.  This code is distributed WITHOUT ANY WARRANTY, whether
7 express or implied. See the GNU GPL for more details
8 (http://www.gnu.org/licenses/gpl.html)
9
10 AS A SPECIAL EXCEPTION, YOU HAVE PERMISSION TO LINK THIS PROGRAM WITH THE
11 CGAL LIBRARY AND DISTRIBUTE EXECUTABLES, AS LONG AS YOU FOLLOW THE REQUIREMENTS
12 OF THE GNU GPL VERSION 2 IN REGARD TO ALL OF THE SOFTWARE IN THE EXECUTABLE
13 ASIDE FROM CGAL.
14 */
15
16 #ifndef CLUSTR_H
17 #define CLUSTR_H
18
19 #define VERSION     "0.2"
20 #define AUTHOR      "Schuyler Erle <schuyler@nocat.net>"
21 #define COPYRIGHT   "(c) 2007-2008 Yahoo!, Inc."
22
23 #include <CGAL/Simple_cartesian.h>
24 #include <CGAL/Filtered_kernel.h>
25 #include <CGAL/algorithm.h>
26 #include <CGAL/Delaunay_triangulation_2.h>
27 #include <CGAL/Alpha_shape_2.h>
28 #include <CGAL/Polygon_2.h>
29
30 #include <cmath>
31 #include <vector>
32 #define KM_PER_DEGREE (40075.16/360)
33
34 namespace Clustr {
35     typedef float coord_type;
36
37     typedef CGAL::Simple_cartesian<coord_type>  SC;
38     typedef CGAL::Filtered_kernel<SC> K;
39
40     typedef K::Point_2  Point;
41     typedef K::Segment_2  Segment;
42     typedef K::Direction_2  Direction;
43
44     typedef CGAL::Alpha_shape_vertex_base_2<K> Vb;
45     typedef CGAL::Alpha_shape_face_base_2<K>  Fb;
46     typedef CGAL::Triangulation_data_structure_2<Vb,Fb> Tds;
47     typedef CGAL::Delaunay_triangulation_2<K,Tds> Triangulation_2;
48
49     template < class Gt, class Vb = CGAL::Alpha_shape_vertex_base_2<Gt> >
50     class Vertex_counter_base : public Vb {
51         typedef typename Vb::Triangulation_data_structure  TDS;
52         unsigned int counter;
53       public:
54         typedef TDS                             Triangulation_data_structure;
55         typedef typename TDS::Vertex_handle     Vertex_handle;
56         typedef typename TDS::Face_handle       Face_handle;
57  
58         typedef typename Gt::FT                 Coord_type;
59         typedef std::pair< Coord_type, Coord_type >    Interval2;
60         typedef typename Vb::Point              Point;
61
62         template < typename TDS2 >
63         struct Rebind_TDS {
64             typedef typename Vb::template Rebind_TDS<TDS2>::Other Vb2;
65             typedef Vertex_counter_base<Gt,Vb2> Other;
66         };
67
68         Vertex_counter_base() : Vb(), counter(0) {};
69         Vertex_counter_base(const Point & p) : Vb(p), counter(0) {};
70         Vertex_counter_base(const Point & p, Face_handle f) : Vb(f,p), counter(0) {};
71         Vertex_counter_base(Face_handle f) : Vb(f), counter(0) {};
72
73         unsigned int operator++ (void) { return ++counter; };
74         unsigned int operator++ (int) { return counter++; };
75         unsigned int count (void) { return counter; };
76     };
77     typedef CGAL::Triangulation_data_structure_2<Vertex_counter_base<K>,Fb> Tds_with_counter;
78     typedef CGAL::Delaunay_triangulation_2<K,Tds_with_counter> Triangulation_with_counter;
79     typedef CGAL::Alpha_shape_2<Triangulation_with_counter> Alpha_shape;
80
81     typedef Alpha_shape::Face  Face;
82     typedef Alpha_shape::Vertex Vertex;
83     typedef Alpha_shape::Edge Edge;
84     typedef Alpha_shape::Face_handle  Face_handle;
85     typedef Alpha_shape::Vertex_handle Vertex_handle;
86
87     typedef Alpha_shape::Face_iterator  Face_iterator;
88     typedef Alpha_shape::Vertex_iterator  Vertex_iterator;
89     typedef Alpha_shape::Edge_circulator  Edge_circulator;
90     typedef Alpha_shape::Face_circulator  Face_circulator;
91
92     typedef Alpha_shape::Alpha_iterator Alpha_iterator;
93     typedef Alpha_shape::Alpha_shape_vertices_iterator Alpha_shape_vertices_iterator;
94
95     class Mesh : public Alpha_shape {
96       public:
97         class vertex_circulator;
98            
99         class component {
100             typedef Alpha_shape_vertices_iterator Mesh_iterator;
101             Mesh *mesh;
102             Mesh_iterator base;
103             Mesh_iterator end;
104           public:
105             component (Mesh &mesh, Mesh_iterator b) : mesh(&mesh), base(b) {};
106             component (Mesh &mesh) : mesh(&mesh) {
107                 base = mesh.alpha_shape_vertices_begin();
108                 end  = mesh.alpha_shape_vertices_end();
109             };
110             bool operator!=(const component &other) { return mesh!=other.mesh || base!=other.base; }; 
111             bool operator==(const component &other) { return mesh==other.mesh && base==other.base; };
112             vertex_circulator operator*() { return vertex_circulator(*this); };
113             component& operator++ (int) { return ++(*this); };
114             component& operator++() {
115                 if (base != end) {
116                     do {++base;} while ((*base)->count() && base != end);
117                 }
118                 return *this;
119             };
120             friend class vertex_circulator;
121         };
122
123         class vertex_circulator {
124             component *ring;
125             Vertex_handle vertex;
126             Edge previous;
127            
128             Vertex_handle target (const Edge &e);
129             Vertex_handle origin (const Edge &e);
130           public:
131             vertex_circulator (component &c): ring(&c), vertex(*c.base), previous() {};
132             Vertex_handle operator*() const { return vertex; };
133             Vertex_handle operator->() const { return vertex; };
134             vertex_circulator& operator++ (int) { return ++(*this); };
135             vertex_circulator& operator++();
136         };
137
138       private:
139         component end_component;
140       public:
141         Mesh(coord_type alpha = coord_type(0)) : Alpha_shape(alpha, Alpha_shape::REGULARIZED),
142                                                  end_component(*this, alpha_shape_vertices_end()) {};
143
144         template <class InputIterator>
145         Mesh(const InputIterator& first, const InputIterator& last,
146                 const coord_type& alpha = coord_type(0))
147                 : Alpha_shape(first, last, alpha, Alpha_shape::REGULARIZED),
148                   end_component(*this, alpha_shape_vertices_end()) {};
149
150         component components_begin () { return component(*this); };
151         component components_end () { return end_component; };
152     };
153
154     /* BIG ASSUMPTION: Point<K> is actually a lon/lat point
155      * -- this underlies all of the following distance and
156      * area calculations. */
157
158     //using std::tr1::cos;
159     //using std::tr1::acos;
160
161     typedef CGAL::Polygon_2<K> Ring_base;
162     class Ring : public Ring_base {
163         coord_type area_;
164         coord_type perimeter_;
165         coord_type scale_x(coord_type lat) { return cos(lat*acos(-1.0)/180); };
166       public:
167         typedef Ring_base::Vertex_iterator iterator;
168         Ring() : Ring_base(), area_(0), perimeter_(0) {};
169         void reverse_orientation (void) { area_ *= -1.0; this->Ring_base::reverse_orientation(); };
170         bool is_ccw (void) { return area_ >= 0; };
171         coord_type area (void) { return area_*KM_PER_DEGREE*KM_PER_DEGREE; };
172         coord_type perimeter (void) { return perimeter_*KM_PER_DEGREE; };
173         void push_back (const Point &p);
174         iterator begin (void) { return vertices_begin(); };
175         iterator end (void) { return vertices_end(); };
176         bool encloses (const Point &p) { bounded_side(p) == CGAL::ON_BOUNDED_SIDE; };
177     };
178
179     typedef std::vector<Ring> Polygon_base;
180     class Polygon : public Polygon_base {
181       public:
182         void push_back (Ring &ring);
183         coord_type area (void);
184         coord_type perimeter (void);
185     };
186
187     struct Config {
188         std::string in_file;
189         std::string out_file;
190         coord_type alpha;
191         bool points_only;
192         bool verbose;
193
194         Config() { 
195             in_file = "-";
196             out_file = "clustr.shp";
197             alpha = 0;
198             points_only = false;   
199             verbose = false;   
200         };
201     };
202 };
203
204 #endif /* CLUSTR_H */
Note: See TracBrowser for help on using the browser.