2

Having around 2000 rows with multiline string coordinates I am implementing code to see where they intersect.

0       MULTILINESTRING ((-2.50909 53.07879, -2.50867 ...
1       MULTILINESTRING ((-2.49312 53.06901, -2.49269 ...

code:

from shapely.geometry import *
import geopandas as gpd
import pandas as pd
import matplotlib.pyplot as plt

sample = gpd.read_file('cleaned_links_v2.geojson')
df = sample['geometry']
line_gdf = sample.iloc[0:2000]
ma = line_gdf.geometry.apply(lambda g: line_gdf.intersects(g)) 

ma 

That code gives me a matrix where I have True or False weather 2 lines are intersecting with each other.

    0   1   2   3   4   5   6   7   8   9   ...     1990    1991    1992    1993    1994    1995    1996    1997    1998    1999
0   True    False   False   False   True    False   True    False   False   False   ...     False   False   False   False   False   False   False   False   False   False
1   False   True    False   False   False   False   False   False   False   False   ...     False   False   False   False   False   False   False   False   False   False
2   False   False   True    True    False   True    False   True    False   False   ...     False   False   False   False   False   False   False   False   False   False
3   False   False   True    True    False   False   False   False   False   False   ...     False   False   False   False   False   False   False   False   False   False
4   True    False   False   False   True    False   True    False   False   False   ...     False   False   False   False   False   False   False   False   False   False
...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...     ...
1995    False   False   False   False   False   False   False   False   False   False   ...     False   False   False   False   True    True    False   False   False   False
1996    False   False   False   False   False   False   False   False   False   False   ...     False   False   False   False   False   False   True    False   False   True
1997    False   False   False   False   False   False   False   False   False   False   ...     False   False   False   False   False   False   False   True    True    False
1998    False   False   False   False   False   False   False   False   False   False   ...     False   False   False   False   False   False   False   True    True    True
1999    False   False   False   False   False   False   False   False   False   False   ...     False   False   False   False   False   False   True    False   True    True

I would like table where per Node (intersection) I got list of all edges that are intesecting here. Count of them would also be good.

something in any form of following: Node ID 1 | Edge 1 | Edge 2 | Edge 7 | count = 3

I got now

import shapely

L1 = MultiLineString(df[2])
L2 = MultiLineString(df[2])
print(L1.intersection(L2))

So I can get coordinates of intersection

0

1 Answer 1

0
###
# A Node class to contain information about a single graph Node (an intersection).
# Each Node will connect to other nodes through edges
###
class Node:

    # Class constructor - called when the class is instantiated
    # Holds the data for the specific node being created
    def __init__(self, node_id, long, lat):
        self.id = node_id
        self.edges = []
        self.edge_map = {}
        self.lat = lat
        self.long = long

    # Python function to check if two nodes are equal
    def __eq__(self, other):
        # Our two objects can only be equal if they are both Nodes
        if isinstance(other, Node):
            # If they are both Nodes, they are equal if they cover the same Lat/Long coords
            return self.lat == other.lat and self.long == other.long

        # If they are not both Nodes, or their Lat/Longs are different, they aren't equal
        return False

    # Prints the Object as a custom string
    def __repr__(self):
        return "Node({} - ({}, {}))".format(self.id, self.long, self.lat)

    # Add an edge to the node that connects this node to another
    def add_edge(self, edge):
        self.edges.append(edge)
        self.edge_map[edge.id] = edge

    # Get all edges for this node
    def get_edges(self):
        return self.edges

    # Get a specific edge based on the edge_id
    def get_edge(self, edge_id):
        return self.edge_map[edge_id]

class Edge:

    def __init__(self, edge_id, nodes, speed):
        self.nodes = nodes
        self.id = edge_id
        self.speed = 30

    # Get the node on the other side of the edge from a given node
    def get_linked_node(self, node):
        # If the given node is one side of the edge, return the other side
        if self.nodes[0] == node:
            return self.nodes[1]
        elif self.nodes[1] == node:
            return self.nodes[0]
        # If the node isn't in the edge, return None as there are no links
        else:
            return None

And

# Graph object which will contain a node & edge representation of our entire network
class Graph:

    # Set up the object with our basic data structures
    def __init__(self):        
        self.nodes = [] # List of all node objects created
        self.edges = [] # List of all edge objects created

        self.node_counter = 0 # Counter for number of nodes created - used for node ID
        self.edge_counter = 0 # Counter for number of edges created - used for edge ID

    # Helper function to store a node if it's new, and return the tracked node object
    def process_node(self, node):
        # Check if this lat/long pair has already been processed
        n = Node(self.node_counter, node[0], node[1])
        if n not in self.nodes:
            # If it hasn't been processed, we need to create a new Node object for it
            self.nodes.append(n) # Add the new node object to the list
            self.node_counter += 1 # Increment our ID counter
            return n
        else:
            # If we have already processed the node - get the already created node
            # object so we can process it 
            return next(x for x in self.nodes if x == n)

    def load_network(self, network):
        # For each edge in our network
        for e in network.iterrows():

            # Get the edge details. It is the second item in the 'e' tuple
            edge = e[1]

            # Get the Geometry information for the edge
            geo = edge['geometry']

            # Get the first point in the geometry. This is an intersection, which we want to track as a node
            start = self.process_node(geo[0].coords[0]) # Start point
            end = self.process_node(geo[0].coords[-1]) # End point

            # Create the edge with the two nodes
            e = Edge(self.edge_counter, (start, end), e[1]['maxspeed'])

            # Add the new edge to our list of edges
            self.edges.append(e)

            # Add our edge to our two nodes
            start.add_edge(e)
            end.add_edge(e)

and

# Load the geojson road data
road_network = gpd.read_file('DATA.geojson')

# Create a graph and load the road data into the Graph
graph = Graph()
graph.load_network(road_network)

and

# Example usage of Graph
print("Total number of nodes: {}".format(len(graph.nodes)))
print("Total number of edges: {}".format(len(graph.edges)))
print("")
# Getting details of a single node
n1 = graph.nodes[0]
print("Looking at node {}".format(n1))
print("Node has {} edges".format(len(n1.get_edges())))
for e in n1.get_edges():
    print("Connects to {}".format(e.get_linked_node(n1)))

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.