/*
* Copyright (C) 2011-2014 GeoForge Project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.geoforge.worldwindogc.util;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.avlist.AVList;
import gov.nasa.worldwind.exception.WWRuntimeException;
import gov.nasa.worldwind.geom.Sector;
import gov.nasa.worldwind.ogc.OGCConstants;
import gov.nasa.worldwind.ogc.wms.WMSLayerCapabilities;
import gov.nasa.worldwind.ogc.wms.WMSLayerStyle;
import gov.nasa.worldwind.util.DataConfigurationUtils;
import gov.nasa.worldwind.util.Logging;
import gov.nasa.worldwind.util.WWIO;
import gov.nasa.worldwind.util.WWXML;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.logging.Logger;
import org.geoforge.java.util.logging.filehandler.FileHandlerLogger;
import org.geoforge.worldwindogc.capabilities.GfrWMSCapabilities;
/**
*
* @author bantchao
*/
abstract public class GfrDataConfigurationUtils extends DataConfigurationUtils
{
// ----
// begin: instantiate logger for this class
final private static Logger _LOGGER_ = Logger.getLogger(GfrDataConfigurationUtils.class.getName());
static
{
GfrDataConfigurationUtils._LOGGER_.addHandler(FileHandlerLogger.s_getInstance());
}
// end: instantiate logger for this class
// ----
public static AVList s_getWMSLayerConfigParams(
GfrWMSCapabilities caps,
String[] formatOrderPreference,
AVList params) throws
WWRuntimeException,
IllegalArgumentException
{
if (caps == null)
{
String message = Logging.getMessage("nullValue.WMSCapabilities");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (params == null)
{
String message = Logging.getMessage("nullValue.ParametersIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
String layerNames = params.getStringValue(AVKey.LAYER_NAMES);
String styleNames = params.getStringValue(AVKey.STYLE_NAMES);
if (layerNames == null || layerNames.length() == 0)
{
String message = Logging.getMessage("nullValue.WMSLayerNames");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
String[] names = layerNames.split(",");
if (names == null || names.length == 0)
{
String message = Logging.getMessage("nullValue.WMSLayerNames");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
for (String name : names)
{
if (caps.getLayerByName(name) == null)
{
String message = Logging.getMessage("WMS.LayerNameMissing", name);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
}
// Define the DISPLAY_NAME and DATASET_NAME from the WMS layer names and styles.
params.setValue(AVKey.DISPLAY_NAME, makeTitle(caps, layerNames, styleNames));
params.setValue(AVKey.DATASET_NAME, layerNames);
// Get the EXPIRY_TIME from the WMS layer last update time.
Long lastUpdate = caps.getLayerLatestLastUpdateTime(caps, names);
if (lastUpdate != null)
{
params.setValue(AVKey.EXPIRY_TIME, lastUpdate);
}
// Get the GET_MAP_URL from the WMS getMapRequest URL.
String mapRequestURIString = caps.getRequestURL("GetMap", "http", "get");
if (params.getValue(AVKey.GET_MAP_URL) == null)
{
params.setValue(AVKey.GET_MAP_URL, mapRequestURIString);
}
mapRequestURIString = params.getStringValue(AVKey.GET_MAP_URL);
// Throw an exception if there's no GET_MAP_URL property, or no getMapRequest URL in the WMS Capabilities.
if (mapRequestURIString == null)
{
Logging.logger().severe("WMS.RequestMapURLMissing");
throw new WWRuntimeException(Logging.getMessage("WMS.RequestMapURLMissing"));
}
// ATTN: added by bantchao, worldWInd's code too sensitive
mapRequestURIString = mapRequestURIString.trim(); // should not be needed anymore!
if (mapRequestURIString.length() == 0)
{
Logging.logger().severe("WMS.RequestMapURLMissing");
throw new WWRuntimeException(Logging.getMessage("WMS.RequestMapURLMissing"));
}
// Get the GET_CAPABILITIES_URL from the WMS getCapabilitiesRequest URL.
String capsRequestURIString = caps.getRequestURL("GetCapabilities", "http", "get");
if (params.getValue(AVKey.GET_CAPABILITIES_URL) == null)
{
params.setValue(AVKey.GET_CAPABILITIES_URL, capsRequestURIString);
}
// Define the SERVICE from the GET_MAP_URL property.
params.setValue(AVKey.SERVICE, params.getValue(AVKey.GET_MAP_URL));
String serviceURL = params.getStringValue(AVKey.SERVICE);
if (serviceURL != null)
{
params.setValue(AVKey.SERVICE, WWXML.fixGetMapString(serviceURL));
}
// Define the SERVICE_NAME as the standard OGC WMS service string.
if (params.getValue(AVKey.SERVICE_NAME) == null)
{
params.setValue(AVKey.SERVICE_NAME, OGCConstants.WMS_SERVICE_NAME);
}
// Define the WMS VERSION as the version fetched from the Capabilities document.
String versionString = caps.getVersion();
if (params.getValue(AVKey.WMS_VERSION) == null)
{
params.setValue(AVKey.WMS_VERSION, versionString);
}
// Form the cache path DATA_CACHE_NAME from a set of unique WMS parameters.
if (params.getValue(AVKey.DATA_CACHE_NAME) == null)
{
try
{
URI mapRequestURI = new URI(mapRequestURIString);
String cacheName = WWIO.formPath(mapRequestURI.getAuthority(), mapRequestURI.getPath(), layerNames,
styleNames);
params.setValue(AVKey.DATA_CACHE_NAME, cacheName);
}
catch (URISyntaxException e)
{
String strError = "mapRequestURIString=\"" + mapRequestURIString + "\"\n";
strError += e.getMessage();
GfrDataConfigurationUtils._LOGGER_.warning(strError);
String message = Logging.getMessage("WMS.RequestMapURLBad", mapRequestURIString);
Logging.logger().log(java.util.logging.Level.SEVERE, message, e);
throw new WWRuntimeException(message);
}
}
// Determine image format to request.
if (params.getStringValue(AVKey.IMAGE_FORMAT) == null)
{
String imageFormat = chooseImageFormat(caps.getImageFormats().toArray(), formatOrderPreference);
params.setValue(AVKey.IMAGE_FORMAT, imageFormat);
}
// Throw an exception if we cannot determine an image format to request.
if (params.getStringValue(AVKey.IMAGE_FORMAT) == null)
{
Logging.logger().severe("WMS.NoImageFormats");
throw new WWRuntimeException(Logging.getMessage("WMS.NoImageFormats"));
}
// Determine bounding sector.
Sector sector = (Sector) params.getValue(AVKey.SECTOR);
if (sector == null)
{
for (String name : names)
{
Sector layerSector = caps.getLayerByName(name).getGeographicBoundingBox();
if (layerSector == null)
{
Logging.logger().log(java.util.logging.Level.SEVERE, "WMS.NoGeographicBoundingBoxForLayer", name);
continue;
}
sector = Sector.union(sector, layerSector);
}
if (sector == null)
{
Logging.logger().severe("WMS.NoGeographicBoundingBox");
throw new WWRuntimeException(Logging.getMessage("WMS.NoGeographicBoundingBox"));
}
params.setValue(AVKey.SECTOR, sector);
}
// TODO: adjust for subsetable, fixedimage, etc.
return params;
}
protected static String makeTitle(GfrWMSCapabilities caps, String layerNames, String styleNames)
{
String[] lNames = layerNames.split(",");
String[] sNames = styleNames != null ? styleNames.split(",") : null;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < lNames.length; i++)
{
if (sb.length() > 0)
{
sb.append(", ");
}
String layerName = lNames[i];
WMSLayerCapabilities layer = caps.getLayerByName(layerName);
String layerTitle = layer.getTitle();
sb.append(layerTitle != null ? layerTitle : layerName);
if (sNames == null || sNames.length <= i)
{
continue;
}
String styleName = sNames[i];
WMSLayerStyle style = layer.getStyleByName(styleName);
if (style == null)
{
continue;
}
sb.append(" : ");
String styleTitle = style.getTitle();
sb.append(styleTitle != null ? styleTitle : styleName);
}
return sb.toString();
}
private GfrDataConfigurationUtils() {}
}