The TDS adds Viewer Links to datasets at the bottom of a dataset's HTML web page, for example:
Currently, the TDS automatically adds the following:
The TDS also supports several ways to configure other viewer links and their results:
Dataset viewer links can be added to dataset HTML pages using "viewer" property elements.
To add a dataset viewer link to a specific dataset, add a property
element that
has a name starting with "viewer". When the TDS generates a dataset HTML page, it looks for all
"viewer" property elements and uses the value of each property element to generate a viewer link.
The value of the "viewer" property
element must be a string containing a URL and a
name separated by a a comma. An HTML link is built using the URL and the name. For instance,
the following example:
<dataset name="Test Single Dataset" ID="testDataset" serviceName="odap" urlPath="test/testData.nc" dataType="Grid">
<property name="viewer" value="https://www.unidata.ucar.edu/staff/caron/,MyViewer"/> <property name="viewer2" value="https://www.unidata.ucar.edu/,MyOtherViewer"/> </dataset>
results in the following HTML fragment:
<a href='https://www.unidata.ucar.edu/staff/caron/'>MyViewer</a> <a href='https://www.unidata.ucar.edu/'>MyOtherViewer</a>
Which looks like this on the TDS page:
When a "viewer" property element is contained in an inherited metadata element, it will apply to all the descendants of the containing dataset. For instance, the following example will result in viewer links for all children datasets:
<dataset name="Test inherited viewer" ID="tiv">
<metadata inherited="true">
<serviceName>all</serviceName>
<property name="viewer" value="https://www.unidata.ucar.edu/staff/caron/,MyViewer" />
</metadata>
<dataset name="test inherited viewer ds 1" ID="tiv/ds1" urlPath="tiv/ds1.nc">
<dataset name="test inherited viewer ds 2" ID="tiv/ds2" urlPath="tiv/ds2.nc">
</dataset>
When added to a datasetScan
elements, the "viewer" property results in a viewer link being added to the HTML dataset pages for each generated
dataset:
<datasetScan name="Test inherited viewer dsScan" ID="tivScan" path="tivScan" location="C:/some/good/data/">
<metadata inherited="true">
<serviceName>all</serviceName>
<property name="viewer" value="https://www.unidata.ucar.edu/staff/caron/,MyViewer" />
</metadata>
</datasetScan>
Adding the same viewer link to all your dataset pages may not be what you want. The TDS also supports inserting a dataset access URL into the viewer link URL. If your dataset has a single service, you can place "{url}" into your viewer link. The datasets access URL will be substituted in place of the "{url}" string. For instance, the following:
<dataset name="Test Viewer2" ID="testViewer2" serviceName="dapService" urlPath="test/testData.nc" dataType="Grid" <property name="viewer" value="http://motherlode.ucar.edu:8080/cdmvalidator/validate?URL={url},Validation Service"/> </dataset>
results in the following viewer link:
<a href="http://motherlode.ucar.edu:8080/cdmvalidator/validate?URL=http://myhost:8080/thredds/dodsC/test/testData.nc">Validation Service</a>
When a Dataset has more than one kind of access, each access will have a seperate URL. Use the service type inside of curly brackets to select which access URL to use.
For example, the following:
<service name="all" base="" serviceType="compound">
<service name="odap" serviceType="OPENDAP" base="/thredds/dodsC/"/>
<service name="http" serviceType="HTTPServer" base="/thredds/fileServer/"/>
<service name="wcs" serviceType="WCS" base="/thredds/wcs/"/>
<service name="wms" serviceType="WMS" base="/thredds/wms/"/>
<service name="ncss" serviceType="NetcdfSubset" base="/thredds/ncss/"/>
<service name="cdmremote" serviceType="CdmRemote" base="/thredds/cdmremote/"/>
<service name="iso" serviceType="ISO" base="/thredds/iso/"/>
<service name="ncml" serviceType="NCML" base="/thredds/ncml/"/>
<service name="uddc" serviceType="UDDC" base="/thredds/uddc/"/>
</service> <dataset name="test viewer select service" ID="tvss"> <metadata inherited="true"> <serviceName>all</serviceName> </metadata> <dataset name="test viewer select service ds 1" ID="tvss/ds1" urlPath="tvss/ds1.nc"> <property name="viewer" value="http://motherlode.ucar.edu:8080/cdmvalidator/validate?URL={OPENDAP},Validation Service" /> </dataset> <dataset name="test viewer select service ds 2" ID="tvss/ds2" urlPath="tvss/ds2.nc"> <property name="viewer" value="http://myhost:8080/wcsView/show?dataset={WCS},Validation Service" /> </dataset> </dataset>
generates a viewer link URL for the first dataset of:
http://motherlode.ucar.edu:8080/cdmvalidator/validate?URL=http://myhost:8080/thredds/dodsC/tvss/ds1.nc
and for the second dataset, the viewer link is:
http://myhost:8080/wmsView/show?dataset=http://myhost:8080/thredds/wcs/tvss/ds2.nc
If your server is publically accessible, this example calls the motherlode validator service for your dataset, using opendap. The dataset page now looks something like:
Viewer links can also support on the fly generation of JNLP files. This can be very useful when using data viewing software that can be started with a JNLP file (i.e., running under Java Webstart). For instance, the automatically generated "IDV" and "NetCDF-Java Tools" viewer links mentioned above use JNLP files to start. The JNLP generation can be used in other user configured viewer links as well.
The TDS will return any JNLP template file under the
${catalina_home}/content/thredds/views/
directory when requested with a URL that
looks like:
http://localhost:8080/thredds/view/<filename>
For example, the URL
http://localhost:8080/thredds/view/my/cool/viewer.jnlp
will look for and return the file
${catalina_home}/content/thredds/views/my/cool/viewer.jnlp
The TDS processes the JNLP template file before sending it to the client as the response to their request. The processing looks for replacement strings of the form "{name}" and replaces them with the value of the corresponding URL query parameter. So, if the JNLP template file contains any occurrences of the "{dataset}" string and the request URL looked like
http://localhost:8080/thredds/view/my/cool/viewer.jnlp?dataset=http://some.other.server/thredds/dodsC/cool/data.nc
all occurrences of "{dataset}" would be replaced by "http://some.other.server/thredds/dodsC/cool/data.nc".
So, looking at an approximation of the IDV JNLP file:
<?xml version="1.0" encoding="utf-8"?>
<!-- JNLP File for Integrated Data Viewer -->
<jnlp spec="1.0+" codebase="https://www.unidata.ucar.edu/software/idv/webstart/">
<information>
<title>Integrated Data Viewer</title>
<vendor>Unidata</vendor>
<homepage href="https://www.unidata.ucar.edu/software/idv/index.html"/>
<description>Integrated Data Viewer(IDV)</description>
<description kind="short">A tool for geoscientific analysis and visualization.
</description>
<icon href="IDV/idv.gif"/>
<offline-allowed/>
</information>
<security>
<all-permissions/>
</security>
<resources>
<j2se version="1.4+" max-heap-size="512m"/>
<jar href="IDV/idv.jar"/>
<extension name="IDV Base" href="IDV/idvbase.jnlp"/>
</resources>
<application-desc main-class="ucar.unidata.idv.DefaultIdv">
<argument>-data</argument>
<argument>type:opendap.grid:{dataset}</argument>
</application-desc>
</jnlp>
The third from the last line would be replaced with
<argument>type:opendap.grid:http://some.other.server/thredds/dodsC/cool/data.nc</argument>
Which passes the dataset access URL to the IDV as an argument.
This method is available in TDS version 3.14+.
This technique gives you full control over whether your viewer link appears, and what the URL looks like. You must create a Java class which implements the thredds.servlet.Viewer interface:
public interface Viewer
{
(1) public boolean isViewable( thredds.catalog.InvDatasetImpl dataset);
(2) public String getViewerLinkHtml( InvDatasetImpl ds, HttpServletRequest req);
}
Example:
package my.package;
include thredds.catalog.*;
public class IDV implements Viewer
{
public boolean isViewable( InvDatasetImpl ds)
{
InvAccess access = ds.getAccess(ServiceType.DODS);
if (access == null) access = ds.getAccess(ServiceType.OPENDAP);
1) if (access == null) return false;
2) return (ds.getDataType() == DataType.GRID);
}
public String getViewerLinkHtml( InvDatasetImpl ds, HttpServletRequest req)
{
InvAccess access = ds.getAccess(ServiceType.DODS);
3) if (access == null) access = ds.getAccess(ServiceType.OPENDAP);
4) URI dataURI = access.getStandardUri();
try
{
URI base = new URI( req.getRequestURL().toString());
5) dataURI = base.resolve( dataURI);
}
catch (URISyntaxException e)
{
log.error("Resolve URL with "+req.getRequestURL(),e);
}
6) return "<a href='/thredds/view/idv.jnlp?url="+dataURI.toString()+"'>Integrated Data Viewer (IDV) (webstart)</a>";
}
}
If the viewer you want to reference is not part of the TDS, just make the href absolute, e.g.:
<a href='http://my.server/viewer?url=http://motherlode.ucar.edu:8080/thredds/dodsC/model/data.grib2'>My Server</a>
In this example, the server would see the OPeNDAP data access URL and remotely read it.
You must place your Viewer class into the ${tomcat_home}/webapps/thredds/WEB-INF/lib or classes directory. (Previous instructions to place it into the ${tomcat_home}/shared directory doesn't work, because of classloader problems).
Then tell the TDS to load it by adding a line to the ${tomcat_home}/content/thredds/threddsConfig.xml file, for example:
<viewer>my.package.MyViewer</viewer>
A Viewer implementation can still use the TDS JNLP template service (see above). It just needs to return the appropriate HTML link referencing an existing JNLP template file and giving the appropriate replacment URL query parameters. The IDV implementation above does just that.
One reason to write an implementation of Viewer and use is JNLP is if the viewer has requirements for the datsets it can handle. Looking at the IDV implementation above we see it enforces two requirements:
To call the ToolsUI application webstart application from your webpage, return this JNLP file:
<?xml version="1.0" encoding="utf-8"?> <jnlp spec="1.0+" codebase="https://downloads.unidata.ucar.edu/netcdf-java/4.6/webstart/"> <information> <title>NetCDF Tools UI</title> <vendor>Unidata</vendor> <homepage href="https://www.unidata.ucar.edu/software/netcdf-java/"/> <description kind="short">GUI interface to netCDF-Java / Common Data Model</description> <icon href="nc.gif"/> <offline-allowed/> </information> <security> <all-permissions/> </security> <resources> <j2se version="1.6+" max-heap-size="1024m"/> <jar href="netcdfUI.jar"/> <extension name="netcdfUI Extra" href="netCDFtoolsExtraJars.jnlp"/> </resources> <application-desc main-class="ucar.nc2.ui.ToolsUI"> <argument>{catalog}#{dataset}</argument> </application-desc> </jnlp>
where
for example:
<application-desc main-class="ucar.nc2.ui.ToolsUI"> <argument>http://motherlode.ucar.edu:8081/thredds/catalog/fmrc/NCEP/GFS/CONUS_95km/files/catalog.xml#fmrc/NCEP/GFS/CONUS_95km/files/GFS_CONUS_95km_20120414_0000.grib1</argument> </application-desc>
If you dont specify the <argument>, ToolsUI will still startup normally, and not jump to the THREDDS catalog tab.
When TDS gets this URL:
http://oos.soest.hawaii.edu/thredds/view/ToolsUI.jnlp?catalog=http://oos.soest.hawaii.edu/thredds/idd/nss_hioos.xml&dataset=NS02agg
It creates a jnlp file which is sent back to your browser. If your browser has Java webstart installed as a helper application (which happens when you
install Java on your computer), the jnlp file is handled by the "Java plugin" on your browser, which downloads ToolsUI from wherever the jnlp file specifies,
currently https://downloads.unidata.ucar.edu/netcdf-java/4.6/webstart
The jnlp file has been customized to include the command line argument of the form "{catalog}#{dataset}", and the ToolsUI application looks for this and uses
it to open that catalog and display the named dataset in the "Catalog Chooser" tab. This UI component gives access to all the metadata and access protocols of
that dataset.