python - 使用 python 3 使用 PyQt4 QWebView 查看 map

标签 python python-3.x pyqt pyqt4 openstreetmap

我正在构建一个程序,可以根据数据库中的特定坐标显示带有标记的 map ,因此过程是:

  1. 使用 (folium) 从 osm 获取 map
  2. 添加标记
  3. 将 map 另存为 HTML
  4. 在 QWebView 中显示 map.html。

但是如果坐标总是在变化,例如(车辆跟踪系统),这种方法就不实用了。

有什么方法可以让我在 map 上添加或更新标记,避免之前的过程,而不必创建 map.html 文件,然后将其加载到 QWebView,然后每次都显示它。

谢谢

最佳答案

前段时间我创建了一个小型库,使用 PyQt 和 Google Maps 在 map 中显示标记。或 OpenStreetMap ,因为你的问题我添加了这个功能所以你可以从这个link下载代码并尝试示例:qOSMExample2.py

在这个回答中,我将向您展示我的代码中最重要的部分,以便您可以添加自定义功能。

QWebView 支持 javascript,所以我使用了 leaflet 库,它包含在 html 中,如下所示:

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>


    <style type="text/css">
			html { height: 100%; }
			body { height: 100%; margin: 0; padding: 0 }
			#mapid { height: 100% }
    </style>

    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css"
          integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ=="
          crossorigin=""/>

    <script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet.js"
            integrity="sha512-A7vV8IFfih/D732iSSKi20u/ooOfj/AGehOKq0f4vLT1Zr2Y+RX7C+w8A1gaSasGtRUZpF/NZgzSAu4/Gc41Lg=="
            crossorigin=""></script>

    <script type="text/javascript" src="qOSM.js"></script>
</head>
<body onload="initialize()">
<div id="mapid" style="width:100%; height:100%"></div>
</body>
</html>

此外,如果我们观察到我已经导入了 qOSM.js 文件,该文件实现了创建逻辑、移动 map 以及与标记相同的逻辑。

另一个重要的是将 python 与 javascript 交互,因为 pyqt 为我们提供了 2 个函数:

void QWebFrame::addToJavaScriptWindowObject(const QString & name, QObject * object)

Make object available under name from within the frame's JavaScript context. The object will be inserted as a child of the frame's window object. [...]

self.page().mainFrame().addToJavaScriptWindowObject("qtWidget", self)

QVariant QWebFrame::evaluateJavaScript(const QString & scriptSource)

Evaluates the JavaScript defined by scriptSource using this frame as context and returns the result of the last executed statement.

def runScript(self, script):
    return self.page().mainFrame().evaluateJavaScript(script)

第一个函数允许我们在 js 中嵌入一个 python 对象,因此我们可以从 js 输出信号并将它们连接到 python 插槽。二是面向执行js函数,接收返回值。总之,第一个用于异步获取答案,第二个用于同步获取答案。

在下一部分中,我将展示实现上述功能的js:

// Where you want to render the map.

var map;

var markers = [];

var LeafIcon;

function initialize() {
    var element = document.getElementById('mapid');

    map = L.map(element);

    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);

    if (typeof qtWidget !== 'undefined') {

        map.on('dragend', function () {
            center = map.getCenter();
            qtWidget.mapMoved(center.lat, center.lng);
        });

        map.on('click', function (ev) {
            qtWidget.mapClicked(ev.latlng.lat, ev.latlng.lng);
        });

        map.on('dblclick', function (ev) {
            qtWidget.mapDoubleClicked(ev.latlng.lat, ev.latlng.lng);
        });

        map.on('contextmenu', function (ev) {
            qtWidget.mapRightClicked(ev.latlng.lat, ev.latlng.lng);
        });
    }

    LeafIcon = L.Icon.extend({
        options: {
            shadowUrl: 'leaf-shadow.png',
            iconSize: [38, 95],
            shadowSize: [50, 64],
            iconAnchor: [22, 94],
            shadowAnchor: [4, 62],
            popupAnchor: [-3, -76]
        }
    });
}

function osm_setCenter(lat, lng) {
    //console.log(lat);
    map.panTo(new L.LatLng(lat, lng));
}

function osm_getCenter() {
    return map.getCenter();
}

function osm_setZoom(zoom) {
    map.setZoom(zoom);
}

function osm_addMarker(key, latitude, longitude, parameters) {

    if (key in markers) {
        osm_deleteMarker(key);
    }

    if ("icon" in parameters) {

        parameters["icon"] = new L.Icon({
            iconUrl: parameters["icon"],
            iconAnchor: new L.Point(16, 16)
        });
    }

    var marker = L.marker([latitude, longitude], parameters).addTo(map);

    if (typeof qtWidget !== 'undefined') {

        marker.on('dragend', function (event) {
            var marker = event.target;
            qtWidget.markerMoved(key, marker.getLatLng().lat, marker.getLatLng().lng);
        });

        marker.on('click', function (event) {
            var marker = event.target;
            //marker.bindPopup(parameters["title"]);
            qtWidget.markerClicked(key, marker.getLatLng().lat, marker.getLatLng().lng);
        });

        marker.on('dbclick', function (event) {
            var marker = event.target;
            qtWidget.markerClicked(key, marker.getLatLng().lat, marker.getLatLng().lng);
        });

        marker.on('contextmenu', function (event) {
            var marker = event.target;
            qtWidget.markerRightClicked(key, marker.getLatLng().lat, marker.getLatLng().lng);
        });
    }

    markers[key] = marker;
    return key;
}

function osm_deleteMarker(key) {
    map.removeLayer(markers[key]);
    delete markers[key];
}

function osm_moveMarker(key, latitude, longitude) {
    marker = markers[key];
    var newLatLng = new L.LatLng(latitude, longitude);
    marker.setLatLng(newLatLng);
}

function osm_posMarker(key) {
    marker = markers[key];
    return [marker.getLatLng().lat, marker.getLatLng().lng];
}


http://

输出:

关于python - 使用 python 3 使用 PyQt4 QWebView 查看 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45971188/

相关文章:

python - `np.concatenate` 一个带有稀疏矩阵的 numpy 数组

python - 分别改变并行进程中的不同python对象

python - 在 for 循环中返回一次迭代?

python - Qt 将不需要的参数传递给槽

python - 想要将 dataset.info() 结果存储到 Python 中的数据框中

Python 注释不同输入情况的返回类型

python - 在Python中自动化时如何使用selenium处理Microsoft Outlook应用程序弹出窗口

Python Pandas fillna()

python - PyQt自定义对话框——如何获取返回值?

python从子部件调用父方法