Reputation: 25
I am working in python. My project's aim is to find a pattern on a network of streets. So for example, I define a "house" with edges and nodes like this
#Step 2: Define the house pattern
def create_house_graph():
"""Create a house-shaped graph."""
H = nx.Graph()
H.add_nodes_from([1, 2, 3, 4, 5]) # 5 nodes
H.add_edges_from([(1, 2), (2, 3), (3, 4), (4, 1), (1, 5), (3, 5)]) # Square with triangle top
return H
house_graph = create_house_graph()
My city graph is defined as
city = "Munich, Germany"
graph_file = "munich_bike_network.graphml"
try:
G = ox.load_graphml(graph_file)
except FileNotFoundError:
G = ox.graph_from_place(city, network_type="bike")
ox.save_graphml(G, graph_file)
How can I perfom a fitting or snapping of my house pattern on my city map. Since networkx is only doing exact matching this approach doesn't work.
This is my try:
# Step 3: Generate more rotated, scaled, and translated variants of the house shape
def generate_house_variants(rotations=5, scales=[0.8, 1, 1.2], translations=[-0.0005, 0, 0.0005]):
variants = []
base_shape = create_house_shape()
for scale in scales:
for rotation in np.linspace(0, 360, rotations, endpoint=False):
for dx in translations:
for dy in translations:
# Create a variant with transformations
variant = nx.Graph()
for node in base_shape.nodes:
# Transform node positions (set default x, y if not present)
x, y = node % 2, node // 2 # Example positions to get x, y coordinates
x, y = scale * (x + dx), scale * (y + dy)
theta = np.radians(rotation)
x_rot = x * np.cos(theta) - y * np.sin(theta) # Rotate
y_rot = x * np.sin(theta) + y * np.cos(theta)
variant.add_node(node, pos=(x_rot, y_rot))
variant.add_edges_from(base_shape.edges)
variants.append(variant)
return variants
# Step 4: Try to find approximate matches with tolerance
house_variants = generate_house_variants()
matches = []
tolerance = 0.0002 # Latitude/longitude tolerance, adjust based on real-world distances
def node_within_tolerance(n1, n2, tolerance):
pos1 = G.nodes[n1]['x'], G.nodes[n1]['y']
pos2 = n2 # n2 is a tuple (x_rot, y_rot)
return np.sqrt((pos1[0] - pos2[0])**2 + (pos1[1] - pos2[1])**2) < tolerance
for i, H_variant in enumerate(house_variants):
match_found = False
for g_node in G.nodes:
variant_nodes = list(H_variant.nodes(data="pos"))
match = []
for _, pos in variant_nodes:
nearby_nodes = [n for n in G.nodes if node_within_tolerance(n, pos, tolerance)]
if nearby_nodes:
match.extend(nearby_nodes)
else:
break
if len(match) == len(H_variant.nodes):
match_found = True
matches.append((H_variant, match))
break # Stop after finding the first match for this variant
Can anyone advise?
BR Konstantin
Upvotes: 0
Views: 16