Branch data Line data Source code
1 : : /* 2 : : * libpal - Automated Placement of Labels Library 3 : : * 4 : : * Copyright (C) 2008 Maxence Laurent, MIS-TIC, HEIG-VD 5 : : * University of Applied Sciences, Western Switzerland 6 : : * http://www.hes-so.ch 7 : : * 8 : : * Contact: 9 : : * maxence.laurent <at> heig-vd <dot> ch 10 : : * or 11 : : * eric.taillard <at> heig-vd <dot> ch 12 : : * 13 : : * This file is part of libpal. 14 : : * 15 : : * libpal is free software: you can redistribute it and/or modify 16 : : * it under the terms of the GNU General Public License as published by 17 : : * the Free Software Foundation, either version 3 of the License, or 18 : : * (at your option) any later version. 19 : : * 20 : : * libpal is distributed in the hope that it will be useful, 21 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 : : * GNU General Public License for more details. 24 : : * 25 : : * You should have received a copy of the GNU General Public License 26 : : * along with libpal. If not, see <http://www.gnu.org/licenses/>. 27 : : * 28 : : */ 29 : : 30 : : #ifndef PAL_PROBLEM_H 31 : : #define PAL_PROBLEM_H 32 : : 33 : : #define SIP_NO_FILE 34 : : 35 : : 36 : : #include "qgis_core.h" 37 : : #include <list> 38 : : #include <QList> 39 : : #include "palrtree.h" 40 : : #include <memory> 41 : : #include <vector> 42 : : 43 : : namespace pal 44 : : { 45 : : 46 : : class LabelPosition; 47 : : class Label; 48 : : class PriorityQueue; 49 : : 50 : : /** 51 : : * \class pal::Sol 52 : : * \ingroup core 53 : : * \brief Chain solution parameters. 54 : : * \note not available in Python bindings 55 : : */ 56 : : 57 : 0 : struct Chain 58 : : { 59 : : int degree; 60 : : double delta; 61 : 0 : int *feat = nullptr; 62 : 0 : int *label = nullptr; 63 : : }; 64 : : 65 : : /** 66 : : * \ingroup core 67 : : * \brief Representation of a labeling problem 68 : : * \class pal::Problem 69 : : * \note not available in Python bindings 70 : : */ 71 : : class CORE_EXPORT Problem 72 : : { 73 : : friend class Pal; 74 : : 75 : : public: 76 : : 77 : : /** 78 : : * Constructor for Problem. 79 : : * 80 : : * The \a extent argument specifies the bounds of the incoming coordinates. 81 : : */ 82 : : Problem( const QgsRectangle &extent ); 83 : : 84 : : //Problem(char *lorena_file, bool displayAll); 85 : : 86 : : ~Problem(); 87 : : 88 : : //! Problem cannot be copied 89 : : Problem( const Problem &other ) = delete; 90 : : //! Problem cannot be copied 91 : : Problem &operator=( const Problem &other ) = delete; 92 : : 93 : : /** 94 : : * Adds a candidate label position to the problem. 95 : : * \param position label candidate position. Ownership is transferred to Problem. 96 : : * \since QGIS 2.12 97 : : */ 98 : 0 : void addCandidatePosition( std::unique_ptr< LabelPosition > position ) { mLabelPositions.emplace_back( std::move( position ) ); } 99 : : 100 : : /** 101 : : * Returns the total number of features considered during the labeling problem. 102 : : */ 103 : 0 : std::size_t featureCount() const { return mFeatureCount; } 104 : : 105 : : /** 106 : : * Returns the number of candidates generated for the \a feature at the specified index. 107 : : */ 108 : 0 : int featureCandidateCount( int feature ) const { return mFeatNbLp[feature]; } 109 : : 110 : : /** 111 : : * Returns the candidate corresponding to the specified \a feature and \a candidate index. 112 : : */ 113 : 0 : LabelPosition *featureCandidate( int feature, int candidate ) const { return mLabelPositions[ mFeatStartId[feature] + candidate ].get(); } 114 : : 115 : : void reduce(); 116 : : 117 : : /** 118 : : * \brief Test with very-large scale neighborhood 119 : : */ 120 : : void chain_search(); 121 : : 122 : : /** 123 : : * Solves the labeling problem, selecting the best candidate locations for all labels and returns a list of these 124 : : * calculated label positions. 125 : : * 126 : : * If \a returnInactive is TRUE, then the best positions for ALL labels will be returned, regardless of whether these 127 : : * labels overlap other labels. 128 : : * 129 : : * If the optional \a unlabeled list is specified, it will be filled with a list of all feature labels which could 130 : : * not be placed in the returned solution (e.g. due to overlaps or other constraints). 131 : : * 132 : : * Ownership of the returned labels is not transferred - it resides with the pal object. 133 : : */ 134 : : QList<LabelPosition *> getSolution( bool returnInactive, QList<LabelPosition *> *unlabeled = nullptr ); 135 : : 136 : : /* useful only for postscript post-conversion*/ 137 : : //void toFile(char *label_file); 138 : : 139 : : void init_sol_falp(); 140 : : 141 : : /** 142 : : * Returns a reference to the list of label positions which correspond to 143 : : * features with no candidates. 144 : : * 145 : : * Ownership of positions added to this list is transferred to the problem. 146 : : */ 147 : 0 : std::vector< std::unique_ptr< LabelPosition > > *positionsWithNoCandidates() 148 : : { 149 : 0 : return &mPositionsWithNoCandidates; 150 : : } 151 : : 152 : : /** 153 : : * Returns the index containing all label candidates. 154 : : */ 155 : 0 : PalRtree< LabelPosition > &allCandidatesIndex() { return mAllCandidatesIndex; } 156 : : 157 : : private: 158 : : 159 : : /** 160 : : * Returns TRUE if a labelling candidate \a lp1 conflicts with \a lp2. 161 : : */ 162 : : bool candidatesAreConflicting( const LabelPosition *lp1, const LabelPosition *lp2 ) const; 163 : : 164 : : /** 165 : : * Total number of layers containing labels 166 : : */ 167 : : int mLayerCount = 0; 168 : : 169 : : /** 170 : : * Names of the labelled layers 171 : : */ 172 : : QStringList labelledLayersName; 173 : : 174 : : /** 175 : : * Total number of active candidates (remaining after reduce()) 176 : : */ 177 : : int mTotalCandidates = 0; 178 : : 179 : : /** 180 : : * Number of candidates (all, including) 181 : : */ 182 : : int mAllNblp = 0; 183 : : 184 : : /** 185 : : * Total number of features to label. 186 : : */ 187 : : std::size_t mFeatureCount = 0; 188 : : 189 : : /** 190 : : * if TRUE, special value -1 is prohibited 191 : : */ 192 : : bool mDisplayAll = false; 193 : : 194 : : /** 195 : : * Map extent (xmin, ymin, xmax, ymax) 196 : : */ 197 : : double mMapExtentBounds[4] = {0, 0, 0, 0}; 198 : : 199 : : std::vector< std::unique_ptr< LabelPosition > > mLabelPositions; 200 : : 201 : : PalRtree<LabelPosition> mAllCandidatesIndex; 202 : : PalRtree<LabelPosition> mActiveCandidatesIndex; 203 : : 204 : : std::vector< std::unique_ptr< LabelPosition > > mPositionsWithNoCandidates; 205 : : 206 : : std::vector< int > mFeatStartId; 207 : : std::vector< int > mFeatNbLp; 208 : : std::vector< double > mInactiveCost; 209 : : 210 : 0 : class Sol 211 : : { 212 : : public: 213 : : 214 : : //! Placeholder list for active labels. Will contain label id for active labels, or -1 for empty positions in list 215 : : std::vector< int > activeLabelIds; 216 : : 217 : 0 : double totalCost = 0; 218 : : 219 : 0 : void init( std::size_t featureCount ) 220 : : { 221 : 0 : activeLabelIds.resize( featureCount, -1 ); 222 : 0 : totalCost = 0; 223 : 0 : } 224 : : }; 225 : : 226 : : Sol mSol; 227 : : double mNbOverlap = 0.0; 228 : : 229 : : Chain *chain( int seed ); 230 : : 231 : : Pal *pal = nullptr; 232 : : 233 : : void solution_cost(); 234 : : void ignoreLabel( const LabelPosition *lp, pal::PriorityQueue &list, PalRtree<LabelPosition> &candidatesIndex ); 235 : : }; 236 : : 237 : : } // namespace 238 : : 239 : : #endif