################################################################################ # Network Import from Openstreetmap data in osm data file format. # # # # Uses Gauss-Krüger-Dataformat instead of geographical coordinates to make # # live easier for distance and speed computing # ################################################################################ # Create and open database # ################################################################################ create database ruegen; open database ruegen; ################################################################################ # (1) Set parameters to control import # ################################################################################ # Set path to osm source files. # ################################################################################ let SRC_DIR_PATH = '/home/jandt/Downloads/OSM-Dateien/'; let SOURCEFILE = 'mecklenburg-vorpommern.osm' ################################################################################ # Select part of data by defining bounding box rectangle and selecting the # # correct Gauss-Krüger-Region for the imported data set. # ################################################################################ let GK_VALUE_FOR_REGION = 4; let SELECT_RECT = rectangle2(13.244, 13.446, 53.946, 54.002); let PARTREGION = gk( (SELECT_RECT) rect2region, GK_VALUE_FOR_REGION); ################################################################################ # (2) Import the raw data from osm-file # ################################################################################ let OsmNodesRel = osmimport(SRC_DIR_PATH + SOURCEFILE ,'node') extend [GeoData: gk(makepoint(.Lon,.Lat),GK_VALUE_FOR_REGION)] remove [Lon,Lat] reNameattr[PointType: "Type"] consume; let OsmWaysTmp = osmimport(SRC_DIR_PATH + SOURCEFILE,'way') reNameattr[RoadType: "type"] filter [isdefined(.RoadType)] project[Ref, Name, RoadType, Osm_id, Oneway, Layer, Maxspeed, NodeRefs] consume; let OsmRestrictionsRel = osmimport(SRC_DIR_PATH + SOURCEFILE,'restriction') reNameattr[FromWay: "From", ViaNode: "Via", ToWay: "To"] consume; ################################################################################ # (4) Use way and node data sets to define spatial curves for the imported ways# # # # Build curve as sline from NodeRefs. # # Set Direction of curve like defined by node sequence and Oneway value # # Set Vmax by Maxspeed or if Maxspeed not defined by RoadType. # ################################################################################ let SecWaysTmp = OsmWaysTmp feed projectextend[Ref, Name, RoadType, Osm_id, Oneway, Layer, NodeRefs; Vmax: ifthenelse(.Maxspeed > 0, int2real(.Maxspeed), ifthenelse(.RoadType contains "motorway", 130.0, ifthenelse(.RoadType contains "trunk", 130.0, ifthenelse(.RoadType contains "primary",100.0, ifthenelse(.RoadType contains "secondary",70.0, ifthenelse(.RoadType contains "tertiary",50.0, ifthenelse(.RoadType contains "residential",30.0, ifthenelse(.RoadType contains "living_street",30.0, ifthenelse(.RoadType contains "road",50.0, ifthenelse(.RoadType contains "unclassified",50.0, ifthenelse(.RoadType contains "service",50.0, ifthenelse(.RoadType contains "track", 5.0, 4.0))))))))))))] projectextendstream[Ref, Name, RoadType, Osm_id, Oneway, Layer, Vmax; NodeIdString: tokenize(.NodeRefs,",")] extend[NodeId: toObject(.NodeIdString,0)] remove[NodeIdString] addcounter[OrderId,1] OsmNodesRel feed {n} hashjoin[NodeId, Osm_id_n, 9997] projectextend[Ref, Name, RoadType, Osm_id, Oneway, Layer, Vmax, OrderId, NodeId; NodEPoint: .GeoData_n] sortby[Osm_id, OrderId] groupby[Osm_id, Ref, Name, RoadType, Oneway, Layer, Vmax; Geometry: group feed projecttransformstream [NodEPoint] collect_sline[TRUE], StartNodeOSMId: group feed sortby [OrderId] head[1] extract[NodeId], EndNodeOSMId: group feed sortby [OrderId] tail[1] extract[NodeId]] OsmNodesRel feed {s} hashjoin[StartNodeOSMId, Osm_id_s,9997] projectextend[Osm_id, Ref, Name, RoadType, Oneway, Layer, Vmax, Geometry, EndNodeOSMId; SPoint: .GeoData_s] OsmNodesRel feed {e} hashjoin[EndNodeOSMId, Osm_id_e,9997] projectextend[Osm_id, Ref, Name, RoadType, Oneway, Layer, Vmax, Geometry, SPoint; EPoint: .GeoData_e] filter[toline(.Geometry) intersects PARTREGION] projectextend[Osm_id, Ref, Name, RoadType, Oneway, Layer, Vmax; GeoData: set_startsmaller(.Geometry, ifthenelse(.Oneway = -1, ifthenelse(.EPoint < .SPoint, TRUE, FALSE), ifthenelse(.EPoint < .SPoint, FALSE, TRUE)))] consume; ################################################################################ # (5) Build roads as long as possible from way data and create corresponding # # roads relation # ################################################################################ let LongRoadsTmp = SecWaysTmp feed projectextend[Ref, Name, RoadType, Osm_id; SectCurve: toline(.GeoData)] filter [isdefined(.Ref)] filter[not(.RoadType contains "link")] projectextendstream[Name, RoadType, Osm_id, SectCurve; RefToken: tokenize(' '+.Ref,";")] projectextend[Name, RoadType, Osm_id, SectCurve; Ref: trim(toObject('"'+.RefToken +'"',"a")) Dual: ifthenelse(.RoadType contains "motorway", TRUE, FALSE)] sortby[Ref,Osm_id, Dual] groupby[Ref, Dual; RoadCurve: group feed projecttransformstream[SectCurve] collect_line[TRUE], OsmIdSet: group feed projecttransformstream[Osm_id] createlistj] sortby[Ref, RoadCurve, OsmIdSet] rdup consume; let RoadsTmp = SecWaysTmp feed projectextend[Ref, Name, RoadType, Osm_id; SectCurve: toline(.GeoData), Dual: FALSE] filter[not(isdefined(.Ref))] filter[isdefined(.Name)] filter[not(.RoadType contains "link")] sortby[Name,Osm_id, Dual] groupby[Name, Dual; RoadCurve: group feed projecttransformstream[SectCurve] collect_line[TRUE], OsmIdSet: group feed projecttransformstream[Osm_id] createlistj] sortby[Name, RoadCurve, OsmIdSet] rdup consume; let RoadsPartsTmp1 = SecWaysTmp feed projectextend[Ref, Name, RoadType, Osm_id; SectCurve: toline(.GeoData), Dual: FALSE] filter[(.RoadType contains "link")] filter[isdefined(.Ref) or isdefined(.Name)] sortby[Osm_id, Dual] groupby[Osm_id, Dual; RoadCurve: group feed projecttransformstream[SectCurve] collect_line[TRUE], OsmIdSet: group feed projecttransformstream[Osm_id] createlistj] sortby[Osm_id, RoadCurve, OsmIdSet] rdup consume; let RoadsPartsTmp = SecWaysTmp feed projectextend[Ref, Name, RoadType, Osm_id; SectCurve: toline(.GeoData), Dual: FALSE] filter[not(isdefined(.Ref))] filter[(not(isdefined(.Name)))] sortby[Osm_id, Dual] groupby[Osm_id, Dual; RoadCurve: group feed projecttransformstream[SectCurve] collect_line[TRUE], OsmIdSet: group feed projecttransformstream[Osm_id] createlistj] sortby[Osm_id, RoadCurve, OsmIdSet] rdup consume; let RoadsRelation = ((LongRoadsTmp feed project[RoadCurve, OsmIdSet, Dual]) (RoadsTmp feed project[RoadCurve, OsmIdSet, Dual]) concat) ((RoadsPartsTmp feed project[RoadCurve, OsmIdSet, Dual]) (RoadsPartsTmp1 feed project[RoadCurve, OsmIdSet, Dual]) concat) concat projectextendstream[OsmIdSet, Dual; Geometry: .RoadCurve polylines[TRUE]] projectextend[OsmIdSet, Dual; GeoData: fromline(.Geometry), Lenth: size(.Geometry)] extend [StartSmaller: get_startsmaller(.GeoData)] sortby[GeoData] addcounter[RoadId,1] consume; ################################################################################ # Compute all junctions and terminating points by finding the existing # # crossings between ways and add terminating points # ################################################################################ let CrossingPtsTmp = SecWaysTmp feed project [Osm_id,GeoData,Layer] {s1} SecWaysTmp feed project [Osm_id,GeoData,Layer] {s2} itSpatialJoin [GeoData_s1, GeoData_s2, 4 ,8] filter[(.Layer_s1 = .Layer_s2)] filter[.Osm_id_s1 < .Osm_id_s2] filter[.GeoData_s1 intersects .GeoData_s2] projectextendstream[; Osm_id1: .Osm_id_s1, Osm_id2: .Osm_id_s2, Pt: components(crossings(.GeoData_s1, .GeoData_s2))] filter[isdefined(.Pt)] consume; let RoadEndsHelp = RoadsRelation feed projectextendstream[GeoData; Osm_id: createstreamj(.OsmIdSet)] consume; let JunctionsTmp = (((CrossingPtsTmp feed projectextend[Pt; WayId: .Road1]) (CrossingPtsTmp feed projectextend[Pt; WayId: .Road2]) concat) ((SecWaysTmp feed projectextend [; Pt: getstartpoint(.GeoData), WayId: .Osm_id]) (SecWaysTmp feed projectextend [; Pt: getendpoint(.GeoData), WayId: .Osm_id]) concat) concat) ((RoadEndsHelp feed projectextend[;Pt: getstartpoint(.GeoData), WayId: .Osm_id]) (RoadEndsHelp feed projectextend[;Pt: getendpoint(.GeoData), WayId: .Osm_id]) concat) concat filter[isdefined(.Pt)] consume; let JunctionNumbers = JunctionsTmp feed project[Pt] filter[isdefined(.Pt)] sortby[Pt] rdup addcounter[JuncId,1] consume; let JunctionsRelHelp= JunctionsTmp feed {j} JunctionNumbers feed {n} itSpatialJoin[Pt_j, Pt_n,4,8] projectextend[;WayId: .WayId_j, Pt: .Pt_j, JuncId: .JuncId_n] sortby[JuncId, WayId] rdup consume; let JunctionsRel = OsmNodesRel feed {o} JunctionsRelHelp feed itSpatialJoin[GeoData_o,Pt,4,8] projectextend[JuncId, WayId;Osm_id: .Osm_id_o, GeoData: .GeoData_o] consume; let TerminatingPts = JunctionsRel feed sortby [WayId] groupby [WayId; WayPts: group feed projecttransformstream [GeoData] collect_points [TRUE], Juncs: group feed projecttransformstream[JuncId] createlistj] consume; ################################################################################ # Split ways into sections # ################################################################################ let SectionsHelp1 = SecWaysTmp feed TerminatingPts feed {a} hashjoin[Osm_id, WayId_a,9997] project[Osm_id, Ref, Name, RoadType, Oneway, Vmax, GeoData, WayPts_a] sortby [Osm_id] projectextendstream [Osm_id, Ref, Name, RoadType, Oneway, GeoData, Vmax; SectionCurve: toline(.GeoData) polylines [FALSE,.WayPts_a]] addcounter[SecId,1] projectextend[Osm_id, Ref, Name, SecId, RoadType, Oneway, Vmax, GeoData; SectGeoData: fromline(.SectionCurve)] extend[SectStartSmaller: get_startsmaller(.SectGeoData), StartNodEPoint: getstartpoint(.SectGeoData), EndNodEPoint: getendpoint(.SectGeoData), Lenth: size(.SectGeoData)] extend[StartOnCurve: atpoint(.GeoData, .StartNodEPoint), EndOnCurve: atpoint(.GeoData, .EndNodEPoint)] projectextend[Osm_id, Ref, Name, SecId, RoadType, Oneway, Vmax, Lenth, StartOnCurve, EndOnCurve; GeoDataSection: set_startsmaller(.SectGeoData, ifthenelse(.StartOnCurve < .EndOnCurve, .SectStartSmaller, not(.SectStartSmaller)))] extend[Direc: ifthenelse((.Oneway = 0) and (not(.RoadType contains "motorway")), [const jdirection value(Both)], ifthenelse((.Oneway = 0) and (.RoadType contains "link"), [const jdirection value(Both)], ifthenelse(get_startsmaller(.GeoDataSection) = (.StartOnCurve < .EndOnCurve), [const jdirection value(Up)], [const jdirection value(Down)]))), StartNodEPoint: getstartpoint(.GeoDataSection), EndNodEPoint: getendpoint(.GeoDataSection)] JunctionsRel feed {j} itSpatialJoin[StartNodEPoint,GeoData_j,4,8] filter[.StartNodEPoint = .GeoData_j] projectextend[Osm_id, Ref, Name, SecId, RoadType, Oneway, Vmax, Lenth, Direc, EndNodEPoint; StartNodeOSMId: .Osm_id_j, StartNodeJuncId: .JuncId_j, GeoData: .GeoDataSection] consume; let SectionsTmp= SectionsHelp1 feed JunctionsRel feed {n} itSpatialJoin[EndNodEPoint,GeoData_n,4,8] projectextend[Osm_id, Ref, Name, SecId, RoadType, Oneway, Vmax, GeoData, Lenth, Direc, StartNodeOSMId, StartNodeJuncId; EndNodeOSMId: .Osm_id_n, EndNodeJuncId: .JuncId_n] sortby[SecId] rdup consume; ################################################################################ # Connect roads with junctions and sections to compute roadintervals for each # # section and junctions for each road # ################################################################################ let RoadSectionsHelp = RoadsRelation feed projectextendstream[RoadId, GeoData, Lenth; SectOSMId: createstreamj(.OsmIdSet)] SectionsTmp feed sortby[Osm_id] {s} hashjoin[SectOSMId,Osm_id_s,9997] projectextend[RoadId, GeoData, SectOSMId, Lenth, SecId_s, StartNodeJuncId_s, EndNodeJuncId_s, Direc_s, GeoData_s, Lenth_s, Vmax_s; StartPoint: getstartpoint(.GeoData_s), EndPoint: getendpoint(.GeoData_s), StartPos: atpoint(.GeoData, getstartpoint(.GeoData_s)), EndPos: atpoint(.GeoData, getendpoint(.GeoData_s))] filter[isdefined(.StartPos)] filter[isdefined(.EndPos)] sortby[RoadId, SecId_s] rdup consume; let RoadSections = RoadSectionsHelp feed projectextend [RoadId, StartNodeJuncId_s, EndNodeJuncId_s, SecId_s, Vmax_s, Direc_s, Lenth_s; GeoData: .GeoData_s, RouteInt: createrouteinterval(.RoadId, .StartPos, .EndPos, .Direc_s)] sortby[RoadId, RouteInt] rdup consume; let RoadJunctions = (RoadSectionsHelp feed projectextend[RoadId; Pos: .StartPoint, JuncId: .StartNodeJuncId_s, JuncPosOnRoad: createroutelocation(.RoadId, .StartPos, .Direc_s)]) (RoadSectionsHelp feed projectextend[RoadId; Pos: .EndPoint, JuncId: .EndNodeJuncId_s, JuncPosOnRoad: createroutelocation(.RoadId, .EndPos, .Direc_s)]) concat sortby[RoadId, JuncId] rdup consume; ################################################################################ # Connect Restrictions with junctions and positions # ################################################################################ let SecRestrictionsNodes = JunctionsRel feed {j} OsmRestrictionsRel feed hashjoin[Osm_id_j,ViaNode,9997] projectextend [Osm_id, FromWay, ViaNode, ToWay, Restriction; ViaPoint: .GeoData_j, ViaJuncId: .JuncId_j] SectionsTmp feed {s1} hashjoin[Osm_id_s1,FromWay,9997] projectextend[Osm_id, FromWay, ViaNode, ToWay, Restriction, ViaPoint, ViaJuncId; FromWaySecId: .SecId_s1, FromWayJuncId1: .StartNodeJuncId_s1, FromWayJuncId2: .EndNodeJuncId_s1] SectionsTmp feed {s2} hashjoin[Osm_id, ToWay, 9997] projectextend[Osm_id, FromWay, ViaNode, ToWay, Restriction, ViaPoint, ViaJuncId, FromWaySecId, FromWayJuncId1, FromWayJuncId2; ToWaySecId: .SecId_s2, ToWayJuncId1: .StartNodeJuncId_s1, ToWayJuncId2: .EndNodeJuncId_s2] sortby[ViaJuncId] consume; let SecRestrictionsSects = SectionsTmp feed {s} OsmRestrictionsRel feed hashjoin[Osm_id_s, ViaNode,9997] projectextend[Osm_id, FromWay, ViaNode, ToWay, Restriction; ViaSectionId: .SecId_s, ViaSectionJuncId1: .StartNodeJuncId_s, ViaSectionJuncId2: .EndNodeJuncId_s] SectionsTmp feed {s1} hashjoin[Osm_id_s1,FromWay,9997] projectextend[Osm_id, FromWay, ViaNode, ToWay, Restriction, ViaSectionId, ViaSectionJuncId1, ViaSectionJundId2; FromWaySecId: .SecId_s1, FromWayJuncId1: .StartNodeJuncId_s1, FromWayJuncId2: .EndNodeJuncId_s1] SectionsTmp feed {s2} hashjoin[Osm_id_s1,ToWay,9997] projectextend[Osm_id, FromWay, ViaNode, ToWay, Restriction, ViaSectionId, ViaSectionJuncId1, ViaSectionJundId2, FromWaySecId, FromWayJuncId1, FromWayJuncId2; ToWaySecId: .SecId_s2, ToWayJuncId1: .StartNodeJuncId_s2, ToWayJuncId2: .EndNodeJuncId_s2] sortby [ViaSectionId] consume; close database; quit;