Closed patrickjane closed 3 years ago
Corresponding section dealing with image loading: https://github.com/rinigus/mapbox-gl-qml/blob/master/src/qquickitemmapboxgl.cpp#L761
Images can be displayed using different means.
The method that you were calling is to integrate it into Mapbox map and display using Mapbox style. Example use is in Pure Maps. See initialization in Component.onCompleted and update of location at onPositionShownChanged.
Mapbox styles are described at https://docs.mapbox.com/mapbox-gl-js/style-spec/ with layers at https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/ (you are interested in symbol
type). I would suggest to look also at examples on that page.
Depending on the image, this integration is recommended way for markers (current location, POIs), but also satellite images/videos (see Mapbox example with added video).
Alternative would be to use QML items and draw them on top of the map. See https://github.com/rinigus/mapbox-gl-qml/blob/master/api.md#tracking-locations-on-the-map for corresponding section.
Now coming back to your question regarding why it returns false
- I don't know exactly. I can only speculate that for some reason image loading failed.
How would I draw e.g. a Rectangle
on top of the map? I can see the API allows to associate coordinates with an ID (trackLocation
), however it is unclear to me how I would add the actual QML item to said coordinates?
You would have to add an item to pixel coordinates returned by locationChanged
signal. Bit tricky, but possible. In principle,
pixel
of the signal (may wish to set center of rect to that value, depending on your design)Okay, sounds rather complicated. I actually only need to show (clickable) points of interest. I understand that the API resembles the Mapbox GL JS spec, yet I find it really difficult to understand/create simple tasks.
Your recommended way was to use layers, using the symbol type. I'm afraid I really sound stupid here, but I still don't get how I would add the image using the layers.
I understand that I can create a source (which is basically a named pair of coordinates), and add a layer for a given source, into which I can paint (using setPaintProperty
). So tying the source with a layer enables one to paint at a given location.
But the question remains how I would tell the layer to "use" the image, or how I would assign coordinates to the image. I don't see any connection between image and source or image and layer in the API.
I guess I shall do something like:
var res = map.addImagePath("position-icon", Qt.resolvedUrl("qrc:///graphics/myimage.png")) // returns false, but still
map.addLayer("position-something??", {"type": "symbol", "source": "???"}, "waterway-label")
I think I still didn't get the idea of how the API works, so it currently does not make sense to me and I am stuck.
In this case it is rather simple as soon as you figure out the API. It is designed for cases like this and let me help you.
I'll respond later tonight or tomorrow morning.
Let's start with showing just circles in your POIs. Later, we will change to icons
In Mapbox, to display those icons:
you have to define source. Source has a name and is of certain type. For example, series of points https://github.com/rinigus/mapbox-gl-qml/blob/master/app/qml/main.qml#L250 . See how these points are added in the lines below
next, we define layer showing that source. On https://github.com/rinigus/mapbox-gl-qml/blob/master/app/qml/main.qml#L264 the layer is defined using type circle
. Note that it is using filtering in that example (few lines above). Drop it in your example. Note that the same source can be showed in multiple layers as well. In the example, labels are shown using separate layer as shown few lines below.
to draw something, you would have to define layer properties. Layers have either "layer" or "paint" properties, as defined in the style specs. For circle layer, see properties at https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#circle . See how they are defined in https://github.com/rinigus/mapbox-gl-qml/blob/master/app/qml/main.qml#L265
At this point, you should be able to see POIs shown as circles. If you add names, those should be shown as well. Note that as vector tiles maps are layered internally, it is possible also to incorporate your layer somewhere specific in the stack. But, as it sounds from your description, it is not needed.
To process clicks, you would need to add MapboxMapGestureArea https://github.com/rinigus/mapbox-gl-qml/blob/master/app/qml/main.qml#L95 . For just clicking, I suggest to set activeClickedGeo: true
and follow onClickedGeo
signal. Look into how it is implemented in Pure Maps: https://github.com/rinigus/pure-maps/blob/master/qml/MapGestureArea.qml . Notice that all geo clicks are checked by running all POIs in for loop to find the closest POI and check whether click was close enough.
See method coordinatesMatch
in that area implementation on how to link geo coordinates to distance on screen.
To get to show images in the layers, you would have to use bit more complicated layers. See https://github.com/rinigus/pure-maps/blob/master/qml/Map.qml#L359 for layer properties, how it is added https://github.com/rinigus/pure-maps/blob/master/qml/Map.qml#L457 and how corresponding image was added https://github.com/rinigus/pure-maps/blob/master/qml/Map.qml#L449
But I would suggest to start from the top and use circle first and proceed accordingly.
Thanks, got it to work, both the image and the clicking.
Its a bit unfortunate that appearently the image/symbol cannot reference icons coming from the resource file; it won't work when addressing e.g. "qrc:///graphics/something.png"
, but it will when taking e.g. "/usr/share/icons/.../something.png"
.
It does work, however it will force me to adjust the app to install icons in the filesystem accordingly. Would there be another solution maybe?
Oh and also do you happen to know if Mapbox GL QML
can be run in the SailfishOS emulator?
No idea regarding Mapbox GL QML in SFOS emulator - not sure whether its GLES drivers are OK for it.
Re qrc - Corresponding section dealing with image loading: https://github.com/rinigus/mapbox-gl-qml/blob/master/src/qquickitemmapboxgl.cpp#L761 . If you can figure out why it doesn't load your image, patches are welcome
Got it. While in QML it should be "qrc:///graphics/foo.png"
in C++ (and therefore the addImagePath
as well) it must be ":/graphics/foo.png"
.
Excellent!
Closing then here
I am trying to add a PNG image to the map at a given location. The API description is pretty unclear to me regarding images. While I was able to paint a circle as given by the examples, calling
map.addImagePath("position-icon", Qt.resolvedUrl("qrc:///graphics/myimage.png"))
returnsfalse
. According to the docs it should returntrue
when the image was successfully added.I can add a qml image like so:
And it will display just fine, so, the image exists, and can be accessed via
qrc:///graphics/myimage.png
. Why does the function returnfalse
?Also, I fail to understand how I could assign a location to the added image. Do I need to add a source? How do I tie source and image?
Sidequestion: I guess
MapboxMap
does not just plain supportMapQuickItem
so any QML item could be added to the map?