I've got an app that uses local network to talk to some devices, and an http proxy to fetch anything external. I'd like to use the map plugin in it. Now the map would require an http proxy to download the tiles. If I set global Qt proxy settings using http_proxy variable, or do it manually using QNetworkProxy::setApplicationProxy
then the map is loading fine, but the rest of the program breaks. If I disable the proxy then I can talk to my devices, but I can't see the map. I've tried using QQmlNetworkAccessManagerFactory
, as described in the example here, and it works fine for an Image
type object, as defined in the view.qml, but it doesn't work if I replace the Image
with an Item
that contains my map.
Item{
width: 500
height: 500
Map {
Plugin {
id: mapPlugin
name: "osm"
}
anchors.fill: parent
plugin: mapPlugin
center: QtPositioning.coordinate(59.91, 10.75)
zoomLevel: 14
visible: true
}
}
The MyNetworkAccessManagerFactory::create
method never gets called, and I get the following error:
QGeoTileRequestManager: Failed to fetch tile (17366,9541,15) 5 times, giving up. Last error message was: 'Error transferring http://c.tile.openstreetmap.org/15/17366/9541.png - server replied: Service Unavailable'
.
What could be the cause of that? And how can I set a QNetworkProxy for a map plugin?
You have to modify the source code of the plugin:
src/plugins/geoservices/osm/qgeocodingmanagerengineosm.cpp
src/plugins/geoservices/osm/qgeoroutingmanagerengineosm.cpp
src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp
src/plugins/geoservices/osm/qplacemanagerengineosm.cpp
In each of these files is a QNetworkAccessManager so you must add the following code:
#include <QtNetwork/QNetworkProxy>
// ...
// constructor
QString proxy = parameters.value(QStringLiteral("proxy")).toString();
if (!proxy.isEmpty()) {
#ifndef QT_NO_NETWORKPROXY
if (proxy.toLower() != QStringLiteral("system")) {
QUrl proxyUrl(proxy);
if (proxyUrl.isValid()) {
qDebug() << "Setting proxy to " << proxyUrl.toString();
m_networkManager->setProxy(
QNetworkProxy(QNetworkProxy::HttpProxy,
proxyUrl.host(),
proxyUrl.port(8080),
proxyUrl.userName(),
proxyUrl.password()));
}
} else if (QNetworkProxy::applicationProxy().type() == QNetworkProxy::NoProxy) {
QNetworkProxyFactory::setUseSystemConfiguration(true);
qDebug() << "Setting system proxy.";
}
#else
qDebug() << "No proxy support";
#endif
} else {
qDebug() << "No proxy parameter specified.";
}
I have created a .patch to make the update simple, for it download it from here.
Then you place the ends in the folder src/plugins/geoservices/osm
, apply the patch, compile and install with the following:
git clone -b 5.12.1 git@github.com:qt/qtlocation.git
cd qtlocation/src/plugins/geoservices/osm
wget https://raw.githubusercontent.com/eyllanesc/stackoverflow/master/questions/55105933/proxy-osm.patch
git apply proxy-osm.patch
qmake
make
sudo make install
Then after that you can use the proxy using a plugin parameter:
Map {
Plugin {
id: mapPlugin
name: "osm"
PluginParameter { name: "proxy"; value: "http://179.179.253.147:8080" } // <---
}
anchors.fill: parent
plugin: mapPlugin
center: QtPositioning.coordinate(59.91, 10.75)
zoomLevel: 14
visible: true
}