@@ -1722,6 +1722,17 @@ static QVariant fcnGeomZ( const QVariantList &values, const QgsExpressionContext
1722
1722
if ( point )
1723
1723
return point->z ();
1724
1724
}
1725
+ else if ( geom.type () == QgsWkbTypes::PointGeometry && geom.isMultipart () )
1726
+ {
1727
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( geom.constGet () ) )
1728
+ {
1729
+ if ( collection->numGeometries () == 1 )
1730
+ {
1731
+ if ( const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN ( 0 ) ) )
1732
+ return point->z ();
1733
+ }
1734
+ }
1735
+ }
1725
1736
1726
1737
return QVariant ();
1727
1738
}
@@ -1739,6 +1750,17 @@ static QVariant fcnGeomM( const QVariantList &values, const QgsExpressionContext
1739
1750
if ( point )
1740
1751
return point->m ();
1741
1752
}
1753
+ else if ( geom.type () == QgsWkbTypes::PointGeometry && geom.isMultipart () )
1754
+ {
1755
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( geom.constGet () ) )
1756
+ {
1757
+ if ( collection->numGeometries () == 1 )
1758
+ {
1759
+ if ( const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN ( 0 ) ) )
1760
+ return point->m ();
1761
+ }
1762
+ }
1763
+ }
1742
1764
1743
1765
return QVariant ();
1744
1766
}
@@ -1869,6 +1891,17 @@ static QVariant fcnInteriorRingN( const QVariantList &values, const QgsExpressio
1869
1891
return QVariant ();
1870
1892
1871
1893
const QgsCurvePolygon *curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( geom.constGet () );
1894
+ if ( !curvePolygon && geom.isMultipart () )
1895
+ {
1896
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( geom.constGet () ) )
1897
+ {
1898
+ if ( collection->numGeometries () == 1 )
1899
+ {
1900
+ curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->geometryN ( 0 ) );
1901
+ }
1902
+ }
1903
+ }
1904
+
1872
1905
if ( !curvePolygon )
1873
1906
return QVariant ();
1874
1907
@@ -1878,7 +1911,7 @@ static QVariant fcnInteriorRingN( const QVariantList &values, const QgsExpressio
1878
1911
if ( idx >= curvePolygon->numInteriorRings () || idx < 0 )
1879
1912
return QVariant ();
1880
1913
1881
- QgsCurve *curve = static_cast < QgsCurve * >( curvePolygon->interiorRing ( idx )->clone () );
1914
+ QgsCurve *curve = static_cast < QgsCurve * >( curvePolygon->interiorRing ( static_cast < int >( idx ) )->clone () );
1882
1915
QVariant result = curve ? QVariant::fromValue ( QgsGeometry ( curve ) ) : QVariant ();
1883
1916
return result;
1884
1917
}
@@ -1900,7 +1933,7 @@ static QVariant fcnGeometryN( const QVariantList &values, const QgsExpressionCon
1900
1933
if ( idx < 0 || idx >= collection->numGeometries () )
1901
1934
return QVariant ();
1902
1935
1903
- QgsAbstractGeometry *part = collection->geometryN ( idx )->clone ();
1936
+ QgsAbstractGeometry *part = collection->geometryN ( static_cast < int >( idx ) )->clone ();
1904
1937
QVariant result = part ? QVariant::fromValue ( QgsGeometry ( part ) ) : QVariant ();
1905
1938
return result;
1906
1939
}
@@ -2056,25 +2089,57 @@ static QVariant fcnMakePolygon( const QVariantList &values, const QgsExpressionC
2056
2089
}
2057
2090
2058
2091
QgsGeometry outerRing = QgsExpressionUtils::getGeometry ( values.at ( 0 ), parent );
2059
- if ( outerRing.type () != QgsWkbTypes::LineGeometry || outerRing.isMultipart () || outerRing.isNull () )
2092
+ if ( outerRing.type () != QgsWkbTypes::LineGeometry || outerRing.isNull () )
2093
+ return QVariant ();
2094
+
2095
+ std::unique_ptr< QgsPolygon > polygon = qgis::make_unique< QgsPolygon >();
2096
+
2097
+ const QgsCurve *exteriorRing = qgsgeometry_cast< QgsCurve * >( outerRing.constGet () );
2098
+ if ( !exteriorRing && outerRing.isMultipart () )
2099
+ {
2100
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( outerRing.constGet () ) )
2101
+ {
2102
+ if ( collection->numGeometries () == 1 )
2103
+ {
2104
+ exteriorRing = qgsgeometry_cast< QgsCurve * >( collection->geometryN ( 0 ) );
2105
+ }
2106
+ }
2107
+ }
2108
+
2109
+ if ( !exteriorRing )
2060
2110
return QVariant ();
2061
2111
2062
- QgsPolygon * polygon = new QgsPolygon ( );
2063
- polygon-> setExteriorRing ( qgsgeometry_cast< QgsCurve * >( outerRing. constGet ()-> clone () ) );
2112
+ polygon-> setExteriorRing ( exteriorRing-> segmentize () );
2113
+
2064
2114
2065
2115
for ( int i = 1 ; i < values.count (); ++i )
2066
2116
{
2067
2117
QgsGeometry ringGeom = QgsExpressionUtils::getGeometry ( values.at ( i ), parent );
2068
2118
if ( ringGeom.isNull () )
2069
2119
continue ;
2070
2120
2071
- if ( ringGeom.type () != QgsWkbTypes::LineGeometry || ringGeom.isMultipart () || ringGeom. isNull () )
2121
+ if ( ringGeom.type () != QgsWkbTypes::LineGeometry || ringGeom.isNull () )
2072
2122
continue ;
2073
2123
2074
- polygon->addInteriorRing ( qgsgeometry_cast< QgsCurve * >( ringGeom.constGet ()->clone () ) );
2124
+ const QgsCurve *ring = qgsgeometry_cast< QgsCurve * >( ringGeom.constGet () );
2125
+ if ( !ring && ringGeom.isMultipart () )
2126
+ {
2127
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( ringGeom.constGet () ) )
2128
+ {
2129
+ if ( collection->numGeometries () == 1 )
2130
+ {
2131
+ ring = qgsgeometry_cast< QgsCurve * >( collection->geometryN ( 0 ) );
2132
+ }
2133
+ }
2134
+ }
2135
+
2136
+ if ( !ring )
2137
+ continue ;
2138
+
2139
+ polygon->addInteriorRing ( ring->segmentize () );
2075
2140
}
2076
2141
2077
- return QVariant::fromValue ( QgsGeometry ( polygon ) );
2142
+ return QVariant::fromValue ( QgsGeometry ( std::move ( polygon ) ) );
2078
2143
}
2079
2144
2080
2145
static QVariant fcnMakeTriangle ( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
@@ -2093,6 +2158,17 @@ static QVariant fcnMakeTriangle( const QVariantList &values, const QgsExpression
2093
2158
return QVariant ();
2094
2159
2095
2160
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.constGet () );
2161
+ if ( !point && geom.isMultipart () )
2162
+ {
2163
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( geom.constGet () ) )
2164
+ {
2165
+ if ( collection->numGeometries () == 1 )
2166
+ {
2167
+ point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN ( 0 ) );
2168
+ }
2169
+ }
2170
+ }
2171
+
2096
2172
if ( !point )
2097
2173
return QVariant ();
2098
2174
@@ -2122,6 +2198,19 @@ static QVariant fcnMakeCircle( const QVariantList &values, const QgsExpressionCo
2122
2198
return QVariant ();
2123
2199
}
2124
2200
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.constGet () );
2201
+ if ( !point && geom.isMultipart () )
2202
+ {
2203
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( geom.constGet () ) )
2204
+ {
2205
+ if ( collection->numGeometries () == 1 )
2206
+ {
2207
+ point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN ( 0 ) );
2208
+ }
2209
+ }
2210
+ }
2211
+ if ( !point )
2212
+ return QVariant ();
2213
+
2125
2214
QgsCircle circ ( *point, radius );
2126
2215
return QVariant::fromValue ( QgsGeometry ( circ.toPolygon ( segment ) ) );
2127
2216
}
@@ -2145,6 +2234,19 @@ static QVariant fcnMakeEllipse( const QVariantList &values, const QgsExpressionC
2145
2234
return QVariant ();
2146
2235
}
2147
2236
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( geom.constGet () );
2237
+ if ( !point && geom.isMultipart () )
2238
+ {
2239
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( geom.constGet () ) )
2240
+ {
2241
+ if ( collection->numGeometries () == 1 )
2242
+ {
2243
+ point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN ( 0 ) );
2244
+ }
2245
+ }
2246
+ }
2247
+ if ( !point )
2248
+ return QVariant ();
2249
+
2148
2250
QgsEllipse elp ( *point, majorAxis, minorAxis, azimuth );
2149
2251
return QVariant::fromValue ( QgsGeometry ( elp.toPolygon ( segment ) ) );
2150
2252
}
@@ -2179,8 +2281,34 @@ static QVariant fcnMakeRegularPolygon( const QVariantList &values, const QgsExpr
2179
2281
parent->setEvalErrorString ( QObject::tr ( " Option can be 0 (inscribed) or 1 (circumscribed)" ) );
2180
2282
return QVariant ();
2181
2283
}
2284
+
2182
2285
const QgsPoint *center = qgsgeometry_cast< const QgsPoint * >( pt1.constGet () );
2286
+ if ( !center && pt1.isMultipart () )
2287
+ {
2288
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( pt1.constGet () ) )
2289
+ {
2290
+ if ( collection->numGeometries () == 1 )
2291
+ {
2292
+ center = qgsgeometry_cast< const QgsPoint * >( collection->geometryN ( 0 ) );
2293
+ }
2294
+ }
2295
+ }
2296
+ if ( !center )
2297
+ return QVariant ();
2298
+
2183
2299
const QgsPoint *corner = qgsgeometry_cast< const QgsPoint * >( pt2.constGet () );
2300
+ if ( !corner && pt2.isMultipart () )
2301
+ {
2302
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( pt2.constGet () ) )
2303
+ {
2304
+ if ( collection->numGeometries () == 1 )
2305
+ {
2306
+ corner = qgsgeometry_cast< const QgsPoint * >( collection->geometryN ( 0 ) );
2307
+ }
2308
+ }
2309
+ }
2310
+ if ( !corner )
2311
+ return QVariant ();
2184
2312
2185
2313
QgsRegularPolygon rp = QgsRegularPolygon ( *center, *corner, nbEdges, option );
2186
2314
@@ -2461,6 +2589,17 @@ static QVariant fcnIsClosed( const QVariantList &values, const QgsExpressionCont
2461
2589
return QVariant ();
2462
2590
2463
2591
const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( fGeom .constGet () );
2592
+ if ( !curve && fGeom .isMultipart () )
2593
+ {
2594
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( fGeom .constGet () ) )
2595
+ {
2596
+ if ( collection->numGeometries () == 1 )
2597
+ {
2598
+ curve = qgsgeometry_cast< const QgsCurve * >( collection->geometryN ( 0 ) );
2599
+ }
2600
+ }
2601
+ }
2602
+
2464
2603
if ( !curve )
2465
2604
return QVariant ();
2466
2605
@@ -2563,6 +2702,17 @@ static QVariant fcnWedgeBuffer( const QVariantList &values, const QgsExpressionC
2563
2702
{
2564
2703
QgsGeometry fGeom = QgsExpressionUtils::getGeometry ( values.at ( 0 ), parent );
2565
2704
const QgsPoint *pt = qgsgeometry_cast<const QgsPoint *>( fGeom .constGet () );
2705
+ if ( !pt && fGeom .isMultipart () )
2706
+ {
2707
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( fGeom .constGet () ) )
2708
+ {
2709
+ if ( collection->numGeometries () == 1 )
2710
+ {
2711
+ pt = qgsgeometry_cast< const QgsPoint * >( collection->geometryN ( 0 ) );
2712
+ }
2713
+ }
2714
+ }
2715
+
2566
2716
if ( !pt )
2567
2717
{
2568
2718
parent->setEvalErrorString ( QObject::tr ( " Function `wedge_buffer` requires a point value for the center." ) );
@@ -2766,6 +2916,17 @@ static QVariant fcnExteriorRing( const QVariantList &values, const QgsExpression
2766
2916
return QVariant ();
2767
2917
2768
2918
const QgsCurvePolygon *curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( fGeom .constGet () );
2919
+ if ( !curvePolygon && fGeom .isMultipart () )
2920
+ {
2921
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( fGeom .constGet () ) )
2922
+ {
2923
+ if ( collection->numGeometries () == 1 )
2924
+ {
2925
+ curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( collection->geometryN ( 0 ) );
2926
+ }
2927
+ }
2928
+ }
2929
+
2769
2930
if ( !curvePolygon || !curvePolygon->exteriorRing () )
2770
2931
return QVariant ();
2771
2932
@@ -2850,7 +3011,28 @@ static QVariant fcnAzimuth( const QVariantList &values, const QgsExpressionConte
2850
3011
QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry ( values.at ( 1 ), parent );
2851
3012
2852
3013
const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1 .constGet () );
3014
+ if ( !pt1 && fGeom1 .isMultipart () )
3015
+ {
3016
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( fGeom1 .constGet () ) )
3017
+ {
3018
+ if ( collection->numGeometries () == 1 )
3019
+ {
3020
+ pt1 = qgsgeometry_cast< const QgsPoint * >( collection->geometryN ( 0 ) );
3021
+ }
3022
+ }
3023
+ }
3024
+
2853
3025
const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2 .constGet () );
3026
+ if ( !pt2 && fGeom2 .isMultipart () )
3027
+ {
3028
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( fGeom2 .constGet () ) )
3029
+ {
3030
+ if ( collection->numGeometries () == 1 )
3031
+ {
3032
+ pt2 = qgsgeometry_cast< const QgsPoint * >( collection->geometryN ( 0 ) );
3033
+ }
3034
+ }
3035
+ }
2854
3036
2855
3037
if ( !pt1 || !pt2 )
2856
3038
{
@@ -2933,7 +3115,27 @@ static QVariant fcnInclination( const QVariantList &values, const QgsExpressionC
2933
3115
QgsGeometry fGeom2 = QgsExpressionUtils::getGeometry ( values.at ( 1 ), parent );
2934
3116
2935
3117
const QgsPoint *pt1 = qgsgeometry_cast<const QgsPoint *>( fGeom1 .constGet () );
3118
+ if ( !pt1 && fGeom1 .isMultipart () )
3119
+ {
3120
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( fGeom1 .constGet () ) )
3121
+ {
3122
+ if ( collection->numGeometries () == 1 )
3123
+ {
3124
+ pt1 = qgsgeometry_cast< const QgsPoint * >( collection->geometryN ( 0 ) );
3125
+ }
3126
+ }
3127
+ }
2936
3128
const QgsPoint *pt2 = qgsgeometry_cast<const QgsPoint *>( fGeom2 .constGet () );
3129
+ if ( !pt2 && fGeom2 .isMultipart () )
3130
+ {
3131
+ if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( fGeom2 .constGet () ) )
3132
+ {
3133
+ if ( collection->numGeometries () == 1 )
3134
+ {
3135
+ pt2 = qgsgeometry_cast< const QgsPoint * >( collection->geometryN ( 0 ) );
3136
+ }
3137
+ }
3138
+ }
2937
3139
2938
3140
if ( ( fGeom1 .type () != QgsWkbTypes::PointGeometry ) || ( fGeom2 .type () != QgsWkbTypes::PointGeometry ) ||
2939
3141
!pt1 || !pt2 )
0 commit comments