@@ -1363,18 +1363,31 @@ bool QgsGeometry::moveVertex( double x, double y, int atVertex )
1363
1363
}
1364
1364
}
1365
1365
1366
- bool QgsGeometry::deleteVertex ( QgsConstWkbPtr &srcPtr, QgsWkbPtr &dstPtr, int atVertex, bool hasZValue, int &pointIndex, bool isRing, bool lastItem )
1366
+ // copy vertices from srcPtr to dstPtr and skip/delete one vertex
1367
+ // @param srcPtr ring/part starting with number of points (adjusted in each call)
1368
+ // @param dstPtr ring/part to copy to (adjusted in each call)
1369
+ // @param atVertex index of vertex to skip
1370
+ // @param hasZValue points have 3 elements
1371
+ // @param pointIndex reference to index of first ring/part vertex in overall object (adjusted in each call)
1372
+ // @param isRing srcPtr points to a ring
1373
+ // @param lastItem last ring/part, atVertex after this one must be wrong
1374
+ // @return
1375
+ // 0 no delete was done
1376
+ // 1 "normal" delete was done
1377
+ // 2 last element of the ring/part was deleted
1378
+ int QgsGeometry::deleteVertex ( QgsConstWkbPtr &srcPtr, QgsWkbPtr &dstPtr, int atVertex, bool hasZValue, int &pointIndex, bool isRing, bool lastItem )
1367
1379
{
1368
1380
QgsDebugMsg ( QString ( " atVertex:%1 hasZValue:%2 pointIndex:%3 isRing:%4" ).arg ( atVertex ).arg ( hasZValue ).arg ( pointIndex ).arg ( isRing ) );
1369
1381
const int ps = ( hasZValue ? 3 : 2 ) * sizeof ( double );
1370
1382
int nPoints;
1371
1383
srcPtr >> nPoints;
1372
1384
1385
+ // copy complete ring/part if vertex is in a following one
1373
1386
if ( atVertex < pointIndex || atVertex >= pointIndex + nPoints )
1374
1387
{
1375
1388
// atVertex does not exist
1376
1389
if ( lastItem && atVertex >= pointIndex + nPoints )
1377
- return false ;
1390
+ return 0 ;
1378
1391
1379
1392
dstPtr << nPoints;
1380
1393
@@ -1383,14 +1396,25 @@ bool QgsGeometry::deleteVertex( QgsConstWkbPtr &srcPtr, QgsWkbPtr &dstPtr, int a
1383
1396
dstPtr += len;
1384
1397
srcPtr += len;
1385
1398
pointIndex += nPoints;
1386
- return false ;
1399
+ return 0 ;
1387
1400
}
1388
1401
1402
+ // delete the first vertex of a ring instead of the last
1389
1403
if ( isRing && atVertex == pointIndex + nPoints - 1 )
1390
1404
atVertex = pointIndex;
1391
1405
1406
+ if ( nPoints == ( isRing ? 2 : 1 ) )
1407
+ {
1408
+ // last point of the part/ring is deleted
1409
+ // skip the whole part/ring
1410
+ srcPtr += nPoints * ps;
1411
+ pointIndex += nPoints;
1412
+ return 2 ;
1413
+ }
1414
+
1392
1415
dstPtr << nPoints - 1 ;
1393
1416
1417
+ // copy ring before vertex
1394
1418
int len = ( atVertex - pointIndex ) * ps;
1395
1419
if ( len > 0 )
1396
1420
{
@@ -1399,9 +1423,13 @@ bool QgsGeometry::deleteVertex( QgsConstWkbPtr &srcPtr, QgsWkbPtr &dstPtr, int a
1399
1423
srcPtr += len;
1400
1424
}
1401
1425
1426
+ // skip deleted vertex
1402
1427
srcPtr += ps;
1403
1428
1429
+ // copy reset of ring
1404
1430
len = ( pointIndex + nPoints - atVertex - 1 ) * ps;
1431
+
1432
+ // save position of vertex, if we delete the first vertex of a ring
1405
1433
const unsigned char *first = 0 ;
1406
1434
if ( isRing && atVertex == pointIndex )
1407
1435
{
@@ -1416,20 +1444,22 @@ bool QgsGeometry::deleteVertex( QgsConstWkbPtr &srcPtr, QgsWkbPtr &dstPtr, int a
1416
1444
srcPtr += len;
1417
1445
}
1418
1446
1447
+ // copy new first vertex instead of the old last, if we deleted the original first vertex
1419
1448
if ( first )
1420
1449
{
1421
1450
memcpy ( dstPtr, first, ps );
1422
1451
dstPtr += ps;
1423
1452
srcPtr += ps;
1424
1453
}
1425
1454
1426
- pointIndex += nPoints - 1 ;
1455
+ pointIndex += nPoints;
1427
1456
1428
- return true ;
1457
+ return 1 ;
1429
1458
}
1430
1459
1431
1460
bool QgsGeometry::deleteVertex ( int atVertex )
1432
1461
{
1462
+ QgsDebugMsg ( QString ( " atVertex:%1" ).arg ( atVertex ) );
1433
1463
if ( atVertex < 0 )
1434
1464
return false ;
1435
1465
@@ -1468,7 +1498,14 @@ bool QgsGeometry::deleteVertex( int atVertex )
1468
1498
case QGis::WKBLineString:
1469
1499
{
1470
1500
int pointIndex = 0 ;
1471
- deleted = deleteVertex ( srcPtr, dstPtr, atVertex, hasZValue, pointIndex, false , true );
1501
+ int res = deleteVertex ( srcPtr, dstPtr, atVertex, hasZValue, pointIndex, false , true );
1502
+ if ( res == 2 )
1503
+ {
1504
+ // Linestring with 0 points
1505
+ dstPtr << 0 ;
1506
+ }
1507
+
1508
+ deleted = res != 0 ;
1472
1509
break ;
1473
1510
}
1474
1511
@@ -1477,10 +1514,17 @@ bool QgsGeometry::deleteVertex( int atVertex )
1477
1514
{
1478
1515
int nRings;
1479
1516
srcPtr >> nRings;
1517
+ QgsWkbPtr ptrN ( dstPtr );
1480
1518
dstPtr << nRings;
1481
1519
1482
1520
for ( int ringnr = 0 , pointIndex = 0 ; ringnr < nRings; ++ringnr )
1483
- deleted |= deleteVertex ( srcPtr, dstPtr, atVertex, hasZValue, pointIndex, true , ringnr == nRings - 1 );
1521
+ {
1522
+ int res = deleteVertex ( srcPtr, dstPtr, atVertex, hasZValue, pointIndex, true , ringnr == nRings - 1 );
1523
+ if ( res == 2 )
1524
+ ptrN << nRings - 1 ;
1525
+
1526
+ deleted |= res != 0 ;
1527
+ }
1484
1528
1485
1529
break ;
1486
1530
}
@@ -1524,13 +1568,24 @@ bool QgsGeometry::deleteVertex( int atVertex )
1524
1568
{
1525
1569
int nLines;
1526
1570
srcPtr >> nLines;
1571
+ QgsWkbPtr ptrN ( dstPtr );
1527
1572
dstPtr << nLines;
1528
1573
1529
1574
for ( int linenr = 0 , pointIndex = 0 ; linenr < nLines; ++linenr )
1530
1575
{
1576
+ QgsWkbPtr saveDstPtr ( dstPtr );
1531
1577
srcPtr >> endianness >> wkbType;
1532
1578
dstPtr << endianness << wkbType;
1533
- deleted |= deleteVertex ( srcPtr, dstPtr, atVertex, hasZValue, pointIndex, false , linenr == nLines - 1 );
1579
+
1580
+ int res = deleteVertex ( srcPtr, dstPtr, atVertex, hasZValue, pointIndex, false , linenr == nLines - 1 );
1581
+ if ( res == 2 )
1582
+ {
1583
+ // line string was completely removed
1584
+ ptrN << nLines - 1 ;
1585
+ dstPtr = saveDstPtr;
1586
+ }
1587
+
1588
+ deleted |= res != 0 ;
1534
1589
}
1535
1590
1536
1591
break ;
@@ -1541,16 +1596,38 @@ bool QgsGeometry::deleteVertex( int atVertex )
1541
1596
{
1542
1597
int nPolys;
1543
1598
srcPtr >> nPolys;
1599
+ QgsWkbPtr ptrNPolys ( dstPtr );
1544
1600
dstPtr << nPolys;
1545
1601
1546
1602
for ( int polynr = 0 , pointIndex = 0 ; polynr < nPolys; ++polynr )
1547
1603
{
1548
1604
int nRings;
1549
1605
srcPtr >> endianness >> wkbType >> nRings;
1550
- dstPtr << endianness << wkbType << nRings;
1606
+ QgsWkbPtr saveDstPolyPtr ( dstPtr );
1607
+ dstPtr << endianness << wkbType;
1608
+ QgsWkbPtr ptrNRings ( dstPtr );
1609
+ dstPtr << nRings;
1551
1610
1552
1611
for ( int ringnr = 0 ; ringnr < nRings; ++ringnr )
1553
- deleted |= deleteVertex ( srcPtr, dstPtr, atVertex, hasZValue, pointIndex, true , polynr == nPolys - 1 && ringnr == nRings - 1 );
1612
+ {
1613
+ int res = deleteVertex ( srcPtr, dstPtr, atVertex, hasZValue, pointIndex, true , polynr == nPolys - 1 && ringnr == nRings - 1 );
1614
+ if ( res == 2 )
1615
+ {
1616
+ // ring was completely removed
1617
+ if ( nRings == 1 )
1618
+ {
1619
+ // last ring => remove polygon
1620
+ ptrNPolys << nPolys - 1 ;
1621
+ dstPtr = saveDstPolyPtr;
1622
+ }
1623
+ else
1624
+ {
1625
+ ptrNRings << nRings - 1 ;
1626
+ }
1627
+ }
1628
+
1629
+ deleted |= res != 0 ;
1630
+ }
1554
1631
}
1555
1632
break ;
1556
1633
}
0 commit comments