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 );
74 rtree =
new RTree<FeaturePart*, double, 2, double>();
75 hashtable =
new HashTable<Feature*> ( 5281 );
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;
283 LinkedList <const GEOSGeometry*> *simpleGeometries =
unmulti( the_geom );
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 );
393 LinkedList< FeaturePart*>* lst;
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 )
428 Cell<FeaturePart*>* p = otherParts->getFirst();
452 LinkedList<FeaturePart*>* parts = *partsPtr;
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 );