################################################################################ ### Optimizes networks from imported OSM data (optional) ################################################################################ ### Description: ### - This script optimizes networks from imported OSM data. ### Please, see tu_osm_import.sh for further details. ### ### Preconditions: ### ### Postconditions: ### ### Author: ### - Thomas Uchdorf, thomas.uchdorf(at)fernuni-hagen.de ################################################################################ # Finding junctions between unidirectional streets # A a B # StartNode_a x------>x End_Node_a # | | # b | | d # | | # EndNode_b x<------x Start_Node_b # D c C # Parallelogram law # sum of the squares of the length of the sides = sum of the squares of the # length of the diagonals # a^2 + b^2 + c^2 + d^2 = diag1^2 +diag2^2 # <=> 2 a^2 + 2 b^2 - diag1^2 - diag2^2 = 0 # here we are looking for something close to a parallelogram, so we have # 2 a^2 + 2 b^2 - diag1^2 - diag2^2 < epsilon query (((ExtSectionsRel feed project [StreetId,StartNodeId,EndNodeId,Section] {a} NodesRel feed {n1} hashjoin [StartNodeId_a,NodeId_n1,99997]) NodesRel feed {n2} hashjoin [EndNodeId_a,NodeId_n2,99997]) extend [StartNode_a: .Node_n1, EndNode_a: .Node_n2] ExtStreetsRel feed filter [.OneWay = 1] project [GroupId,StreetId,GeoData,Name] {e1} hashjoin [StreetId_a,StreetId_e1,99997]) (((ExtSectionsRel feed project [StreetId,StartNodeId,EndNodeId,Section] {b} NodesRel feed {n3} hashjoin [StartNodeId_b,NodeId_n3,99997]) nodesRel feed {n4} hashjoin [EndNodeId_b,NodeId_n4,99997]) extend [StartNode_b: .Node_n3, EndNode_b: .Node_n4] ExtStreetsRel feed filter [.OneWay = 1] project [GroupId,StreetId,GeoData] {e2} hashjoin [StreetId_b,StreetId_e2,99997]) hashjoin [GroupId_e1,GroupId_e2,99997] filter [.StreetId_e1 < .StreetId_e2] projectextend [ StreetId_a,Name_e1,GroupId_e1, Section_a,Section_b,GeoData_e1,GeoData_e2; A: distance(.StartNode_a,.EndNode_a), B: distance(.StartNode_a,.EndNode_b), C: distance(.EndNode_b,.StartNode_b), D: distance(.EndNode_a,.StartNode_b), Diag1: distance(.StartNode_a,.StartNode_b), Diag2: distance(.EndNode_a,.EndNode_b)] sortby [GroupId_e1] filter [(abs(.A - .C) < (0.1 * getMaxVal(.A,.C))) and (abs(.B - .D) < (0.1 * getMaxVal(.B,.D))) and (abs(2 * ((.A * .A) + (.B * .B)) - (.Diag1 * .Diag1) - (.Diag2 * .Diag2)) < 0.0001)] consume; #query #extStreetsRel feed {a} #extend [StartNode_a: atposition(.geoData_a,0.0,TRUE), # EndNode_a: atposition(.geoData_a,1.0,TRUE)] #filter [.oneWay_a = 1] #extStreetsRel feed {b} #extend [StartNode_b: atposition(.geoData_b,0.0,TRUE), # EndNode_b: atposition(.geoData_b,1.0,TRUE)] #filter [.oneWay_b = 1] #hashjoin [groupId_a,groupId_b,99997] #filter [.streetId_a < .streetId_b] #extend [a: distance(.StartNode_a,.EndNode_a), # aSharp: distance(.EndNode_b,.StartNode_b), # b: distance(.StartNode_a,.EndNode_b), # bSharp: distance(.EndNode_a,.StartNode_b), # diag1: distance(.StartNode_a,.StartNode_b), # diag2: distance(.EndNode_a,.EndNode_b)] #sortby [groupId_a] #filter [(abs(.a - .aSharp) < (0.1 * getMaxVal(.a,.aSharp))) # and (abs(.b - .bSharp) < (0.1 * getMaxVal(.b,.bSharp))) # and (abs(2 * ((.a * .a) + (.b * .b)) - (.diag1 * .diag1) - (.diag2 * .diag2)) < 0.0001)] #consume;