Skip to main content

Geoman Features API

The Features API provides methods to manage and manipulate features (geometries) on the map. It is accessible through the features property on the Geoman instance.

const options: GmOptionsPartial = {
// configuration options
// see Configuring Geoman section for more details
};

const gm = new Geoman(map,options);
const features = gm.features;

Core Methods​

Iteration Methods​

forEach​

Iterates over all features in the main source.

features.forEach((featureData: FeatureData, id: FeatureId, store: FeatureStore) => void);

Feature Management​

add​

Adds a feature to the store.

features.add(featureData: FeatureData): void;

delete​

Removes a feature from the store. Accepts either a FeatureData instance or a feature ID.

features.delete(featureIdOrFeatureData: FeatureData | FeatureId): Promise<void>;

has​

Checks if a feature exists in a specific source.

features.has(sourceName: FeatureSourceName, featureId: FeatureId): boolean;

get​

Retrieves a feature from a specific source by ID.

features.get(sourceName: FeatureSourceName, featureId: FeatureId): FeatureData | null;

GeoJSON Operations​

importGeoJson​

Imports GeoJSON data and creates features.

features.importGeoJson(
geoJson: GeoJsonImportFeatureCollection | GeoJsonImportFeature,
options?: {
idPropertyName?: string; // Use a specific property as the feature ID
overwrite?: boolean; // When true, replace existing features with matching IDs
onIdCollision?: 'skip' | 'reassign'; // ID-collision handling (default: 'skip')
}
): Promise<{
stats: {
total: number;
success: number;
failed: number;
overwritten: number; // Count of replaced features (when overwrite: true)
};
addedFeatures: Array<FeatureData>;
}>;

When overwrite: true is set, existing features with matching IDs are deleted before importing the new features.

importGeoJsonFeature​

Imports a single GeoJSON feature.

features.importGeoJsonFeature(shapeGeoJson: GeoJsonImportFeature): Promise<FeatureData | null>;

exportGeoJson​

Exports all features as a GeoJSON FeatureCollection from Geoman's internal state. This provides the latest feature data, even during event handlers before MapLibre has committed changes.

features.exportGeoJson(options?: {
allowedShapes?: Array<FeatureShape>; // Filter by shape types
idPropertyName?: string; // Custom property name for IDs
}): GeoJsonShapeFeatureCollection;

exportGeoJsonFromSource​

Exports all features as a GeoJSON FeatureCollection directly from MapLibre's source. This may lag slightly behind Geoman's internal state during rapid updates or in event handlers.

features.exportGeoJsonFromSource(options?: {
allowedShapes?: Array<FeatureShape>; // Filter by shape types
idPropertyName?: string; // Custom property name for IDs
}): GeoJsonShapeFeatureCollection;

deleteAll​

Deletes all features from the store.

features.deleteAll(): Promise<void>;

getAll​

Returns all features as a GeoJSON FeatureCollection.

features.getAll(): FeatureCollection;

Feature Creation and Management​

createFeature​

Creates a new feature from GeoJSON data.

features.createFeature({
featureId?: FeatureId;
shapeGeoJson: GeoJsonShapeFeature;
parent?: FeatureData;
sourceName: FeatureSourceName;
imported?: boolean;
}): Promise<FeatureData | null>;

addGeoJsonFeature​

Adds a single GeoJSON feature to the store.

features.addGeoJsonFeature({
shapeGeoJson: GeoJsonImportFeature;
sourceName?: FeatureSourceName;
defaultSource?: boolean;
}): Promise<FeatureData | null>;

Feature Queries​

getFeatureByMouseEvent​

Gets a feature at the mouse event location.

features.getFeatureByMouseEvent({
event: BaseMapPointerEvent;
sourceNames: Array<FeatureSourceName>;
}): FeatureData | null;

getFeaturesByGeoJsonBounds​

Gets features that intersect with a GeoJSON geometry.

features.getFeaturesByGeoJsonBounds({
geoJson: Feature<Polygon | MultiPolygon | LineString>;
sourceNames: Array<FeatureSourceName>;
}): Array<FeatureData>;

getFeaturesByScreenBounds​

Gets features within screen coordinate bounds.

features.getFeaturesByScreenBounds({
bounds: [ScreenPoint, ScreenPoint];
sourceNames: Array<FeatureSourceName>;
}): Array<FeatureData>;

Source Management​

setDefaultSourceName​

Sets the default source for new features.

features.setDefaultSourceName(sourceName: FeatureSourceName): void;

Marker Feature Operations​

createMarkerFeature​

Creates a new marker feature.

features.createMarkerFeature({
type: MarkerData['type'];
coordinate: LngLatTuple;
parentFeature: FeatureData;
sourceName: FeatureSourceName;
properties?: Record<string, unknown>;
}): Promise<FeatureData | null>;

updateMarkerFeaturePosition​

Updates a marker feature's position.

features.updateMarkerFeaturePosition(
markerFeatureData: FeatureData,
coordinates: LngLatTuple
): Promise<void>;

Source Names​

Geoman has three built-in sources for features:

  • gm_main: The main source for permanent features
  • gm_temporary: For temporary features during editing/drawing
  • gm_standby: For standby features (Pro version only)

FeatureData Instance Methods​

Once you have a FeatureData instance (from importing, creating, or querying features), you can call the following methods directly on the feature instance.

updateProperties​

Updates custom properties on this feature. Properties are merged with existing ones. Set a property value to undefined to delete it. Internal Geoman properties (prefixed with gm_) are protected and cannot be modified through this method.

feature.updateProperties(properties: Record<string, unknown>): Promise<void>;

Example:

// Get a feature
const feature = gm.features.get('gm_main', featureId);

// Update properties (merged with existing)
feature.updateProperties({
name: 'Updated Name',
description: 'New description',
oldProperty: undefined // This deletes the property
});

setProperties​

Replaces all custom properties on this feature. Removes existing custom properties and replaces them with the provided ones. Internal Geoman properties (prefixed with gm_) are preserved and cannot be removed.

feature.setProperties(properties: Record<string, unknown>): Promise<void>;

Example:

// Get a feature
const feature = gm.features.get('gm_main', featureId);

// Replace all custom properties
feature.setProperties({
name: 'New Name',
category: 'residential'
});
// Previous custom properties are removed, only 'name' and 'category' remain

updateGeometry​

Updates the geometry of this feature with new coordinates.

feature.updateGeometry(geometry: BasicGeometry): Promise<void>;

Example:

// Get a feature
const feature = gm.features.get('gm_main', featureId);

// Update the geometry
feature.updateGeometry({
type: 'Polygon',
coordinates: [
[
[-8.15, 49.44],
[-8.10, 49.44],
[-8.10, 49.40],
[-8.15, 49.40],
[-8.15, 49.44]
]
]
});

delete​

Removes this feature and its associated markers from the map.

feature.delete(): Promise<void>;

convertToPolygon​

Converts circle, ellipse, or rectangle shapes to standard polygon form by removing shape-specific properties. Resolves to true if conversion was successful.

feature.convertToPolygon(): Promise<boolean>;

changeSource​

Moves this feature to a different source.

feature.changeSource({
sourceName: FeatureSourceName;
}): Promise<void>;

Types​

FeatureData​

The main class representing a feature on the map.

class FeatureData {
gm: Geoman;
id: FeatureId;
parent: FeatureData | null;
markers: Map<MarkerId, MarkerData>;
source: BaseSource;

// Getters
get shape(): FeatureShape;
get temporary(): boolean;
get sourceName(): FeatureSourceName;

// Instance methods
getGeoJson(): GeoJsonShapeFeature;
updateProperties(properties: Record<string, unknown>): Promise<void>;
setProperties(properties: Record<string, unknown>): Promise<void>;
updateGeometry(geometry: BasicGeometry): Promise<void>;
delete(): Promise<void>;
convertToPolygon(): Promise<boolean>;
changeSource(options: { sourceName: FeatureSourceName }): Promise<void>;
}

FeatureSourceName​

type FeatureSourceName = 'gm_main' | 'gm_temporary' | 'gm_standby';

Example Usage​

// Import GeoJSON data
const geoJson = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [0, 0]
},
properties: {
shape: 'marker'
}
}
]
};

// Import features (importGeoJson is async)
const result = await gm.features.importGeoJson(geoJson);

// Import with overwrite option (replaces existing features with matching IDs)
const resultWithOverwrite = await gm.features.importGeoJson(geoJson, { overwrite: true });
console.log(`Overwritten: ${resultWithOverwrite.stats.overwritten} features`);

// Iterate over features
gm.features.forEach((feature) => {
console.log(feature.id, feature.shape);
});

// Export features from Geoman's internal state
const exported = gm.features.exportGeoJson();

// Export features directly from MapLibre's source
const exportedFromSource = gm.features.exportGeoJsonFromSource();

// Get features in bounds
const bounds: [ScreenPoint, ScreenPoint] = [[0, 0], [100, 100]];
const featuresInBounds = gm.features.getFeaturesByScreenBounds({
bounds,
sourceNames: ['gm_main']
});

// Working with individual feature instances
const feature = gm.features.get('gm_main', 'feature-id');
if (feature) {
// Update properties (merges with existing) — these methods are async
await feature.updateProperties({
name: 'Updated Feature',
status: 'active'
});

// Replace all properties
await feature.setProperties({
name: 'New Name Only'
});

// Update geometry
await feature.updateGeometry({
type: 'Point',
coordinates: [10, 20]
});

// Delete the feature
// await feature.delete();
}