@@ -557,12 +557,66 @@ bool QgsGeometry::moveVertexAt(double x, double y,
557
557
<< " ." << std::endl;
558
558
#endif
559
559
560
- // Do just-in-time conversion to GEOS
561
- // TODO: This should be more of a "import to GEOS" since GEOS will be the home geometry.
562
560
exportWkbToGeos ();
563
561
564
562
if (mGeos )
565
563
{
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
566
620
switch (mGeos->getGeometryTypeId())
567
621
{
568
622
case geos::GEOS_POINT: // a point
@@ -630,7 +684,7 @@ bool QgsGeometry::moveVertexAt(double x, double y,
630
684
} // case geos::GEOS_GEOMETRYCOLLECTION
631
685
632
686
} // switch (mGeos->getGeometryTypeId())
633
-
687
+ # endif // 0
634
688
} // if (mGeos)
635
689
636
690
return FALSE ;
@@ -908,6 +962,21 @@ QgsPoint QgsGeometry::closestVertexWithContext(QgsPoint& point,
908
962
909
963
if (mGeos )
910
964
{
965
+ geos::CoordinateSequence* sequence = mGeos ->getCoordinates ();
966
+ if (sequence)
967
+ {
968
+ for (int i = 0 ; i < sequence->getSize (); ++i)
969
+ {
970
+ double testDist = point.sqrDist (sequence->getAt (i).x , sequence->getAt (i).y );
971
+ if (testDist < sqrDist)
972
+ {
973
+ closestVertexIndex = i;
974
+ sqrDist = testDist;
975
+ }
976
+ }
977
+ }
978
+ atVertex.push_back (closestVertexIndex);
979
+ #if 0
911
980
switch (mGeos->getGeometryTypeId())
912
981
{
913
982
case geos::GEOS_POINT: // a point
@@ -957,7 +1026,20 @@ QgsPoint QgsGeometry::closestVertexWithContext(QgsPoint& point,
957
1026
958
1027
case geos::GEOS_POLYGON: // a polygon
959
1028
{
960
- // TODO
1029
+ geos::CoordinateSequence* sequence = mGeos->getCoordinates();
1030
+ if(sequence)
1031
+ {
1032
+ for(int i = 0; i < sequence->getSize(); ++i)
1033
+ {
1034
+ double testDist = point.sqrDist(sequence->getAt(i).x, sequence->getAt(i).y);
1035
+ if(testDist < sqrDist)
1036
+ {
1037
+ closestVertexIndex = i;
1038
+ sqrDist = testDist;
1039
+ }
1040
+ }
1041
+ }
1042
+ atVertex.push_back(closestVertexIndex);
961
1043
break;
962
1044
} // case geos::GEOS_POLYGON
963
1045
@@ -985,7 +1067,7 @@ QgsPoint QgsGeometry::closestVertexWithContext(QgsPoint& point,
985
1067
break;
986
1068
} // case geos::GEOS_GEOMETRYCOLLECTION
987
1069
}
988
-
1070
+ # endif
989
1071
} // if (mGeos)
990
1072
991
1073
return minDistPoint;
@@ -1850,10 +1932,6 @@ bool QgsGeometry::exportWkbToGeos() const
1850
1932
bool QgsGeometry::exportGeosToWkb () const
1851
1933
// TODO: Make this work
1852
1934
{
1853
- #ifdef QGISDEBUG
1854
- std::cout << " QgsGeometry::exportGeosToWkb: entered." << std::endl;
1855
- #endif
1856
-
1857
1935
if (!mDirtyWkb )
1858
1936
{
1859
1937
// No need to convert again
@@ -1876,11 +1954,6 @@ bool QgsGeometry::exportGeosToWkb() const
1876
1954
// set up byteOrder
1877
1955
char byteOrder = 1 ; // TODO
1878
1956
1879
- #ifdef QGISDEBUG
1880
- std::cout << " QgsGeometry::exportGeosToWkb: Testing mGeos->getGeometryTypeId() = '"
1881
- << mGeos ->getGeometryTypeId () << " '." << std::endl;
1882
- #endif
1883
-
1884
1957
switch (mGeos ->getGeometryTypeId ())
1885
1958
{
1886
1959
case geos::GEOS_POINT: // a point
@@ -1943,10 +2016,9 @@ bool QgsGeometry::exportGeosToWkb() const
1943
2016
}
1944
2017
1945
2018
mDirtyWkb = FALSE ;
2019
+ return true ;
1946
2020
1947
2021
// TODO: Deal with endian-ness
1948
-
1949
- break ;
1950
2022
} // case geos::GEOS_LINESTRING
1951
2023
1952
2024
case geos::GEOS_LINEARRING: // a linear ring (linestring with 1st point == last point)
@@ -1957,7 +2029,96 @@ bool QgsGeometry::exportGeosToWkb() const
1957
2029
1958
2030
case geos::GEOS_POLYGON: // a polygon
1959
2031
{
1960
- // TODO
2032
+ int geometrySize;
2033
+ double x, y; // point coordinates
2034
+ geos::Polygon* thePolygon = dynamic_cast <geos::Polygon*>(mGeos );
2035
+ const geos::LineString* theRing = 0 ;
2036
+ int nPointsInRing = 0 ;
2037
+
2038
+ if (thePolygon)
2039
+ {
2040
+ // first calculate the geometry size
2041
+ geometrySize = 1 + 2 *sizeof (int ); // endian, type, number of rings
2042
+ theRing = thePolygon->getExteriorRing ();
2043
+ if (theRing)
2044
+ {
2045
+ geometrySize += sizeof (int );
2046
+ geometrySize += theRing->getNumPoints ()*2 *sizeof (double );
2047
+ }
2048
+ for (int i = 0 ; i < thePolygon->getNumInteriorRing (); ++i)
2049
+ {
2050
+ geometrySize += sizeof (int ); // number of points in ring
2051
+ theRing = thePolygon->getInteriorRingN (i);
2052
+ if (theRing)
2053
+ {
2054
+ geometrySize += theRing->getNumPoints ()*2 *sizeof (double );
2055
+ }
2056
+ }
2057
+
2058
+ mGeometry = new unsigned char [geometrySize];
2059
+
2060
+ // then fill the geometry itself into the wkb
2061
+ int position = 0 ;
2062
+ // assign byteOrder
2063
+ memcpy (mGeometry , &byteOrder, 1 );
2064
+ position += 1 ;
2065
+ // endian flag must be added by QgsVectorLayer
2066
+ int wkbtype=QGis::WKBPolygon;
2067
+ memcpy (&mGeometry [position],&wkbtype, sizeof (int ));
2068
+ position += sizeof (int );
2069
+ int nRings = thePolygon->getNumInteriorRing ()+1 ;
2070
+ memcpy (&mGeometry [position], &nRings, sizeof (int ));
2071
+ position += sizeof (int );
2072
+
2073
+ // exterior ring first
2074
+ theRing = thePolygon->getExteriorRing ();
2075
+ if (theRing)
2076
+ {
2077
+ nPointsInRing = theRing->getNumPoints ();
2078
+ memcpy (&mGeometry [position], &nPointsInRing, sizeof (int ));
2079
+ position += sizeof (int );
2080
+ const geos::CoordinateSequence* ringSequence = theRing->getCoordinatesRO ();
2081
+ // for(int j = 0; j < nPointsInRing; ++j)
2082
+ for (int j = 0 ; j <ringSequence->getSize (); ++j)
2083
+ {
2084
+ // x = theRing->getPointN(j)->getX();
2085
+ x = ringSequence->getAt (j).x ;
2086
+ memcpy (&mGeometry [position], &x, sizeof (double ));
2087
+ position += sizeof (double );
2088
+ // y = theRing->getPointN(j)->getY();
2089
+ y = ringSequence->getAt (j).y ;
2090
+ memcpy (&mGeometry [position], &y, sizeof (double ));
2091
+ position += sizeof (double );
2092
+ }
2093
+ }
2094
+
2095
+ // interior rings after
2096
+ for (int i = 0 ; i < thePolygon->getNumInteriorRing (); ++i)
2097
+ {
2098
+ theRing = thePolygon->getInteriorRingN (i);
2099
+ if (theRing)
2100
+ {
2101
+ nPointsInRing = theRing->getNumPoints ();
2102
+ memcpy (&mGeometry [position], &nPointsInRing, sizeof (int ));
2103
+ position += sizeof (int );
2104
+ for (int j = 0 ; j < nPointsInRing; ++j)
2105
+ {
2106
+ x = theRing->getPointN (j)->getX ();
2107
+ memcpy (&mGeometry [position], &x, sizeof (double ));
2108
+ position += sizeof (double );
2109
+ y = theRing->getPointN (j)->getY ();
2110
+ memcpy (&mGeometry [position], &y, sizeof (double ));
2111
+ position += sizeof (double );
2112
+ }
2113
+ }
2114
+ }
2115
+ mDirtyWkb = FALSE ;
2116
+ return true ;
2117
+ }
2118
+ else
2119
+ {
2120
+ // error
2121
+ }
1961
2122
break ;
1962
2123
} // case geos::GEOS_POLYGON
1963
2124
0 commit comments