1 /********************************************************************** 2 * 3 * rttopo - topology library 4 * http://git.osgeo.org/gitea/rttopo/librttopo 5 * 6 * rttopo is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * rttopo is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with rttopo. If not, see <http://www.gnu.org/licenses/>. 18 * 19 ********************************************************************** 20 * 21 * Copyright (C) 2015 Sandro Santilli <strk@kbt.io> 22 * 23 **********************************************************************/ 24 25 26 27 #ifndef LIBRTGEOM_TOPO_H 28 #define LIBRTGEOM_TOPO_H 1 29 30 #include "librttopo_geom.h" 31 32 /* INT64 */ 33 typedef int64_t RTT_INT64; 34 35 /** Identifier of topology element */ 36 typedef RTT_INT64 RTT_ELEMID; 37 38 /* 39 * ISO primitive elements 40 */ 41 42 /** NODE */ 43 typedef struct 44 { 45 RTT_ELEMID node_id; 46 RTT_ELEMID containing_face; /* -1 if not isolated */ 47 RTPOINT *geom; 48 } 49 RTT_ISO_NODE; 50 51 void rtt_iso_node_release(RTT_ISO_NODE* node); 52 53 /** Node fields */ 54 #define RTT_COL_NODE_NODE_ID 1<<0 55 #define RTT_COL_NODE_CONTAINING_FACE 1<<1 56 #define RTT_COL_NODE_GEOM 1<<2 57 #define RTT_COL_NODE_ALL (1<<3)-1 58 59 /** EDGE */ 60 typedef struct 61 { 62 RTT_ELEMID edge_id; 63 RTT_ELEMID start_node; 64 RTT_ELEMID end_node; 65 RTT_ELEMID face_left; 66 RTT_ELEMID face_right; 67 RTT_ELEMID next_left; 68 RTT_ELEMID next_right; 69 RTLINE *geom; 70 } 71 RTT_ISO_EDGE; 72 73 /** Edge fields */ 74 #define RTT_COL_EDGE_EDGE_ID 1<<0 75 #define RTT_COL_EDGE_START_NODE 1<<1 76 #define RTT_COL_EDGE_END_NODE 1<<2 77 #define RTT_COL_EDGE_FACE_LEFT 1<<3 78 #define RTT_COL_EDGE_FACE_RIGHT 1<<4 79 #define RTT_COL_EDGE_NEXT_LEFT 1<<5 80 #define RTT_COL_EDGE_NEXT_RIGHT 1<<6 81 #define RTT_COL_EDGE_GEOM 1<<7 82 #define RTT_COL_EDGE_ALL (1<<8)-1 83 84 /** FACE */ 85 typedef struct 86 { 87 RTT_ELEMID face_id; 88 RTGBOX *mbr; 89 } 90 RTT_ISO_FACE; 91 92 /** Face fields */ 93 #define RTT_COL_FACE_FACE_ID 1<<0 94 #define RTT_COL_FACE_MBR 1<<1 95 #define RTT_COL_FACE_ALL (1<<2)-1 96 97 typedef enum RTT_SPATIALTYPE_T { 98 RTT_PUNTAL = 0, 99 RTT_LINEAL = 1, 100 RTT_AREAL = 2, 101 RTT_COLLECTION = 3 102 } RTT_SPATIALTYPE; 103 104 /* 105 * Backend handling functions 106 */ 107 108 /* opaque pointers referencing native backend objects */ 109 110 /** 111 * Backend private data pointer 112 * 113 * Only the backend handler needs to know what it really is. 114 * It will be passed to all registered callback functions. 115 */ 116 typedef struct RTT_BE_DATA_T RTT_BE_DATA; 117 118 /** 119 * Backend interface handler 120 * 121 * Embeds all registered backend callbacks and private data pointer. 122 * Will need to be passed (directly or indirectly) to al public facing 123 * APIs of this library. 124 */ 125 typedef struct RTT_BE_IFACE_T RTT_BE_IFACE; 126 127 /** 128 * Topology handler. 129 * 130 * Embeds backend interface handler. 131 * Will need to be passed to all topology manipulation APIs 132 * of this library. 133 */ 134 typedef struct RTT_BE_TOPOLOGY_T RTT_BE_TOPOLOGY; 135 136 /** 137 * Structure containing base backend callbacks 138 * 139 * Used for registering into the backend iface 140 */ 141 typedef struct RTT_BE_CALLBACKS_T { 142 143 /** 144 * Read last error message from backend 145 * 146 * @return NULL-terminated error string 147 */ 148 const char* (*lastErrorMessage) (const RTT_BE_DATA* be); 149 150 /** 151 * Create a new topology in the backend 152 * 153 * @param name the topology name 154 * @param srid the topology SRID 155 * @param precision the topology precision/tolerance 156 * @param hasZ non-zero if topology primitives should have a Z ordinate 157 * @return a topology handler, which embeds the backend data/params 158 * or NULL on error (@see lastErrorMessage) 159 */ 160 RTT_BE_TOPOLOGY* (*createTopology) ( 161 const RTT_BE_DATA* be, 162 const char* name, int srid, double precision, int hasZ 163 ); 164 165 /** 166 * Load a topology from the backend 167 * 168 * @param name the topology name 169 * @return a topology handler, which embeds the backend data/params 170 * or NULL on error (@see lastErrorMessage) 171 */ 172 RTT_BE_TOPOLOGY* (*loadTopologyByName) ( 173 const RTT_BE_DATA* be, 174 const char* name 175 ); 176 177 /** 178 * Release memory associated to a backend topology 179 * 180 * @param topo the backend topology handler 181 * @return 1 on success, 0 on error (@see lastErrorMessage) 182 */ 183 int (*freeTopology) (RTT_BE_TOPOLOGY* topo); 184 185 /** 186 * Get nodes by id 187 * 188 * @param topo the topology to act upon 189 * @param ids an array of element identifiers 190 * @param numelems input/output parameter, pass number of node identifiers 191 * in the input array, gets number of node in output array. 192 * @param fields fields to be filled in the returned structure, see 193 * RTT_COL_NODE_* macros 194 * 195 * @return an array of nodes 196 * or NULL in the following cases: 197 * - no edge found ("numelems" is set to 0) 198 * - error ("numelems" is set to -1) 199 * (@see lastErrorMessage) 200 * 201 */ 202 RTT_ISO_NODE* (*getNodeById) ( 203 const RTT_BE_TOPOLOGY* topo, 204 const RTT_ELEMID* ids, int* numelems, int fields 205 ); 206 207 /** 208 * Get nodes within distance by point 209 * 210 * @param topo the topology to act upon 211 * @param pt the query point 212 * @param dist the distance 213 * @param numelems output parameter, gets number of elements found 214 * if the return is not null, otherwise see @return 215 * section for semantic. 216 * @param fields fields to be filled in the returned structure, see 217 * RTT_COL_NODE_* macros 218 * @param limit max number of nodes to return, 0 for no limit, -1 219 * to only check for existance if a matching row. 220 * 221 * @return an array of nodes or null in the following cases: 222 * - limit=-1 ("numelems" is set to 1 if found, 0 otherwise) 223 * - limit>0 and no records found ("numelems" is set to 0) 224 * - error ("numelems" is set to -1) 225 * 226 */ 227 RTT_ISO_NODE* (*getNodeWithinDistance2D) ( 228 const RTT_BE_TOPOLOGY* topo, 229 const RTPOINT* pt, double dist, int* numelems, 230 int fields, int limit 231 ); 232 233 /** 234 * Insert nodes 235 * 236 * Insert node primitives in the topology, performing no 237 * consistency checks. 238 * 239 * @param topo the topology to act upon 240 * @param nodes the nodes to insert. Those with a node_id set to -1 241 * it will be replaced to an automatically assigned identifier 242 * @param nelems number of elements in the nodes array 243 * 244 * @return 1 on success, 0 on error (@see lastErrorMessage) 245 */ 246 int (*insertNodes) ( 247 const RTT_BE_TOPOLOGY* topo, 248 RTT_ISO_NODE* nodes, 249 int numelems 250 ); 251 252 /** 253 * Get edge by id 254 * 255 * @param topo the topology to act upon 256 * @param ids an array of element identifiers 257 * @param numelems input/output parameter, pass number of edge identifiers 258 * in the input array, gets number of edges in output array 259 * if the return is not null, otherwise see @return 260 * section for semantic. 261 * @param fields fields to be filled in the returned structure, see 262 * RTT_COL_EDGE_* macros 263 * 264 * @return an array of edges or NULL in the following cases: 265 * - none found ("numelems" is set to 0) 266 * - error ("numelems" is set to -1) 267 */ 268 RTT_ISO_EDGE* (*getEdgeById) ( 269 const RTT_BE_TOPOLOGY* topo, 270 const RTT_ELEMID* ids, int* numelems, int fields 271 ); 272 273 /** 274 * Get edges within distance by point 275 * 276 * @param topo the topology to act upon 277 * @param pt the query point 278 * @param dist the distance 279 * @param numelems output parameter, gets number of elements found 280 * if the return is not null, otherwise see @return 281 * section for semantic. 282 * @param fields fields to be filled in the returned structure, see 283 * RTT_COL_EDGE_* macros 284 * @param limit max number of edges to return, 0 for no limit, -1 285 * to only check for existance if a matching row. 286 * 287 * @return an array of edges or null in the following cases: 288 * - limit=-1 ("numelems" is set to 1 if found, 0 otherwise) 289 * - limit>0 and no records found ("numelems" is set to 0) 290 * - error ("numelems" is set to -1) 291 * 292 */ 293 RTT_ISO_EDGE* (*getEdgeWithinDistance2D) ( 294 const RTT_BE_TOPOLOGY* topo, 295 const RTPOINT* pt, double dist, int* numelems, 296 int fields, int limit 297 ); 298 299 /** 300 * Get next available edge identifier 301 * 302 * Identifiers returned by this function should not be considered 303 * available anymore. 304 * 305 * @param topo the topology to act upon 306 * 307 * @return next available edge identifier or -1 on error 308 */ 309 RTT_ELEMID (*getNextEdgeId) ( 310 const RTT_BE_TOPOLOGY* topo 311 ); 312 313 /** 314 * Insert edges 315 * 316 * Insert edge primitives in the topology, performing no 317 * consistency checks. 318 * 319 * @param topo the topology to act upon 320 * @param edges the edges to insert. Those with a edge_id set to -1 321 * it will be replaced to an automatically assigned identifier 322 * @param nelems number of elements in the edges array 323 * 324 * @return number of inserted edges, or -1 (@see lastErrorMessage) 325 */ 326 int (*insertEdges) ( 327 const RTT_BE_TOPOLOGY* topo, 328 RTT_ISO_EDGE* edges, 329 int numelems 330 ); 331 332 /** 333 * Update edges selected by fields match/mismatch 334 * 335 * @param topo the topology to act upon 336 * @param sel_edge an RTT_ISO_EDGE object with selecting fields set. 337 * @param sel_fields fields used to select edges to be updated, 338 * see RTT_COL_EDGE_* macros 339 * @param upd_edge an RTT_ISO_EDGE object with updated fields set. 340 * @param upd_fields fields to be updated for the selected edges, 341 * see RTT_COL_EDGE_* macros 342 * @param exc_edge an RTT_ISO_EDGE object with exclusion fields set, 343 * can be NULL if no exlusion condition exists. 344 * @param exc_fields fields used for excluding edges from the update, 345 * see RTT_COL_EDGE_* macros 346 * 347 * @return number of edges being updated or -1 on error 348 * (@see lastErroMessage) 349 */ 350 int (*updateEdges) ( 351 const RTT_BE_TOPOLOGY* topo, 352 const RTT_ISO_EDGE* sel_edge, int sel_fields, 353 const RTT_ISO_EDGE* upd_edge, int upd_fields, 354 const RTT_ISO_EDGE* exc_edge, int exc_fields 355 ); 356 357 /** 358 * Get faces by id 359 * 360 * @param topo the topology to act upon 361 * @param ids an array of element identifiers 362 * @param numelems input/output parameter, pass number of edge identifiers 363 * in the input array, gets number of node in output array 364 * if the return is not null, otherwise see @return 365 * section for semantic. 366 * @param fields fields to be filled in the returned structure, see 367 * RTT_COL_FACE_* macros 368 * 369 * @return an array of faces or NULL in the following cases: 370 * - none found ("numelems" is set to 0) 371 * - error ("numelems" is set to -1) 372 */ 373 RTT_ISO_FACE* (*getFaceById) ( 374 const RTT_BE_TOPOLOGY* topo, 375 const RTT_ELEMID* ids, int* numelems, int fields 376 ); 377 378 /** 379 * Get face containing point 380 * 381 * @param topo the topology to act upon 382 * @param pt the query point 383 * 384 * @return a face identifier, -1 if no face contains the point 385 * (could be in universe face or on an edge) 386 * or -2 on error (@see lastErrorMessage) 387 */ 388 RTT_ELEMID (*getFaceContainingPoint) ( 389 const RTT_BE_TOPOLOGY* topo, 390 const RTPOINT* pt 391 ); 392 393 /** 394 * Update TopoGeometry objects after an edge split event 395 * 396 * @param topo the topology to act upon 397 * @param split_edge identifier of the edge that was split. 398 * @param new_edge1 identifier of the first new edge that was created 399 * as a result of edge splitting. 400 * @param new_edge2 identifier of the second new edge that was created 401 * as a result of edge splitting, or -1 if the old edge was 402 * modified rather than replaced. 403 * 404 * @return 1 on success, 0 on error 405 * 406 * @note on splitting an edge, the new edges both have the 407 * same direction as the original one. If a second new edge was 408 * created, its start node will be equal to the first new edge 409 * end node. 410 */ 411 int (*updateTopoGeomEdgeSplit) ( 412 const RTT_BE_TOPOLOGY* topo, 413 RTT_ELEMID split_edge, RTT_ELEMID new_edge1, RTT_ELEMID new_edge2 414 ); 415 416 /** 417 * Delete edges 418 * 419 * @param topo the topology to act upon 420 * @param sel_edge an RTT_ISO_EDGE object with selecting fields set. 421 * @param sel_fields fields used to select edges to be deleted, 422 * see RTT_COL_EDGE_* macros 423 * 424 * @return number of edges being deleted or -1 on error 425 * (@see lastErroMessage) 426 */ 427 int (*deleteEdges) ( 428 const RTT_BE_TOPOLOGY* topo, 429 const RTT_ISO_EDGE* sel_edge, int sel_fields 430 ); 431 432 /** 433 * Get edges whose bounding box overlaps a given 2D bounding box 434 * 435 * @param topo the topology to act upon 436 * @param box the query box 437 * @param numelems output parameter, gets number of elements found 438 * if the return is not null, otherwise see @return 439 * section for semantic. 440 * @param fields fields to be filled in the returned structure, see 441 * RTT_COL_NODE_* macros 442 * @param limit max number of nodes to return, 0 for no limit, -1 443 * to only check for existance if a matching row. 444 * 445 * @return an array of nodes or null in the following cases: 446 * - limit=-1 ("numelems" is set to 1 if found, 0 otherwise) 447 * - limit>0 and no records found ("numelems" is set to 0) 448 * - error ("numelems" is set to -1) 449 * 450 */ 451 RTT_ISO_NODE* (*getNodeWithinBox2D) ( 452 const RTT_BE_TOPOLOGY* topo, 453 const RTGBOX* box, 454 int* numelems, int fields, int limit 455 ); 456 457 /** 458 * Get edges whose bounding box overlaps a given 2D bounding box 459 * 460 * @param topo the topology to act upon 461 * @param box the query box, to be considered infinite if NULL 462 * @param numelems output parameter, gets number of elements found 463 * if the return is not null, otherwise see @return 464 * section for semantic. 465 * @param fields fields to be filled in the returned structure, see 466 * RTT_COL_EDGE_* macros 467 * @param limit max number of edges to return, 0 for no limit, -1 468 * to only check for existance if a matching row. 469 * 470 * @return an array of edges or null in the following cases: 471 * - limit=-1 ("numelems" is set to 1 if found, 0 otherwise) 472 * - limit>0 and no records found ("numelems" is set to 0) 473 * - error ("numelems" is set to -1) 474 * 475 */ 476 RTT_ISO_EDGE* (*getEdgeWithinBox2D) ( 477 const RTT_BE_TOPOLOGY* topo, 478 const RTGBOX* box, 479 int* numelems, int fields, int limit 480 ); 481 482 /** 483 * Get edges that start or end on any of the given node identifiers 484 * 485 * @param topo the topology to act upon 486 * @param ids an array of node identifiers 487 * @param numelems input/output parameter, pass number of node identifiers 488 * in the input array, gets number of edges in output array 489 * if the return is not null, otherwise see @return 490 * section for semantic. 491 * @param fields fields to be filled in the returned structure, see 492 * RTT_COL_EDGE_* macros 493 * 494 * @return an array of edges that are incident to a node 495 * or NULL in the following cases: 496 * - no edge found ("numelems" is set to 0) 497 * - error ("numelems" is set to -1) 498 * (@see lastErrorMessage) 499 */ 500 RTT_ISO_EDGE* (*getEdgeByNode) ( 501 const RTT_BE_TOPOLOGY* topo, 502 const RTT_ELEMID* ids, int* numelems, int fields 503 ); 504 505 /** 506 * Update nodes selected by fields match/mismatch 507 * 508 * @param topo the topology to act upon 509 * @param sel_node an RTT_ISO_NODE object with selecting fields set. 510 * @param sel_fields fields used to select nodes to be updated, 511 * see RTT_COL_NODE_* macros 512 * @param upd_node an RTT_ISO_NODE object with updated fields set. 513 * @param upd_fields fields to be updated for the selected nodes, 514 * see RTT_COL_NODE_* macros 515 * @param exc_node an RTT_ISO_NODE object with exclusion fields set, 516 * can be NULL if no exlusion condition exists. 517 * @param exc_fields fields used for excluding nodes from the update, 518 * see RTT_COL_NODE_* macros 519 * 520 * @return number of nodes being updated or -1 on error 521 * (@see lastErroMessage) 522 */ 523 int (*updateNodes) ( 524 const RTT_BE_TOPOLOGY* topo, 525 const RTT_ISO_NODE* sel_node, int sel_fields, 526 const RTT_ISO_NODE* upd_node, int upd_fields, 527 const RTT_ISO_NODE* exc_node, int exc_fields 528 ); 529 530 /** 531 * Update TopoGeometry objects after a face split event 532 * 533 * @param topo the topology to act upon 534 * @param split_face identifier of the face that was split. 535 * @param new_face1 identifier of the first new face that was created 536 * as a result of face splitting. 537 * @param new_face2 identifier of the second new face that was created 538 * as a result of face splitting, or -1 if the old face was 539 * modified rather than replaced. 540 * 541 * @return 1 on success, 0 on error (@see lastErroMessage) 542 * 543 */ 544 int (*updateTopoGeomFaceSplit) ( 545 const RTT_BE_TOPOLOGY* topo, 546 RTT_ELEMID split_face, RTT_ELEMID new_face1, RTT_ELEMID new_face2 547 ); 548 549 /** 550 * Insert faces 551 * 552 * Insert face primitives in the topology, performing no 553 * consistency checks. 554 * 555 * @param topo the topology to act upon 556 * @param faces the faces to insert. Those with a node_id set to -1 557 * it will be replaced to an automatically assigned identifier 558 * @param nelems number of elements in the faces array 559 * 560 * @return number of inserted faces, or -1 (@see lastErrorMessage) 561 */ 562 int (*insertFaces) ( 563 const RTT_BE_TOPOLOGY* topo, 564 RTT_ISO_FACE* faces, 565 int numelems 566 ); 567 568 /** 569 * Update faces by id 570 * 571 * @param topo the topology to act upon 572 * @param faces an array of RTT_ISO_FACE object with selecting id 573 * and setting mbr. 574 * @param numfaces number of faces in the "faces" array 575 * 576 * @return number of faces being updated or -1 on error 577 * (@see lastErroMessage) 578 */ 579 int (*updateFacesById) ( 580 const RTT_BE_TOPOLOGY* topo, 581 const RTT_ISO_FACE* faces, int numfaces 582 ); 583 584 /* 585 * Get the ordered list edge visited by a side walk 586 * 587 * The walk starts from the side of an edge and stops when 588 * either the max number of visited edges OR the starting 589 * position is reached. The output list never includes a 590 * duplicated signed edge identifier. 591 * 592 * It is expected that the walk uses the "next_left" and "next_right" 593 * attributes of ISO edges to perform the walk (rather than recomputing 594 * the turns at each node). 595 * 596 * @param topo the topology to operate on 597 * @param edge walk start position and direction: 598 * abs value identifies the edge, sign expresses 599 * side (left if positive, right if negative) 600 * and direction (forward if positive, backward if negative). 601 * @param numedges output parameter, gets the number of edges visited 602 * @param limit max edges to return (to avoid an infinite loop in case 603 * of a corrupted topology). 0 is for unlimited. 604 * The function is expected to error out if the limit is hit. 605 * 606 * @return an array of signed edge identifiers (positive edges being 607 * walked in their direction, negative ones in opposite) or 608 * NULL on error (@see lastErroMessage) 609 */ 610 RTT_ELEMID* (*getRingEdges) ( 611 const RTT_BE_TOPOLOGY* topo, 612 RTT_ELEMID edge, int *numedges, int limit 613 ); 614 615 /** 616 * Update edges by id 617 * 618 * @param topo the topology to act upon 619 * @param edges an array of RTT_ISO_EDGE object with selecting id 620 * and updating fields. 621 * @param numedges number of edges in the "edges" array 622 * @param upd_fields fields to be updated for the selected edges, 623 * see RTT_COL_EDGE_* macros 624 * 625 * @return number of edges being updated or -1 on error 626 * (@see lastErroMessage) 627 */ 628 int (*updateEdgesById) ( 629 const RTT_BE_TOPOLOGY* topo, 630 const RTT_ISO_EDGE* edges, int numedges, 631 int upd_fields 632 ); 633 634 /** 635 * \brief 636 * Get edges that have any of the given faces on the left or right side 637 * and optionally whose bounding box overlaps the given one. 638 * 639 * @param topo the topology to act upon 640 * @param ids an array of face identifiers 641 * @param numelems input/output parameter, pass number of face identifiers 642 * in the input array, gets number of edges in output array 643 * if the return is not null, otherwise see @return 644 * section for semantic. 645 * @param fields fields to be filled in the returned structure, see 646 * RTT_COL_EDGE_* macros 647 * @param box optional bounding box to further restrict matches, use 648 * NULL for no further restriction. 649 * 650 * @return an array of edges identifiers or NULL in the following cases: 651 * - no edge found ("numelems" is set to 0) 652 * - error ("numelems" is set to -1) 653 */ 654 RTT_ISO_EDGE* (*getEdgeByFace) ( 655 const RTT_BE_TOPOLOGY* topo, 656 const RTT_ELEMID* ids, int* numelems, int fields, 657 const RTGBOX *box 658 ); 659 660 /** 661 * Get isolated nodes contained in any of the given faces 662 * 663 * @param topo the topology to act upon 664 * @param faces an array of face identifiers 665 * @param numelems input/output parameter, pass number of face 666 * identifiers in the input array, gets number of 667 * nodes in output array if the return is not null, 668 * otherwise see @return section for semantic. 669 * @param fields fields to be filled in the returned structure, see 670 * RTT_COL_NODE_* macros 671 * @param box optional bounding box to further restrict matches, use 672 * NULL for no further restriction. 673 * 674 * @return an array of nodes or NULL in the following cases: 675 * - no nod found ("numelems" is set to 0) 676 * - error ("numelems" is set to -1, @see lastErrorMessage) 677 */ 678 RTT_ISO_NODE* (*getNodeByFace) ( 679 const RTT_BE_TOPOLOGY* topo, 680 const RTT_ELEMID* faces, int* numelems, int fields, 681 const RTGBOX *box 682 ); 683 684 /** 685 * Update nodes by id 686 * 687 * @param topo the topology to act upon 688 * @param nodes an array of RTT_ISO_EDGE objects with selecting id 689 * and updating fields. 690 * @param numnodes number of nodes in the "nodes" array 691 * @param upd_fields fields to be updated for the selected edges, 692 * see RTT_COL_NODE_* macros 693 * 694 * @return number of nodes being updated or -1 on error 695 * (@see lastErroMessage) 696 */ 697 int (*updateNodesById) ( 698 const RTT_BE_TOPOLOGY* topo, 699 const RTT_ISO_NODE* nodes, int numnodes, 700 int upd_fields 701 ); 702 703 /** 704 * Delete faces by id 705 * 706 * @param topo the topology to act upon 707 * @param ids an array of face identifiers 708 * @param numelems number of face identifiers in the ids array 709 * 710 * @return number of faces being deleted or -1 on error 711 * (@see lastErroMessage) 712 */ 713 int (*deleteFacesById) ( 714 const RTT_BE_TOPOLOGY* topo, 715 const RTT_ELEMID* ids, 716 int numelems 717 ); 718 719 /** 720 * Get topology SRID 721 * @return 0 for unknown 722 */ 723 int (*topoGetSRID) ( 724 const RTT_BE_TOPOLOGY* topo 725 ); 726 727 /** 728 * Get topology precision 729 */ 730 double (*topoGetPrecision) ( 731 const RTT_BE_TOPOLOGY* topo 732 ); 733 734 /** 735 * Get topology Z flag 736 * @return 1 if topology elements do have Z value, 0 otherwise 737 */ 738 int (*topoHasZ) ( 739 const RTT_BE_TOPOLOGY* topo 740 ); 741 742 /** 743 * Delete nodes by id 744 * 745 * @param topo the topology to act upon 746 * @param ids an array of node identifiers 747 * @param numelems number of node identifiers in the ids array 748 * 749 * @return number of nodes being deleted or -1 on error 750 * (@see lastErroMessage) 751 */ 752 int (*deleteNodesById) ( 753 const RTT_BE_TOPOLOGY* topo, 754 const RTT_ELEMID* ids, 755 int numelems 756 ); 757 758 /** 759 * Check TopoGeometry objects before an edge removal event 760 * 761 * @param topo the topology to act upon 762 * @param rem_edge identifier of the edge that's been removed 763 * @param face_left identifier of the face on the edge's left side 764 * @param face_right identifier of the face on the edge's right side 765 * 766 * @return 1 to allow, 0 to forbid the operation 767 * (reporting reason via lastErrorMessage) 768 * 769 */ 770 int (*checkTopoGeomRemEdge) ( 771 const RTT_BE_TOPOLOGY* topo, 772 RTT_ELEMID rem_edge, 773 RTT_ELEMID face_left, 774 RTT_ELEMID face_right 775 ); 776 777 /** 778 * Update TopoGeometry objects after healing two faces 779 * 780 * @param topo the topology to act upon 781 * @param face1 identifier of the first face 782 * @param face2 identifier of the second face 783 * @param newface identifier of the new face 784 * 785 * @note that newface may or may not be equal to face1 or face2, 786 * while face1 should never be the same as face2. 787 * 788 * @return 1 on success, 0 on error (@see lastErrorMessage) 789 * 790 */ 791 int (*updateTopoGeomFaceHeal) ( 792 const RTT_BE_TOPOLOGY* topo, 793 RTT_ELEMID face1, RTT_ELEMID face2, RTT_ELEMID newface 794 ); 795 796 /** 797 * Check TopoGeometry objects before a node removal event 798 * 799 * @param topo the topology to act upon 800 * @param rem_node identifier of the node that's been removed 801 * @param e1 identifier of the first connected edge 802 * @param e2 identifier of the second connected edge 803 * 804 * The operation should be forbidden if any TopoGeometry object 805 * exists which contains only one of the two healed edges. 806 * 807 * The operation should also be forbidden if the removed node 808 * takes part in the definition of a TopoGeometry, although 809 * this wasn't the case yet as of PostGIS version 2.1.8: 810 * https://trac.osgeo.org/postgis/ticket/3239 811 * 812 * @return 1 to allow, 0 to forbid the operation 813 * (reporting reason via lastErrorMessage) 814 * 815 */ 816 int (*checkTopoGeomRemNode) ( 817 const RTT_BE_TOPOLOGY* topo, 818 RTT_ELEMID rem_node, 819 RTT_ELEMID e1, 820 RTT_ELEMID e2 821 ); 822 823 /** 824 * Update TopoGeometry objects after healing two edges 825 * 826 * @param topo the topology to act upon 827 * @param edge1 identifier of the first edge 828 * @param edge2 identifier of the second edge 829 * @param newedge identifier of the new edge, taking the space 830 * previously occupied by both original edges 831 * 832 * @note that newedge may or may not be equal to edge1 or edge2, 833 * while edge1 should never be the same as edge2. 834 * 835 * @return 1 on success, 0 on error (@see lastErrorMessage) 836 * 837 */ 838 int (*updateTopoGeomEdgeHeal) ( 839 const RTT_BE_TOPOLOGY* topo, 840 RTT_ELEMID edge1, RTT_ELEMID edge2, RTT_ELEMID newedge 841 ); 842 843 /** 844 * Get faces whose bounding box overlaps a given 2D bounding box 845 * 846 * @param topo the topology to act upon 847 * @param box the query box 848 * @param numelems output parameter, gets number of elements found 849 * if the return is not null, otherwise see @return 850 * section for semantic. 851 * @param fields fields to be filled in the returned structure, see 852 * RTT_COL_FACE_* macros 853 * @param limit max number of faces to return, 0 for no limit, -1 854 * to only check for existance if a matching row. 855 * 856 * @return an array of faces or null in the following cases: 857 * - limit=-1 ("numelems" is set to 1 if found, 0 otherwise) 858 * - limit>0 and no records found ("numelems" is set to 0) 859 * - error ("numelems" is set to -1) 860 * 861 */ 862 RTT_ISO_FACE* (*getFaceWithinBox2D) ( 863 const RTT_BE_TOPOLOGY* topo, 864 const RTGBOX* box, 865 int* numelems, int fields, int limit 866 ); 867 868 } RTT_BE_CALLBACKS; 869 870 871 /** 872 * Create a new backend interface 873 * 874 * Ownership to caller delete with rtt_FreeBackendIface 875 * 876 * @param ctx librtgeom context, create with rtgeom_init 877 * @param data Backend data, passed as first parameter 878 * to all callback functions 879 */ 880 RTT_BE_IFACE* rtt_CreateBackendIface(const RTCTX* ctx, 881 const RTT_BE_DATA* data); 882 883 /** 884 * Register backend callbacks into the opaque iface handler 885 * 886 * @param iface the backend interface handler (see rtt_CreateBackendIface) 887 * @param cb a pointer to the callbacks structure; ownership left to caller. 888 */ 889 void rtt_BackendIfaceRegisterCallbacks(RTT_BE_IFACE* iface, 890 const RTT_BE_CALLBACKS* cb); 891 892 /** Release memory associated with an RTT_BE_IFACE */ 893 void rtt_FreeBackendIface(RTT_BE_IFACE* iface); 894 895 /******************************************************************** 896 * 897 * End of BE interface 898 * 899 *******************************************************************/ 900 901 /** 902 * Topology errors type 903 */ 904 typedef enum RTT_TOPOERR_TYPE_T { 905 RTT_TOPOERR_EDGE_CROSSES_NODE, 906 RTT_TOPOERR_EDGE_INVALID, 907 RTT_TOPOERR_EDGE_NOT_SIMPLE, 908 RTT_TOPOERR_EDGE_CROSSES_EDGE, 909 RTT_TOPOERR_EDGE_STARTNODE_MISMATCH, 910 RTT_TOPOERR_EDGE_ENDNODE_MISMATCH, 911 RTT_TOPOERR_FACE_WITHOUT_EDGES, 912 RTT_TOPOERR_FACE_HAS_NO_RINGS, 913 RTT_TOPOERR_FACE_OVERLAPS_FACE, 914 RTT_TOPOERR_FACE_WITHIN_FACE 915 } RTT_TOPOERR_TYPE; 916 917 /** Topology error */ 918 typedef struct RTT_TOPOERR_T { 919 /** Type of error */ 920 RTT_TOPOERR_TYPE err; 921 /** Identifier of first affected element */ 922 RTT_ELEMID elem1; 923 /** Identifier of second affected element (0 if inapplicable) */ 924 RTT_ELEMID elem2; 925 } RTT_TOPOERR; 926 927 /* 928 * Topology functions 929 */ 930 931 /** Opaque topology structure 932 * 933 * Embeds backend interface and topology 934 */ 935 typedef struct RTT_TOPOLOGY_T RTT_TOPOLOGY; 936 937 938 /******************************************************************* 939 * 940 * Non-ISO signatures here 941 * 942 *******************************************************************/ 943 944 /** 945 * Initializes a new topology 946 * 947 * @param iface the backend interface handler (see rtt_CreateBackendIface) 948 * @param name name of the new topology 949 * @param srid the topology SRID 950 * @param prec the topology precision/tolerance 951 * @param hasz non-zero if topology primitives should have a Z ordinate 952 * 953 * @return the handler of the topology, or NULL on error 954 * (librtgeom error handler will be invoked with error message) 955 */ 956 RTT_TOPOLOGY *rtt_CreateTopology(RTT_BE_IFACE *iface, const char *name, 957 int srid, double prec, int hasz); 958 959 /** 960 * Loads an existing topology by name from the database 961 * 962 * @param iface the backend interface handler (see rtt_CreateBackendIface) 963 * @param name name of the topology to load 964 * 965 * @return the handler of the topology, or NULL on error 966 * (librtgeom error handler will be invoked with error message) 967 */ 968 RTT_TOPOLOGY *rtt_LoadTopology(RTT_BE_IFACE *iface, const char *name); 969 970 /** 971 * Drop a topology and all its associated objects from the database 972 * 973 * @param topo the topology to drop 974 */ 975 void rtt_DropTopology(RTT_TOPOLOGY* topo); 976 977 /** Release memory associated with an RTT_TOPOLOGY 978 * 979 * @param topo the topology to release (it's not removed from db) 980 */ 981 void rtt_FreeTopology(RTT_TOPOLOGY* topo); 982 983 /** 984 * Retrieve the id of a node at a point location 985 * 986 * @param topo the topology to operate on 987 * @param point the point to use for query 988 * @param tol max distance around the given point to look for a node 989 * @return a node identifier if one is found, 0 if none is found, -1 990 * on error (multiple nodes within distance). 991 * The librtgeom error handler will be invoked in case of error. 992 */ 993 RTT_ELEMID rtt_GetNodeByPoint(RTT_TOPOLOGY *topo, RTPOINT *pt, double tol); 994 995 /** 996 * Find the edge-id of an edge that intersects a given point 997 * 998 * @param topo the topology to operate on 999 * @param point the point to use for query 1000 * @param tol max distance around the given point to look for an 1001 * intersecting edge 1002 * @return an edge identifier if one is found, 0 if none is found, -1 1003 * on error (multiple edges within distance). 1004 * The librtgeom error handler will be invoked in case of error. 1005 */ 1006 RTT_ELEMID rtt_GetEdgeByPoint(RTT_TOPOLOGY *topo, RTPOINT *pt, double tol); 1007 1008 /** 1009 * Find the face-id of a face containing a given point 1010 * 1011 * @param topo the topology to operate on 1012 * @param point the point to use for query 1013 * @param tol max distance around the given point to look for a 1014 * containing face 1015 * @return a face identifier if one is found (0 if universe), -1 1016 * on error (multiple faces within distance or point on node 1017 * or edge). 1018 * The librtgeom error handler will be invoked in case of error. 1019 */ 1020 RTT_ELEMID rtt_GetFaceByPoint(RTT_TOPOLOGY *topo, RTPOINT *pt, double tol); 1021 1022 1023 /******************************************************************* 1024 * 1025 * Topology population (non-ISO) 1026 * 1027 *******************************************************************/ 1028 1029 /** 1030 * Adds a point to the topology 1031 * 1032 * The given point will snap to existing nodes or edges within given 1033 * tolerance. An existing edge may be split by the point. 1034 * 1035 * @param topo the topology to operate on 1036 * @param point the point to add 1037 * @param tol snap tolerance, the topology tolerance will be used if -1 1038 * 1039 * @return identifier of added (or pre-existing) node or -1 on error 1040 * (librtgeom error handler will be invoked with error message) 1041 */ 1042 RTT_ELEMID rtt_AddPoint(RTT_TOPOLOGY* topo, RTPOINT* point, double tol); 1043 1044 /** 1045 * Adds a linestring to the topology 1046 * 1047 * The given line will snap to existing nodes or edges within given 1048 * tolerance. Existing edges or faces may be split by the line. 1049 * 1050 * @param topo the topology to operate on 1051 * @param line the line to add 1052 * @param tol snap tolerance, the topology tolerance will be used if -1 1053 * @param nedges output parameter, will be set to number of edges the 1054 * line was split into, or -1 on error 1055 * (librtgeom error handler will be invoked with error message) 1056 * 1057 * @return an array of <nedges> edge identifiers that sewed togheter 1058 * will build up the input linestring (after snapping). Caller 1059 * will need to free the array using rtfree(const RTCTX *ctx), 1060 * if not null. 1061 */ 1062 RTT_ELEMID* rtt_AddLine(RTT_TOPOLOGY* topo, RTLINE* line, double tol, 1063 int* nedges); 1064 1065 /** 1066 * Adds a linestring to the topology without determining generated faces 1067 * 1068 * The given line will snap to existing nodes or edges within given 1069 * tolerance. Existing edges or faces may be split by the line. 1070 * Side faces for the new edges will not be determined and no new 1071 * faces will be created, effectively leaving the topology in an 1072 * invalid state (WARNING!) 1073 * 1074 * @param topo the topology to operate on 1075 * @param line the line to add 1076 * @param tol snap tolerance, the topology tolerance will be used if -1 1077 * @param nedges output parameter, will be set to number of edges the 1078 * line was split into, or -1 on error 1079 * (librtgeom error handler will be invoked with error message) 1080 * 1081 * @return an array of <nedges> edge identifiers that sewed togheter 1082 * will build up the input linestring (after snapping). Caller 1083 * will need to free the array using rtfree(const RTCTX *ctx), 1084 * if not null. 1085 */ 1086 RTT_ELEMID* rtt_AddLineNoFace(RTT_TOPOLOGY* topo, RTLINE* line, double tol, 1087 int* nedges); 1088 1089 /** 1090 * Determine and register all topology faces: 1091 * 1092 * - Determines which faces are generated by existing 1093 * edges. 1094 * - Creates face records with correct mbr 1095 * - Update edge left/right face attributes 1096 * 1097 * Precondition: 1098 * - the topology edges are correctly linked 1099 * 1100 * Postconditions: 1101 * - all left/right face attributes of edges 1102 * reference faces with correct mbr. 1103 * 1104 * Notes: 1105 * - does not attempt to assign isolated nodes to their 1106 * containing faces 1107 * - does not remove existing face records 1108 * - loads in memory all the topology edges 1109 * 1110 * @param topo the topology to operate on 1111 * 1112 * @return 0 on success, -1 on error 1113 * (librtgeom error handler will be invoked with error message) 1114 */ 1115 int rtt_Polygonize(RTT_TOPOLOGY* topo); 1116 1117 /** 1118 * Adds a polygon to the topology 1119 * 1120 * The boundary of the given polygon will snap to existing nodes or 1121 * edges within given tolerance. 1122 * Existing edges or faces may be split by the boundary of the polygon. 1123 * 1124 * @param topo the topology to operate on 1125 * @param poly the polygon to add 1126 * @param tol snap tolerance, the topology tolerance will be used if -1 1127 * @param nfaces output parameter, will be set to number of faces the 1128 * polygon was split into, or -1 on error 1129 * (librtgeom error handler will be invoked with error message) 1130 * 1131 * @return an array of <nfaces> face identifiers that sewed togheter 1132 * will build up the input polygon (after snapping). Caller 1133 * will need to free the array using rtfree(const RTCTX *ctx), 1134 * if not null. 1135 */ 1136 RTT_ELEMID* rtt_AddPolygon(RTT_TOPOLOGY* topo, RTPOLY* poly, double tol, 1137 int* nfaces); 1138 1139 /******************************************************************* 1140 * 1141 * ISO signatures here 1142 * 1143 *******************************************************************/ 1144 1145 /** 1146 * Populate an empty topology with data from a simple geometry 1147 * 1148 * For ST_CreateTopoGeo 1149 * 1150 * @param topo the topology to operate on 1151 * @param geom the geometry to import 1152 * 1153 */ 1154 void rtt_CreateTopoGeo(RTT_TOPOLOGY* topo, RTGEOM *geom); 1155 1156 /** 1157 * Add an isolated node 1158 * 1159 * For ST_AddIsoNode 1160 * 1161 * @param topo the topology to operate on 1162 * @param face the identifier of containing face or -1 for "unknown" 1163 * @param pt the node position 1164 * @param skipChecks if non-zero skips consistency checks 1165 * (coincident nodes, crossing edges, 1166 * actual face containement) 1167 * 1168 * @return ID of the newly added node, or -1 on error 1169 * (librtgeom error handler will be invoked with error message) 1170 * 1171 */ 1172 RTT_ELEMID rtt_AddIsoNode(RTT_TOPOLOGY* topo, RTT_ELEMID face, 1173 RTPOINT* pt, int skipChecks); 1174 1175 /** 1176 * Move an isolated node 1177 * 1178 * For ST_MoveIsoNode 1179 * 1180 * @param topo the topology to operate on 1181 * @param node the identifier of the nod to be moved 1182 * @param pt the new node position 1183 * @return 0 on success, -1 on error 1184 * (librtgeom error handler will be invoked with error message) 1185 * 1186 */ 1187 int rtt_MoveIsoNode(RTT_TOPOLOGY* topo, 1188 RTT_ELEMID node, RTPOINT* pt); 1189 1190 /** 1191 * Remove an isolated node 1192 * 1193 * For ST_RemoveIsoNode 1194 * 1195 * @param topo the topology to operate on 1196 * @param node the identifier of the node to be moved 1197 * @return 0 on success, -1 on error 1198 * (librtgeom error handler will be invoked with error message) 1199 * 1200 */ 1201 int rtt_RemoveIsoNode(RTT_TOPOLOGY* topo, RTT_ELEMID node); 1202 1203 /** 1204 * Remove an isolated edge 1205 * 1206 * For ST_RemIsoEdge 1207 * 1208 * @param topo the topology to operate on 1209 * @param edge the identifier of the edge to be moved 1210 * @return 0 on success, -1 on error 1211 * (librtgeom error handler will be invoked with error message) 1212 * 1213 */ 1214 int rtt_RemIsoEdge(RTT_TOPOLOGY* topo, RTT_ELEMID edge); 1215 1216 /** 1217 * Add an isolated edge connecting two existing isolated nodes 1218 * 1219 * For ST_AddIsoEdge 1220 * 1221 * @param topo the topology to operate on 1222 * @param start_node identifier of the starting node 1223 * @param end_node identifier of the ending node 1224 * @param geom the edge geometry 1225 * @return ID of the newly added edge, or -1 on error 1226 * (librtgeom error handler will be invoked with error message) 1227 * 1228 */ 1229 RTT_ELEMID rtt_AddIsoEdge(RTT_TOPOLOGY* topo, 1230 RTT_ELEMID startNode, RTT_ELEMID endNode, 1231 const RTLINE *geom); 1232 1233 /** 1234 * Add a new edge possibly splitting a face (modifying it) 1235 * 1236 * For ST_AddEdgeModFace 1237 * 1238 * If the new edge splits a face, the face is shrinked and a new one 1239 * is created. Unless the face being split is the Universal Face, the 1240 * new face will be on the right side of the newly added edge. 1241 * 1242 * @param topo the topology to operate on 1243 * @param start_node identifier of the starting node 1244 * @param end_node identifier of the ending node 1245 * @param geom the edge geometry 1246 * @param skipChecks if non-zero skips consistency checks 1247 * (curve being simple and valid, start/end nodes 1248 * consistency actual face containement) 1249 * 1250 * @return ID of the newly added edge or null on error 1251 * (librtgeom error handler will be invoked with error message) 1252 * 1253 */ 1254 RTT_ELEMID rtt_AddEdgeModFace(RTT_TOPOLOGY* topo, 1255 RTT_ELEMID start_node, RTT_ELEMID end_node, 1256 RTLINE *geom, int skipChecks); 1257 1258 /** 1259 * Add a new edge possibly splitting a face (replacing with two new faces) 1260 * 1261 * For ST_AddEdgeNewFaces 1262 * 1263 * If the new edge splits a face, the face is replaced by two new faces. 1264 * 1265 * @param topo the topology to operate on 1266 * @param start_node identifier of the starting node 1267 * @param end_node identifier of the ending node 1268 * @param geom the edge geometry 1269 * @param skipChecks if non-zero skips consistency checks 1270 * (curve being simple and valid, start/end nodes 1271 * consistency actual face containement) 1272 * @return ID of the newly added edge 1273 * 1274 */ 1275 RTT_ELEMID rtt_AddEdgeNewFaces(RTT_TOPOLOGY* topo, 1276 RTT_ELEMID start_node, RTT_ELEMID end_node, 1277 RTLINE *geom, int skipChecks); 1278 1279 /** 1280 * Remove an edge, possibly merging two faces (replacing both with a new one) 1281 * 1282 * For ST_RemEdgeNewFace 1283 * 1284 * @param topo the topology to operate on 1285 * @param edge identifier of the edge to be removed 1286 * @return the id of newly created face, 0 if no new face was created 1287 * or -1 on error 1288 * 1289 */ 1290 RTT_ELEMID rtt_RemEdgeNewFace(RTT_TOPOLOGY* topo, RTT_ELEMID edge); 1291 1292 /** 1293 * Remove an edge, possibly merging two faces (replacing one with the other) 1294 * 1295 * For ST_RemEdgeModFace 1296 * 1297 * Preferentially keep the face on the right, to be symmetric with 1298 * rtt_AddEdgeModFace. 1299 * 1300 * @param topo the topology to operate on 1301 * @param edge identifier of the edge to be removed 1302 * @return the id of the face that takes the space previously occupied 1303 * by the removed edge, or -1 on error 1304 * (librtgeom error handler will be invoked with error message) 1305 * 1306 */ 1307 RTT_ELEMID rtt_RemEdgeModFace(RTT_TOPOLOGY* topo, RTT_ELEMID edge); 1308 1309 /** 1310 * Changes the shape of an edge without affecting the topology structure. 1311 * 1312 * For ST_ChangeEdgeGeom 1313 * 1314 * @param topo the topology to operate on 1315 * @param curve the edge geometry 1316 * @return 0 on success, -1 on error 1317 * (librtgeom error handler will be invoked with error message) 1318 * 1319 */ 1320 int rtt_ChangeEdgeGeom(RTT_TOPOLOGY* topo, RTT_ELEMID edge, RTLINE* curve); 1321 1322 /** 1323 * Split an edge by a node, modifying the original edge and adding a new one. 1324 * 1325 * For ST_ModEdgeSplit 1326 * 1327 * @param topo the topology to operate on 1328 * @param edge identifier of the edge to be split 1329 * @param pt geometry of the new node 1330 * @param skipChecks if non-zero skips consistency checks 1331 * (coincident node, point not on edge...) 1332 * @return the id of newly created node, or -1 on error 1333 * (librtgeom error handler will be invoked with error message) 1334 * 1335 */ 1336 RTT_ELEMID rtt_ModEdgeSplit(RTT_TOPOLOGY* topo, RTT_ELEMID edge, 1337 RTPOINT* pt, int skipChecks); 1338 1339 /** 1340 * Split an edge by a node, replacing it with two new edges 1341 * 1342 * For ST_NewEdgesSplit 1343 * 1344 * @param topo the topology to operate on 1345 * @param edge identifier of the edge to be split 1346 * @param pt geometry of the new node 1347 * @param skipChecks if non-zero skips consistency checks 1348 * (coincident node, point not on edge...) 1349 * @return the id of newly created node 1350 * 1351 */ 1352 RTT_ELEMID rtt_NewEdgesSplit(RTT_TOPOLOGY* topo, RTT_ELEMID edge, 1353 RTPOINT* pt, int skipChecks); 1354 1355 /** 1356 * Merge two edges, modifying the first and deleting the second 1357 * 1358 * For ST_ModEdgeHeal 1359 * 1360 * @param topo the topology to operate on 1361 * @param e1 identifier of first edge 1362 * @param e2 identifier of second edge 1363 * @return the id of the removed node or -1 on error 1364 * (librtgeom error handler will be invoked with error message) 1365 * 1366 */ 1367 RTT_ELEMID rtt_ModEdgeHeal(RTT_TOPOLOGY* topo, RTT_ELEMID e1, RTT_ELEMID e2); 1368 1369 /** 1370 * Merge two edges, replacing both with a new one 1371 * 1372 * For ST_NewEdgeHeal 1373 * 1374 * @param topo the topology to operate on 1375 * @param e1 identifier of first edge 1376 * @param e2 identifier of second edge 1377 * @return the id of the new edge or -1 on error 1378 * (librtgeom error handler will be invoked with error message) 1379 * 1380 */ 1381 RTT_ELEMID rtt_NewEdgeHeal(RTT_TOPOLOGY* topo, RTT_ELEMID e1, RTT_ELEMID e2); 1382 1383 /** 1384 * Return the list of directed edges bounding a face 1385 * 1386 * For ST_GetFaceEdges 1387 * 1388 * @param topo the topology to operate on 1389 * @param face identifier of the face 1390 * @param edges will be set to an array of signed edge identifiers, will 1391 * need to be released with rtfree 1392 * @return the number of edges in the edges array, or -1 on error 1393 * (librtgeom error handler will be invoked with error message) 1394 * 1395 */ 1396 int rtt_GetFaceEdges(RTT_TOPOLOGY* topo, RTT_ELEMID face, RTT_ELEMID **edges); 1397 1398 /** 1399 * Return the geometry of a face 1400 * 1401 * For ST_GetFaceGeometry 1402 * 1403 * @param topo the topology to operate on 1404 * @param face identifier of the face 1405 * @return a polygon geometry representing the face, ownership to caller, 1406 * to be released with rtgeom_release, or NULL on error 1407 * (librtgeom error handler will be invoked with error message) 1408 */ 1409 RTGEOM* rtt_GetFaceGeometry(RTT_TOPOLOGY* topo, RTT_ELEMID face); 1410 1411 /******************************************************************* 1412 * 1413 * Utility functions 1414 * 1415 *******************************************************************/ 1416 1417 1418 /* 1419 * rtt_tpsnap - snap geometry to topology 1420 * 1421 * Uses Trevisani-Peri algorithm version 13 as reported here: 1422 * https://git.osgeo.org/gitea/rttopo/librttopo/wiki/SnapToTopo-algorithm 1423 * 1424 * @param topo the reference topology 1425 * @param gin the input geometry 1426 * @param tolerance_snap snap tolerance 1427 * @param tolerance_removal removal tolerance (use -1 to skip removal phase) 1428 * @param iterate if non zero, allows snapping to more than a single vertex, 1429 * iteratively 1430 * 1431 * @return a new geometry, or NULL on error 1432 * 1433 */ 1434 RTGEOM* rtt_tpsnap(RTT_TOPOLOGY *topo, const RTGEOM *gin, 1435 double tolerance_snap, 1436 double tolerance_removal, 1437 int iterate); 1438 1439 #endif /* LIBRTGEOM_TOPO_H */ 1440