Class MassifInterop

java.lang.Object
com.massifmaps.api.MassifInterop

public class MassifInterop extends Object
The bridge between the object API and the facade.

Split off MassifApi so that class names no SDK type at all: a binding written by hand -
JNI, , N-API, dart:ffi - can carry the whole of MassifApi, and the C ABI already
does. Everything here names an SDK class in its signature, so it is only callable from a
platform that already holds the object API, which is exactly what "interop" means (#159).

A binding built on the facade alone never needs this class. An app migrating to the facade
a piece at a time needs it for as long as the migration lasts.
  • Method Summary

    Modifier and Type
    Method
    Description
    static int
    adopt(String kind, String objectId, Layers layers)
    Registers the map's layer list, so a layer built from a spec can be PUT on the map.

    A spec builds an object, it does not place it - the same reason LocalVectorDataSource
    needs add().
    static int
    adopt(String kind, String objectId, Options options)
    Adopts an object built with the object API, so it can be addressed by id and handle.

    The TYPE picks what is being adopted, not the kind string - `kind` is only the id
    namespace, and the same Options is legitimately adopted as "map" by one app and
    "options" by another.
    static int
    adopt(String kind, String objectId, TileDataSource source)
     
    static int
    adopt(String kind, String objectId, VectorDataSource vectorSource)
    The same for a vector data source, which is what an EXTENSION adopts.

    Both data source bases are SWIG directors, so a source the SDK has no factory for -
    GDAL/OGR, a proprietary format, anything with its own native library - is subclassed in
    Java, Objective-C or TypeScript and adopted here.
    static int
    adopt(String kind, String objectId, Layer layer)
    The same for a layer or a source built with the object API.

    This is what lets an app adopt the facade a piece at a time: everything it already
    built keeps working, and gains an id, properties, methods and events.
    static int
    adopt(String kind, String objectId, BaseMapView view)
    The map view, which is what carries the CAMERA.

    Adopt it and moveTo, flyTo, fitBounds, screenToMap, mapToScreen and stopFlight become
    ordinary facade calls, with focusPos, zoom, rotation, tilt and flightActive as read-only
    properties beside them.
    static int
    adopt(String kind, String objectId, AssetPackage assets)
    The same for an asset package, which is the one a binding cannot express as a spec.

    An app that reads its styles from somewhere the SDK has no factory for - a NativeScript
    app folder, an app's own decryption - subclasses AssetPackage in Java, Objective-C or
    TypeScript and adopts the instance here.
    createEventBridge(int handle, MapEventListener chained)
    Builds the listener that turns a map's callbacks into facade events on a target.

    The app installs it with the map view's own setMapEventListener, which is also why it
    takes the listener that was already there: a single slot means adopting the facade
    would otherwise disconnect the app's existing handlers.

    int handle = MassifInterop.adopt("map", "main", mapView.getOptions());
    mapView.setMapEventListener(
    MassifInterop.createEventBridge(handle, mapView.getMapEventListener()));

    The same for a vector layer's element clicks.
    The same for a vector tile layer's clicks, which is where a feature payload comes from.
    Install it with the layer's setVectorTileEventListener.

    The click is claimed if either the chained listener or a consuming subscriber claims it.
    static Layer
    getLayer(String objectId)
    Returns a layer built earlier, so it can be added to a map with the object API.
    static Layer
    getLayerByHandle(int handle)
     
    getSource(String objectId)
    Returns a source built or adopted earlier, so it can be handed to the object API.
    This is the escape hatch: anything the facade cannot express yet is still reachable.
    getSourceByHandle(int handle)
    The same by HANDLE, for an object that was never given an id - a child read off a
    property, a call result.

    Methods inherited from class java.lang.Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • adopt

      public static int adopt(String kind, String objectId, Options options)
      Adopts an object built with the object API, so it can be addressed by id and handle.

      The TYPE picks what is being adopted, not the kind string - `kind` is only the id
      namespace, and the same Options is legitimately adopted as "map" by one app and
      "options" by another. One overload per adoptable base class, and that set is closed:
      SWIG emits one thunk per signature, and the SDK's bases share no common root to
      declare a single parameter as.

      Not named `register`: that is a C++ keyword, and a C one, so it is not a legal
      Objective-C selector piece either.

      Parameters:
      kind - The namespace, e.g. "options". Ids only collide within a kind.
      objectId - The caller's name for the object. "id" is a keyword in Objective-C.
      options - The object.
      Returns:
      The handle, or 0 when the id is already taken.
    • adopt

      public static int adopt(String kind, String objectId, Layer layer)
      The same for a layer or a source built with the object API.

      This is what lets an app adopt the facade a piece at a time: everything it already
      built keeps working, and gains an id, properties, methods and events. The CONCRETE
      class is recovered at runtime, so an adopted VectorTileLayer answers to a vector tile
      layer's properties rather than only to Layer's.

      Returns:
      The handle, or 0 when the id is taken or the class is not a wrapped one.
    • adopt

      public static int adopt(String kind, String objectId, Layers layers)
      Registers the map's layer list, so a layer built from a spec can be PUT on the map.

      A spec builds an object, it does not place it - the same reason LocalVectorDataSource
      needs add(). This is the one for layers; call add/remove on the handle it returns.
    • adopt

      public static int adopt(String kind, String objectId, TileDataSource source)
    • adopt

      public static int adopt(String kind, String objectId, VectorDataSource vectorSource)
      The same for a vector data source, which is what an EXTENSION adopts.

      Both data source bases are SWIG directors, so a source the SDK has no factory for -
      GDAL/OGR, a proprietary format, anything with its own native library - is subclassed in
      Java, Objective-C or TypeScript and adopted here. That is the whole extension mechanism:
      the SDK ships no dependency, and the source is a facade object like any other.

      TileDataSource has had this since the facade landed; this is its vector counterpart.

      The parameter is `vectorSource`, not `source`: Objective-C has no overloading and
      builds its selector from the parameter names, so two `source` overloads are one
      duplicate `adopt:objectId:source:`.
    • adopt

      public static int adopt(String kind, String objectId, AssetPackage assets)
      The same for an asset package, which is the one a binding cannot express as a spec.

      An app that reads its styles from somewhere the SDK has no factory for - a NativeScript
      app folder, an app's own decryption - subclasses AssetPackage in Java, Objective-C or
      TypeScript and adopts the instance here. Every spec that takes an `assets` key resolves
      a string as an id of this kind, so `{"type":"cartocss","css":…,"assets":"shared"}`
      then reaches it.
    • adopt

      public static int adopt(String kind, String objectId, BaseMapView view)
      The map view, which is what carries the CAMERA.

      Adopt it and moveTo, flyTo, fitBounds, screenToMap, mapToScreen and stopFlight become
      ordinary facade calls, with focusPos, zoom, rotation, tilt and flightActive as read-only
      properties beside them. Until that existed the typed sugar on each platform called the
      map view directly, so the camera was the one part of the surface a binding could not
      reach through the C ABI - see #159.
    • getSource

      public static TileDataSource getSource(String objectId)
      Returns a source built or adopted earlier, so it can be handed to the object API.
      This is the escape hatch: anything the facade cannot express yet is still reachable.
    • getSourceByHandle

      public static TileDataSource getSourceByHandle(int handle)
      The same by HANDLE, for an object that was never given an id - a child read off a
      property, a call result. An app handing the base map's tiles to its own native code has
      one of those and no id to name it by.
    • getLayer

      public static Layer getLayer(String objectId)
      Returns a layer built earlier, so it can be added to a map with the object API. Layers
      are not attached by create - that needs the map verbs.
    • getLayerByHandle

      public static Layer getLayerByHandle(int handle)
    • createEventBridge

      public static MapEventListener createEventBridge(int handle, MapEventListener chained)
      Builds the listener that turns a map's callbacks into facade events on a target.

      The app installs it with the map view's own setMapEventListener, which is also why it
      takes the listener that was already there: a single slot means adopting the facade
      would otherwise disconnect the app's existing handlers.

      int handle = MassifInterop.adopt("map", "main", mapView.getOptions());
      mapView.setMapEventListener(
      MassifInterop.createEventBridge(handle, mapView.getMapEventListener()));

      Parameters:
      handle - The target events are emitted on.
      chained - The listener already installed, or null.
      Returns:
      The bridge.
    • createVectorTileEventBridge

      public static VectorTileEventListener createVectorTileEventBridge(int handle, VectorTileEventListener chained)
      The same for a vector tile layer's clicks, which is where a feature payload comes from.
      Install it with the layer's setVectorTileEventListener.

      The click is claimed if either the chained listener or a consuming subscriber claims it.
    • createVectorElementEventBridge

      public static VectorElementEventListener createVectorElementEventBridge(int handle, VectorElementEventListener chained)
      The same for a vector layer's element clicks.