@@ -507,188 +507,43 @@ bool QgsGeometry::insertVertexBefore(double x, double y,
507
507
508
508
}
509
509
510
-
511
- bool QgsGeometry::moveVertexAt (double x, double y,
512
- int atVertex,
513
- const geos::CoordinateSequence* old_sequence,
514
- geos::CoordinateSequence** new_sequence)
515
- {
516
- int numPoints = old_sequence->getSize ();
517
-
518
- // Bounds checking
519
- if (
520
- (atVertex < 0 ) ||
521
- (atVertex >= numPoints)
522
- )
523
- {
524
- (*new_sequence) = 0 ;
525
- return FALSE ;
526
- }
527
-
528
- // Copy to the new sequence, including the moved vertex
529
- (*new_sequence) = new geos::DefaultCoordinateSequence ();
530
-
531
- for (int i = 0 ; i < numPoints; i++)
532
- {
533
- // Do we move the vertex here?
534
- if (atVertex == i)
535
- {
536
- (*new_sequence)->add ( geos::Coordinate (x, y) );
537
- }
538
- else
539
- {
540
- (*new_sequence)->add ( old_sequence->getAt (i) );
541
- }
542
- }
543
- // TODO: Check that the sequence is still simple, e.g. with geos::Geometry->isSimple()
544
- return true ;
545
- }
546
-
547
-
548
510
bool QgsGeometry::moveVertexAt (double x, double y,
549
511
QgsGeometryVertexIndex atVertex)
550
512
{
551
-
552
- #ifdef QGISDEBUG
553
- std::cout << " QgsGeometry::moveVertexAt: Entered with "
554
- << " x " << x << " , y " << y
555
- // << "beforeVertex " << beforeVertex << ", atRing " << atRing << ", atItem"
556
- // << " " << atItem
557
- << " ." << std::endl;
558
- #endif
559
-
560
513
exportWkbToGeos ();
561
-
562
514
if (mGeos )
563
515
{
564
- geos::CoordinateSequence* old_sequence = mGeos ->getCoordinates ();
565
- geos::CoordinateSequence* new_sequence;
566
- if (moveVertexAt (x, y, atVertex.back (), old_sequence, &new_sequence))
567
- {
568
- switch (mGeos ->getGeometryTypeId ())
569
- {
570
- case geos::GEOS_POINT:
571
- {
572
- delete new_sequence;
573
- return false ;
574
- }
575
- case geos::GEOS_LINESTRING:
576
- {
577
- setGeos ( static_cast <geos::Geometry*>( geosGeometryFactory->createLineString (new_sequence) ) );
578
- break ;
579
- }
580
- case geos::GEOS_POLYGON:
581
- {
582
- // make sure the ring is closed if the first/last point is moved
583
- if (atVertex.back () == 0 )
584
- {
585
- new_sequence->setAt (geos::Coordinate (x, y), new_sequence->getSize ()-1 );
586
- }
587
- else if (atVertex.back () == new_sequence->getSize ()-1 )
588
- {
589
- new_sequence->setAt (geos::Coordinate (x, y), 0 );
590
- }
591
- #ifdef QGISDEBUG
592
- for (int i = 0 ; i < new_sequence->getSize (); ++i)
593
- {
594
- qWarning (QString::number (new_sequence->getAt (i).x )+" //" +QString::number (new_sequence->getAt (i).y ));
595
- }
596
- #endif
597
- geos::LinearRing* theRing;
598
- try
599
- {
600
- theRing = geosGeometryFactory->createLinearRing (new_sequence);
601
- }
602
- catch (geos::IllegalArgumentException* e)
603
- {
604
- return false ;
605
- }
606
- std::vector<geos::Geometry*>* holes = new std::vector<geos::Geometry*>(); // no holes
607
- setGeos (static_cast <geos::Geometry*>(geosGeometryFactory->createPolygon (theRing, holes)));
608
- break ;
609
- }
610
- }
611
- delete old_sequence;
612
- mDirtyWkb = true ;
613
- return true ;
614
- }
615
- else
616
- {
617
- return false ;
618
- }
619
- #if 0
620
516
switch (mGeos ->getGeometryTypeId ())
621
517
{
622
- case geos::GEOS_POINT: // a point
623
- {
624
- // Cannot move an arbitrary vertex to a point!
625
- return FALSE;
626
-
627
- } // case geos::GEOS_POINT
628
-
629
- case geos::GEOS_LINESTRING: // a linestring
630
- {
631
- // Get the embedded GEOS Coordinate Sequence
632
- geos::LineString* geosls = static_cast<geos::LineString*>(mGeos);
633
- const geos::CoordinateSequence* old_sequence = geosls->getCoordinatesRO();
634
- geos::CoordinateSequence* new_sequence;
635
-
636
- if ( moveVertexAt(x, y, atVertex.back(), old_sequence, (&new_sequence) ) )
637
- {
638
- // Put in the new GEOS geometry
639
- setGeos( static_cast<geos::Geometry*>( geosGeometryFactory->createLineString(new_sequence) ) );
640
- mDirtyWkb = true;
641
- return TRUE;
642
- }
643
- else
644
- {
645
- return FALSE;
646
- }
647
-
648
- } // case geos::GEOS_LINESTRING
649
-
650
- case geos::GEOS_LINEARRING: // a linear ring (linestring with 1st point == last point)
651
- {
652
- // TODO
653
- break;
654
- } // case geos::GEOS_LINEARRING
655
-
656
- case geos::GEOS_POLYGON: // a polygon
657
- {
658
- // TODO
659
- break;
660
- } // case geos::GEOS_POLYGON
661
-
662
- case geos::GEOS_MULTIPOINT: // a collection of points
518
+ case geos::GEOS_POINT:
663
519
{
664
- // TODO
665
- break;
666
- } // case geos::GEOS_MULTIPOINT
667
-
668
- case geos::GEOS_MULTILINESTRING: // a collection of linestrings
669
- {
670
- // TODO
671
- break;
672
- } // case geos::GEOS_MULTILINESTRING
673
-
674
- case geos::GEOS_MULTIPOLYGON: // a collection of polygons
520
+ return false ;
521
+ }
522
+ case geos::GEOS_LINESTRING:
675
523
{
676
- // TODO
677
- break;
678
- } // case geos::GEOS_MULTIPOLYGON
679
-
680
- case geos::GEOS_GEOMETRYCOLLECTION: // a collection of heterogeneus geometries
524
+ geos::CoordinateSequence* sequence = mGeos ->getCoordinates ();
525
+ sequence->setAt (geos::Coordinate (x, y), atVertex.back ());
526
+ setGeos ( static_cast <geos::Geometry*>( geosGeometryFactory->createLineString (sequence) ) );
527
+ break ;
528
+ }
529
+ case geos::GEOS_POLYGON:
681
530
{
682
- // TODO
683
- break;
684
- } // case geos::GEOS_GEOMETRYCOLLECTION
685
-
686
- } // switch (mGeos->getGeometryTypeId())
687
- #endif // 0
688
- } // if (mGeos)
689
-
690
- return FALSE ;
691
-
531
+ if (moveVertexFromPolygon (atVertex.back (), x, y))
532
+ {
533
+ mDirtyWkb = true ;
534
+ return true ;
535
+ }
536
+ else
537
+ {
538
+ return false ;
539
+ }
540
+ }
541
+ mDirtyWkb = true ;
542
+ return true ;
543
+ }
544
+ }
545
+
546
+ return false ;
692
547
}
693
548
694
549
@@ -2225,4 +2080,140 @@ double QgsGeometry::distanceSquaredPointToSegment(QgsPoint& point,
2225
2080
2226
2081
}
2227
2082
2083
+ bool QgsGeometry::moveVertexFromPolygon (int atVertex, double x, double y)
2084
+ {
2085
+ if (!mGeos )
2086
+ {
2087
+ return false ;
2088
+ }
2228
2089
2090
+ geos::Polygon* originalpoly = dynamic_cast <geos::Polygon*>(mGeos );
2091
+ if (!originalpoly)
2092
+ {
2093
+ return false ;
2094
+ }
2095
+
2096
+ geos::CoordinateSequence* coordinates = originalpoly->getCoordinates ();
2097
+ std::vector<int > rings (originalpoly->getNumInteriorRing () + 1 ); // a vector storing the number of points in each ring
2098
+ // todo: consider that the point to be moved could be the starting point/ end point of a ring
2099
+ const geos::LineString* outerRing = originalpoly->getExteriorRing ();
2100
+ int pointcounter = 0 ;
2101
+
2102
+ if (atVertex == 0 || atVertex == outerRing->getNumPoints ()-1 )
2103
+ {
2104
+ coordinates->setAt (geos::Coordinate (x, y), 0 );
2105
+ coordinates->setAt (geos::Coordinate (x, y), outerRing->getNumPoints ()-1 );
2106
+ }
2107
+ else if (atVertex < outerRing->getNumPoints ())
2108
+ {
2109
+ coordinates->setAt (geos::Coordinate (x, y), atVertex);
2110
+ }
2111
+ rings[0 ] = outerRing->getNumPoints ();
2112
+ pointcounter += outerRing->getNumPoints ();
2113
+
2114
+ for (int i = 0 ; i < originalpoly->getNumInteriorRing (); ++i)
2115
+ {
2116
+ const geos::LineString* innerRing = originalpoly->getInteriorRingN (i);
2117
+ if (atVertex == pointcounter || atVertex== pointcounter + innerRing->getNumPoints ()-1 )
2118
+ {
2119
+ coordinates->setAt (geos::Coordinate (x, y), pointcounter);
2120
+ coordinates->setAt (geos::Coordinate (x, y), pointcounter + innerRing->getNumPoints ()-1 );
2121
+ }
2122
+ else if (atVertex > pointcounter && atVertex < pointcounter + innerRing->getNumPoints ()-1 )
2123
+ {
2124
+ coordinates->setAt (geos::Coordinate (x, y), atVertex);
2125
+ }
2126
+ rings[i+1 ] = innerRing->getNumPoints ();
2127
+ pointcounter += innerRing->getNumPoints ();
2128
+ }
2129
+
2130
+ geos::Polygon* newPolygon = createPolygonFromCoordSequence (coordinates, rings);
2131
+ delete coordinates;
2132
+ if (newPolygon)
2133
+ {
2134
+ delete mGeos ;
2135
+ mGeos = newPolygon;
2136
+ return true ;
2137
+ }
2138
+ else
2139
+ {
2140
+ return false ;
2141
+ }
2142
+ }
2143
+
2144
+ bool QgsGeometry::deleteVertexFromPolygon (int atVertex)
2145
+ {
2146
+ return false ; // soon
2147
+ }
2148
+
2149
+ bool QgsGeometry::insertVertexToPolygon (int beforeVertex, double x, double y)
2150
+ {
2151
+ return false ; // soon
2152
+ }
2153
+
2154
+ geos::Polygon* QgsGeometry::createPolygonFromCoordSequence (const geos::CoordinateSequence* coords, const std::vector<int >& pointsInRings) const
2155
+ {
2156
+
2157
+ geos::CoordinateSequence* outerRingSequence = new geos::DefaultCoordinateSequence ();
2158
+ int pointcounter = 0 ;
2159
+ for (int i = 0 ; i < pointsInRings[0 ]; ++i)
2160
+ {
2161
+ outerRingSequence->add (geos::Coordinate (coords->getAt (pointcounter)));
2162
+ ++pointcounter;
2163
+ }
2164
+ geos::LinearRing* newOuterRing = 0 ;
2165
+ try
2166
+ {
2167
+ newOuterRing = geosGeometryFactory->createLinearRing (outerRingSequence);
2168
+ }
2169
+ catch (geos::IllegalArgumentException* e)
2170
+ {
2171
+ delete outerRingSequence;
2172
+ return 0 ;
2173
+ }
2174
+
2175
+ std::vector<geos::Geometry*>* newInnerRings = new std::vector<geos::Geometry*>(pointsInRings.size ()-1 );
2176
+
2177
+ for (int i = 0 ; i < pointsInRings.size ()-1 ; ++i)
2178
+ {
2179
+ geos::CoordinateSequence* innerRingSequence = new geos::DefaultCoordinateSequence ();
2180
+ for (int j = 0 ; j < pointsInRings[i+1 ]; ++j)
2181
+ {
2182
+ innerRingSequence->add (geos::Coordinate (coords->getAt (pointcounter)));
2183
+ ++pointcounter;
2184
+ }
2185
+ geos::LinearRing* newInnerRing = 0 ;
2186
+ try
2187
+ {
2188
+ newInnerRing = geosGeometryFactory->createLinearRing (innerRingSequence);
2189
+ }
2190
+ catch (geos::IllegalArgumentException* e)
2191
+ {
2192
+ delete outerRingSequence;
2193
+ // also delete the already created rings
2194
+ for (int j = 0 ; j < i; ++j)
2195
+ {
2196
+ delete (*newInnerRings)[i];
2197
+ }
2198
+ return 0 ;
2199
+ }
2200
+ (*newInnerRings)[i] = newInnerRing;
2201
+ }
2202
+
2203
+ geos::Polygon* newPolygon = 0 ;
2204
+ try
2205
+ {
2206
+ newPolygon = geosGeometryFactory->createPolygon (newOuterRing, newInnerRings);
2207
+ }
2208
+ catch (geos::IllegalArgumentException* e)
2209
+ {
2210
+ delete newOuterRing;
2211
+ for (int i = 0 ; i < newInnerRings->size (); ++i)
2212
+ {
2213
+ delete (*newInnerRings)[i];
2214
+ }
2215
+ return 0 ;
2216
+ }
2217
+
2218
+ return newPolygon;
2219
+ }
0 commit comments