👥 Audience: Developers using GeoView in their applications
For Core Contributors: See Adding Layer Types for implementation details
GeoView Layers are the primary way to display spatial data on your map. This guide explains layer concepts, types, configuration, and usage.
A GeoView Layer is an abstraction that wraps OpenLayers layers and provides a consistent API across different data sources. Each GeoView Layer:
- Has a unique identifier (
geoviewLayerId) - Can contain one or more sub-layers (layer hierarchy)
- Manages its own metadata, styling, and configuration
- Provides events for lifecycle management (loading, loaded, error)
- Supports temporal data and filtering
GeoView layers are divided into two main categories:
Raster layers display image-based data rendered on the server or as tiles.
Supported Types:
ogcWms- OGC Web Map ServiceesriDynamic- ESRI Dynamic Map ServiceesriImage- ESRI Image ServiceimageStatic- Static image with geographic boundsxyzTiles- XYZ tile service (raster tiles)
Characteristics:
- Server-rendered images
- Good for large datasets
- Fixed styling (defined on server)
- Limited client-side interaction
Vector tile layers display pre-tiled vector data for efficient rendering.
Supported Types:
vectorTiles- Mapbox Vector Tiles (MVT) format
Characteristics:
- Pre-processed vector tiles
- Client-side styling control
- Efficient for large datasets
- Smooth zoom and rotation
- Smaller file sizes than raster tiles
Vector layers display geometry-based data rendered on the client.
Supported Types:
ogcFeature- OGC API FeaturesogcWfs- OGC Web Feature Service (WFS)esriFeature- ESRI Feature ServiceGeoJSON- GeoJSON file or URLCSV- CSV file with coordinatesKML- Keyhole Markup Language fileWKB- Well-Known Binary formatGeoPackage- GeoPackage file (converted to GeoJSON/WKB on load)shapefile- ESRI Shapefile (converted to GeoJSON on load)
Characteristics:
- Client-rendered geometries
- Flexible styling
- Rich interaction (selection, hover, filtering)
- Attribute access
Note:
GeoPackageandshapefileare input formats that are automatically converted to appropriate vector layer types (GeoJSON or WKB) during loading.
GeoView layers support hierarchical structures:
GeoView Layer (geoviewLayerId: "myLayer")
+-- Layer Entry (layerPath: "myLayer/sublayer1")
+-- Layer Entry (layerPath: "myLayer/sublayer1/feature1")
Layer Path Format: geoviewLayerId/entryId/subEntryId/...
The layer path uniquely identifies each node in the hierarchy and is used for:
- Controlling visibility
- Setting opacity
- Applying filters
- Querying features
- Event handling
const mapViewer = cgpv.api.getMapViewer("mapId");
const result = mapViewer.layer.addGeoviewLayer({
geoviewLayerId: "myWmsLayer",
geoviewLayerName: "My WMS Layer",
geoviewLayerType: "ogcWms",
metadataAccessPath: "https://example.com/wms",
listOfLayerEntryConfig: [
{
layerId: "layer1",
layerName: "Layer 1",
},
],
});
console.log("Layer added:", result.layer.getLayerPath());// Load layer from GeoCore catalog
await mapViewer.layer.addGeoviewLayerByGeoCoreUUID("uuid-from-geocore", "en");// Load multiple layers at once
await mapViewer.layer.loadListOfGeoviewLayer([
{ geoviewLayerId: "layer1", geoviewLayerType: "ogcWms" /* ... */ },
{ geoviewLayerId: "layer2", geoviewLayerType: "esriFeature" /* ... */ },
]);A layer configuration object contains:
interface TypeGeoviewLayerConfig {
// Required
geoviewLayerId: string; // Unique identifier
geoviewLayerType: TypeGeoviewLayerType; // Layer type
// Recommended
geoviewLayerName?: string; // Display name
metadataAccessPath?: string; // Service URL
// Optional
initialSettings?: {
opacity?: number; // 0-1
visible?: boolean; // true/false
extent?: Extent; // [minX, minY, maxX, maxY]
};
// Layer entries (sublayers)
listOfLayerEntryConfig?: TypeLayerEntryConfig[];
// Temporal settings
serviceDateFormat?: string; // Server date format
externalDateFormat?: string; // User-facing date format
// Filter
layerFilter?: string; // OGC CQL filter
}See Configuration Reference for complete details.
// Get all layer IDs
const layerIds = mapViewer.layer.getGeoviewLayerIds();
// Get all layer paths (includes sublayers)
const layerPaths = mapViewer.layer.getGeoviewLayerPaths();
// Get layer by path
const layerPath = "myLayer/sublayer1";
const layer = mapViewer.layer.getGeoviewLayerByLayerPath(layerPath);
// Get layer configuration
const config = mapViewer.layer.getLayerConfig(layerPath);// Get visibility
const isVisible = mapViewer.layer.getVisible(layerPath);
// Set visibility
mapViewer.layer.setVisible(layerPath, true);// Get opacity
const opacity = mapViewer.layer.getOpacity(layerPath);
// Set opacity (0 = transparent, 1 = opaque)
mapViewer.layer.setOpacity(layerPath, 0.7);// Remove specific layer
mapViewer.layer.removeLayerUsingPath(layerPath);
// Remove all layers
mapViewer.layer.removeAllGeoviewLayers();Listen to layer lifecycle events:
cgpv.onMapInit((mapViewer) => {
// Layer configuration added
mapViewer.layer.onLayerConfigAdded((sender, payload) => {
console.log("Layer config added:", payload.layer.geoviewLayerId);
});
// Layer created (ready to use)
mapViewer.layer.onLayerCreated((sender, payload) => {
const layer = payload.layer;
console.log("Layer created:", layer.getLayerPath());
});
// Layer first loaded
mapViewer.layer.onLayerFirstLoaded((sender, payload) => {
console.log("Layer loaded:", payload.layer.getLayerPath());
});
// Layer status changed
mapViewer.layer.onLayerStatusChanged((sender, payload) => {
console.log("Layer status:", payload.status);
});
// Layer error
mapViewer.layer.onLayerError((sender, payload) => {
console.error("Layer error:", payload.error);
});
});See Layer Events for complete event reference.
GeoView supports layers with temporal data (time-enabled layers).
GeoView uses ISO UTC format internally for all dates:
- Numeric dates: Milliseconds since January 1, 1970 UTC
- String dates: ISO 8601 format (e.g.,
2023-10-29T12:00:00Z)
If your service uses a different date format:
{
geoviewLayerId: 'temporalLayer',
geoviewLayerType: 'esriDynamic',
// Tell GeoView how the server formats dates
serviceDateFormat: 'MM/DD/YYYY HH:mm:ss-05:00',
// Tell GeoView how to display dates to users
externalDateFormat: 'YYYY-MM-DD[THH:mm:ssZ]'
}Supported Formats:
YYYY-MM-DDTHH:MM:SS(timezone)MM-DD-YYYYTHH:MM:SS(timezone)DD-MM-YYYYTHH:MM:SS(timezone)
Separators:
- Date separator:
-or/ - Date/time separator:
Tor(space) - Timezone:
Z,+HH:MM, or-HH:MM
Truncating Dates:
Use square brackets to remove date/time components from display:
// Show only date, hide time
externalDateFormat: "YYYY-MM-DD[THH:MM:SSZ]";
// Show only year
externalDateFormat: "YYYY[-MM-DDTHH:MM:SSZ]";
// Show month and year
externalDateFormat: "MM-YYYY[THH:MM:SSZ]";Filter temporal layers by date range:
// CQL filter syntax
const filter =
"dateField >= date'2023-01-01T00:00:00Z' AND dateField <= date'2023-12-31T23:59:59Z'";
mapViewer.layer.applyViewFilter(layerPath, filter);If using externalDateFormat, use that format in your filters:
// If externalDateFormat is 'DD/MM/YYYY HH:mm:ss-05:00'
const filter = "dateField >= date'01/01/2023 00:00:00-05:00'";Apply attribute or spatial filters to layers:
// Attribute filter
mapViewer.layer.applyViewFilter(
layerPath,
"population > 100000 AND name LIKE 'New%'"
);
// Temporal filter
mapViewer.layer.applyViewFilter(
layerPath,
"dateField >= date'2023-01-01T00:00:00Z'"
);
// Clear filter
mapViewer.layer.applyViewFilter(layerPath, "");CQL Filter Syntax:
- Comparison:
=,<>,<,>,<=,>= - Logical:
AND,OR,NOT - Strings:
LIKE,IN - Dates:
date'YYYY-MM-DDTHH:MM:SSZ' - Spatial:
INTERSECTS,CONTAINS,WITHIN
Query features from layers:
// Get features at a coordinate
const features = await mapViewer.layer.getFeatureInfo(
[longitude, latitude],
layerPath
);
features.forEach((feature) => {
console.log("Feature properties:", feature.fieldInfo);
});See Layer API Reference for more query methods.
Vector layers can be styled using OpenLayers style configuration:
{
geoviewLayerId: 'vectorLayer',
geoviewLayerType: 'GeoJSON',
listOfLayerEntryConfig: [{
layerId: 'features',
source: {
dataAccessPath: 'https://example.com/data.geojson'
},
style: {
Point: {
color: '#FF0000',
size: 8
},
LineString: {
color: '#0000FF',
width: 2
},
Polygon: {
fillColor: '#00FF00',
fillOpacity: 0.5,
strokeColor: '#000000',
strokeWidth: 1
}
}
}]
}Raster layers use server-defined styles. Check your service's capabilities for available styles:
{
geoviewLayerId: 'wmsLayer',
geoviewLayerType: 'ogcWms',
listOfLayerEntryConfig: [{
layerId: 'layer1',
style: 'custom_style_name' // Must exist on server
}]
}-
Use unique layer IDs
geoviewLayerId: "unique-layer-id-123";
-
Provide localized names
geoviewLayerName: "English Name";
-
Set initial visibility and opacity
initialSettings: { visible: true, opacity: 0.8 }
-
Handle layer events
mapViewer.layer.onLayerError((sender, payload) => { console.error("Failed to load layer:", payload.error); });
-
Use layer paths for operations
mapViewer.layer.setVisible("myLayer/sublayer1", true);
-
Don't use duplicate layer IDs
// BAD - will cause conflicts addGeoviewLayer({ geoviewLayerId: 'layer1', ... }); addGeoviewLayer({ geoviewLayerId: 'layer1', ... });
-
Don't modify OpenLayers layers directly
// BAD - use GeoView API instead mapViewer.map.getLayers().forEach((layer) => layer.setOpacity(0.5));
-
Don't forget error handling
// BAD await mapViewer.layer.addGeoviewLayer(config); // GOOD try { await mapViewer.layer.addGeoviewLayer(config); } catch (error) { console.error("Failed to add layer:", error); }
Web Map Service - server-rendered raster images.
{
geoviewLayerId: 'wmsLayer',
geoviewLayerType: 'ogcWms',
metadataAccessPath: 'https://example.com/wms',
listOfLayerEntryConfig: [{
layerId: 'layerName'
}]
}ESRI Dynamic Map Service - server-rendered images.
{
geoviewLayerId: 'esriLayer',
geoviewLayerType: 'esriDynamic',
metadataAccessPath: 'https://example.com/MapServer',
listOfLayerEntryConfig: [{
layerId: '0' // Layer index
}]
}ESRI Feature Service - vector features.
{
geoviewLayerId: 'featureLayer',
geoviewLayerType: 'esriFeature',
metadataAccessPath: 'https://example.com/FeatureServer/0'
}Web Feature Service - vector features.
{
geoviewLayerId: 'wfsLayer',
geoviewLayerType: 'ogcWfs',
metadataAccessPath: 'https://example.com/wfs',
listOfLayerEntryConfig: [{
layerId: 'featureTypeName'
}]
}GeoJSON file or URL.
{
geoviewLayerId: 'geojsonLayer',
geoviewLayerType: 'GeoJSON',
listOfLayerEntryConfig: [{
layerId: 'features',
source: {
dataAccessPath: 'https://example.com/data.geojson'
}
}]
}Tile service using XYZ URL pattern (raster tiles).
{
geoviewLayerId: 'tileLayer',
geoviewLayerType: 'xyzTiles',
listOfLayerEntryConfig: [{
layerId: 'tiles',
source: {
dataAccessPath: 'https://example.com/tiles/{z}/{x}/{y}.png'
}
}]
}CSV file with coordinate columns.
{
geoviewLayerId: 'csvLayer',
geoviewLayerType: 'CSV',
listOfLayerEntryConfig: [{
layerId: 'data',
source: {
dataAccessPath: 'https://example.com/data.csv'
},
// Specify coordinate columns
sourceOptions: {
x: 'longitude', // or 'lon', 'x'
y: 'latitude' // or 'lat', 'y'
}
}]
}CSV Requirements:
- Must have coordinate columns (latitude/longitude or x/y)
- Coordinates should be in decimal degrees
- First row should contain column headers
Keyhole Markup Language file (Google Earth format).
{
geoviewLayerId: 'kmlLayer',
geoviewLayerType: 'KML',
listOfLayerEntryConfig: [{
layerId: 'features',
source: {
dataAccessPath: 'https://example.com/data.kml'
}
}]
}KML Features:
- Supports points, lines, polygons
- Preserves KML styling and icons
- Supports network links
- Handles extended data attributes
Binary geometry format for efficient storage.
{
geoviewLayerId: 'wkbLayer',
geoviewLayerType: 'WKB',
listOfLayerEntryConfig: [{
layerId: 'geometries',
source: {
dataAccessPath: 'https://example.com/data.wkb'
}
}]
}WKB Characteristics:
- Compact binary format
- Faster parsing than text formats
- Commonly used in databases (PostGIS)
Pre-tiled vector data in Mapbox Vector Tiles (MVT) format.
{
geoviewLayerId: 'vectorTileLayer',
geoviewLayerType: 'vectorTiles',
listOfLayerEntryConfig: [{
layerId: 'tiles',
source: {
dataAccessPath: 'https://example.com/tiles/{z}/{x}/{y}.pbf'
}
}]
}Vector Tiles Features:
- Client-side styling
- Smooth zoom and rotation
- Smaller file sizes than raster
- Interactive features
SQLite-based spatial database container (converted on load).
{
geoviewLayerId: 'geopackageLayer',
geoviewLayerType: 'GeoPackage',
listOfLayerEntryConfig: [{
layerId: 'layer',
source: {
dataAccessPath: 'https://example.com/data.gpkg'
}
}]
}Note: GeoPackage files are automatically converted to an appropriate vector format (GeoJSON or WKB) during loading.
ESRI Shapefile format (converted on load).
{
geoviewLayerId: 'shapefileLayer',
geoviewLayerType: 'shapefile',
listOfLayerEntryConfig: [{
layerId: 'features',
source: {
dataAccessPath: 'https://example.com/data.zip' // ZIP containing .shp, .shx, .dbf, .prj
}
}]
}Shapefile Requirements:
- Must be provided as ZIP file
- ZIP must contain: .shp, .shx, .dbf files (minimum)
- .prj file recommended for projection information
- Automatically converted to GeoJSON during loading
const result = mapViewer.layer.addGeoviewLayer(config);
mapViewer.layer.onLayerFirstLoaded((sender, payload) => {
if (payload.layer.getLayerPath() === result.layerPath) {
// Zoom to layer extent
const extent = mapViewer.layer.getExtent(result.layerPath);
if (extent) {
mapViewer.map.getView().fit(extent);
}
}
});async function loadLayersByCategory(category: string) {
const layers = await fetchLayersFromAPI(category);
for (const layerConfig of layers) {
try {
await mapViewer.layer.addGeoviewLayer(layerConfig);
} catch (error) {
console.warn(
`Failed to load layer ${layerConfig.geoviewLayerId}:`,
error
);
}
}
}// Keep two layers in sync
mapViewer.layer.onVisibilityChanged((sender, payload) => {
if (payload.layerPath === "layer1") {
mapViewer.layer.setVisible("layer2", payload.visible);
}
});- Layer API Reference - Complete API method reference
- Layer Events - Layer event documentation
- Configuration Reference - Configuration schema
- Creating Maps - Map initialization
- Event Processors - State management
🔧 For Core Contributors: See Adding Layer Types for implementing new layer types