415 lines
14 KiB
Plaintext
415 lines
14 KiB
Plaintext
|
|
################################################################################
|
||
|
|
### Preparing network creation from imported OSM data (7 / 11)
|
||
|
|
################################################################################
|
||
|
|
### Description:
|
||
|
|
### - This script prepares network creation from imported OSM data.
|
||
|
|
### Please, see tu_osm_import.sh for further details.
|
||
|
|
###
|
||
|
|
### Preconditions:
|
||
|
|
### - activated necessary algebras
|
||
|
|
### - existing open database with successfully imported osm data
|
||
|
|
### - ExtStreetsRel-relation
|
||
|
|
### ExtStreetsRel: rel{GeoData: sline, StreetId: int, Name: string,
|
||
|
|
### Ref: string, RoadClassRef: int, OneWay: int,
|
||
|
|
### Bridge: int, MaxSpeed: int, tunnel: bool,
|
||
|
|
### layer: int, GroupId: int}
|
||
|
|
### - NodesRel-relation
|
||
|
|
### NodesRel: rel{Node: point, NodeId: int}
|
||
|
|
### - ExtSectionsRel-relation
|
||
|
|
### ExtSectionsRel: rel{SectionId: int, Section: sline, StartNodeId: int,
|
||
|
|
### EndNodeId: int, StreetId: int, GroupId: int,
|
||
|
|
### SectionDist: real}
|
||
|
|
### - onlyRestrictions
|
||
|
|
### onlyRestrictions: rel{FromStreeRef: int, ToStreetRef: int,
|
||
|
|
### ViaNodeRef: int, ViaNode: point,
|
||
|
|
### only: bool, restriction: text}
|
||
|
|
### - NoUturnRestrictions
|
||
|
|
### NoUturnRestrictions: rel{FromStreeRef: int, ToStreetRef: int,
|
||
|
|
### ViaNodeRef: int, ViaNode: point,
|
||
|
|
### NoUturn: bool}
|
||
|
|
### - NoLeftTurnRestrictions
|
||
|
|
### NoLeftTurnRestrictions: rel{FromStreeRef: int, ToStreetRef: int,
|
||
|
|
### ViaNodeRef: int, ViaNode: point,
|
||
|
|
### NoLeftTurn: bool}
|
||
|
|
### - NoRightTurnRestrictions
|
||
|
|
### NoRightTurnRestrictions: rel{FromStreeRef: int, ToStreetRef: int,
|
||
|
|
### ViaNodeRef: int, ViaNode: point,
|
||
|
|
### NoRightTurn: bool}
|
||
|
|
### - NoStraightOnRestrictions
|
||
|
|
### NoStraightOnRestrictions: rel{FromStreeRef: int, ToStreetRef: int,
|
||
|
|
### ViaNodeRef: int, ViaNode: point,
|
||
|
|
### NoStraightOn: bool}
|
||
|
|
###
|
||
|
|
### Postconditions:
|
||
|
|
### - twoSecJuncBtwTwoSts-relation
|
||
|
|
### twoSecJuncBtwTwoSts: rel{Road1: int, Pos1: double, Road2: int,
|
||
|
|
### Pos2: double, JunctionType: int}
|
||
|
|
### - threeSecJuncBtwTwoSts-relation
|
||
|
|
### threeSecJuncBtwTwoSts: rel{Road1: int, Pos1: double, Road2: int,
|
||
|
|
### Pos2: double, JunctionType: int}
|
||
|
|
### - fourSecJuncBtwTwoSts-relation
|
||
|
|
### fourSecJuncBtwTwoSts: rel{Road1: int, Pos1: double, Road2: int,
|
||
|
|
### Pos2: double, JunctionType: int}
|
||
|
|
###
|
||
|
|
### Author:
|
||
|
|
### - Thomas Uchdorf, thomas.uchdorf(at)fernuni-hagen.de
|
||
|
|
################################################################################
|
||
|
|
|
||
|
|
# Gathering data that will be used for network creation
|
||
|
|
let FullSectionsView =
|
||
|
|
((((ExtStreetsRel feed {a}
|
||
|
|
ExtSectionsRel feed {b}
|
||
|
|
hashjoin [StreetId_a,StreetId_b,99997]
|
||
|
|
projectextend [;
|
||
|
|
GroupId: .GroupId_a,
|
||
|
|
StreetId: .StreetId_a,
|
||
|
|
SectionId: .SectionId_b,
|
||
|
|
StartNodeId: .StartNodeId_b,
|
||
|
|
EndNodeId: .EndNodeId_b,
|
||
|
|
StreetData: .GeoData_a,
|
||
|
|
SectionData: .Section_b,
|
||
|
|
SectionDist: .SectionDist_b,
|
||
|
|
Name: .Name_a,
|
||
|
|
Ref: .Ref_a,
|
||
|
|
OneWay: .OneWay_a,
|
||
|
|
MaxSpeed: .MaxSpeed_a,
|
||
|
|
Bridge: .Bridge_a,
|
||
|
|
RoadClassRef: .RoadClassRef_a,
|
||
|
|
StreetStartNode: atposition(.GeoData_a,0.0,TRUE),
|
||
|
|
StreetEndNode: atposition(.GeoData_a,size(.GeoData_a),TRUE)])
|
||
|
|
NodesRel feed {c}
|
||
|
|
hashjoin [StartNodeId,NodeId_c,99997]
|
||
|
|
remove [NodeId_c])
|
||
|
|
NodesRel feed {d}
|
||
|
|
hashjoin [EndNodeId,NodeId_d,99997]
|
||
|
|
remove [NodeId_d])
|
||
|
|
NodesRel feed {e}
|
||
|
|
hashjoin [StreetStartNode,Node_e,99997]
|
||
|
|
remove [Node_e])
|
||
|
|
NodesRel feed {f}
|
||
|
|
hashjoin [StreetEndNode,Node_f,99997]
|
||
|
|
remove [Node_f]
|
||
|
|
reNameattr [StartNode: "Node_c",EndNode: "Node_d",
|
||
|
|
StreetStartNodeId: "NodeId_e",StreetEndNodeId: "NodeId_f"]
|
||
|
|
consume;
|
||
|
|
|
||
|
|
# Building indexes to speed up queries
|
||
|
|
derive FullSectionsView_GroupId_btree =
|
||
|
|
FullSectionsView createbtree[GroupId];
|
||
|
|
derive FullSectionsView_StreetId_btree =
|
||
|
|
FullSectionsView createbtree[StreetId];
|
||
|
|
derive FullSectionsView_SectionId_btree =
|
||
|
|
FullSectionsView createbtree[SectionId];
|
||
|
|
derive FullSectionsView_StartNodeId_btree =
|
||
|
|
FullSectionsView createbtree[StartNodeId];
|
||
|
|
derive FullSectionsView_EndNodeId_btree =
|
||
|
|
FullSectionsView createbtree[EndNodeId];
|
||
|
|
derive FullSectionsView_StreetData_rtree =
|
||
|
|
FullSectionsView creatertree[StreetData];
|
||
|
|
derive FullSectionsView_SectionData_rtree =
|
||
|
|
FullSectionsView creatertree[SectionData];
|
||
|
|
derive FullSectionsView_StartNode_rtree =
|
||
|
|
FullSectionsView creatertree[StartNode];
|
||
|
|
derive FullSectionsView_EndNode_rtree =
|
||
|
|
FullSectionsView creatertree[EndNode];
|
||
|
|
|
||
|
|
# Determining all possible pairs of crossing Streets
|
||
|
|
let StartSections =
|
||
|
|
NodesRel feed
|
||
|
|
FullSectionsView feed
|
||
|
|
sortby [SectionId]
|
||
|
|
project [StreetId,SectionId,StartNodeId,EndNodeId,StreetData,SectionData,
|
||
|
|
OneWay,StreetStartNodeId,StreetEndNodeId]
|
||
|
|
hashjoin [NodeId,StartNodeId,99997]
|
||
|
|
consume;
|
||
|
|
let EndSections =
|
||
|
|
NodesRel feed
|
||
|
|
FullSectionsView feed
|
||
|
|
sortby [SectionId]
|
||
|
|
project [StreetId,SectionId,StartNodeId,EndNodeId,StreetData,SectionData,
|
||
|
|
OneWay,StreetStartNodeId,StreetEndNodeId]
|
||
|
|
hashjoin [NodeId,EndNodeId,99997]
|
||
|
|
consume;
|
||
|
|
let StartFromScratchSections =
|
||
|
|
StartSections feed
|
||
|
|
filter [(.StreetStartNodeId = .StartNodeId) and
|
||
|
|
not(.StreetStartNodeId = .StreetEndNodeId)]
|
||
|
|
consume;
|
||
|
|
let EndFromScratchSections =
|
||
|
|
EndSections feed
|
||
|
|
filter [(.StreetEndNodeId = .EndNodeId) and
|
||
|
|
not(.StreetStartNodeId = .StreetEndNodeId)]
|
||
|
|
consume;
|
||
|
|
let Two =
|
||
|
|
(StartFromScratchSections feed
|
||
|
|
EndFromScratchSections feed
|
||
|
|
concat
|
||
|
|
sortby [SectionId]) {a}
|
||
|
|
(StartFromScratchSections feed
|
||
|
|
EndFromScratchSections feed
|
||
|
|
concat
|
||
|
|
sortby [SectionId]) {b}
|
||
|
|
hashjoin [NodeId_a,NodeId_b]
|
||
|
|
filter [.SectionId_a < .SectionId_b]
|
||
|
|
filter [not(.StreetId_a = .StreetId_b)]
|
||
|
|
projectextend [;
|
||
|
|
Node: .Node_a,
|
||
|
|
Road1: .StreetId_a,
|
||
|
|
Pos1: atpoint(.StreetData_a,.Node_a),
|
||
|
|
Road2: .StreetId_b,
|
||
|
|
Pos2: atpoint(.StreetData_b,.Node_a),
|
||
|
|
JunctionType: getconnectivitycode(
|
||
|
|
ifthenelse(.NodeId_a = .EndNodeId_a, 1, 2),
|
||
|
|
ifthenelse(.NodeId_b = .EndNodeId_b, 1, 2),
|
||
|
|
0,
|
||
|
|
0,
|
||
|
|
.OneWay_a = 1,.OneWay_b = 1,FALSE,FALSE)]
|
||
|
|
consume;
|
||
|
|
let Three =
|
||
|
|
((StartSections feed
|
||
|
|
EndSections feed
|
||
|
|
concat
|
||
|
|
sortby [SectionId]) {a}
|
||
|
|
(StartSections feed
|
||
|
|
EndSections feed
|
||
|
|
concat
|
||
|
|
sortby [SectionId]) {b}
|
||
|
|
hashjoin [NodeId_a,NodeId_b]
|
||
|
|
filter [.SectionId_a < .SectionId_b])
|
||
|
|
(StartSections feed
|
||
|
|
EndSections feed
|
||
|
|
concat
|
||
|
|
sortby [SectionId]) {c}
|
||
|
|
hashjoin [NodeId_a,NodeId_c]
|
||
|
|
extend [
|
||
|
|
Road1: .StreetId_a,
|
||
|
|
Road2: .StreetId_b,
|
||
|
|
Road3: .StreetId_c,
|
||
|
|
NodeId: .NodeId_a,
|
||
|
|
Node: .Node_a]
|
||
|
|
filter [
|
||
|
|
((((.NodeId = .StartNodeId_b) and
|
||
|
|
((.StreetStartNodeId_b = .StartNodeId_b) and
|
||
|
|
not(.StreetStartNodeId_b = .StreetEndNodeId_b)))
|
||
|
|
or ((.NodeId = .EndNodeId_b) and
|
||
|
|
((.StreetEndNodeId_b = .EndNodeId_b) and
|
||
|
|
not(.StreetStartNodeId_b = .StreetEndNodeId_b))))
|
||
|
|
and (.SectionId_a < .SectionId_c) and
|
||
|
|
(.Road1 = .Road3) and not(.Road1 = .Road2))
|
||
|
|
or
|
||
|
|
((((.NodeId = .StartNodeId_a) and
|
||
|
|
((.StreetStartNodeId_a = .StartNodeId_a) and
|
||
|
|
not(.StreetStartNodeId_a = .StreetEndNodeId_a)))
|
||
|
|
or ((.NodeId = .EndNodeId_a) and
|
||
|
|
((.StreetEndNodeId_a = .EndNodeId_a) and
|
||
|
|
not(.StreetStartNodeId_a = .StreetEndNodeId_a))))
|
||
|
|
and (.SectionId_c < .SectionId_b) and
|
||
|
|
(.Road2 = .Road3) and not(.Road1 = .Road2))]
|
||
|
|
projectextend [Node;
|
||
|
|
Road1: .Road1,
|
||
|
|
Pos1: atpoint(.StreetData_a,.Node),
|
||
|
|
Road2: .Road2,
|
||
|
|
Pos2: atpoint(.StreetData_b,.Node),
|
||
|
|
JunctionType: getconnectivitycode(
|
||
|
|
ifthenelse(.NodeId_a = .EndNodeId_a, 1, 2),
|
||
|
|
ifthenelse(.NodeId_b = .EndNodeId_b, 1, 2),
|
||
|
|
ifthenelse(.Road1 = .Road3,
|
||
|
|
ifthenelse(.NodeId_c = .EndNodeId_c, 1, 2),0),
|
||
|
|
ifthenelse(.Road2 = .Road3,
|
||
|
|
ifthenelse(.NodeId_c = .EndNodeId_c, 1, 2),0),
|
||
|
|
.OneWay_a = 1,.OneWay_b = 1,
|
||
|
|
ifthenelse(.Road1 = .Road3, .OneWay_c = 1, FALSE),
|
||
|
|
ifthenelse(.Road2 = .Road3, .OneWay_c = 1, FALSE))]
|
||
|
|
consume;
|
||
|
|
let Four =
|
||
|
|
(((StartSections feed
|
||
|
|
EndSections feed
|
||
|
|
concat
|
||
|
|
sortby [SectionId]) {a}
|
||
|
|
(StartSections feed
|
||
|
|
EndSections feed
|
||
|
|
concat
|
||
|
|
sortby [SectionId]) {b}
|
||
|
|
hashjoin [NodeId_a,NodeId_b]
|
||
|
|
filter [.SectionId_a < .SectionId_b])
|
||
|
|
(StartSections feed
|
||
|
|
EndSections feed
|
||
|
|
concat
|
||
|
|
sortby [SectionId]) {c}
|
||
|
|
hashjoin [NodeId_a,NodeId_c]
|
||
|
|
filter [.SectionId_a < .SectionId_c])
|
||
|
|
(StartSections feed
|
||
|
|
EndSections feed
|
||
|
|
concat
|
||
|
|
sortby [SectionId]) {d}
|
||
|
|
hashjoin [NodeId_a,NodeId_d]
|
||
|
|
filter [.SectionId_b < .SectionId_d]
|
||
|
|
extend [
|
||
|
|
Road1: .StreetId_a,
|
||
|
|
Road2: .StreetId_b,
|
||
|
|
Road3: .StreetId_c,
|
||
|
|
Road4: .StreetId_d,
|
||
|
|
NodeId: .NodeId_a,
|
||
|
|
Node: .Node_a]
|
||
|
|
filter [(.Road1 = .Road3) and (.Road2 = .Road4) and not(.Road1 = .Road2)]
|
||
|
|
projectextend [Node;
|
||
|
|
Road1: .Road1,
|
||
|
|
Pos1: atpoint(.StreetData_a,.Node),
|
||
|
|
Road2: .Road2,
|
||
|
|
Pos2: atpoint(.StreetData_b,.Node),
|
||
|
|
JunctionType: getconnectivitycode(
|
||
|
|
ifthenelse(.NodeId_a = .EndNodeId_a, 1, 2),
|
||
|
|
ifthenelse(.NodeId_b = .EndNodeId_b, 1, 2),
|
||
|
|
ifthenelse(.NodeId_c = .EndNodeId_c, 1, 2),
|
||
|
|
ifthenelse(.NodeId_d = .EndNodeId_d, 1, 2),
|
||
|
|
.OneWay_a = 1,.OneWay_b = 1,.OneWay_c = 1,.OneWay_d = 1)]
|
||
|
|
consume;
|
||
|
|
let TargetRel =
|
||
|
|
(Two feed
|
||
|
|
project [Road1,Road2,Node]
|
||
|
|
Three feed
|
||
|
|
project [Road1,Road2,Node]
|
||
|
|
concat)
|
||
|
|
Four feed
|
||
|
|
project [Road1,Road2,Node]
|
||
|
|
concat
|
||
|
|
consume;
|
||
|
|
|
||
|
|
# Using left outer join to add the different restrictions to crossings
|
||
|
|
# that share the same junction and the same incoming Street
|
||
|
|
let Road1ToRoad2 =
|
||
|
|
((((TargetRel feed
|
||
|
|
OnlyRestrictions feed
|
||
|
|
symmouterjoin [(.Node = ..ViaNode) and
|
||
|
|
(.Road1 = ..FromStreetRef)]
|
||
|
|
filter [isdefined(.Node)])
|
||
|
|
NoUturnRestrictions feed {u}
|
||
|
|
symmouterjoin [(.Node = ..ViaNode_u) and
|
||
|
|
(.Road1 = ..FromStreetRef_u)]
|
||
|
|
filter [isdefined(.Node)])
|
||
|
|
NoLeftTurnRestrictions feed {l}
|
||
|
|
symmouterjoin [(.Node = ..ViaNode_l) and
|
||
|
|
(.Road1 = ..FromStreetRef_l)]
|
||
|
|
filter [isdefined(.Node)])
|
||
|
|
NoStraightOnRestrictions feed {s}
|
||
|
|
symmouterjoin [(.Node = ..ViaNode_s) and
|
||
|
|
(.Road1 = ..FromStreetRef_s)]
|
||
|
|
filter [isdefined(.Node)])
|
||
|
|
NoRightTurnRestrictions feed {r}
|
||
|
|
symmouterjoin [(.Node = ..ViaNode_r) and (.Road1 = ..FromStreetRef_r)]
|
||
|
|
filter [isdefined(.Node)]
|
||
|
|
extend [
|
||
|
|
Road1ToRoad2:
|
||
|
|
# matching "only_..."
|
||
|
|
(isdefined(.ViaNode) and
|
||
|
|
.Only and
|
||
|
|
(.Road1 = .FromStreetRef) and
|
||
|
|
(.Road2 = .ToStreetRef)) or
|
||
|
|
# no contradictory "only_..."
|
||
|
|
(not(isdefined(.ViaNode)) and
|
||
|
|
# as well as no restrictive restrictions
|
||
|
|
# no "no_u_turn"
|
||
|
|
not(isdefined(.ViaNode_u) and
|
||
|
|
(.Road2 = .ToStreetRef_u) and
|
||
|
|
.NoUturn_u) and
|
||
|
|
# no "no_left_turn"
|
||
|
|
not(isdefined(.ViaNode_l) and
|
||
|
|
(.Road2 = .ToStreetRef_l) and
|
||
|
|
.NoLeftTurn_l) and
|
||
|
|
# no "no_straight_on"
|
||
|
|
not(isdefined(.ViaNode_s) and
|
||
|
|
(.Road2 = .ToStreetRef_s) and
|
||
|
|
.NoStraightOn_s) and
|
||
|
|
# no "no_right_turn"
|
||
|
|
not(isdefined(.ViaNode_r) and
|
||
|
|
(.Road2 = .ToStreetRef_r) and
|
||
|
|
.NoRightTurn_r)),
|
||
|
|
Road1ToRoad1:
|
||
|
|
# no "no_u_turn" on same Street
|
||
|
|
not(isdefined(.ViaNode_u) and
|
||
|
|
(.Road1 = .ToStreetRef_u) and
|
||
|
|
.NoUturn_u)]
|
||
|
|
remove [FromStreetRef,FromStreetRef_u,FromStreetRef_l,FromStreetRef_s,
|
||
|
|
FromStreetRef_r,ToStreetRef,ToStreetRef_u,ToStreetRef_l,
|
||
|
|
ToStreetRef_s,ToStreetRef_r,ViaNodeRef,ViaNodeRef_u,
|
||
|
|
ViaNodeRef_l,ViaNodeRef_s,ViaNodeRef_r,ViaNode,ViaNode_u,
|
||
|
|
ViaNode_l,ViaNode_s,ViaNode_r,Restriction,Only,NoUturn_u,
|
||
|
|
NoLeftTurn_l,NoStraightOn_s,NoRightTurn_r]
|
||
|
|
consume;
|
||
|
|
|
||
|
|
let Road2ToRoad1 =
|
||
|
|
((((TargetRel feed
|
||
|
|
OnlyRestrictions feed
|
||
|
|
symmouterjoin [(.Node = ..ViaNode) and
|
||
|
|
(.Road2 = ..FromStreetRef)]
|
||
|
|
filter [isdefined(.Node)])
|
||
|
|
NoUturnRestrictions feed {u}
|
||
|
|
symmouterjoin [(.Node = ..ViaNode_u) and
|
||
|
|
(.Road2 = ..FromStreetRef_u)]
|
||
|
|
filter [isdefined(.Node)])
|
||
|
|
NoLeftTurnRestrictions feed {l}
|
||
|
|
symmouterjoin [(.Node = ..ViaNode_l) and
|
||
|
|
(.Road2 = ..FromStreetRef_l)]
|
||
|
|
filter [isdefined(.Node)])
|
||
|
|
NoStraightOnRestrictions feed {s}
|
||
|
|
symmouterjoin [(.Node = ..ViaNode_s) and
|
||
|
|
(.Road2 = ..FromStreetRef_s)]
|
||
|
|
filter [isdefined(.Node)])
|
||
|
|
NoRightTurnRestrictions feed {r}
|
||
|
|
symmouterjoin [(.Node = ..ViaNode_r) and (.Road2 = ..FromStreetRef_r)]
|
||
|
|
filter [isdefined(.Node)]
|
||
|
|
extend [
|
||
|
|
Road2ToRoad1:
|
||
|
|
# matching "only_..."
|
||
|
|
(isdefined(.ViaNode) and
|
||
|
|
.Only and
|
||
|
|
(.Road2 = .FromStreetRef) and
|
||
|
|
(.Road1 = .ToStreetRef)) or
|
||
|
|
# no contradictory "only_..."
|
||
|
|
(not(isdefined(.ViaNode)) and
|
||
|
|
# as well as no restrictive restrictions
|
||
|
|
# no "no_u_turn"
|
||
|
|
not(isdefined(.ViaNode_u) and
|
||
|
|
(.Road1 = .ToStreetRef_u) and
|
||
|
|
.NoUturn_u) and
|
||
|
|
# no "no_left_turn"
|
||
|
|
not(isdefined(.ViaNode_l) and
|
||
|
|
(.Road1 = .ToStreetRef_l) and
|
||
|
|
.NoLeftTurn_l) and
|
||
|
|
# no "no_straight_on"
|
||
|
|
not(isdefined(.ViaNode_s) and
|
||
|
|
(.Road1 = .ToStreetRef_s) and
|
||
|
|
.NoStraightOn_s) and
|
||
|
|
# no "no_right_turn"
|
||
|
|
not(isdefined(.ViaNode_r) and
|
||
|
|
(.Road1 = .ToStreetRef_r) and
|
||
|
|
.NoRightTurn_r)),
|
||
|
|
Road2ToRoad2:
|
||
|
|
# no "no_u_turn" on same Street
|
||
|
|
not(isdefined(.ViaNode_u) and
|
||
|
|
(.Road2 = .ToStreetRef_u) and
|
||
|
|
.NoUturn_u)]
|
||
|
|
remove [FromStreetRef,FromStreetRef_u,FromStreetRef_l,FromStreetRef_s,
|
||
|
|
FromStreetRef_r,ToStreetRef,ToStreetRef_u,ToStreetRef_l,
|
||
|
|
ToStreetRef_s,ToStreetRef_r,ViaNodeRef,ViaNodeRef_u,
|
||
|
|
ViaNodeRef_l,ViaNodeRef_s,ViaNodeRef_r,ViaNode,ViaNode_u,
|
||
|
|
ViaNode_l,ViaNode_s,ViaNode_r,Restriction,Only,NoUturn_u,
|
||
|
|
NoLeftTurn_l,NoStraightOn_s,NoRightTurn_r]
|
||
|
|
consume;
|
||
|
|
|
||
|
|
#TODO Add Road1ToRoad1 and Road2ToRoad2
|
||
|
|
|
||
|
|
# Updating the connectivity code according to the restrictions
|
||
|
|
# (only_right_turn, only_left_turn, only_straight_on,
|
||
|
|
# no_left_turn, no_right_turn, no_straight_on,
|
||
|
|
# no_u_turn)
|
||
|
|
# since Streets have to be separated at restriction Nodes according to osm
|
||
|
|
# policy, it is sufficient to take a look at junctions between two Sections
|
||
|
|
# belonging to two Streets
|
||
|
|
let TwoSecJuncBtwTwoSts =
|
||
|
|
Two feed consume;
|
||
|
|
let ThreeSecJuncBtwTwoSts =
|
||
|
|
Three feed consume;
|
||
|
|
let FourSecJuncBtwTwoSts =
|
||
|
|
Four feed consume;
|