@@ -2878,14 +2878,35 @@ int QgsGeometry::splitGeometry( const QList<QgsPoint>& splitLine, QList<QgsGeome
2878
2878
return 7 ;
2879
2879
2880
2880
// make sure splitLine is valid
2881
- if ( splitLine.size () < 2 )
2881
+ if ( splitLine.size () < 1 )
2882
2882
return 1 ;
2883
2883
2884
+ // Treat the special case of a single point to split a line without geos
2885
+ if ( splitLine.size () == 1 )
2886
+ {
2887
+ // A point cannot split a polygon
2888
+ if ( type () == QGis::Polygon )
2889
+ return 1 ;
2890
+ // return splitLinearGeometryAtPoint( splitLine[0], newGeometries );
2891
+ }
2892
+
2884
2893
newGeometries.clear ();
2885
2894
2886
2895
try
2887
2896
{
2888
- GEOSGeometry *splitLineGeos = createGeosLineString ( splitLine.toVector () );
2897
+ GEOSGeometry* splitLineGeos;
2898
+ if ( splitLine.size () > 1 )
2899
+ {
2900
+ splitLineGeos = createGeosLineString ( splitLine.toVector () );
2901
+ }
2902
+ else if ( splitLine.size () == 1 )
2903
+ {
2904
+ splitLineGeos = createGeosPoint ( splitLine.at ( 0 ) );
2905
+ }
2906
+ else
2907
+ {
2908
+ return 1 ;
2909
+ }
2889
2910
if ( !GEOSisValid ( splitLineGeos ) || !GEOSisSimple ( splitLineGeos ) )
2890
2911
{
2891
2912
GEOSGeom_destroy ( splitLineGeos );
@@ -4549,6 +4570,105 @@ void QgsGeometry::transformVertex( QgsWkbPtr &wkbPtr, const QgsCoordinateTransfo
4549
4570
4550
4571
}
4551
4572
4573
+ GEOSGeometry* QgsGeometry::linePointDifference ( GEOSGeometry* GEOSsplitPoint )
4574
+ {
4575
+ int type = GEOSGeomTypeId ( mGeos );
4576
+ QgsMultiPolyline multiLine;
4577
+
4578
+ if ( type == GEOS_MULTILINESTRING )
4579
+ multiLine = asMultiPolyline ();
4580
+ else if ( type == GEOS_LINESTRING )
4581
+ multiLine = QgsMultiPolyline () << asPolyline ();
4582
+ else
4583
+ return 0 ;
4584
+
4585
+ QgsPoint splitPoint = fromGeosGeom ( GEOSsplitPoint )->asPoint ();
4586
+
4587
+ QgsPoint p1, p2;
4588
+ QgsGeometry* g;
4589
+ QgsMultiPolyline lines;
4590
+ QgsPolyline line;
4591
+ QgsPolyline newline;
4592
+
4593
+ // For each part
4594
+ for ( int i = 0 ; i < multiLine.size () ; ++i )
4595
+ {
4596
+ line = multiLine[i];
4597
+ // For each segment
4598
+ newline = QgsPolyline ();
4599
+ for ( int j = 1 ; j < line.size () ; ++j )
4600
+ {
4601
+ p1 = line[j-1 ];
4602
+ p2 = line[j];
4603
+ g = QgsGeometry::fromPolyline ( QgsPolyline () << p1 << p2 );
4604
+ QgsDebugMsg ( g->exportToWkt () );
4605
+ QgsDebugMsg ( splitPoint.toString () );
4606
+
4607
+ newline.append ( p1 );
4608
+
4609
+ double x1 = p1.x ();
4610
+ double y1 = p1.y ();
4611
+ double x2 = p2.x ();
4612
+ double y2 = p2.y ();
4613
+ double xt = splitPoint.x ();
4614
+ double yt = splitPoint.y ();
4615
+ double k;
4616
+ double diff;
4617
+ if ( x2 == x1 )
4618
+ {
4619
+ if ( y2 == y1 )
4620
+ {
4621
+ k = -1 ;
4622
+ diff = 1e50 ;
4623
+ }
4624
+ else
4625
+ {
4626
+ k = ( yt - y1 ) / ( y2 - y1 );
4627
+ diff = k * ( x2 - x1 ) - ( xt - x1 );
4628
+ }
4629
+ }
4630
+ else
4631
+ {
4632
+ k = ( xt - x1 ) / ( x2 - x1 );
4633
+ diff = k * ( y2 - y1 ) - ( yt - y1 );
4634
+ }
4635
+ if ( abs ( diff ) < 1e-7 )
4636
+ {
4637
+ if ( k == 0 )
4638
+ {
4639
+ lines.append ( newline );
4640
+ newline = QgsPolyline ();
4641
+ newline.append ( p1 );
4642
+ }
4643
+ if ( k == 1 )
4644
+ {
4645
+ newline.append ( p2 );
4646
+ lines.append ( newline );
4647
+ newline = QgsPolyline ();
4648
+ }
4649
+ if ( k > 0 && k < 1 )
4650
+ {
4651
+ newline.append ( splitPoint );
4652
+ lines.append ( newline );
4653
+ newline = QgsPolyline ();
4654
+ newline.append ( splitPoint );
4655
+ }
4656
+ if ( k < 0 || k > 1 )
4657
+ {
4658
+ // Nothing happens, we are on the line but not the segment
4659
+ }
4660
+ }
4661
+ }
4662
+ newline.append ( line.last () );
4663
+ lines.append ( newline );
4664
+ }
4665
+ QgsGeometry* splitLines = fromMultiPolyline ( lines );
4666
+ GEOSGeometry* splitGeom = GEOSGeom_clone ( splitLines->asGeos () );
4667
+
4668
+ return splitGeom;
4669
+
4670
+ }
4671
+
4552
4672
int QgsGeometry::splitLinearGeometry ( GEOSGeometry *splitLine, QList<QgsGeometry*>& newGeometries )
4553
4673
{
4554
4674
if ( !splitLine )
@@ -4560,16 +4680,25 @@ int QgsGeometry::splitLinearGeometry( GEOSGeometry *splitLine, QList<QgsGeometry
4560
4680
if ( !mGeos )
4561
4681
return 5 ;
4562
4682
4563
- // first test if linestring intersects geometry. If not, return straight away
4564
- if ( !GEOSIntersects ( splitLine, mGeos ) )
4565
- return 1 ;
4566
4683
4567
4684
// check that split line has no linear intersection
4568
4685
int linearIntersect = GEOSRelatePattern ( mGeos , splitLine, " 1********" );
4569
4686
if ( linearIntersect > 0 )
4570
4687
return 3 ;
4571
4688
4572
- GEOSGeometry* splitGeom = GEOSDifference ( mGeos , splitLine );
4689
+ int splitGeomType = GEOSGeomTypeId ( splitLine );
4690
+ // first test if linestring intersects geometry. If not, return straight away
4691
+ if ( splitGeomType == GEOS_LINESTRING && !GEOSIntersects ( splitLine, mGeos ) )
4692
+ return 1 ;
4693
+ GEOSGeometry* splitGeom;
4694
+ if ( splitGeomType == GEOS_LINESTRING )
4695
+ {
4696
+ splitGeom = GEOSDifference ( mGeos , splitLine );
4697
+ }
4698
+ else
4699
+ {
4700
+ splitGeom = linePointDifference ( splitLine );
4701
+ }
4573
4702
QVector<GEOSGeometry*> lineGeoms;
4574
4703
4575
4704
int splitType = GEOSGeomTypeId ( splitGeom );
0 commit comments