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 point column 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 polygon column 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 (point and polygon):

- 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

Snippet 1JSON
{
  "archetypes": {
    "map": {
      "advancedFilter": false,
      "center": {
        "lat": 39.8283,
        "lng": -98.5795
  • advancedFilter: when true, shows the wuic-filter-bar for the map archetype (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 over markerColorField and markerContentCallback.
  • markerColorField: name of the record field that contains a CSS color (#rrggbb); the marker is rendered as a colored PinElement. Ignored when customMarkerImageSrcField is 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):

Snippet 2SQL
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 URL

Column metadata:

Columnmc_ui_column_typevoa_classNotes
colore_markercolor1native color picker (#rrggbb)
svg_markertxt_area1inline SVG or URL — optional, overrides the color

Map archetype propsbag on the route that renders the mezzi:

Snippet 3JSON
{
  "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_marker and colore_marker = '#16a34a' → marker = green PinElement.
  • 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

Snippet 4JSON
{
  "archetypes": {
    "map": {
      "advancedFilter": true,
      "polyline": {
        "enabled": true,
        "groupByField": "mezzo_id",

All polyline options

  • enabled: enables the polyline overlay (default false).
  • 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: if true and colorField is 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: if true, 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: if false, also hides the last-in-group marker (default

true — one marker per group).

  • showWaypointDots: if true, 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 (default 8).
  • travelMode: travel mode for snapToRoads (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:

Snippet 5SQL
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;
Snippet 6JSON
{
  "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 with rowData.record when 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:

Snippet 7ts
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:

Snippet 8HTML
<wuic-map-list
  [hardcodedDatasource]="citiesDs"
  (onMapClick)="handleMapClick($event)"
  (onMarkerClick)="handleMarkerClick($event)"
  (onMarkerDragStart)="handleMarkerDragStart($event)"
  (onMarkerDragEnd)="handleMarkerDragEnd($event)"
  (onPolygonClick)="handlePolygonClick($event)"

Subscribe example (ViewChild):

Snippet 9ts
@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:

Snippet 10ts
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

map-list / manual-map-01
map-list / manual-map-01
map-list / manual-map-02
map-list / manual-map-02
map-list / map-list-main
map-list / map-list-main
Map list - marker
Map list - marker
Map list - poligoni
Map list - poligoni