Skip to content

LOD attributes all have string data types #68

@ymoisan

Description

@ymoisan

Here's a cityjson file excerpt

 "lod": "2.2",
          "semantics": {
            "surfaces": [
...
              {
                "rf_azimuth": 244.7989501953125,
                "rf_roof_elevation_50p": 165.9402618408203,
                "rf_roof_elevation_70p": 166.33753967285156,
                "rf_roof_elevation_max": 166.9029083251953,
                "rf_roof_elevation_min": 164.65676879882812,
                "rf_slope": 29.86277198791504,
                "type": "RoofSurface"
              },
...

The current implementation of the plugin will import all of those as strings even though all but one are not.

I tried this implementation

class SemanticSurfaceFieldsDecorator:
    """A class that creates an LoD field"""

    def __init__(self, decorated, citymodel):
        self._decorated = decorated
        self._citymodel = citymodel
        self._attribute_types = self._get_attribute_types()

    def _get_qgis_type(self, value):
        if isinstance(value, bool):
            return QVariant.Bool
        elif isinstance(value, int):
            return QVariant.Int
        elif isinstance(value, float):
            return QVariant.Double
        else:
            return QVariant.String

    def _get_attribute_types(self):
        attribute_types = {}
        for obj in self._citymodel["CityObjects"].values():
            if "geometry" in obj:
                for geom in obj["geometry"]:
                    if "semantics" in geom:
                        for surface in geom["semantics"]["surfaces"]:
                            for att_key, att_value in surface.items():
                                qtype = self._get_qgis_type(att_value)
                                if att_key not in attribute_types or (qtype == QVariant.Double and attribute_types[att_key] != QVariant.Double) or (qtype == QVariant.String and attribute_types[att_key] != QVariant.String):
                                    attribute_types[att_key] = qtype
                                elif qtype == QVariant.Int and attribute_types[att_key] == QVariant.Bool:
                                     attribute_types[att_key] = qtype

        return attribute_types

And it solved the issue. See below (after modification at top)

Image

I wonder if there would be a cleaner way to do it ?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions