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