@@ -62,7 +62,7 @@ namespace pal
62
62
: pal( pal ), obstacle( obstacle ), active( active ),
63
63
toLabel ( toLabel ), label_unit( label_unit ),
64
64
min_scale( min_scale ), max_scale( max_scale ),
65
- arrangement( arrangement ), arrangementFlags( 0 ), mode(LabelPerFeature)
65
+ arrangement( arrangement ), arrangementFlags( 0 ), mode(LabelPerFeature), mergeLines( false )
66
66
{
67
67
68
68
this ->name = new char [strlen ( lyrName ) +1 ];
@@ -73,6 +73,9 @@ namespace pal
73
73
rtree = new RTree<FeaturePart*, double , 2 , double >();
74
74
hashtable = new HashTable<Feature*> ( 5281 );
75
75
76
+ connectedHashtable = new HashTable< LinkedList<FeaturePart*>* > ( 5391 );
77
+ connectedTexts = new LinkedList< char * >( strCompare );
78
+
76
79
if ( defaultPriority < 0.0001 )
77
80
this ->defaultPriority = 0.0001 ;
78
81
else if ( defaultPriority > 1.0 )
@@ -95,8 +98,13 @@ namespace pal
95
98
delete featureParts->pop_front ();
96
99
}
97
100
delete featureParts;
101
+
98
102
}
99
103
104
+ // this hashtable and list should be empty if they still exist
105
+ delete connectedHashtable;
106
+ double connectedTexts;
107
+
100
108
// features in the hashtable
101
109
if ( features )
102
110
{
@@ -219,7 +227,7 @@ namespace pal
219
227
220
228
221
229
222
- bool Layer::registerFeature ( const char *geom_id, PalGeometry *userGeom, double label_x, double label_y )
230
+ bool Layer::registerFeature ( const char *geom_id, PalGeometry *userGeom, double label_x, double label_y, const char * labelText )
223
231
{
224
232
if ( !geom_id || label_x < 0 || label_y < 0 )
225
233
return false ;
@@ -297,7 +305,7 @@ bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double
297
305
}
298
306
299
307
// feature part is ready!
300
- addFeaturePart (fpart);
308
+ addFeaturePart (fpart, labelText );
301
309
302
310
first_feat = false ;
303
311
}
@@ -310,7 +318,7 @@ bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double
310
318
// if using only biggest parts...
311
319
if (mode == LabelPerFeature && biggest_part != NULL )
312
320
{
313
- addFeaturePart (biggest_part);
321
+ addFeaturePart (biggest_part, labelText );
314
322
first_feat = false ;
315
323
}
316
324
@@ -328,7 +336,7 @@ bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double
328
336
return !first_feat; // true if we've added something
329
337
}
330
338
331
- void Layer::addFeaturePart ( FeaturePart* fpart )
339
+ void Layer::addFeaturePart ( FeaturePart* fpart, const char * labelText )
332
340
{
333
341
double bmin[2 ];
334
342
double bmax[2 ];
@@ -339,6 +347,28 @@ void Layer::addFeaturePart( FeaturePart* fpart )
339
347
340
348
// add to r-tree for fast spatial access
341
349
rtree->Insert ( bmin, bmax, fpart );
350
+
351
+ // add to hashtable with equally named feature parts
352
+ if (mergeLines && labelText)
353
+ {
354
+ LinkedList< FeaturePart*>** lstPtr = connectedHashtable->find (labelText);
355
+ LinkedList< FeaturePart*>* lst;
356
+ if (lstPtr == NULL )
357
+ {
358
+ // entry doesn't exist yet
359
+ lst = new LinkedList<FeaturePart*>( ptrFeaturePartCompare );
360
+ connectedHashtable->insertItem (labelText, lst);
361
+
362
+ char * txt = new char [strlen (labelText) +1 ];
363
+ strcpy (txt, labelText);
364
+ connectedTexts->push_back (txt);
365
+ }
366
+ else
367
+ {
368
+ lst = *lstPtr;
369
+ }
370
+ lst->push_back (fpart); // add to the list
371
+ }
342
372
}
343
373
344
374
@@ -354,6 +384,78 @@ Units Layer::getLabelUnit()
354
384
}
355
385
356
386
387
+ static FeaturePart* _findConnectedPart (FeaturePart* partCheck, LinkedList<FeaturePart*>* otherParts)
388
+ {
389
+ // iterate in the rest of the parts with the same label
390
+ Cell<FeaturePart*>* p = otherParts->getFirst ();
391
+ while (p)
392
+ {
393
+ if (partCheck->isConnected (p->item ))
394
+ {
395
+ // stop checking for other connected parts
396
+ return p->item ;
397
+ }
398
+ p = p->next ;
399
+ }
400
+
401
+ return NULL ; // no connected part found...
402
+ }
403
+
404
+ void Layer::joinConnectedFeatures ()
405
+ {
406
+ // go through all label texts
407
+ char * labelText;
408
+ while ( labelText = connectedTexts->pop_front () )
409
+ {
410
+ // std::cerr << "JOIN: " << labelText << std::endl;
411
+ LinkedList<FeaturePart*>** partsPtr = connectedHashtable->find (labelText);
412
+ if (!partsPtr)
413
+ continue ; // shouldn't happen
414
+ LinkedList<FeaturePart*>* parts = *partsPtr;
415
+
416
+ // go one-by-one part, try to merge
417
+ while (parts->size ())
418
+ {
419
+ // part we'll be checking against other in this round
420
+ FeaturePart* partCheck = parts->pop_front ();
421
+
422
+ FeaturePart* otherPart = _findConnectedPart (partCheck, parts);
423
+ if (otherPart)
424
+ {
425
+ // std::cerr << "- connected " << partCheck << " with " << otherPart << std::endl;
426
+
427
+ // remove partCheck from r-tree
428
+ double bmin[2 ], bmax[2 ];
429
+ partCheck->getBoundingBox (bmin, bmax);
430
+ rtree->Remove (bmin,bmax, partCheck);
431
+
432
+ otherPart->getBoundingBox (bmin, bmax);
433
+
434
+ // merge points from partCheck to p->item
435
+ if (otherPart->mergeWithFeaturePart (partCheck))
436
+ {
437
+ // reinsert p->item to r-tree (probably not needed)
438
+ rtree->Remove (bmin,bmax, otherPart);
439
+ otherPart->getBoundingBox (bmin, bmax);
440
+ rtree->Insert (bmin, bmax, otherPart);
441
+ }
442
+ }
443
+ }
444
+
445
+ // we're done processing feature parts with this particular label text
446
+ delete parts;
447
+ *partsPtr = NULL ;
448
+ delete labelText;
449
+ }
450
+
451
+ // we're done processing connected fetures
452
+ delete connectedHashtable;
453
+ connectedHashtable = NULL ;
454
+ delete connectedTexts;
455
+ connectedTexts = NULL ;
456
+ }
457
+
458
+
357
459
358
460
} // end namespace
359
461
0 commit comments