How can I create a online/offline map in QML? - qt

Currently I have this map. My problem is that the plugin parameter "osm.mapping.offline.directory" loads all tiles in the cache. If I have 20000 tiles in the folder he tries to load all those tiles. This takes a lot of time.
How can I tell the OSM Plugin how many tiles he should load.
If this does not work, have I write a new plugin?
Map
{
id: map
anchors.fill: parent
zoomLevel: 14
property bool isMapOnline = false
Component.onCompleted: map.plugin = _guiMap.mapIsOnline ? osmPlugin : offlinePlugin
Plugin
{
id: osmPlugin
name: "osm"
PluginParameter { name: "osm.mapping.host"; value: "http://tile.openstreetmap.org/" }
PluginParameter { name: "osm.mapping.providersrepository.disabled"; value: "true" }
}
Plugin
{
id: offlinePlugin
name: "osm"
PluginParameter { name: "osm.mapping.offline.directory"; value: "C:/Tiles" }
}

I have a working solution which looks very similar to yours.
First, fix the syntax error in your property initialization.
property bool isMapOnline: false
Second, replace
Component.onCompleted: map.plugin = _guiMap.mapIsOnline ? osmPlugin : offlinePlugin
with
plugin: isMapOnline ? osmPlugin : offlinePlugin
There are some other minor differences; however, this should get you working.

Related

How to use Loader and StackView both together, when needs some pages load once and some several times?

I have a pages flow like this:
That i Implemented it with a "Loader" and a "StackView", "splash" and "authorize" load in "Loader", and "Dashboard" and other pages will load in "StackView", "StackView" is not nasted (load) in "Loader", Just i invisable it befor load "Dashboard" like:
Loader {
id:loader
anchors.fill: parent
visible: true // till authorization
source: "qrc:/pages/Splash.qml"
}
StackView {
id: stack_view
anchors.fill: parent
visible: false // till authorization done and load dashboard
}
StateGroup {
id: state_group
state: "SPLASH"
states: [
State {
name: "SPLASH"
PropertyChanges {target: loader; source: "qrc:/pages/Splash.qml"}
},
State {
name: "AOUTHORIZE"
PropertyChanges {target: loader; source: "qrc:/pages/Login.qml"}
},
State {
name: "STACKVIEW"
PropertyChanges {target: loader; visible: false}
PropertyChanges {target: stack_view; visible: true}
}
]
}
As diagram shows "Splash" and "Authorize" load once, "Dashboard" and other pages may load several times, I want to know the way i used "Loader" and "StackView" is good? or how and what components is beter to use?

Route doesn't show

By following a part of this example
display multiple routes on a map using RouteMap QML Qt
I'm trying to show a route inside a MapView in a QML view of my QT application, by using the following code; but the route don't appear. No errors are appearing in the output console. Did I do something wrong?
Map {
anchors.fill: parent
plugin: mapboxglPlugin
center: QtPositioning.coordinate(60.170448, 24.942046) // Oslo
zoomLevel: 16
id: mapMain
copyrightsVisible: false
RouteModel {
id: rm
plugin: mapboxglPlugin
query: RouteQuery {id: routeQuery }
Component.onCompleted: {
routeQuery.addWaypoint(QtPositioning.coordinate(60.170448, 24.942046));
routeQuery.addWaypoint(QtPositioning.coordinate(62.170448, 23.942046));
update();
}
}
MapItemView {
model: rm
delegate: Component{
MapRoute {
route: routeData
line.color: "green"
line.width: 5
smooth: true
}
}
}
}

display multiple routes on a map using RouteMap QML Qt

I want to display a list of routes on a map using Qt Location properties, I was able to display one route, but I don't know how to display multiple ones. Here's my code:
RouteModel {
id: routeModel
plugin: somePlugin
query: RouteQuery {}
Component.onCompleted: {
query.addWaypoint(QtPositioning.coordinate(26.328045523310905, 50.080033033011546));
query.addWaypoint(QtPositioning.coordinate(26.333615791655415, 50.097984054173025));
routeModel.update();
query.addWaypoint(QtPositioning.coordinate(26.291584, 50.199094));
query.addWaypoint(QtPositioning.coordinate(26.288128, 50.188725));
routeModel.update();
}
onStatusChanged: console.debug("current route model status", status, count, errorString)
}
I wish for each couple of addWayPoints to be a distinct route. How canI achieve that?
I added multiple models with their correspondent mapitemview, still it didn't work.
RouteModel {
id: routeModel
plugin: somePlugin
query: RouteQuery {}
Component.onCompleted: {
query.addWaypoint(QtPositioning.coordinate(26.328045523310905, 50.080033033011546));
query.addWaypoint(QtPositioning.coordinate(26.333615791655415, 50.097984054173025));
routeModel.update();
}
}
RouteModel {
id: rm
plugin: somePlugin
query: RouteQuery {}
Component.onCompleted: {
query.addWaypoint(QtPositioning.coordinate(26.291584, 50.199094));
query.addWaypoint(QtPositioning.coordinate(26.288128, 50.188725));
rm.update();
}
}
RouteModel {
id: rm1
plugin: somePlugin
query: RouteQuery {}
Component.onCompleted: {
query.addWaypoint(QtPositioning.coordinate(26.278496, 50.203740));
query.addWaypoint(QtPositioning.coordinate(26.272351, 50.185939));
rm.update();
}
}
Map {
id: map
anchors.fill: parent
plugin: somePlugin
center: magione
gesture.enabled: true
zoomLevel: 13
MapItemView {
model: routeModel
delegate: MapRoute {
route: routeData
line.color: "blue"
line.width: 5
smooth: true
}
}
MapItemView {
model: rm
delegate: MapRoute {
route: routeData1
line.color: "green"
line.width: 5
smooth: true
}
}
MapItemView {
model: rm2
delegate: MapRoute {
route: routeData2
line.color: "black"
line.width: 5
smooth: true
}
}
}
I was just trying to do the same task, just accomplished IT. As in your first attempt, you should add multiple addWayPoints, but update the model only once at the end. Here is an example of a route visiting the following places A->B->C->A
Component.onCompleted:
{
query.addWaypoint(QtPositioning.coordinate(-25.402340, -49.248682));
query.addWaypoint(QtPositioning.coordinate(-25.392142, -49.202556));
query.addWaypoint(QtPositioning.coordinate(-25.372512, -49.227785));
query.addWaypoint(QtPositioning.coordinate(-25.402340, -49.248682));
routeModel.update();
}
Results in: Multiple routes:
Just wondering now how do I get pinpoints at each route stoppoint.
Showing all routes returned from a query normally works out of the box (assuming the plugin you are using gives you more than one result per route request).
If you want to simultaneously display routes for multiple requests, you need one model/view per request you want to simultaneously display
I finish pointing out that, in your example, you are using the model roles wrong.
There is no such routeData1 or routeData2, but only routeData, and you should use this role every time you try to access the route data from a route model.

QML: show only certain Components depending on a State

I have several ui.qml files, let's say A.ui.qml, B.ui.qml, C.ui.qml.
Then I have to create, depending on a State, a window that shows A+B, or B+A, or B+C, etc.
In my main.qml, I've actually written the following:
...
Item {
id: contentArea
state: "state1"
AForm {
id: aForm
}
BForm {
id: bForm
}
states: [
State {
name: "state1"
PropertyChanges { target: aForm; x: 0 }
PropertyChanges { target: bForm; x: 400 }
},
State {
name: "state2"
PropertyChanges { target: aForm; x: 400 }
PropertyChanges { target: bForm; x: 0 }
}
]
...
So, when setting contentArea.state = "state2", A and B forms are swapped.
But this is just an example to see if it works.
Now I need to create all the forms (I guess using Component) and show them only if the state is a certain one.
How to do that?
You replace AForm and BForm by Loaders, and set the source-property of this Loaders to the right file name, or the sourceComponent to the right Component id.
Loader {
id: topLoader
}
Loader {
id: bottomLoader
y: 200
}
states: [
State {
name: "state1"
PropertyChanges { target: topLoader; source: "AForm.ui.qml" }
PropertyChanges { target: bottomLoader; source: "BForm.ui.qml" }
},
...
]
This process will destroy and recreate the instances of the ui.qml-files whenever the state changes.
You can also use e.g. a ListView with snapMode: ListView.SnapToItem, interactive: false, and change the currentItem when the state changes.
You could also create all the objects, and only parent the two you want to show to Items that serve as frames, and the rest is parented to null.
Or you use three or four Loaders of which you only show two, that you shift around as necessary, only loading files that shall be shown. Here you will need to write a bit more logic.

How to put MouseArea inside buildings boundaries in QML Map

I'm trying to make buildings on map clickable using MouseArea. I tried using GeocodeModel with query "building" which was obviously stupid idea. Then I tried getting mapItems : list of Map Object and printing them on the console, but that: "qml: Map items: []" was the only result. Now I'm thinking if it is even possible without going into implementation side of maybe delegate of Map if such thing exists :P Why there is nothing in mapItems ? Are they in some way private in Map ?
My shortened code:
Window {
visible: true
width: 640
height: 480
Map {
id: map
anchors.fill: parent
plugin: Plugin{
name: "osm"
}
zoomLevel: 15
Component.onCompleted: {
console.log("Map items: ", map.mapItems);
}
}
GeocodeModel{
id: geoModel
plugin: Plugin{
name: "osm"
}
autoUpdate: true
query: "building"
limit: -1
onLocationsChanged: {
map.center = geoModel.get(0).coordinate
console.log(count);
}
}

Resources