Advanced: queries, styles and editing

This page is for scripters who write their own styles or query what the map shows. Terms used here: a style is the JSON file that describes the map (see Your own style), a layer is one drawing rule in it, a source is a set of data, and a feature is one item of a source (a building, a road, a marker). The examples use these namespaces, and need your assembly to reference the Worldprint assemblies if you use an assembly definition:

using RustyAstroboy.Worldprint;
using RustyAstroboy.Worldprint.Interaction;   // LayerEventType, QueriedFeature, EditPhase
using Newtonsoft.Json.Linq;                     // JObject, for GeoJSON data

Load or replace a style

LoadStyle reads a style file or URL (a relative path is looked up in StreamingAssets first, then in the project folder). SetStyle takes the JSON itself, with an optional location that relative URLs inside the style resolve from.

map.LoadStyle("Worldprint/<scene>/style-custom.json");
map.SetStyle(json, "Worldprint/<scene>/style.json");   // same, from a string

Both replace the current map. Listeners you added with On are kept.

Diagnostics

Diagnostic is raised for each part of a style the map cannot read or draw, and for problems found later, such as a missing font or a source that fails to load. The map also writes it to the Console. Each has a Path (where in the style) and a Message.

map.Diagnostic += d => Debug.LogWarning(d.Path + ": " + d.Message);

Subscribe before you call LoadStyle, so you also get the messages of the first load.

Events on layers

On listens to the pointer over the features of a layer. The types are Click, MouseMove, MouseEnter, MouseLeave, MouseDown and MouseUp. The event gives the features under the pointer, top one first, and the pointer position in UI points from the top-left corner of the map.

map.On(LayerEventType.Click, "buildings", e =>
    Debug.Log(e.Features[0].Properties["name"]));

Off with the same arguments removes the listener. A call with several layer ids takes a list of names.

Query what is drawn

QueryRenderedFeatures returns the features drawn at a point, or in a box, top layer first. Coordinates are UI points from the top-left corner. Pass layer ids to look at only those layers, and a filter (a style filter as a JToken) to narrow the result.

List<QueriedFeature> hits = map.QueryRenderedFeatures(x, y, new[] { "buildings" });
List<QueriedFeature> inBox = map.QueryRenderedFeatures(x1, y1, x2, y2);
List<QueriedFeature> all = map.QuerySourceFeatures("cartograph", "tree");   // drawn or not

Each QueriedFeature has Properties, Id, Source, SourceLayer, Layer, State and ToGeoJson().

Feature state

Feature state is a set of values you attach to one feature, for example “hover”. A style reads it with ["feature-state", "hover"], and the map redraws without reloading anything. For a vector source you pass the source layer; for a GeoJSON source you pass null.

map.SetFeatureState("sketch", null, 1, new Dictionary<string, object> { ["hover"] = true });
map.RemoveFeatureState("sketch", null, 1, "hover");     // one key; leave key out for all of them

GetFeatureState reads it back. The id is the feature id, or the property named by promoteId in the source.

Change GeoJSON data

A GeoJSON source holds data you can change at run time. SetGeoJsonData(source, geoJson) replaces it. UpdateGeoJsonData(source, diff) applies a change and reloads only the tiles it touches. The diff has the keys removeAll, remove (a list of ids), add and update (lists of features).

map.UpdateGeoJsonData("sketch", JObject.Parse(@"{""remove"": [2]}"));

Edit features with the pointer

EnableEditing makes the features of a GeoJSON source draggable: a vertex, an edge or the whole shape. The second argument is an optional GeoJSON source, drawn by a circle layer of your style, that shows the handles of the selected feature. FeatureEdited fires on every step.

map.EnableEditing("sketch", "sketch-handles");
map.FeatureEdited += e =>
{
    if (e.Phase == EditPhase.DragEnd) undo.Push(e.Previous);   // e.Geometry and e.Diff hold the new shape
};

The phases are DragStart, Drag, DragEnd and Edit (inserting or deleting a vertex). During Drag the shape is drawn live but is not yet in the source. EditTolerance sets how close, in UI points, the pointer must be to grab a vertex. DisableEditing() stops it. The members EditHitTest, InsertVertex, DeleteVertex and SelectFeature let you drive the same actions from your own UI.

Use a MapView without a bake

MapView does not need a baked scene. Add it to a RawImage on a canvas, and load any style. The map takes its input from the UI EventSystem.

var map = rawImage.gameObject.AddComponent<MapView>();
map.Diagnostic += d => Debug.LogWarning(d);
map.LoadStyle("https://example.com/style.json");   // a path or an http(s) URL
map.Longitude = 0.12; map.Latitude = -0.12; map.Zoom = 11.5;

A style loaded this way has no scene placement, so use MapCoordinate.LngLat for places (see Coordinates). For tile servers and pictures, UseXyz and UseImage are simpler (see Real-world maps).