Skip to main content

Custom layers

Contents

Once a source is set and has data, a layer can reference it. Layers are used to visualize the data from a source. There are a variety of layer types including: Circle, Line, Fill and Symbol.

Circle layer

A circle layer uses single coordinates from a source to display and render a circle at a location on a map. Circles can be styled with size options, coloring, opacity etc.

Import CircleLayerModule from NativeModules.

import { NativeModules } from "react-native";
const CircleLayerModule = NativeModules.CircleLayerModule;

Create your circle layer properties.

const CircleConstants = CircleLayerModule.getConstants();

let circleProperties = {};
circleProperties[CircleConstants.RADIUS] = 4;
// fill color of circle
circleProperties[CircleConstants.COLOR] = "#FFFFFF";
// border color of circle
circleProperties[CircleConstants.STROKE_COLOR] = "#000000";
circleProperties[CircleConstants.STROKE_WIDTH] = 5.0;

After creating and adding your geojson source for the circle layer, you can create the layer as shown below.

// create and add geojson source to module
...

const circleLayerId = "circleLayerId"; // define your circle layer id
const createCircleLayer = async () => {
  //  define circleProperties
  let circleProperties = {...}

  // create circle layer
  await CircleLayerModule.createCircleLayerWithProperties(
      circleLayerId,
      sourceId,
      circleProperties
  );
};

Like the geojson source, you have to add the layer to the map style for the layer to show on the map. This should be done after the map has loaded and after the CircleLayer is created.

// get StyleConstants
const StyleConstants = StyleManagerModule?.getConstants();
// depending on the platform, pass the respective mapViewTag
const createAndAddCircleLayer = async (mapViewTag) => {
  await createCircleLayer();
  await StyleManagerModule.addLayerToStyle(mapViewTag, circleLayerId,
    StyleConstants.CIRCLE_LAYER);
}

Any circle layer created is stored in the CircleLayerModule. To remove a circle layer from the map:

// depending on the platform, pass the respective mapViewTag
const removeLayerFromMap = async(mapViewTag) => {
  // removes layer from map
  await StyleManagerModule.removeLayerFromStyle(mapViewTag, circleLayerId,
    StyleConstants.CIRCLE_LAYER);
  // deletes the circle layer
  await CircleLayerModule.removeCircleLayer(circleLayerId);
}

A more detailed example of the Circle Layer in action can be found in the Dots on a Map code example.

Line layer

The line layer is used to visualize a series of coordinates as a line on the map. A line is drawn between each coordinate provided in the geometry in the source.

const LineLayerModule = NativeModules.LineLayerModule;
const StyleManagerModule = NativeModules.StyleManagerModule;
const StyleConstants = StyleManagerModule?.getConstants();

// create and add geojson source for line layer
let lineSourceId = "lineSourceId"; // your geojson source id
...

let lineLayerId = "lineLayerId"; // define your line layer id

// depending on the platform, pass the respective mapViewTag
const createAndAddLineLayer = async (mapViewTag) => {
  const LineConstants = LineLayerModule.getConstants();
  let lineProperties = {};
  lineProperties[LineConstants.WIDTH] = 4;
  lineProperties[LineConstants.COLOR] = "#0000FF";
  lineProperties[LineConstants.OPACITY] = 0.5;

  // create circle layer
  await LineLayerModule.createLineLayerWithProperties(
      lineLayerId,
      lineSourceId,
      lineProperties
  );

  // add layer to the current map style
  await StyleManagerModule.addLayerToStyle(mapViewTag, lineLayerId,
    StyleConstants.LINE_LAYER);
}

// clean up
const removeLayerFromMap = async(mapViewTag) => {
  // remove layer from map
  await StyleManagerModule.removeLayerFromStyle(mapViewTag, lineLayerId,
    StyleConstants.LINE_LAYER);
  // deletes the line layer
  await LineLayerModule.removeLineLayer(lineLayerId);
}

A more detailed example of the line Layer in action can be found in the Lines on a Map code example.

Fill layer

A fill layer makes use of the polygon geometry from the linked source. A shape is drawn enclosed on the map and the shape is filled in.

const FillLayerModule = NativeModules.FillLayerModule;
const StyleManagerModule = NativeModules.StyleManagerModule;
const StyleConstants = StyleManagerModule?.getConstants();

// create and add geojson source for fill layer
let fillSourceId = "fillSourceId"; // your geojson source id
...

let fillLayerId = "fillLayerId"; // define your fill layer id

const createAndAddFillLayer = async() => {
  const FillConstants = FillLayerModule.getConstants();
  let fillProperties = {};
  fillProperties[FillConstants.OUTLINE_COLOR] = "#000FF";
  fillProperties[FillConstants.COLOR] = "#0000FF";
  fillProperties[FillConstants.OPACITY] = 0.5;

  // create fill layer
  await FillLayerModule.createFillLayerWithProperties(
      fillLayerId,
      fillSourceId,
      fillProperties
  );

  // add layer to the current map style
  await StyleManagerModule.addLayerToStyle(mapViewTag, fillLayerId,
    StyleConstants.FILL_LAYER);
};

// clean up
const removeFillLayer = async () => {
  // remove layer from map
  await StyleManagerModule.removeLayerFromStyle(mapViewTag, fillLayerId,
    StyleConstants.FILL_LAYER);
  // deletes the fill layer
  await FillLayerModule.removeFillLayer(fillLayerId);
}

Symbol layer

The symbol layer is used to display text or icons on the map. The locations for rendering are pulled from the coordinates in the source’s data.

Create and add a symbol to map style.

let imageId = "image id"; // unique image id for identifying the image source
let uriStr = "uri"; // either a url or local image file name with extension
// depending on the platform, pass the respective mapViewTag
const addImageToStyle = async (mapViewTag) => {
  await StyleManagerModule.addImageToStyle(mapViewTag, imageId, uriStr);
}

You can then create and add the layer similar to the other layers.

const SymbolLayerModule = NativeModules.SymbolLayerModule;
const StyleManagerModule = NativeModules.StyleManagerModule;
const StyleConstants = StyleManagerModule?.getConstants();

// create and add geojson source for symbol layer
let symbolSourceId = "symbolSourceId"; // your geojson source id
...

let symbolLayerId = "symbolLayerId"; // define your symbol layer id

let imageId = "image id"; // unique image id for identifying the image source
let uriStr = "uri"; // either a url or local image file name with extension

const addImageToStyle = async (mapViewTag) => {
  await StyleManagerModule.addImageToStyle(mapViewTag, imageId, uriStr);
};

// depending on the platform, pass the respective mapViewTag
const createAndAddSymbolLayer = async (mapViewTag) => {
  const SymbolConstants = SymbolLayerModule.getConstants();
  let symbolProperties = {};
  // set icon image property to the image id
  symbolProperties[SymbolConstants.ICON_IMAGE] = imageId;

  // create symbol layer
  await SymbolLayerModule.createSymbolLayerWithProperties(
      symbolLayerId,
      symbolSourceId,
      symbolProperties
  );

  // add layer to the current map style
  await StyleManagerModule.addLayerToStyle(mapViewTag, symbolLayerId,
    StyleConstants.SYMBOL_LAYER);
};

// depending on the platform, pass the respective mapViewTag
const removeSymbolLayer = async (mapViewTag) => {
  // remove layer from map
  await StyleManagerModule.removeLayerFromStyle(mapViewTag, symbolLayerId,
    StyleConstants.SYMBOL_LAYER);
  // deletes the symbol layer
  await SymbolLayerModule.removeSymbolLayer(symbolLayerId)
  // remove image from map style
  await SymbolLayerModule.removeImageFromStyle(mapVieTag, imageId, uriStr)
}

Note: for Android, any images should be added to the android drawable directory and the uriStr must be android.resource://com.mapssampleapp/drawable/{image_name}

For iOS, images can be from a URL or it can be from a local image, but it must be included in the iOS app in the main bundle. If you are using a local image included in the iOS app main bundle, the uriStr should be the name of the file.

Last updated February 13, 2024.
Contents