00001 /***************************************************************************** 00002 * 00003 * This file is part of Mapnik (c++ mapping toolkit) 00004 * 00005 * Copyright (C) 2006 Artem Pavlenko 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00020 * 00021 *****************************************************************************/ 00022 00023 //$Id$ 00024 00025 #if !defined LABEL_COLLISION_DETECTOR 00026 #define LABEL_COLLISION_DETECTOR 00027 // stl 00028 #include <vector> 00029 // mapnik 00030 #include <mapnik/quad_tree.hpp> 00031 00032 namespace mapnik 00033 { 00034 //this needs to be tree structure 00035 //as a proof of a concept _only_ we use sequential scan 00036 00037 struct label_collision_detector 00038 { 00039 typedef std::vector<Envelope<double> > label_placements; 00040 00041 bool has_plasement(Envelope<double> const& box) 00042 { 00043 label_placements::const_iterator itr=labels_.begin(); 00044 for( ; itr !=labels_.end();++itr) 00045 { 00046 if (itr->intersects(box)) 00047 { 00048 return false; 00049 } 00050 } 00051 labels_.push_back(box); 00052 return true; 00053 } 00054 void clear() 00055 { 00056 labels_.clear(); 00057 } 00058 00059 private: 00060 00061 label_placements labels_; 00062 }; 00063 00064 // quad_tree based label collision detector 00065 class label_collision_detector2 : boost::noncopyable 00066 { 00067 typedef quad_tree<Envelope<double> > tree_t; 00068 tree_t tree_; 00069 public: 00070 00071 explicit label_collision_detector2(Envelope<double> const& extent) 00072 : tree_(extent) {} 00073 00074 bool has_placement(Envelope<double> const& box) 00075 { 00076 tree_t::query_iterator itr = tree_.query_in_box(box); 00077 tree_t::query_iterator end = tree_.query_end(); 00078 00079 for ( ;itr != end; ++itr) 00080 { 00081 if (itr->intersects(box)) 00082 { 00083 return false; 00084 } 00085 } 00086 00087 tree_.insert(box,box); 00088 return true; 00089 } 00090 00091 void clear() 00092 { 00093 tree_.clear(); 00094 } 00095 00096 }; 00097 00098 // quad_tree based label collision detector with seperate check/insert 00099 class label_collision_detector3 : boost::noncopyable 00100 { 00101 typedef quad_tree< Envelope<double> > tree_t; 00102 tree_t tree_; 00103 public: 00104 00105 explicit label_collision_detector3(Envelope<double> const& extent) 00106 : tree_(extent) {} 00107 00108 bool has_placement(Envelope<double> const& box) 00109 { 00110 tree_t::query_iterator itr = tree_.query_in_box(box); 00111 tree_t::query_iterator end = tree_.query_end(); 00112 00113 for ( ;itr != end; ++itr) 00114 { 00115 if (itr->intersects(box)) 00116 { 00117 return false; 00118 } 00119 } 00120 00121 return true; 00122 } 00123 00124 void insert(Envelope<double> const& box) 00125 { 00126 tree_.insert(box, box); 00127 } 00128 00129 void clear() 00130 { 00131 tree_.clear(); 00132 } 00133 }; 00134 } 00135 00136 #endif