cityjson / cjio

CityJSON/io: Python CLI to process and manipulate CityJSON files
MIT License
126 stars 32 forks source link

get_subset_ids() : get all children #165

Open esgn opened 1 year ago

esgn commented 1 year ago

Is your feature request related to a problem? Please describe.

I'm trying to clip a CityJSON file to keep only buildings situated inside a polygon. I wrote a python script using cjio to test if building/buildingparts ground surfaces are contained in the polygon. The result is a list of Building IDs I'm using with cityjson.get_subset_ids() to try and filter the original cityjson file. Doing so, I stumbled on a case where the depth of children harvesting in select_co_ids() does not seem to be sufficient.

In this example, if i try to get_subset_ids(['Node_1647']), I never get Node_41582 and a chimney is lost in the process ;)

CityObjects": {
        "Node_1647": {
            "type": "Building",
            "attributes": {
                "class": "Building",
            },
            "children": [
                "Node_1655"
            ]
        ...
        },
        ...
        "Node_1655": {
            "type": "BuildingPart",
            "attributes": {
                "measuredHeight": 6.731028337652901,
            },
            "parents": [
                "Node_1647"
            ],
            "children": [
                "Node_41582"
            ],
            ...
           },
           ...
        "Node_41582": {
            "type": "BuildingInstallation",
            "attributes": {
                "class": "BuildingSuperStructure",
                "function": "chimney"
            },
            "parents": [
                "Node_1655"
            ]
        },

I presume the depth of search is not sufficient in select_co_ids(j,IDs)

#-- also add the children
    for id in j["CityObjects"]:
        if id in IDs:
            if "children" in j['CityObjects'][id]:
                for child in j['CityObjects'][id]['children']:
                    re.add(child)
            if "parents" in j['CityObjects'][id]:
                for p in j['CityObjects'][id]['parents']:
                    re.add(p) 
                    #-- add siblings
                    if "children" in j['CityObjects'][p]:
                        for child in j['CityObjects'][p]['children']:
                            re.add(child)

Describe the solution you'd like

As an user, I expect to get all children of a building node at any depth.

Describe alternatives you've considered

For the moment, the solutions seems to keep all intermediate children IDs and also pass them to get_subset_ids(). edit : Tested it this morning and it does work fine.

Additional context

I would also be interested in a clipping function in cjio :)

Thanks in advance

hugoledoux commented 1 year ago

I assume you're using master branch, right?

I fixed that a while ago (https://github.com/cityjson/cjio/commit/2fb9f90227903f585566de41bb75adf4d8be991d) but it's in branch 'develop' only at the moment since I didn't test it properly. Perhaps you could test it and report here? That would be super useful.

How to use the develop branch is explained there: https://github.com/cityjson/cjio#installation

esgn commented 1 year ago

I'm using cjio installed via pip so I'm in version v0.8.1 and I didn't use the develop version yet. I wrote a workaround but I'll try to use the develop branch If I find the time. Is the develop branch related to the cjlib announced in the comments ? Thanks for your answer

hugoledoux commented 1 year ago

No it's not, it's just where we fix things.

@balazsdukai is working very very part-time on cjlib, so not sure when it'll be ready....

balazsdukai commented 1 year ago

Indeed, very very part-time is a good way to put it :-). I hope that I'll get some time over the summer for cjlib.