Zoomlevel in qml map using osm plugin - qt

I have a qml map that uses osm plugin and it is in offline mode. I noticed that the maximum zoomlevel is 19 and I want to increase it. How can I change the maximum zoomlevel using this plugin?
Is there a solution?
import QtQuick.Window 2.12
import QtQuick 2.0
import QtLocation 5.11
import QtPositioning 5.11
import QtQuick.Controls 2.5
import QtQuick.Controls.Styles 1.4
Window {
visible: true
width: 640
height: 480
Plugin {
id: mapPlugin
name: "osm"
PluginParameter {
name: "osm.mapping.custom.host"
value: "file:///home/mahmud/Maps/humanitarian/" // this is the directory of map tiles
}
PluginParameter {
name: "osm.mapping.providersrepository.disabled"
value: true
}
}
Map {
id: map
anchors.fill: parent
width: parent.width
height:parent.height
plugin: mapPlugin
center: QtPositioning.coordinate(32.4279, 53.6880) // Oslo
zoomLevel: 6
maximumZoomLevel: 30
onZoomLevelChanged: {
console.log(map.zoomLevel)
}
Component.onCompleted: {
for( var i_type in supportedMapTypes ) {
if( supportedMapTypes[i_type].name.localeCompare( "Custom URL Map" ) === 0 ) {
activeMapType = supportedMapTypes[i_type]
}
}
}
}
}

Related

QML Custom Tile server

I'm trying to plot an offline map using a custom server that my machine is hosting. I've followed the steps of this project for docker. It works when I use my browser (http://localhost:8080/). But when I try to access QML using the code below I just get a Static image GPS output
.
What am I doing wrong? I should see Zambia with a good resolution as I see in the Browser.
QML CODE
import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.VirtualKeyboard 2.4
import QtLocation 5.11
ApplicationWindow {
id: window
width: 640
height: 480
visible: true
title: qsTr("GPS")
Plugin{
id: plugin_osm
name: "osm"
PluginParameter {
name: "osm.mapping.custom.host"
value: "http://localhost:8080"
}
/*disable retrieval of the providers information from the remote repository.
If this parameter is not set to true (as shown here), then while offline,
network errors will be generated at run time*/
PluginParameter {
name: "osm.mapping.providersrepository.disabled"
value: true
}
}
Map {
id: map
anchors.fill: parent
plugin: plugin_osm
zoomLevel: 12
minimumZoomLevel: 5
maximumZoomLevel: 17
center: QtPositioning.coordinate(54.2,16.2)
activeMapType: supportedMapTypes[supportedMapTypes.length - 1]
}
}
You have 2 errors:
The host is wrong.
The coordinate is not to Zambia but to Poland
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtLocation 5.15
import QtPositioning 5.15
ApplicationWindow {
id: window
width: 640
height: 480
visible: true
title: qsTr("GPS")
Plugin {
id: plugin_osm
name: "osm"
PluginParameter {
name: "osm.mapping.custom.host"
value: "http://localhost/tile/"
}
/*disable retrieval of the providers information from the remote repository.
If this parameter is not set to true (as shown here), then while offline,
network errors will be generated at run time*/
PluginParameter {
name: "osm.mapping.providersrepository.disabled"
value: true
}
}
Map {
id: map
anchors.fill: parent
plugin: plugin_osm
zoomLevel: 12
minimumZoomLevel: 5
maximumZoomLevel: 17
center: QtPositioning.coordinate(-15.4067, 28.2871)
activeMapType: supportedMapTypes[supportedMapTypes.length - 1]
}
}
Output:

Dynamically change custom host URL of osm Plugin in a QML Map

I have a custom chart host with several tiled maps in a directory structure:
http://host/New_York/
http://host/Washington/
http://host/Montreal/
The QML application has a ComboBox component that allows the user to select which chart he wants to display.
The Map component uses the osm Plugin with a PluginParameter pointing to the URL to use for the chart. I thought I could simply dynamically assign a value to this PluginParameter, but it does not work, the value remains unchanged even after assigning it. I also tried destroying the Plugin object, recreating it and assigning it to the Map object, but I get an error saying that the plugin property is ReadOnly.
What is the proper way to dynamically change the custom host URL of a Plugin object used by a Map component?
Plugin {
id: mapPlugin
name: "osm"
PluginParameter { id: charturl; name: "osm.mapping.custom.host"; }
}
Map {
id: mapview
plugin: mapPlugin
activeMapType: supportedMapTypes[supportedMapTypes.length - 1]
...
ComboBox {
...
onCurrentIndexChanged: {
charturl.value = cbItems.get(currentIndex).url
...
The Plugin can only be written once, so you cannot change it later, so in this you will have to create a new map using Loader:
main.qml
import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Layouts 1.14
import QtQuick.Controls 2.14
import QtLocation 5.14
import QtPositioning 5.14
Window {
visible: true
width: 640
height: 480
ColumnLayout {
anchors.fill: parent
ComboBox {
id: combobox
model: [
"http://host/New_York/",
"http://host/Washington/",
"http://host/Montreal/"
]
Layout.fillWidth: true
onActivated: changeHost()
}
Loader{
id: loader
Layout.fillWidth: true
Layout.fillHeight: true
onStatusChanged: if (loader.status === Loader.Ready) console.log('Loaded')
}
Component.onCompleted: changeHost()
}
function changeHost(){
var item = loader.item
var zoomLevel = item ? item.zoomLevel: 14
var center = item ? item.center: QtPositioning.coordinate(59.91, 10.75)
loader.setSource("MapComponent.qml", {
"host": combobox.currentValue,
"center": center,
"zoomLevel": zoomLevel}
)
}
}
MapComponent.qml
import QtLocation 5.14
Map {
id: map
property string host: ""
plugin: Plugin {
name: "osm"
PluginParameter {
name: "osm.mapping.custom.host"
value: map.host
}
}
activeMapType: supportedMapTypes[supportedMapTypes.length - 1]
}

How to use Material.elevation and Radius in a Pane?

I'm trying to use a Pane which I add Material.elevation: 6 but in turn I want to give it a rounded edge and I can not get both together at the same time
The following is attempted but the elevation is lost.
Pane {
// ...
Material.elevation: 6
background: Rectangle {
radius: 15
}
// ...
}
The idea is that you can keep both aspects to achieve something like:
You have to overwrite based on the source code:
RoundPane.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls.Material 2.12
import QtQuick.Controls.Material.impl 2.12
Pane {
id: control
property int radius: 2
background: Rectangle {
color: control.Material.backgroundColor
radius: control.Material.elevation > 0 ? control.radius : 0
layer.enabled: control.enabled && control.Material.elevation > 0
layer.effect: ElevationEffect {
elevation: control.Material.elevation
}
}
}
IconPane.qml
import QtQuick 2.12
import QtQuick.Controls.Material 2.12
import QtQuick.Layouts 1.12
RoundPane {
id: control
property alias name: txt.text
property alias icon: image.source
Material.elevation: 6
radius: 15
RowLayout{
anchors.fill: parent
Image {
id: image
sourceSize.height: parent.height
}
Text {
id: txt;
}
}
}
main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
IconPane{
name: "Stack <b>Overflow</b>"
icon: "https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-icon.svg"
anchors.centerIn: parent
}
}

Displaying Marker in QT QML Map

I'm trying to add marker in QT QML Map. This is the code that I use to add a marker in Map, but the marker is not displaying. Please do help! I'm a beginner in QT Programming. Sorry for my grammar. Thank you!
Plugin {
id: mapPlugin
name: "osm"
}
function addMarker(latitude, longitude)
{
var Component = Qt.createComponent("qrc:///views/marker.qml")
var Item = Component.createObject(window, { coordinate:
QtPositioning.coordinate(latitude, longitude) })
Map.addMapItem(Item)
}
Map {
anchors.fill: parent
plugin: mapPlugin
center: QtPositioning.coordinate(59.14, 14.15)
zoomLevel: 14
Component.onCompleted:
{
addMarker(59.14, 14.15)
}
}
Marker.qml
MapQuickItem
{
id: marker
anchorPoint.x: marker.width / 4
anchorPoint.y: marker.height
sourceItem: Image
{
Image
{
id: icon
source: "marker.png"
sourceSize.width: 40
sourceSize.height: 40
}
}
}
You have to use the ids to refer to the components, for example if you had Map and run Map.addMapItem(...) to what Map would the item be added ?. On the other hand you have a bad habit: you use names of existing elements such as Item that is already a type, in this case change it to item to avoid confusion, considering the above the solution is:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtLocation 5.12
import QtPositioning 5.12
Window {
id: window
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Plugin {
id: mapPlugin
name: "osm"
}
function addMarker(latitude, longitude)
{
var Component = Qt.createComponent("qrc:///views/marker.qml")
var item = Component.createObject(window, {
coordinate: QtPositioning.coordinate(latitude, longitude)
})
map.addMapItem(item)
}
Map {
id: map
anchors.fill: parent
plugin: mapPlugin
center: QtPositioning.coordinate(59.14, 14.15)
zoomLevel: 14
Component.onCompleted:addMarker(59.14, 14.15)
}
}
On the other hand in marker you point out that an Image has as a child another Image, do you think it is correct?, it is not necessary so the corrected Marker code is:
import QtQuick 2.0
import QtLocation 5.12
MapQuickItem{
id: marker
anchorPoint.x: marker.width / 4
anchorPoint.y: marker.height
sourceItem: Image{
id: icon
source: "marker.png"
sourceSize.width: 40
sourceSize.height: 40
}
}
The complete example is in the following link

How can I assign an ordering number to dynamically created component in qml?

My code (actually an official example) can draw markers and polylines on the point which I clicked. And I want that every marker has their own Text which represents its order. Text "1" for the first marker, and Text "2" for the second marker, for example. But markerCount(declared in componentCreation.js) for the Text does not increase, so all of the Text of the marker is "1" which is a default.
In the code, Rectangle which is MapQuickItem's child represents a marker, and it is dynamically created by createElements() (componentCreation.js). markerCount++ is implemented in Component.onCompleted.
The code is:
componentCreation.js
var arrayLines = []
var lineComplete = false
var markerCount = 1
function createElements(point) {
console.log(markerCount)
var componentMarker = Qt.createComponent("Marker.qml");
if (componentMarker.status === Component.Ready) {
var markerFirstCorner = componentMarker.createObject(map);
markerFirstCorner.coordinate = map.toCoordinate(point)
map.addMapItem(markerFirstCorner)
} else {
console.log("Marker not created")
}
var theLine
if (arrayLines.length === 0) {
createLine(point)
} else {
theLine = arrayLines[arrayLines.length-1]
theLine.mainPolyline.addCoordinate(map.toCoordinate(point))
}
}
function createLine(point){
var componentLine = Qt.createComponent("Line.qml")
if (componentLine.status === Component.Ready) {
var lineFirstCorner = componentLine.createObject(map);
lineFirstCorner.mainPolyline.addCoordinate(map.toCoordinate(point))
map.addMapItem(lineFirstCorner)
arrayLines.push(lineFirstCorner)
} else {
console.log("Line not created")
}
}
main.qml
import QtQuick 2.11
import QtQuick.Window 2.11
import QtLocation 5.11
import QtPositioning 5.8
import QtQuick.Controls 2.1
import "componentCreation.js" as MyScript
ApplicationWindow {
id: applicationWindow
visible: true
width: 640
height: 480
Plugin {
id: mapPlugin
name: "googlemaps"
}
Map {
id: map
anchors.fill: parent
zoomLevel: 12
plugin: mapPlugin
center: QtPositioning.coordinate(35.8926195, 128.6000172)
MouseArea{
id: mouseArea
anchors.fill: parent
z: 1
onClicked: {
console.log("Before creation : " + MyScript.markerCount)
var point = Qt.point(mouse.x, mouse.y)
console.log()
console.log("You clicked : " + map.toCoordinate(point))
MyScript.createElements(Qt.point(mouse.x,mouse.y))
}
}
}
}
Marker.qml
import QtQuick 2.0
import QtLocation 5.11
import "componentCreation.js" as MyScript
MapQuickItem {
property alias marker: marker
id: marker
sourceItem: Rectangle {
width: 50
height: 50
color: "transparent"
Image {
anchors.fill: parent
source: "images/drone.svg" // Ignore warnings from this
sourceSize: Qt.size(parent.width, parent.height)
}
Text {
anchors.fill: parent
text: { MyScript.markerCount }
}
Component.onCompleted: {
MyScript.markerCount++
console.log("markerCount: " + MyScript.markerCount)
}
}
opacity: 1.0
anchorPoint: Qt.point(sourceItem.width/2, sourceItem.height/2)
}
Line.qml
import QtQuick 2.0
import QtLocation 5.8
MapPolyline {
property alias mainPolyline: mainPolyline
id: mainPolyline
line.width: 3
line.color: 'black'
}
I'm new to Qt and Qml. I don't know why markerCount does not increase. Please tell me why or give me another way to order the markers.
Thank you for your help.
You are complicating yourself too much, in case you want to store a lot of information the correct thing is to use a model, in this case ListModel, and a view, in this case MapItemView, that has as a delegate the Marker, then use a property to save the index that it is obtained by using the count property of the model:
Marker.qml
import QtQuick 2.0
import QtLocation 5.11
MapQuickItem {
id: marker
property alias text: txt.text
sourceItem: Rectangle {
width: 50
height: 50
color: "transparent"
Image {
anchors.fill: parent
source: "images/drone.svg" // Ignore warnings from this
sourceSize: Qt.size(parent.width, parent.height)
}
Text {
id: txt
anchors.fill: parent
}
}
opacity: 1.0
anchorPoint: Qt.point(sourceItem.width/2, sourceItem.height/2)
}
main.qml
import QtQuick 2.11
import QtQuick.Window 2.11
import QtLocation 5.11
import QtPositioning 5.8
import QtQuick.Controls 2.1
ApplicationWindow {
id: applicationWindow
visible: true
width: 640
height: 480
Plugin {
id: mapPlugin
name: "googlemaps"
}
ListModel{
id: md
}
Map {
id: map
anchors.fill: parent
zoomLevel: 12
plugin: mapPlugin
center: QtPositioning.coordinate(35.8926195, 128.6000172)
MapItemView{
model: md
delegate: Marker{
text: title
coordinate: QtPositioning.coordinate(coords.latitude, coords.longitude)
}
}
Line{
id: li
}
MouseArea{
id: mouseArea
anchors.fill: parent
z: 1
onClicked: {
var point = Qt.point(mouse.x, mouse.y)
var coord = map.toCoordinate(point);
var text = md.count + 1;
md.append({"coords": coord, "title": text})
li.addCoordinate(coord)
}
}
}
}
Line.qml
import QtQuick 2.0
import QtLocation 5.8
MapPolyline {
id: mainPolyline
line.width: 3
line.color: 'black'
}

Resources