User:Baiuvarius/Topo 50/Orientierung von Punkten auf Wegen

From OpenStreetMap Wiki
Jump to navigation Jump to search

Ermittlung der Orientierung von punktförmigen Objekten anhand der anliegenden Wegstücke mit Python in Maperitive

Grundlagen


Vorbereitung und Winkelberechnung allgemein

from maperipy import *
from maperipy.osm import *
import math

def angle(A,B):
	angle= (360+math.degrees(math.atan2((B.location.x-A.location.x)*math.cos(math.radians((A.location.y+B.location.y)/2)), B.location.y - A.location.y)))%360
	return angle

def set_dir2(node,angle2):
	if not node.has_tag("dir2"):
		node.set_tag("dir2",str(round(angle2)))
		if not node.has_tag("dir1"):
			node.set_tag("rail_direction",str(round(angle2)))
		else:
			angle1=float(node.get_tag("dir1"))
			angle=(angle1+angle2)/2
			if abs(angle2-angle1)>180:
				angle=(angle+180)%360
			node.set_tag("rail_direction",str(round(angle)))
	else:
		node.set_tag("has_direction","False")

def set_dir1(node,angle1):
	if not node.has_tag("dir1"):
		node.set_tag("dir1",str(round(angle1)))
		if not node.has_tag("dir2"):
			node.set_tag("rail_direction",str(round(angle1)))
		else:
			angle2=float(node.get_tag("dir2"))
			angle=(angle1+angle2)/2
			if abs(angle2-angle1)>180:
				angle=(angle+180)%360
			node.set_tag("rail_direction",str(round(angle)))
	else:
		node.set_tag("has_direction","False")

osm = None
osm_layer= None
layer_index=0
for layer in Map.layers:
	layer_index += 1
	if layer.layer_type == "OsmLayer":
		osm = layer.osm
		break
if osm == None:
	raise AssertionError("There are no OSM map souces.")

Tunnelportale und Brücken

Tunnel

for way in osm.find_ways(lambda x : x.has_tag("tunnel") and not (x.has_tag("tunnel", "no") or x.has_tag("tunnel", "building_passage"))):
	if way.has_tag("layer"):
		layer=way.get_tag("layer")
	else:
		layer="0"
	if way.has_tag("highway"):
		k="highway"
		v=way.get_tag("highway")
		if v=="track":
			if way.has_tag("tracktype","grade1"):
				v="track1"
		elif v=="trunk":
			if (not way.has_tag("oneway","yes") or way.has_tag("junction","roundabout")):
				v="primary"
	elif way.has_tag("railway"):
		k="railway"
		v=way.get_tag("railway")
		if v=="rail" or v=="light_rail":
			if way.has_tag("usage","service") or way.has_tag("usage","tourism"):
				v="railservice"
	elif way.has_tag("waterway"):
		k="waterway"
		v=way.get_tag("waterway")
	n=osm.node(way.nodes[0])
	if not n.has_tag("tunnel_start"):
		n.set_tag("tunnel_start","yes")
		n.set_tag("tunnel_direction",str(round(angle(osm.node(way.nodes[0]),osm.node(way.nodes[1])))))
		n.set_tag("tunnel_key",k)
		n.set_tag("tunnel_value",v)
		n.set_tag("tunnel_layer",layer)
	else:
		n.set_tag("tunnel_start","no")		

	n=osm.node(way.nodes[way.nodes_count-1])
	if not n.has_tag("tunnel_end"):
		n.set_tag("tunnel_end","yes")
		n.set_tag("tunnel_direction",str(round(angle(osm.node(way.nodes[way.nodes_count-2]),osm.node(way.nodes[way.nodes_count-1])))))
		n.set_tag("tunnel_key",k)
		n.set_tag("tunnel_value",v)
		n.set_tag("tunnel_layer",layer)
	else:
		n.set_tag("tunnel_end","no")

Brücken

for way in osm.find_ways(lambda x : x.has_tag("bridge") and not x.has_tag("bridge", "no")):
	if way.has_tag("layer"):
		layer=way.get_tag("layer")
	else:
		layer="0"
	if way.has_tag("highway"):
		k="highway"
		v=way.get_tag("highway")
		if v=="track":
			if way.has_tag("tracktype","grade1"):
				v="track1"
		elif v=="trunk":
			if (not way.has_tag("oneway","yes") or way.has_tag("junction","roundabout")):
				v="primary"
	elif way.has_tag("railway"):
		k="railway"
		v=way.get_tag("railway")
		if v=="rail" or v=="light_rail":
			if way.has_tag("usage","service") or way.has_tag("usage","tourism"):
				v="railservice"
	elif way.has_tag("waterway"):
		k="waterway"
		v=way.get_tag("waterway")
	n=osm.node(way.nodes[0])
	if not n.has_tag("bridge_start"):
		n.set_tag("bridge_start","yes")
		n.set_tag("bridge_direction",str(round(angle(osm.node(way.nodes[0]),osm.node(way.nodes[1])))))
		n.set_tag("bridge_key",k)
		n.set_tag("bridge_value",v)
		n.set_tag("bridge_layer",layer)
	else:
		n.set_tag("bridge_start","no")		

	n=osm.node(way.nodes[way.nodes_count-1])
	if not n.has_tag("bridge_end"):
		n.set_tag("bridge_end","yes")
		n.set_tag("bridge_direction",str(round(angle(osm.node(way.nodes[way.nodes_count-2]),osm.node(way.nodes[way.nodes_count-1])))))
		n.set_tag("bridge_key",k)
		n.set_tag("bridge_value",v)
		n.set_tag("bridge_layer",layer)
	else:
		n.set_tag("bridge_end","no")

Bahnhöfe

for way in osm.find_ways(lambda x : x.has_tag("railway","rail") or x.has_tag("railway","light_rail") or x.has_tag("railway","narrow_gauge") or x.has_tag("railway","funicular") or x.has_tag("railway","monorail")):
	for i in range(0,way.nodes_count-1):
		n=osm.node(way.nodes[i])
		if n.has_tag("railway","station") or n.has_tag("railway","halt") or n.has_tag("railway","stop") or n.has_tag("public_transport","stop_position"):
			a=angle(n,osm.node(way.nodes[i+1]))
			set_dir2(n,a)
	for i in range(1,way.nodes_count):
		n=osm.node(way.nodes[i])
		if n.has_tag("railway","station") or n.has_tag("railway","halt") or n.has_tag("railway","stop") or n.has_tag("public_transport","stop_position"):
			a=angle(osm.node(way.nodes[i-1]),n)
			set_dir1(n,a)

for station in osm.find_nodes(lambda x: x.has_tag("railway","station") or x.has_tag("railway","halt")):
	if station.has_tag("rail_direction"):
		dir=station.get_tag("rail_direction")
		station.set_tag("station_direction",dir)
		continue
	minref=2147483647
	railwaystops=[]
	for node in osm.find_nodes(lambda x: x.has_tag("rail_direction")):
		if node.has_tag("name") and station.has_tag("name"):
			if node.get_tag("name")==station.get_tag("name"):
				railwaystops.append(node)
	if len(railwaystops)>0:
		dir=railwaystops[0].get_tag("rail_direction")
		for element in railwaystops:
			if element.has_tag("ref"):
				ref=element.get_tag("ref")
				if ref<minref:
					minref=ref
					dir=element.get_tag("rail_direction")
		station.set_tag("station_direction",dir)

Gewässer

ef condition(node):
	if node.has_tag("waterway","waterfall") or node.has_tag("waterway","dam") or node.has_tag("waterway","weir") or node.has_tag("waterway","lock_gate"):
		return True
	else:
		return False
	return True
[...]
for way in osm.find_ways(lambda x : x.has_tag("waterway","river") or x.has_tag("waterway","stream") or x.has_tag("waterway","canal") or x.has_tag("waterway","drain") or x.has_tag("waterway","ditch")):
	for i in range(0,way.nodes_count-1):
		n=osm.node(way.nodes[i])
		if condition(n):
			a=angle(n,osm.node(way.nodes[i+1]))
			set_dir2(n,a)
	for i in range(1,way.nodes_count):
		n=osm.node(way.nodes[i])
		if condition(n):
			a=angle(osm.node(way.nodes[i-1]),n)
			set_dir1(n,a)