Changeset 461
- Timestamp:
- 11/12/08 18:11:11 (1 year ago)
- Files:
-
- trunk/clustr/README (modified) (1 diff)
- trunk/clustr/clustr.cpp (modified) (4 diffs)
- trunk/clustr/clustr.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/clustr/README
r460 r461 63 63 Bugs 64 64 ---- 65 At present, clustr does not handle polygon holes correctly. 65 Clustr does not use an exceptionally sophisticated algorithm for extracting 66 polygons from the generated alpha shape, with the result that on occasion 67 improper or self-intersecting polygons get generated. This can confuse GIS 68 programs that expect better behaved data sets, and ought to be fixed someday. 69 70 Also, the total count of points input is written to every shape record, which 71 will be wrong if there are multiple components for a given input tag. This 72 could be fixed by testing inclusion of each point after the polygons are 73 constructed, which would lengthen runtime. Cost/benefit? Not sure. 66 74 67 75 License 68 ---- 76 ------- 69 77 70 78 Copyright (c) 2007-2008 Yahoo! Inc. trunk/clustr/clustr.cpp
r460 r461 21 21 #include <stdexcept> 22 22 #include <cmath> 23 #include <algorithm> 23 24 24 25 #include <unistd.h> … … 79 80 } 80 81 82 bool compare_polygon_sizes (const Polygon &a, const Polygon &b) { 83 return a.size() < b.size(); 84 } 85 86 void attach_interior_rings (vector<Polygon> &input, vector<Polygon> &output, bool verbose = false) { 87 unsigned int count = 0; 88 89 /* First, sort the polygons by area. This guarantees that smaller polygons 90 * will wind up inside larger polygons. */ 91 sort(input.begin(), input.end(), compare_polygon_sizes); 92 93 for (vector<Polygon>::iterator it = input.begin(); it != input.end(); it++) { 94 bool is_interior_ring = false; 95 96 for (vector<Polygon>::iterator comp = it + 1; comp != input.end(); comp++) { 97 /* check if the first point in the first ring of *it is inside the outer ring 98 * of *comp. If it is, then we assume that the entire polygon *it is actually 99 * inside *comp. 100 * 101 * Note that *comp needs to be a simple polygon -- it *should* be but sometimes 102 * the polygons that come out of the alpha shape self-intersect at a point. 103 * Not sure what to do about this. */ 104 if ((*comp)[0].is_simple() && (*comp)[0].encloses((*it)[0][0])) { 105 for (Polygon::iterator ring = it->begin(); ring != it->end(); ring++) { 106 // this is actually going to get double-interior rings backwards, 107 // but fixing that means making the logic in 108 // Polygon::push_back a lot more sophisticated... 109 comp->push_back(*ring); 110 } 111 is_interior_ring = true; 112 count++; 113 break; 114 } 115 } 116 117 if (!is_interior_ring) 118 output.push_back(*it); 119 } 120 121 if (verbose && count) 122 cerr << count << " interior rings attached." << endl; 123 } 124 81 125 void construct_alpha_shape (Config &config, Shapefile &shape, 82 126 vector<Point> &pts, string text) … … 84 128 coord_type alpha = config.alpha; 85 129 Mesh mesh(pts.begin(), pts.end(), alpha); 130 vector<Polygon> polygons, output; 86 131 87 132 if (alpha == 0) { … … 96 141 " component(s) found for alpha value " << alpha << "." << endl; 97 142 98 for (Mesh::component c = mesh.components_begin(); 99 c != mesh.components_end(); c++) { 143 for (Mesh::component c = mesh.components_begin(); c != mesh.components_end(); c++) { 100 144 Polygon poly; 101 if (extract_alpha_component(c, poly, config.verbose)) { 102 if (config.verbose) 103 cerr << "Writing polygon for tag '" << text << "'." << endl; 104 write_polygon_to_shapefile(shape, poly, text, pts.size()); 105 } 145 if (extract_alpha_component(c, poly, config.verbose)) 146 polygons.push_back(poly); 147 } 148 149 attach_interior_rings(polygons, output, config.verbose); 150 151 if (config.verbose) cerr << "Writing " << output.size() << " polygons to shapefile." << endl; 152 for (vector<Polygon>::iterator poly = output.begin(); poly != output.end(); poly++) { 153 write_polygon_to_shapefile(shape, *poly, text, pts.size()); // FIXME: size is broken 106 154 } 107 155 } trunk/clustr/clustr.h
r460 r461 17 17 #define CLUSTR_H 18 18 19 #define VERSION "0. 1"19 #define VERSION "0.2" 20 20 #define AUTHOR "Schuyler Erle <schuyler@nocat.net>" 21 21 #define COPYRIGHT "(c) 2007-2008 Yahoo!, Inc." … … 174 174 iterator begin (void) { return vertices_begin(); }; 175 175 iterator end (void) { return vertices_end(); }; 176 bool encloses (const Point &p) { bounded_side(p) == CGAL::ON_BOUNDED_SIDE; }; 176 177 }; 177 178