@@ -329,6 +329,7 @@ bool QgsGeometryAnalyzer::extent( QgsVectorLayer* layer, const QString& shapefil
329
329
QList<double > QgsGeometryAnalyzer::simpleMeasure ( QgsGeometry* mpGeometry )
330
330
{
331
331
QList<double > list;
332
+ double perim;
332
333
if ( mpGeometry->wkbType () == QGis::WKBPoint )
333
334
{
334
335
QgsPoint pt = mpGeometry->asPoint ();
@@ -341,11 +342,11 @@ QList<double> QgsGeometryAnalyzer::simpleMeasure( QgsGeometry* mpGeometry )
341
342
list.append ( measure.measure ( mpGeometry ) );
342
343
if ( mpGeometry->type () == QGis::Polygon )
343
344
{
344
- list.append ( perimeterMeasure ( mpGeometry, measure ) );
345
+ perim = perimeterMeasure ( mpGeometry, measure );
346
+ list.append ( perim );
345
347
}
346
348
}
347
349
return list;
348
-
349
350
}
350
351
351
352
double QgsGeometryAnalyzer::perimeterMeasure ( QgsGeometry* geometry, QgsDistanceArea& measure )
@@ -383,51 +384,90 @@ bool QgsGeometryAnalyzer::convexHull( QgsVectorLayer* layer, const QString& shap
383
384
{
384
385
return false ;
385
386
}
386
-
387
387
QgsVectorDataProvider* dp = layer->dataProvider ();
388
388
if ( !dp )
389
389
{
390
390
return false ;
391
391
}
392
+ bool useField = false ;
393
+ if ( uniqueIdField == -1 )
394
+ {
395
+ uniqueIdField = 0 ;
396
+ }
397
+ else
398
+ {
399
+ useField = true ;
400
+ }
401
+ QgsFieldMap fields;
402
+ fields.insert ( 0 , QgsField ( QString ( " UID" ), QVariant::String ) );
403
+ fields.insert ( 1 , QgsField ( QString ( " AREA" ), QVariant::Double ) );
404
+ fields.insert ( 2 , QgsField ( QString ( " PERIM" ), QVariant::Double ) );
392
405
393
406
QGis::WkbType outputType = QGis::WKBPolygon;
394
407
const QgsCoordinateReferenceSystem crs = layer->srs ();
395
408
396
- QgsVectorFileWriter vWriter ( shapefileName, dp->encoding (), dp-> fields () , outputType, &crs );
409
+ QgsVectorFileWriter vWriter ( shapefileName, dp->encoding (), fields, outputType, &crs );
397
410
QgsFeature currentFeature;
398
411
QgsGeometry* dissolveGeometry; // dissolve geometry
399
412
QMultiMap<QString, int > map;
400
- bool useField = false ;
401
413
402
- if ( uniqueIdField == - 1 )
414
+ if ( onlySelectedFeatures )
403
415
{
404
- uniqueIdField = 0 ;
416
+ // use QgsVectorLayer::featureAtId
417
+ const QgsFeatureIds selection = layer->selectedFeaturesIds ();
418
+ QgsFeatureIds::const_iterator it = selection.constBegin ();
419
+ for ( ; it != selection.constEnd (); ++it )
420
+ {
421
+ // if ( p )
422
+ // {
423
+ // p->setValue( processedFeatures );
424
+ // }
425
+ // if ( p && p->wasCanceled() )
426
+ // {
427
+ // // break; // it may be better to do something else here?
428
+ // return false;
429
+ // }
430
+ if ( !layer->featureAtId ( *it, currentFeature, true , true ) )
431
+ {
432
+ continue ;
433
+ }
434
+ map.insert ( currentFeature.attributeMap ()[ uniqueIdField ].toString (), currentFeature.id () );
435
+ }
405
436
}
406
437
else
407
438
{
408
- useField = true ;
409
439
layer->select ( layer->pendingAllAttributesList (), QgsRectangle (), true , false );
410
440
while ( layer->nextFeature ( currentFeature ) )
411
441
{
412
- map.insert ( currentFeature.attributeMap ()[uniqueIdField].toString (), currentFeature.id () );
442
+ // if ( p )
443
+ // {
444
+ // p->setValue( processedFeatures );
445
+ // }
446
+ // if ( p && p->wasCanceled() )
447
+ // {
448
+ // // break; // it may be better to do something else here?
449
+ // return false;
450
+ // }
451
+ map.insert ( currentFeature.attributeMap ()[ uniqueIdField ].toString (), currentFeature.id () );
413
452
}
414
453
}
415
- QMultiMap<QString, int >::const_iterator jt;
416
- for (jt = map.constBegin (); jt != map.constEnd (); ++jt)
454
+
455
+ QMultiMap<QString, int >::const_iterator jt = map.constBegin ();
456
+ while ( jt != map.constEnd () )
417
457
{
418
458
QString currentKey = jt.key ();
419
459
int processedFeatures = 0 ;
420
460
// take only selection
421
461
if ( onlySelectedFeatures )
422
462
{
423
463
// use QgsVectorLayer::featureAtId
424
- const QgsFeatureIds selection = layer->selectedFeaturesIds ();
464
+ const QgsFeatureIds selection = layer->selectedFeaturesIds ();
425
465
if ( p )
426
466
{
427
- p->setMaximum ( selection.size () );
467
+ p->setMaximum ( selection.size () );
428
468
}
429
469
processedFeatures = 0 ;
430
- while ( jt != map.end () && ( jt.key () == currentKey || !useField ) )
470
+ while ( jt != map.constEnd () && ( jt.key () == currentKey || !useField ) )
431
471
{
432
472
if ( p && p->wasCanceled () )
433
473
{
@@ -437,18 +477,26 @@ bool QgsGeometryAnalyzer::convexHull( QgsVectorLayer* layer, const QString& shap
437
477
{
438
478
if ( p )
439
479
{
440
- p->setValue ( processedFeatures );
480
+ p->setValue ( processedFeatures );
441
481
}
442
482
if ( !layer->featureAtId ( jt.value (), currentFeature, true , true ) )
443
483
{
444
- continue ;
484
+ continue ;
445
485
}
446
486
convexFeature ( currentFeature, processedFeatures, &dissolveGeometry );
447
487
++processedFeatures;
448
488
}
449
489
++jt;
450
490
}
491
+ QList<double > values;
492
+ dissolveGeometry = dissolveGeometry->convexHull ();
493
+ values = simpleMeasure ( dissolveGeometry );
494
+ QgsAttributeMap attributeMap;
495
+ attributeMap.insert ( 0 , QVariant ( currentKey ) );
496
+ attributeMap.insert ( 1 , values[ 0 ] );
497
+ attributeMap.insert ( 2 , values[ 1 ] );
451
498
QgsFeature dissolveFeature;
499
+ dissolveFeature.setAttributeMap ( attributeMap );
452
500
dissolveFeature.setGeometry ( dissolveGeometry );
453
501
vWriter.addFeature ( dissolveFeature );
454
502
}
@@ -461,7 +509,7 @@ bool QgsGeometryAnalyzer::convexHull( QgsVectorLayer* layer, const QString& shap
461
509
p->setMaximum ( featureCount );
462
510
}
463
511
processedFeatures = 0 ;
464
- while ( jt != map.end () && ( jt.key () == currentKey || !useField ) )
512
+ while ( jt != map.constEnd () && ( jt.key () == currentKey || !useField ) )
465
513
{
466
514
if ( p )
467
515
{
@@ -480,9 +528,19 @@ bool QgsGeometryAnalyzer::convexHull( QgsVectorLayer* layer, const QString& shap
480
528
++processedFeatures;
481
529
++jt;
482
530
}
483
- QgsFeature dissolveFeature;
484
- dissolveFeature.setGeometry ( dissolveGeometry );
485
- vWriter.addFeature ( dissolveFeature );
531
+ QList<double > values;
532
+ // QgsGeometry* tmpGeometry = 0;
533
+ dissolveGeometry = dissolveGeometry->convexHull ();
534
+ // values = simpleMeasure( tmpGeometry );
535
+ values = simpleMeasure ( dissolveGeometry );
536
+ QgsAttributeMap attributeMap;
537
+ attributeMap.insert ( 0 , QVariant ( currentKey ) );
538
+ attributeMap.insert ( 1 , QVariant ( values[ 0 ] ) );
539
+ attributeMap.insert ( 2 , QVariant ( values[ 1 ] ) );
540
+ QgsFeature dissolveFeature;
541
+ dissolveFeature.setAttributeMap ( attributeMap );
542
+ dissolveFeature.setGeometry ( dissolveGeometry );
543
+ vWriter.addFeature ( dissolveFeature );
486
544
}
487
545
}
488
546
return true ;
@@ -522,51 +580,69 @@ bool QgsGeometryAnalyzer::dissolve( QgsVectorLayer* layer, const QString& shapef
522
580
{
523
581
return false ;
524
582
}
525
-
526
583
QgsVectorDataProvider* dp = layer->dataProvider ();
527
584
if ( !dp )
528
585
{
529
586
return false ;
530
587
}
588
+ bool useField = false ;
589
+ if ( uniqueIdField == -1 )
590
+ {
591
+ uniqueIdField = 0 ;
592
+ }
593
+ else
594
+ {
595
+ useField = true ;
596
+ }
531
597
532
598
QGis::WkbType outputType = dp->geometryType ();
533
599
const QgsCoordinateReferenceSystem crs = layer->srs ();
534
600
535
601
QgsVectorFileWriter vWriter ( shapefileName, dp->encoding (), dp->fields (), outputType, &crs );
536
602
QgsFeature currentFeature;
537
- QgsGeometry* dissolveGeometry; // dissolve geometry
538
603
QMultiMap<QString, int > map;
539
- bool useField = false ;
540
604
541
- if ( uniqueIdField == - 1 )
605
+ if ( onlySelectedFeatures )
542
606
{
543
- uniqueIdField = 0 ;
607
+ // use QgsVectorLayer::featureAtId
608
+ const QgsFeatureIds selection = layer->selectedFeaturesIds ();
609
+ QgsFeatureIds::const_iterator it = selection.constBegin ();
610
+ for ( ; it != selection.constEnd (); ++it )
611
+ {
612
+ if ( !layer->featureAtId ( *it, currentFeature, true , true ) )
613
+ {
614
+ continue ;
615
+ }
616
+ map.insert ( currentFeature.attributeMap ()[ uniqueIdField ].toString (), currentFeature.id () );
617
+ }
544
618
}
545
619
else
546
620
{
547
- useField = true ;
548
621
layer->select ( layer->pendingAllAttributesList (), QgsRectangle (), true , false );
549
622
while ( layer->nextFeature ( currentFeature ) )
550
623
{
551
- map.insert ( currentFeature.attributeMap ()[uniqueIdField].toString (), currentFeature.id () );
624
+ map.insert ( currentFeature.attributeMap ()[ uniqueIdField ].toString (), currentFeature.id () );
552
625
}
553
626
}
554
- QMultiMap<QString, int >::const_iterator jt;
555
- for (jt = map.constBegin (); jt != map.constEnd (); ++jt)
627
+
628
+ QgsGeometry* dissolveGeometry; // dissolve geometry
629
+ QMultiMap<QString, int >::const_iterator jt = map.constBegin ();
630
+ QgsFeature outputFeature;
631
+ while ( jt != map.constEnd () )
556
632
{
557
633
QString currentKey = jt.key ();
558
634
int processedFeatures = 0 ;
635
+ bool first = true ;
559
636
// take only selection
560
637
if ( onlySelectedFeatures )
561
638
{
562
639
// use QgsVectorLayer::featureAtId
563
- const QgsFeatureIds selection = layer->selectedFeaturesIds ();
640
+ const QgsFeatureIds selection = layer->selectedFeaturesIds ();
564
641
if ( p )
565
642
{
566
- p->setMaximum ( selection.size () );
643
+ p->setMaximum ( selection.size () );
567
644
}
568
- processedFeatures = 0 ;
569
- while ( jt != map.end () && ( jt.key () == currentKey || !useField ) )
645
+ while ( jt != map.constEnd () && ( jt.key () == currentKey || !useField ) )
570
646
{
571
647
if ( p && p->wasCanceled () )
572
648
{
@@ -576,20 +652,22 @@ bool QgsGeometryAnalyzer::dissolve( QgsVectorLayer* layer, const QString& shapef
576
652
{
577
653
if ( p )
578
654
{
579
- p->setValue ( processedFeatures );
655
+ p->setValue ( processedFeatures );
580
656
}
581
657
if ( !layer->featureAtId ( jt.value (), currentFeature, true , true ) )
582
658
{
583
- continue ;
659
+ continue ;
660
+ }
661
+ if ( first )
662
+ {
663
+ outputFeature.setAttributeMap ( currentFeature.attributeMap () );
664
+ first = false ;
584
665
}
585
666
dissolveFeature ( currentFeature, processedFeatures, &dissolveGeometry );
586
667
++processedFeatures;
587
668
}
588
669
++jt;
589
670
}
590
- QgsFeature dissolveFeature;
591
- dissolveFeature.setGeometry ( dissolveGeometry );
592
- vWriter.addFeature ( dissolveFeature );
593
671
}
594
672
// take all features
595
673
else
@@ -599,8 +677,7 @@ bool QgsGeometryAnalyzer::dissolve( QgsVectorLayer* layer, const QString& shapef
599
677
{
600
678
p->setMaximum ( featureCount );
601
679
}
602
- processedFeatures = 0 ;
603
- while ( jt != map.end () && ( jt.key () == currentKey || !useField ) )
680
+ while ( jt != map.constEnd () && ( jt.key () == currentKey || !useField ) )
604
681
{
605
682
if ( p )
606
683
{
@@ -615,22 +692,24 @@ bool QgsGeometryAnalyzer::dissolve( QgsVectorLayer* layer, const QString& shapef
615
692
{
616
693
continue ;
617
694
}
695
+ {
696
+ outputFeature.setAttributeMap ( currentFeature.attributeMap () );
697
+ first = false ;
698
+ }
618
699
dissolveFeature ( currentFeature, processedFeatures, &dissolveGeometry );
619
700
++processedFeatures;
620
701
++jt;
621
702
}
622
- QgsFeature dissolveFeature;
623
- dissolveFeature.setGeometry ( dissolveGeometry );
624
- vWriter.addFeature ( dissolveFeature );
625
703
}
704
+ outputFeature.setGeometry ( dissolveGeometry );
705
+ vWriter.addFeature ( outputFeature );
626
706
}
627
707
return true ;
628
708
}
629
709
630
710
void QgsGeometryAnalyzer::dissolveFeature ( QgsFeature& f, int nProcessedFeatures, QgsGeometry** dissolveGeometry )
631
711
{
632
712
QgsGeometry* featureGeometry = f.geometry ();
633
- QgsGeometry* tmpGeometry = 0 ;
634
713
635
714
if ( !featureGeometry )
636
715
{
@@ -639,13 +718,15 @@ void QgsGeometryAnalyzer::dissolveFeature( QgsFeature& f, int nProcessedFeatures
639
718
640
719
if ( nProcessedFeatures == 0 )
641
720
{
642
- *dissolveGeometry = featureGeometry;
721
+ int geomSize = featureGeometry->wkbSize ();
722
+ *dissolveGeometry = new QgsGeometry ();
723
+ unsigned char * wkb = new unsigned char [geomSize];
724
+ memcpy (wkb, featureGeometry->asWkb (), geomSize);
725
+ (*dissolveGeometry)->fromWkb (wkb, geomSize);
643
726
}
644
727
else
645
728
{
646
- tmpGeometry = *dissolveGeometry;
647
729
*dissolveGeometry = ( *dissolveGeometry )->combine ( featureGeometry );
648
- delete tmpGeometry;
649
730
}
650
731
}
651
732
0 commit comments