This file is indexed.

/usr/include/qgis/qgssnappingutils.h is in libqgis-dev 2.14.11+dfsg-3+deb9u1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/***************************************************************************
  qgssnappingutils.h
  --------------------------------------
  Date                 : November 2014
  Copyright            : (C) 2014 by Martin Dobias
  Email                : wonder dot sk at gmail dot com
 ***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef QGSSNAPPINGUTILS_H
#define QGSSNAPPINGUTILS_H


#include "qgsmapsettings.h"
#include "qgstolerance.h"
#include "qgspointlocator.h"

/**
 * This class has all the configuration of snapping and can return answers to snapping queries.
 * Internally, it keeps a cache of QgsPointLocator instances for multiple layers.
 *
 * Currently it supports the following queries:
 * - snapToMap() - has multiple modes of operation
 * - snapToCurrentLayer()
 * For more complex queries it is possible to use locatorForLayer() method that returns
 * point locator instance with layer's indexed data.
 *
 * Indexing strategy determines how fast the queries will be and how much memory will be used.
 *
 * When working with map canvas, it may be useful to use derived class QgsMapCanvasSnappingUtils
 * which keeps the configuration in sync with map canvas (e.g. current view, active layer).
 *
 * @note added in 2.8
 */
class CORE_EXPORT QgsSnappingUtils : public QObject
{
    Q_OBJECT
  public:
    QgsSnappingUtils( QObject* parent = nullptr );
    ~QgsSnappingUtils();

    // main actions

    /** Get a point locator for the given layer. If such locator does not exist, it will be created */
    QgsPointLocator* locatorForLayer( QgsVectorLayer* vl );

    /** Snap to map according to the current configuration (mode). Optional filter allows discarding unwanted matches. */
    QgsPointLocator::Match snapToMap( QPoint point, QgsPointLocator::MatchFilter* filter = nullptr );
    QgsPointLocator::Match snapToMap( const QgsPoint& pointMap, QgsPointLocator::MatchFilter* filter = nullptr );

    /** Snap to current layer */
    QgsPointLocator::Match snapToCurrentLayer( QPoint point, int type, QgsPointLocator::MatchFilter* filter = nullptr );

    // environment setup

    /** Assign current map settings to the utils - used for conversion between screen coords to map coords */
    void setMapSettings( const QgsMapSettings& settings );
    const QgsMapSettings& mapSettings() const { return mMapSettings; }

    /** Set current layer so that if mode is SnapCurrentLayer we know which layer to use */
    void setCurrentLayer( QgsVectorLayer* layer );
    QgsVectorLayer* currentLayer() const { return mCurrentLayer; }


    // configuration

    //! modes for "snap to background"
    enum SnapToMapMode
    {
      SnapCurrentLayer,    //!< snap just to current layer (tolerance and type from defaultSettings())
      SnapAllLayers,       //!< snap to all rendered layers (tolerance and type from defaultSettings())
      SnapAdvanced,        //!< snap according to the configuration set in setLayers()
    };

    /** Set how the snapping to map is done */
    void setSnapToMapMode( SnapToMapMode mode );
    /** Find out how the snapping to map is done */
    SnapToMapMode snapToMapMode() const { return mSnapToMapMode; }

    enum IndexingStrategy
    {
      IndexAlwaysFull,    //!< For all layers build index of full extent. Uses more memory, but queries are faster.
      IndexNeverFull,     //!< For all layers only create temporary indexes of small extent. Low memory usage, slower queries.
      IndexHybrid         //!< For "big" layers using IndexNeverFull, for the rest IndexAlwaysFull. Compromise between speed and memory usage.
    };

    /** Set a strategy for indexing geometry data - determines how fast and memory consuming the data structures will be */
    void setIndexingStrategy( IndexingStrategy strategy ) { mStrategy = strategy; }
    /** Find out which strategy is used for indexing - by default hybrid indexing is used */
    IndexingStrategy indexingStrategy() const { return mStrategy; }

    /** Configure options used when the mode is snap to current layer or to all layers */
    void setDefaultSettings( int type, double tolerance, QgsTolerance::UnitType unit );
    /** Query options used when the mode is snap to current layer or to all layers */
    void defaultSettings( int& type, double& tolerance, QgsTolerance::UnitType& unit );

    /**
     * Configures how a certain layer should be handled in a snapping operation
     */
    struct LayerConfig
    {
      LayerConfig( QgsVectorLayer* l, const QgsPointLocator::Types& t, double tol, QgsTolerance::UnitType u ) : layer( l ), type( t ), tolerance( tol ), unit( u ) {}

      bool operator==( const LayerConfig& other ) const
      {
        return layer == other.layer && type == other.type && tolerance == other.tolerance && unit == other.unit;
      }
      bool operator!=( const LayerConfig& other ) const
      {
        return !operator==( other );
      }

      //! The layer to configure.
      QgsVectorLayer* layer;
      //! To which geometry properties of this layers a snapping should happen.
      QgsPointLocator::Types type;
      //! The range around snapping targets in which snapping should occur.
      double tolerance;
      //! The units in which the tolerance is specified.
      QgsTolerance::UnitType unit;
    };

    /** Set layers which will be used for snapping */
    void setLayers( const QList<LayerConfig>& layers );
    /** Query layers used for snapping */
    QList<LayerConfig> layers() const { return mLayers; }

    /** Set whether to consider intersections of nearby segments for snapping */
    void setSnapOnIntersections( bool enabled );
    /** Query whether to consider intersections of nearby segments for snapping */
    bool snapOnIntersections() const { return mSnapOnIntersection; }

    /** Get extra information about the instance
     * @note added in QGIS 2.14
     */
    QString dump();

  public slots:
    /** Read snapping configuration from the project */
    void readConfigFromProject();

  signals:
    /** Emitted when snapping configuration has been changed
     * @note added in QGIS 2.14
     */
    void configChanged();

  protected:
    //! Called when starting to index - can be overridden and e.g. progress dialog can be provided
    virtual void prepareIndexStarting( int count ) { Q_UNUSED( count ); }
    //! Called when finished indexing a layer. When index == count the indexing is complete
    virtual void prepareIndexProgress( int index ) { Q_UNUSED( index ); }

  private slots:
    void onLayersWillBeRemoved( const QStringList& layerIds );

  private:
    //! get from map settings pointer to destination CRS - or 0 if projections are disabled
    const QgsCoordinateReferenceSystem* destCRS();

    //! delete all existing locators (e.g. when destination CRS has changed and we need to reindex)
    void clearAllLocators();

    //! return a locator (temporary or not) according to the indexing strategy
    QgsPointLocator* locatorForLayerUsingStrategy( QgsVectorLayer* vl, const QgsPoint& pointMap, double tolerance );
    //! return a temporary locator with index only for a small area (will be replaced by another one on next request)
    QgsPointLocator* temporaryLocatorForLayer( QgsVectorLayer* vl, const QgsPoint& pointMap, double tolerance );

    typedef QPair< QgsVectorLayer*, QgsRectangle > LayerAndAreaOfInterest;

    //! find out whether the strategy would index such layer or just use a temporary locator
    bool isIndexPrepared( QgsVectorLayer* vl, const QgsRectangle& areaOfInterest );
    //! initialize index for layers where it makes sense (according to the indexing strategy)
    void prepareIndex( const QList<LayerAndAreaOfInterest>& layers );

  private:
    // environment
    QgsMapSettings mMapSettings;
    QgsVectorLayer* mCurrentLayer;

    // configuration
    SnapToMapMode mSnapToMapMode;
    IndexingStrategy mStrategy;
    int mDefaultType;
    double mDefaultTolerance;
    QgsTolerance::UnitType mDefaultUnit;
    QList<LayerConfig> mLayers;
    bool mSnapOnIntersection;

    // internal data
    typedef QMap<QgsVectorLayer*, QgsPointLocator*> LocatorsMap;
    //! on-demand locators used (locators are owned)
    LocatorsMap mLocators;
    //! temporary locators (indexing just a part of layers). owned by the instance
    LocatorsMap mTemporaryLocators;
    //! list of layer IDs that are too large to be indexed (hybrid strategy will use temporary locators for those)
    QSet<QString> mHybridNonindexableLayers;
    //! a record for each layer seen:
    //! - value -1  == it is small layer -> fully indexed
    //! - value > 0 == maximum area (in map units) for which it may make sense to build index.
    //!   This means that index is built in area around the point with this total area, because
    //!   for a larger area the number of features will likely exceed the limit. When the limit
    //!   is exceeded, the maximum area is lowered to prevent that from happening.
    //!   When requesting snap in area that is not currently indexed, layer's index is destroyed
    //!   and a new one is built in the different area.
    QHash<QString, double> mHybridMaxAreaPerLayer;
    //! if using hybrid strategy, how many features of one layer may be indexed (to limit amount of consumed memory)
    int mHybridPerLayerFeatureLimit;

    //! internal flag that an indexing process is going on. Prevents starting two processes in parallel.
    bool mIsIndexing;
};


#endif // QGSSNAPPINGUTILS_H