Hey Mayca
I have an example here that uses a map in a frame in a layout and adds legends for all the layers.
The legend is created at the top-left of the frame, inside the map window. You can change this to start anywhere you prefer.
You can grab the frame ID of the frame with the map after creating this, and from this, get the map ID.
Include "MapBasic.Def"
Declare Sub Main
Sub Main
Dim nLayer, nMapWID, nLayoutWID, nLegendWID, nMapFrameID, nNumLayers As Integer
Dim fFrameX, fFrameY, fFramePositionY, fFrameWidth, fFrameHeight, fLegendWidth, fLegendWidthMax As Float
Dim sLayerAlias As String
nLayoutWID = FrontWindow()
If nLayoutWID = 0 Then
Note "Please open a layout window!"
Exit Sub
End If
If not WindowInfo(nLayoutWID, WIN_INFO_TYPE) = WIN_LAYOUT_DESIGNER Then
Note "Please make a layout window the active window!"
Exit Sub
End If
nMapFrameID = LayoutItemID(nLayoutWID, "", LAYOUT_ITEM_TYPE_MAPPER)
If nMapFrameID = -1 Then
Note "The frame with the map not found."
Exit Sub
End If
Set Paper Units "in"
Set CoordSys Layout Units "in"
nMapWID = LayoutItemInfo(nLayoutWID, nMapFrameID, LAYOUT_ITEM_INFO_WIN)
fFrameX = LayoutItemInfo(nLayoutWID, nMapFrameID, LAYOUT_ITEM_INFO_POS_X)
fFrameY = LayoutItemInfo(nLayoutWID, nMapFrameID, LAYOUT_ITEM_INFO_POS_Y)
fFrameWidth = LayoutItemInfo(nLayoutWID, nMapFrameID, LAYOUT_ITEM_INFO_WIDTH)
fFrameHeight = LayoutItemInfo(nLayoutWID, nMapFrameID, LAYOUT_ITEM_INFO_HEIGHT)
fFramePositionY = fFrameY
nNumLayers = MapperInfo(nMapWID, MAPPER_INFO_LAYERS)
For nLayer = 1 to nNumLayers
If LayerInfo(nMapWID, nLayer, LAYER_INFO_TYPE) In (LAYER_INFO_TYPE_NORMAL, LAYER_INFO_TYPE_THEMATIC) Then
sLayerAlias = LayerInfo(nMapWID, nLayer, LAYER_INFO_ALIAS)
Print nLayer & ". Layer Alias: " & sLayerAlias
'Create Designer Legend
' From Window 3018
' Portrait
' Default Frame Style "Stores" Font ("Arial",0,8,0)
' Frame
' From Layer 1 Using column object label default
If nLegendWID = 0 Then
Create Designer Legend
From Window nMapWID
Default Frame Style "#" Font ("Arial",0,8,0)
Custom
Frame From Layer nLayer
Position (fFrameX, fFramePositionY) Units "in"
Using Column Object Label default
nLegendWID = LayoutItemInfo(nLayoutWID, LayoutInfo(nLayoutWID, LAYOUT_INFO_NUM_ITEMS), LAYOUT_ITEM_INFO_LEGEND_DESIGNER_WINDOW)
Else
Add Designer Frame
Window nLegendWID
Custom
Frame From Layer nLayer
Position (fFrameX, fFramePositionY) Units "in"
Using Column Object Label default
End If
fFramePositionY = fFramePositionY + LayoutItemInfo(nLayoutWID, LayoutInfo(nLayoutWID, LAYOUT_INFO_NUM_ITEMS), LAYOUT_ITEM_INFO_HEIGHT)
fLegendWidth = LayoutItemInfo(nLayoutWID, LayoutInfo(nLayoutWID, LAYOUT_INFO_NUM_ITEMS), LAYOUT_ITEM_INFO_WIDTH)
fLegendWidthMax = Maximum(fLegendWidthMax, fLegendWidth)
print nLayer & ". Max Legend width: " & fLegendWidthMax & " in"
End If
Next 'nLayer
print ("Created Legend...creating frame")
' // Create frame to sit behind legend and create white space
Create Rect (fFrameX, fFrameY) (fFrameX + fLegendWidthMax, fFramePositionY)
Pen (1,2,0)
Brush (2,16777215,16777215)
Priority 1
print ("Collected layer/map info")
End Sub
------------------------------
Peter Horsbøll Møller
Principal Presales Consultant | Distinguished Engineer
Precisely | Trust in Data
------------------------------
Original Message:
Sent: 02-25-2026 03:09
From: Mayca González Pérez
Subject: MapBasic Monday: Add thematic legend to a Layout / Presentation programmatically
Hi everyone,
I'm working with MapBasic and I'm generating a thematic map (Shade) on an already opened Map window. After creating the thematic layer, I create a Layout (presentation) by code and I want to automatically add the corresponding legend into the Layout as a legend frame/object.
Right now, I can:
detect the active/open Map window (the one the user is viewing),
create/apply the thematic mapping by Run Command (e.g. Shade window ...),
create a Layout and place map frames/text frames.
What I'm missing is the "best practice" / correct MapBasic approach to:
create (or reference) the thematic legend for the active Map window, and
insert that legend into the Layout as a legend frame (positioned and sized programmatically).
Questions:
Is there a recommended MapBasic sequence to generate the legend object for a thematic layer and place it in a Layout?
Do I need to create a separate Legend window first, and then copy/insert it into the Layout, or can the legend frame be created directly in the Layout referencing the Map window/layer?
Which MapBasic statements/functions are typically used for this (e.g., Create Legend, Set Legend, Add Frame, Create Map Frame, etc.)?
If useful, I'm currently creating the thematic map with something like:
Then I create the Layout and frames. I just don't know the proper way to attach the legend of that thematic to the layout automatically.
Any sample code or guidance would be greatly appreciated (especially how to reference the correct map/layer and ensure the legend matches the current thematic).
Thanks!
Sub TEMATICO_INFRAESTR_VIARIAOnError GoTo errorTematicoViaria'1) Cargar configuración guardada'2) Cargar parámetros geométricos'3) Crear layout con tamaño correcto'4) Aplicar formato impresora'5) Insertar frames usando coordenadas parametrizadasDim nMapID, nMapIDInLayout, nLayoutID, nLegendID, i As IntegerDim strStatement, cmdstr, str_tit_principal, str_tit_leyenda as stringstrTitulo = "MUNICIPIO: "+gblNOMBRE_MUNICIPIO+chr$(13)+"NÚCLEO:"+gblNOMBRE_NUCLEOCall CARGAR_PARAM_TEMATICOS'Set Printer Name gblThematicPrinter''##### ASIGNANDO NOMBRE DEL MUNICIPIO ENCUESTADO Y RUTA DE ARCHIVOS ###############Call TEMATICO_CARGAR_PARAMETROSstr_tit_principal = WindowInfo(FrontWindow(), WIN_INFO_NAME)'**Let's find a map window to insertFor i = 1 To NumWindows() If WindowInfo(WindowID(i), WIN_INFO_TYPE) = WIN_MAPPER Then nMapID = WindowID(i) Exit For End IfNextPrint "Map: " & WindowInfo(nMapID, WIN_INFO_NAME)Dim strMapName As StringDim strMunicipio As StringDim strNucleo As StringDim strTematico As StringDim posGuion As IntegerDim posAsterisco As IntegerstrMapName = WindowInfo(nMapID, WIN_INFO_NAME)posGuion = InStr(1, strMapName, " - ")posAsterisco = InStr(1, strMapName, "*")If posGuion > 0 Then strMunicipio = Left$(strMapName, Len(posGuion) - 1)End IfIf posAsterisco > 0 Then strNucleo = Mid$(strMapName, posGuion + 3, posAsterisco - (Len(posGuion) + 3)) strTematico = Mid$(strMapName, posAsterisco + 1, Len(strMapName) - posAsterisco)End If'Create Layout windowLayout Designer Position (0.0,0.0) Units "in" Width pWidth Height pHeight Units "in"nLayoutID = FrontWindow()i_layout_id = FrontWindow()Set Layout Window nLayoutID Extents To Fit Zoom 100Set CoordSys Layout Units "in"Set Paper Units "In"Call TEMATICO_FORMATO_IMPRIMIR_PAPEL Dim ancho As FloatDim alto As Floatancho = LayoutInfo(nLayoutID, LAYOUT_INFO_WIDTH)alto = LayoutInfo(nLayoutID, LAYOUT_INFO_HEIGHT)Dim margen As FloatDim franja As FloatDim banda As Floatmargen = ancho * 0.03 ' 3% margenfranja = ancho * 0.18 ' 18% franja derechabanda = alto * 0.10 ' 10% banda superior'Insert Map into LayoutCreate Frame Into Window nLayoutID (margen, margen) (ancho-franja, alto-banda) 'Pen (1,2,0) Brush (2, 16777215, 16777215) From Window nMapID FillFrame OnnMapIDInLayout = WindowID(0)num_win_principal = nMapIDCall TEMATICO_CAPAS_AUXILIARESDim colX1 As FloatDim colX2 As FloatDim zonaY1 As FloatDim zonaY2 As FloatDim bloqueAltura As FloatDim logoY1 As FloatDim logoY2 As FloatDim textoY1 As FloatDim textoY2 As FloatlogoY1 = zonaY1logoY2 = zonaY2 - 2*bloqueAlturatextoY1 = logoY2textoY2 = logoY2 + (bloqueAltura * 0.40)colX1 = ancho - franja + margen/2colX2 = ancho - margen/2zonaY1 = margenzonaY2 = alto - bandabloqueAltura = (zonaY2 - zonaY1) / 3Dim alturaTotal As FloatDim hLoc As FloatDim hNorte As FloatDim hLogo As FloatDim hTexto As FloatcolX1 = ancho - franja + margen/2colX2 = ancho - margen/2zonaY1 = margenzonaY2 = alto - bandaalturaTotal = zonaY2 - zonaY1hLoc = alturaTotal * 0.35hNorte = alturaTotal * 0.20hLogo = alturaTotal * 0.25hTexto = alturaTotal * 0.20Dim yActual As FloatyActual = zonaY2'LOCALIZACIÓN'Create Frame Into Window nLayoutID (colX1, zonaY2 - 2*bloqueAltura) (colX2, zonaY2)Create Frame Into Window nLayoutID (colX1, yActual - hLoc) (colX2, yActual) Pen (1,2,0) Brush (2,16777215,16777215) From Window num_win_localizacion FillFrame OnyActual = yActual - hLoc'NORTE'Create Frame Into Window nLayoutID (colX1, zonaY2 - 2*bloqueAltura) (colX2, zonaY2 - bloqueAltura)Create Frame Into Window nLayoutID (colX1, yActual - hNorte) (colX2, yActual) Pen (1,2,0) Brush (2,16777215,16777215) From Window num_win_norte FillFrame OnyActual = yActual - hNorte'LOGO'Create Frame Into Window nLayoutID (colX1, zonaY1) (colX2, zonaY2 - 2*bloqueAltura)Create Frame Into Window nLayoutID (colX1, yActual - hLogo) (colX2, yActual) Pen (1,2,0) Brush (2,16777215,16777215) From Window num_win_logo FillFrame OnyActual = yActual - hLogo 'MUNICIPIOCreate Rect Into Window nLayoutID (colX1, zonaY1) (colX2, yActual) Pen (1,2,0) Brush (2,16777215,16777215) Create Text Into Window nLayoutID "MAPA TEMÁTICO: " + UCase$(strTematico) + Chr$(13) + Chr$(13) + "MUNICIPIO: " + gblNOMBRE_MUNICIPIO + Chr$(13) + "NÚCLEO: " + gblNOMBRE_NUCLEO (colX1, zonaY1) (colX2, yActual) Font ("Arial",1,9,1) Justify Center 'Set Map Window nMapIDInLayout Zoom Entire Layer SelectionIf WindowInfo(nMapIDInLayout, WIN_INFO_TYPE) <> WIN_MAPPER Then Note "La ventana activa no es un mapa" Exit SubEnd IfDONE: Exit SuberrorTematicoViaria: Note "ERROR:" + Chr$(13) + Error$() Exit SubEnd Sub
------------------------------
Mayca González Pérez
COMUNIDAD. AUT. REG MURCIA
------------------------------