QT QML - Changing Mapbox font size - qt

I'm using QT 5.12.4 with the MapboxGl plugin and I'm trying to figure out how to make the street names display in a larger font but I'm very confused about how to specify a text size. I need to change the size dynamically so using a predefined style is not going to meet the requirements.
The two confusing aspects are that Mapbox's documentation has to be translated into "MapParameters" for QML and I'm clueless as to what exactly is needed to change the text size. Between reading through the documentation and playing with the mapbox studio it seems like I need to modify the "road-label" layer. If anyone has some sample code of how to change the text size I would really appreciate it if you could share.
https://docs.mapbox.com/mapbox-gl-js/style-spec/#layout-symbol-text-size
MapParameter
{
type: "layout"
property var layer: "road-label"
property var textSize: 20
}

What you did looks correct. You need to define a MapParameter with the type layout because the text-size is a layout property in the Mapbox Style Specification. We cannot use - on QML variable names, so we camelCase it to textSize. After that you can bind textSize to anything you want.
You need to make sure that the layer road-label exists on the style at the moment the MapParameter is added.

I solved the problem and the key was getting the JSON for the predefined style that I was using (navigation-preview-day-v2). This post showed me how to get the pre-defined sytle:
URL for Mapbox style sheet JSON
For the navigation-preview-day-v2 style, the URL would be:
https://api.mapbox.com/styles/v1/mapbox/navigation-preview-day-v2?access_token=(your token here)
Run the JSON through a formatter so you can read it and find the layer(s) where the street names are rendered. In this case, there are four layers:
road-label-small
road-label-medium
road-label-large
road-label-extra-large
Here is an example of how to form the MapParameter in QML for the font size:
MapParameter
{
type: "layout"
property var layer: "road-label-large"
property var textSize:
{
"base": 1,
"stops":
[
[9, 10],
[20, 16]
]
}
}
You can also import the JSON into Mapbox Studio to review or manipulate the style. In my case I wanted to dynamically scale the font size so in my QML I added a scale factor and the resulting MapParameter is:
MapParameter
{
type: "layout"
property var layer: "road-label-large"
property var textSize:
{
"base": 1,
"stops":
[
[9, Math.floor(10 * fontScaleFactor)],
[20, Math.floor(16 * fontScaleFactor)]
]
}
}

Related

iOS Dynamic Type sizes — possible to change default sizes / have pt sizes in between styles?

See here for Apple's Dynamic Type sizes.
I want to use dynamic font sizing, to make text in my app scale according to accessibility settings. However, the default pt sizes don't cover what I require.
Eg.:
Title 1 — 28pt
Title 2 — 22pt
I want to be able to use a 24pt font, with dynamic sizing. With the Large (default) setting, this is not possible... but if the user has the xLarge setting, Title 2 actually scales to 24pt...
As I am targeting iOS 15, I am using these modifiers on my Text so I can use a rounded font with dynamic sizing:
.font(.system(.title2, design: .rounded))
.fontWeight(.regular)
I've searched and searched, but none of the suggested answers work for me. I like the idea of being able to scale the existing dynamic type sizes by a multiplier but if I use .scaleEffect(value) it created pixellation when scaling up, and messes with padding even when scaling down.
You can create a font with a custom point size that scales with other dynamic fonts using:
Font.custom(_:size:relativeTo:)
e.g.
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Title").font(.title).border(.green)
Text("Title").font(.title1½).border(.blue)
Text("Title").font(.title2).border(.red)
}
}
}
extension Font {
static let title1½ = Font.custom("", size: 24, relativeTo: .title2)
}
(leaving the name blank seems to return the system font)
You can adapt this to use rounded fonts in iOS 15. First you'll need to find the name of the font itself, using UIKit:
let font = UIFont.systemFont(ofSize: 24, weight: .regular)
let fontDescriptor = font.fontDescriptor.withDesign(.rounded)!
let roundedFont = UIFont(descriptor: fontDescriptor, size: 24)
print(roundedFont.fontName)
// .AppleSystemUIFontRounded-Regular
You can use this in your custom Font method:
extension Font {
static let title1Rounded = Font.custom(".AppleSystemUIFontRounded-Regular", size: 28, relativeTo: .title)
static let title1½Rounded = Font.custom(".AppleSystemUIFontRounded-Regular", size: 24, relativeTo: .title2)
static let title2Rounded = Font.custom(".AppleSystemUIFontRounded-Regular", size: 22, relativeTo: .title2)
}

Custom properties don't exist at compile time? "Cannot assign to non-existent property"

In referencing an item's properties from outside its parent component, I can get a "Cannot assign to non-existent property" error that seems to depend on some compile time order-of-operations.
I have created a small example app that shows some various ways to assign a color to this property, where direct assignment fails, but similar assignment to default properties works, or even later assignment works.
Here is my main.qml:
import QtQuick 2.7
import QtQuick.Window 2.12
Window {
id: application_window
visible: true
width: 640
height: 480
Thing {
// colors.backgroundColor: "red" // Direct assignment of custom property: Fails
// thing.color: "red" // Direct assignment of default property: Works
// Component.onCompleted: colors.backgroundColor = "red" // Run time assignment of custom property: Works
}
}
and a file called Thing.qml in the same dir:
Item {
id: root
height: 50
width: 50
property alias colors: colors
property alias thing: thing
Rectangle {
id: thing
anchors.fill: root
color: colors.backgroundColor
}
Item {
id: colors
property color backgroundColor: "blue"
}
}
By individually uncommenting the lines in main.qml, you can see that directly assigning colors.backgroundColor does not work, but the other ways of changing the color do work, even assigning colors.backgroundColor at runtime. I have also moved the 'colors' Item to a different file, which allows direct assignment (I guess the backgroundColor becomes considered like a default property in this case). Is there any way to directly assign the colors.background color without a separate file or waiting until runtime?
Is there any way to directly assign the colors.background color without a separate file or waiting until runtime?
No.
When you are declaratively setting (using it in the left hand side of a binding) a sub property (property of a grouped property) like foo.bar, the QML engine can only do so if the type of foo has a bar property.
In your example when doing thing.color, thing's type is Rectangle so it does have a color property.
When doing colors.backgroundColor, I guess the type of colors is Item and not the implicit type defined in Thing.qml.
When you are creating a 'colors' Item in a different file, the QML engine is aware of the explicit type of the object and the binding then works.
One could argue that the engine could use the implicit type for the alias property, but I'm not sure if it's the correct way, you are essentially exposing an inline implementation detail to the outside.
You could alway open a bug about that, at least to clarify things even if the behaviour is not changed.

QML load and display .ply mesh with color attributes

I am trying to load a simple cube with per-vertex color information from a Stanford PLY file using QML.
My entity looks like this:
Entity
{
id: circle
property Material materialPoint: Material {
effect: Effect {
techniques: Technique {
renderPasses: RenderPass {
shaderProgram: ShaderProgram {
vertexShaderCode: loadSource("qrc:/imports/org/aid/shared/geometry/shaders/point.vert")
fragmentShaderCode: loadSource("qrc:/imports/org/aid/shared/geometry/shaders/point.frag")
}
}
}
}
parameters: Parameter { name: "pointSize"; value: 2 }
}
property alias translation: circleTransform.translation
property alias rotation : circleTransform.rotationZ
Mesh
{
id: circleMesh
source: "qrc:/resources/models/rg.ply"
}
Transform
{
id: circleTransform
scale : 1
}
components:
[materialPoint, circleTransform, circleMesh]
}
I have also tried replacing the material property with the default Qt material purposely created to solve this problem:
property Material materialPoint: PerVertexColorMaterial {}.
Unfortunately, there are no per-vertex colors visible in the scene.
Is there any recommended way of importing a PLY file with vertex color data in QML? (I suppose it is possible to achieve this if one writes the logic in C++ and creates a specialized QML entity for doing so, but the functionality should be available already).
Loading PLY in Qt3D doesn't include color as you've noticed. Par for the course for Qt3D at the moment, I'm afraid.
You can either:
build and load the Qt Assimp Sceneparser plugin which does support color attributes in PLY, or:
Write your own Qt3D geometry loader in C++. I have done similar when needing to load a custom OBJ model with extra data in each vertex. The loader code is pretty straightforward to work with, you need only modify it to read the extra data, and you can either modify the code in Qt3D itself, or create a plugin and load it in your application for this to work.
Note: it is not necessary to create a specialized QML entity. The loader will read your file in as QMesh.

openlayers-3 change external wms layer styles

Is it possible change the style of a external wms layer??
im trying to use this layer:
https://firms.modaps.eosdis.nasa.gov/wms/?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&LAYERS=fires24&width=400&height=250&BBOX=-26,34,35,82
with this code on openlayers3
var fill = new ol.style.Fill({color: 'GREEN'});
var stroke = new ol.style.Stroke({color: 'GREEN'});
var styles = [new ol.style.Style({
image: new ol.style.Circle({
fill: fill,
stroke: stroke,
radius: 5
})
})];
var fires = new ol.layer.Image({
name: 'fires',
source: new ol.source.ImageWMS({
url: 'https://firms.modaps.eosdis.nasa.gov/wms/',
params: {
'LAYERS': 'fires24',
'VERSION': '1.1.1'
}
}),
style: styles
});
the layer is displayed correctly but without my own styles.
Is it possible to do that or replace with a custom icon?
The WMS link you use is returning a PNG file, which I believe OpenLayers cannot style 'after the fact'. Once you've got it it's immutable - it's not 'data' but an image with transparency that is overlaid on top of your underlying map source.
There are some params you can pass into a wms call (as you've done) and the standard looks like it can support you passing styles into the call to the WMS server to get it to use those when rendering the image.
I've got a list of possible parameters from the geoserver website (a GIS server) - http://docs.geoserver.org/stable/en/user/services/wms/reference.html
Looking at that link it looks like sld or sld_body parameters may work. SLD is like OL styles but in XML. Details of these stylesheets are here - http://docs.geoserver.org/stable/en/user/styling/index.html#styling
I've had a go at this jsfiddle : https://jsfiddle.net/y7fj57dj/ but it's not working as such - it could either be my SLD (I'm not up to speed with it) or the NASA server doesn't know what to do with it/is ignoring it.
You may need to contact NASA server admins to confirm if you can style the WMS calls (support#earthdata.nasa.gov, retrieved by going to https://firms.modaps.eosdis.nasa.gov/wms/?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetCapabilities).

Openlayers Feature.Vector only uses default style

I'm changing from markers to vector layer and I can't make my site to use any sort of non-default icon, whatever I put in externalGraphic style attribute doesnt have effect on map. I just see orange circles. To be exact, no matter what I put in Openlayers.Style to style my point features, I get default look of icons.
It should be easy, but I try for days and can't make it work, so I came here for help. When warstwa_ikon was markers layer everything was fine, but I need extra functionality.
Thats my styling code:
var StylIkony = new OpenLayers.Style({
externalGraphic : '${symbol}',
graphicWidth : 15,
graphicHeight : 15,
cursor : 'pointer'
});
var StylWarstwyIkon = new OpenLayers.StyleMap ({
default: StylIkony,
delete: StylIkony,
select: StylIkony,
temporary: StylIkony
});
warstwa_ikon = new OpenLayers.Layer.Vector("Ikony Lokali",{ eventListeners: { "featureselected": WywolajRamke }});
warstwa_ikon.StyleMap = StylWarstwyIkon;
map.addLayer(warstwa_ikon);
Thats already executed code from generating Features:
WspolrzedneIkony = new OpenLayers.Geometry.Point(2279231, 7127620);
Ikona = new OpenLayers.Feature.Vector(WspolrzedneIkony,
{ "symbol": "../GRAFIKI/IkonyLokali/10.png", "idLokalu": 1 });
warstwa_ikon.addFeatures([Ikona]);
WspolrzedneIkony = new OpenLayers.Geometry.Point(2279245, 7127630);
Ikona = newOpenLayers.Feature.Vector(WspolrzedneIkony,
{ "symbol": "../GRAFIKI/IkonyLokali/6.png", "idLokalu": 2 });
warstwa_ikon.addFeatures([Ikona]);
Thats DOM of my vector layers (warstwa_ikon) StyleMap:
http://s24.postimg.org/hwfjakg0l/stylemap.png
Thats DOM of my vector layer first Feature, which should be styled:
http://s9.postimg.org/oxlocyku7/feature.png
Sorry, I can't include normal images yet. I should add that this is not a problem with accessing icon image file, I can't get layer to use any sort of images, even from internet links.
Declares StyleMap on layer creation as:
warstwa_ikon = new OpenLayers.Layer.Vector("Ikony Lokali", {
styleMap: StylWarstwyIkon,
eventListeners: ...
});
and removes:
warstwa_ikon.StyleMap = StylWarstwyIkon;

Resources