LaneFactory.java

  1. package org.opentrafficsim.road.network.factory;

  2. import java.awt.Color;
  3. import java.rmi.RemoteException;
  4. import java.util.ArrayList;
  5. import java.util.Arrays;
  6. import java.util.LinkedHashMap;
  7. import java.util.List;
  8. import java.util.Map;

  9. import javax.naming.NamingException;

  10. import org.djunits.unit.LengthUnit;
  11. import org.djunits.value.vdouble.scalar.Length;
  12. import org.djunits.value.vdouble.scalar.Speed;
  13. import org.opentrafficsim.core.geometry.Bezier;
  14. import org.opentrafficsim.core.geometry.OTSGeometryException;
  15. import org.opentrafficsim.core.geometry.OTSLine3D;
  16. import org.opentrafficsim.core.geometry.OTSPoint3D;
  17. import org.opentrafficsim.core.gtu.GTUType;
  18. import org.opentrafficsim.core.network.LinkType;
  19. import org.opentrafficsim.core.network.Network;
  20. import org.opentrafficsim.core.network.NetworkException;
  21. import org.opentrafficsim.core.network.Node;
  22. import org.opentrafficsim.core.network.OTSNode;
  23. import org.opentrafficsim.core.network.animation.LinkAnimation;
  24. import org.opentrafficsim.road.network.animation.LaneAnimation;
  25. import org.opentrafficsim.road.network.lane.CrossSectionLink;
  26. import org.opentrafficsim.road.network.lane.Lane;
  27. import org.opentrafficsim.road.network.lane.LaneType;
  28. import org.opentrafficsim.road.network.lane.changing.LaneKeepingPolicy;
  29. import org.opentrafficsim.road.network.lane.changing.OvertakingConditions;

  30. import nl.tudelft.simulation.dsol.simulators.AnimatorInterface;
  31. import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
  32. import nl.tudelft.simulation.language.d3.DirectedPoint;

  33. /**
  34.  * <p>
  35.  * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  36.  * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  37.  * <p>
  38.  * $LastChangedDate: 2015-09-16 19:20:07 +0200 (Wed, 16 Sep 2015) $, @version $Revision: 1405 $, by $Author: averbraeck $,
  39.  * initial version 30 okt. 2014 <br>
  40.  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  41.  */
  42. public final class LaneFactory
  43. {
  44.     /** Do not instantiate this class. */
  45.     private LaneFactory()
  46.     {
  47.         // Cannot be instantiated.
  48.     }

  49.     /**
  50.      * Create a Link along intermediate coordinates from one Node to another.
  51.      * @param network the network
  52.      * @param name String; name of the new Link
  53.      * @param from Node; start Node of the new Link
  54.      * @param to Node; end Node of the new Link
  55.      * @param intermediatePoints OTSPoint3D[]; array of intermediate coordinates (may be null); the intermediate points may
  56.      *            contain the coordinates of the from node and to node
  57.      * @param simulator the simulator for this network
  58.      * @return Link; the newly constructed Link
  59.      * @throws OTSGeometryException when the design line is degenerate (only one point or duplicate point)
  60.      * @throws NetworkException if link already exists in the network, if name of the link is not unique, or if the start node
  61.      *             or the end node of the link are not registered in the network.
  62.      */
  63.     public static CrossSectionLink makeLink(final Network network, final String name, final Node from, final Node to,
  64.             final OTSPoint3D[] intermediatePoints, final DEVSSimulatorInterface.TimeDoubleUnit simulator)
  65.             throws OTSGeometryException, NetworkException
  66.     {
  67.         List<OTSPoint3D> pointList =
  68.                 intermediatePoints == null ? new ArrayList<>() : new ArrayList<>(Arrays.asList(intermediatePoints));
  69.         if (pointList.size() == 0 || !from.getPoint().equals(pointList.get(0)))
  70.         {
  71.             pointList.add(0, from.getPoint());
  72.         }
  73.         if (pointList.size() == 0 || !to.getPoint().equals(pointList.get(pointList.size() - 1)))
  74.         {
  75.             pointList.add(to.getPoint());
  76.         }

  77.         /*-
  78.         // see if an intermediate point needs to be created to the start of the link in the right direction
  79.         OTSPoint3D s1 = pointList.get(0);
  80.         OTSPoint3D s2 = pointList.get(1);
  81.         double dy = s2.y - s1.y;
  82.         double dx = s2.x - s1.x;
  83.         double a = from.getLocation().getRotZ();
  84.         if (Math.abs(a - Math.atan2(dy, dx)) > 1E-6)
  85.         {
  86.             double r = Math.min(1.0, Math.sqrt(dy * dy + dx * dx) / 4.0);
  87.             OTSPoint3D extra = new OTSPoint3D(s1.x + r * Math.cos(a), s1.y + r * Math.sin(a), s1.z);
  88.             pointList.add(1, extra);
  89.         }
  90.        
  91.         // see if an intermediate point needs to be created to the end of the link in the right direction
  92.         s1 = pointList.get(pointList.size() - 2);
  93.         s2 = pointList.get(pointList.size() - 1);
  94.         dy = s2.y - s1.y;
  95.         dx = s2.x - s1.x;
  96.         a = to.getLocation().getRotZ() - Math.PI;
  97.         if (Math.abs(a - Math.atan2(dy, dx)) > 1E-6)
  98.         {
  99.             double r = Math.min(1.0, Math.sqrt(dy * dy + dx * dx) / 4.0);
  100.             OTSPoint3D extra = new OTSPoint3D(s2.x + r * Math.cos(a), s2.y + r * Math.sin(a), s2.z);
  101.             pointList.add(pointList.size() - 2, extra);
  102.         }
  103.          */

  104.         OTSLine3D designLine = new OTSLine3D(pointList);
  105.         CrossSectionLink link = new CrossSectionLink(network, name, from, to, LinkType.ROAD, designLine, simulator,
  106.                 LaneKeepingPolicy.KEEP_RIGHT);
  107.         return link;
  108.     }

  109.     /**
  110.      * Create one Lane.
  111.      * @param link Link; the link that owns the new Lane
  112.      * @param id String; the id of this lane, should be unique within the link
  113.      * @param laneType LaneType&lt;String&gt;; the type of the new Lane
  114.      * @param latPosAtStart Length; the lateral position of the new Lane with respect to the design line of the link at the
  115.      *            start of the link
  116.      * @param latPosAtEnd Length; the lateral position of the new Lane with respect to the design line of the link at the end of
  117.      *            the link
  118.      * @param width Length; the width of the new Lane
  119.      * @param speedLimit Speed; the speed limit on the new Lane
  120.      * @param simulator DEVSSimulatorInterface.TimeDoubleUnit; the simulator
  121.      * @return Lane
  122.      * @throws NamingException when names cannot be registered for animation
  123.      * @throws NetworkException on network inconsistency
  124.      * @throws OTSGeometryException when creation of center line or contour fails
  125.      */
  126.     @SuppressWarnings("checkstyle:parameternumber")
  127.     private static Lane makeLane(final CrossSectionLink link, final String id, final LaneType laneType,
  128.             final Length latPosAtStart, final Length latPosAtEnd, final Length width, final Speed speedLimit,
  129.             final DEVSSimulatorInterface.TimeDoubleUnit simulator) throws NamingException, NetworkException, OTSGeometryException
  130.     {
  131.         Map<GTUType, Speed> speedMap = new LinkedHashMap<>();
  132.         speedMap.put(GTUType.VEHICLE, speedLimit);
  133.         Lane result = new Lane(link, id, latPosAtStart, latPosAtEnd, width, width, laneType, speedMap,
  134.                 new OvertakingConditions.LeftAndRight());
  135.         if (simulator instanceof AnimatorInterface)
  136.         {
  137.             try
  138.             {
  139.                 new LaneAnimation(result, simulator, Color.LIGHT_GRAY, false);
  140.             }
  141.             catch (RemoteException exception)
  142.             {
  143.                 exception.printStackTrace();
  144.             }
  145.         }
  146.         return result;
  147.     }

  148.     /**
  149.      * Create a simple Lane.
  150.      * @param network the network
  151.      * @param name String; name of the Lane (and also of the Link that owns it)
  152.      * @param from Node; starting node of the new Lane
  153.      * @param to Node; ending node of the new Lane
  154.      * @param intermediatePoints OTSPoint3D[]; intermediate coordinates or null to create a straight road; the intermediate
  155.      *            points may contain the coordinates of the from node and to node
  156.      * @param laneType LaneType; type of the new Lane
  157.      * @param speedLimit Speed; the speed limit on the new Lane
  158.      * @param simulator DEVSSimulatorInterface.TimeDoubleUnit; the simulator
  159.      * @return Lane; the new Lane
  160.      * @throws NamingException when names cannot be registered for animation
  161.      * @throws NetworkException on network inconsistency
  162.      * @throws OTSGeometryException when creation of center line or contour fails
  163.      */
  164.     public static Lane makeLane(final Network network, final String name, final OTSNode from, final OTSNode to,
  165.             final OTSPoint3D[] intermediatePoints, final LaneType laneType, final Speed speedLimit,
  166.             final DEVSSimulatorInterface.TimeDoubleUnit simulator) throws NamingException, NetworkException, OTSGeometryException
  167.     {
  168.         Length width = new Length(4.0, LengthUnit.METER);
  169.         final CrossSectionLink link = makeLink(network, name, from, to, intermediatePoints, simulator);
  170.         Length latPos = new Length(0.0, LengthUnit.METER);
  171.         return makeLane(link, "lane", laneType, latPos, latPos, width, speedLimit, simulator);
  172.     }

  173.     /**
  174.      * Create a simple road with the specified number of Lanes.<br>
  175.      * This method returns an array of Lane. These lanes are embedded in a Link that can be accessed through the getParentLink
  176.      * method of the Lane.
  177.      * @param network the network
  178.      * @param name String; name of the Link
  179.      * @param from Node; starting node of the new Lane
  180.      * @param to Node; ending node of the new Lane
  181.      * @param intermediatePoints OTSPoint3D[]; intermediate coordinates or null to create a straight road; the intermediate
  182.      *            points may contain the coordinates of the from node and to node
  183.      * @param laneCount int; number of lanes in the road
  184.      * @param laneOffsetAtStart int; extra offset from design line in lane widths at start of link
  185.      * @param laneOffsetAtEnd int; extra offset from design line in lane widths at end of link
  186.      * @param laneType LaneType; type of the new Lanes
  187.      * @param speedLimit Speed; the speed limit on all lanes
  188.      * @param simulator DEVSSimulatorInterface.TimeDoubleUnit; the simulator
  189.      * @return Lane&lt;String, String&gt;[]; array containing the new Lanes
  190.      * @throws NamingException when names cannot be registered for animation
  191.      * @throws NetworkException on topological problems
  192.      * @throws OTSGeometryException when creation of center line or contour fails
  193.      */
  194.     @SuppressWarnings("checkstyle:parameternumber")
  195.     public static Lane[] makeMultiLane(final Network network, final String name, final OTSNode from, final OTSNode to,
  196.             final OTSPoint3D[] intermediatePoints, final int laneCount, final int laneOffsetAtStart, final int laneOffsetAtEnd,
  197.             final LaneType laneType, final Speed speedLimit, final DEVSSimulatorInterface.TimeDoubleUnit simulator)
  198.             throws NamingException, NetworkException, OTSGeometryException
  199.     {
  200.         final CrossSectionLink link = makeLink(network, name, from, to, intermediatePoints, simulator);
  201.         Lane[] result = new Lane[laneCount];
  202.         Length width = new Length(4.0, LengthUnit.METER);
  203.         for (int laneIndex = 0; laneIndex < laneCount; laneIndex++)
  204.         {
  205.             // Be ware! LEFT is lateral positive, RIGHT is lateral negative.
  206.             Length latPosAtStart = new Length((-0.5 - laneIndex - laneOffsetAtStart) * width.getSI(), LengthUnit.SI);
  207.             Length latPosAtEnd = new Length((-0.5 - laneIndex - laneOffsetAtEnd) * width.getSI(), LengthUnit.SI);
  208.             result[laneIndex] =
  209.                     makeLane(link, "lane." + laneIndex, laneType, latPosAtStart, latPosAtEnd, width, speedLimit, simulator);
  210.         }
  211.         if (simulator instanceof AnimatorInterface)
  212.         {
  213.             try
  214.             {
  215.                 new LinkAnimation(link, simulator, 3f);
  216.             }
  217.             catch (RemoteException exception)
  218.             {
  219.                 exception.printStackTrace();
  220.             }
  221.         }
  222.         return result;
  223.     }

  224.     /**
  225.      * Create a simple road with the specified number of Lanes.<br>
  226.      * This method returns an array of Lane. These lanes are embedded in a Link that can be accessed through the getParentLink
  227.      * method of the Lane.
  228.      * @param network the network
  229.      * @param name String; name of the Link
  230.      * @param from Node; starting node of the new Lane
  231.      * @param to Node; ending node of the new Lane
  232.      * @param intermediatePoints OTSPoint3D[]; intermediate coordinates or null to create a straight road; the intermediate
  233.      *            points may contain the coordinates of the from node and to node
  234.      * @param laneCount int; number of lanes in the road
  235.      * @param laneType LaneType; type of the new Lanes
  236.      * @param speedLimit Speed the speed limit (applies to all generated lanes)
  237.      * @param simulator DEVSSimulatorInterface.TimeDoubleUnit; the simulator
  238.      * @return Lane&lt;String, String&gt;[]; array containing the new Lanes
  239.      * @throws NamingException when names cannot be registered for animation
  240.      * @throws NetworkException on topological problems
  241.      * @throws OTSGeometryException when creation of center line or contour fails
  242.      */
  243.     @SuppressWarnings("checkstyle:parameternumber")
  244.     public static Lane[] makeMultiLane(final Network network, final String name, final OTSNode from, final OTSNode to,
  245.             final OTSPoint3D[] intermediatePoints, final int laneCount, final LaneType laneType, final Speed speedLimit,
  246.             final DEVSSimulatorInterface.TimeDoubleUnit simulator) throws NamingException, NetworkException, OTSGeometryException
  247.     {
  248.         return makeMultiLane(network, name, from, to, intermediatePoints, laneCount, 0, 0, laneType, speedLimit, simulator);
  249.     }

  250.     /**
  251.      * Create a simple road with the specified number of Lanes, based on a Bezier curve.<br>
  252.      * This method returns an array of Lane. These lanes are embedded in a Link that can be accessed through the getParentLink
  253.      * method of the Lane.
  254.      * @param network the network
  255.      * @param name String; name of the Link
  256.      * @param n1 Node; control node for the start direction
  257.      * @param n2 Node; starting node of the new Lane
  258.      * @param n3 Node; ending node of the new Lane
  259.      * @param n4 Node; control node for the end direction
  260.      * @param laneCount int; number of lanes in the road
  261.      * @param laneOffsetAtStart int; extra offset from design line in lane widths at start of link
  262.      * @param laneOffsetAtEnd int; extra offset from design line in lane widths at end of link
  263.      * @param laneType LaneType; type of the new Lanes
  264.      * @param speedLimit Speed; the speed limit on all lanes
  265.      * @param simulator DEVSSimulatorInterface.TimeDoubleUnit; the simulator
  266.      * @return Lane&lt;String, String&gt;[]; array containing the new Lanes
  267.      * @throws NamingException when names cannot be registered for animation
  268.      * @throws NetworkException on topological problems
  269.      * @throws OTSGeometryException when creation of center line or contour fails
  270.      */
  271.     @SuppressWarnings("checkstyle:parameternumber")
  272.     public static Lane[] makeMultiLaneBezier(final Network network, final String name, final OTSNode n1, final OTSNode n2,
  273.             final OTSNode n3, final OTSNode n4, final int laneCount, final int laneOffsetAtStart, final int laneOffsetAtEnd,
  274.             final LaneType laneType, final Speed speedLimit, final DEVSSimulatorInterface.TimeDoubleUnit simulator)
  275.             throws NamingException, NetworkException, OTSGeometryException
  276.     {
  277.         OTSLine3D bezier = makeBezier(n1, n2, n3, n4);
  278.         final CrossSectionLink link = makeLink(network, name, n2, n3, bezier.getPoints(), simulator);
  279.         Lane[] result = new Lane[laneCount];
  280.         Length width = new Length(4.0, LengthUnit.METER);
  281.         for (int laneIndex = 0; laneIndex < laneCount; laneIndex++)
  282.         {
  283.             // Be ware! LEFT is lateral positive, RIGHT is lateral negative.
  284.             Length latPosAtStart = new Length((-0.5 - laneIndex - laneOffsetAtStart) * width.getSI(), LengthUnit.SI);
  285.             Length latPosAtEnd = new Length((-0.5 - laneIndex - laneOffsetAtEnd) * width.getSI(), LengthUnit.SI);
  286.             result[laneIndex] =
  287.                     makeLane(link, "lane." + laneIndex, laneType, latPosAtStart, latPosAtEnd, width, speedLimit, simulator);
  288.         }
  289.         return result;
  290.     }

  291.     /**
  292.      * @param n1 node 1
  293.      * @param n2 node 2
  294.      * @param n3 node 3
  295.      * @param n4 node 4
  296.      * @return line between n2 and n3 with start-direction n1--&gt;n2 and end-direction n3--&gt;n4
  297.      * @throws OTSGeometryException on failure of Bezier curve creation
  298.      */
  299.     public static OTSLine3D makeBezier(final OTSNode n1, final OTSNode n2, final OTSNode n3, final OTSNode n4)
  300.             throws OTSGeometryException
  301.     {
  302.         OTSPoint3D p1 = n1.getPoint();
  303.         OTSPoint3D p2 = n2.getPoint();
  304.         OTSPoint3D p3 = n3.getPoint();
  305.         OTSPoint3D p4 = n4.getPoint();
  306.         DirectedPoint dp1 = new DirectedPoint(p2.x, p2.y, p2.z, 0.0, 0.0, Math.atan2(p2.y - p1.y, p2.x - p1.x));
  307.         DirectedPoint dp2 = new DirectedPoint(p3.x, p3.y, p3.z, 0.0, 0.0, Math.atan2(p4.y - p3.y, p4.x - p3.x));
  308.         return Bezier.cubic(dp1, dp2);
  309.     }

  310. }