Line data Source code
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 : #define GNM_MD_NAME "net_name"
45 : #define GNM_MD_DESCR "net_description"
46 : #define GNM_MD_SRS "net_srs"
47 : #define GNM_MD_VERSION "net_version"
48 : #define GNM_MD_RULE "net_rule"
49 : #define GNM_MD_FORMAT "FORMAT"
50 : #define GNM_MD_FETCHEDGES "fetch_edge"
51 : #define GNM_MD_FETCHVERTEX "fetch_vertex"
52 : #define GNM_MD_NUM_PATHS "num_paths"
53 : #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 0 : virtual int GetVersion() const
133 : {
134 0 : return 0;
135 : }
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 7 : static inline GNMNetwork *FromHandle(GNMGenericNetworkH hNet)
168 : {
169 7 : return static_cast<GNMNetwork *>(hNet);
170 : }
171 :
172 : /** Casts a pointer to a handle */
173 5 : static inline GNMGenericNetworkH ToHandle(GNMNetwork *poNetwork)
174 : {
175 5 : return static_cast<GNMGenericNetworkH>(poNetwork);
176 : }
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 16 : 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 1 : static inline GNMGenericNetwork *FromHandle(GNMGenericNetworkH hNet)
421 : {
422 1 : return static_cast<GNMGenericNetwork *>(hNet);
423 : }
424 :
425 : /** Casts a pointer to a handle */
426 1 : static inline GNMGenericNetworkH ToHandle(GNMGenericNetwork *poNetwork)
427 : {
428 1 : return static_cast<GNMGenericNetworkH>(poNetwork);
429 : }
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 50 : 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 28 : class CPL_DLL GNMRule
655 : {
656 : // to hopefully please Coverity Scan which complains about missing
657 : // move assignment operator for performance reasons
658 : GNMRule &operator==(GNMRule &&) = delete;
659 :
660 : public:
661 : /** Constructor */
662 : GNMRule();
663 : /** Constructor */
664 : explicit GNMRule(const std::string &oRule);
665 : /** Constructor */
666 : explicit GNMRule(const char *pszRule);
667 : /** Constructor */
668 : GNMRule(const GNMRule &oRule);
669 :
670 : /** Assignment operator */
671 : GNMRule &operator=(const GNMRule &) = default;
672 :
673 : virtual ~GNMRule();
674 : /**
675 : * @brief This function indicate if rule string was parsed successfully
676 : * @return true if rule is valid
677 : */
678 : virtual bool IsValid() const;
679 : /**
680 : * @brief Indicator of any layer state
681 : * @return true if accept any layer
682 : */
683 : virtual bool IsAcceptAny() const;
684 : /**
685 : * @brief This is for future use to indicate the rule type/ Now return only
686 : * GRTConnection type.
687 : * @return the rule type
688 : */
689 : virtual GNMRuleType GetType() const;
690 : /**
691 : * @brief Check if connection can take place.
692 : * @param soSrcLayerName - the layer name
693 : * @param soTgtLayerName - the layer name
694 : * @param soConnLayerName - the layer name
695 : * @return true if can connect features from soSrcLayerName and
696 : * soTgtLayerName via soConnLayerName
697 : */
698 : virtual bool CanConnect(const CPLString &soSrcLayerName,
699 : const CPLString &soTgtLayerName,
700 : const CPLString &soConnLayerName = "");
701 : /** Return source layer name */
702 : virtual CPLString GetSourceLayerName() const;
703 : /** Return target layer name */
704 : virtual CPLString GetTargetLayerName() const;
705 : /** Return connector layer name */
706 : virtual CPLString GetConnectorLayerName() const;
707 : /** Return rule as a string */
708 : const char *c_str() const;
709 : /** Return rule as a string */
710 : operator const char *(void) const;
711 :
712 : protected:
713 : //! @cond Doxygen_Suppress
714 : virtual bool ParseRuleString();
715 :
716 : protected:
717 : CPLString m_soSrcLayerName{};
718 : CPLString m_soTgtLayerName{};
719 : CPLString m_soConnLayerName{};
720 : bool m_bAllow = false;
721 : bool m_bValid = false;
722 : bool m_bAny = false;
723 : CPLString m_soRuleString{};
724 : //! @endcond
725 : };
726 :
727 : /**
728 : * @brief The OGRGNMWrappedResultLayer class for search paths queries results.
729 : *
730 : * @since GDAL 2.1
731 : */
732 :
733 : class OGRGNMWrappedResultLayer : public OGRLayer
734 : {
735 : public:
736 : OGRGNMWrappedResultLayer(GDALDataset *poDS, OGRLayer *poLayer);
737 : ~OGRGNMWrappedResultLayer();
738 :
739 : // OGRLayer
740 : virtual void ResetReading() override;
741 : virtual OGRFeature *GetNextFeature() override;
742 : virtual OGRErr SetNextByIndex(GIntBig nIndex) override;
743 : virtual OGRFeature *GetFeature(GIntBig nFID) override;
744 : virtual OGRFeatureDefn *GetLayerDefn() override;
745 : virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
746 : virtual int TestCapability(const char *pszCap) override;
747 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
748 : int bApproxOK = TRUE) override;
749 : virtual OGRErr CreateGeomField(const OGRGeomFieldDefn *poField,
750 : int bApproxOK = TRUE) override;
751 : virtual const char *GetFIDColumn() override;
752 : virtual const char *GetGeometryColumn() override;
753 : virtual OGRSpatialReference *GetSpatialRef() override;
754 :
755 : // OGRGNMWrappedResultLayer
756 : virtual OGRErr InsertFeature(OGRFeature *poFeature,
757 : const CPLString &soLayerName, int nPathNo,
758 : bool bIsEdge);
759 :
760 : protected:
761 : virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
762 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
763 :
764 : protected:
765 : //! @cond Doxygen_Suppress
766 : GDALDataset *poDS = nullptr;
767 : OGRLayer *poLayer = nullptr;
768 : //! @endcond
769 :
770 : private:
771 : CPL_DISALLOW_COPY_ASSIGN(OGRGNMWrappedResultLayer)
772 : };
773 :
774 : #endif // __cplusplus
775 :
776 : #endif // GNM
|