Skip to main content

Caller-owned layer panels and map tools

Public operations, state/events and complete HTML/CSS/JS.

Caller-owned UI reads public states and uses public operations/events. The complete example contains HTML, CSS, every button/input handler, subscriptions, stale-read protection and destruction cleanup. It creates only generated local points: no keys, hidden network requests or third-party credits are required. Copy it alongside the matching SDK dist directory and serve over HTTP.

Open complete example · Copy full HTML/CSS/JS · Canonical API index

UIOperationRead state / event
Layer list / nameaddLayer/removeLayer; sqs.setLayerMetadatasqs.getLayers / getLayerMetadata; sqs.layerschange
Visibility / opacity / colorsetLayoutProperty; setPaintPropertygetLayer; getPaintProperty/getLayoutProperty; sqs.layerschange
OrderingmoveLayer(id,beforeId?)sqs.getLayers; sqs.layerschange
Zoom / northzoomIn/zoomOut/resetNorthsqs.cameraState/getMinZoom/getMaxZoom; move
Top-down / pitched viewsetProjection({type:'mercator'});setPitch(0 or45)sqs.viewModeState;move/terrain
Globe / flat projectionsetProjection/getProjectionsqs.viewModeState;move/terrain
Local scalesqs.scaleAtmove; projection/viewport changes
Creditssqs.getAttributionssqs.attributionschange
Cleanupunsubscribe; remove referencing layers before sources; destroy host mapremove; no late UI refresh

The table uses the common script facade. Standalone SDK methods are viewModeState/cameraState/scaleAt/getStyleLayers/getLayerMetadata/setLayerMetadata/getAttributions, without the script's sqs prefix; standard operations/events keep their canonical names. Reads require await. Layer names are application metadata, not inferred field semantics. getStyleLayers lists shared business layers, not internal basemap layers; read getStyle for the style document. Metadata replacement should preserve caller-owned keys.

The example edits constant circle paint values, and is not a universal expression or stylesheet editor. Applications choose other controls for expressions and tiled/internal style layers. The supported local scale is geographic/Mercator and connected pitched ground intersections, with globe support described in globe-scale; terrain-surface surveying is separate; the example reports that bound rather than inventing a scale. North reset preserves pitch; 2D sets explicit zero pitch;3D sets the documented 45 degree target, while globe and terrain are separate concepts.

Flush confirms the captured applied watermark and optionally an actual new frame; it does not imply all resources are loaded or animation is idle. Loading events and errors describe those conditions. Disable controls while an operation is pending. A monotonic refresh token rejects old async reads; changing the UI never mutates a snapshot directly. Script stop does not destroy the host map; the application's dispose action owns map destruction and unsubscription.

Layer API and bounds · Camera and projection · Scale calculation · Events and subscriptions

The sample passes duration:0 for zoom/north buttons; animations can instead use their documented options and completion events. Applied-frame confirmation does not certify animation completion.

Dimension and pitch switching: globe/terrain stay separate; buttons read canSwitchTo2d/3d.

Host conditions: fullscreen, system location and input

Application UI and its system host own these tools; the map core receives map operations. Common scripts currently expose neither fullscreen nor system-location permission requests and accept no DOM/native widget objects. GPU capability flags do not imply system permissions.

ToolStandalone web SDK hostNative/mobile hostMap operations/events
FullscreenAfter a user click, inspect document.fullscreenEnabled; call container.requestFullscreen, observe fullscreenchange and update the actual viewport; exit via document.exitFullscreenChange host window/Activity state and call sqsm_map_set_viewport with actual dimensions; host determines availabilityRefresh camera/scale and redraw; remove UI listeners on disposal
System locationIn HTTPS secure context inspect navigator.geolocation; user-trigger getCurrentPosition and handle denial/timeoutHost owns permissions, service availability and coordinate conversion; mobile GIS/iOS integration remains separatePass WGS84lng,lat to jumpTo/easeTo and observe move/errors/completion; discard late callbacks after disposal
TouchInspect touchZoomRotate/touchPitch enabled/isActive; host may disable built-in inputForward the unified input contract; Android standalone host is connected, device/mobile GIS/iOS acceptance remains separateShared camera events; see touch-navigation for scope
KeyboardFocus map before using keyboard toggles; do not intercept text-field inputWindow host forwards contracted keys; a mobile soft keyboard does not imply hardware-key supportShared pan/zoom/bearing and move events; dispose input bindings

A standalone web SDK UI click handler can obtain a host position and then use the map:

let disposed = false;
const locate = () => {
  if (!globalThis.isSecureContext || !navigator.geolocation) return;
  navigator.geolocation.getCurrentPosition(({coords}) => {
    if (disposed) return;
    view.easeTo({center:[coords.longitude,coords.latitude],zoom:14});
  }, error => { if (!disposed) console.error(error.message); },
  {enableHighAccuracy:false,timeout:10000,maximumAge:30000});
};
// Bind locate to caller-owned UI; set disposed=true before UI disposal.

This is browser host code. Portable scripts retain map operations and receive normalized coordinates from their host. Continuous watchPosition use must store the watch ID and clearWatch on stop. Hosts report unavailable permissions/services. Convert raw system coordinates to WGS84 before using map coordinates.

Use synchronous map.listens(type) for regular/once/delegated listeners owned by this facade; tables are independent. Seeevent listener queries.