2

There is distance matrix with 9.455 features without geometries in GeoJSON format. It was created outside of QGIS with a tool similar to QGIS's "Distance matrix".

The matrix looks like this:

input

Now I am trying to connect these features with points from/to that have geometries and stored in other layers.

I am doing it with "Geometry by expression", where I take my matrix as an 'Input layer'

window

and I am using this expression to create a line:

make_line(
    geometry(
        get_feature(
            'layer_from',
            'fid',
            "FROM_ID"
            )
        ), 
    geometry(
        get_feature(
            'layer_to',
            'fid',
            "TO_ID"
            )
        )
    )

When I press Run I receive an empty output. Why?

I wrapped the above expression into is_empty_or_null(...) and I got false -> means that geometries are not NULL, they exist somewhere.

When I read the documentation it says that input layer is a vector layer:

INPUT: Input layer

Parameter type: QgsProcessingParameterFeatureSource

Accepted data types:
    - str: layer ID
    - str: layer name
    - str: layer source
    - QgsProcessingFeatureSourceDefinition
    - QgsProperty
    - QgsVectorLayer

This is logical. Moreover, when I checked the 'Matrix' layer with some PyQGIS:

layer = QgsProject.instance().mapLayersByName('Matrix')[0]

print(layer.type()) # QgsMapLayerType.VectorLayer
print(layer.LayerType) # <enum 'QgsMapLayerType'>
print(layer.PropertyType) # <class 'qgis._core.QgsMapLayer.PropertyType'>
print(layer.geometryType()) # 4
print(layer.providerType()) # ogr
print(layer.storageType()) # GeoJSON

it looks also promising to me, looks like a Vector, is not it?

Are there any workarounds available? Maybe it is not possible at all. And simply saying "Geometry by expression" in QGIS does not except layer without geometry as an input.

The one that I found is to refer to layer with destination-points via 'Matrix' layer, taking origin-points as an 'Input' in the "Geometry by expression".

Perhaps it is again the same story, that:

QGIS does not support GeometryCollection as a valid geometry type.

which is inside of my GeoJSON:

geojson

BTW, this is a piece of GeoJSON that I am working on:

{
"type": "FeatureCollection",
"name": "Matrix",
"features": [
{ "type": "Feature", "properties": { "FROM_ID": 1, "TO_ID": 1, "DURATION_H": 0.92035555555555559, "DIST_KM": 4.60184 }, "geometry": null },
{ "type": "Feature", "properties": { "FROM_ID": 1, "TO_ID": 2, "DURATION_H": 1.1758277777777777, "DIST_KM": 5.87926 }, "geometry": null },
{ "type": "Feature", "properties": { "FROM_ID": 1, "TO_ID": 3, "DURATION_H": 1.5567583333333332, "DIST_KM": 7.7839 }, "geometry": null },
{ "type": "Feature", "properties": { "FROM_ID": 1, "TO_ID": 4, "DURATION_H": 1.5678055555555557, "DIST_KM": 7.83914 }, "geometry": null },
{ "type": "Feature", "properties": { "FROM_ID": 1, "TO_ID": 5, "DURATION_H": 0.44944166666666668, "DIST_KM": 2.24724 }, "geometry": null },
{ "type": "Feature", "properties": { "FROM_ID": 1, "TO_ID": 6, "DURATION_H": 0.41768055555555555, "DIST_KM": 2.08844 }, "geometry": null },
{ "type": "Feature", "properties": { "FROM_ID": 1, "TO_ID": 7, "DURATION_H": 1.156236111111111, "DIST_KM": 5.78126 }, "geometry": null },
{ "type": "Feature", "properties": { "FROM_ID": 1, "TO_ID": 8, "DURATION_H": 1.2599444444444445, "DIST_KM": 6.2998 }, "geometry": null },
{ "type": "Feature", "properties": { "FROM_ID": 1, "TO_ID": 9, "DURATION_H": 1.1397833333333334, "DIST_KM": 5.69899 }, "geometry": null },
{ "type": "Feature", "properties": { "FROM_ID": 1, "TO_ID": 10, "DURATION_H": 0.60408888888888879, "DIST_KM": 3.02048 }, "geometry": null }
]
}
8
  • 2
    And no Virtual Layers this time ? You can do it so easily with ! Dec 2, 2021 at 15:20
  • 1
    @J.Monticolo yes, I know how to. But imho it is not an efficient when the data is big.
    – Taras
    Dec 2, 2021 at 15:22
  • So virtual layer is slower than expressions? This question is still unanswered: gis.stackexchange.com/q/382520/88814
    – Babel
    Dec 2, 2021 at 15:27
  • @Babel, I think the expression Tag is redundant here. It is more about data input and geo algorithm itself
    – Taras
    Dec 2, 2021 at 15:31
  • 1
    You can create a Polyline layer without geometry, have the attributes of the JSON and directly update the field geometry with your expression. Dec 2, 2021 at 15:42

1 Answer 1

4

The problem

The problem with your expression is that you apply it on the Matrix layer, but this is a layer without geometry. Creating geometries works only on layers that contain geomtries. It does not even work on a geometry layer that does not contain any features (empty layer).

I think Geometry generator (and by extension Geometry by expression) is a way to style (visualize) geometries - however, when you do not have any geometries, you can't style anything. In your case, you have an "attribute only" layer. I don't know why this is considered to be a vector, maybe vector in the sense that it's not a raster layer. It's data structure (a layer with an attribute table) is closer to a vector then a raster layer.

How to solve it

So the expression must be based on one of the point layers that you want to connect. Here I used the layer_from.

Use this expression:

collect_geometries( 
    array_foreach (
        generate_series (0,  aggregate( 'matrix', 'count', $id)-1),
        make_line(
            geometry(
                get_feature(
                    'layer_from',
                    'fid',
                    attribute (
                        get_feature_by_id (
                            'matrix',
                            @element
                        ),
                    'FROM_ID'
                    )
                )
            ), 
            geometry(
                get_feature(
                    'layer_to',
                    'fid',
                    attribute (
                        get_feature_by_id (
                            'matrix',
                            @element
                        ),
                    'TO_ID'
                    )
                )
            )
        )
    )
)

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.