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