@@ -457,6 +457,243 @@ QgsPoint QgsGeometry::closestVertex(const QgsPoint& point, QgsGeometryVertexInde
457
457
}
458
458
459
459
460
+ void QgsGeometry::adjacentVerticies (const QgsGeometryVertexIndex& atVertex, int & beforeVertex, int & afterVertex) const
461
+ {
462
+ if (mDirtyWkb )
463
+ {
464
+ exportGeosToWkb ();
465
+ }
466
+
467
+ beforeVertex = -1 ;
468
+ afterVertex = -1 ;
469
+
470
+ if (mGeometry )
471
+ {
472
+ int vertexcounter = 0 ;
473
+
474
+ int wkbType;
475
+
476
+ memcpy (&wkbType, (mGeometry +1 ), sizeof (int ));
477
+
478
+ switch (wkbType)
479
+ {
480
+ case QGis::WKBPoint:
481
+ {
482
+ // NOOP - Points do not have adjacent verticies
483
+ break ;
484
+ }
485
+
486
+ case QGis::WKBLineString:
487
+ {
488
+ unsigned char * ptr = mGeometry +5 ;
489
+ int * npoints = (int *) ptr;
490
+
491
+ const int index = atVertex.back ();
492
+
493
+ // assign the rubber band indices
494
+
495
+ if (index == 0 )
496
+ {
497
+ beforeVertex = -1 ;
498
+ }
499
+ else
500
+ {
501
+ beforeVertex = index -1 ;
502
+ }
503
+
504
+ if (index == (*npoints - 1 ))
505
+ {
506
+ afterVertex = -1 ;
507
+ }
508
+ else
509
+ {
510
+ afterVertex = index +1 ;
511
+ }
512
+
513
+ break ;
514
+ }
515
+ case QGis::WKBPolygon:
516
+ {
517
+ int * nrings=(int *)(mGeometry +5 );
518
+ int * npoints;
519
+ unsigned char * ptr=mGeometry +9 ;
520
+
521
+ // Walk through the POLYGON WKB
522
+
523
+ for (int index0 = 0 ; index0 < *nrings; ++index0)
524
+ {
525
+ npoints=(int *)ptr;
526
+ ptr+=sizeof (int );
527
+
528
+ for (int index1 = 0 ; index1 < *npoints; ++index1)
529
+ {
530
+ ptr += sizeof (double );
531
+ ptr += sizeof (double );
532
+
533
+ if (vertexcounter == atVertex.back ())
534
+ // TODO: The above is deprecated as it doesn't allow for multiple linear rings in the polygon.
535
+ // replace with the below when the rest of QgsGeometry is migrated to a GEOS back-end.
536
+ // if (
537
+ // (index0 == atVertex.get_at(0)) &&
538
+ // (index1 == atVertex.get_at(1))
539
+ // )
540
+ {
541
+ // Found the vertex of the linear-ring we were looking for.
542
+
543
+ // assign the rubber band indices
544
+
545
+ if (index1 == 0 )
546
+ {
547
+ beforeVertex = vertexcounter+(*npoints-2 );
548
+ afterVertex = vertexcounter+1 ;
549
+ }
550
+ else if (index1 == (*npoints-1 ))
551
+ {
552
+ beforeVertex = vertexcounter-1 ;
553
+ afterVertex = vertexcounter - (*npoints-2 );
554
+ }
555
+ else
556
+ {
557
+ beforeVertex = vertexcounter-1 ;
558
+ afterVertex = vertexcounter+1 ;
559
+ }
560
+ }
561
+
562
+ ++vertexcounter;
563
+ }
564
+ }
565
+ break ;
566
+ }
567
+
568
+ case QGis::WKBMultiPoint:
569
+ {
570
+ // NOOP - Points do not have adjacent verticies
571
+ break ;
572
+ }
573
+
574
+ case QGis::WKBMultiLineString:
575
+ {
576
+ unsigned char * ptr=mGeometry +5 ;
577
+ int * nlines=(int *)ptr;
578
+ int * npoints = 0 ;
579
+ ptr+=sizeof (int );
580
+
581
+ for (int index0 = 0 ; index0 < *nlines; ++index0)
582
+ {
583
+ ptr += (sizeof (int ) + 1 );
584
+ npoints = (int *)ptr;
585
+ ptr += sizeof (int );
586
+
587
+ for (int index1 = 0 ; index1 < *npoints; ++index1)
588
+ {
589
+ ptr+=sizeof (double );
590
+ ptr+=sizeof (double );
591
+
592
+ if (vertexcounter == atVertex.back ())
593
+ // TODO: The above is deprecated as it doesn't allow for account for all ends of lines.
594
+ // replace with the below when the rest of QgsGeometry is migrated to a GEOS back-end.
595
+ // if (
596
+ // (index0 == atVertex.get_at(0)) &&
597
+ // (index1 == atVertex.get_at(1))
598
+ // )
599
+ {
600
+ // Found the vertex of the linestring we were looking for.
601
+
602
+ // assign the rubber band indices
603
+
604
+ if (index1 == 0 )
605
+ {
606
+ beforeVertex = -1 ;
607
+ }
608
+ else
609
+ {
610
+ beforeVertex = vertexcounter-1 ;
611
+ }
612
+ if (index1 == (*npoints)-1 )
613
+ {
614
+ afterVertex = -1 ;
615
+ }
616
+ else
617
+ {
618
+ afterVertex = vertexcounter+1 ;
619
+ }
620
+ }
621
+ ++vertexcounter;
622
+ }
623
+ }
624
+
625
+ break ;
626
+ }
627
+
628
+ case QGis::WKBMultiPolygon:
629
+ {
630
+ unsigned char * ptr=mGeometry +5 ;
631
+ int * npolys=(int *)ptr;
632
+ int * nrings;
633
+ int * npoints;
634
+ ptr+=sizeof (int );
635
+
636
+ for (int index0 = 0 ; index0 < *npolys; ++index0)
637
+ {
638
+ ptr += (1 + sizeof (int )); // skip endian and polygon type
639
+ nrings=(int *)ptr;
640
+ ptr+=sizeof (int );
641
+
642
+ for (int index1 = 0 ; index1 < *nrings; ++index1)
643
+ {
644
+ npoints=(int *)ptr;
645
+ ptr+=sizeof (int );
646
+
647
+ for (int index2 = 0 ; index2 < *npoints; ++index2)
648
+ {
649
+ ptr += sizeof (double );
650
+ ptr += sizeof (double );
651
+
652
+ if (vertexcounter == atVertex.back ())
653
+ // TODO: The above is deprecated as it doesn't allow for multiple linear rings in the polygon.
654
+ // replace with the below when the rest of QgsGeometry is migrated to a GEOS back-end.
655
+ // if (
656
+ // (index0 == atVertex.get_at(0)) &&
657
+ // (index1 == atVertex.get_at(1)) &&
658
+ // (index2 == atVertex.get_at(2))
659
+ // )
660
+ {
661
+ // Found the vertex of the linear-ring of the polygon we were looking for.
662
+
663
+ // assign the rubber band indices
664
+
665
+ if (index2 == 0 )
666
+ {
667
+ beforeVertex = vertexcounter+(*npoints-2 );
668
+ afterVertex = vertexcounter+1 ;
669
+ }
670
+ else if (index2 == (*npoints-1 ))
671
+ {
672
+ beforeVertex = vertexcounter-1 ;
673
+ afterVertex = vertexcounter - (*npoints-2 );
674
+ }
675
+ else
676
+ {
677
+ beforeVertex = vertexcounter-1 ;
678
+ afterVertex = vertexcounter+1 ;
679
+ }
680
+ }
681
+ ++vertexcounter;
682
+ }
683
+ }
684
+ }
685
+
686
+ break ;
687
+ }
688
+
689
+ default :
690
+ break ;
691
+ } // switch (wkbType)
692
+
693
+ } // if (mGeometry)
694
+ }
695
+
696
+
460
697
461
698
bool QgsGeometry::insertVertexBefore (double x, double y,
462
699
int beforeVertex,
0 commit comments