Skip to content


Kx Luna is a high-performance temporal geospatial visualisation component.



  • High-performance 60FPS/120FPS rendering of both temporal and static geospatial data
  • Multiple layer rendering types and customisable presentations:
    • Points
    • Polygons
    • Video




Title / Subtitle
Optionally set a Title and Subtitle (shown in the bottom-left of the map)
Time field sets a Float . This value can be set to a viewstate, Luna will update this View State when the time-slider changes.
ILatitude / ILongitude / _IZoom
Sets the initial load for the Latitude, Longitude and Zoom
Latitude / Longitude / Zoom
Tracks the current Latitude, Longitude and Zoom values


Multiple Layers can be displayed on a Luna Map

Toggle the display of the Luna Layer
Set the Name to a name that will be shown on the map (presentation only)
Set the Type to the relevant Layer Type
Set the LayerId to match the .luna file in the Luna Registry (no extension)
(optional) limit on the number of slices to load. This allows you to load a subset of available slices, useful for reducing load time when debugging.
(optional) Icon, which can be: A Font Awesome Free v4 Icon Name and optional colour e.g. fa-car green. A relative path to an image file e.g. circle.png (relative to /modules/Luna/luna/assets/) or Empty, which will use the default icon (dot.png)

Quick Setup

The following is the set up for the Undersea Cables ( demo


Cables luna files demo built into application

  • Name: Undersea Cables
  • Type: LineSegment
  • LayerId: cables.luna


Developing a Layer

Luna Layers are composed of :

  • Packed-binary .luna file(s) containing one or more temporal vectors, which may represent X,Y co-ordinates across time or other representations


UVs, colours. For larger temporal layers there may be a set of .luna files, typically each will represent 1 time-slice (a “slice”).

  • A .meta file containing JSON metadata definitions of the contents of the .luna file

Layers are “baked” offline using kdb+ and luna.q, typically from a source table containing time,latitude,longitude columns. The .luna files are downloaded as static assets by Luna running in the browser, hosted as a component inside of Kx Dashboards.

Your source table must contain at least the following columns:

  • time (timestamp)
  • id (long)
  • lat (real)
  • long (real)

Each row should represent a single object’s positional co-ordinate in time (but you do not need to represent all Thing’s each every timestep).

The id of your objects must be sequential and contiguous (no gaps), if it is not you should map your id’s to a sequential counterpart using

Example Query

df:update id:((distinct dfVehicleId)!(til count distinct dfVehicleId))[VehicleId] from df;

You should snap your times to a regular cadence (e.g. update time:0D00:00:30 xbar time from `df) so as to limit the total number of slices.

You are limited to a maximum of 9,999 slices (however this is an arbitrary limit and only relates to download time of so many individual slices for Raw layers)

Generating Layer Data

Layer Type: Raw

Raw layers are able to encode large volumes of encoded temporal position data and may span thousands of files, each representing an individual timeslice. These can be directly loaded by the Luna frontend from static asset files on disk.

To generate the layer data (using luna.q):

q) layer:.luna.table2layer_raw[table]

This function pivots your table in the following way: - Each row is a specific timeslice - Each row represents all objects positions (projected lat,long) at that timeslice The function returns a layer dictionary containing metadata about the layer, and layer data. It does not alter the source table.

Saving a Layer to Disk

To save the layer output by .luna.table2layer_raw to disk:

q) .luna.layer2disk[`$"walks/telewalk";layer]

Each row (timeslice) is output as a separate sequentially named file e.g. walks/telewalk_512x64x8_0000.luna walks/telewalk_512x64x8_0001.luna


The filename naming convention for Raw layers (which lack a .meta) is important as it encodes the total slices (e.g. 512), width (64) and height (8) dimensions of the layer buffers.

Deploying a Layer

The .luna files (aka “Layers”) are static assets/files, and are retrieved by Luna from the URL: https://.../modules/Luna/luna/assets/layers/xxx.luna Your .luna files should either reside within the Kx Dashboards deployment in e.g.: dash/www/modules/Luna/luna/assets/layers/

If the kdb+ instance where you are saving out your layer resides on a different server or path to where your static assets are delivered (from e.g. nginx) you will need to manually transfer the files to that location, in order for Kx Luna for Dashboards to download it.

Alternatively, use an nginx reverse proxy “fronting” Kx Dashboards to intercept the above URL and serve the static assets from another location on disk using the following nginx.conf:

        server {
                listen 8443;
                gzip on;
                gzip_types text/plain application/xml application/json;

                location /modules/Luna/luna/assets {
                        alias /nvme0/kx/kx-luna-assets;
                location / {
                        proxy_http_version 1.1;
                        proxy_set_header Upgrade $http_upgrade;
                        proxy_set_header Connection "Upgrade";
                        proxy_set_header Host $host;

This assumes an existing Kx Dashboards Direct running on port 10001 on localhost, with your .luna static assets in the path /nvme0/kx/kx-luna-assets/.