|
|
|
|
// Copyright (C) 2017 The Qt Company Ltd.
|
|
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
|
|
|
|
|
|
|
|
//! [Imports]
|
|
|
|
|
import QtQuick
|
|
|
|
|
import QtPositioning
|
|
|
|
|
import QtLocation
|
|
|
|
|
|
|
|
|
|
//! [Imports]
|
|
|
|
|
Map{
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
id: map //! [Initialize Plugin]
|
|
|
|
|
plugin: Plugin {
|
|
|
|
|
id: myPlugin
|
|
|
|
|
name: "TiMap"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
center: QtPositioning.coordinate(37.8564642, 107.4229819)
|
|
|
|
|
|
|
|
|
|
zoomLevel: 4
|
|
|
|
|
minimumZoomLevel: 2
|
|
|
|
|
maximumZoomLevel: 18
|
|
|
|
|
onZoomLevelChanged: {
|
|
|
|
|
if (zoomLevel < minimumZoomLevel) {
|
|
|
|
|
zoomLevel = minimumZoomLevel
|
|
|
|
|
}
|
|
|
|
|
if (zoomLevel > maximumZoomLevel) {
|
|
|
|
|
zoomLevel = maximumZoomLevel
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Component.onCompleted: {console.log(map.supportedMapTypes)}
|
|
|
|
|
Component.onCompleted: updateActiveMapType(map,"Tianditu Street");
|
|
|
|
|
|
|
|
|
|
//更新地图显示类型
|
|
|
|
|
function updateActiveMapType(control,para) {
|
|
|
|
|
for (var i = 0; i < control.supportedMapTypes.length; i++) {
|
|
|
|
|
console.log(control.supportedMapTypes[i].name)
|
|
|
|
|
if (para === control.supportedMapTypes[i].name) {
|
|
|
|
|
control.activeMapType = control.supportedMapTypes[i]
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 被选中位置显示,与页面列表信息同步
|
|
|
|
|
// signal locationClicked(string imsi)
|
|
|
|
|
signal indexClicked(int row)
|
|
|
|
|
|
|
|
|
|
MapItemView {
|
|
|
|
|
id: itemview
|
|
|
|
|
parent: map
|
|
|
|
|
// model: testModel
|
|
|
|
|
model: imsiDataModel
|
|
|
|
|
z:2
|
|
|
|
|
delegate: MapQuickItem {
|
|
|
|
|
id: location
|
|
|
|
|
// property bool isSelected: false // 标记是否选中
|
|
|
|
|
property string imsi: model.imsi
|
|
|
|
|
property double latitude: model.latitude
|
|
|
|
|
property double longitude: model.longitude
|
|
|
|
|
coordinate: QtPositioning.coordinate(latitude, longitude)
|
|
|
|
|
//图像底部中心对齐坐标点
|
|
|
|
|
anchorPoint.x: image.width * 0.5
|
|
|
|
|
anchorPoint.y: image.height
|
|
|
|
|
|
|
|
|
|
sourceItem: Item {
|
|
|
|
|
width: image.width
|
|
|
|
|
height: image.height
|
|
|
|
|
Image {
|
|
|
|
|
id: image
|
|
|
|
|
source: "marker"
|
|
|
|
|
property double imageWidth: 20
|
|
|
|
|
property double imageHeight: 25
|
|
|
|
|
width: itemMouse.containsMouse ? imageWidth*1.25 : imageWidth
|
|
|
|
|
height: itemMouse.containsMouse ? imageHeight*1.25: imageHeight
|
|
|
|
|
Text {
|
|
|
|
|
anchors.centerIn: parent
|
|
|
|
|
text: (model.row + 1)
|
|
|
|
|
font.pixelSize: image.width*0.5
|
|
|
|
|
color: "black"
|
|
|
|
|
horizontalAlignment: Text.AlignRight // 设置水平对齐方式为右对齐
|
|
|
|
|
verticalAlignment: Text.AlignBottom // 设置垂直对齐方式为底部对齐
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MouseArea {
|
|
|
|
|
id: itemMouse
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
hoverEnabled: true
|
|
|
|
|
propagateComposedEvents: true
|
|
|
|
|
cursorShape: Qt.PointingHandCursor
|
|
|
|
|
onClicked: {
|
|
|
|
|
indexClicked(model.row)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//点击外部列表时,地图上显示被选中的图标
|
|
|
|
|
ListModel {
|
|
|
|
|
id: listSelectModel
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MapItemView {
|
|
|
|
|
parent: map
|
|
|
|
|
// model: testModel
|
|
|
|
|
model: listSelectModel
|
|
|
|
|
z:3
|
|
|
|
|
delegate: MapQuickItem { // 当前选中的标记
|
|
|
|
|
z: itemview.z + 1
|
|
|
|
|
// property string imsi: model.imsi
|
|
|
|
|
property double latitude: model.latitude
|
|
|
|
|
property double longitude: model.longitude
|
|
|
|
|
property string imagesource: "selectlocation.png"
|
|
|
|
|
property bool selected: true
|
|
|
|
|
coordinate: QtPositioning.coordinate(latitude, longitude)
|
|
|
|
|
//图像底部中心对齐坐标点
|
|
|
|
|
anchorPoint.x: selectimgae.width * 0.5
|
|
|
|
|
anchorPoint.y: selectimgae.height
|
|
|
|
|
sourceItem: Item {
|
|
|
|
|
Image {
|
|
|
|
|
id: selectimgae
|
|
|
|
|
source: imagesource
|
|
|
|
|
property double imageWidth: 30
|
|
|
|
|
property double imageHeight: 30
|
|
|
|
|
width: imageWidth
|
|
|
|
|
height: imageHeight
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// // 外部信号发射时创建图标
|
|
|
|
|
Connections {
|
|
|
|
|
target: imsiDataModel
|
|
|
|
|
function onDataCleared() {
|
|
|
|
|
listSelectModel.clear()
|
|
|
|
|
map.zoomLevel = 5
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// // 外部信号发射时创建图标, 可多选
|
|
|
|
|
Connections {
|
|
|
|
|
target: imsiSelectModel
|
|
|
|
|
function onSelectionChanged (selected, deselected) {
|
|
|
|
|
updateSelect(imsiSelectModel)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Connections {
|
|
|
|
|
target: imsiDataModel
|
|
|
|
|
function onDataChanged(topLeft, bottomRight,roles) {
|
|
|
|
|
updateSelect(imsiSelectModel)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
function updateSelect(imsiSelectModel) {
|
|
|
|
|
var indexs = imsiSelectModel.selectedIndexes
|
|
|
|
|
console.log(indexs)
|
|
|
|
|
// if (indexs.length === 0) {
|
|
|
|
|
listSelectModel.clear()
|
|
|
|
|
// }
|
|
|
|
|
if (indexs.length === 0) return;
|
|
|
|
|
|
|
|
|
|
var minLat = 999;
|
|
|
|
|
var maxLat = -999;
|
|
|
|
|
var minLon = 999;
|
|
|
|
|
var maxLon = -999;
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i<indexs.length; i++){
|
|
|
|
|
if (indexs[i].column === 0) {
|
|
|
|
|
var latitude = Number(imsiDataModel.data(indexs[i], imsiDataModel.getRole("latitude")))
|
|
|
|
|
var longitude = Number(imsiDataModel.data(indexs[i], imsiDataModel.getRole("longitude")))
|
|
|
|
|
|
|
|
|
|
if (latitude < minLat) minLat = latitude;
|
|
|
|
|
if (latitude > maxLat) maxLat = latitude;
|
|
|
|
|
if (longitude < minLon) minLon = longitude;
|
|
|
|
|
if (longitude > maxLon) maxLon = longitude;
|
|
|
|
|
|
|
|
|
|
listSelectModel.append({
|
|
|
|
|
"latitude": latitude, // 258
|
|
|
|
|
"longitude": longitude //257
|
|
|
|
|
});// 258);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var centerLat = (minLat + maxLat) / 2.;
|
|
|
|
|
console.log(minLat, maxLat, )
|
|
|
|
|
var centerLon = (minLon + maxLon) / 2.;
|
|
|
|
|
|
|
|
|
|
var latDiff = maxLat - minLat;
|
|
|
|
|
var lonDiff = maxLon - minLon;
|
|
|
|
|
var maxDiff = Math.max(latDiff, lonDiff);
|
|
|
|
|
|
|
|
|
|
// 根据最大差值调整缩放级别
|
|
|
|
|
if (maxDiff < 0.01) {
|
|
|
|
|
map.zoomLevel = 15;
|
|
|
|
|
} else if (maxDiff < 0.1) {
|
|
|
|
|
map.zoomLevel = 12;
|
|
|
|
|
} else if (maxDiff < 1) {
|
|
|
|
|
map.zoomLevel = 10;
|
|
|
|
|
} else {
|
|
|
|
|
map.zoomLevel = 5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
map.center = QtPositioning.coordinate(centerLat, centerLon);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 右下角经纬度显示
|
|
|
|
|
HoverHandler {
|
|
|
|
|
// 最外层的鼠标事件不要用MouseArea,不然hover事件和内层冲突
|
|
|
|
|
id: mapHoverHandler
|
|
|
|
|
acceptedDevices: PointerDevice.Mouse
|
|
|
|
|
onPointChanged: {
|
|
|
|
|
var position = map.toCoordinate(point.position)
|
|
|
|
|
coordinatesDisplay.latitude = position.latitude
|
|
|
|
|
coordinatesDisplay.longitude = position.longitude
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Rectangle {
|
|
|
|
|
id: coordinatesDisplay
|
|
|
|
|
width: 270
|
|
|
|
|
height: 20
|
|
|
|
|
anchors.right: parent.right
|
|
|
|
|
anchors.bottom: parent.bottom
|
|
|
|
|
color: "transparent" // 设置背景颜色为透明
|
|
|
|
|
property double latitude
|
|
|
|
|
property double longitude
|
|
|
|
|
Text {
|
|
|
|
|
anchors.centerIn: parent
|
|
|
|
|
text: "Latitude: " + parent.latitude.toFixed(
|
|
|
|
|
7) + " Longitude: " + parent.longitude.toFixed(7)
|
|
|
|
|
color: "black"
|
|
|
|
|
horizontalAlignment: Text.AlignRight // 设置水平对齐方式为右对齐
|
|
|
|
|
verticalAlignment: Text.AlignBottom // 设置垂直对齐方式为底部对齐
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//叠加标注信息图层
|
|
|
|
|
Map {
|
|
|
|
|
id: overlay_map
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
plugin: Plugin {
|
|
|
|
|
name: "TiMap"
|
|
|
|
|
}
|
|
|
|
|
center: parent.center
|
|
|
|
|
color: 'transparent' // Necessary to make this map transparent
|
|
|
|
|
minimumFieldOfView: parent.minimumFieldOfView
|
|
|
|
|
maximumFieldOfView: parent.maximumFieldOfView
|
|
|
|
|
minimumTilt: parent.minimumTilt
|
|
|
|
|
maximumTilt: parent.maximumTilt
|
|
|
|
|
minimumZoomLevel: parent.minimumZoomLevel
|
|
|
|
|
maximumZoomLevel: parent.maximumZoomLevel
|
|
|
|
|
zoomLevel: parent.zoomLevel
|
|
|
|
|
tilt: parent.tilt;
|
|
|
|
|
bearing: parent.bearing
|
|
|
|
|
fieldOfView: parent.fieldOfView
|
|
|
|
|
z: parent.z + 1;
|
|
|
|
|
Component.onCompleted: {
|
|
|
|
|
// 失量图 标注
|
|
|
|
|
updateActiveMapType(this,"Tianditu Street Road");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 注意: Qt6 中,地图控件不再自带拖拽,缩放等操作,需要手动操作,官方提供以下方式进行地图操作
|
|
|
|
|
PinchHandler {
|
|
|
|
|
id: pinch
|
|
|
|
|
target: null
|
|
|
|
|
onActiveChanged: if (active) {
|
|
|
|
|
map.startCentroid = map.toCoordinate(pinch.centroid.position, false)
|
|
|
|
|
}
|
|
|
|
|
onScaleChanged: (delta) => {
|
|
|
|
|
map.zoomLevel += Math.log2(delta)
|
|
|
|
|
map.alignCoordinateToPoint(map.startCentroid, pinch.centroid.position)
|
|
|
|
|
}
|
|
|
|
|
onRotationChanged: (delta) => {
|
|
|
|
|
map.bearing -= delta
|
|
|
|
|
map.alignCoordinateToPoint(map.startCentroid, pinch.centroid.position)
|
|
|
|
|
}
|
|
|
|
|
grabPermissions: PointerHandler.TakeOverForbidden
|
|
|
|
|
}
|
|
|
|
|
WheelHandler {
|
|
|
|
|
id: wheel
|
|
|
|
|
// workaround for QTBUG-87646 / QTBUG-112394 / QTBUG-112432:
|
|
|
|
|
// Magic Mouse pretends to be a trackpad but doesn't work with PinchHandler
|
|
|
|
|
// and we don't yet distinguish mice and trackpads on Wayland either
|
|
|
|
|
acceptedDevices: Qt.platform.pluginName === "cocoa" || Qt.platform.pluginName === "wayland"
|
|
|
|
|
? PointerDevice.Mouse | PointerDevice.TouchPad
|
|
|
|
|
: PointerDevice.Mouse
|
|
|
|
|
rotationScale: 1/15
|
|
|
|
|
property: "zoomLevel"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//注意,如果使用此方式,在地图上层有Rectangle 等控件时,在此控件上操作也会影响到底层的地图,DragHandler暂时无法解决,
|
|
|
|
|
// 如果遇到此问题,可以尝试使用 下方 MouseArea 里的地图拖拽方式,禁用DragHandler
|
|
|
|
|
DragHandler {
|
|
|
|
|
id: drag
|
|
|
|
|
target: null
|
|
|
|
|
onTranslationChanged: (delta) => map.pan(-delta.x, -delta.y)
|
|
|
|
|
}
|
|
|
|
|
Shortcut {
|
|
|
|
|
enabled: map.zoomLevel < map.maximumZoomLevel
|
|
|
|
|
sequence: StandardKey.ZoomIn
|
|
|
|
|
onActivated: map.zoomLevel = Math.round(map.zoomLevel + 1)
|
|
|
|
|
}
|
|
|
|
|
Shortcut {
|
|
|
|
|
enabled: map.zoomLevel > map.minimumZoomLevel
|
|
|
|
|
sequence: StandardKey.ZoomOut
|
|
|
|
|
onActivated: map.zoomLevel = Math.round(map.zoomLevel - 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
MouseArea {
|
|
|
|
|
id: mapMouseArea
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
hoverEnabled: true
|
|
|
|
|
z: overlayMap.visible ? overlayMap.z + 1 : map.z + 1
|
|
|
|
|
property real startMouseX: 0
|
|
|
|
|
property real startMouseY: 0
|
|
|
|
|
property real lastMouseX: 0
|
|
|
|
|
property real lastMouseY: 0
|
|
|
|
|
|
|
|
|
|
onClicked: mouse => {
|
|
|
|
|
if (mouse.button === Qt.LeftButton) {
|
|
|
|
|
let point = Qt.point(mouse.x, mouse.y)
|
|
|
|
|
// mapPositionClicked(point)
|
|
|
|
|
// mapCoordinateClicked(map.toCoordinate(point))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onPressed: mouse => {
|
|
|
|
|
lastMouseX = Math.round(mouse.x)
|
|
|
|
|
lastMouseY = Math.round(mouse.y)
|
|
|
|
|
startMouseX = lastMouseX
|
|
|
|
|
startMouseY = lastMouseY
|
|
|
|
|
}
|
|
|
|
|
onDoubleClicked: mouse => {
|
|
|
|
|
// mapPositionDoubleClicked(Qt.point(mouse.x,
|
|
|
|
|
// mouse.y))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onPositionChanged: mouse => {
|
|
|
|
|
let point = Qt.point(mouse.x, mouse.y)
|
|
|
|
|
mapPosition = point
|
|
|
|
|
mapCoordinate = map.toCoordinate(point)
|
|
|
|
|
if (pressed) {
|
|
|
|
|
var newMouseX = Math.round(mouse.x)
|
|
|
|
|
var newMouseY = Math.round(mouse.y)
|
|
|
|
|
map.pan(lastMouseX - newMouseX,
|
|
|
|
|
lastMouseY - newMouseY)
|
|
|
|
|
lastMouseX = newMouseX
|
|
|
|
|
lastMouseY = newMouseY
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
}
|