Skip to content

Commit 3211776

Browse files

File tree

4 files changed

+188
-22
lines changed

4 files changed

+188
-22
lines changed
 

‎src/core/qgsgeometry.cpp‎

Lines changed: 178 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -557,12 +557,66 @@ bool QgsGeometry::moveVertexAt(double x, double y,
557557
<< "." << std::endl;
558558
#endif
559559

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.
562560
exportWkbToGeos();
563561

564562
if (mGeos)
565563
{
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
566620
switch (mGeos->getGeometryTypeId())
567621
{
568622
case geos::GEOS_POINT: // a point
@@ -630,7 +684,7 @@ bool QgsGeometry::moveVertexAt(double x, double y,
630684
} // case geos::GEOS_GEOMETRYCOLLECTION
631685

632686
} // switch (mGeos->getGeometryTypeId())
633-
687+
#endif //0
634688
} // if (mGeos)
635689

636690
return FALSE;
@@ -908,6 +962,21 @@ QgsPoint QgsGeometry::closestVertexWithContext(QgsPoint& point,
908962

909963
if (mGeos)
910964
{
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
911980
switch (mGeos->getGeometryTypeId())
912981
{
913982
case geos::GEOS_POINT: // a point
@@ -957,7 +1026,20 @@ QgsPoint QgsGeometry::closestVertexWithContext(QgsPoint& point,
9571026

9581027
case geos::GEOS_POLYGON: // a polygon
9591028
{
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);
9611043
break;
9621044
} // case geos::GEOS_POLYGON
9631045

@@ -985,7 +1067,7 @@ QgsPoint QgsGeometry::closestVertexWithContext(QgsPoint& point,
9851067
break;
9861068
} // case geos::GEOS_GEOMETRYCOLLECTION
9871069
}
988-
1070+
#endif
9891071
} // if (mGeos)
9901072

9911073
return minDistPoint;
@@ -1850,10 +1932,6 @@ bool QgsGeometry::exportWkbToGeos() const
18501932
bool QgsGeometry::exportGeosToWkb() const
18511933
// TODO: Make this work
18521934
{
1853-
#ifdef QGISDEBUG
1854-
std::cout << "QgsGeometry::exportGeosToWkb: entered." << std::endl;
1855-
#endif
1856-
18571935
if (!mDirtyWkb)
18581936
{
18591937
// No need to convert again
@@ -1876,11 +1954,6 @@ bool QgsGeometry::exportGeosToWkb() const
18761954
// set up byteOrder
18771955
char byteOrder = 1; // TODO
18781956

1879-
#ifdef QGISDEBUG
1880-
std::cout << "QgsGeometry::exportGeosToWkb: Testing mGeos->getGeometryTypeId() = '"
1881-
<< mGeos->getGeometryTypeId() << "'." << std::endl;
1882-
#endif
1883-
18841957
switch (mGeos->getGeometryTypeId())
18851958
{
18861959
case geos::GEOS_POINT: // a point
@@ -1943,10 +2016,9 @@ bool QgsGeometry::exportGeosToWkb() const
19432016
}
19442017

19452018
mDirtyWkb = FALSE;
2019+
return true;
19462020

19472021
// TODO: Deal with endian-ness
1948-
1949-
break;
19502022
} // case geos::GEOS_LINESTRING
19512023

19522024
case geos::GEOS_LINEARRING: // a linear ring (linestring with 1st point == last point)
@@ -1957,7 +2029,96 @@ bool QgsGeometry::exportGeosToWkb() const
19572029

19582030
case geos::GEOS_POLYGON: // a polygon
19592031
{
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+
}
19612122
break;
19622123
} // case geos::GEOS_POLYGON
19632124

‎src/core/qgsgeometryvertexindex.cpp‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ void QgsGeometryVertexIndex::push_back(int& i)
4949

5050
int QgsGeometryVertexIndex::back()
5151
{
52+
#ifdef QGISDEBUG
53+
for(std::vector<int>::iterator it = mIndex.begin(); it != mIndex.end(); ++it)
54+
{
55+
qWarning("mIndex contains: "+QString::number(*it));
56+
}
57+
#endif
5258
return mIndex.back();
5359
}
5460

‎src/gui/qgsmaptoolcapture.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ void QgsMapToolCapture::canvasReleaseEvent(QMouseEvent * e)
212212
int length=mCaptureList.size()+1;//+1 because the first point is needed twice
213213
int numrings=1;
214214
memcpy(&wkb[1],&wkbtype, sizeof(int));
215-
memcpy(&wkb[5],&numrings,sizeof(int));
216-
memcpy(&wkb[9],&length, sizeof(int));
215+
memcpy(&wkb[1+sizeof(int)],&numrings,sizeof(int));
216+
memcpy(&wkb[1+2*sizeof(int)],&length, sizeof(int));
217217
int position=1+3*sizeof(int);
218218
double x,y;
219219
std::list<QgsPoint>::iterator it;

‎src/gui/qgsmaptoolvertexedit.cpp‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,9 +279,8 @@ void QgsMapToolVertexEdit::canvasReleaseEvent(QMouseEvent * e)
279279
delete mRubberBand;
280280
mRubberBand = 0;
281281

282-
// TODO: Find nearest line portion of the selected line, add a node at the mouse location
283-
284282
// Add the new vertex
283+
//todo: snap to nearest vertex of vectorlayer
285284
vlayer->insertVertexBefore(point.x(), point.y(), mSnappedAtFeatureId, mSnappedBeforeVertex);
286285
mCanvas->refresh();
287286
}
@@ -293,7 +292,7 @@ void QgsMapToolVertexEdit::canvasReleaseEvent(QMouseEvent * e)
293292

294293
delete mRubberBand;
295294
mRubberBand = 0;
296-
295+
//todo: snap to nearest vertex of vectorlayer
297296
vlayer->moveVertexAt(point.x(), point.y(), mSnappedAtFeatureId, mSnappedAtVertex);
298297
mCanvas->refresh();
299298
}

0 commit comments

Comments
 (0)
Please sign in to comment.