// Copyright (C) Stichting Deltares 2016. All rights reserved.
//
// This file is part of Ringtoets.
//
// Ringtoets 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 3 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, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using BruTile;
using BruTile.Wmts;
using Core.Components.BruTile.Data;
using Core.Components.BruTile.Properties;
using Core.Components.Gis.Exceptions;
namespace Core.Components.BruTile.Configurations
{
///
/// A configuration for a connection to a Web Map Tile Service (WMTS).
///
///
/// Original source: https://github.com/FObermaier/DotSpatial.Plugins/blob/master/DotSpatial.Plugins.BruTileLayer/Configuration/WmtsLayerConfiguration.cs
/// Original license: http://www.apache.org/licenses/LICENSE-2.0.html
///
public class WmtsLayerConfiguration : PersistentCacheConfiguration
{
private readonly string capabilitiesUri;
private readonly string capabilityIdentifier;
private readonly string preferredFormat;
///
/// Creates an instance of .
///
/// The capabilities URL of the WMTS.
/// The capability name to get tiles from.
/// The preferred tile image format, as MIME-type.
/// The directory path to the persistent tile cache.
/// Thrown when
/// is an invalid folder path.
/// Thrown when any input argument is null.
private WmtsLayerConfiguration(string wmtsCapabilitiesUrl, string capabilityIdentifier, string preferredFormat,
string persistentCacheDirectoryPath) : base(persistentCacheDirectoryPath)
{
ValidateConfigurationParameters(wmtsCapabilitiesUrl, capabilityIdentifier, preferredFormat);
capabilitiesUri = wmtsCapabilitiesUrl;
this.capabilityIdentifier = capabilityIdentifier;
this.preferredFormat = preferredFormat;
Initialized = false;
}
///
/// Creates a new initialized instance of .
///
/// The capabilities URL of the WMTS.
/// The tile source.
/// Thrown when creating the file
/// cache failed.
/// Thrown when
/// does not allow for tiles to be retrieved.
/// Thrown when a critical error
/// occurs when creating the tile cache.
private WmtsLayerConfiguration(string wmtsCapabilitiesUrl, ITileSource tileSource)
: base(SuggestTileCachePath(ValidateTileSource(tileSource)))
{
capabilitiesUri = wmtsCapabilitiesUrl;
capabilityIdentifier = ((WmtsTileSchema) tileSource.Schema).Identifier;
preferredFormat = tileSource.Schema.Format;
InitializeFromTileSource(tileSource);
}
///
/// Creates a fully initialized instance of .
///
/// The capabilities URL of the WMTS.
/// The capability name to get tiles from.
/// The preferred tile image format, as MIME-type.
/// The new .
/// Thrown when any input argument is null.
/// Thrown when
/// is not an image MIME-type.
/// Thrown when it has become impossible
/// to create an based on the given information (for example:
/// unable to connect to server).
/// Thrown when the configured
/// does not allow for tiles to be retrieved.
/// Thrown when a critical error
/// occurs when creating the tile cache.
public static WmtsLayerConfiguration CreateInitializedConfiguration(string wmtsCapabilitiesUrl, string capabilityIdentifier, string preferredFormat)
{
ValidateConfigurationParameters(wmtsCapabilitiesUrl, capabilityIdentifier, preferredFormat);
ITileSource tileSource = GetConfiguredTileSource(wmtsCapabilitiesUrl, capabilityIdentifier, preferredFormat);
return new WmtsLayerConfiguration(wmtsCapabilitiesUrl, tileSource);
}
protected override IConfiguration OnClone()
{
return new WmtsLayerConfiguration(capabilitiesUri, capabilityIdentifier, preferredFormat, PersistentCacheDirectoryPath);
}
protected override void OnInitialize()
{
if (Initialized)
{
return;
}
ITileSource tileSource = GetConfiguredTileSource(capabilitiesUri, capabilityIdentifier, preferredFormat);
InitializeFromTileSource(tileSource);
}
///
/// Validates an .
///
/// The source to be validated.
/// Returns .
/// Thrown when
/// doesn't contain a .
private static ITileSource ValidateTileSource(ITileSource tileSource)
{
if (!(tileSource.Schema is WmtsTileSchema))
{
throw new CannotCreateTileCacheException(Resources.WmtsLayerConfiguration_ValidateTileSource_TileSource_must_have_WmtsTileSchema);
}
return tileSource;
}
///
/// Validate the configuration parameters.
///
/// The capabilities URL of the WMTS.
/// The capability name to get tiles from.
/// The preferred tile image format, as MIME-type.
/// Thrown when any input argument is null.
/// Thrown when
/// is not specified as a MIME-type.
private static void ValidateConfigurationParameters(string wmtsCapabilitiesUrl, string capabilityIdentifier, string preferredFormat)
{
if (wmtsCapabilitiesUrl == null)
{
throw new ArgumentNullException(nameof(wmtsCapabilitiesUrl));
}
if (capabilityIdentifier == null)
{
throw new ArgumentNullException(nameof(capabilityIdentifier));
}
if (preferredFormat == null)
{
throw new ArgumentNullException(nameof(preferredFormat));
}
if (!preferredFormat.StartsWith("image/"))
{
throw new ArgumentException(Resources.WmtsLayerConfiguration_ValidateConfigurationParameters_PreferredFormat_must_be_mimetype,
nameof(preferredFormat));
}
}
///
/// Connects to the WMTS to retrieve the configured tile source.
///
/// The URL of the tile source server.
/// The identifier of the tile source.
/// The preferred tile image format, as MIME-type.
/// The tile source with .
/// Thrown when unable to retrieve
/// the configured tile source.
private static ITileSource GetConfiguredTileSource(string capabilitiesUri, string capabilityIdentifier, string preferredFormat)
{
IEnumerable tileSources = TileSourceFactory.Instance.GetWmtsTileSources(capabilitiesUri);
ITileSource tileSource = tileSources.FirstOrDefault(ts => IsMatch(ts, capabilityIdentifier, preferredFormat));
if (tileSource == null)
{
string message = string.Format(Resources.WmtsLayerConfiguration_GetConfiguredTileSource_Cannot_find_LayerId_0_at_WmtsUrl_1_,
capabilityIdentifier, capabilitiesUri);
throw new CannotFindTileSourceException(message);
}
return tileSource;
}
private static bool IsMatch(ITileSource wmtsTileSource, string capabilityIdentifier, string preferredFormat)
{
var schema = (WmtsTileSchema) wmtsTileSource.Schema;
return schema.Identifier.Equals(capabilityIdentifier)
&& schema.Format.Equals(preferredFormat);
}
private static string SuggestTileCachePath(ITileSource tileSource)
{
var tileSchema = (WmtsTileSchema) tileSource.Schema;
string host = tileSchema.Title;
string format = tileSchema.Format.Split('/')[1];
string layerStyle = tileSchema.Identifier;
if (!string.IsNullOrEmpty(tileSchema.Style))
{
layerStyle += "_" + tileSchema.Style;
}
foreach (var c in Path.GetInvalidFileNameChars())
{
host = host.Replace(c, '$');
}
foreach (var c in Path.GetInvalidFileNameChars())
{
layerStyle = layerStyle.Replace(c, '$');
}
return Path.Combine(BruTileSettings.PersistentCacheDirectoryRoot, "Wmts", host, layerStyle, format);
}
}
}