Skip to content

Commit 1325b98

Browse files
committedJul 23, 2015
[pal] Simplify handling of layers
1 parent d252936 commit 1325b98

File tree

3 files changed

+73
-161
lines changed

3 files changed

+73
-161
lines changed
 

‎src/core/pal/layer.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ namespace pal
7373
ShowAll // show upside down for all labels, including dynamic ones
7474
};
7575

76+
virtual ~Layer();
77+
7678
bool displayAll() const { return mDisplayAll; }
7779

7880
/** Returns the number of features in layer.
@@ -326,11 +328,6 @@ namespace pal
326328
*/
327329
Layer( const QString& lyrName, Arrangement arrangement, double defaultPriority, bool obstacle, bool active, bool toLabel, Pal *pal, bool displayAll = false );
328330

329-
/**
330-
* \brief Delete the layer
331-
*/
332-
virtual ~Layer();
333-
334331
/** Add newly created feature part into r tree and to the list */
335332
void addFeaturePart( FeaturePart* fpart, const QString &labelText = QString() );
336333
};

‎src/core/pal/pal.cpp

Lines changed: 61 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,6 @@ namespace pal
8383
fnIsCancelled = 0;
8484
fnIsCancelledContext = 0;
8585

86-
layers = new QList<Layer*>();
87-
8886
ejChainDeg = 50;
8987
tenure = 10;
9088
candListSize = 0.2;
@@ -109,88 +107,74 @@ namespace pal
109107

110108
}
111109

112-
QList<Layer*> *Pal::getLayers()
110+
QList<Layer*> Pal::getLayers()
113111
{
114112
// TODO make const ! or whatever else
115-
return layers;
113+
return mLayers.values();
116114
}
117115

118-
Layer *Pal::getLayer( const QString& lyrName )
116+
Layer *Pal::getLayer( const QString& layerName )
119117
{
120118
mMutex.lock();
121-
for ( QList<Layer*>::iterator it = layers->begin(); it != layers->end(); ++it )
122-
if (( *it )->name() == lyrName )
123-
{
124-
mMutex.unlock();
125-
return *it;
126-
}
119+
if ( !mLayers.contains( layerName ) )
120+
{
121+
mMutex.unlock();
122+
throw new PalException::UnknownLayer();
123+
}
127124

125+
Layer* result = mLayers.value( layerName );
128126
mMutex.unlock();
129-
throw new PalException::UnknownLayer();
127+
return result;
130128
}
131129

132-
133130
void Pal::removeLayer( Layer *layer )
134131
{
132+
if ( !layer )
133+
return;
134+
135135
mMutex.lock();
136-
if ( layer )
136+
QString key = mLayers.key( layer, QString() );
137+
if ( !key.isEmpty() )
137138
{
138-
layers->removeOne( layer );
139-
delete layer;
139+
mLayers.remove( key );
140140
}
141+
delete layer;
141142
mMutex.unlock();
142143
}
143144

144-
145145
Pal::~Pal()
146146
{
147147

148148
mMutex.lock();
149-
while ( layers->size() > 0 )
150-
{
151-
delete layers->front();
152-
layers->pop_front();
153-
}
154149

155-
delete layers;
150+
qDeleteAll( mLayers );
151+
mLayers.clear();
156152
mMutex.unlock();
157153

158154
// do not init and exit GEOS - we do it inside QGIS
159155
//finishGEOS();
160156
}
161157

162-
163-
Layer * Pal::addLayer( const QString &lyrName, Arrangement arrangement, double defaultPriority, bool obstacle, bool active, bool toLabel, bool displayAll )
158+
Layer* Pal::addLayer( const QString &layerName, Arrangement arrangement, double defaultPriority, bool obstacle, bool active, bool toLabel, bool displayAll )
164159
{
165-
Layer *lyr;
166160
mMutex.lock();
167161

168-
#ifdef _DEBUG_
169-
std::cout << "Pal::addLayer" << std::endl;
170-
std::cout << "lyrName:" << lyrName << std::endl;
171-
std::cout << "nbLayers:" << layers->size() << std::endl;
172-
#endif
173-
174-
for ( QList<Layer*>::iterator it = layers->begin(); it != layers->end(); ++it )
162+
//check if layer is already known
163+
if ( mLayers.contains( layerName ) )
175164
{
176-
if (( *it )->name() == lyrName ) // if layer already known
177-
{
178-
mMutex.unlock();
179-
//There is already a layer with this name, so we just return the existing one.
180-
//Sometimes the same layer is added twice (e.g. datetime split with otf-reprojection)
181-
return *it;
182-
}
165+
mMutex.unlock();
166+
//There is already a layer with this name, so we just return the existing one.
167+
//Sometimes the same layer is added twice (e.g. datetime split with otf-reprojection)
168+
return mLayers.value( layerName );
183169
}
184170

185-
lyr = new Layer( lyrName, arrangement, defaultPriority, obstacle, active, toLabel, this, displayAll );
186-
layers->push_back( lyr );
187-
171+
Layer* layer = new Layer( layerName, arrangement, defaultPriority, obstacle, active, toLabel, this, displayAll );
172+
mLayers.insert( layerName, layer );
188173
mMutex.unlock();
189174

190-
return lyr;
175+
return layer;
191176
}
192177

193-
194178
typedef struct _featCbackCtx
195179
{
196180
Layer *layer;
@@ -302,7 +286,7 @@ namespace pal
302286
return true;
303287
}
304288

305-
Problem* Pal::extract( int nbLayers, const QStringList& layersName, double lambda_min, double phi_min, double lambda_max, double phi_max )
289+
Problem* Pal::extract( const QStringList& layerNames, double lambda_min, double phi_min, double lambda_max, double phi_max )
306290
{
307291
// to store obstacles
308292
RTree<FeaturePart*, double, 2, double> *obstacles = new RTree<FeaturePart*, double, 2, double>();
@@ -341,75 +325,50 @@ namespace pal
341325
context->bbox_max[0] = amax[0];
342326
context->bbox_max[1] = amax[1];
343327

344-
#ifdef _VERBOSE_
345-
std::cout << nbLayers << "/" << layers->size() << " layers to extract " << std::endl;
346-
#endif
347-
328+
// first step : extract features from layers
348329

349-
/* First step : extract feature from layers
350-
*
351-
* */
352-
int oldNbft = 0;
330+
int previousFeatureCount = 0;
353331
Layer *layer;
354332

355-
QStringList labLayers;
333+
QStringList layersWithFeaturesInBBox;
356334

357335
mMutex.lock();
358-
for ( i = 0; i < nbLayers; i++ )
336+
Q_FOREACH ( QString layerName, layerNames )
359337
{
360-
for ( QList<Layer*>::iterator it = layers->begin(); it != layers->end(); ++it ) // iterate on pal->layers
338+
layer = mLayers.value( layerName, 0 );
339+
if ( !layer )
361340
{
362-
layer = *it;
363-
// Only select those who are active and labellable or those who are active and which must be treated as obstaclewhich must be treated as obstacle
364-
if ( layer->active()
365-
&& ( layer->obstacle() || layer->labelLayer() ) )
366-
{
367-
368-
// check if this selected layers has been selected by user
369-
if ( layersName.at( i ) == layer->name() )
370-
{
371-
// check for connected features with the same label text and join them
372-
if ( layer->mergeConnectedLines() )
373-
layer->joinConnectedFeatures();
374-
375-
layer->chopFeaturesAtRepeatDistance();
376-
341+
// invalid layer name
342+
continue;
343+
}
377344

378-
context->layer = layer;
379-
// lookup for feature (and generates candidates list)
345+
// only select those who are active
346+
if ( !layer->active() )
347+
continue;
380348

381-
context->layer->mMutex.lock();
382-
context->layer->rtree->Search( amin, amax, extractFeatCallback, ( void* ) context );
383-
context->layer->mMutex.unlock();
349+
// check for connected features with the same label text and join them
350+
if ( layer->mergeConnectedLines() )
351+
layer->joinConnectedFeatures();
384352

385-
#ifdef _VERBOSE_
386-
std::cout << "Layer's name: " << layer->getName() << std::endl;
387-
std::cout << " active:" << layer->isToLabel() << std::endl;
388-
std::cout << " obstacle:" << layer->isObstacle() << std::endl;
389-
std::cout << " toLabel:" << layer->isToLabel() << std::endl;
390-
std::cout << " # features: " << layer->getNbFeatures() << std::endl;
391-
std::cout << " # extracted features: " << context->fFeats->size() - oldNbft << std::endl;
392-
#endif
393-
if ( context->fFeats->size() - oldNbft > 0 )
394-
{
395-
labLayers << layer->name();
396-
}
397-
oldNbft = context->fFeats->size();
353+
layer->chopFeaturesAtRepeatDistance();
398354

355+
// find features within bounding box and generate candidates list
356+
context->layer = layer;
357+
context->layer->mMutex.lock();
358+
context->layer->rtree->Search( amin, amax, extractFeatCallback, ( void* ) context );
359+
context->layer->mMutex.unlock();
399360

400-
break;
401-
}
402-
}
361+
if ( context->fFeats->size() - previousFeatureCount > 0 )
362+
{
363+
layersWithFeaturesInBBox << layer->name();
403364
}
365+
previousFeatureCount = context->fFeats->size();
404366
}
405367
delete context;
406368
mMutex.unlock();
407369

408-
prob->nbLabelledLayers = labLayers.size();
409-
for ( i = 0; i < prob->nbLabelledLayers; i++ )
410-
{
411-
prob->labelledLayersName << labLayers.takeFirst();
412-
}
370+
prob->nbLabelledLayers = layersWithFeaturesInBBox.size();
371+
prob->labelledLayersName = layersWithFeaturesInBBox;
413372

414373
if ( fFeats->size() == 0 )
415374
{
@@ -577,36 +536,13 @@ namespace pal
577536

578537
std::list<LabelPosition*>* Pal::labeller( double bbox[4], PalStat **stats, bool displayAll )
579538
{
580-
581-
#ifdef _DEBUG_FULL_
582-
std::cout << "LABELLER (active)" << std::endl;
583-
#endif
584-
int i;
585-
586-
mMutex.lock();
587-
int nbLayers = layers->size();
588-
589-
QStringList layersName;
590-
Layer *layer;
591-
i = 0;
592-
for ( QList<Layer*>::iterator it = layers->begin(); it != layers->end(); ++it )
593-
{
594-
layer = *it;
595-
layersName << layer->name();
596-
i++;
597-
}
598-
mMutex.unlock();
599-
600-
std::list<LabelPosition*> * solution = labeller( nbLayers, layersName, bbox, stats, displayAll );
601-
602-
return solution;
539+
return labeller( mLayers.keys(), bbox, stats, displayAll );
603540
}
604541

605-
606542
/*
607543
* BIG MACHINE
608544
*/
609-
std::list<LabelPosition*>* Pal::labeller( int nbLayers, const QStringList& layersName, double bbox[4], PalStat **stats, bool displayAll )
545+
std::list<LabelPosition*>* Pal::labeller( const QStringList& layerNames, double bbox[4], PalStat **stats, bool displayAll )
610546
{
611547
#ifdef _DEBUG_
612548
std::cout << "LABELLER (selection)" << std::endl;
@@ -631,7 +567,7 @@ namespace pal
631567
t.start();
632568

633569
// First, extract the problem
634-
if (( prob = extract( nbLayers, layersName, bbox[0], bbox[1], bbox[2], bbox[3] ) ) == NULL )
570+
if (( prob = extract( layerNames, bbox[0], bbox[1], bbox[2], bbox[3] ) ) == NULL )
635571
{
636572
// nothing to be done => return an empty result set
637573
if ( stats )
@@ -706,24 +642,7 @@ namespace pal
706642

707643
Problem* Pal::extractProblem( double bbox[4] )
708644
{
709-
// find out: nbLayers, layersName, layersFactor
710-
mMutex.lock();
711-
int nbLayers = layers->size();
712-
713-
QStringList layersName;
714-
Layer *layer;
715-
int i = 0;
716-
for ( QList<Layer*>::iterator it = layers->begin(); it != layers->end(); ++it )
717-
{
718-
layer = *it;
719-
layersName << layer->name();
720-
i++;
721-
}
722-
mMutex.unlock();
723-
724-
Problem* prob = extract( nbLayers, layersName, bbox[0], bbox[1], bbox[2], bbox[3] );
725-
726-
return prob;
645+
return extract( mLayers.keys(), bbox[0], bbox[1], bbox[2], bbox[3] );
727646
}
728647

729648
std::list<LabelPosition*>* Pal::solveProblem( Problem* prob, bool displayAll )

‎src/core/pal/pal.h

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ namespace pal
127127
/**
128128
* \brief add a new layer
129129
*
130-
* @param lyrName layer's name
130+
* @param layerName layer's name
131131
* @param arrangement Howto place candidates
132132
* @param defaultPriority layer's prioriry (0 is the best, 1 the worst)
133133
* @param obstacle 'true' will discourage other label to be placed above features of this layer
@@ -139,25 +139,25 @@ namespace pal
139139
*
140140
* @todo add symbolUnit
141141
*/
142-
Layer* addLayer( const QString& lyrName, Arrangement arrangement, double defaultPriority, bool obstacle, bool active, bool toLabel, bool displayAll = false );
142+
Layer* addLayer( const QString& layerName, Arrangement arrangement, double defaultPriority, bool obstacle, bool active, bool toLabel, bool displayAll = false );
143143

144144
/**
145145
* \brief Look for a layer
146146
*
147-
* @param lyrName name of layer to search
147+
* @param layerName name of layer to search
148148
*
149149
* @throws PalException::UnkownLayer
150150
*
151151
* @return a pointer on layer or NULL if layer not exist
152152
*/
153-
Layer *getLayer( const QString &lyrName );
153+
Layer *getLayer( const QString &layerName );
154154

155155
/**
156156
* \brief get all layers
157157
*
158158
* @return a list of all layers
159159
*/
160-
QList<Layer*> *getLayers();
160+
QList<Layer*> getLayers();
161161

162162
/**
163163
* \brief remove a layer
@@ -182,9 +182,7 @@ namespace pal
182182
* \brief the labeling machine
183183
* Active layers are specifiend through layersName array
184184
* @todo add obstacles and tolabel arrays
185-
*
186-
* @param nbLayers # layers
187-
* @param layersName names of layers to label
185+
* @param layerNames names of layers to label
188186
* @param bbox map extent
189187
* @param stat will be filled with labelling process statistics, can be NULL
190188
* @param displayAll if true, all feature will be labelled even though overlaps occur
@@ -193,8 +191,7 @@ namespace pal
193191
*
194192
* @return A list of label to display on map
195193
*/
196-
std::list<LabelPosition*> *labeller( int nbLayers,
197-
const QStringList &layersName,
194+
std::list<LabelPosition*> *labeller( const QStringList& layerNames,
198195
double bbox[4],
199196
PalStat **stat,
200197
bool displayAll );
@@ -282,7 +279,8 @@ namespace pal
282279
SearchMethod getSearch();
283280

284281
private:
285-
QList<Layer*> *layers;
282+
283+
QHash< QString, Layer* > mLayers;
286284

287285
QMutex mMutex;
288286

@@ -329,15 +327,13 @@ namespace pal
329327
* \brief Problem factory
330328
* Extract features to label and generates candidates for them,
331329
* respects to a bounding box
332-
*
333-
* @param nbLayers number of layers to extract
334330
* @param layersName layers name to be extracted
335331
* @param lambda_min xMin bounding-box
336332
* @param phi_min yMin bounding-box
337333
* @param lambda_max xMax bounding-box
338334
* @param phi_max yMax bounding-box
339335
*/
340-
Problem* extract( int nbLayers, const QStringList& layersName,
336+
Problem* extract( const QStringList& layersName,
341337
double lambda_min, double phi_min,
342338
double lambda_max, double phi_max );
343339

0 commit comments

Comments
 (0)
Please sign in to comment.