Overview
Map List
Geographic visualization with markers, clusters, boundary filters, and custom marker templates.
Screenshot reference (user manual)
manual__map__01.png: route map overview with toolbar, markers, and clustering.manual__map__02.png: advanced map archetype configuration (center/zoom/fields/info/template).
Use cases
- Asset geo-localization.
- Tracking of geolocated events.
- Heatmaps or territorial aggregations.
Behavior difference: point vs polygon
The map automatically adapts rendering and interactions based on the metadata fields with mc_ui_column_type.
- If at least one
pointcolumn is present:
- each record is rendered as a marker (map-advanced-marker);
- it supports clustering (useClusterer);
- it supports marker drag (when enabled from the toolbar);
- a click on a marker opens an infoWindow with titleField/infoField and template.
- If a
polygoncolumn is present:
- each record is rendered as a polygon (map-polygon);
- it does not use the marker clusterer;
- the boundaries filter can also use the polygonal geometry;
- a click on a polygon opens the same infoWindow as the markers (positioned at the clicked point or, as a fallback, at the geometric center).
- If both are present (
pointandpolygon):
- the component can display both layers;
- the toolbar favors the actions consistent with the primary type (marker drag on marker scenarios, edit polygons on polygon-only scenarios);
- the maparea filter uses the first available geographic field among point/polygon.
Operational notes
Make sure the coordinate fields are correctly mapped in the column metadata.
md_props_bag: archetypes.map
{
"archetypes": {
"map": {
"advancedFilter": false,
"center": {
"lat": 39.8283,
"lng": -98.5795advancedFilter: whentrue, shows thewuic-filter-barfor themaparchetype (at the data-repeater level).zoom: initial zoom.center.lat/center.lng: initial map center; if missing, the component's default behavior is used.minZoom/maxZoom: zoom limits.useCurrentLocation: uses browser geolocation as the center.useClusterer: enables marker clustering.filterByBoundaries: filters the visible records based on the current bounding box.titleField: metadata field used as the marker title.infoField: metadata field used as the marker base info.customMarkerImageSrc: fixed marker URL (image or inline SVG applied to all markers).customMarkerImageSrcField: name of the record field that contains an image URL or inline SVG (<svg ...>...</svg>); format is auto-detected. Wins overmarkerColorFieldandmarkerContentCallback.markerColorField: name of the record field that contains a CSS color (#rrggbb); the marker is rendered as a coloredPinElement. Ignored whencustomMarkerImageSrcFieldis set for that record (the image takes precedence).markerContentCallback: JS callback for marker content.infoFunction: JS callback for info window rendering. (Alternative to itemTemplateString)itemTemplateString: custom content template. (Alternative to infoFunction)polyline: polyline overlay for GPS route tracking — see the dedicated section below.
Per-record marker customization (color + image/SVG)
The map archetype lets you **customize each marker based on the data of the
individual record** without writing JS callbacks, by configuring the record
fields directly from the mdpropsbag.
Marker rendering priority
The framework resolves the marker content in this order (first match wins):
1. `customMarkerImageSrcField` — record field with an image URL or inline SVG.
Auto-detect: if the string starts with <svg, it is wrapped in a <div> as
AdvancedMarker content; otherwise it is placed in an <img src>.
2. `customMarkerImageSrc` — fixed image/SVG applied to all.
3. `markerColorField` — per-record CSS color, rendered as a PinElement
(standard colored Google Maps pin).
4. `markerContentCallback` — user-supplied JS callback (receives record).
Example: colore_marker + svg_marker fields on the mezzi table
Data DB schema (extract):
ALTER TABLE dbo.mezzi ADD colore_marker NVARCHAR(7) NULL; -- e.g. '#dc2626'
ALTER TABLE dbo.mezzi ADD svg_marker NVARCHAR(MAX) NULL; -- inline SVG or URLColumn metadata:
| Column | mc_ui_column_type | voa_class | Notes |
|---|---|---|---|
colore_marker | color | 1 | native color picker (#rrggbb) |
svg_marker | txt_area | 1 | inline SVG or URL — optional, overrides the color |
Map archetype propsbag on the route that renders the mezzi:
{
"archetypes": {
"map": {
"markerColorField": "colore_marker",
"customMarkerImageSrcField": "svg_marker"
}
}Runtime behavior:
- record with
svg_marker = '<svg ...>...</svg>'→ marker = inline SVG (overrides the color). - record with
svg_marker = 'https://.../truck.png'→ marker =<img>with that URL. - record with empty
svg_markerandcolore_marker = '#16a34a'→ marker = greenPinElement. - record with both empty → default Google Maps marker.
Polyline overlay (GPS route tracking)
The map archetype can render one polyline per group of records
(e.g. the historized GPS track of a vehicle for a day) by reading the
coordinates from the existing point column on the route, grouping the records
by a field (groupByField) and ordering them by a temporal field
(orderByField).
When polyline.enabled=true, the map does NOT render a marker for each
record: only one marker per group, positioned at the **latest temporal
point** (the most recent one). All other records are represented as
polyline nodes.
Minimal configuration
{
"archetypes": {
"map": {
"advancedFilter": true,
"polyline": {
"enabled": true,
"groupByField": "mezzo_id",All polyline options
enabled: enables the polyline overlay (defaultfalse).groupByField: record field to group the records into distinct polylines
(e.g. mezzo_id, tracking_session_id). If omitted, all records end up
in a single global polyline.
orderByField: record field to order the points within each group
(e.g. timestamp_pos). If omitted, arrival order is used.
pointField: record field from which to read{lat,lng}. Default:
auto-detect of the first column with mc_ui_column_type='point' in the
metaInfo (the same one the map-list uses for normal markers).
colorField: record field with a per-group polyline color (CSS#rrggbb).
The color is read from the first record of the group (assumes homogeneity).
Overrides strokeColorByGroup and strokeColor. Typical use-case: bring
the colore_marker configured on the lookup entity (e.g. mezzi) into view.
strokeColor: fixed polyline color (default#1d4ed8). Used only if
colorField does not resolve and strokeColorByGroup=false.
strokeColorByGroup: iftrueandcolorFieldis not set, each group
receives a distinct color from an internal palette (8 colors).
strokeWeight: stroke thickness in px (default 4).strokeOpacity: opacity 0..1 (default 0.85).snapToRoads: iftrue, the polyline is snapped to the real roads via
the Google Maps Routes API (Route.computeRoutes, with automatic fallback
to the legacy DirectionsService if the routes library is not loaded).
Requires "Routes API" enabled on the key in the Google Cloud Console.
The call is chunked to 25 waypoints per request (Routes API limit).
showMarkers: iffalse, also hides the last-in-group marker (default
true — one marker per group).
showWaypointDots: iftrue, draws a<map-circle>(geographic
circle) on each original waypoint of the record. Useful to visually
distinguish the GPS points historized in the DB from the
interpolated/snapped path.
waypointDotRadius: dot radius in meters (default8).travelMode: travel mode forsnapToRoads(DRIVING/WALKING/
BICYCLING). For city trips with waypoints in restricted-traffic/pedestrian
zones, prefer WALKING (DRIVING often gives no results in the Italian
historic city center).
Combining polyline color + marker color from the same column
If the entity table (e.g. mezzi) already has a colore_marker field,
configure the same field for both the marker and the polyline by bringing
that field into the source view:
CREATE VIEW vw_mezzi_posizioni_giorno AS
SELECT p.*, m.colore_marker, m.svg_marker, ...
FROM dbo.mezzi_posizioni p JOIN dbo.mezzi m ON m.id = p.mezzo_id;{
"archetypes": {
"map": {
"markerColorField": "colore_marker",
"customMarkerImageSrcField": "svg_marker",
"polyline": {
"enabled": true,Each vehicle will have a marker, polyline, and dots of the same color configured on the
mezzi record (the user edits it from the master data and it propagates everywhere).
For the vehicle with svg_marker set, the marker will be the custom icon
(inline SVG or image URL) and the color will still be used for the
polyline + dots.
Template context (itemTemplateString)
The following inputs are available in the custom template:
record: current record (in the map archetype it coincides withrowData.recordwhen present).rowData: current marker/polygon event payload.metaInfo: table/column metadata of the datasource.datasource: reference to the associated datasource component.
Runtime context used by the framework:
inputs: { record: item, rowData: item, metaInfo: metaInfo, datasource: datasource }Events and subscriptions (host)
Events available on wuic-map-list:
onMapClick: click on the map (google-map mapClick).onMarkerClick: click on a marker.onMarkerDragStart: marker drag start.onMarkerDragEnd: marker drag end (with final position).onPolygonClick: click on a polygon.onPolygonShapeChangedEvent: shape changed on a polygon in edit mode.onMapDataBound: emitted when the wrapper completes data binding from the datasource.
Template example:
<wuic-map-list
[hardcodedDatasource]="citiesDs"
(onMapClick)="handleMapClick($event)"
(onMarkerClick)="handleMarkerClick($event)"
(onMarkerDragStart)="handleMarkerDragStart($event)"
(onMarkerDragEnd)="handleMarkerDragEnd($event)"
(onPolygonClick)="handlePolygonClick($event)"Subscribe example (ViewChild):
@ViewChild(MapListComponent) mapList?: MapListComponent;
private readonly subs = new Subscription();
ngAfterViewInit(): void {
if (!this.mapList) return;
this.subs.add(this.mapList.onMapClick.subscribe((e) => console.log(e)));
this.subs.add(this.mapList.onMarkerClick.subscribe((e) => console.log(e)));<!-- import-and-mount -->
Import and mount (Angular component)
Import MapListComponent from 'wuic-framework-lib' and mount it with the framework DataSource:
import { DataSourceComponent, MapListComponent } from 'wuic-framework-lib';
@Component({
selector: 'app-esempio',
imports: [DataSourceComponent, MapListComponent],
template: `
<wuic-data-source #ds [hardcodedRoute]="'<route>'" [autoload]="true"></wuic-data-source>EXACT names (wuic-framework-lib barrel): class MapListComponent, selector <wuic-map-list>. Import that class, not invented variants (e.g. a Lazy prefix where there is none, or vice versa) → otherwise the build fails with has no exported member.
Metadata-driven config: the tag accepts ONLY the standard inputs [hardcodedRoute], [hardcodedDatasource], [autoload], [hideToolbar]. The specific configuration (here: the location/coordinate field) is NOT an HTML input ([groupField], [type], … give NG8002 not a known property) → it goes in the metadata (md_props_bag/archetype) or in-code via metaInfo.
Screenshot




