Skip to content

Commit 0b15d8b

Browse files
committedAug 31, 2015
Fix many leaks in PAL and simplify code
1 parent 30407c3 commit 0b15d8b

File tree

10 files changed

+140
-160
lines changed

10 files changed

+140
-160
lines changed
 

‎src/core/pal/costcalculator.cpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@
2828
namespace pal
2929
{
3030

31+
bool CostCalculator::candidateSortGrow( const LabelPosition *c1, const LabelPosition *c2 )
32+
{
33+
return c1->cost() < c2->cost();
34+
}
35+
36+
bool CostCalculator::candidateSortShrink( const LabelPosition *c1, const LabelPosition *c2 )
37+
{
38+
return c1->cost() > c2->cost();
39+
}
40+
3141
void CostCalculator::addObstacleCostPenalty( LabelPosition* lp, FeaturePart* obstacle )
3242
{
3343
int n = 0;
@@ -85,7 +95,7 @@ namespace pal
8595

8696
////////
8797

88-
void CostCalculator::setPolygonCandidatesCost( int nblp, LabelPosition **lPos, int max_p, RTree<FeaturePart*, double, 2, double> *obstacles, double bbx[4], double bby[4] )
98+
void CostCalculator::setPolygonCandidatesCost( int nblp, QList< LabelPosition* >& lPos, int max_p, RTree<FeaturePart*, double, 2, double> *obstacles, double bbx[4], double bby[4] )
8999
{
90100
int i;
91101

@@ -98,14 +108,13 @@ namespace pal
98108
for ( i = 0; i < nblp; i++ )
99109
setCandidateCostFromPolygon( lPos[i], obstacles, bbx, bby );
100110

101-
// lPos with big values came fisrts (value = min distance from label to Polygon's Perimeter)
102-
//sort ( (void**) lPos, nblp, costGrow);
103-
sort(( void** ) lPos, nblp, LabelPosition::costShrink );
111+
// lPos with big values came first (value = min distance from label to Polygon's Perimeter)
112+
qSort( lPos.begin(), lPos.end(), candidateSortShrink );
104113

105114

106115
// define the value's range
107-
double cost_max = lPos[0]->cost();
108-
double cost_min = lPos[max_p-1]->cost();
116+
double cost_max = lPos.at( 0 )->cost();
117+
double cost_min = lPos.at( max_p - 1 )->cost();
109118

110119
cost_max -= cost_min;
111120

@@ -128,7 +137,7 @@ namespace pal
128137
//if (cost_max - cost_min < EPSILON)
129138
if ( cost_max > EPSILON )
130139
{
131-
lPos[i]->mCost = 0.0021 - ( lPos[i]->cost() - cost_min ) * normalizer;
140+
lPos[i]->mCost = 0.0021 - ( lPos.at( i )->cost() - cost_min ) * normalizer;
132141
}
133142
else
134143
{
@@ -174,22 +183,22 @@ namespace pal
174183
int CostCalculator::finalizeCandidatesCosts( Feats* feat, int max_p, RTree <FeaturePart*, double, 2, double> *obstacles, double bbx[4], double bby[4] )
175184
{
176185
// If candidates list is smaller than expected
177-
if ( max_p > feat->nblp )
178-
max_p = feat->nblp;
186+
if ( max_p > feat->lPos.count() )
187+
max_p = feat->lPos.count();
179188
//
180189
// sort candidates list, best label to worst
181-
sort(( void** ) feat->lPos, feat->nblp, LabelPosition::costGrow );
190+
qSort( feat->lPos.begin(), feat->lPos.end(), candidateSortGrow );
182191

183192
// try to exclude all conflitual labels (good ones have cost < 1 by pruning)
184193
double discrim = 0.0;
185194
int stop;
186195
do
187196
{
188197
discrim += 1.0;
189-
for ( stop = 0; stop < feat->nblp && feat->lPos[stop]->cost() < discrim; stop++ )
198+
for ( stop = 0; stop < feat->lPos.count() && feat->lPos[stop]->cost() < discrim; stop++ )
190199
;
191200
}
192-
while ( stop == 0 && discrim < feat->lPos[feat->nblp-1]->cost() + 2.0 );
201+
while ( stop == 0 && discrim < feat->lPos.last()->cost() + 2.0 );
193202

194203
if ( discrim > 1.5 )
195204
{
@@ -211,7 +220,7 @@ namespace pal
211220
{
212221
int arrangement = feat->feature->layer()->arrangement();
213222
if ( arrangement == P_FREE || arrangement == P_HORIZ )
214-
setPolygonCandidatesCost( stop, ( LabelPosition** ) feat->lPos, max_p, obstacles, bbx, bby );
223+
setPolygonCandidatesCost( stop, feat->lPos, max_p, obstacles, bbx, bby );
215224
}
216225

217226
// add size penalty (small lines/polygons get higher cost)

‎src/core/pal/costcalculator.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef COSTCALCULATOR_H
1616
#define COSTCALCULATOR_H
1717

18+
#include <QList>
1819
#include "rtree.hpp"
1920

2021
namespace pal
@@ -27,13 +28,21 @@ namespace pal
2728
/** Increase candidate's cost according to its collision with passed feature */
2829
static void addObstacleCostPenalty( LabelPosition* lp, pal::FeaturePart *obstacle );
2930

30-
static void setPolygonCandidatesCost( int nblp, LabelPosition **lPos, int max_p, RTree<pal::FeaturePart*, double, 2, double> *obstacles, double bbx[4], double bby[4] );
31+
static void setPolygonCandidatesCost( int nblp, QList< LabelPosition* >& lPos, int max_p, RTree<pal::FeaturePart*, double, 2, double> *obstacles, double bbx[4], double bby[4] );
3132

3233
/** Set cost to the smallest distance between lPos's centroid and a polygon stored in geoetry field */
3334
static void setCandidateCostFromPolygon( LabelPosition* lp, RTree<pal::FeaturePart *, double, 2, double> *obstacles, double bbx[4], double bby[4] );
3435

3536
/** Sort candidates by costs, skip the worse ones, evaluate polygon candidates */
3637
static int finalizeCandidatesCosts( Feats* feat, int max_p, RTree<pal::FeaturePart *, double, 2, double> *obstacles, double bbx[4], double bby[4] );
38+
39+
/** Sorts label candidates in ascending order of cost
40+
*/
41+
static bool candidateSortGrow( const LabelPosition *c1, const LabelPosition *c2 );
42+
43+
/** Sorts label candidates in descending order of cost
44+
*/
45+
static bool candidateSortShrink( const LabelPosition *c1, const LabelPosition *c2 );
3746
};
3847

3948
/**

‎src/core/pal/feature.cpp

Lines changed: 35 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "qgis.h"
4646
#include "qgsgeos.h"
4747
#include "qgsmessagelog.h"
48+
#include "costcalculator.h"
4849
#include <QLinkedList>
4950
#include <cmath>
5051
#include <cfloat>
@@ -242,10 +243,9 @@ namespace pal
242243
}
243244
}
244245

245-
int FeaturePart::setPositionOverPoint( double x, double y, LabelPosition ***lPos, double angle, PointSet *mapShape )
246+
int FeaturePart::setPositionOverPoint( double x, double y, QList< LabelPosition*>& lPos, double angle, PointSet *mapShape )
246247
{
247248
int nbp = 1;
248-
*lPos = new LabelPosition *[nbp];
249249

250250
// get from feature
251251
double labelW = mFeature->label_x;
@@ -317,17 +317,15 @@ namespace pal
317317
{
318318
if ( !mapShape->containsLabelCandidate( lx, ly, labelW, labelH, angle ) )
319319
{
320-
delete[] *lPos;
321-
*lPos = 0;
322320
return 0;
323321
}
324322
}
325323

326-
( *lPos )[0] = new LabelPosition( id, lx, ly, labelW, labelH, angle, cost, this, false, quadrantFromOffset() );
324+
lPos << new LabelPosition( id, lx, ly, labelW, labelH, angle, cost, this, false, quadrantFromOffset() );
327325
return nbp;
328326
}
329327

330-
int FeaturePart::setPositionForPoint( double x, double y, LabelPosition ***lPos, double angle, PointSet *mapShape )
328+
int FeaturePart::setPositionForPoint( double x, double y, QList< LabelPosition* >& lPos, double angle, PointSet *mapShape )
331329
{
332330

333331
#ifdef _DEBUG_
@@ -483,18 +481,17 @@ namespace pal
483481

484482
if ( !candidates.isEmpty() )
485483
{
486-
*lPos = new LabelPosition *[candidates.count()];
487484
for ( int i = 0; i < candidates.count(); ++i )
488485
{
489-
( *lPos )[i] = candidates.at( i );
486+
lPos << candidates.at( i );
490487
}
491488
}
492489

493490
return candidates.count();
494491
}
495492

496493
// TODO work with squared distance by removing call to sqrt or dist_euc2d
497-
int FeaturePart::setPositionForLine( LabelPosition ***lPos, PointSet *mapShape )
494+
int FeaturePart::setPositionForLine( QList< LabelPosition* >& lPos, PointSet *mapShape )
498495
{
499496
#ifdef _DEBUG_
500497
std::cout << "SetPosition (line) : " << layer->name << "/" << uid << std::endl;
@@ -669,12 +666,9 @@ namespace pal
669666
delete[] ad;
670667

671668
int nbp = positions.size();
672-
*lPos = new LabelPosition *[nbp];
673-
i = 0;
674669
while ( positions.size() > 0 )
675670
{
676-
( *lPos )[i] = positions.takeFirst();
677-
i++;
671+
lPos << positions.takeFirst();
678672
}
679673

680674
return nbp;
@@ -885,7 +879,7 @@ namespace pal
885879
return newLp;
886880
}
887881

888-
int FeaturePart::setPositionForLineCurved( LabelPosition ***lPos, PointSet* mapShape )
882+
int FeaturePart::setPositionForLineCurved( QList< LabelPosition* >& lPos, PointSet* mapShape )
889883
{
890884
// label info must be present
891885
if ( mFeature->labelInfo == NULL || mFeature->labelInfo->char_num == 0 )
@@ -976,11 +970,11 @@ namespace pal
976970

977971

978972
int nbp = positions.size();
979-
( *lPos ) = new LabelPosition*[nbp];
980973
for ( int i = 0; i < nbp; i++ )
981974
{
982-
( *lPos )[i] = positions.takeFirst();
975+
lPos << positions.takeFirst();
983976
}
977+
984978
delete[] path_distances;
985979

986980
return nbp;
@@ -1001,7 +995,7 @@ namespace pal
1001995
*
1002996
*/
1003997

1004-
int FeaturePart::setPositionForPolygon( LabelPosition ***lPos, PointSet *mapShape )
998+
int FeaturePart::setPositionForPolygon( QList< LabelPosition*>& lPos, PointSet *mapShape )
1005999
{
10061000

10071001
#ifdef _DEBUG_
@@ -1207,10 +1201,9 @@ namespace pal
12071201

12081202
nbp = positions.size();
12091203

1210-
( *lPos ) = new LabelPosition*[nbp];
12111204
for ( i = 0; i < nbp; i++ )
12121205
{
1213-
( *lPos )[i] = positions.takeFirst();
1206+
lPos << positions.takeFirst();
12141207
}
12151208

12161209
for ( bbid = 0; bbid < j; bbid++ )
@@ -1256,12 +1249,10 @@ namespace pal
12561249
}
12571250
#endif
12581251

1259-
int FeaturePart::setPosition( LabelPosition ***lPos,
1252+
int FeaturePart::setPosition( QList< LabelPosition*>& lPos,
12601253
double bbox_min[2], double bbox_max[2],
12611254
PointSet *mapShape, RTree<LabelPosition*, double, 2, double> *candidates )
12621255
{
1263-
int nbp = 0;
1264-
int i;
12651256
double bbox[4];
12661257

12671258
bbox[0] = bbox_min[0];
@@ -1273,25 +1264,23 @@ namespace pal
12731264

12741265
if ( mFeature->fixedPosition() )
12751266
{
1276-
nbp = 1;
1277-
*lPos = new LabelPosition *[nbp];
1278-
( *lPos )[0] = new LabelPosition( 0, mFeature->fixedPosX, mFeature->fixedPosY, mFeature->label_x, mFeature->label_y, angle, 0.0, this );
1267+
lPos << new LabelPosition( 0, mFeature->fixedPosX, mFeature->fixedPosY, mFeature->label_x, mFeature->label_y, angle, 0.0, this );
12791268
}
12801269
else
12811270
{
12821271
switch ( type )
12831272
{
12841273
case GEOS_POINT:
12851274
if ( mFeature->layer->arrangement() == P_POINT_OVER || mFeature->fixedQuadrant() )
1286-
nbp = setPositionOverPoint( x[0], y[0], lPos, angle );
1275+
setPositionOverPoint( x[0], y[0], lPos, angle );
12871276
else
1288-
nbp = setPositionForPoint( x[0], y[0], lPos, angle );
1277+
setPositionForPoint( x[0], y[0], lPos, angle );
12891278
break;
12901279
case GEOS_LINESTRING:
12911280
if ( mFeature->layer->arrangement() == P_CURVED )
1292-
nbp = setPositionForLineCurved( lPos, mapShape );
1281+
setPositionForLineCurved( lPos, mapShape );
12931282
else
1294-
nbp = setPositionForLine( lPos, mapShape );
1283+
setPositionForLine( lPos, mapShape );
12951284
break;
12961285

12971286
case GEOS_POLYGON:
@@ -1302,52 +1291,47 @@ namespace pal
13021291
double cx, cy;
13031292
mapShape->getCentroid( cx, cy, mFeature->layer->centroidInside() );
13041293
if ( mFeature->layer->arrangement() == P_POINT_OVER )
1305-
nbp = setPositionOverPoint( cx, cy, lPos, angle, mapShape );
1294+
setPositionOverPoint( cx, cy, lPos, angle, mapShape );
13061295
else
1307-
nbp = setPositionForPoint( cx, cy, lPos, angle, mapShape );
1296+
setPositionForPoint( cx, cy, lPos, angle, mapShape );
13081297
break;
13091298
case P_LINE:
1310-
nbp = setPositionForLine( lPos, mapShape );
1299+
setPositionForLine( lPos, mapShape );
13111300
break;
13121301
default:
1313-
nbp = setPositionForPolygon( lPos, mapShape );
1302+
setPositionForPolygon( lPos, mapShape );
13141303
break;
13151304
}
13161305
}
13171306
}
13181307

1319-
int rnbp = nbp;
1320-
13211308
// purge candidates that are outside the bbox
1322-
for ( i = 0; i < nbp; i++ )
1309+
1310+
QMutableListIterator< LabelPosition*> i( lPos );
1311+
while ( i.hasNext() )
13231312
{
1313+
LabelPosition* pos = i.next();
13241314
bool outside = false;
13251315
if ( mFeature->layer->pal->getShowPartial() )
1326-
outside = !( *lPos )[i]->isIntersect( bbox );
1316+
outside = !pos->isIntersect( bbox );
13271317
else
1328-
outside = !( *lPos )[i]->isInside( bbox );
1318+
outside = !pos->isInside( bbox );
13291319
if ( outside )
13301320
{
1331-
rnbp--;
1332-
( *lPos )[i]->setCost( DBL_MAX ); // infinite cost => do not use
1321+
i.remove();
1322+
delete pos;
13331323
}
13341324
else // this one is OK
13351325
{
1336-
( *lPos )[i]->insertIntoIndex( candidates );
1326+
pos->insertIntoIndex( candidates );
13371327
}
13381328
}
13391329

1340-
sort(( void** )( *lPos ), nbp, LabelPosition::costGrow );
1341-
1342-
for ( i = rnbp; i < nbp; i++ )
1343-
{
1344-
delete( *lPos )[i];
1345-
}
1346-
1347-
return rnbp;
1330+
qSort( lPos.begin(), lPos.end(), CostCalculator::candidateSortGrow );
1331+
return lPos.count();
13481332
}
13491333

1350-
void FeaturePart::addSizePenalty( int nbp, LabelPosition** lPos, double bbx[4], double bby[4] )
1334+
void FeaturePart::addSizePenalty( int nbp, QList< LabelPosition* >& lPos, double bbx[4], double bby[4] )
13511335
{
13521336
if ( !mGeos )
13531337
createGeosGeom();
@@ -1402,7 +1386,7 @@ namespace pal
14021386
// apply the penalty
14031387
for ( int i = 0; i < nbp; i++ )
14041388
{
1405-
lPos[i]->setCost( lPos[i]->cost() + sizeCost / 100 );
1389+
lPos.at( i )->setCost( lPos.at( i )->cost() + sizeCost / 100 );
14061390
}
14071391
}
14081392

‎src/core/pal/feature.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ namespace pal
223223
* @param mapShape optional geometry of source polygon
224224
* @returns the number of generated candidates
225225
*/
226-
int setPositionForPoint( double x, double y, LabelPosition ***lPos, double angle, PointSet *mapShape = 0 );
226+
int setPositionForPoint( double x, double y, QList<LabelPosition *> &lPos, double angle, PointSet *mapShape = 0 );
227227

228228
/** Generate one candidate over or offset the specified point.
229229
* @param x x coordinate of the point
@@ -233,14 +233,14 @@ namespace pal
233233
* @param mapShape optional geometry of source polygon
234234
* @returns the number of generated candidates (always 1)
235235
*/
236-
int setPositionOverPoint( double x, double y, LabelPosition ***lPos, double angle, PointSet *mapShape = 0 );
236+
int setPositionOverPoint( double x, double y, QList<LabelPosition *> &lPos, double angle, PointSet *mapShape = 0 );
237237

238238
/** Generate candidates for line feature.
239239
* @param lPos pointer to an array of candidates, will be filled by generated candidates
240240
* @param mapShape a pointer to the line
241241
* @returns the number of generated candidates
242242
*/
243-
int setPositionForLine( LabelPosition ***lPos, PointSet *mapShape );
243+
int setPositionForLine( QList<LabelPosition *> &lPos, PointSet *mapShape );
244244

245245
LabelPosition* curvedPlacementAtOffset( PointSet* path_positions, double* path_distances,
246246
int orientation, int index, double distance );
@@ -250,14 +250,14 @@ namespace pal
250250
* @param mapShape a pointer to the line
251251
* @returns the number of generated candidates
252252
*/
253-
int setPositionForLineCurved( LabelPosition ***lPos, PointSet* mapShape );
253+
int setPositionForLineCurved( QList<LabelPosition *> &lPos, PointSet* mapShape );
254254

255255
/** Generate candidates for polygon features.
256256
* \param lPos pointer to an array of candidates, will be filled by generated candidates
257257
* \param mapShape a pointer to the polygon
258258
* \return the number of generated candidates
259259
*/
260-
int setPositionForPolygon( LabelPosition ***lPos, PointSet *mapShape );
260+
int setPositionForPolygon( QList<LabelPosition *> &lPos, PointSet *mapShape );
261261

262262
/** Returns the parent feature.
263263
*/
@@ -276,7 +276,7 @@ namespace pal
276276
* \param candidates index for candidates
277277
* \return the number of candidates in *lPos
278278
*/
279-
int setPosition( LabelPosition ***lPos, double bbox_min[2], double bbox_max[2], PointSet *mapShape, RTree<LabelPosition*, double, 2, double>*candidates );
279+
int setPosition( QList<LabelPosition *> &lPos, double bbox_min[2], double bbox_max[2], PointSet *mapShape, RTree<LabelPosition*, double, 2, double>*candidates );
280280

281281
/** Returns the unique ID of the feature.
282282
*/
@@ -315,7 +315,7 @@ namespace pal
315315
* Return true on success, false if the feature wasn't modified */
316316
bool mergeWithFeaturePart( FeaturePart* other );
317317

318-
void addSizePenalty( int nbp, LabelPosition** lPos, double bbx[4], double bby[4] );
318+
void addSizePenalty( int nbp, QList<LabelPosition *> &lPos, double bbx[4], double bby[4] );
319319

320320
protected:
321321

‎src/core/pal/labelposition.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,6 @@ namespace pal
402402
return (( LabelPosition* ) l )->mCost > (( LabelPosition* ) r )->mCost;
403403
}
404404

405-
406405
bool LabelPosition::polygonObstacleCallback( FeaturePart *obstacle, void *ctx )
407406
{
408407
PolygonCostCalculator *pCost = ( PolygonCostCalculator* ) ctx;

‎src/core/pal/layer.cpp

Lines changed: 28 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,6 @@ namespace pal
6060
, mUpsidedownLabels( Upright )
6161
{
6262
rtree = new RTree<FeaturePart*, double, 2, double>();
63-
hashtable = new QHash< QString, Feature*>;
64-
65-
connectedHashtable = new QHash< QString, QLinkedList<FeaturePart*>* >;
66-
connectedTexts = new QLinkedList< QString >;
6763

6864
if ( defaultPriority < 0.0001 )
6965
mDefaultPriority = 0.0001;
@@ -73,7 +69,6 @@ namespace pal
7369
mDefaultPriority = defaultPriority;
7470

7571
featureParts = new QLinkedList<FeaturePart*>;
76-
features = new QLinkedList<Feature*>;
7772
}
7873

7974
Layer::~Layer()
@@ -86,27 +81,23 @@ namespace pal
8681
delete featureParts;
8782
}
8883

89-
// this hashtable and list should be empty if they still exist
90-
delete connectedHashtable;
91-
9284
// features in the hashtable
93-
if ( features )
94-
{
95-
qDeleteAll( *features );
96-
delete features;
97-
}
85+
qDeleteAll( features );
86+
features.clear();
87+
88+
//should already be empty
89+
qDeleteAll( mConnectedHashtable );
90+
mConnectedHashtable.clear();
9891

9992
delete rtree;
10093

101-
delete hashtable;
10294
mMutex.unlock();
103-
delete connectedTexts;
10495
}
10596

10697
Feature* Layer::getFeature( const QString& geom_id )
10798
{
108-
QHash< QString, Feature*>::const_iterator i = hashtable->find( geom_id );
109-
if ( i != hashtable->constEnd() )
99+
QHash< QString, Feature*>::const_iterator i = mHashtable.find( geom_id );
100+
if ( i != mHashtable.constEnd() )
110101
return *i;
111102
else
112103
return 0;
@@ -131,7 +122,7 @@ namespace pal
131122

132123
mMutex.lock();
133124

134-
if ( hashtable->contains( geom_id ) )
125+
if ( mHashtable.contains( geom_id ) )
135126
{
136127
mMutex.unlock();
137128
//A feature with this id already exists. Don't throw an exception as sometimes,
@@ -264,8 +255,8 @@ namespace pal
264255
// add feature to layer if we have added something
265256
if ( !first_feat )
266257
{
267-
features->append( f );
268-
hashtable->insert( geom_id, f );
258+
features << f;
259+
mHashtable.insert( geom_id, f );
269260
}
270261
else
271262
{
@@ -290,18 +281,17 @@ namespace pal
290281
// add to hashtable with equally named feature parts
291282
if ( mMergeLines && !labelText.isEmpty() )
292283
{
293-
QHash< QString, QLinkedList<FeaturePart*>* >::const_iterator lstPtr = connectedHashtable->find( labelText );
294284
QLinkedList< FeaturePart*>* lst;
295-
if ( lstPtr == connectedHashtable->constEnd() )
285+
if ( !mConnectedHashtable.contains( labelText ) )
296286
{
297287
// entry doesn't exist yet
298288
lst = new QLinkedList<FeaturePart*>;
299-
connectedHashtable->insert( labelText, lst );
300-
connectedTexts->append( labelText );
289+
mConnectedHashtable.insert( labelText, lst );
290+
mConnectedTexts << labelText;
301291
}
302292
else
303293
{
304-
lst = *lstPtr;
294+
lst = mConnectedHashtable.value( labelText );
305295
}
306296
lst->append( fpart ); // add to the list
307297
}
@@ -327,16 +317,12 @@ namespace pal
327317
void Layer::joinConnectedFeatures()
328318
{
329319
// go through all label texts
330-
QString labelText;
331-
while ( !connectedTexts->isEmpty() )
320+
Q_FOREACH ( QString labelText, mConnectedTexts )
332321
{
333-
labelText = connectedTexts->takeFirst();
334-
335-
//std::cerr << "JOIN: " << labelText << std::endl;
336-
QHash< QString, QLinkedList<FeaturePart*>* >::const_iterator partsPtr = connectedHashtable->find( labelText );
337-
if ( partsPtr == connectedHashtable->constEnd() )
322+
if ( !mConnectedHashtable.contains( labelText ) )
338323
continue; // shouldn't happen
339-
QLinkedList<FeaturePart*>* parts = *partsPtr;
324+
325+
QLinkedList<FeaturePart*>* parts = mConnectedHashtable.value( labelText );
340326

341327
// go one-by-one part, try to merge
342328
while ( !parts->isEmpty() )
@@ -365,18 +351,22 @@ namespace pal
365351
otherPart->getBoundingBox( bmin, bmax );
366352
rtree->Insert( bmin, bmax, otherPart );
367353
}
354+
delete partCheck;
368355
}
369356
}
370357

371358
// we're done processing feature parts with this particular label text
372359
delete parts;
360+
mConnectedHashtable.remove( labelText );
373361
}
374362

375-
// we're done processing connected fetures
376-
delete connectedHashtable;
377-
connectedHashtable = NULL;
378-
delete connectedTexts;
379-
connectedTexts = NULL;
363+
// we're done processing connected features
364+
365+
//should be empty, but clear to be safe
366+
qDeleteAll( mConnectedHashtable );
367+
mConnectedHashtable.clear();
368+
369+
mConnectedTexts.clear();
380370
}
381371

382372
void Layer::chopFeaturesAtRepeatDistance()

‎src/core/pal/layer.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ namespace pal
7979

8080
/** Returns the number of features in layer.
8181
*/
82-
int featureCount() { return features->size(); }
82+
int featureCount() { return features.size(); }
8383

8484
/** Returns the layer's name.
8585
*/
@@ -282,7 +282,7 @@ namespace pal
282282
QLinkedList<FeaturePart*> *featureParts;
283283

284284
/** List of features - for deletion */
285-
QLinkedList<Feature*> *features;
285+
QList<Feature*> features;
286286

287287
Pal *pal;
288288

@@ -306,10 +306,10 @@ namespace pal
306306

307307
// indexes (spatial and id)
308308
RTree<FeaturePart*, double, 2, double, 8, 4> *rtree;
309-
QHash< QString, Feature*> *hashtable;
309+
QHash< QString, Feature*> mHashtable;
310310

311-
QHash< QString, QLinkedList<FeaturePart*>* >* connectedHashtable;
312-
QLinkedList< QString >* connectedTexts;
311+
QHash< QString, QLinkedList<FeaturePart*>* > mConnectedHashtable;
312+
QStringList mConnectedTexts;
313313

314314
QMutex mMutex;
315315

‎src/core/pal/pal.cpp

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -217,24 +217,21 @@ namespace pal
217217
}
218218

219219
// generate candidates for the feature part
220-
LabelPosition** lPos = NULL;
221-
int nblp = ft_ptr->setPosition( &lPos, context->bbox_min, context->bbox_max, ft_ptr, context->candidates );
222-
223-
if ( nblp > 0 )
220+
QList< LabelPosition* > lPos;
221+
if ( ft_ptr->setPosition( lPos, context->bbox_min, context->bbox_max, ft_ptr, context->candidates ) )
224222
{
225223
// valid features are added to fFeats
226224
Feats *ft = new Feats();
227225
ft->feature = ft_ptr;
228226
ft->shape = NULL;
229-
ft->nblp = nblp;
230227
ft->lPos = lPos;
231228
ft->priority = ft_ptr->getFeature()->calculatePriority();
232229
context->fFeats->append( ft );
233230
}
234231
else
235232
{
236233
// Others are deleted
237-
delete[] lPos;
234+
qDeleteAll( lPos );
238235
}
239236

240237
return true;
@@ -386,6 +383,12 @@ namespace pal
386383

387384
if ( isCancelled() )
388385
{
386+
Q_FOREACH ( Feats* feat, *fFeats )
387+
{
388+
qDeleteAll( feat->lPos );
389+
feat->lPos.clear();
390+
}
391+
389392
qDeleteAll( *fFeats );
390393
delete fFeats;
391394
delete prob;
@@ -397,9 +400,7 @@ namespace pal
397400
for ( i = 0; i < prob->nbft; i++ ) /* foreach feature into prob */
398401
{
399402
feat = fFeats->takeFirst();
400-
#ifdef _DEBUG_FULL_
401-
std::cout << "Feature:" << feat->feature->getLayer()->getName() << "/" << feat->feature->getUID() << " candidates " << feat->nblp << std::endl;
402-
#endif
403+
403404
prob->featStartId[i] = idlp;
404405
prob->inactiveCost[i] = pow( 2, 10 - 10 * feat->priority );
405406

@@ -419,24 +420,20 @@ namespace pal
419420
// sort candidates by cost, skip less interesting ones, calculate polygon costs (if using polygons)
420421
max_p = CostCalculator::finalizeCandidatesCosts( feat, max_p, obstacles, bbx, bby );
421422

422-
#ifdef _DEBUG_FULL_
423-
std::cout << "All costs are set" << std::endl;
424-
#endif
425423
// only keep the 'max_p' best candidates
426-
for ( j = max_p; j < feat->nblp; j++ )
424+
while ( feat->lPos.count() > max_p )
427425
{
428426
// TODO remove from index
429-
feat->lPos[j]->removeFromIndex( prob->candidates );
430-
delete feat->lPos[j];
427+
feat->lPos.last()->removeFromIndex( prob->candidates );
428+
delete feat->lPos.takeLast();
431429
}
432-
feat->nblp = max_p;
433430

434431
// update problem's # candidate
435-
prob->featNbLp[i] = feat->nblp;
436-
prob->nblp += feat->nblp;
432+
prob->featNbLp[i] = feat->lPos.count();
433+
prob->nblp += feat->lPos.count();
437434

438435
// add all candidates into a rtree (to speed up conflicts searching)
439-
for ( j = 0; j < feat->nblp; j++, idlp++ )
436+
for ( j = 0; j < feat->lPos.count(); j++, idlp++ )
440437
{
441438
lp = feat->lPos[j];
442439
//lp->insertIntoIndex(prob->candidates);
@@ -445,26 +442,20 @@ namespace pal
445442
fFeats->append( feat );
446443
}
447444

448-
#ifdef _DEBUG_FULL_
449-
std::cout << "Malloc problem...." << std::endl;
450-
#endif
451-
452-
453445
idlp = 0;
454446
int nbOverlaps = 0;
455447
prob->labelpositions = new LabelPosition*[prob->nblp];
456-
//prob->feat = new int[prob->nblp];
457-
458-
#ifdef _DEBUG_FULL_
459-
std::cout << "problem malloc'd" << std::endl;
460-
#endif
461-
462448

463-
j = 0;
464449
while ( fFeats->size() > 0 ) // foreach feature
465450
{
466451
if ( isCancelled() )
467452
{
453+
Q_FOREACH ( Feats* feat, *fFeats )
454+
{
455+
qDeleteAll( feat->lPos );
456+
feat->lPos.clear();
457+
}
458+
468459
qDeleteAll( *fFeats );
469460
delete fFeats;
470461
delete prob;
@@ -473,9 +464,9 @@ namespace pal
473464
}
474465

475466
feat = fFeats->takeFirst();
476-
for ( i = 0; i < feat->nblp; i++, idlp++ ) // foreach label candidate
467+
while ( !feat->lPos.isEmpty() ) // foreach label candidate
477468
{
478-
lp = feat->lPos[i];
469+
lp = feat->lPos.takeFirst();
479470
lp->resetNumOverlaps();
480471

481472
// make sure that candidate's cost is less than 1
@@ -490,12 +481,8 @@ namespace pal
490481
prob->candidates->Search( amin, amax, LabelPosition::countOverlapCallback, ( void* ) lp );
491482

492483
nbOverlaps += lp->getNumOverlaps();
493-
#ifdef _DEBUG_FULL_
494-
std::cout << "Nb overlap for " << idlp << "/" << prob->nblp - 1 << " : " << lp->getNumOverlaps() << std::endl;
495-
#endif
484+
idlp++;
496485
}
497-
j++;
498-
delete[] feat->lPos;
499486
delete feat;
500487
}
501488
delete fFeats;

‎src/core/pal/pointset.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,8 @@ namespace pal
239239

240240
void PointSet::deleteCoords()
241241
{
242-
if ( x )
243-
delete[] x;
244-
if ( y )
245-
delete[] y;
242+
delete[] x;
243+
delete[] y;
246244
x = NULL;
247245
y = NULL;
248246
}

‎src/core/pal/util.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,15 @@ namespace pal
5050
class Feats
5151
{
5252
public:
53+
Feats()
54+
: feature( 0 )
55+
, shape( 0 )
56+
{}
57+
5358
FeaturePart *feature;
5459
PointSet *shape;
5560
double priority;
56-
int nblp;
57-
LabelPosition **lPos;
61+
QList< LabelPosition*> lPos;
5862
};
5963

6064

0 commit comments

Comments
 (0)
Please sign in to comment.