Coverage Report

Created: 2025-06-09 08:44

/src/gdal/gnm/gnm.h
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Project:  GDAL/OGR Geography Network support (Geographic Network Model)
4
 * Purpose:  GNM general public declarations.
5
 * Authors:  Mikhail Gusev (gusevmihs at gmail dot com)
6
 *           Dmitry Baryshnikov, polimax@mail.ru
7
 *
8
 ******************************************************************************
9
 * Copyright (c) 2014, Mikhail Gusev
10
 * Copyright (c) 2014-2015, NextGIS <info@nextgis.com>
11
 *
12
 * Permission is hereby granted, free of charge, to any person obtaining a
13
 * copy of this software and associated documentation files (the "Software"),
14
 * to deal in the Software without restriction, including without limitation
15
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16
 * and/or sell copies of the Software, and to permit persons to whom the
17
 * Software is furnished to do so, subject to the following conditions:
18
 *
19
 * The above copyright notice and this permission notice shall be included
20
 * in all copies or substantial portions of the Software.
21
 *
22
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28
 * DEALINGS IN THE SOFTWARE.
29
 ****************************************************************************/
30
31
#ifndef GNM
32
#define GNM
33
34
#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
35
#include "ogrsf_frmts.h"
36
#endif
37
#include "gnmgraph.h"
38
39
// Direction of an edge.
40
typedef int GNMDirection;  // We use int values in order to save them to the
41
                           // network data.
42
43
// Network's metadata parameters names.
44
4
#define GNM_MD_NAME "net_name"
45
4
#define GNM_MD_DESCR "net_description"
46
4
#define GNM_MD_SRS "net_srs"
47
0
#define GNM_MD_VERSION "net_version"
48
0
#define GNM_MD_RULE "net_rule"
49
0
#define GNM_MD_FORMAT "FORMAT"
50
0
#define GNM_MD_FETCHEDGES "fetch_edge"
51
0
#define GNM_MD_FETCHVERTEX "fetch_vertex"
52
0
#define GNM_MD_NUM_PATHS "num_paths"
53
0
#define GNM_MD_EMITTER "emitter"
54
55
// TODO: Constants for capabilities.
56
// #define GNMCanChangeConnections "CanChangeConnections"
57
58
typedef enum
59
{
60
    /** Dijkstra shortest path */ GATDijkstraShortestPath = 1,
61
    /** KShortest Paths        */ GATKShortestPath,
62
    /** Recursive Breadth-first search */ GATConnectedComponents
63
} GNMGraphAlgorithmType;
64
65
#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
66
67
/**
68
 * General GNM class which represents a geography network of common format.
69
 *
70
 * @since GDAL 2.1
71
 */
72
73
class CPL_DLL GNMNetwork : public GDALDataset
74
{
75
  public:
76
    GNMNetwork();
77
    virtual ~GNMNetwork();
78
79
    // GDALDataset Interface
80
    const OGRSpatialReference *GetSpatialRef() const override;
81
    virtual char **GetFileList(void) override;
82
83
    // GNMNetwork Interface
84
85
    /**
86
     * @brief Create network system layers
87
     *
88
     * Creates the connectivity (the "network path" of data) over the dataset
89
     * and returns the resulting network.
90
     * NOTE: This method does not create any connections among features
91
     * but creates the necessary set of fields, layers, etc.
92
     * NOTE: After the successful creation the passed dataset must not be
93
     * modified outside (but can be read as usual).
94
     * NOTE: For the common network format the creation is forbidden if the
95
     * passed dataset already has network system layers and OVERWRITE creation
96
     * option is FALSE.
97
     *
98
     * @param pszFilename - A path there the network folder (schema, etc.) will
99
     *                      be created. The folder (schema, etc.) name get
100
     *                      options.
101
     * @param papszOptions - create network options. The create options
102
     *                       specific for gnm driver.
103
     * @return CE_None on success
104
     */
105
    virtual CPLErr Create(const char *pszFilename, char **papszOptions) = 0;
106
107
    /**
108
     * @brief Open a network
109
     * @param poOpenInfo GDALOpenInfo pointer
110
     * @return CE_None on success
111
     */
112
    virtual CPLErr Open(GDALOpenInfo *poOpenInfo) = 0;
113
114
    /**
115
     * @brief Delete network. Delete all dependent layers
116
     * @return CE_None on success
117
     */
118
    virtual CPLErr Delete() = 0;
119
120
    /**
121
     * @brief GetName - a network name. The value provided to create function
122
     *        in GNM_MD_NAME key. While creation this value used to create the
123
     *        folder or db schema name. But can be changed after creation.
124
     * @return Network name string
125
     */
126
    virtual const char *GetName() const;
127
128
    /**
129
     * @brief GetVersion return the network version if applicable
130
     * @return version value
131
     */
132
    virtual int GetVersion() const
133
0
    {
134
0
        return 0;
135
0
    }
136
137
    /**
138
     * @brief DisconnectAll method clears the network graph
139
     * @return CE_None on success
140
     */
141
    virtual CPLErr DisconnectAll() = 0;
142
143
    /**
144
     * @brief GetFeatureByGlobalFID search all network layers for given feature
145
     *        identificator.
146
     * @param nGFID feature identificator.
147
     * @return OGRFeature pointer or NULL. The pointer should be freed via
148
     *         OGRFeature::DestroyFeature().
149
     */
150
    virtual OGRFeature *GetFeatureByGlobalFID(GNMGFID nGFID) = 0;
151
152
    /**
153
     * @brief Create path between start and end GFIDs.
154
     * @param nStartFID - start identificator
155
     * @param nEndFID - end identificator
156
     * @param eAlgorithm - The algorithm to get path
157
     * @param papszOptions - algorithm specific options
158
     * @return In memory OGRLayer pointer with features constituting
159
     *         the shortest path (or paths). The caller have to free
160
     *         the pointer via @see ReleaseResultSet().
161
     */
162
    virtual OGRLayer *GetPath(GNMGFID nStartFID, GNMGFID nEndFID,
163
                              GNMGraphAlgorithmType eAlgorithm,
164
                              char **papszOptions) = 0;
165
166
    /** Casts a handle to a pointer */
167
    static inline GNMNetwork *FromHandle(GNMGenericNetworkH hNet)
168
0
    {
169
0
        return static_cast<GNMNetwork *>(hNet);
170
0
    }
171
172
    /** Casts a pointer to a handle */
173
    static inline GNMGenericNetworkH ToHandle(GNMNetwork *poNetwork)
174
0
    {
175
0
        return static_cast<GNMGenericNetworkH>(poNetwork);
176
0
    }
177
178
  protected:
179
    /**
180
     * @brief Check if network already exist
181
     * @param pszFilename - path to network (folder or database
182
     * @param papszOptions - create options
183
     * @return TRUE if exist and not overwrite or FALSE
184
     */
185
    virtual int CheckNetworkExist(const char *pszFilename,
186
                                  char **papszOptions) = 0;
187
188
  protected:
189
    //! @cond Doxygen_Suppress
190
    CPLString m_soName{};
191
    OGRSpatialReference m_oSRS{};
192
    //! @endcond
193
};
194
195
class GNMRule;
196
class OGRGNMWrappedResultLayer;
197
198
/**
199
 * GNM class which represents a geography network of generic format.
200
 *
201
 * @since GDAL 2.1
202
 */
203
204
class CPL_DLL GNMGenericNetwork : public GNMNetwork
205
{
206
  public:
207
    GNMGenericNetwork();
208
    virtual ~GNMGenericNetwork();
209
210
    // GDALDataset Interface
211
212
    virtual int GetLayerCount() override;
213
    virtual OGRLayer *GetLayer(int) override;
214
    virtual OGRErr DeleteLayer(int) override;
215
216
    virtual int TestCapability(const char *) override;
217
218
    virtual OGRLayer *CopyLayer(OGRLayer *poSrcLayer, const char *pszNewName,
219
                                char **papszOptions = nullptr) override;
220
221
    virtual int CloseDependentDatasets() override;
222
    virtual CPLErr FlushCache(bool bAtClosing) override;
223
224
    // GNMNetwork Interface
225
226
    virtual CPLErr Create(const char *pszFilename,
227
                          char **papszOptions) override = 0;
228
    virtual CPLErr Delete() override;
229
230
    virtual int GetVersion() const override;
231
    /**
232
     * @brief GetNewGlobalFID increase the global ID counter.
233
     * @return New global feature ID.
234
     */
235
    virtual GNMGFID GetNewGlobalFID();
236
237
    /**
238
     * @brief Get the algorithm name
239
     * @param eAlgorithm GNM algorithm type
240
     * @param bShortName Indicator which name to return - short or long
241
     * @return String with algorithm name
242
     */
243
    virtual CPLString GetAlgorithmName(GNMDirection eAlgorithm,
244
                                       bool bShortName);
245
246
    /**
247
     * @brief AddFeatureGlobalFID add the FID <-> Layer name link to fast access
248
     *        features by global FID.
249
     * @param nFID - global FID
250
     * @param pszLayerName - layer name
251
     * @return CE_None on success
252
     */
253
    virtual CPLErr AddFeatureGlobalFID(GNMGFID nFID, const char *pszLayerName);
254
255
    /**
256
     * @brief Connects two features via third feature (may be virtual, so the
257
     *        identificator should be -1). The features may be at the same layer
258
     *        or different layers.
259
     * @param nSrcFID - source feature identificator
260
     * @param nTgtFID - target feature identificator
261
     * @param nConFID - connection feature identificator (-1 for virtual
262
     * connection)
263
     * @param dfCost - cost moving from source to target (default 1)
264
     * @param dfInvCost - cost moving from target to source (default 1)
265
     * @param eDir - direction, may be source to target, target to source or
266
     * both. (default - both)
267
     * @return CE_None on success
268
     */
269
    virtual CPLErr ConnectFeatures(GNMGFID nSrcFID, GNMGFID nTgtFID,
270
                                   GNMGFID nConFID = -1, double dfCost = 1,
271
                                   double dfInvCost = 1,
272
                                   GNMDirection eDir = GNM_EDGE_DIR_BOTH);
273
274
    /**
275
     * @brief Remove features connection
276
     * @param nSrcFID - source feature identificator
277
     * @param nTgtFID - target feature identificator
278
     * @param nConFID - connection feature identificator
279
     * @return CE_None on success
280
     */
281
    virtual CPLErr DisconnectFeatures(GNMGFID nSrcFID, GNMGFID nTgtFID,
282
                                      GNMGFID nConFID);
283
284
    /**
285
     * @brief Find the corresponding identificator in graph (source, target,
286
     *        connector) and remove such connections.
287
     * @param nFID - identificator to find.
288
     * @return CE_None on success
289
     */
290
    virtual CPLErr DisconnectFeaturesWithId(GNMGFID nFID);
291
292
    /**
293
     * @brief Change connection attributes. Search the connection by source
294
     *        feature identificator, target feature identificator and connection
295
     *        identificator.
296
     * @param nSrcFID - source feature identificator
297
     * @param nTgtFID - target feature identificator
298
     * @param nConFID - connection feature identificator
299
     * @param dfCost - new cost moving from source to target
300
     * @param dfInvCost - new cost moving from target to source
301
     * @param eDir - new direction
302
     * @return CE_None on success
303
     */
304
    virtual CPLErr ReconnectFeatures(GNMGFID nSrcFID, GNMGFID nTgtFID,
305
                                     GNMGFID nConFID, double dfCost = 1,
306
                                     double dfInvCost = 1,
307
                                     GNMDirection eDir = GNM_EDGE_DIR_BOTH);
308
309
    virtual CPLErr DisconnectAll() override;
310
311
    virtual OGRFeature *GetFeatureByGlobalFID(GNMGFID nFID) override;
312
313
    /**
314
     * @brief Create network rule
315
     *
316
     * Creates the rule in the network according to the special syntax. These
317
     * rules are declarative and make an effect for the network when they exist.
318
     * Each rule for layer can be created only if the corresponding layer
319
     * existed and removed when the layer is being deleted.
320
     *
321
     * Rules syntax for the common network format in GNM contains the key words
322
     * (words in capital letters or signs) and the modifiers which refers to the
323
     * network objects. All the following combinations are available:
324
     *
325
     *  Notation:
326
     *  layer1, layer2, layer3 - a layer names (the corresponding layers must be
327
     *                           exist;
328
     *  field1 - a field name (field must be exist);
329
     *  constant1 - any double constant;
330
     *  string1 - any string;
331
     *
332
     *  Rules describing which layer can be connected or not connected with each
333
     *  other, and (optional) which layer must serve as a connector. By default
334
     *  all connections are forbidden. But while network creation process the
335
     *  rule to allow any connection added. During the connection process each
336
     *  rule tested if this connection can be created.
337
     *
338
     *    "ALLOW CONNECTS ANY"
339
     *    "DENY CONNECTS ANY"
340
     *    "DENY CONNECTS layer1 WITH layer2"
341
     *    "ALLOW CONNECTS layer1 WITH layer2 VIA layer3"
342
     *
343
     * @param pszRuleStr Rule string which will parsed. If the parsing was
344
     *        successful, the rule will start having effect immediately.
345
     * @return CE_None on success.
346
     */
347
    virtual CPLErr CreateRule(const char *pszRuleStr);
348
349
    /**
350
     * @brief Delete all rules from network
351
     * @return CE_None on success.
352
     */
353
    virtual CPLErr DeleteAllRules();
354
355
    /**
356
     * @brief Delete the specified rule
357
     * @param pszRuleStr - the rule to delete
358
     * @return CE_None on success.
359
     */
360
    virtual CPLErr DeleteRule(const char *pszRuleStr);
361
362
    /**
363
     * @brief Get the rule list
364
     * @return list of rule strings. The caller have to free the lis via
365
     * CPLDestroy.
366
     */
367
    virtual char **GetRules() const;
368
369
    /**
370
     * @brief Attempts to build the network topology automatically
371
     *
372
     * The method simply gets point and line or multiline layers from the
373
     * papszLayerList and searches for each line which connects two points:
374
     * start and end, so it can be not so effective in performance when it is
375
     * called on huge networks. Note, when passing your tolerance value: this
376
     * value will depend of spatial reference system of the network, and
377
     * especially of its 0,0 position because dfTolerance is just divided by 2
378
     * and added/subtracted to/from both sides of each line-feature end point
379
     * forming thus the square area around it. The first point-feature occurred
380
     * inside this area will be given as a start/end point for the current
381
     * connection. So it is also desirable that at least two layers are passed
382
     * in papszLayerList (one point and one line), and they are already
383
     * connected "visually" ("geometrically").
384
     *
385
     * @param papszLayerList A list of layers to connect. The list should be
386
     *                       freed via CSLDestroy.
387
     * @param dfTolerance Snapping tolerance.
388
     * @param dfCost Direct cost.
389
     * @param dfInvCost Inverse cost.
390
     * @param eDir Direction.
391
     * @return CE_None on success
392
     */
393
    virtual CPLErr ConnectPointsByLines(char **papszLayerList,
394
                                        double dfTolerance, double dfCost,
395
                                        double dfInvCost, GNMDirection eDir);
396
397
    /**
398
     * @brief Change the block state of edge or vertex
399
     * @param nFID Identificator
400
     * @param bIsBlock Block or unblock
401
     * @return CE_None on success
402
     */
403
    virtual CPLErr ChangeBlockState(GNMGFID nFID, bool bIsBlock);
404
405
    /**
406
     * @brief Change all vertices and edges block state.
407
     *
408
     * This is mainly use for unblock all vertices and edges.
409
     *
410
     * @param bIsBlock Block or unblock
411
     * @return CE_None on success
412
     */
413
    virtual CPLErr ChangeAllBlockState(bool bIsBlock = false);
414
415
    virtual OGRLayer *GetPath(GNMGFID nStartFID, GNMGFID nEndFID,
416
                              GNMGraphAlgorithmType eAlgorithm,
417
                              char **papszOptions) override;
418
419
    /** Casts a handle to a pointer */
420
    static inline GNMGenericNetwork *FromHandle(GNMGenericNetworkH hNet)
421
0
    {
422
0
        return static_cast<GNMGenericNetwork *>(hNet);
423
0
    }
424
425
    /** Casts a pointer to a handle */
426
    static inline GNMGenericNetworkH ToHandle(GNMGenericNetwork *poNetwork)
427
0
    {
428
0
        return static_cast<GNMGenericNetworkH>(poNetwork);
429
0
    }
430
431
  protected:
432
    /**
433
     * @brief Check or create layer OGR driver
434
     * @param pszDefaultDriverName - default driver name
435
     * @param papszOptions - create options
436
     * @return CE_None if driver is exist or CE_Failure
437
     */
438
    virtual CPLErr CheckLayerDriver(const char *pszDefaultDriverName,
439
                                    char **papszOptions);
440
    /**
441
     * @brief Check if provided OGR driver accepted as storage for network data
442
     * @param pszDriverName The driver name
443
     * @return true if supported, else false
444
     */
445
    virtual bool CheckStorageDriverSupport(const char *pszDriverName) = 0;
446
447
  protected:
448
    //! @cond Doxygen_Suppress
449
    virtual CPLErr CreateMetadataLayer(GDALDataset *const pDS, int nVersion,
450
                                       size_t nFieldSize = 1024);
451
    virtual CPLErr StoreNetworkSrs();
452
    virtual CPLErr LoadNetworkSrs();
453
    virtual CPLErr CreateGraphLayer(GDALDataset *const pDS);
454
    virtual CPLErr CreateFeaturesLayer(GDALDataset *const pDS);
455
    virtual CPLErr LoadMetadataLayer(GDALDataset *const pDS);
456
    virtual CPLErr LoadGraphLayer(GDALDataset *const pDS);
457
    virtual CPLErr LoadGraph();
458
    virtual CPLErr LoadFeaturesLayer(GDALDataset *const pDS);
459
    virtual CPLErr DeleteMetadataLayer() = 0;
460
    virtual CPLErr DeleteGraphLayer() = 0;
461
    virtual CPLErr DeleteFeaturesLayer() = 0;
462
    virtual CPLErr LoadNetworkLayer(const char *pszLayername) = 0;
463
    virtual CPLErr DeleteNetworkLayers() = 0;
464
    virtual void ConnectPointsByMultiline(
465
        GIntBig nFID, const OGRMultiLineString *poMultiLineString,
466
        const std::vector<OGRLayer *> &paPointLayers, double dfTolerance,
467
        double dfCost, double dfInvCost, GNMDirection eDir);
468
    virtual void
469
    ConnectPointsByLine(GIntBig nFID, const OGRLineString *poLineString,
470
                        const std::vector<OGRLayer *> &paPointLayers,
471
                        double dfTolerance, double dfCost, double dfInvCost,
472
                        GNMDirection eDir);
473
    virtual GNMGFID
474
    FindNearestPoint(const OGRPoint *poPoint,
475
                     const std::vector<OGRLayer *> &paPointLayers,
476
                     double dfTolerance);
477
    virtual OGRFeature *FindConnection(GNMGFID nSrcFID, GNMGFID nTgtFID,
478
                                       GNMGFID nConFID);
479
    virtual bool SaveRules();
480
    virtual GNMGFID GetNewVirtualFID();
481
    virtual void FillResultLayer(OGRGNMWrappedResultLayer *poResLayer,
482
                                 const GNMPATH &path, int nNoOfPath,
483
                                 bool bReturnVertices, bool bReturnEdges);
484
    //! @endcond
485
  protected:
486
    //! @cond Doxygen_Suppress
487
    int m_nVersion = 0;
488
    GNMGFID m_nGID = 0;
489
    GNMGFID m_nVirtualConnectionGID = -1;
490
    OGRLayer *m_poMetadataLayer = nullptr;
491
    OGRLayer *m_poGraphLayer = nullptr;
492
    OGRLayer *m_poFeaturesLayer = nullptr;
493
494
    GDALDriver *m_poLayerDriver = nullptr;
495
496
    std::map<GNMGFID, CPLString> m_moFeatureFIDMap{};
497
    std::vector<OGRLayer *> m_apoLayers{};
498
    std::vector<GNMRule> m_asRules{};
499
    bool m_bIsRulesChanged = false;
500
501
    GNMGraph m_oGraph{};
502
    bool m_bIsGraphLoaded = false;
503
    //! @endcond
504
  private:
505
    CPL_DISALLOW_COPY_ASSIGN(GNMGenericNetwork)
506
};
507
508
/**
509
 * GNM layer which represents a geography network layer of generic format.
510
 * The class override some OGRLayer methods to fulfill the network requirements.
511
 *
512
 * @since GDAL 2.1
513
 */
514
515
class GNMGenericLayer : public OGRLayer
516
{
517
  public:
518
    GNMGenericLayer(OGRLayer *poLayer, GNMGenericNetwork *poNetwork);
519
    virtual ~GNMGenericLayer();
520
521
    // OGRLayer Interface
522
523
    virtual OGRGeometry *GetSpatialFilter() override;
524
525
    virtual OGRErr ISetSpatialFilter(int iGeomField,
526
                                     const OGRGeometry *) override;
527
528
    virtual OGRErr SetAttributeFilter(const char *) override;
529
530
    virtual void ResetReading() override;
531
    virtual OGRFeature *GetNextFeature() override;
532
    virtual OGRErr SetNextByIndex(GIntBig nIndex) override;
533
534
    virtual OGRErr DeleteFeature(GIntBig nFID) override;
535
536
    virtual const char *GetName() override;
537
    virtual OGRwkbGeometryType GetGeomType() override;
538
    virtual OGRFeatureDefn *GetLayerDefn() override;
539
    virtual int FindFieldIndex(const char *pszFieldName,
540
                               int bExactMatch) override;
541
542
    virtual OGRSpatialReference *GetSpatialRef() override;
543
544
    virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
545
546
    virtual OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
547
                              bool bForce = true) override;
548
549
    virtual int TestCapability(const char *) override;
550
551
    virtual OGRErr CreateField(const OGRFieldDefn *poField,
552
                               int bApproxOK = TRUE) override;
553
    virtual OGRErr DeleteField(int iField) override;
554
    virtual OGRErr ReorderFields(int *panMap) override;
555
    virtual OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
556
                                  int nFlagsIn) override;
557
558
    virtual OGRErr CreateGeomField(const OGRGeomFieldDefn *poField,
559
                                   int bApproxOK = TRUE) override;
560
561
    virtual OGRErr SyncToDisk() override;
562
563
    virtual OGRStyleTable *GetStyleTable() override;
564
    virtual void SetStyleTableDirectly(OGRStyleTable *poStyleTable) override;
565
566
    virtual void SetStyleTable(OGRStyleTable *poStyleTable) override;
567
568
    virtual OGRErr StartTransaction() override;
569
    virtual OGRErr CommitTransaction() override;
570
    virtual OGRErr RollbackTransaction() override;
571
572
    virtual const char *GetFIDColumn() override;
573
    virtual const char *GetGeometryColumn() override;
574
575
    virtual OGRErr SetIgnoredFields(CSLConstList papszFields) override;
576
577
    /** Intersection */
578
    OGRErr Intersection(OGRLayer *pLayerMethod, OGRLayer *pLayerResult,
579
                        char **papszOptions = nullptr,
580
                        GDALProgressFunc pfnProgress = nullptr,
581
                        void *pProgressArg = nullptr);
582
    /** Union */
583
    OGRErr Union(OGRLayer *pLayerMethod, OGRLayer *pLayerResult,
584
                 char **papszOptions = nullptr,
585
                 GDALProgressFunc pfnProgress = nullptr,
586
                 void *pProgressArg = nullptr);
587
    /** SymDifference */
588
    OGRErr SymDifference(OGRLayer *pLayerMethod, OGRLayer *pLayerResult,
589
                         char **papszOptions, GDALProgressFunc pfnProgress,
590
                         void *pProgressArg);
591
    /** Identity */
592
    OGRErr Identity(OGRLayer *pLayerMethod, OGRLayer *pLayerResult,
593
                    char **papszOptions = nullptr,
594
                    GDALProgressFunc pfnProgress = nullptr,
595
                    void *pProgressArg = nullptr);
596
    /** Update */
597
    OGRErr Update(OGRLayer *pLayerMethod, OGRLayer *pLayerResult,
598
                  char **papszOptions = nullptr,
599
                  GDALProgressFunc pfnProgress = nullptr,
600
                  void *pProgressArg = nullptr);
601
    /** Clip */
602
    OGRErr Clip(OGRLayer *pLayerMethod, OGRLayer *pLayerResult,
603
                char **papszOptions = nullptr,
604
                GDALProgressFunc pfnProgress = nullptr,
605
                void *pProgressArg = nullptr);
606
    /** Erase */
607
    OGRErr Erase(OGRLayer *pLayerMethod, OGRLayer *pLayerResult,
608
                 char **papszOptions = nullptr,
609
                 GDALProgressFunc pfnProgress = nullptr,
610
                 void *pProgressArg = nullptr);
611
612
    /** GetFeaturesRead */
613
    GIntBig GetFeaturesRead();
614
615
    /** AttributeFilterEvaluationNeedsGeometry */
616
    int AttributeFilterEvaluationNeedsGeometry();
617
618
    //! @cond Doxygen_Suppress
619
    /* consider these private */
620
    OGRErr InitializeIndexSupport(const char *);
621
    OGRLayerAttrIndex *GetIndex();
622
    //! @endcond
623
624
  protected:
625
    //! @cond Doxygen_Suppress
626
    virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
627
    virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
628
629
  protected:
630
    CPLString m_soLayerName{};
631
    OGRLayer *m_poLayer = nullptr;
632
    GNMGenericNetwork *m_poNetwork = nullptr;
633
    std::map<GNMGFID, GIntBig> m_mnFIDMap{};
634
    //! @endcond
635
636
  private:
637
    CPL_DISALLOW_COPY_ASSIGN(GNMGenericLayer)
638
};
639
640
typedef enum
641
{
642
    /** Rule for connect features */ GRTConnection = 0
643
} GNMRuleType;
644
645
/**
646
 * @brief The simple class for rules
647
 *
648
 * By now we have only connect rules, so the one class is enough. Maybe in
649
 * future the set of classes for different rule types will be needed.
650
 *
651
 * @since GDAL 2.1
652
 */
653
654
class CPL_DLL GNMRule
655
{
656
  public:
657
    /** Constructor */
658
    GNMRule();
659
    /** Constructor */
660
    explicit GNMRule(const std::string &oRule);
661
    /** Constructor */
662
    explicit GNMRule(const char *pszRule);
663
664
    /** Copy constructor */
665
0
    GNMRule(const GNMRule &) = default;
666
667
    /** Move constructor */
668
0
    GNMRule(GNMRule &&) = default;
669
670
    /** Assignment operator */
671
    GNMRule &operator=(const GNMRule &) = default;
672
673
    /** Move assignment operator */
674
0
    GNMRule &operator=(GNMRule &&) = default;
675
676
    /** Destructor */
677
    virtual ~GNMRule();
678
679
    /**
680
     * @brief  This function indicate if rule string was parsed successfully
681
     * @return true if rule is valid
682
     */
683
    virtual bool IsValid() const;
684
    /**
685
     * @brief Indicator of any layer state
686
     * @return true if accept any layer
687
     */
688
    virtual bool IsAcceptAny() const;
689
    /**
690
     * @brief This is for future use to indicate the rule type/ Now return only
691
     * GRTConnection type.
692
     * @return the rule type
693
     */
694
    virtual GNMRuleType GetType() const;
695
    /**
696
     * @brief Check if connection can take place.
697
     * @param soSrcLayerName - the layer name
698
     * @param soTgtLayerName - the layer name
699
     * @param soConnLayerName - the layer name
700
     * @return true if can connect features from soSrcLayerName and
701
     * soTgtLayerName via soConnLayerName
702
     */
703
    virtual bool CanConnect(const CPLString &soSrcLayerName,
704
                            const CPLString &soTgtLayerName,
705
                            const CPLString &soConnLayerName = "");
706
    /** Return source layer name */
707
    virtual CPLString GetSourceLayerName() const;
708
    /** Return target layer name */
709
    virtual CPLString GetTargetLayerName() const;
710
    /** Return connector layer name */
711
    virtual CPLString GetConnectorLayerName() const;
712
    /** Return rule as a string */
713
    const char *c_str() const;
714
    /** Return rule as a string */
715
    operator const char *(void) const;
716
717
  protected:
718
    //! @cond Doxygen_Suppress
719
    virtual bool ParseRuleString();
720
721
  protected:
722
    CPLString m_soSrcLayerName{};
723
    CPLString m_soTgtLayerName{};
724
    CPLString m_soConnLayerName{};
725
    bool m_bAllow = false;
726
    bool m_bValid = false;
727
    bool m_bAny = false;
728
    CPLString m_soRuleString{};
729
    //! @endcond
730
};
731
732
/**
733
 * @brief The OGRGNMWrappedResultLayer class for search paths queries results.
734
 *
735
 * @since GDAL 2.1
736
 */
737
738
class OGRGNMWrappedResultLayer : public OGRLayer
739
{
740
  public:
741
    OGRGNMWrappedResultLayer(GDALDataset *poDS, OGRLayer *poLayer);
742
    ~OGRGNMWrappedResultLayer();
743
744
    // OGRLayer
745
    virtual void ResetReading() override;
746
    virtual OGRFeature *GetNextFeature() override;
747
    virtual OGRErr SetNextByIndex(GIntBig nIndex) override;
748
    virtual OGRFeature *GetFeature(GIntBig nFID) override;
749
    virtual OGRFeatureDefn *GetLayerDefn() override;
750
    virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
751
    virtual int TestCapability(const char *pszCap) override;
752
    virtual OGRErr CreateField(const OGRFieldDefn *poField,
753
                               int bApproxOK = TRUE) override;
754
    virtual OGRErr CreateGeomField(const OGRGeomFieldDefn *poField,
755
                                   int bApproxOK = TRUE) override;
756
    virtual const char *GetFIDColumn() override;
757
    virtual const char *GetGeometryColumn() override;
758
    virtual OGRSpatialReference *GetSpatialRef() override;
759
760
    // OGRGNMWrappedResultLayer
761
    virtual OGRErr InsertFeature(OGRFeature *poFeature,
762
                                 const CPLString &soLayerName, int nPathNo,
763
                                 bool bIsEdge);
764
765
  protected:
766
    virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
767
    virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
768
769
  protected:
770
    //! @cond Doxygen_Suppress
771
    GDALDataset *poDS = nullptr;
772
    OGRLayer *poLayer = nullptr;
773
    //! @endcond
774
775
  private:
776
    CPL_DISALLOW_COPY_ASSIGN(OGRGNMWrappedResultLayer)
777
};
778
779
#endif  // __cplusplus
780
781
#endif  // GNM