Layer Operations
Adding Layers
Add a data source first, then add the corresponding layer based on the source. For example, adding a wms raster layer:
map.addSource('wms-test-source', {
'type': 'raster',
'tiles': [
wmsurl
],
'tileSize': 256
});
map.addLayer({
'id': 'wms-test-layer',
'type': 'raster',
'source': 'wms-test-source',
'paint': { "raster-opacity": 1 }
}
);
Online example: Tianditu overlaid with CAD map
// Create a GeoJSON data source named "ids"
map.addGeoJSONSource('ids');
// Create a circle layer with id 'ids-circle' linked to "ids"
map.addCircleLayer('ids-circle', 'ids', {
// Set different colors based on hover state
circleColor: ['case', ['to-boolean', ['feature-state', 'hover']], 'red', '#FFA0FD'],
// Set different stroke width based on hover state
circleStrokeWidth: ['case', ['to-boolean', ['feature-state', 'hover']], 2, 1],
});
// Set the circle radius for the layer
map.setCircleRadius(['ids-circle'], 12);
// Set mouse to 'pointer' shape when over this layer
map.hoverPointer(['ids-circle']);
// Enable hover feature state for this layer to set different values based on hover
map.hoverFeatureState('ids-circle');
// Randomly generate some GeoJSON points
let data = mapBounds.randomGeoJsonPointCollection(1000);
// Set data source data
map.setData('ids', map.toLngLat(data))
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// Open map
let res = await svc.openMap({
mapid: "sys_hello", // map ID
mapopenway: vjmap.MapOpenWay.GeomRender, // geometry render
style: vjmap.openMapLightStyle() // use dark style when container has dark background
})
if (res.error) {
showError(res.error)
return;
}
// Map bounds
let mapBounds = vjmap.GeoBounds.fromString(res.bounds);
// Create projection
let prj = new vjmap.GeoProjection(mapBounds);
//
// Map instance
let map = new vjmap.Map({
container: 'map', // container ID
style: svc.rasterStyle(), // raster style
center: prj.toLngLat(mapBounds.center()), // center
zoom: 1, // zoom level
pitch: 0,
renderWorldCopies: false // no world copies
});
// Attach service and projection
map.attach(svc, prj);
await map.onLoad();
// Add GeoJSON source "ids"
map.addGeoJSONSource('ids');
// Add circle layer "ids-circle" from source "ids"
map.addCircleLayer('ids-circle', 'ids', {
// Color by hover state
circleColor: ['case', ['to-boolean', ['feature-state', 'hover']], 'red', '#FFA0FD'],
// Stroke width by hover state
circleStrokeWidth: ['case', ['to-boolean', ['feature-state', 'hover']], 2, 1],
});
// Set circle radius
map.setCircleRadius(['ids-circle'], 12);
// Pointer cursor on hover
map.hoverPointer(['ids-circle']);
// Enable hover feature state for styling
map.hoverFeatureState('ids-circle');
// Random GeoJSON points
let data = mapBounds.randomGeoJsonPointCollection(1000);
// Set source data
map.setData('ids', map.toLngLat(data))
setInterval(() => {
data = mapBounds.randomGeoJsonPointCollection(Math.floor(Math.random() * 1000));
// Simulate data update
map.setData('ids', map.toLngLat(data))
}, 5000)Other methods for adding layers
/** Add a layer with given id, source, type, and properties.
* @param id
* @param source
* @param type
* @param props
* @param before
*/
addLayerEx(
id: string,
source: string,
type: string,
props: {},
before: string | null | undefined
): SourceBoundUtils;
/** Add a layer before another layer, with given id, source, type, and properties.
* @param id
* @param source
* @param type
* @param props
* @param before
*/
addLayerBefore(
id: string,
source: SourceOrData,
type: string,
props: {},
before?: string
): SourceBoundUtils | null | undefined;
/** Add a layer of type "line".
* @param id
* @param props
* @param before
* @param source
*/
addLineLayer(id: string, source: string, props: LineLayerStyleProp, before?: string): void;
/** Add a layer of type "fill".
* @param id
* @param props
* @param before
* @param source
*/
addFillLayer(id: string, source: string, props: FillLayerStyleProp, before?: string): void;
/** Add a layer of type "circle".
* @param id
* @param props
* @param before
* @param source
*/
addCircleLayer(
id: string,
source: string,
props: CircleLayerStyleProp,
before?: string
): void;
/** Add a layer of type "symbol".
* @param id
* @param props
* @param before
* @param source
*/
addSymbolLayer(
id: string,
source: string,
props: SymbolLayerStyleProp,
before?: string
): void;
/** Add a layer of type `video`.
* @param id
* @param props
* @param before
* @param source
*/
addVideoLayer(id: string, source: string, props: object, before?: string): void;
/** Add a layer of type `raster`.
* @param id
* @param props
* @param before
* @param source
*/
addRasterLayer(
id: string,
source: string,
props: RasterLayerStyleProp,
before?: string
): void;
/** Add a layer of type "fill-extrusion".
* @param id
* @param props
* @param before
* @param source
*/
addFillExtrusionLayer(
id: string,
source: string,
props: FillExtrusionLayerStyleProp,
before?: string
): void;
/** Add a layer of type "heatmap".
* @param id
* @param props
* @param before
* @param source
*/
addHeatmapLayer(
id: string,
source: string,
props: HeatmapLayerStyleProp,
before?: string
): void;
/** Add a layer of type "hillshade".
* @param id
* @param props
* @param before
* @param source
*/
addHillshadeLayer(
id: string,
source: string,
props: HillshadeLayerStyleProp,
before?: string
): void;
/** Add a `raster` source
@param sourceId ID of the new source.
@param {object} props Properties defining the source, per the style spec.
*/
addRasterSource(sourceId: string, props: RasterSourceSpecification): SourceBoundUtils;
/** Add a `raster-dem` source
@param sourceId ID of the new source.
@param {object} props Properties defining the source, per the style spec.
*/
addRasterDemSource(sourceId: string, props: RasterDEMSourceSpecification): SourceBoundUtils;
/** Add an `image` source
@param sourceId ID of the new source.
@param {object} props Properties defining the source, per the style spec.
*/
addImageSource(sourceId: string, props: ImageSourceSpecification): SourceBoundUtils;
/** Add a "video" source
@param sourceId ID of the new source.
@param {object} props Properties defining the source, per the style spec.
*/
addVideoSource(sourceId: string, props: VideoSourceSpecification): SourceBoundUtils;
Removing Layers
removeLayer removes the layer with the given ID from the map style. If no such layer exists, an error event is triggered.
if (map.getLayer('state-data')) map.removeLayer('state-data');
removeLayerEx removes one or more layers; does not throw if they do not exist
map.removeLayerEx('state-data');
map.removeLayerEx(['state-data', "layer2"]);
removeSourceEx removes one or more sources, first removing all layers that depend on them. Does not error if the source does not exist
map.removeSourceEx('ids');
map.removeSourceEx(['source1', "source2"]);
Showing Layers
Show a layer by setting the layout visibility property to visible
map.setLayoutProperty(layerid, "visibility", "visible");
Or show by layer id
map.show(layerid);
or
map.toggle(layerid, true)
Or make all layers associated with a data source visible
map.showSource(sourceid);
or
map.toggleSource(sourceid, true)
Hiding Layers
Hide a layer by setting the layout visibility property to none
map.setLayoutProperty(layerid, "visibility", "none");
Or hide by layer id
map.hide(layerid);
or
map.toggle(layerid, false)
Or hide all layers associated with a data source
map.hideSource(sourceid);
or
map.toggleSource(sourceid, false)
Setting Layer Properties
// They all work on multiple layers at once:
map.setLineWidth([ 'mylayer' , 'mylayer-highlight' ], 4 );
map.setLineOpacity( /^ border- / , 0 );
map.setFillColor( layer => layer.source === 'farms' , 'green' );
// There is also a more familiar setProperty() form.
map.setProperty( 'mylayer' , 'line-width' , 3 );
// Simpler way to update source data:
map.setData( 'mysource' , data);
// You can omit the data parameter to clear a GeoJSON source:
map.setData( 'mysource' );
// Update multiple filters at once.
map.setFilter([ 'buildings-fill' , 'buildings-outline' , 'buildings-label' ], [...]);
Layer Events
Listen via map events, e.g.
map.on("click", layerid, e => {
console.log(e)
})
or
// clickLayer() is similar to .on('click)', but can accept an array and adds a 'features' member to the event for the clicked content.
map.clickLayer([ 'towns' , 'town-labels' ], e => panel.selectedId = e.features[ 0 ].id);
// Use mouse "pointer" cursor when hovering over this layer.
map.hoverPointer( 'mylayer' );
// If you pass multiple layers, it correctly handles moving from one layer to another
// Use mouse "pointer" cursor when hovering over that layer.
map.hoverPointer([ 'regions-border' , 'regions-fill' ]);
// When the mouse moves over a feature on this layer, set the "hover" feature state to true or false.
// Requires features to have an `id`.
map.hoverFeatureState( 'mylayer' );
// Want to apply hover feature state to a different source?
// E.g. you hover over a label but want to highlight the surrounding boundary.
map.hoverFeatureState( 'town-labels' , 'boundaries' , 'town-boundaries' );
// You can also add other event handlers:
map.hoverFeatureState( 'mylayer' , 'mysource' , 'mysourcelayer' ,
e => console.log(`Entered ${e.features[0].id}`),
e => console.log(`Left ${e.oldFeatureid}`);
// Show a popup when a feature is hovered or clicked.
// The third parameter is an options object passed to the Popup constructor.
// Callback is called as: (feature, popup) => htmlString
map.hoverPopup( 'mylayer' , f => `<h3> ${f.properties.Name} </h3> ${f.properties.Description} ` , { anchor : 'left' });
map.clickPopup( 'mylayer' , f => `<h3> ${f.properties.Name} </h3> ${f.properties.Description} ` , { maxWidth : 500 });
// clickOneLayer tests multiple layers in order, triggering the callback on the first hit. Callback receives { features, feature, layer, event }.
map.clickOneLayer([ 'town-labels' , 'state-boundaries' ], e => {
if (e.layer === 'town-labels') {
setView('town');
panel.selectedId = e.features[0].id;
} else if (e.layer === 'state-boundaries') {
setView('state');
panel.selectedId = e.features[0].id;
}
});
// Optionally pass an extra callback that fires for clicks that miss all layers:
map.clickOneLayer(['town-labels', 'state-boundaries'], e => {...}, e => {
console.log('Missed everything');
});
// All these functions return an "undo" function that removes the added handler:
const remove = map.hoverPopup( 'mylayer' , showPopupFunc);
//...
remove(); // No more hover popup