EgtGeomKernel :

- miglioria alla gestione della RemoveAlignedPoints con limite sulla lunghezza.
This commit is contained in:
Daniele Bariletti
2026-07-09 14:44:51 +02:00
parent 4d3b7ea6cf
commit 5bd2b869f8
+63 -35
View File
@@ -737,7 +737,7 @@ PolyLine::AdjustForMaxSegmentLen( double dMaxLen)
//-----------------------------------------------------------------------------
static bool
DouglasPeuckerSimplification( const PNTUVECTOR& vPtU, const double dSqTol, const int nIndStart,
const int nIndEnd, INTVECTOR& vInd, double dMaxLen)
const int nIndEnd, INTVECTOR& vInd)
{
// se indici uguali, ritorno
if ( nIndStart == nIndEnd)
@@ -745,7 +745,7 @@ DouglasPeuckerSimplification( const PNTUVECTOR& vPtU, const double dSqTol, const
// distanza massima e indice del punto associato
double dMaxSqDist = 0. ;
int nMaxInd = nIndStart + 1 ;
int nMaxInd = 0 ;
// scorro i punti intermedi tra nIndStart e nIndEnd
for ( int i = nIndStart + 1 ; i < nIndEnd ; ++ i) {
@@ -761,15 +761,12 @@ DouglasPeuckerSimplification( const PNTUVECTOR& vPtU, const double dSqTol, const
// se la distanza massima trovata è sopra la tolleranza, allora controllo la parte di PolyLine tra
// (nIndStart, nMaxInd) e quella tra (nMaxInd, nIndEnd)
bool bSplit = dMaxSqDist > dSqTol ;
if ( dMaxLen < INFINITO)
bSplit = bSplit || ( nIndEnd - nIndStart > 1 && Dist( vPtU[nIndStart].first, vPtU[nIndEnd].first) > dMaxLen) ;
if ( bSplit) {
if ( dMaxSqDist > dSqTol) {
// inserisco il punto
vInd.push_back( nMaxInd) ;
// split
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, nIndStart, nMaxInd, vInd, dMaxLen) ||
! DouglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, nIndEnd, vInd, dMaxLen))
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, nIndStart, nMaxInd, vInd) ||
! DouglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, nIndEnd, vInd))
return false ;
}
@@ -795,34 +792,65 @@ PolyLine::RemoveAlignedPoints( double dToler, bool bStartEnd, double dMaxLen)
// vettore indici dei punti rimanenti
INTVECTOR vInd ; vInd.reserve( vPtU.size()) ;
// se aperta
if ( ! IsClosed()) {
// considero tutti i punti della PolyLine
vInd.push_back( 0) ;
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, 0, int( vPtU.size()) - 1, vInd, dMaxLen))
return false ;
vInd.push_back( int( vPtU.size()) - 1) ;
}
// altrimenti chiusa
else {
// cerco il punto più distante dal primo
double dMaxDist = 0. ;
int nMaxInd = 0 ;
for ( int i = 1 ; i < int( vPtU.size()) ; ++ i) {
double dCurrDist = Dist( vPtU[0].first, vPtU[i].first) ;
if ( dCurrDist > dMaxDist) {
dMaxDist = dCurrDist ;
nMaxInd = i ;
}
if ( dMaxLen > INFINITO - 1) {
// se aperta
if ( ! IsClosed()) {
// considero tutti i punti della PolyLine
vInd.push_back( 0) ;
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, 0, int( vPtU.size()) - 1, vInd))
return false ;
vInd.push_back( int( vPtU.size()) - 1) ;
}
// altrimenti chiusa
else {
// cerco il punto più distante dal primo
double dMaxDist = 0. ;
int nMaxInd = 0 ;
for ( int i = 1 ; i < int( vPtU.size()) ; ++ i) {
double dCurrDist = Dist( vPtU[0].first, vPtU[i].first) ;
if ( dCurrDist > dMaxDist) {
dMaxDist = dCurrDist ;
nMaxInd = i ;
}
}
// recupero due PolyLine di approssimazione
vInd.push_back( 0) ;
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, 0, nMaxInd, vInd))
return false ;
vInd.push_back( nMaxInd) ;
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, int( vPtU.size()) - 1, vInd))
return false ;
vInd.push_back( int( vPtU.size()) - 1) ;
}
}
else {
// raggruppo i punti della polyline a gruppi che stanno entro la lunghezza massima e ad ognuno applico Douglas
vInd.push_back(0) ;
int i = 0 ;
while ( i < ssize(vPtU) - 1) {
int nLast = i + 1 ;
while ( nLast < ssize( vPtU) && Dist( vPtU[i].first, vPtU[nLast].first) <= dMaxLen)
++nLast ;
// l'ultimo punto era oltre il limite
--nLast ;
// sicurezza: almeno un passo avanti
if ( nLast == i)
nLast = i + 1 ;
// mantieni l'estremo del tratto
if ( vInd.back() != nLast)
vInd.push_back( nLast) ;
// semplifica il tratto interno
if ( nLast - i > 1) {
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, i, nLast, vInd))
return false ;
}
i = nLast ;
}
// recupero due PolyLine di approssimazione
vInd.push_back( 0) ;
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, 0, nMaxInd, vInd, dMaxLen))
return false ;
vInd.push_back( nMaxInd) ;
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, int( vPtU.size()) - 1, vInd, dMaxLen))
return false ;
vInd.push_back( int( vPtU.size()) - 1) ;
}
// ordino in senso crescente