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 )
62 : pal( pal ), obstacle( obstacle ), active( active ),
63 toLabel( toLabel ), displayAll( displayAll ), centroidInside( false ), label_unit( label_unit ),
64 min_scale( min_scale ), max_scale( max_scale ),
65 arrangement( arrangement ), arrangementFlags( 0 ), mode( LabelPerFeature ), mergeLines( false ),
66 upsidedownLabels( Upright )
69 this->
name =
new char[strlen( lyrName ) +1];
70 strcpy( this->
name, lyrName );
80 if ( defaultPriority < 0.0001 )
81 this->defaultPriority = 0.0001;
82 else if ( defaultPriority > 1.0 )
83 this->defaultPriority = 1.0;
131 return ( fptr ? *fptr : NULL );
221 if ( priority >= 1.0 )
223 else if ( priority <= 0.0001 )
232 double labelPosX,
double labelPosY,
bool fixedPos,
double angle,
bool fixedAngle,
233 int xQuadOffset,
int yQuadOffset,
double xOffset,
double yOffset,
bool alwaysShow,
double repeatDistance )
235 if ( !geom_id || label_x < 0 || label_y < 0 )
251 Feature* f =
new Feature(
this, geom_id, userGeom, label_x, label_y );
256 if ( xQuadOffset != 0 || yQuadOffset != 0 )
260 if ( xOffset != 0.0 || yOffset != 0.0 )
269 if ( !fixedPos && angle != 0.0 )
277 bool first_feat =
true;
279 double geom_size = -1, biggest_size = -1;
284 if ( simpleGeometries == NULL )
292 while ( simpleGeometries->size() > 0 )
294 const GEOSGeometry* geom = simpleGeometries->pop_front();
297 if ( GEOSisValid_r( geosctxt, geom ) != 1 )
299 std::cerr <<
"ignoring invalid feature " << geom_id << std::endl;
303 int type = GEOSGeomTypeId_r( geosctxt, geom );
305 if ( type != GEOS_POINT && type != GEOS_LINESTRING && type != GEOS_POLYGON )
314 if (( type == GEOS_LINESTRING && fpart->
nbPoints < 2 ) ||
315 ( type == GEOS_POLYGON && fpart->
nbPoints < 3 ) )
330 if ( type == GEOS_LINESTRING )
331 GEOSLength_r( geosctxt, geom, &geom_size );
332 else if ( type == GEOS_POLYGON )
333 GEOSArea_r( geosctxt, geom, &geom_size );
335 if ( geom_size > biggest_size )
337 biggest_size = geom_size;
339 biggest_part = fpart;
350 delete simpleGeometries;
387 rtree->Insert( bmin, bmax, fpart );
394 if ( lstPtr == NULL )
400 char* txt =
new char[strlen( labelText ) +1];
401 strcpy( txt, labelText );
408 lst->push_back( fpart );
415 if ( label_unit ==
PIXEL || label_unit ==
METER )
455 while ( parts->size() )
466 double bmin[2], bmax[2];
468 rtree->Remove( bmin, bmax, partCheck );
477 rtree->Remove( bmin, bmax, otherPart );
479 rtree->Insert( bmin, bmax, otherPart );
503 const GEOSGeometry* geom = fpart->getGeometry();
504 double chopInterval = fpart->getFeature()->repeatDistance();
505 if ( chopInterval != 0. && GEOSGeomTypeId_r( geosctxt, geom ) == GEOS_LINESTRING )
508 double bmin[2], bmax[2];
509 fpart->getBoundingBox( bmin, bmax );
510 rtree->Remove( bmin, bmax, fpart );
512 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq_r( geosctxt, geom );
516 GEOSCoordSeq_getSize_r( geosctxt, cs, &n );
519 std::vector<Point> points( n );
520 for (
unsigned int i = 0; i < n; ++i )
522 GEOSCoordSeq_getX_r( geosctxt, cs, i, &points[i].x );
523 GEOSCoordSeq_getY_r( geosctxt, cs, i, &points[i].y );
527 std::vector<double> len( n, 0 );
528 for (
unsigned int i = 1; i < n; ++i )
530 double dx = points[i].x - points[i - 1].x;
531 double dy = points[i].y - points[i - 1].y;
532 len[i] = len[i - 1] + std::sqrt( dx * dx + dy * dy );
536 unsigned int cur = 0;
538 std::vector<Point> part;
541 lambda += chopInterval;
542 for ( ; cur < n && lambda > len[cur]; ++cur )
544 part.push_back( points[cur] );
550 double c = ( lambda - len[cur - 1] ) / ( len[cur] - len[cur - 1] );
552 p.
x = points[cur - 1].x + c * ( points[cur].x - points[cur - 1].x );
553 p.
y = points[cur - 1].y + c * ( points[cur].y - points[cur - 1].y );
555 GEOSCoordSequence* cooSeq = GEOSCoordSeq_create_r( geosctxt, part.size(), 2 );
556 for ( std::size_t i = 0; i < part.size(); ++i )
558 GEOSCoordSeq_setX_r( geosctxt, cooSeq, i, part[i].x );
559 GEOSCoordSeq_setY_r( geosctxt, cooSeq, i, part[i].y );
562 GEOSGeometry* newgeom = GEOSGeom_createLineString_r( geosctxt, cooSeq );
564 newFeatureParts->push_back( newfpart );
566 rtree->Insert( bmin, bmax, newfpart );
571 part.push_back( points[n - 1] );
572 GEOSCoordSequence* cooSeq = GEOSCoordSeq_create_r( geosctxt, part.size(), 2 );
573 for ( std::size_t i = 0; i < part.size(); ++i )
575 GEOSCoordSeq_setX_r( geosctxt, cooSeq, i, part[i].x );
576 GEOSCoordSeq_setY_r( geosctxt, cooSeq, i, part[i].y );
579 GEOSGeometry* newgeom = GEOSGeom_createLineString_r( geosctxt, cooSeq );
581 newFeatureParts->push_back( newfpart );
583 rtree->Insert( bmin, bmax, newfpart );
587 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