5

I have a GeoJSON point file for use in navigation. I need to create a line network connecting the points to their corresponding 'neighbors' in the data. I have looked for any sort of plug in or native algorithm but have not found anything that can perform the connection. Is there a way to do this? Here is a sample of the data.

 {
"type": "FeatureCollection",
"features": [
    {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [
                -122.51407721663476,
                37.92935472657569
            ]
        },
        "properties": {
            "id": "n_59d3a0656850d07d450000fc",
            "level": "59d39a1a6850d04750000000",
            "neighbors": [
                "n_59d3a1c66850d07d4500010c",
                "n_59d3a1cd6850d07d4500010d",
                "n_59d3a7f26850d07d4500015e"
            ],
            "weight": 1
        }
    },
    {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [
                -122.51377017089081,
                37.92918570092726
            ]
        },
        "properties": {
            "id": "n_59d3a1c66850d07d4500010c",
            "level": "59d39a1a6850d04750000000",
            "neighbors": [
                "n_59d3a0656850d07d450000fc",
                "n_59d3a2f66850d07d4500010f"
            ],
            "weight": 1
        }
    },
    {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [
                -122.51388322052854,
                37.92957582123205
            ]
        },
        "properties": {
            "id": "n_59d3a1cd6850d07d4500010d",
            "level": "59d39a1a6850d04750000000",
            "neighbors": [
                "n_59d3a0656850d07d450000fc"
            ],
            "weight": 1
        }
    },
    {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [
                -122.51414818592386,
                37.92934461122832
            ]
        },
        "properties": {
            "id": "n_59d3a7f26850d07d4500015e",
            "level": "59d39a1a6850d04750000000",
            "neighbors": [
                "n_59d3a0656850d07d450000fc",
                "n_59d3a0e46850d07d45000106",
                "n_59d3a7f66850d07d4500015f",
                "n_59f354f824ee960562000000"
            ],
            "weight": 1
        }
    }
]

}

3
  • 1
    according to your file those 2 points are not actually neighbors. Also I updated that geojson as I couldn't visualize it either. I believe the tool you would be looking for is hublines. though you would need to figure out a parent layer and a child layer and join a specific property from the parent layer to a property in child's layer. It would help to add more points to your example and to actually make sure they are neighbors to help further. and make the geojson file valid.
    – B-C B.
    Nov 15, 2019 at 17:22
  • 1
    I've updated the geojson to show them as neighbors. I tried hublines but it's very limited and I would have to break up the layer into hundreds of seperate layers in order to get it to work.
    – brink
    Nov 15, 2019 at 18:15
  • yeah this is awesome. so we can use this layer as the hub, and then create a layer which would have a bunch of overlapping points (1 point per element in neighbors list) and then we could use hub lines. we just need to find a way to multiply features by the number of neighbor in neighbors list and attribute them a single specific neighbor by iterating over that list of neighbors.
    – B-C B.
    Nov 15, 2019 at 19:57

1 Answer 1

1
+100

I believe I figured something out. So you will use hublines, using your initial geojson as hub layer using id as hub field and create a neighbor layer which will be used as spoke layer and use neighbor as spoke field. To create your neighbor layer you will parse through your geojson file and append features inside an empty geojson file. Parse through your original geojson file and dump the feature collection inside your new empty file:

#import necessary modules
from geojson import Point, Feature, FeatureCollection, dump
import json
#Create neighbor geojson file
open("neighbor.geojson", 'a').close()
#your original geojson file
json_file = r'original_file.geojson'
#create list to append into neighbor geojson
something = []
#Parse through Geojson file
with open(json_file, 'r') as f:
    blah_dict = json.load(f)
for features in blah_dict["features"]:
    #get necessary info to build geojson file
    id = features['properties']["id"]
    neighbor = features['properties']['neighbors']
    long = features['geometry']['coordinates'][0]
    lat = features['geometry']['coordinates'][1]
    point = Point((long,lat))
    for x in neighbor:
        something.append(Feature(geometry=point, properties={"id": id, "neighbor": x}))
feature_collection = FeatureCollection(something)
print (feature_collection)
with open('neighbor.geojson', 'w') as w:
    dump(feature_collection, w)

Now you can use hublines with these 2 files:

processing.run("native:hublines", {'HUBS':'original_file.geojson','HUB_FIELD':'id','HUB_FIELDS':[],'SPOKES':'neighbor.geojson','SPOKE_FIELD':'neighbor','SPOKE_FIELDS':[],'OUTPUT':'your_output_file.geojson'})

Your output should look like this:enter image description here

4
  • Thank you. This does seem to work however i've never used python coding so i'm having to kind hack my way through it in qgis. I may have some followup questions.
    – brink
    Nov 19, 2019 at 17:29
  • sounds good. I Believe these codes should work in the python console editor in qgis without having to install any new modules.
    – B-C B.
    Nov 19, 2019 at 18:27
  • This works perfectly, thank you. There is a single quote missing at the end of the processing code. It won't let me edit it but I thought I would make a note in case somebody else needs it. eg. 'your_output_file.geojson'
    – brink
    Nov 22, 2019 at 19:46
  • Good to hear. I edited the code for that quotation mark. thanks.
    – B-C B.
    Nov 22, 2019 at 19:53

Your Answer

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

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