2

I am new to QGIS.

When I export my file to KML and open it in Google Earth, the balloon for each shapefile shows up by default in a basic white table. Installing the MMGIS plugin changes the export formatting, but what I'm really looking for is an end result that looks like this with the blue and white rows:

enter image description here

I need to be able to change this prior to export - changing the coding in each shapefile after the fact is not going to be feasible. I am starting to be concerned that this only appears if you're using ArcGIS (which is not an option).

Could you let me know what am I missing, and can you help me get this result (or something similar)?

2 Answers 2

5
+50

You could use the QGIS field calculator to add a column with an expression to build the HTML you want for the popup.

We can take @öbl's html and convert it to a field calculator expression:

'<table>
    <tr style=''background-color:#9DBBE0''>
       <th colspan=''2''>'|| "AMA_NAME"|| '</th>
    </tr>
    <tr style=''background-color:#ffffff''>
       <td>FID</td>
    <td> '|| "FID"||' </td>
    </tr>
    <tr style=''background-color:#9DBBE0''>
       <td>AMA_NAME</td>
       <td>'||  "AMA_NAME"  ||'</td>
    </tr>
</table>'

enter image description here

Note the double quotes surrounding the html properties need to be changed to pairs of single quotes, because the field calculator uses double quotes to identify field names.

When you export as KML you choose the calculated column for the "DescriptionField" and the AMA_Name for the "NameField". enter image description here

I don't have the same data as you, but here is an example of the type of thing you should see in Google Earth:

enter image description here

Edit: Here is a custom function for the field calculator to build the HTML table for you so you don't have to do the concatenation by hand. (Its my first attempt at a custom function, I would have liked to make the second and third arguments optional and to pass them in as python lists instead of strings - that was how it worked in the python console, but I couldn't get it to work that way as a custom function)

#Sample custom function file
 #(uncomment to use and customize or Add button to create a new file) 
from qgis.core import *
from qgis.gui import *

@qgsfunction(args='auto', group='Custom')
def KMLDescription(titleField,columns,labels,feature,parent):
    """
    <h2>KMLDescription</h2>
    Function to concatenate columns into HTML table for KML export or HTML label in QGIS
    <h2>Syntax</h2>
    KMLDescription ( titleField, columns, labels )
    <h2>Arguments</h2>
        <ul>
    <li> titleField: string, the name of the column containing the value to show in the table header</li>
    <li> columns: string, comma separated list of attributes to include in the table rows <br/>
    <b> Use asterisk: '*' to include all columns</br></li>
    <li> labels: string, comma separated list of descriptions as a user friendly alternative to the attribute names <br/>
    <b> Use asterisk: '*' if you just want to use attribute names</b></li>
</ul>
    <h2>Examples</h2>
    <ul>
    <li> KMLDescription ( 'Site Name', '*', '*' )</li>
    <li> KMLDescription ( 'Site Name', 'RESP_UNIT,LAST_INSP', '*' )</li>
    <li> KMLDescription ( 'Site Name', 'RESP_UNIT,LAST_INSP', 'Responsible Unit,Last Inspection Date' )</li>
</ul>
    """
    #layer=iface.activeLayer()
    #f=layer.selectedFeatures()[0]
    fields=feature.fields()
    oddRowColour='#9DBBE0'
    evenRowColour='#ffffff'
    backColour=oddRowColour
    #titleField=args[0]
    if (columns=='*'):
        columns=fields.names()
    else:
        columns=columns.split(',')
    if (labels=='*'):
        labels=columns
    else:
        labels=labels.split(',')
    headerRow='<tr style="background-color:{0}">'\
                '<th colspan="2">{1}</th>'\
                '</tr>'
    dataRow='<tr style="background-color:{0}">'\
                '<td>{1}</td>'\
                '<td>{2}</td>'\
                '</tr>'
    html='<table>'
    html +=headerRow.format(backColour,str(feature[titleField]))
    for idx, fld in enumerate(columns):
        backColour = evenRowColour if backColour == oddRowColour else oddRowColour
        html+=dataRow.format(backColour,labels[idx], str(feature[fld]))
     
    html+='</table>'
    return(html)

enter image description here

3
  • Very cool solution! Commented Nov 8, 2021 at 8:21
  • Will try it tomorrow at work!
    – Opazo
    Commented Nov 11, 2021 at 16:04
  • Thanks, see my update with a custom function - its a bit clunky and not thoroughly tested, but might be useful.
    – M Bain
    Commented Nov 11, 2021 at 23:00
3

KML uses HTML syntax for styling the popup. Whatever is in the <description></description> tag is displayed when clicking a Placemark. Have a look into the KML Reference.

Unfortunately I am not aware of any plugin in QGIS which enables to specify the table style. You could try to write a script that postprocesses the KML after creation.

Here is a simple sample with blue and white table rows. If you want it to look the same as in your screenshot more styling needs to be applied:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2">
    <Document id="11">
        <Folder id="3">
            <Style id="0">
                <LineStyle id="1">
                    <color>ff232323</color>
                    <colorMode>normal</colorMode>
                    <width>0.52</width>
                </LineStyle>
                <PolyStyle id="2">
                    <color>ff8f8b7d</color>
                    <colorMode>normal</colorMode>
                    <fill>1</fill>
                    <outline>1</outline>
                </PolyStyle>
            </Style>
            <name>layer2</name>
            <Placemark id="5">
                <description>
                    <![CDATA[
                        <table>
                        <tr style="background-color:#9DBBE0">
                            <td colspan="2">Alexander Creek</td>
                        </tr>
                        <tr style="background-color:#ffffff">
                            <td>FID</td>
                            <td>$[FID]</td>
                        </tr>
                        <tr style="background-color:#9DBBE0">
                            <td>AMA_NAME</td>
                            <td>$[AMA_NAME]</td>
                        </tr>
                        </table>
                    ]]>
                </description>
                <styleUrl>#0</styleUrl>
                <ExtendedData>
                    <Data name="FID">
                        <value>4</value>
                        <displayName>FID</displayName>
                    </Data>
                    <Data name="AMA_NAME">
                        <value>Alexander Creek</value>
                        <displayName>AMA_NAME</displayName>
                    </Data>
                </ExtendedData>
                <Polygon id="4">
                    <altitudeMode>clampToGround</altitudeMode>
                    <outerBoundaryIs>
                        <LinearRing id="8">
                            <coordinates>13.261202830189648,47.333742988506444,0.0 14.487028299095272,47.333742988506444,0.0 14.487028299095272,48.05380916001477,0.0 13.261202830189648,48.05380916001477,0.0 13.261202830189648,47.333742988506444,0.0</coordinates>
                        </LinearRing>
                    </outerBoundaryIs>
                </Polygon>
            </Placemark>
        </Folder>
    </Document>
</kml>

Popup:

enter image description here

1
  • I came to the same conclusion! I am indeed in mid process of writing a script to style QGis KML files... Kinda messy because I never wrote anything in html or xml or whatever its called... If I can wrap it up i will post it
    – Opazo
    Commented Nov 6, 2021 at 10:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.