I am creating a layout of map using QGIS 3.10
I want to show attribute table with each point logo in table.
I have a field which has the complete path to each logo and this field is already being used in symbology to show each respective college logo.e.g. in below picture attribute table is shown and in pic_path
column instead of actual path I want logo to be shown.
1 Answer 1
This might work for you. It requires the image to be accessed through a local server (not difficult) rather than by path and filename as I can't find a way to get QGIS to access the images files directly. Maybe someone else can suggest a way.
This solution uses a workaround so that the images are displayed in a HTML frame rather than in a table item. You build the HTML code through a virtual field in the layer which will hold HTML table-row code for each feature.
Then the HTML code is aggregated in the HTML frame source for all features that are visible.
QGIS version 3.30 used.
1) Create and run a local server e.g. with jupyter to serve images. This example is on port 8000.
2) With the polygon layer, add a virtual field with this expression that will generate the html code;
Here is the expression:
'<tr><td>' || "pic_path" || '</td><td><img src="http://localhost:8000/' || file_name("pic_path") || '" alt="Image" style="max-width:100px;max-height:100px;" /></td></tr>'
3) Add a HTML frame to the print layout with this code:
HTML Frame properties: enter image description here
HTML Source:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
table {
width: 100%;
border-collapse: collapse;
}
table, th, td {
border: 1px solid black;
}
th, td {
padding: 8px;
text-align: left;
}
</style>
</head>
<body>
<h1>Features currently visible on theMap</h1>
<table>
<thead>
<tr>
<th>pic_path</th>
<th>Image</th>
</tr>
</thead>
<tbody>
[%
aggregate(
layer:='poly1',
aggregate:='concatenate',
expression:="html_pic_path",
concatenator:=' ',
filter:= intersects(@geometry,map_get(item_variables('theMap'),'map_extent'))
)
%]
</tbody>
</table>
</body>
</html>
The important part is the aggregate expression that retrieves the html code from the virtual field in layer poly1's virtual field and filters so that only those features on the layout map item (in this example called theMap) are displayed in the HTML frame:
aggregate(
layer:='poly1',
aggregate:='concatenate',
expression:="html_pic_path",
concatenator:=' ',
filter:= intersects(@geometry,map_get(item_variables('theMap'),'map_extent'))
)
If you want to show all features, just remove the filter.
Here is some example output:
Print layout where all features are displayed:
Print layout - zoomed in on 3 features enter image description here
Important: If you change the extent of the map, you need to refresh the HTML.
-
But QGIS is able to access files on local??? In the preview (of the expression builder), I can see them!!katagena– katagena2024年09月27日 15:06:54 +00:00Commented Sep 27, 2024 at 15:06
-
Ok, using an HTML frame, it works, but it is « very » complicated for a simple task!!!katagena– katagena2024年09月27日 15:07:51 +00:00Commented Sep 27, 2024 at 15:07
-
1I agree, but I can't see a way to format with HTML within a table object.Aquamarine– Aquamarine2024年09月27日 15:46:44 +00:00Commented Sep 27, 2024 at 15:46
-
Your html formula has only the expression with ´html_pic_path’... but your html table has also the column with ´pic_path’! How do you do that?katagena– katagena2024年09月27日 17:35:34 +00:00Commented Sep 27, 2024 at 17:35
-
1The virtual field ("html_pic_path") formula determines how many fields are displayed in the HTML frame. The aggregate on html_pic_path concatenates the code for each feature in the map extent.Aquamarine– Aquamarine2024年09月27日 22:16:00 +00:00Commented Sep 27, 2024 at 22:16
Explore related questions
See similar questions with these tags.
'<img src="'|| "pic_path" ||'" />'
and set the police with HTML format, but it doesn't do anything.