Introduction
AurOpenlayers is a declarative framework built on top of OpenLayers specifically for Angular applications. It transforms the way you work with maps by shifting from imperative manual updates to a contract-based approach where your business models and the map stay in perfect sync.
Instead of manually creating OpenLayers Feature objects and handling event listeners, you define a Schema that describes how your data should look and behave. The engine handles the rest—rendering, interaction logic, and performance optimizations.
The Declarative Philosophy
In a standard OpenLayers setup, you often find yourself writing "glue code":
- Manually updating geometry when a model changes.
- Writing complex hit-tests for clicks and hovers.
- Managing the lifecycle of layers and clusters.
AurOpenlayers replaces this with a Contract. You define a MapSchema that acts as a single source of truth. When your Angular component updates its data, the map reflects those changes automatically.
Quick Start: Building Your First Map
To get started, you primarily interact with the <mff-map-host> component. Let's look at how to render a simple point that represents a business model.
1. Define Your Model
Start with a standard TypeScript class or interface for your data.
export interface Station {
id: string;
name: string;
coordinates: [number, number]; // [lng, lat]
}
2. Create the Map Configuration
The MapHostConfig is where you define your layers using VectorLayerDescriptor. This descriptor maps your Station model to OpenLayers geometries and styles.
import { MapHostConfig, VectorLayerDescriptor } from 'aur-openlayers';
import { Point } from 'ol/geom';
import { fromLonLat } from 'ol/proj';
import { Style, Circle, Fill, Stroke } from 'ol/style';
const mapConfig: MapHostConfig = {
schema: {
layers: [
{
id: 'stations-layer',
feature: {
// Identify the unique key in your model
id: (model: Station) => model.id,
// Convert model data to geometry
geometry: {
fromModel: (model: Station) => new Point(fromLonLat(model.coordinates)),
},
// Define visual representation
style: {
base: (model: Station) => ({
color: '#3b82f6',
label: model.name
}),
render: (opts) => new Style({
image: new Circle({
radius: 6,
fill: new Fill({ color: opts.color }),
stroke: new Stroke({ color: '#ffffff', width: 2 })
})
})
}
}
}
]
},
view: {
centerLonLat: [37.61, 55.75], // Moscow
zoom: 10
},
osm: true // Use OpenStreetMap as a base layer
};
3. Use the Component in your Template
Pass the configuration and your data to the mff-map-host component.
<!-- app.component.html -->
<mff-map-host
[config]="mapConfig"
(ready)="onMapReady($event)">
</mff-map-host>
// app.component.ts
onMapReady(ctx: MapContext) {
const layerApi = ctx.layers['stations-layer'];
const data: Station[] = [
{ id: '1', name: 'Central Station', coordinates: [37.61, 55.75] }
];
// Set models: the map renders them immediately
layerApi.setModels(data);
}
Core Concepts
To master AurOpenlayers, keep these three pillars in mind:
1. Two-Way Synchronization
The framework doesn't just render data; it can modify it. By defining applyGeometryToModel in your descriptor, interactions like dragging a point on the map will automatically update your TypeScript model objects.
2. Interaction Management
Instead of adding global event listeners to the map, you define interactions (click, hover, translate, modify) directly inside the feature descriptor. This ensures that hit-testing and event propagation follow predictable rules.
3. State-Driven Styling
You can define specific styles for different states, such as HOVER, SELECTED, or DRAG. The framework manages the transition between these styles automatically when a user interacts with the feature.
style: {
base: () => ({ color: 'blue' }),
states: {
HOVER: () => ({ color: 'red' }),
SELECTED: () => ({ color: 'green' })
}
}
Next Steps
- Explore Interactions: Learn how to enable dragging and clicking in the Interactions Guide.
- Layer Management: Discover how to handle clustering and multiple layers in the Layers Walkthrough.
- Advanced Styling: See how to create dynamic LOD (Level of Detail) styles in the Styling Tutorial.