mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-06 00:07:29 -04:00
Restrict results to ONLY those matching the selected geometry types
This commit is contained in:
parent
8ad47c01f3
commit
edc26aeb0b
@ -55,6 +55,12 @@ Returns the geometry field for a specified entity ``type``.
|
||||
static bool entityTypeHasGeometry( Qgis::SensorThingsEntity type );
|
||||
%Docstring
|
||||
Returns ``True`` if the specified entity ``type`` can have geometry attached.
|
||||
%End
|
||||
|
||||
static QString filterForWkbType( Qgis::WkbType type );
|
||||
%Docstring
|
||||
Returns a filter string which restricts results to those matching the specified
|
||||
WKB ``type``.
|
||||
%End
|
||||
|
||||
};
|
||||
|
@ -55,6 +55,12 @@ Returns the geometry field for a specified entity ``type``.
|
||||
static bool entityTypeHasGeometry( Qgis::SensorThingsEntity type );
|
||||
%Docstring
|
||||
Returns ``True`` if the specified entity ``type`` can have geometry attached.
|
||||
%End
|
||||
|
||||
static QString filterForWkbType( Qgis::WkbType type );
|
||||
%Docstring
|
||||
Returns a filter string which restricts results to those matching the specified
|
||||
WKB ``type``.
|
||||
%End
|
||||
|
||||
};
|
||||
|
@ -140,7 +140,12 @@ long long QgsSensorThingsSharedData::featureCount( QgsFeedback *feedback ) const
|
||||
mError.clear();
|
||||
|
||||
// return no features, just the total count
|
||||
const QUrl url = parseUrl( QUrl( QStringLiteral( "%1?$top=0&$count=true" ).arg( mEntityBaseUri ) ) );
|
||||
QString countUri = QStringLiteral( "%1?$top=0&$count=true" ).arg( mEntityBaseUri );
|
||||
const QString typeFilter = QgsSensorThingsUtils::filterForWkbType( mGeometryType );
|
||||
if ( !typeFilter.isEmpty() )
|
||||
countUri += '&' + typeFilter;
|
||||
|
||||
const QUrl url = parseUrl( QUrl( countUri ) );
|
||||
|
||||
QNetworkRequest request( url );
|
||||
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsSensorThingsSharedData" ) );
|
||||
@ -209,6 +214,9 @@ bool QgsSensorThingsSharedData::getFeature( QgsFeatureId id, QgsFeature &f, QgsF
|
||||
{
|
||||
locker.changeMode( QgsReadWriteLocker::Write );
|
||||
mNextPage = QStringLiteral( "%1?$top=%2&$count=false" ).arg( mEntityBaseUri ).arg( mMaximumPageSize );
|
||||
const QString typeFilter = QgsSensorThingsUtils::filterForWkbType( mGeometryType );
|
||||
if ( !typeFilter.isEmpty() )
|
||||
mNextPage += '&' + typeFilter;
|
||||
}
|
||||
|
||||
locker.unlock();
|
||||
@ -245,7 +253,8 @@ QgsFeatureIds QgsSensorThingsSharedData::getFeatureIdsInExtent( const QgsRectang
|
||||
}
|
||||
|
||||
// TODO -- is using 'geography' always correct here?
|
||||
QString queryUrl = !thisPage.isEmpty() ? thisPage : QStringLiteral( "%1?$filter=geo.intersects(%2, geography'%3')&$top=%4&$count=false" ).arg( mEntityBaseUri, mGeometryField, extent.asWktPolygon() ).arg( mMaximumPageSize );
|
||||
const QString typeFilter = QgsSensorThingsUtils::filterForWkbType( mGeometryType );
|
||||
QString queryUrl = !thisPage.isEmpty() ? thisPage : QStringLiteral( "%1?$filter=geo.intersects(%2, geography'%3')&$top=%4&$count=false%5" ).arg( mEntityBaseUri, mGeometryField, extent.asWktPolygon() ).arg( mMaximumPageSize ).arg( typeFilter.isEmpty() ? QString() : ( QStringLiteral( "&" ) + typeFilter ) );
|
||||
|
||||
if ( thisPage.isEmpty() && mCachedExtent.intersects( extentGeom ) )
|
||||
{
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "qgssensorthingsutils.h"
|
||||
#include "qgsfield.h"
|
||||
#include "qgsfields.h"
|
||||
#include "qgswkbtypes.h"
|
||||
|
||||
Qgis::SensorThingsEntity QgsSensorThingsUtils::stringToEntity( const QString &type )
|
||||
{
|
||||
@ -217,3 +218,21 @@ bool QgsSensorThingsUtils::entityTypeHasGeometry( Qgis::SensorThingsEntity type
|
||||
}
|
||||
BUILTIN_UNREACHABLE
|
||||
}
|
||||
|
||||
QString QgsSensorThingsUtils::filterForWkbType( Qgis::WkbType type )
|
||||
{
|
||||
switch ( QgsWkbTypes::geometryType( type ) )
|
||||
{
|
||||
case Qgis::GeometryType::Point:
|
||||
return QStringLiteral( "$filter=location/type eq 'Point'" );
|
||||
case Qgis::GeometryType::Polygon:
|
||||
return QStringLiteral( "$filter=location/type eq 'Polygon'" );
|
||||
case Qgis::GeometryType::Line:
|
||||
// TODO -- confirm
|
||||
return QStringLiteral( "$filter=location/type eq 'LineString'" );
|
||||
case Qgis::GeometryType::Unknown:
|
||||
case Qgis::GeometryType::Null:
|
||||
break;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
@ -68,6 +68,12 @@ class CORE_EXPORT QgsSensorThingsUtils
|
||||
*/
|
||||
static bool entityTypeHasGeometry( Qgis::SensorThingsEntity type );
|
||||
|
||||
/**
|
||||
* Returns a filter string which restricts results to those matching the specified
|
||||
* WKB \a type.
|
||||
*/
|
||||
static QString filterForWkbType( Qgis::WkbType type );
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSSENSORTHINGSUTILS_H
|
||||
|
@ -28,9 +28,13 @@ from qgis.testing import start_app, QgisTestCase
|
||||
|
||||
|
||||
def sanitize(endpoint, x):
|
||||
if x.startswith("/Locations"):
|
||||
x = x[len("/Locations"):]
|
||||
endpoint = endpoint + "_Locations"
|
||||
for prefix in ('/Locations',
|
||||
'/HistoricalLocations',
|
||||
'/Things',
|
||||
'/FeaturesOfInterest'):
|
||||
if x.startswith(prefix):
|
||||
x = x[len(prefix):]
|
||||
endpoint = endpoint + "_" + prefix[1:]
|
||||
|
||||
if len(endpoint + x) > 150:
|
||||
ret = endpoint + hashlib.md5(x.encode()).hexdigest()
|
||||
@ -74,6 +78,23 @@ class TestPyQgsSensorThingsProvider(QgisTestCase): # , ProviderTestCase):
|
||||
)
|
||||
super().tearDownClass()
|
||||
|
||||
def test_filter_for_wkb_type(self):
|
||||
self.assertEqual(
|
||||
QgsSensorThingsUtils.filterForWkbType(Qgis.WkbType.Point), "$filter=location/type eq 'Point'"
|
||||
)
|
||||
self.assertEqual(
|
||||
QgsSensorThingsUtils.filterForWkbType(Qgis.WkbType.PointZ), "$filter=location/type eq 'Point'"
|
||||
)
|
||||
self.assertEqual(
|
||||
QgsSensorThingsUtils.filterForWkbType(Qgis.WkbType.Polygon), "$filter=location/type eq 'Polygon'"
|
||||
)
|
||||
# TODO -- there is NO documentation on what the type must be for line filtering,
|
||||
# and I can't find any public servers with line geometries to test with!
|
||||
# Find some way to confirm if this is 'Line' or 'LineString' or ...
|
||||
self.assertEqual(
|
||||
QgsSensorThingsUtils.filterForWkbType(Qgis.WkbType.LineString), "$filter=location/type eq 'LineString'"
|
||||
)
|
||||
|
||||
def test_utils_string_to_entity(self):
|
||||
self.assertEqual(
|
||||
QgsSensorThingsUtils.stringToEntity("x"), Qgis.SensorThingsEntity.Invalid
|
||||
@ -230,7 +251,7 @@ class TestPyQgsSensorThingsProvider(QgisTestCase): # , ProviderTestCase):
|
||||
)
|
||||
|
||||
with open(
|
||||
sanitize(endpoint, "/Locations?$top=0&$count=true"),
|
||||
sanitize(endpoint, "/Locations?$top=0&$count=true&$filter=location/type eq 'Point'"),
|
||||
"wt",
|
||||
encoding="utf8",
|
||||
) as f:
|
||||
@ -449,14 +470,14 @@ class TestPyQgsSensorThingsProvider(QgisTestCase): # , ProviderTestCase):
|
||||
)
|
||||
|
||||
with open(
|
||||
sanitize(endpoint, "/Locations?$top=0&$count=true"),
|
||||
sanitize(endpoint, "/Locations?$top=0&$count=true&$filter=location/type eq 'Point'"),
|
||||
"wt",
|
||||
encoding="utf8",
|
||||
) as f:
|
||||
f.write("""{"@iot.count":3,"value":[]}""")
|
||||
|
||||
with open(
|
||||
sanitize(endpoint, "/Locations?$top=2&$count=false"),
|
||||
sanitize(endpoint, "/Locations?$top=2&$count=false&$filter=location/type eq 'Point'"),
|
||||
"wt",
|
||||
encoding="utf8",
|
||||
) as f:
|
||||
@ -504,7 +525,7 @@ class TestPyQgsSensorThingsProvider(QgisTestCase): # , ProviderTestCase):
|
||||
|
||||
}
|
||||
],
|
||||
"@iot.nextLink": "endpoint/Locations?$top=2&$skip=2"
|
||||
"@iot.nextLink": "endpoint/Locations?$top=2&$skip=2&$filter=location/type eq 'Point'"
|
||||
}
|
||||
""".replace(
|
||||
"endpoint", "http://" + endpoint
|
||||
@ -512,7 +533,7 @@ class TestPyQgsSensorThingsProvider(QgisTestCase): # , ProviderTestCase):
|
||||
)
|
||||
|
||||
with open(
|
||||
sanitize(endpoint, "/Locations?$top=2&$skip=2"),
|
||||
sanitize(endpoint, "/Locations?$top=2&$skip=2&$filter=location/type eq 'Point'"),
|
||||
"wt",
|
||||
encoding="utf8",
|
||||
) as f:
|
||||
@ -626,14 +647,14 @@ class TestPyQgsSensorThingsProvider(QgisTestCase): # , ProviderTestCase):
|
||||
)
|
||||
|
||||
with open(
|
||||
sanitize(endpoint, "/Locations?$top=0&$count=true"),
|
||||
sanitize(endpoint, "/Locations?$top=0&$count=true&$filter=location/type eq 'Point'"),
|
||||
"wt",
|
||||
encoding="utf8",
|
||||
) as f:
|
||||
f.write("""{"@iot.count":3,"value":[]}""")
|
||||
|
||||
with open(
|
||||
sanitize(endpoint, "/Locations?$top=2&$count=false"),
|
||||
sanitize(endpoint, "/Locations?$top=2&$count=false&$filter=location/type eq 'Point'"),
|
||||
"wt",
|
||||
encoding="utf8",
|
||||
) as f:
|
||||
@ -681,7 +702,7 @@ class TestPyQgsSensorThingsProvider(QgisTestCase): # , ProviderTestCase):
|
||||
|
||||
}
|
||||
],
|
||||
"@iot.nextLink": "endpoint/Locations?$top=2&$skip=2"
|
||||
"@iot.nextLink": "endpoint/Locations?$top=2&$skip=2&$filter=location/type eq 'Point'"
|
||||
}
|
||||
""".replace(
|
||||
"endpoint", "http://" + endpoint
|
||||
@ -689,7 +710,7 @@ class TestPyQgsSensorThingsProvider(QgisTestCase): # , ProviderTestCase):
|
||||
)
|
||||
|
||||
with open(
|
||||
sanitize(endpoint, "/Locations?$top=2&$skip=2"),
|
||||
sanitize(endpoint, "/Locations?$top=2&$skip=2&$filter=location/type eq 'Point'"),
|
||||
"wt",
|
||||
encoding="utf8",
|
||||
) as f:
|
||||
@ -724,7 +745,7 @@ class TestPyQgsSensorThingsProvider(QgisTestCase): # , ProviderTestCase):
|
||||
)
|
||||
|
||||
with open(
|
||||
sanitize(endpoint, "/Locations?$filter=geo.intersects(location, geography'POLYGON((1 0, 10 0, 10 80, 1 80, 1 0))')&$top=2&$count=false"),
|
||||
sanitize(endpoint, "/Locations?$filter=geo.intersects(location, geography'POLYGON((1 0, 10 0, 10 80, 1 80, 1 0))')&$top=2&$count=false&$filter=location/type eq 'Point'"),
|
||||
"wt",
|
||||
encoding="utf8",
|
||||
) as f:
|
||||
@ -777,7 +798,7 @@ class TestPyQgsSensorThingsProvider(QgisTestCase): # , ProviderTestCase):
|
||||
)
|
||||
|
||||
with open(
|
||||
sanitize(endpoint, "/Locations?$filter=geo.intersects(location, geography'POLYGON((10 0, 20 0, 20 80, 10 80, 10 0))')&$top=2&$count=false"),
|
||||
sanitize(endpoint, "/Locations?$filter=geo.intersects(location, geography'POLYGON((10 0, 20 0, 20 80, 10 80, 10 0))')&$top=2&$count=false&$filter=location/type eq 'Point'"),
|
||||
"wt",
|
||||
encoding="utf8",
|
||||
) as f:
|
||||
@ -1841,14 +1862,14 @@ class TestPyQgsSensorThingsProvider(QgisTestCase): # , ProviderTestCase):
|
||||
)
|
||||
|
||||
with open(
|
||||
sanitize(endpoint, "/FeaturesOfInterest?$top=0&$count=true"),
|
||||
sanitize(endpoint, "/FeaturesOfInterest?$top=0&$count=true&$filter=location/type eq 'Point'"),
|
||||
"wt",
|
||||
encoding="utf8",
|
||||
) as f:
|
||||
f.write("""{"@iot.count":3,"value":[]}""")
|
||||
|
||||
with open(
|
||||
sanitize(endpoint, "/FeaturesOfInterest?$top=2&$count=false"),
|
||||
sanitize(endpoint, "/FeaturesOfInterest?$top=2&$count=false&$filter=location/type eq 'Point'"),
|
||||
"wt",
|
||||
encoding="utf8",
|
||||
) as f:
|
||||
@ -1901,7 +1922,7 @@ class TestPyQgsSensorThingsProvider(QgisTestCase): # , ProviderTestCase):
|
||||
|
||||
}
|
||||
],
|
||||
"@iot.nextLink": "endpoint/FeaturesOfInterest?$top=2&$skip=2"
|
||||
"@iot.nextLink": "endpoint/FeaturesOfInterest?$top=2&$skip=2&$filter=location/type eq 'Point'"
|
||||
}
|
||||
""".replace(
|
||||
"endpoint", "http://" + endpoint
|
||||
@ -1909,7 +1930,7 @@ class TestPyQgsSensorThingsProvider(QgisTestCase): # , ProviderTestCase):
|
||||
)
|
||||
|
||||
with open(
|
||||
sanitize(endpoint, "/FeaturesOfInterest?$top=2&$skip=2"),
|
||||
sanitize(endpoint, "/FeaturesOfInterest?$top=2&$skip=2&$filter=location/type eq 'Point'"),
|
||||
"wt",
|
||||
encoding="utf8",
|
||||
) as f:
|
||||
|
Loading…
x
Reference in New Issue
Block a user