Learn to configure the <placemark_name_template>
element for Pull Reports™ Ad Hoc
report and data service software.
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
GString
s 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:
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}
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>
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.
land_ownership
tableid | owner_name | street_address | state | zip | geom_kml |
---|---|---|---|---|---|
39 | Carrie Franklin | 49 West Sheely | Vermont | 98833 | ... |
40 | Marjo Hoff | 104 Juniper | Vermont | 98833 | ... |
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:
Use a <placemark_name_template>
to achieve this Placemark output. Notice that the
required columns within the template are referenced via their column resource paths.
<?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>
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.ExportConfigurationBuilder;
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 ExportConfigurationBuilder()
.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);
}
}
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:
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>
<kml> |