You approach is possible, but very inefficient. I would heavily advice to create an atlas (see my other solution). However, just to answer your question and show a way to solve your problem with the approach you tried. There are in fact two problems with what you tried:

CRS issue
Use the same CRS for the project and the layer(s) you use to get the intersection. You had EPSG:32629
as project CRS (used also for your layout), but EPSG:3763
for the layer Cont_AAD_CAOP2021
. Reproject the layer to the project CRS, then intersection will work.
Expression/syntax
Now use the following expression - see below for explanation:
array_max(
array_foreach (
aggregate( 'Cont_AAD_CAOP2021', 'array_agg', $id),
if(
intersects (
map_get (item_variables('Map 1'), 'map_extent_center'),
geometry (get_feature_by_id ('Cont_AAD_CAOP2021', @element))
),
attribute (
get_feature_by_id ('Cont_AAD_CAOP2021', @element),
'Concelho'
),
''
)
))
Explanation:
The correct syntax to get the center of the current layout page is: map_get (item_variables ('Map 1'), 'map_extent_center')
, see item_variables()
and map_get()
.
Instead of aggregate/concatenate the names of the attribute "Concelho"
and filtering by intersection, rather use aggregate/array_agg
to get an array of all id's of the layer, then use get_feature_by_id ()
and geometry()
to get an array of the geometries from the layer. With array-foreach()
an an if()
clause then test if these geometries intersect with the center of the layout (step 2).
For the geometry that returns true (intersects with the center of the current layout), get the value of the field Concelho
using attribute()
.
Use array_max()
to get rid of the empty values and keep only the value of the field Concelho
that indeed intersects the layout's center.