Skip to content

Commit 4c3841b

Browse files
author
mhugent
committedApr 23, 2006
also added a wkb method to delete vertices
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@5350 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 7b3b2d8 commit 4c3841b

File tree

2 files changed

+249
-5
lines changed

2 files changed

+249
-5
lines changed
 

‎src/core/qgsgeometry.cpp

Lines changed: 248 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,6 @@ bool QgsGeometry::moveVertexAt(double x, double y, QgsGeometryVertexIndex atVert
524524
}
525525

526526
unsigned int wkbType;
527-
double *xPtr, *yPtr;
528527
unsigned char* ptr = mGeometry+1;
529528
memcpy(&wkbType, ptr, sizeof(wkbType));
530529
ptr += sizeof(wkbType);
@@ -538,6 +537,7 @@ bool QgsGeometry::moveVertexAt(double x, double y, QgsGeometryVertexIndex atVert
538537
memcpy(ptr, &x, sizeof(double));
539538
ptr += sizeof(double);
540539
memcpy(ptr, &y, sizeof(double));
540+
mDirtyGeos = true;
541541
return true;
542542
}
543543
else
@@ -558,6 +558,7 @@ bool QgsGeometry::moveVertexAt(double x, double y, QgsGeometryVertexIndex atVert
558558
memcpy(ptr, &x, sizeof(double));
559559
ptr += sizeof(double);
560560
memcpy(ptr, &y, sizeof(double));
561+
mDirtyGeos = true;
561562
return true;
562563
}
563564
case QGis::WKBMultiLineString:
@@ -575,6 +576,7 @@ bool QgsGeometry::moveVertexAt(double x, double y, QgsGeometryVertexIndex atVert
575576
ptr += (vertexnr-pointindex)*2*sizeof(double);
576577
memcpy(ptr, &x, sizeof(double));
577578
memcpy(ptr+sizeof(double), &y, sizeof(double));
579+
mDirtyGeos = true;
578580
return true;
579581
}
580582
pointindex += (*nrPoints);
@@ -599,6 +601,7 @@ bool QgsGeometry::moveVertexAt(double x, double y, QgsGeometryVertexIndex atVert
599601
memcpy(ptr+sizeof(double), &y, sizeof(double));
600602
memcpy(ptr+2*sizeof(double)*(*nrPoints-1), &x, sizeof(double));
601603
memcpy(ptr+sizeof(double)+2*sizeof(double)*(*nrPoints-1), &y, sizeof(double));
604+
mDirtyGeos = true;
602605
return true;
603606
}
604607
else if(vertexnr > pointindex && vertexnr < pointindex + (*nrPoints-1))//move only one point
@@ -607,6 +610,7 @@ bool QgsGeometry::moveVertexAt(double x, double y, QgsGeometryVertexIndex atVert
607610
memcpy(ptr, &x, sizeof(double));
608611
ptr += sizeof(double);
609612
memcpy(ptr, &y, sizeof(double));
613+
mDirtyGeos = true;
610614
return true;
611615
}
612616
ptr += 2*sizeof(double)*(*nrPoints);
@@ -636,6 +640,7 @@ bool QgsGeometry::moveVertexAt(double x, double y, QgsGeometryVertexIndex atVert
636640
memcpy(ptr+sizeof(double), &y, sizeof(double));
637641
memcpy(ptr+2*sizeof(double)*(*nrPoints-1), &x, sizeof(double));
638642
memcpy(ptr+sizeof(double)+2*sizeof(double)*(*nrPoints-1), &y, sizeof(double));
643+
mDirtyGeos = true;
639644
return true;
640645
}
641646
else if(vertexnr > pointindex && vertexnr < pointindex + (*nrPoints-1))//move only one point
@@ -644,6 +649,7 @@ bool QgsGeometry::moveVertexAt(double x, double y, QgsGeometryVertexIndex atVert
644649
memcpy(ptr, &x, sizeof(double));
645650
ptr += sizeof(double);
646651
memcpy(ptr, &y, sizeof(double));
652+
mDirtyGeos = true;
647653
return true;
648654
}
649655
ptr += 2*sizeof(double)*(*nrPoints);
@@ -655,6 +661,245 @@ bool QgsGeometry::moveVertexAt(double x, double y, QgsGeometryVertexIndex atVert
655661
}
656662
}
657663

664+
bool QgsGeometry::deleteVertexAt(QgsGeometryVertexIndex atVertex)
665+
{
666+
int vertexnr = atVertex.back();
667+
bool success = false;
668+
669+
if(mDirtyWkb)
670+
{
671+
exportGeosToWkb();
672+
}
673+
674+
//create a new geometry buffer for the modified geometry
675+
unsigned char* newbuffer = new unsigned char[mGeometrySize-2*sizeof(double)];
676+
memcpy(newbuffer, mGeometry, 1+sizeof(int)); //endian and type are the same
677+
678+
int pointindex = 0;
679+
unsigned int wkbType;
680+
unsigned char* ptr = mGeometry+1;
681+
memcpy(&wkbType, ptr, sizeof(wkbType));
682+
ptr += sizeof(wkbType);
683+
unsigned char* newBufferPtr = newbuffer+1+sizeof(int);
684+
685+
switch(wkbType)
686+
{
687+
case QGis::WKBPoint:
688+
{
689+
break; //cannot remove the only point vertex
690+
}
691+
case QGis::WKBMultiPoint:
692+
case QGis::WKBLineString:
693+
{
694+
int* nPoints = (int*)ptr;
695+
if((*nPoints) < 3 || vertexnr > (*nPoints)-1 || vertexnr < 0)
696+
{
697+
break;
698+
}
699+
int newNPoints = (*nPoints)-1; //new number of points
700+
memcpy(newBufferPtr, &newNPoints, sizeof(int));
701+
ptr += sizeof(int);
702+
newBufferPtr += sizeof(int);
703+
for(int pointnr = 0; pointnr < *nPoints; ++pointnr)
704+
{
705+
if(vertexnr != pointindex)
706+
{
707+
memcpy(newBufferPtr, ptr, sizeof(double));
708+
memcpy(newBufferPtr+sizeof(double), ptr+sizeof(double), sizeof(double));
709+
newBufferPtr += 2*sizeof(double);
710+
}
711+
else
712+
{
713+
success = true;
714+
}
715+
ptr += 2*sizeof(double);
716+
++pointindex;
717+
}
718+
break;
719+
}
720+
case QGis::WKBMultiLineString:
721+
{
722+
int* nLines = (int*)ptr;
723+
memcpy(newBufferPtr, nLines, sizeof(int));
724+
newBufferPtr += sizeof(int);
725+
ptr += sizeof(int);
726+
int* nPoints = 0; //number of points in a line
727+
int pointindex = 0;
728+
for(int linenr = 0; linenr < *nLines; ++linenr)
729+
{
730+
nPoints = (int*)ptr;
731+
ptr += sizeof(int);
732+
int newNPoint;
733+
734+
//find out if the vertex is in this line
735+
if(vertexnr >= pointindex && vertexnr < pointindex + (*nPoints))
736+
{
737+
if(*nPoints < 3)
738+
{
739+
break;
740+
}
741+
newNPoint = (*nPoints)-1;
742+
}
743+
else
744+
{
745+
newNPoint = *nPoints;
746+
}
747+
memcpy(newBufferPtr, &newNPoint, sizeof(int));
748+
749+
for(int pointnr = 0; pointnr < *nPoints; ++pointnr)
750+
{
751+
if(vertexnr != pointindex)
752+
{
753+
memcpy(newBufferPtr, ptr, sizeof(double));//x
754+
memcpy(newBufferPtr+sizeof(double), ptr+sizeof(double), sizeof(double));//y
755+
newBufferPtr += 2*sizeof(double);
756+
}
757+
else
758+
{
759+
success = true;
760+
}
761+
ptr += 2*sizeof(double);
762+
++pointindex;
763+
}
764+
}
765+
break;
766+
}
767+
case QGis::WKBPolygon:
768+
{
769+
int* nRings = (int*)ptr;
770+
memcpy(newBufferPtr, nRings, sizeof(int));
771+
ptr += sizeof(int);
772+
newBufferPtr += sizeof(int);
773+
int* nPoints = 0; //number of points in a ring
774+
int pointindex = 0;
775+
776+
for(int ringnr = 0; ringnr < *nRings; ++ringnr)
777+
{
778+
nPoints = (int*)ptr;
779+
ptr += sizeof(int);
780+
int newNPoints;
781+
if(vertexnr >= pointindex && vertexnr < pointindex + *nPoints)//vertex to delete is in this ring
782+
{
783+
if(*nPoints < 5) //a ring has at least 3 points
784+
{
785+
break;
786+
}
787+
newNPoints = *nPoints - 1;
788+
}
789+
else
790+
{
791+
newNPoints = *nPoints;
792+
}
793+
memcpy(newBufferPtr, &newNPoints, sizeof(int));
794+
newBufferPtr += sizeof(int);
795+
796+
for(int pointnr = 0; pointnr < *nPoints; ++pointnr)
797+
{
798+
if(vertexnr != pointindex)
799+
{
800+
memcpy(newBufferPtr, ptr, sizeof(double));//x
801+
memcpy(newBufferPtr+sizeof(double), ptr+sizeof(double), sizeof(double));//y
802+
newBufferPtr += 2*sizeof(double);
803+
}
804+
else
805+
{
806+
if(pointnr == 0)//adjust the last point of the ring
807+
{
808+
memcpy(ptr+(*nPoints-1)*2*sizeof(double), ptr+2*sizeof(double), sizeof(double));
809+
memcpy(ptr+sizeof(double)+(*nPoints-1)*2*sizeof(double), ptr+3*sizeof(double), sizeof(double));
810+
}
811+
if(pointnr == (*nPoints)-1)
812+
{
813+
memcpy(newBufferPtr-(*nPoints-2)*2*sizeof(double), ptr-2*sizeof(double), sizeof(double));
814+
memcpy(newBufferPtr-(*nPoints-2)*2*sizeof(double)+sizeof(double), ptr-sizeof(double), sizeof(double));
815+
}
816+
success = true;
817+
}
818+
ptr += 2*sizeof(double);
819+
++pointindex;
820+
}
821+
}
822+
break;
823+
}
824+
case QGis::WKBMultiPolygon:
825+
{
826+
int* nPolys = (int*)ptr;
827+
memcpy(newBufferPtr, nPolys, sizeof(int));
828+
newBufferPtr += sizeof(int);
829+
ptr +=sizeof(int);
830+
int* nRings = 0;
831+
int* nPoints = 0;
832+
int pointindex = 0;
833+
834+
for(int polynr = 0; polynr < *nPolys; ++polynr)
835+
{
836+
nRings = (int*)ptr;
837+
memcpy(newBufferPtr, nRings, sizeof(int));
838+
newBufferPtr += sizeof(int);
839+
ptr += sizeof(int);
840+
for(int ringnr = 0; ringnr < *nRings; ++ringnr)
841+
{
842+
nPoints = (int*)ptr;
843+
ptr += sizeof(int);
844+
int newNPoints;
845+
if(vertexnr >= pointindex && vertexnr < pointindex + *nPoints)//vertex to delete is in this ring
846+
{
847+
if(*nPoints < 5) //a ring has at least 3 points
848+
{
849+
break;
850+
}
851+
newNPoints = *nPoints - 1;
852+
}
853+
else
854+
{
855+
newNPoints = *nPoints;
856+
}
857+
memcpy(newBufferPtr, &newNPoints, sizeof(int));
858+
newBufferPtr += sizeof(int);
859+
860+
for(int pointnr = 0; pointnr < *nPoints; ++pointnr)
861+
{
862+
if(vertexnr != pointindex)
863+
{
864+
memcpy(newBufferPtr, ptr, sizeof(double));//x
865+
memcpy(newBufferPtr+sizeof(double), ptr+sizeof(double), sizeof(double));//y
866+
newBufferPtr += 2*sizeof(double);
867+
}
868+
else
869+
{
870+
if(pointnr == 0)//adjust the last point of the ring
871+
{
872+
memcpy(ptr+(*nPoints-1)*2*sizeof(double), ptr+2*sizeof(double), sizeof(double));
873+
memcpy(ptr+sizeof(double)+(*nPoints-1)*2*sizeof(double), ptr+3*sizeof(double), sizeof(double));
874+
}
875+
if(pointnr == (*nPoints)-1)
876+
{
877+
memcpy(newBufferPtr-(*nPoints-2)*2*sizeof(double), ptr-2*sizeof(double), sizeof(double));
878+
memcpy(newBufferPtr-(*nPoints-2)*2*sizeof(double)+sizeof(double), ptr-sizeof(double), sizeof(double));
879+
}
880+
success = true;
881+
}
882+
ptr += 2*sizeof(double);
883+
++pointindex;
884+
}
885+
}
886+
}
887+
break;
888+
}
889+
}
890+
if(success)
891+
{
892+
delete mGeometry;
893+
mGeometry = newbuffer;
894+
mGeometrySize -= (2*sizeof(double));
895+
mDirtyGeos = true;
896+
}
897+
else
898+
{
899+
delete[] newbuffer;
900+
}
901+
}
902+
658903

659904

660905
#if 0
@@ -697,6 +942,7 @@ bool QgsGeometry::moveVertexAt(double x, double y,
697942
}
698943
#endif
699944

945+
#if 0
700946
bool QgsGeometry::deleteVertexAt(QgsGeometryVertexIndex atVertex)
701947
{
702948

@@ -789,6 +1035,7 @@ bool QgsGeometry::deleteVertexAt(QgsGeometryVertexIndex atVertex)
7891035
return FALSE;
7901036

7911037
}
1038+
#endif
7921039

7931040

7941041
bool QgsGeometry::vertexAt(double &x, double &y,

‎src/core/qgsgeometry.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,7 @@ class QgsGeometry {
104104
* ring and item (first number is index 0)
105105
* to the given coordinates.
106106
* Returns FALSE if atVertex does not correspond to a valid vertex
107-
* on this geometry (including if this geometry is a Point).
108-
* It is up to the caller to distinguish between
109-
* these error conditions. (Or maybe we add another method to this
110-
* object to help make the distinction?)
107+
* on this geometry
111108
*/
112109
bool moveVertexAt(double x, double y, QgsGeometryVertexIndex atVertex);
113110

0 commit comments

Comments
 (0)