<placemark_name_template>

Abstract

Learn to configure the <placemark_name_template> element for Pull Reports™ Ad Hoc report and data service software.


Table of Contents

Catalog Configuration Java API reference:  KmlConfiguration

In KML viewers such as Google Earth, KML <Placemarks> are labeled via their child <name> element. Use the <placemark_name_template> element to customize the Placemark <name> per Export Report REST API result row with values unique to the row.

The body of a <placemark_name_template> is a template which may include one or more column resource paths surrounded by dollar sign curly bracket (${...}) notation. When exported via the Export Report REST API, each row's actual column value is substituted for the respective column resource paths within ${...} to form the KML Placemark name for that row. The column resource paths within a <placemark_name_template> may only reference columns within the report's base table.

<placemark_name_template>: behind the scenes

<placemark_name_template> values are processed into Groovy GStrings and filled by the Groovy SimpleTemplateEngine for each row of results in the kml format export results.

However, since column resource paths within ${...} expressions are not valid Groovy variable names, each ${...} expression within the template is transformed in two steps:

  1. Column resource paths to base table columns which contain the table id are simplified to only refer to the column id. For example: ${/baseTableId@columnId} becomes ${@columnId}

  2. All column id references have their @ character substituted with two underscore (__) characters. For example: ${@columnId} becomes ${__columnId}

In this way, a <placemark_name_template> of

${/account@id}: ${@full_name} (${@created_date})

becomes:

${__id}: ${__full_name} (${__created_date})

Then, at report fill time, each value of the base table result row is added to a java.util.Map keyed by '__' prefixed column ids. The SimpleTemplateEngine uses this Map to fill the processed <placemark_name_template> and create each <Placemarks> <name>

Usage

Basic usage

In the following fictional example, the land_ownership table contains information about the land ownership parcels in a suburban neighborhood. The table contains both attribute information about each parcel such as its address and owner's name plus a geom_kml column containing the parcel's KML geometry.

Table 1. land_ownership table
idowner_namestreet_addressstatezipgeom_kml
39Carrie Franklin49 West SheelyVermont98833...
40Marjo Hoff104 JuniperVermont98833...

When exported via the Export Report REST API and viewed within a KML viewer, each record within the land_ownership table should be labeled with a KML Placemark formatted like this:

[Owner Name] - [ZIP] (ID: [ID])

With this template, the two rows from the land_ownership table would create the following KML Placemarks:

Figure 1. Two KML Placemarks with a custom name
Two KML Placemarks with a custom name

Use <placemark_name_template> to achieve this Placemark output. Notice that the required columns within the template are referenced via their column resource paths.

Example 1. Via an XML Catalog file
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="http://www.pullreports.com/catalog-1.6.1" id="land-ownership" name="Land Ownership Reports"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.pullreports.com/catalog-1.6.1
    https://www.pullreports.com/docs/xsd/pullreports-catalog-1.6.1.xsd">
    <report id="parcel-information" name="Parcel Information">
        <export_config defaultColumns='id,oname'>
            <kml geometryColumnPath="@parcel-geometry-kml">
                <placemark_name_template>${/parcel@oname} - ${/parcel@zip} (ID: ${/parcel@id})</placemark_name_template>
            </kml>
       </export_config>
        <table id="parcel" displayName="Land Parcel" name="land_ownership"> 
            <column id="id" name="id" displayName="Parcel ID" paramType="java.lang.Integer"/>
            <column id="oname" name="owner_name" displayName="Owner Name"/>
            <column id="street" name="street_address" displayName="Street" />
            <column id="state" name="state" displayName="State" />
            <column id="zip" name="zip" displayName="Zip" />
            <column id="parcel-geometry-kml" name="geom_kml" displayName="KML" />
        </table>
    </report>
</catalog>

Example 2. Via the Catalog Configuration Java API

The following example is an identical Catalog Configuration Java API configuration.

package com.pullreports.examples.placemarknametemplate;

import com.pullreports.model.CatalogId;
import com.pullreports.model.ColumnId;
import com.pullreports.model.ParamType;
import com.pullreports.model.ReportId;
import com.pullreports.model.TableId;
import com.pullreports.model.config.CatalogConfiguration;
import com.pullreports.model.config.CatalogConfigurationFactory;
import com.pullreports.model.config.ColumnConfiguration;
import com.pullreports.model.config.ReportConfiguration;
import com.pullreports.model.config.TableConfiguration;
import com.pullreports.model.exportconfig.ExportConfiguration;
import com.pullreports.model.exportconfig.KmlConfiguration;

import javax.servlet.ServletContext;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class PlacemarkNameTemplateCatalogConfigurationFactory implements CatalogConfigurationFactory {

    @Override
    public CatalogConfiguration makeCatalog(ServletContext servletContext) {

        ColumnConfiguration idColumnConfiguration = new ColumnConfiguration.Builder(
            new ColumnId("id"),"id")
            .setParamType(ParamType.INTEGER)
            .setDisplayName("Parcel ID").build();

        ColumnConfiguration onameColumnConfiguration = new ColumnConfiguration.Builder(
            new ColumnId("oname"),"owner_name")
            .setDisplayName("Owner Name")
            .build();

        ColumnConfiguration streetColumnConfiguration = new ColumnConfiguration.Builder(
            new ColumnId("street"),"street_address")
            .setDisplayName("Street")
            .build();

        ColumnConfiguration stateColumnConfiguration = new ColumnConfiguration.Builder(
            new ColumnId("state"),"state")
            .setDisplayName("State")
            .build();

        ColumnConfiguration zipColumnConfiguration = new ColumnConfiguration.Builder(
            new ColumnId("zip"),"zip")
            .setDisplayName("Zip").build();

        ColumnConfiguration kmlColumnConfiguration = new ColumnConfiguration.Builder(
            new ColumnId("parcel-geometry-kml"),"geom_kml")
            .setDisplayName("KML").build();

        List<ColumnConfiguration> columnConfigurations = Arrays.asList(
                idColumnConfiguration
                ,onameColumnConfiguration
                ,streetColumnConfiguration
                ,stateColumnConfiguration
                ,zipColumnConfiguration
                ,kmlColumnConfiguration);

        TableConfiguration parcelTableConfiguration = new TableConfiguration.Builder(
            new TableId("parcel"),"Land Parcel",columnConfigurations)
            .setName("land_ownership").build();

        KmlConfiguration kmlConfiguration = new KmlConfiguration(
            kmlColumnConfiguration.getId(),"${/parcel@oname} - ${/parcel@zip} (ID: ${/parcel@id})");

        ReportConfiguration parcelReportConfiguration = new ReportConfiguration.Builder(
            new ReportId("parcel-information"),"Parcel Information",parcelTableConfiguration)
            .setExportConfiguration(
                new ExportConfiguration.Builder()
                    .setDefaultColumns(Arrays.asList(
                    idColumnConfiguration.getId()
                        ,onameColumnConfiguration.getId()))
                    .setKmlConfiguration(kmlConfiguration)
                .build()).build();
        
        List<ReportConfiguration> reportConfigurations = Collections.singletonList(parcelReportConfiguration);

        return new CatalogConfiguration(new CatalogId("land-ownership"),"Land Ownership Reports",reportConfigurations);
    }
}

                

Default KML <Placemark> name

If no <placemark_name_template> is configured for a <kml> element, the Export Report REST API kml format will return a default placemark that conforms to this template:

[Report Name] Geometry

In the case of the prior example, each Placemark would be:

Parcel Information Geometry

The two rows from the land_ownership table would then create the following KML Placemarks assuming no <placemark_name_template> is configured:

Figure 2. Two KML Placemarks with the default name
Two KML Placemarks with the default name

Using a static method and Groovy operators

In addition to simple substitution of column values, the placemark_name_template may contain other constructs supported by Groovy's SimpleTemplateEngine. For instance, Groovy or Java math, logic, or String operators and static method calls such as System.getProperty(String) and org.apache.commons.lang3.StringUtils.substring(String, int) are all permitted. Note that the last use of org.apache.commons.lang3.StringUtils requires the commons-lang3.jar on the JVM classpath.

In the following example, the <placemark_name_template> abbreviates the oname column to 20 characters and appends the sale value expressed in 1000's of dollars. The Groovy Elvis operator, ?:, is used to transform @oname to the empty String, '', and @saleValue to 0 if either value is null for a particular row.

<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="http://www.pullreports.com/catalog-1.6.1" id="land-ownership" name="Land Ownership Reports"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.pullreports.com/catalog-1.6.1
    https://www.pullreports.com/docs/xsd/pullreports-catalog-1.6.1.xsd">
    <report id="parcel-information" name="Parcel Information">
        <export_config defaultColumns='id,oname'>
            <kml geometryColumnPath="@parcel-geometry-kml">
                <placemark_name_template>
                    ${org.apache.commons.lang3.StringUtils.abbreviate(@oname?:'',20)} : \$${(@saleValue?:0) / 1000}K
                </placemark_name_template>
            </kml>
       </export_config>
        <table id="parcel" displayName="Parcel" name="land_parcel"> 
            <column id="id" name="id" displayName="Parcel ID" paramType="java.lang.Integer"/>
            <column id="oname" name="owner_name" displayName="Owner Name"/>
            <column id="street" name="street_address" displayName="Street" />
            <column id="state" name="state" displayName="State" />
            <column id="zip" name="zip" displayName="Zip" />
            <column id="saleValue" name="sale" displayName="Sale Value" paramType="java.lang.Integer"/>
            <column id="parcel-geometry-kml" name="geom_kml" displayName="KML" />
        </table>
    </report>
</catalog>

Parents

<kml>