mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-07 00:03:52 -05:00
Add optional viewport property for geocoder results
Allows specifying an optional recommended viewport bounds for displaying the geocode result (e.g. the canvas extent to zoom to for showing the results)
This commit is contained in:
parent
e70caeb3e1
commit
cbaeb99a72
@ -99,6 +99,32 @@ Sets the coordinate reference system for the calculated :py:func:`~QgsGeocoderRe
|
||||
.. seealso:: :py:func:`crs`
|
||||
|
||||
.. seealso:: :py:func:`geometry`
|
||||
%End
|
||||
|
||||
QgsRectangle viewport() const;
|
||||
%Docstring
|
||||
Returns the suggested viewport for the result, which reflects a recommended
|
||||
map extent for displaying the result.
|
||||
|
||||
This is an optional property, and will return a null rectangle if a recommended viewport
|
||||
is not available (or not appropriate).
|
||||
|
||||
The viewport CRS will match the CRS of :py:func:`~QgsGeocoderResult.geometry`, and can be retrieved via the :py:func:`~QgsGeocoderResult.crs` method.
|
||||
|
||||
.. seealso:: :py:func:`setViewport`
|
||||
%End
|
||||
|
||||
void setViewport( const QgsRectangle &viewport );
|
||||
%Docstring
|
||||
Sets the suggested ``viewport`` for the result, which reflects a recommended
|
||||
map extent for displaying the result.
|
||||
|
||||
This is an optional property, and can be set to a null rectangle if a recommended viewport
|
||||
is not available (or not appropriate).
|
||||
|
||||
The viewport CRS must match the CRS of geometry()d.
|
||||
|
||||
.. seealso:: :py:func:`viewport`
|
||||
%End
|
||||
|
||||
QVariantMap additionalAttributes() const;
|
||||
|
||||
@ -76,6 +76,7 @@ QgsGeocoderResult QgsAbstractGeocoderLocatorFilter::locatorResultToGeocoderResul
|
||||
attrs.value( QStringLiteral( "geom" ) ).value< QgsGeometry >(),
|
||||
attrs.value( QStringLiteral( "crs" ) ).value< QgsCoordinateReferenceSystem >() );
|
||||
geocodeResult.setAdditionalAttributes( attrs.value( QStringLiteral( "attributes" ) ).toMap() );
|
||||
geocodeResult.setViewport( attrs.value( QStringLiteral( "viewport" ) ).value< QgsRectangle >() );
|
||||
return geocodeResult;
|
||||
}
|
||||
|
||||
@ -84,6 +85,7 @@ QgsLocatorResult QgsAbstractGeocoderLocatorFilter::geocoderResultToLocatorResult
|
||||
QVariantMap attrs;
|
||||
attrs.insert( QStringLiteral( "identifier" ), result.identifier() );
|
||||
attrs.insert( QStringLiteral( "geom" ), result.geometry() );
|
||||
attrs.insert( QStringLiteral( "viewport" ), result.viewport() );
|
||||
attrs.insert( QStringLiteral( "crs" ), result.crs() );
|
||||
attrs.insert( QStringLiteral( "attributes" ), result.additionalAttributes() );
|
||||
return QgsLocatorResult( this, result.identifier(), attrs );
|
||||
|
||||
@ -107,6 +107,32 @@ class CORE_EXPORT QgsGeocoderResult
|
||||
*/
|
||||
void setCrs( const QgsCoordinateReferenceSystem &crs ) { mCrs = crs; }
|
||||
|
||||
/**
|
||||
* Returns the suggested viewport for the result, which reflects a recommended
|
||||
* map extent for displaying the result.
|
||||
*
|
||||
* This is an optional property, and will return a null rectangle if a recommended viewport
|
||||
* is not available (or not appropriate).
|
||||
*
|
||||
* The viewport CRS will match the CRS of geometry(), and can be retrieved via the crs() method.
|
||||
*
|
||||
* \see setViewport()
|
||||
*/
|
||||
QgsRectangle viewport() const { return mViewport; }
|
||||
|
||||
/**
|
||||
* Sets the suggested \a viewport for the result, which reflects a recommended
|
||||
* map extent for displaying the result.
|
||||
*
|
||||
* This is an optional property, and can be set to a null rectangle if a recommended viewport
|
||||
* is not available (or not appropriate).
|
||||
*
|
||||
* The viewport CRS must match the CRS of geometry()d.
|
||||
*
|
||||
* \see viewport()
|
||||
*/
|
||||
void setViewport( const QgsRectangle &viewport ) { mViewport = viewport; }
|
||||
|
||||
/**
|
||||
* Contains additional attributes generated during the geocode,
|
||||
* which may be added to features being geocoded.
|
||||
@ -133,6 +159,7 @@ class CORE_EXPORT QgsGeocoderResult
|
||||
QString mIdentifier;
|
||||
QgsGeometry mGeometry;
|
||||
QgsCoordinateReferenceSystem mCrs;
|
||||
QgsRectangle mViewport;
|
||||
QVariantMap mAdditionalAttributes;
|
||||
|
||||
};
|
||||
|
||||
@ -243,6 +243,18 @@ QgsGeocoderResult QgsGoogleMapsGeocoder::jsonToResult( const QVariantMap &json )
|
||||
}
|
||||
}
|
||||
|
||||
if ( geometry.contains( QStringLiteral( "viewport" ) ) )
|
||||
{
|
||||
const QVariantMap viewport = geometry.value( QStringLiteral( "viewport" ) ).toMap();
|
||||
const QVariantMap northEast = viewport.value( QStringLiteral( "northeast" ) ).toMap();
|
||||
const QVariantMap southWest = viewport.value( QStringLiteral( "southwest" ) ).toMap();
|
||||
res.setViewport( QgsRectangle( southWest.value( QStringLiteral( "lng" ) ).toDouble(),
|
||||
southWest.value( QStringLiteral( "lat" ) ).toDouble(),
|
||||
northEast.value( QStringLiteral( "lng" ) ).toDouble(),
|
||||
northEast.value( QStringLiteral( "lat" ) ).toDouble()
|
||||
) );
|
||||
}
|
||||
|
||||
res.setAdditionalAttributes( attributes );
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -34,10 +34,19 @@ void QgsGeocoderLocatorFilter::handleGeocodeResult( const QgsGeocoderResult &res
|
||||
{
|
||||
QgsCoordinateTransform ct( result.crs(), mCanvas->mapSettings().destinationCrs(), mCanvas->mapSettings().transformContext() );
|
||||
QgsGeometry g = result.geometry();
|
||||
const QgsRectangle viewport = result.viewport();
|
||||
try
|
||||
{
|
||||
g.transform( ct );
|
||||
QgsRectangle bounds = g.boundingBox();
|
||||
QgsRectangle bounds;
|
||||
if ( viewport.isNull() )
|
||||
{
|
||||
g.transform( ct );
|
||||
bounds = g.boundingBox();
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds = ct.transformBoundingBox( viewport );
|
||||
}
|
||||
mCanvas->zoomToFeatureExtent( bounds );
|
||||
|
||||
mCanvas->flashGeometries( QList< QgsGeometry >() << g );
|
||||
|
||||
@ -22,7 +22,8 @@ from qgis.core import (
|
||||
QgsCoordinateReferenceSystem,
|
||||
QgsLocatorContext,
|
||||
QgsFeedback,
|
||||
QgsGeocoderContext
|
||||
QgsGeocoderContext,
|
||||
QgsRectangle
|
||||
)
|
||||
from qgis.gui import (
|
||||
QgsMapCanvas,
|
||||
@ -55,6 +56,7 @@ class TestGeocoder(QgsGeocoderInterface):
|
||||
result2 = QgsGeocoderResult('res 2', QgsGeometry.fromPointXY(QgsPointXY(13, 14)),
|
||||
QgsCoordinateReferenceSystem('EPSG:3857'))
|
||||
result2.setAdditionalAttributes({'d': 456})
|
||||
result2.setViewport(QgsRectangle(1, 2, 3, 4))
|
||||
return [result1, result2]
|
||||
|
||||
return []
|
||||
@ -93,6 +95,7 @@ class TestQgsGeocoderLocatorFilter(unittest.TestCase):
|
||||
self.assertEqual(geocode_result.geometry().asWkt(), 'Point (1 2)')
|
||||
self.assertEqual(geocode_result.crs().authid(), 'EPSG:4326')
|
||||
self.assertEqual(geocode_result.additionalAttributes(), {'b': 123, 'c': 'xyz'})
|
||||
self.assertTrue(geocode_result.viewport().isNull())
|
||||
|
||||
# two possible results
|
||||
filter.fetchResults('b', context, feedback)
|
||||
@ -105,12 +108,14 @@ class TestQgsGeocoderLocatorFilter(unittest.TestCase):
|
||||
self.assertEqual(geocode_result.geometry().asWkt(), 'Point (11 12)')
|
||||
self.assertEqual(geocode_result.crs().authid(), 'EPSG:4326')
|
||||
self.assertEqual(geocode_result.additionalAttributes(), {'b': 123, 'c': 'xyz'})
|
||||
self.assertTrue(geocode_result.viewport().isNull())
|
||||
self.assertEqual(res2.displayString, 'res 2')
|
||||
geocode_result = filter.locatorResultToGeocoderResult(res2)
|
||||
self.assertEqual(geocode_result.identifier(), 'res 2')
|
||||
self.assertEqual(geocode_result.geometry().asWkt(), 'Point (13 14)')
|
||||
self.assertEqual(geocode_result.crs().authid(), 'EPSG:3857')
|
||||
self.assertEqual(geocode_result.additionalAttributes(), {'d': 456})
|
||||
self.assertEqual(geocode_result.viewport(), QgsRectangle(1, 2, 3, 4))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@ -144,6 +144,16 @@ class TestQgsGeocoderLocatorFilter(unittest.TestCase):
|
||||
"lng": -83.55521200000001
|
||||
},
|
||||
"location_type": "APPROXIMATE",
|
||||
"viewport": {
|
||||
"northeast": {
|
||||
"lat": 42.1,
|
||||
"lng": -87.7
|
||||
},
|
||||
"southwest": {
|
||||
"lat": 42.0,
|
||||
"lng": -87.7
|
||||
}
|
||||
}
|
||||
},
|
||||
"place_id": "ChIJeU4e_C2HO4gRRcM6RZ_IPHw",
|
||||
"types": ["locality", "political"]
|
||||
@ -159,6 +169,7 @@ class TestQgsGeocoderLocatorFilter(unittest.TestCase):
|
||||
'locality': 'Mountain View', 'location_type': 'APPROXIMATE',
|
||||
'place_id': 'ChIJeU4e_C2HO4gRRcM6RZ_IPHw', 'postal_code': '94043',
|
||||
'route': 'Amphitheatre Pkwy', 'street_number': '1600'})
|
||||
self.assertEqual(res.viewport(), QgsRectangle(-87.7, 42, -87.7, 42.1))
|
||||
|
||||
def test_geocode(self):
|
||||
geocoder = QgsGoogleMapsGeocoder('my key')
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user