34 #define _CRT_SECURE_NO_DEPRECATE
49 #include "linkedlist.hpp"
50 #include "hashtable.hpp"
61 Layer::Layer(
const char *lyrName,
double min_scale,
double max_scale,
Arrangement arrangement,
Units label_unit,
double defaultPriority,
bool obstacle,
bool active,
bool toLabel,
Pal *pal,
bool displayAll )
63 , obstacle( obstacle )
66 , displayAll( displayAll )
67 , centroidInside( false )
68 , label_unit( label_unit )
69 , min_scale( min_scale )
70 , max_scale( max_scale )
71 , arrangement( arrangement )
72 , arrangementFlags( 0 )
73 , mode( LabelPerFeature )
75 , upsidedownLabels( Upright )
78 this->
name =
new char[strlen( lyrName ) +1];
79 strcpy( this->
name, lyrName );
89 if ( defaultPriority < 0.0001 )
90 this->defaultPriority = 0.0001;
91 else if ( defaultPriority > 1.0 )
92 this->defaultPriority = 1.0;
140 return ( fptr ? *fptr : NULL );
230 if ( priority >= 1.0 )
232 else if ( priority <= 0.0001 )
241 double labelPosX,
double labelPosY,
bool fixedPos,
double angle,
bool fixedAngle,
242 int xQuadOffset,
int yQuadOffset,
double xOffset,
double yOffset,
bool alwaysShow,
double repeatDistance )
244 if ( !geom_id || label_x < 0 || label_y < 0 )
260 Feature* f =
new Feature(
this, geom_id, userGeom, label_x, label_y );
265 if ( xQuadOffset != 0 || yQuadOffset != 0 )
269 if ( xOffset != 0.0 || yOffset != 0.0 )
278 if ( !fixedPos && angle != 0.0 )
286 bool first_feat =
true;
288 double geom_size = -1, biggest_size = -1;
293 if ( simpleGeometries == NULL )
301 while ( simpleGeometries->size() > 0 )
303 const GEOSGeometry* geom = simpleGeometries->pop_front();
306 if ( GEOSisValid_r( geosctxt, geom ) != 1 )
308 std::cerr <<
"ignoring invalid feature " << geom_id << std::endl;
312 int type = GEOSGeomTypeId_r( geosctxt, geom );
314 if ( type != GEOS_POINT && type != GEOS_LINESTRING && type != GEOS_POLYGON )
323 if (( type == GEOS_LINESTRING && fpart->
nbPoints < 2 ) ||
324 ( type == GEOS_POLYGON && fpart->
nbPoints < 3 ) )
339 if ( type == GEOS_LINESTRING )
340 GEOSLength_r( geosctxt, geom, &geom_size );
341 else if ( type == GEOS_POLYGON )
342 GEOSArea_r( geosctxt, geom, &geom_size );
344 if ( geom_size > biggest_size )
346 biggest_size = geom_size;
348 biggest_part = fpart;
359 delete simpleGeometries;
396 rtree->Insert( bmin, bmax, fpart );
403 if ( lstPtr == NULL )
409 char* txt =
new char[strlen( labelText ) +1];
410 strcpy( txt, labelText );
417 lst->push_back( fpart );
424 if ( label_unit ==
PIXEL || label_unit ==
METER )
464 while ( parts->size() )
475 double bmin[2], bmax[2];
477 rtree->Remove( bmin, bmax, partCheck );
486 rtree->Remove( bmin, bmax, otherPart );
488 rtree->Insert( bmin, bmax, otherPart );
512 const GEOSGeometry* geom = fpart->getGeometry();
513 double chopInterval = fpart->getFeature()->repeatDistance();
514 if ( chopInterval != 0. && GEOSGeomTypeId_r( geosctxt, geom ) == GEOS_LINESTRING )
517 double bmin[2], bmax[2];
518 fpart->getBoundingBox( bmin, bmax );
519 rtree->Remove( bmin, bmax, fpart );
521 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq_r( geosctxt, geom );
525 GEOSCoordSeq_getSize_r( geosctxt, cs, &n );
528 std::vector<Point> points( n );
529 for (
unsigned int i = 0; i < n; ++i )
531 GEOSCoordSeq_getX_r( geosctxt, cs, i, &points[i].x );
532 GEOSCoordSeq_getY_r( geosctxt, cs, i, &points[i].y );
536 std::vector<double> len( n, 0 );
537 for (
unsigned int i = 1; i < n; ++i )
539 double dx = points[i].x - points[i - 1].x;
540 double dy = points[i].y - points[i - 1].y;
541 len[i] = len[i - 1] + std::sqrt( dx * dx + dy * dy );
545 unsigned int cur = 0;
547 std::vector<Point> part;
550 lambda += chopInterval;
551 for ( ; cur < n && lambda > len[cur]; ++cur )
553 part.push_back( points[cur] );
559 double c = ( lambda - len[cur - 1] ) / ( len[cur] - len[cur - 1] );
561 p.
x = points[cur - 1].x + c * ( points[cur].x - points[cur - 1].x );
562 p.
y = points[cur - 1].y + c * ( points[cur].y - points[cur - 1].y );
564 GEOSCoordSequence* cooSeq = GEOSCoordSeq_create_r( geosctxt, part.size(), 2 );
565 for ( std::size_t i = 0; i < part.size(); ++i )
567 GEOSCoordSeq_setX_r( geosctxt, cooSeq, i, part[i].x );
568 GEOSCoordSeq_setY_r( geosctxt, cooSeq, i, part[i].y );
571 GEOSGeometry* newgeom = GEOSGeom_createLineString_r( geosctxt, cooSeq );
573 newFeatureParts->push_back( newfpart );
575 rtree->Insert( bmin, bmax, newfpart );
580 part.push_back( points[n - 1] );
581 GEOSCoordSequence* cooSeq = GEOSCoordSeq_create_r( geosctxt, part.size(), 2 );
582 for ( std::size_t i = 0; i < part.size(); ++i )
584 GEOSCoordSeq_setX_r( geosctxt, cooSeq, i, part[i].x );
585 GEOSCoordSeq_setY_r( geosctxt, cooSeq, i, part[i].y );
588 GEOSGeometry* newgeom = GEOSGeom_createLineString_r( geosctxt, cooSeq );
590 newFeatureParts->push_back( newfpart );
592 rtree->Insert( bmin, bmax, newfpart );
596 newFeatureParts->push_back( fpart );
Arrangement arrangement
optional flags used for some placement methods
void setObstacle(bool obstacle)
mark layer's features as obstacles
int reorderPolygon(int nbPoints, double *x, double *y)
bool isObstacle()
return the obstacle status
void setMaxScale(double max_scale)
set the maximum valid scale, upon this scale the layer will not be labelled
void addFeaturePart(FeaturePart *fpart, const char *labelText=NULL)
add newly creted feature part into r tree and to the list
LinkedList< const GEOSGeometry * > * unmulti(const GEOSGeometry *the_geom)
bool isScaleValid(double scale)
check if the scal is in the scale range min_scale -> max_scale
double getPriority()
return the layer's priority
LinkedList< FeaturePart * > * featureParts
list of feature parts
void setFixedAngle(double a)
bool isActive()
return the layer's activity status
void setPriority(double priority)
\ brief set the layer priority
static FeaturePart * _findConnectedPart(FeaturePart *partCheck, LinkedList< FeaturePart * > *otherParts)
Units getLabelUnit()
get units for label size
LinkedList< char * > * connectedTexts
Feature * getFeature(const char *geom_id)
return pointer to feature or NULL if doesn't exist
int getNbFeatures()
get the number of features into layer
double getMaxScale()
return the maximum valid scale
void setArrangement(Arrangement arrangement)
set arrangement policy
void setPosOffset(double x, double y)
double getMinScale()
return the minimum valid scale
bool ptrFeaturePartCompare(FeaturePart *a, FeaturePart *b)
void setQuadOffset(double x, double y)
virtual const GEOSGeometry * getGeosGeometry()=0
get the GEOSGeometry of the feature This method is called by Pal each time it needs a geom's coordina...
bool mergeWithFeaturePart(FeaturePart *other)
merge other (connected) part with this one and save the result in this part (other is unchanged)...
void setMinScale(double min_scale)
set the minimum valid scale, below this scale the layer will not be labelled
void setAlwaysShow(bool bl)
void setRepeatDistance(double dist)
bool isConnected(FeaturePart *p2)
check whether this part is connected with some other part
void setLabelUnit(Units label_unit)
set unit for label size
GEOSContextHandle_t geosContext()
Get GEOS context handle to be used in all GEOS library calls with reentrant API.
HashTable< Feature * > * hashtable
Main class to handle feature.
Thrown when a geometry type is not like expected.
Layer(const char *lyrName, double min_scale, double max_scale, Arrangement arrangement, Units label_unit, double defaultPriority, bool obstacle, bool active, bool toLabel, Pal *pal, bool displayAll=false)
Create a new layer.
bool isToLabel()
return if the layer will be labelled or not
Arrangement getArrangement()
get arrangement policy
double ANALYSIS_EXPORT angle(Point3D *p1, Point3D *p2, Point3D *p3, Point3D *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
bool strCompare(char *a, char *b)
bool registerFeature(const char *geom_id, PalGeometry *userGeom, double label_x=-1, double label_y=-1, const char *labelText=NULL, double labelPosX=0.0, double labelPosY=0.0, bool fixedPos=false, double angle=0.0, bool fixedAngle=false, int xQuadOffset=0, int yQuadOffset=0, double xOffset=0.0, double yOffset=0.0, bool alwaysShow=false, double repeatDistance=0)
register a feature in the layer
void getBoundingBox(double min[2], double max[2]) const
void joinConnectedFeatures()
join connected features with the same label text
const char * getName()
get layer's name
void setFixedPosition(double x, double y)
virtual ~Layer()
Delete the layer.
enum _arrangement Arrangement
typedef for _arrangement enumeration
void setActive(bool active)
activate or desactivate the layer
LinkedList< Feature * > * features
list of features - for deletion
void chopFeaturesAtRepeatDistance()
chop layer features at the repeat distance
HashTable< LinkedList< FeaturePart * > * > * connectedHashtable
Interface that allows Pal to access user's geometries.
RTree< FeaturePart *, double, 2, double, 8, 4 > * rtree
virtual void releaseGeosGeometry(const GEOSGeometry *the_geom)=0
Called by Pal when it doesn't need the coordinates anymore.
void setToLabel(bool toLabel)
tell pal whether the layer has to be labelled.
enum _Units Units
Typedef for _Units enumeration.
bool ptrFeatureCompare(Feature *a, Feature *b)
bool fixedPosition() const