mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
[pal] Simplify handling of layers
This commit is contained in:
parent
d252936285
commit
1325b98db6
@ -73,6 +73,8 @@ namespace pal
|
||||
ShowAll // show upside down for all labels, including dynamic ones
|
||||
};
|
||||
|
||||
virtual ~Layer();
|
||||
|
||||
bool displayAll() const { return mDisplayAll; }
|
||||
|
||||
/** Returns the number of features in layer.
|
||||
@ -326,11 +328,6 @@ namespace pal
|
||||
*/
|
||||
Layer( const QString& lyrName, Arrangement arrangement, double defaultPriority, bool obstacle, bool active, bool toLabel, Pal *pal, bool displayAll = false );
|
||||
|
||||
/**
|
||||
* \brief Delete the layer
|
||||
*/
|
||||
virtual ~Layer();
|
||||
|
||||
/** Add newly created feature part into r tree and to the list */
|
||||
void addFeaturePart( FeaturePart* fpart, const QString &labelText = QString() );
|
||||
};
|
||||
|
@ -83,8 +83,6 @@ namespace pal
|
||||
fnIsCancelled = 0;
|
||||
fnIsCancelledContext = 0;
|
||||
|
||||
layers = new QList<Layer*>();
|
||||
|
||||
ejChainDeg = 50;
|
||||
tenure = 10;
|
||||
candListSize = 0.2;
|
||||
@ -109,88 +107,74 @@ namespace pal
|
||||
|
||||
}
|
||||
|
||||
QList<Layer*> *Pal::getLayers()
|
||||
QList<Layer*> Pal::getLayers()
|
||||
{
|
||||
// TODO make const ! or whatever else
|
||||
return layers;
|
||||
return mLayers.values();
|
||||
}
|
||||
|
||||
Layer *Pal::getLayer( const QString& lyrName )
|
||||
Layer *Pal::getLayer( const QString& layerName )
|
||||
{
|
||||
mMutex.lock();
|
||||
for ( QList<Layer*>::iterator it = layers->begin(); it != layers->end(); ++it )
|
||||
if (( *it )->name() == lyrName )
|
||||
{
|
||||
mMutex.unlock();
|
||||
return *it;
|
||||
}
|
||||
if ( !mLayers.contains( layerName ) )
|
||||
{
|
||||
mMutex.unlock();
|
||||
throw new PalException::UnknownLayer();
|
||||
}
|
||||
|
||||
Layer* result = mLayers.value( layerName );
|
||||
mMutex.unlock();
|
||||
throw new PalException::UnknownLayer();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void Pal::removeLayer( Layer *layer )
|
||||
{
|
||||
if ( !layer )
|
||||
return;
|
||||
|
||||
mMutex.lock();
|
||||
if ( layer )
|
||||
QString key = mLayers.key( layer, QString() );
|
||||
if ( !key.isEmpty() )
|
||||
{
|
||||
layers->removeOne( layer );
|
||||
delete layer;
|
||||
mLayers.remove( key );
|
||||
}
|
||||
delete layer;
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
Pal::~Pal()
|
||||
{
|
||||
|
||||
mMutex.lock();
|
||||
while ( layers->size() > 0 )
|
||||
{
|
||||
delete layers->front();
|
||||
layers->pop_front();
|
||||
}
|
||||
|
||||
delete layers;
|
||||
qDeleteAll( mLayers );
|
||||
mLayers.clear();
|
||||
mMutex.unlock();
|
||||
|
||||
// do not init and exit GEOS - we do it inside QGIS
|
||||
//finishGEOS();
|
||||
}
|
||||
|
||||
|
||||
Layer * Pal::addLayer( const QString &lyrName, Arrangement arrangement, double defaultPriority, bool obstacle, bool active, bool toLabel, bool displayAll )
|
||||
Layer* Pal::addLayer( const QString &layerName, Arrangement arrangement, double defaultPriority, bool obstacle, bool active, bool toLabel, bool displayAll )
|
||||
{
|
||||
Layer *lyr;
|
||||
mMutex.lock();
|
||||
|
||||
#ifdef _DEBUG_
|
||||
std::cout << "Pal::addLayer" << std::endl;
|
||||
std::cout << "lyrName:" << lyrName << std::endl;
|
||||
std::cout << "nbLayers:" << layers->size() << std::endl;
|
||||
#endif
|
||||
|
||||
for ( QList<Layer*>::iterator it = layers->begin(); it != layers->end(); ++it )
|
||||
//check if layer is already known
|
||||
if ( mLayers.contains( layerName ) )
|
||||
{
|
||||
if (( *it )->name() == lyrName ) // if layer already known
|
||||
{
|
||||
mMutex.unlock();
|
||||
//There is already a layer with this name, so we just return the existing one.
|
||||
//Sometimes the same layer is added twice (e.g. datetime split with otf-reprojection)
|
||||
return *it;
|
||||
}
|
||||
mMutex.unlock();
|
||||
//There is already a layer with this name, so we just return the existing one.
|
||||
//Sometimes the same layer is added twice (e.g. datetime split with otf-reprojection)
|
||||
return mLayers.value( layerName );
|
||||
}
|
||||
|
||||
lyr = new Layer( lyrName, arrangement, defaultPriority, obstacle, active, toLabel, this, displayAll );
|
||||
layers->push_back( lyr );
|
||||
|
||||
Layer* layer = new Layer( layerName, arrangement, defaultPriority, obstacle, active, toLabel, this, displayAll );
|
||||
mLayers.insert( layerName, layer );
|
||||
mMutex.unlock();
|
||||
|
||||
return lyr;
|
||||
return layer;
|
||||
}
|
||||
|
||||
|
||||
typedef struct _featCbackCtx
|
||||
{
|
||||
Layer *layer;
|
||||
@ -302,7 +286,7 @@ namespace pal
|
||||
return true;
|
||||
}
|
||||
|
||||
Problem* Pal::extract( int nbLayers, const QStringList& layersName, double lambda_min, double phi_min, double lambda_max, double phi_max )
|
||||
Problem* Pal::extract( const QStringList& layerNames, double lambda_min, double phi_min, double lambda_max, double phi_max )
|
||||
{
|
||||
// to store obstacles
|
||||
RTree<FeaturePart*, double, 2, double> *obstacles = new RTree<FeaturePart*, double, 2, double>();
|
||||
@ -341,75 +325,50 @@ namespace pal
|
||||
context->bbox_max[0] = amax[0];
|
||||
context->bbox_max[1] = amax[1];
|
||||
|
||||
#ifdef _VERBOSE_
|
||||
std::cout << nbLayers << "/" << layers->size() << " layers to extract " << std::endl;
|
||||
#endif
|
||||
// first step : extract features from layers
|
||||
|
||||
|
||||
/* First step : extract feature from layers
|
||||
*
|
||||
* */
|
||||
int oldNbft = 0;
|
||||
int previousFeatureCount = 0;
|
||||
Layer *layer;
|
||||
|
||||
QStringList labLayers;
|
||||
QStringList layersWithFeaturesInBBox;
|
||||
|
||||
mMutex.lock();
|
||||
for ( i = 0; i < nbLayers; i++ )
|
||||
Q_FOREACH ( QString layerName, layerNames )
|
||||
{
|
||||
for ( QList<Layer*>::iterator it = layers->begin(); it != layers->end(); ++it ) // iterate on pal->layers
|
||||
layer = mLayers.value( layerName, 0 );
|
||||
if ( !layer )
|
||||
{
|
||||
layer = *it;
|
||||
// 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
|
||||
if ( layer->active()
|
||||
&& ( layer->obstacle() || layer->labelLayer() ) )
|
||||
{
|
||||
|
||||
// check if this selected layers has been selected by user
|
||||
if ( layersName.at( i ) == layer->name() )
|
||||
{
|
||||
// check for connected features with the same label text and join them
|
||||
if ( layer->mergeConnectedLines() )
|
||||
layer->joinConnectedFeatures();
|
||||
|
||||
layer->chopFeaturesAtRepeatDistance();
|
||||
|
||||
|
||||
context->layer = layer;
|
||||
// lookup for feature (and generates candidates list)
|
||||
|
||||
context->layer->mMutex.lock();
|
||||
context->layer->rtree->Search( amin, amax, extractFeatCallback, ( void* ) context );
|
||||
context->layer->mMutex.unlock();
|
||||
|
||||
#ifdef _VERBOSE_
|
||||
std::cout << "Layer's name: " << layer->getName() << std::endl;
|
||||
std::cout << " active:" << layer->isToLabel() << std::endl;
|
||||
std::cout << " obstacle:" << layer->isObstacle() << std::endl;
|
||||
std::cout << " toLabel:" << layer->isToLabel() << std::endl;
|
||||
std::cout << " # features: " << layer->getNbFeatures() << std::endl;
|
||||
std::cout << " # extracted features: " << context->fFeats->size() - oldNbft << std::endl;
|
||||
#endif
|
||||
if ( context->fFeats->size() - oldNbft > 0 )
|
||||
{
|
||||
labLayers << layer->name();
|
||||
}
|
||||
oldNbft = context->fFeats->size();
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
// invalid layer name
|
||||
continue;
|
||||
}
|
||||
|
||||
// only select those who are active
|
||||
if ( !layer->active() )
|
||||
continue;
|
||||
|
||||
// check for connected features with the same label text and join them
|
||||
if ( layer->mergeConnectedLines() )
|
||||
layer->joinConnectedFeatures();
|
||||
|
||||
layer->chopFeaturesAtRepeatDistance();
|
||||
|
||||
// find features within bounding box and generate candidates list
|
||||
context->layer = layer;
|
||||
context->layer->mMutex.lock();
|
||||
context->layer->rtree->Search( amin, amax, extractFeatCallback, ( void* ) context );
|
||||
context->layer->mMutex.unlock();
|
||||
|
||||
if ( context->fFeats->size() - previousFeatureCount > 0 )
|
||||
{
|
||||
layersWithFeaturesInBBox << layer->name();
|
||||
}
|
||||
previousFeatureCount = context->fFeats->size();
|
||||
}
|
||||
delete context;
|
||||
mMutex.unlock();
|
||||
|
||||
prob->nbLabelledLayers = labLayers.size();
|
||||
for ( i = 0; i < prob->nbLabelledLayers; i++ )
|
||||
{
|
||||
prob->labelledLayersName << labLayers.takeFirst();
|
||||
}
|
||||
prob->nbLabelledLayers = layersWithFeaturesInBBox.size();
|
||||
prob->labelledLayersName = layersWithFeaturesInBBox;
|
||||
|
||||
if ( fFeats->size() == 0 )
|
||||
{
|
||||
@ -577,36 +536,13 @@ namespace pal
|
||||
|
||||
std::list<LabelPosition*>* Pal::labeller( double bbox[4], PalStat **stats, bool displayAll )
|
||||
{
|
||||
|
||||
#ifdef _DEBUG_FULL_
|
||||
std::cout << "LABELLER (active)" << std::endl;
|
||||
#endif
|
||||
int i;
|
||||
|
||||
mMutex.lock();
|
||||
int nbLayers = layers->size();
|
||||
|
||||
QStringList layersName;
|
||||
Layer *layer;
|
||||
i = 0;
|
||||
for ( QList<Layer*>::iterator it = layers->begin(); it != layers->end(); ++it )
|
||||
{
|
||||
layer = *it;
|
||||
layersName << layer->name();
|
||||
i++;
|
||||
}
|
||||
mMutex.unlock();
|
||||
|
||||
std::list<LabelPosition*> * solution = labeller( nbLayers, layersName, bbox, stats, displayAll );
|
||||
|
||||
return solution;
|
||||
return labeller( mLayers.keys(), bbox, stats, displayAll );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* BIG MACHINE
|
||||
*/
|
||||
std::list<LabelPosition*>* Pal::labeller( int nbLayers, const QStringList& layersName, double bbox[4], PalStat **stats, bool displayAll )
|
||||
std::list<LabelPosition*>* Pal::labeller( const QStringList& layerNames, double bbox[4], PalStat **stats, bool displayAll )
|
||||
{
|
||||
#ifdef _DEBUG_
|
||||
std::cout << "LABELLER (selection)" << std::endl;
|
||||
@ -631,7 +567,7 @@ namespace pal
|
||||
t.start();
|
||||
|
||||
// First, extract the problem
|
||||
if (( prob = extract( nbLayers, layersName, bbox[0], bbox[1], bbox[2], bbox[3] ) ) == NULL )
|
||||
if (( prob = extract( layerNames, bbox[0], bbox[1], bbox[2], bbox[3] ) ) == NULL )
|
||||
{
|
||||
// nothing to be done => return an empty result set
|
||||
if ( stats )
|
||||
@ -706,24 +642,7 @@ namespace pal
|
||||
|
||||
Problem* Pal::extractProblem( double bbox[4] )
|
||||
{
|
||||
// find out: nbLayers, layersName, layersFactor
|
||||
mMutex.lock();
|
||||
int nbLayers = layers->size();
|
||||
|
||||
QStringList layersName;
|
||||
Layer *layer;
|
||||
int i = 0;
|
||||
for ( QList<Layer*>::iterator it = layers->begin(); it != layers->end(); ++it )
|
||||
{
|
||||
layer = *it;
|
||||
layersName << layer->name();
|
||||
i++;
|
||||
}
|
||||
mMutex.unlock();
|
||||
|
||||
Problem* prob = extract( nbLayers, layersName, bbox[0], bbox[1], bbox[2], bbox[3] );
|
||||
|
||||
return prob;
|
||||
return extract( mLayers.keys(), bbox[0], bbox[1], bbox[2], bbox[3] );
|
||||
}
|
||||
|
||||
std::list<LabelPosition*>* Pal::solveProblem( Problem* prob, bool displayAll )
|
||||
|
@ -127,7 +127,7 @@ namespace pal
|
||||
/**
|
||||
* \brief add a new layer
|
||||
*
|
||||
* @param lyrName layer's name
|
||||
* @param layerName layer's name
|
||||
* @param arrangement Howto place candidates
|
||||
* @param defaultPriority layer's prioriry (0 is the best, 1 the worst)
|
||||
* @param obstacle 'true' will discourage other label to be placed above features of this layer
|
||||
@ -139,25 +139,25 @@ namespace pal
|
||||
*
|
||||
* @todo add symbolUnit
|
||||
*/
|
||||
Layer* addLayer( const QString& lyrName, Arrangement arrangement, double defaultPriority, bool obstacle, bool active, bool toLabel, bool displayAll = false );
|
||||
Layer* addLayer( const QString& layerName, Arrangement arrangement, double defaultPriority, bool obstacle, bool active, bool toLabel, bool displayAll = false );
|
||||
|
||||
/**
|
||||
* \brief Look for a layer
|
||||
*
|
||||
* @param lyrName name of layer to search
|
||||
* @param layerName name of layer to search
|
||||
*
|
||||
* @throws PalException::UnkownLayer
|
||||
*
|
||||
* @return a pointer on layer or NULL if layer not exist
|
||||
*/
|
||||
Layer *getLayer( const QString &lyrName );
|
||||
Layer *getLayer( const QString &layerName );
|
||||
|
||||
/**
|
||||
* \brief get all layers
|
||||
*
|
||||
* @return a list of all layers
|
||||
*/
|
||||
QList<Layer*> *getLayers();
|
||||
QList<Layer*> getLayers();
|
||||
|
||||
/**
|
||||
* \brief remove a layer
|
||||
@ -182,9 +182,7 @@ namespace pal
|
||||
* \brief the labeling machine
|
||||
* Active layers are specifiend through layersName array
|
||||
* @todo add obstacles and tolabel arrays
|
||||
*
|
||||
* @param nbLayers # layers
|
||||
* @param layersName names of layers to label
|
||||
* @param layerNames names of layers to label
|
||||
* @param bbox map extent
|
||||
* @param stat will be filled with labelling process statistics, can be NULL
|
||||
* @param displayAll if true, all feature will be labelled even though overlaps occur
|
||||
@ -193,8 +191,7 @@ namespace pal
|
||||
*
|
||||
* @return A list of label to display on map
|
||||
*/
|
||||
std::list<LabelPosition*> *labeller( int nbLayers,
|
||||
const QStringList &layersName,
|
||||
std::list<LabelPosition*> *labeller( const QStringList& layerNames,
|
||||
double bbox[4],
|
||||
PalStat **stat,
|
||||
bool displayAll );
|
||||
@ -282,7 +279,8 @@ namespace pal
|
||||
SearchMethod getSearch();
|
||||
|
||||
private:
|
||||
QList<Layer*> *layers;
|
||||
|
||||
QHash< QString, Layer* > mLayers;
|
||||
|
||||
QMutex mMutex;
|
||||
|
||||
@ -329,15 +327,13 @@ namespace pal
|
||||
* \brief Problem factory
|
||||
* Extract features to label and generates candidates for them,
|
||||
* respects to a bounding box
|
||||
*
|
||||
* @param nbLayers number of layers to extract
|
||||
* @param layersName layers name to be extracted
|
||||
* @param lambda_min xMin bounding-box
|
||||
* @param phi_min yMin bounding-box
|
||||
* @param lambda_max xMax bounding-box
|
||||
* @param phi_max yMax bounding-box
|
||||
*/
|
||||
Problem* extract( int nbLayers, const QStringList& layersName,
|
||||
Problem* extract( const QStringList& layersName,
|
||||
double lambda_min, double phi_min,
|
||||
double lambda_max, double phi_max );
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user