Sometimes you will need the capabilities of a full programming language to accomplish complicated data import tasks. For instance, you might need to extract all input fields of a certain type and add them as map object attributes; or you might want to use loops, variables or functions. The ability to use ChaiScript code in the import rules system adds a full programming language to the system. The language itself is documented elsewhere; the page you are reading deals with how CartoType uses it.

Even if you don't want to do anything complex you might prefer using a full programming language to XML. You can do anything in ChaiScript that you can do in ordinary XML import rules, except for <file>, <file_type> and <dbf>, which have to be in XML.

ChaiScript code interoperates freely and seamlessly with the XML import rules system. You can write makemap files composed of mixed XML rules and ChaiScript code as convenient.

Using the ChaiScript language: <script>

The CartoType import rules system can use ChaiScript , which is a simple C++-like scripting language. Anywhere in an import rules (.makemap) file where you would write a series of rules like <set>, <set_layer>, <commit>, etc., you can insert a <script> element like this:

<script>
... ChaiScript code ...
</script>

It's often a good idea to enclose your ChaiScript code in a CDATA section so that you can use characters like < and > without needing cumbersome XML entity references like &lt; and &gt;. Here's what it looks like:

<script>
<![CDATA
... ChaiScript code ...
]]>
</script>

Every <script> section is enclosed (by the CartoType import rules parser) in a block, that is, a pair of curly brackets { ... }. This causes local variables you create in a <script> section to have the scope of that script section.

Global variables

The CartoType import rules system adds the following global variables to ChaiScript. They are cleared before each imported record is processed, just as the values set by <set_layer>, etc., are cleared. The Chaiscript vaues are connected to the XML values; <set_layer> sets the layer variable, and the other way around, and the same is true for object_type and attrib, and for values set using functions, like the road type and integer attribute.

layer is a string containing the layer name. Assign to it to set the layer.

object_type is an integer containing the current map object type. Assign one of the constants POINT, OBJECT and LINE to it to set the map object type.

attrib is a ChaiScript Map object containing the map object attributes. You can set attributes like this: attrib["attrib_name"] = 3 * 19;. You can assign a value of any type to any attribute, but values other than strings and numbers are ignored. Use the "name" attribute for the map object's standard name or label.

Functions

The CartoType import rules system adds the following functions to ChaiScript.

set(string aAttribName,aValue) sets a map object attribute to aValue; the same as attrib[aAttribName] = aValue; You can assign a value of any type to any attribute, but values other than strings and numbers are ignored.

in(string aFieldName) returns the value of the field aFieldName in the input record
in(string aFieldName,size_t aSubscript) returns the value of the field aFieldName, subscripted by aSubscript, in the input record; subscripted fields are used for associated DBF files with multiple records for a single key in the main input record.

exists(string aFieldName) returns true if the field aFieldName exists in the input record
exists(string aFieldName,size_t aSubscript) returns true if aFieldName, subscripted by aSubscript, exists in the input record; subscripted fields are used for associated DBF files with multiple records for a single key in the main input record.

dbf_record_count(string aPrefix) returns the number of records for the current key, for the DBF file with the specified prefix. Values from 0 to the number of records minus one may be used as subscripts when getting fields. See the <dbf> element in the XML import rules.

commit() creates a new output data object by copying current values (layer, object type, and attributes), and adds it to the list of output data objects to be made into map objects.
commit(string aLayer) is a variant of commit() that overrides the current layer with a layer specified as a function parameter.
commit(string aLayer,string aOsmType) is a variant of commit() that overrides the current layer and OSM type with a layer and OSM type specified as function parameters.

copy(string aName) sets the string attribute(s) named by aName, which may contain wild cards, to the same string attributes in the output object. The name 'name' copies the 'name' attribute to the unnamed output attribute, which by convention is the name.
copy(string aPrefix,string aName) is a variant of copy() that prefixes aPrefix to the copied output attributes.

set_int(uint32_t aValue,uint32_t aMask,int32_t aShift) sets the integer attribute, masked by aMask, to aValue shifted left by aShift.
set_int(uint32_t aValue,uint32_t aMask) sets the integer attribute, masked by aMask, to aValue (i.e., aShift = 0).
set_int(uint32_t aValue) sets the integer attribute to aValue (i.e, aMask = 0xFFFFFFFF and aShift = 0).

set_int_low(uint32_t aValue) is the same as set_int(aValue,0x1FFFF,0); it sets the low 17 bits of the integer attribute.

set_road(uint32_t aValue,uint32_t aMask,int32_t aShift) sets the road attribute, masked by aMask, to aValue shifted left by aShift.
set_road(uint32_t aValue,uint32_t aMask) sets the road attribute, masked by aMask, to aValue (i.e., aShift = 0).
set_road(uint32_t aValue) sets the road attribute to aValue (i.e, aMask = 0xFFFFFFFF and aShift = 0).

set_one_way_forward() and set_one_way() are the same as set_road(16,48,0) and set the one-way state to forwards.
set_one_way_backward() is the same as set_road(32,48,0) and sets the one-way state to backwards.
set_roundabout() is the same as set_road(4,4,0) and sets the roundabout flag.
set_toll() is the same as set_road(2,2,0) and sets the toll flag.
set_level(int32_t aLevel) is the same as set_road(uint32_t(aLevel),0xF000,12) and sets the level, which must be in the range -8...7.
set_bridge() is the same as set_road(0x1000,0x1000,0) and sets the bridge flag.
set_tunnel() is the same as set_road(1,1,0) and sets the tunnel flag.

set_road_type(string aName) Sets the road type (by convention, bits 6...11 of the road attribute) to the predefined value in aName, which must be one of Motorway, MotorwayLink, TrunkRoad, TrunkRoadLink, PrimaryRoad, PrimaryRoadLink, SecondaryRoad, SecondaryRoadLink, TertiaryRoad, TertiaryRoadLink, UnclassifiedRoad, ResidentialRoad, Track, ServiceRoad, PedestrianRoad, VehicularFerry, PassengerFerry, Other0 ... Other7. Case is insignificant, and values are matched on the first five characters of aName, plus a suffix of 'link' to indicate a link road, or a digit suffix to indicate a road of type other0...other7.

start_group() and end_group() work like the <group> ... </group> element in the XML import rules.

is_osm_node() returns true if the input object is an OSM node.
is_osm_way() returns true if the input object is an OSM way.
is_osm_relation() returns true if the input object is an OSM relation.

filename() returns the current input file name if known.

size() returns the size of an object in meters, measured as the diagonal of its bounding box.