Package road

Class MacaoRoad

     Implementing Your Own Road Types
          Terminology
          The Constructor
          Inheriting the Class
          Registering the Road Type
          Implementing the Init Method
          An Example

Constructor   Methods

The class MacaoRoad is the super class for all classes, which are implementing road types.

You can use the road types, which are defined in the package optional/road/roadTypes.js. You may also implement your own road types.

Implementing Your Own Road Types

To implement your own road types you have to subclass the class MacaoRoad and to provide the matching images.

Terminology

The class MacaoRoad is the super class for all road types. So you implement a road type by sub-classing the class MacaoRoad. At runtime there will be created an instance of a road type for each road element. So a road element is an instance of a road type.

The Constructor

To subclass the class MacaoRoad, you have to write a function with the name of your new class. This will be the constructor. The constructor has to have the parameters gridLeft, gridTop, ordination and roadName. GridLeft and gridTop are describing the grid position of the left top corner of a new road element of this type. The orientation describes the direction, the new element will be directed to. RoadName is a name, which will be assigned to a new element.

The constructor has to call the method initRoad(), which is implemented in the super class. Calling this method, it has to pass it's own parameters and to add some parameters, that are defining the road type. Those parameters are the typeName, gridWith, gridHeight, imageBase and maxOrdinations.

The typeName is a unique name, which you have to choose for this type of road element.

The parameters gridWidth and gridHeight are defining the size of the road element in grid units. These have to be the measures of the base orientation (see below). A road element can span one or more grid cells.

The imageBase has to contain the path and the start of the filename of the images, which are used to display the road element. Because the road element can be displayed in up to four orientations, there have to be one to four images, showing the road element in the orientations. The filenames of the images for the orientations have to start with the imageBase. Then comes a number of 1, 2, 3 or 4 for the orientation. The image with the number 1 represents the base orientation. If you have a maxOrdination of 4, the images are to be rotated by 90 degrees in clockwise order. If you have a maxOrientation of 2, the images have to be rotated by 180 degrees. A maxOrdiantion of 1 only needs one image. Behind the orientation there may be a part for the phase. The phase is only used for road types, which can change their view, like traffic lights. The filename has to end with the extension ".gif".

Note: The orientation of the class MacaoRoad works with a base of zero. But the filenames of the images are numbered with a base of one. So the base orientation has the number 0 and it's filename has the number 1.

The number of useful orientations depends on the shape of the road element and is defined by the parameter maxOrientations. This parameter has to have one of the values 1, 2 or 4. For example a straight road element normally has only two useful orientations, the base orientation and rotated by 90 degrees. If you rotate it 180 degrees, it will look the same as the base orientation. If you have a curve, it is useful to provide this road element in all four orientations. A symmetric four-way-junction will look the same, even if you rotate it for 90 or 180 degrees. So you only need to provide only one orientation.

Inheriting the Class

To inherit the methods and properties of the class MacaoRoad, you have to assign an instance of MacaoRoad as a prototype to your new class. This goes like the following example, where MyRoad is the name of your constructor and so the name of your new class:

MyRoad.prototype = new MacaoRoad

This line creates a new object of the class MacaoRoad with no parameters. This does the same as if you would write = new MacaoRoad() with brackets. Because Java Script is a prototype-based language, you need an instance of a class to subclass it. Now MyRoad has all the methods and properties, which are defined for the super class.

Registering the Road Type

You need to call the method MacaoPage.addRoadType() to register your new road type. Only registered road types are displayed in the Road Editor and can be used to add them to a page. As parameters you have to provide the typeName, which you have chosen in your constructor, and your new class:

addRoadType("MyRoad", MyRoad)

Implementing the Init Method

At last you have to implement a method init() for your new class, which needs no parameters. This method will be called, when a road element of your new road type is added to the page. In the method, you have to create the nodes of your road element, create the internal connections and assign some of the nodes to the edges. To implement this method, you only have to consider the image with the base orientation. That is the image with the number "1" in the filename.

Call the method MacaoRoad.createNode(), to create a new node for the road element. This method creates the node regarding to the road elements position, orientation and to the grid cell size. You have to define the position of the node in grid units. So if for example you want to place the node in the middle of the left top cell, which is covered by the road element, you have to provide 0.5 and 0.5 for the xPos and the yPos. For nodes that will be edge nodes, you have to define, if it has to be only used as entrance or exit or both. So the linker knows, how to connect your node to the node of an adjacent road element. Keep your nodes in local variables, so you can assign them to the edges and connect them.

Use the method MacaoRoad.setEdgeNode() to assign these nodes to edges, which may be linked to adjacent road elements. The linker will search nodes of adjacent edges of adjacent road elements and connects them. To assign a node, you have to provide the number of the edge and the grid unit, to which the node is assigned. The edges are numbered from 0 to 3 beginning with the top edge in clockwise order. So 0 = top edge, 1 = right edge, 2 = bottom edge and 3 = left edge. Because a road element can span several grid cells, you have to provide the grid unit of the node. There can only be one node to at each grid unit of an edge. The units at all edges are numbered from left to right and from top to bottom. The index starts with the value 0.

Note: Avoid placing edge nodes sharp to the edge. This could make the connection between the two nodes of adjacent road elements direct not in the direction of the road, which is shown by the image. Or the connection between the nodes could have a length of zero. You should leave a margin of 0.2 to 0.5 cells between the node and the edge.

Use the method MacaoNode.connectTo() to create the internal connections of the road element.

An Example

The following example implements a two-lane straight road type, with the length of two grid units. The basic orientation shows the lane in horizontal direction. The road element gets four edges. Two of them are assigned to the left and two of them are assigned to the right edge. There are two internal connections created between the nodes for right hand traffic.

The road type has the class name "MyRoad" and the type name "MyRoad". These names don't need to be the same.

This straight road element has a maxOrdination of two. It uses the two images RoadTwoLane1.gif and RoadTwoLane2.gif.

// the consturctor of the new road type
function MyRoad(gridLeft, gridTop, ordination, roadName) {
	this.initRoad(
		gridLeft, gridTop, ordination, roadName,
		"MyRoad", 2, 2, "examples/roadType/RoadTwoLane", 2
	)
}

// inherit the new road type from MacaoRoad
MyRoad.prototype = new MacaoRoad

// register the new road type
addRoadType("MyRoad", MyRoad)

// implement the init method
MyRoad.prototype.init = function() {
	
	// create the element's nodes
	var node1 = this.createNode("Road", 0.5, 0.6, true, false)
	var node2 = this.createNode("Road", 0.5, 1.4, false, true)
	var node3 = this.createNode("Road", 1.5, 0.6, false, true)
	var node4 = this.createNode("Road", 1.5, 1.4, true, false)
	
	// assign the nodes to edges
	this.setEdgeNode(node1, 3, 0)
	this.setEdgeNode(node2, 3, 1)
	this.setEdgeNode(node3, 1, 0)
	this.setEdgeNode(node4, 1, 1)
	
	// connect the nodes
	node3.connectTo(node1, false)
	node2.connectTo(node4, false)
}

The example examples/roadType/roadType.html adds this road type to a page with a road grid. When you open the Road Editor at this page, it contains the new road type in the list of road types. When you move the mouse over the road type, it displays the tool tip with the name MyRoad.

Constructor Summary
MacaoRoad()
     Use this constructor to create a prototype for a new road type.

Method Summary
MacaoNode createNode(String netType, number xPos, number yPos, optional boolean onlyExit, optional boolean onlyEntrance)
     Call this method in the method init() to create a new node in a road element.
integer getGridHeight()
     Call this method to get the height of the road element.
integer getGridLeft()
     Call this method to get the x-coordinate of the top left grid cell of the road element.
integer getGridTop()
     Call this method to get the y-coordinate of the top left grid cell of the road element.
integer getGridWidth()
     Call this method to get the width of the road element.
String getImageBase()
     Call this method to get the path and the beginning of the filename of the images used to display this road element.
Image getImageObject()
     Call this method to get the image object, which is used to display the road element in the road grid.
String getImagePhase()
     Call this method to get the phase of the image.
String getImageSource(integer ordination)
     Call this method to get the path and filename of the image, which is used to display the image.
integer getMaxOrdinations()
     Call this method to get the maximum number of ordinations of this road element.
String getName()
     Call this method to get the name of the road element.
MacaoNode getNodeByIndex(integer nodeIndex)
     Call this method to get a node that belongs to the road element.
integer getOrdination()
     Call this method to get the ordination of the road element.
String getTypeName()
     Call this method to get the type name of the road type.
void init()
     Overwrite this method, when you implement your own road type.
void initRoad(integer gridLeft, integer gridTop, integer ordination, String roadName, String typeName, integer gridWidth, integer gridHeigth, String imageBase, integer maxOrdinations)
     Call this method in the constructor of your road type, to set the road type properties and the road element properties.
MacaoNode setEdgeNode(MacaoNode node, integer edgeNo, integer edgePos)
     Call this method in the method init(), to define a node of the road element as edge node.
void setImagePhase(String phase)
     Call this method to set a new phase and display the fitting image.

Constructor Details
MacaoRoad()

Method Details
MacaoNode createNode(String netType, number xPos, number yPos, optional boolean onlyExit, optional boolean onlyEntrance)

integer getGridHeight()

integer getGridLeft()

integer getGridTop()

integer getGridWidth()

String getImageBase()

Image getImageObject()

String getImagePhase()

String getImageSource(integer ordination)

integer getMaxOrdinations()

String getName()

MacaoNode getNodeByIndex(integer nodeIndex)

integer getOrdination()

String getTypeName()

void init()

void initRoad(integer gridLeft, integer gridTop, integer ordination, String roadName, String typeName, integer gridWidth, integer gridHeigth, String imageBase, integer maxOrdinations)

MacaoNode setEdgeNode(MacaoNode node, integer edgeNo, integer edgePos)

void setImagePhase(String phase)