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 : : 49 : : /** 50 : : * \class pal::Sol 51 : : * \ingroup core 52 : : * \brief Chain solution parameters. 53 : : * \note not available in Python bindings 54 : : */ 55 : : 56 : 0 : struct Chain 57 : : { 58 : : int degree; 59 : : double delta; 60 : 0 : int *feat = nullptr; 61 : 0 : int *label = nullptr; 62 : : }; 63 : : 64 : : /** 65 : : * \ingroup core 66 : : * \brief Representation of a labeling problem 67 : : * \class pal::Problem 68 : : * \note not available in Python bindings 69 : : */ 70 : : class CORE_EXPORT Problem 71 : : { 72 : : friend class Pal; 73 : : 74 : : public: 75 : : 76 : : /** 77 : : * Constructor for Problem. 78 : : * 79 : : * The \a extent argument specifies the bounds of the incoming coordinates. 80 : : */ 81 : : Problem( const QgsRectangle &extent ); 82 : : 83 : : //Problem(char *lorena_file, bool displayAll); 84 : : 85 : : ~Problem(); 86 : : 87 : : //! Problem cannot be copied 88 : : Problem( const Problem &other ) = delete; 89 : : //! Problem cannot be copied 90 : : Problem &operator=( const Problem &other ) = delete; 91 : : 92 : : /** 93 : : * Adds a candidate label position to the problem. 94 : : * \param position label candidate position. Ownership is transferred to Problem. 95 : : * \since QGIS 2.12 96 : : */ 97 : 0 : void addCandidatePosition( std::unique_ptr< LabelPosition > position ) { mLabelPositions.emplace_back( std::move( position ) ); } 98 : : 99 : : /** 100 : : * Returns the total number of features considered during the labeling problem. 101 : : */ 102 : 0 : std::size_t featureCount() const { return mFeatureCount; } 103 : : 104 : : /** 105 : : * Returns the number of candidates generated for the \a feature at the specified index. 106 : : */ 107 : 0 : int featureCandidateCount( int feature ) const { return mFeatNbLp[feature]; } 108 : : 109 : : /** 110 : : * Returns the candidate corresponding to the specified \a feature and \a candidate index. 111 : : */ 112 : 0 : LabelPosition *featureCandidate( int feature, int candidate ) const { return mLabelPositions[ mFeatStartId[feature] + candidate ].get(); } 113 : : 114 : : void reduce(); 115 : : 116 : : /** 117 : : * \brief Test with very-large scale neighborhood 118 : : */ 119 : : void chain_search(); 120 : : 121 : : /** 122 : : * Solves the labeling problem, selecting the best candidate locations for all labels and returns a list of these 123 : : * calculated label positions. 124 : : * 125 : : * If \a returnInactive is TRUE, then the best positions for ALL labels will be returned, regardless of whether these 126 : : * labels overlap other labels. 127 : : * 128 : : * If the optional \a unlabeled list is specified, it will be filled with a list of all feature labels which could 129 : : * not be placed in the returned solution (e.g. due to overlaps or other constraints). 130 : : * 131 : : * Ownership of the returned labels is not transferred - it resides with the pal object. 132 : : */ 133 : : QList<LabelPosition *> getSolution( bool returnInactive, QList<LabelPosition *> *unlabeled = nullptr ); 134 : : 135 : : /* useful only for postscript post-conversion*/ 136 : : //void toFile(char *label_file); 137 : : 138 : : void init_sol_falp(); 139 : : 140 : : /** 141 : : * Returns a reference to the list of label positions which correspond to 142 : : * features with no candidates. 143 : : * 144 : : * Ownership of positions added to this list is transferred to the problem. 145 : : */ 146 : 0 : std::vector< std::unique_ptr< LabelPosition > > *positionsWithNoCandidates() 147 : : { 148 : 0 : return &mPositionsWithNoCandidates; 149 : : } 150 : : 151 : : /** 152 : : * Returns the index containing all label candidates. 153 : : */ 154 : 0 : PalRtree< LabelPosition > &allCandidatesIndex() { return mAllCandidatesIndex; } 155 : : 156 : : private: 157 : : 158 : : /** 159 : : * Total number of layers containing labels 160 : : */ 161 : : int mLayerCount = 0; 162 : : 163 : : /** 164 : : * Names of the labelled layers 165 : : */ 166 : : QStringList labelledLayersName; 167 : : 168 : : /** 169 : : * Total number of active candidates (remaining after reduce()) 170 : : */ 171 : : int mTotalCandidates = 0; 172 : : 173 : : /** 174 : : * Number of candidates (all, including) 175 : : */ 176 : : int mAllNblp = 0; 177 : : 178 : : /** 179 : : * Total number of features to label. 180 : : */ 181 : : std::size_t mFeatureCount = 0; 182 : : 183 : : /** 184 : : * if TRUE, special value -1 is prohibited 185 : : */ 186 : : bool mDisplayAll = false; 187 : : 188 : : /** 189 : : * Map extent (xmin, ymin, xmax, ymax) 190 : : */ 191 : : double mMapExtentBounds[4] = {0, 0, 0, 0}; 192 : : 193 : : std::vector< std::unique_ptr< LabelPosition > > mLabelPositions; 194 : : 195 : : PalRtree<LabelPosition> mAllCandidatesIndex; 196 : : PalRtree<LabelPosition> mActiveCandidatesIndex; 197 : : 198 : : std::vector< std::unique_ptr< LabelPosition > > mPositionsWithNoCandidates; 199 : : 200 : : std::vector< int > mFeatStartId; 201 : : std::vector< int > mFeatNbLp; 202 : : std::vector< double > mInactiveCost; 203 : : 204 : 0 : class Sol 205 : : { 206 : : public: 207 : : 208 : : //! Placeholder list for active labels. Will contain label id for active labels, or -1 for empty positions in list 209 : : std::vector< int > activeLabelIds; 210 : : 211 : 0 : double totalCost = 0; 212 : : 213 : 0 : void init( std::size_t featureCount ) 214 : : { 215 : 0 : activeLabelIds.resize( featureCount, -1 ); 216 : 0 : totalCost = 0; 217 : 0 : } 218 : : }; 219 : : 220 : : Sol mSol; 221 : : double mNbOverlap = 0.0; 222 : : 223 : : Chain *chain( int seed ); 224 : : 225 : : Pal *pal = nullptr; 226 : : 227 : : void solution_cost(); 228 : : }; 229 : : 230 : : } // namespace 231 : : 232 : : #endif