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