Online Help > AlpineQuest 2.x > Maps & Layers > How to create a custom map?

How to create a custom map?


The application uses an XML based format for its custom on-demand maps configuration. Files must have an .aqx extension.

To import an .aqx configuration file, you can simply select it from your device file manager, and choose the application when asked which application to use to open the file. The file will be imported and the maps it contains will be added to the on-demand maps list.

Alternatively, you can manually put the configuration file in the [application folder]/datastore/maps/ folder. See how to locate the application folder here.


Basic example


Here is a simple example to access the default http://www.openstreetmap.org/ map:

TEST1.AQX
<?xml version="1.0" encoding="utf-8" ?>
<aqx version="11">
 
  <name>Simple Test AQX</name>
  <description>© OpenStreetMap</description>
 
  <source id="MAP_UID">
    <name>Standard Mapnik</name>
    <zoom-levels z="1-17">
      <server><![CDATA[https://a.tile.openstreetmap.org/{$z}/{$x}/{$y}.png]]></server>
    </zoom-levels>
  </source>
 
</aqx>

This example will be displayed like this in the application: on-demand-create-preview-1.jpg

Note that the application will recognize the {$x}, {$y} and {$z} variable and replace them with correct values.

If the map server uses the TMS standard (reversed y values compared to the Google/OSM standard), use {$!y} instead of {$y}.

The source id field must be unique in the file, and should only contain characters and numbers. It is used internally by the application to identify the data storage of the map.


Advanced example


A lot of optional fields have been omitted in the basic example, so here is a more complete example:

TEST2.AQX
<?xml version="1.0" encoding="utf-8" ?>
<aqx version="11">
 
  <name>Simple Test AQX</name>
  <description>© OpenStreetMap</description>
 
  <source id="MAP_UID" type="topo">
 
    <name>Standard Mapnik</name>
 
    <outline>2.54,49.49 2.54,51.51 6.41,51.51 6.41,49.49</outline>
    <preview-location>5.90,44.80,12</preview-location>
 
    <zoom-levels z="1,3,5,7,8,9,10,11,12,13,14,15,16,17" insecure="true">
 
      <update-delay>3M</update-delay>
      <max-threads>2</max-threads>
      <key-url><![CDATA[https://www.openstreetmap.org/key]]></key-url>
      <referer><![CDATA[https://www.openstreetmap.org/]]></referer>
      <user-agent>MyApp</user-agent>
 
      <server><![CDATA[https://a.tile.openstreetmap.org/{$z}/{$x}/{$y}.png]]></server>
      <server><![CDATA[https://b.tile.openstreetmap.org/{$z}/{$x}/{$y}.png]]></server>
      <server><![CDATA[https://c.tile.openstreetmap.org/{$z}/{$x}/{$y}.png]]></server>
 
    </zoom-levels>
 
  </source>
 
</aqx>

The type attribute allows to define the type of the map. If no preview is available, the application will use common preview based on the map type. Can be one of roads, topo, satellite, hybrid, nautical, aeronautical, historical, hillshade, contours.

An <outline> tag (pairs of longitudes/latitudes, space separated) can be used to define the area covered by the map. When the map is selected while another area is displayed, the application will ask the user if he wants to move the map over the covered area.

The <preview-location> tag (approximate longitude, latitude and OSM zoom id) allows the application to display the map with a preview background: on-demand-create-preview-2.jpg

The insecure attribute tells the application to accepts all HTTPS certificates without checking them (usually fixes most SSL related issues).

The <update-delay> tag indicates after how many time the stored map data should be updated if it's used again. The default is None, meaning the application will never try to update the stored data. Must end with D (number of days), W (weeks), M (months) or Y (years). For example, 3M means 3 months. Use 0D to force the application to update the data on each display.

You can limit the number of threads used to download the map using the <max-threads> tag. The default and maximum value is 3.

The <key-url> tag can be used to provide a link to the key (legend) of the map. The map key is available from the menu of a map.

The <referer> and <user-agent> tags allow you to specify what is sent in the HTTP get headers when contacting the map server.


Map layer


The difference between regular maps and map layers is that a map layer is added over the current map when being selected. This is usually used for maps having a transparent background. Here is how to define a map layer:

  <source id="MAP_UID" layer="true" opacity="50">
    <name>Map Layer Example</name>
    <zoom-levels z="1-17">
      <server><![CDATA[https://a.tile.openstreetmap.org/{$z}/{$x}/{$y}.png]]></server>
    </zoom-levels>
  </source>

The optional opacity attribute allows to define an initial opacity, given in percent.


Quadtree encoded tiles


Instead of using the {$x}, {$y} and {$z} variables, you can use the {$q} variable that contains the quadtree encoded coordinates of the tiles, like in this example:

  <source id="MAP_UID">
    <name>Quadtree Map Example</name>
    <zoom-levels z="1-17">
      <server><![CDATA[https://map.example.com/tiles/{$q}]]></server>
    </zoom-levels>
  </source>


Force a particular map projection


By default, the application uses the “WGS 84 / Pseudo-Mercator” map projection (EPSG:3857). You can force a different map projection by using the <projection-code> tag:

  <source id="MAP_UID_1">
    <name>KKJ/4 Projection</name>
    <zoom-levels z="1-17">    
      <projection-code>EPSG:2394</projection-code>
      <server><![CDATA[https://map.example.com/tiles/{$z}/{$x}/{$y}]]></server>
    </zoom-levels>
  </source>

In case you want to use a map projection which is not known by the application, you can import its WKT or PROJ definition:

  <import-crs-txt-def code="MY_2394_DEF">PROJCS["KKJ / Finland zone 4",GEOGCS["KKJ",DATUM["Kartastokoordinaattijarjestelma_1966",SPHEROID["International 1924",6378388,297,AUTHORITY["EPSG","7022"]],AUTHORITY["EPSG","6123"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4123"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",30],PARAMETER["scale_factor",1],PARAMETER["false_easting",4500000],PARAMETER["false_northing",0],AUTHORITY["EPSG","2394"],AXIS["Y",EAST],AXIS["X",NORTH]]</import-crs-txt-def>
  <source id="MAP_UID_2">
    <name>KKJ/4 Projection</name>
    <zoom-levels z="1-17">    
      <projection-code>MY_2394_DEF</projection-code>
      <server><![CDATA[https://map.example.com/tiles/{$z}/{$x}/{$y}]]></server>
    </zoom-levels>
  </source>


WMS servers


To access WMS servers, just use the {$bbox} variable in place of the bounding box BBOX WMS parameter. You can specify the coordinate system of the bounding box using the <bbox-crs-code> tag (EPSG:3857 by default).

  <source id="MAP_UID">
    <name>WMS Map Example</name>
    <zoom-levels z="1-17">
      <bbox-crs-code>EPSG:4326</bbox-crs-code>
      <server><![CDATA[https://server.example.com/wms/Service?REQUEST=GetMap&VERSION=1.1.1&LAYERS=layer&FORMAT=image/png&BBOX={$bbox}&SRS=EPSG:4326&WIDTH=256&HEIGHT=256]]></server>
    </zoom-levels>
  </source>

In the server requires a bounding box with integer numbers, you can use the {$ibbox} variable instead of {$bbox}.


WMTS server


To access WMTS servers, you need to manually configure each levels:

<?xml version="1.0" encoding="utf-8" ?>
<aqx version="11">
 
  <import-ogc-wkt-def code="EPSG:4218">GEOGCS["Bogota 1975",DATUM["Bogota_1975",SPHEROID["International 1924",6378388,297,AUTHORITY["EPSG","7022"]],TOWGS84[307,304,-318,0,0,0,0],AUTHORITY["EPSG","6218"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4218"]]</import-ogc-wkt-def>
 
  <source id="MAP_UID">
    <name>WMTS Map Example</name>
 
    <zoom-levels z="8">
      <projection-code>EPSG:4218</projection-code>
      <projection-resolution>2.645833333</projection-resolution>
      <projection-offset-x>-450000.0</projection-offset-x><!-- optional, default is 0 -->
      <projection-offset-y>-800000.0</projection-offset-y><!-- optional, default is 0 -->
      <tiles-size>256</tiles-size><!-- optional, default is 256 -->
      <tiles-bounds>104,80,527,423</tiles-bounds><!-- optional, expressed as "min x,min y,max x,max y" -->
      <referer>https://server.example.com/wmts/</referer><!-- optional, default is empty -->
      <server>https://server.example.com/wmts/{$z}/{$y}/{$x}.png</server>
    </zoom-levels>
 
     <zoom-levels z="9">
      <projection-code>EPSG:4218</projection-code>
      <projection-resolution>1.322916667</projection-resolution>
      <projection-offset-x>-450000.0</projection-offset-x><!-- optional, default is 0 -->
      <projection-offset-y>-800000.0</projection-offset-y><!-- optional, default is 0 -->
      <tiles-size>256</tiles-size><!-- optional, default is 256 -->
      <tiles-bounds>208,160,1047,839</tiles-bounds><!-- optional -->
      <referer>https://server.example.com/wmts/</referer><!-- optional, default is empty -->
      <server>https://server.example.com/wmts/{$z}/{$y}/{$x}.png</server>
    </zoom-levels>
 
  </source>
 
</aqx>

To get the <projection-resolution> from a ScaleDenominator, just multiply this value by 0.00028 (which is the “standardized rendering pixel size”, in meters).

If you want to use a projection which is not natively supported by the application, you need to import its definition using the <import-ogc-wkt-def> tag. You can find the OGC WKT definition of almost all projections here: http://www.spatialreference.org/.


Advanced features

Custom variables


In addition to the variables provided by default, you can create your own variables defined by mathematical expressions:

  <source id="MAP_UID">
    <name>Custom Variables Map Example</name>
    <zoom-levels z="1-17">
      <expression set="my_variable" type="int">iif( z>10, x*y, x+y )</expression>
      <server><![CDATA[https://map.example.com/tiles/{$my_variable}.png]]></server>
    </zoom-levels>
  </source>

The set attribute defines the name of the custom variable, the type attribute tells how to display the variable (either int, long, float or double).

Most common functions and operators can be used, for example abs(x), sqrt(x), hypot(x,y), cos(x), charat(str,index), replace(str,target,replace), deg_to_rad(x), dist_eucl(x1,y1,x2,y2), md5(str), rand_uni(), quadtree(x,y,z), etc.

The <expression> tag and custom variables can only be used inside the zoom levels definition (i.e. a <zoom-level> and <zoom-levels> tag). The usual operator precedence is followed.

See here for more details on available operators and functions.


Global parameters


You can declare parameters at the file level, which may be useful to store a key or a token that is used in multiple places within the file.

Global parameters are shared among all installed files, be sure to use different parameter names in all your files.

<?xml version="1.0" encoding="utf-8" ?>
<aqx version="11">
 
  <name>Test global parameter</name>
 
  <param name="key">8451-5814-5311</param>
 
  <source id="MAP_UID_1">
    <name>Map 1</name>
    <zoom-levels z="5-15">
      <server><![CDATA[https://example.server.com/style1/{$z}/{$x}/{$y}?token={$param:key}]]></server>
    </zoom-levels>
  </source>
 
  <source id="MAP_UID_2">
    <name>Map 2</name>
    <zoom-levels z="5-15">
      <server><![CDATA[https://example.server.com/style2/{$z}/{$x}/{$y}?token={$param:key}]]></server>
    </zoom-levels>
  </source>
 
</aqx>


Make a color or a color range transparent


You can make a color become transparent (erase the color) of any map. Just specify the RGB values of the color:

   ...
    <zoom-levels z="3,5,7,8,9,10,11,12,13,14,15,16,17">
      <clear-color r="255" g="255" b="255" />
      ...
    </zoom-levels>
   ...

This example will make all white areas transparent.

You can also clear a color range:

   ...
    <zoom-levels z="3,5,7,8,9,10,11,12,13,14,15,16,17">
      <clear-color r="240-255" g="240-255" b="240-255" />
      ...
    </zoom-levels>
   ...


Send cookies or headers to the map server


You can send headers using the <header> tag and cookies using the <cookies> tag, as shown in the example below:

   ...
    <zoom-levels z="1-17">
      <header>Accept: */*</header>
      <cookie>_usr_name=Name;_usr_password=123</cookie>
      ...
    </zoom-levels>
   ...


Appendices

AQX versions


AQX file version Min. app version Notable changes
12 2.3.3 Map resolution for geodetic CRS now expressed in deg/px instead of m/px. Default CRS for WMS BBOX is now EPSG:3857 (WGS 84 / Pseudo-Mercator). Added support for sha1 and hash hash functions.
11 2.3.0 Added support for polar stereographic projections.
10 2.2.5 Added support for composite sources. Added support for insecure parameter. Added support for unixtime and tostring(int,radix) functions. Added support for {$y!} variable.
9 2.0.4 Added support for default-location tag. Added support for china-offset and clear-color parameters. Added support for md5 function. Sources parameter opacity expressed in percent (0-100) instead of 0-255.
8 2.0.0 Added support for zoom-level and zoom-levels definitions. Added support for replace and format functions.


Inline expressions


List of operators

Operator Note
+ Additive operator (also used for string concatenation).
- Subtraction operator.
* Multiplication operator.
/ Division operator.
% Remainder operator.
^ Power operator.
== Equal to operator (also used for string).
!= 1 Not equal to operator (also used for string).
> Greater than operator.
> = Greater than or equal to operator.
< Less than operator.
< = Less than or equal to operator.
&& Conditional AND operator.
|| Conditional OR operator.
! Logical complement operator.
< < Signed left shift operator.
> > Signed right shift operator.

1. Available from AQ 2.2.8c

List of variables

Variable Note
c The speed of light in vacuum.
e Euler's number.
h Planck's constant.
k Boltzmann's constant.
pi The number π.
q The elementary charge.

List of common functions

Function Return type Note
abs(double) double Returns the absolute value of a double value.
acos(double) double Returns the arc cosine of a value; the returned angle is in the range 0.0 through π.
asin(double) double Returns the arc sine of a value; the returned angle is in the range -π÷2 through π÷2.
atan(double) double Returns the arc tangent of a value; the returned angle is in the range -π÷2 through π÷2.
ceil(double) long Returns the smallest (closest to negative infinity) double value that is greater than or equal to the argument and is equal to a mathematical integer.
charAt(string,long) string Returns the char value at the specified index.
cos(double) double Returns the trigonometric cosine of an angle.
deg_to_rad(double) double Converts from degrees to radians.
dist_eucl(double,double,double,double) double Computes the Euclidean distance between to points x1 (first parameter), y1 (second parameter) and x2 (third parameter), y2 (fourth parameter) as defined by hypot( (x2-x1), (y2-y1) ).
exp(double) double Returns Euler's number e raised to the power of a double value.
fact(long) long Return the product of all positive integers less than or equal to the specified value.
floor(double) long Returns the largest (closest to positive infinity) double value that is less than or equal to the argument and is equal to a mathematical integer.
format(string,double) string Returns a formatted string of the second parameter value, using the format string specified by the first parameter. See here for the format details. Example: format(“%tm”,(unixtime(1))) gives the current month number with two digits.
hash(string,string) string Returns the hash of the second string parameter, using the algorithm given in the first string parameter.
hypot(double,double) double Returns sqrt(x²+y²) without intermediate overflow or underflow.
iif(double,mixed,mixed) mixed If the first parameter is different from 0.0, return the second parameter, else the third one.
len(string), length(string) long Returns the length of a string.
ln(double) double Returns the natural logarithm (base e) of a double value.
log(double) double Returns the base 10 logarithm of a double value.
md5(string) string Returns the MD5 hash of the string parameter.
not(double) long If the parameter is different from 0.0, return 0, else return 1.
pow(double,double) double Returns the value of the first argument raised to the power of the second argument.
quadtree(long,long,long) string Combines the x (first parameter), x (second parameter) and zoom (third parameter) values into a one-dimensional quadtree key string.
rad_to_deg(double) double Converts from radians to degrees.
rand_uni() double Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0. Returned values are chosen pseudorandomly with (approximately) uniform distribution from that range.
replace(string,string,string) string Replaces each substring of a string (first parameter) that matches the literal target sequence (second parameter) with the specified literal replacement sequence (third parameter).
round(double) long Returns the closest long to the argument, with ties rounding to positive infinity.
sha1(string) string Returns the SHA-1 hash of the string parameter.
sin(double) 1 double Returns the trigonometric sine of an angle.
sqrt(double) double Returns the correctly rounded positive square root of a double value.
substr(string,long) string Returns a string that is a substring of the string given in the first parameter. The substring begins with the character at the index specified by the second parameter and extends to the end of the string.
substr(string,long,long) string Returns a string that is a substring the string given in the first parameter. The substring begins with the character at the index specified by the second parameter and extends to the character at the index specified by the third parameter, minus 1.
tan(double) double Returns the trigonometric tangent of an angle.
toDouble(mixed) double Returns a double holding the value represented by the argument. If the parameter is a long or double, the same value is returned. If the parameter is a string, it will be converted to a double value using this method.
toLong(mixed) long Returns a long holding the value represented by the argument. If the parameter is a long, the same value is returned. If the parameter is a double, the rounded value is returned. If the parameter is a string, it will be converted to a long value using this method.
toString(mixed) string Returns a string representing the value represented by the argument. If the parameter is a long, it is returned as a signed decimal representation. If the parameter is a double, it is returned as a string that represents its sign and magnitude (absolute value). If the parameter is a string, the same value is returned.
toString(mixed,long) string Returns a string representing the value represented by the argument. If the parameter is a long, it is returned as a signed decimal representation in the radix specified by the second parameter. If the parameter is a double, it is returned as a string that represents its sign and magnitude (absolute value). If the parameter is a string, the same value is returned.
unixtime() long Returns the current time in seconds.
unixtime(long) long If the parameter is 1, returns the current time in milliseconds, otherwise returns the current time in seconds.
valueAt(long,mixed…) mixed Returns the value at the index (starting from zero after the first parameter) specified by the first parameter.

1. Available from AQ 2.2.8c